vendor: 3,695 bytes, lines 1-89
1/******/ (function(modules) { // webpackBootstrap 2/******/ // The module cache 3/******/ var installedModules = {}; 4/******/ 5/******/ // The require function 6/******/ function __webpack_require__(moduleId) { 7 /******/ 8/******/ // Check if module is in cache 9/******/ if(installedModules[moduleId]) { 10 /******/ return installedModules[moduleId].exports; 11/******/ } 12/******/ // Create a new module (and put it into the cache) 13/******/ var module = installedModules[moduleId] = { 14 /******/ i: moduleId, 15 /******/ l: false, 16 /******/ exports: {} 17/******/ }; 18/******/ 19/******/ // Execute the module function 20/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21/******/ 22/******/ // Flag the module as loaded 23/******/ module.l = true; 24/******/ 25/******/ // Return the exports of the module 26/******/ return module.exports; 27/******/ } 28/******/ 29/******/ 30/******/ // expose the modules object (__webpack_modules__) 31/******/ __webpack_require__.m = modules; 32/******/ 33/******/ // expose the module cache 34/******/ __webpack_require__.c = installedModules; 35/******/ 36/******/ // define getter function for harmony exports 37/******/ __webpack_require__.d = function(exports, name, getter) { 38 /******/ if(!__webpack_require__.o(exports, name)) { 39 /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40 /******/ } 41/******/ }; 42/******/ 43/******/ // define __esModule on exports 44/******/ __webpack_require__.r = function(exports) { 45 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47 /******/ } 48 /******/ Object.defineProperty(exports, '__esModule', { value: true }); 49/******/ }; 50/******/ 51/******/ // create a fake namespace object 52/******/ // mode & 1: value is a module id, require it 53/******/ // mode & 2: merge all properties of value into the ns 54/******/ // mode & 4: return value when already ns object 55/******/ // mode & 8|1: behave like require 56/******/ __webpack_require__.t = function(value, mode) { 57 /******/ if(mode & 1) value = __webpack_require__(value); 58 /******/ if(mode & 8) return value; 59 /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60 /******/ var ns = Object.create(null); 61 /******/ __webpack_require__.r(ns); 62 /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63 /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64 /******/ return ns; 65/******/ }; 66/******/ 67/******/ // getDefaultExport function for compatibility with non-harmony modules 68/******/ __webpack_require__.n = function(module) { 69 /******/ var getter = module && module.__esModule ? 70 /******/ function getDefault() { return module['default']; } : 71 /******/ function getModuleExports() { return module; }; 72 /******/ __webpack_require__.d(getter, 'a', getter); 73 /******/ return getter; 74/******/ }; 75/******/ 76/******/ // Object.prototype.hasOwnProperty.call 77/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78/******/ 79/******/ // __webpack_public_path__ 80/******/ __webpack_require__.p = ""; 81/******/ 82/******/ 83/******/ // Load entry module and return exports 84/******/ return __webpack_require__(__webpack_require__.s = "./wp-content/themes/pnr/assets/src/js/app.js"); 85/******/ }) 86/************************************************************************/ 87/******/ ({ 88 89
89/***/ "./.modernizrrc.js": 90/*!*************************!*\ 91 !*** ./.modernizrrc.js ***! 92 \*************************/ 93 /*! no static exports found */ 94 /***/ (function(module, exports) { 95 96 function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 97 98 ; 99 100 (function (window) { 101 var hadGlobal = 'Modernizr' in window; 102 var oldGlobal = window.Modernizr; 103 /*! modernizr 3.6.0 (Custom Build) | MIT * 104 * https://modernizr.com/download/?-backgroundcliptext-flexbox-objectfit-promises-serviceworker-touchevents-setclasses !*/ 105 106 !function (e, n, t) { 107 function r(e, n) { 108 return _typeof(e) === n; 109 } 110 111 function o() { 112 var e, n, t, o, i, s, a; 113 114 for (var l in C) { 115 if (C.hasOwnProperty(l)) { 116 if (e = [], n = C[l], n.name && (e.push(n.name.toLowerCase()), n.options && n.options.aliases && n.options.aliases.length)) for (t = 0; t < n.options.aliases.length; t++) { 117 e.push(n.options.aliases[t].toLowerCase()); 118 } 119 120 for (o = r(n.fn, "function") ? n.fn() : n.fn, i = 0; i < e.length; i++) { 121 s = e[i], a = s.split("."), 1 === a.length ? Modernizr[a[0]] = o : (!Modernizr[a[0]] || Modernizr[a[0]] instanceof Boolean || (Modernizr[a[0]] = new Boolean(Modernizr[a[0]])), Modernizr[a[0]][a[1]] = o), w.push((o ? "" : "no-") + a.join("-")); 122 } 123 } 124 } 125 } 126 127 function i(e) { 128 var n = S.className, 129 t = Modernizr._config.classPrefix || ""; 130 131 if (_ && (n = n.baseVal), Modernizr._config.enableJSClass) { 132 var r = new RegExp("(^|\\s)" + t + "no-js(\\s|$)"); 133 n = n.replace(r, "$1" + t + "js$2"); 134 } 135 136 Modernizr._config.enableClasses && (n += " " + t + e.join(" " + t), _ ? S.className.baseVal = n : S.className = n); 137 } 138 139 function s(e, n) { 140 return !!~("" + e).indexOf(n); 141 } 142 143 function a() { 144 return "function" != typeof n.createElement ? n.createElement(arguments[0]) : _ ? n.createElementNS.call(n, "http://www.w3.org/2000/svg", arguments[0]) : n.createElement.apply(n, arguments); 145 } 146 147 function l() { 148 var e = n.body; 149 return e || (e = a(_ ? "svg" : "body"), e.fake = !0), e; 150 } 151 152 function u(e, t, r, o) { 153 var i, 154 s, 155 u, 156 f, 157 c = "modernizr", 158 d = a("div"), 159 p = l(); 160 if (parseInt(r, 10)) for (; r--;) { 161 u = a("div"), u.id = o ? o[r] : c + (r + 1), d.appendChild(u); 162 } 163 return i = a("style"), i.type = "text/css", i.id = "s" + c, (p.fake ? p : d).appendChild(i), p.appendChild(d), i.styleSheet ? i.styleSheet.cssText = e : i.appendChild(n.createTextNode(e)), d.id = c, p.fake && (p.style.background = "", p.style.overflow = "hidden", f = S.style.overflow, S.style.overflow = "hidden", S.appendChild(p)), s = t(d, e), p.fake ? (p.parentNode.removeChild(p), S.style.overflow = f, S.offsetHeight) : d.parentNode.removeChild(d), !!s; 164 } 165 166 function f(e) { 167 return e.replace(/([A-Z])/g, function (e, n) { 168 return "-" + n.toLowerCase(); 169 }).replace(/^ms-/, "-ms-"); 170 } 171 172 function c(n, t, r) { 173 var o; 174 175 if ("getComputedStyle" in e) { 176 o = getComputedStyle.call(e, n, t); 177 var i = e.console; 178 if (null !== o) r && (o = o.getPropertyValue(r));else if (i) { 179 var s = i.error ? "error" : "log"; 180 i[s].call(i, "getComputedStyle returning null, its possible modernizr test results are inaccurate"); 181 } 182 } else o = !t && n.currentStyle && n.currentStyle[r]; 183 184 return o; 185 } 186 187 function d(n, r) { 188 var o = n.length; 189 190 if ("CSS" in e && "supports" in e.CSS) { 191 for (; o--;) { 192 if (e.CSS.supports(f(n[o]), r)) return !0; 193 } 194 195 return !1; 196 } 197 198 if ("CSSSupportsRule" in e) { 199 for (var i = []; o--;) { 200 i.push("(" + f(n[o]) + ":" + r + ")"); 201 } 202 203 return i = i.join(" or "), u("@supports (" + i + ") { #modernizr { position: absolute; } }", function (e) { 204 return "absolute" == c(e, null, "position"); 205 }); 206 } 207 208 return t; 209 } 210 211 function p(e) { 212 return e.replace(/([a-z])-([a-z])/g, function (e, n, t) { 213 return n + t.toUpperCase(); 214 }).replace(/^-/, ""); 215 } 216 217 function m(e, n, o, i) { 218 function l() { 219 f && (delete j.style, delete j.modElem); 220 } 221 222 if (i = r(i, "undefined") ? !1 : i, !r(o, "undefined")) { 223 var u = d(e, o); 224 if (!r(u, "undefined")) return u; 225 } 226 227 for (var f, c, m, v, h, g = ["modernizr", "tspan", "samp"]; !j.style && g.length;) { 228 f = !0, j.modElem = a(g.shift()), j.style = j.modElem.style; 229 } 230 231 for (m = e.length, c = 0; m > c; c++) { 232 if (v = e[c], h = j.style[v], s(v, "-") && (v = p(v)), j.style[v] !== t) { 233 if (i || r(o, "undefined")) return l(), "pfx" == n ? v : !0; 234 235 try { 236 j.style[v] = o; 237 } catch (y) {} 238 239 if (j.style[v] != h) return l(), "pfx" == n ? v : !0; 240 } 241 } 242 243 return l(), !1; 244 } 245 246 function v(e, n) { 247 return function () { 248 return e.apply(n, arguments); 249 }; 250 } 251 252 function h(e, n, t) { 253 var o; 254 255 for (var i in e) { 256 if (e[i] in n) return t === !1 ? e[i] : (o = n[e[i]], r(o, "function") ? v(o, t || n) : o); 257 } 258 259 return !1; 260 } 261 262 function g(e, n, t, o, i) { 263 var s = e.charAt(0).toUpperCase() + e.slice(1), 264 a = (e + " " + P.join(s + " ") + s).split(" "); 265 return r(n, "string") || r(n, "undefined") ? m(a, n, o, i) : (a = (e + " " + z.join(s + " ") + s).split(" "), h(a, n, t)); 266 } 267 268 function y(e, n, r) { 269 return g(e, t, t, n, r); 270 } 271 272 var C = [], 273 x = { 274 _version: "3.6.0", 275 _config: { 276 classPrefix: "", 277 enableClasses: !0, 278 enableJSClass: !0, 279 usePrefixes: !0 280 }, 281 _q: [], 282 on: function on(e, n) { 283 var t = this; 284 setTimeout(function () { 285 n(t[e]); 286 }, 0); 287 }, 288 addTest: function addTest(e, n, t) { 289 C.push({ 290 name: e, 291 fn: n, 292 options: t 293 }); 294 }, 295 addAsyncTest: function addAsyncTest(e) { 296 C.push({ 297 name: null, 298 fn: e 299 }); 300 } 301 }, 302 Modernizr = function Modernizr() {}; 303 304 Modernizr.prototype = x, Modernizr = new Modernizr(); 305 306 var w = [], 307 S = n.documentElement, 308 _ = "svg" === S.nodeName.toLowerCase(), 309 b = "Moz O ms Webkit", 310 P = x._config.usePrefixes ? b.split(" ") : []; 311 312 x._cssomPrefixes = P; 313 var T = { 314 elem: a("modernizr") 315 }; 316 317 Modernizr._q.push(function () { 318 delete T.elem; 319 }); 320 321 var j = { 322 style: T.elem.style 323 }; 324 325 Modernizr._q.unshift(function () { 326 delete j.style; 327 }); 328 329 var z = x._config.usePrefixes ? b.toLowerCase().split(" ") : []; 330 x._domPrefixes = z, x.testAllProps = g, x.testAllProps = y, Modernizr.addTest("flexbox", y("flexBasis", "1px", !0)), Modernizr.addTest("promises", function () { 331 return "Promise" in e && "resolve" in e.Promise && "reject" in e.Promise && "all" in e.Promise && "race" in e.Promise && function () { 332 var n; 333 return new e.Promise(function (e) { 334 n = e; 335 }), "function" == typeof n; 336 }(); 337 }), Modernizr.addTest("serviceworker", "serviceWorker" in navigator); 338 var k = x._config.usePrefixes ? " -webkit- -moz- -o- -ms- ".split(" ") : ["", ""]; 339 x._prefixes = k; 340 var E = x.testStyles = u; 341 Modernizr.addTest("touchevents", function () { 342 var t; 343 if ("ontouchstart" in e || e.DocumentTouch && n instanceof DocumentTouch) t = !0;else { 344 var r = ["@media (", k.join("touch-enabled),("), "heartz", ")", "{#modernizr{top:9px;position:absolute}}"].join(""); 345 E(r, function (e) { 346 t = 9 === e.offsetTop; 347 }); 348 } 349 return t; 350 }); 351 352 var N = function N(n) { 353 var r, 354 o = k.length, 355 i = e.CSSRule; 356 if ("undefined" == typeof i) return t; 357 if (!n) return !1; 358 if (n = n.replace(/^@/, ""), r = n.replace(/-/g, "_").toUpperCase() + "_RULE", r in i) return "@" + n; 359 360 for (var s = 0; o > s; s++) { 361 var a = k[s], 362 l = a.toUpperCase() + "_" + r;
363 if (l in i) return "@-" + a.toLowerCase() + "-" + n; 364 } 365 366 return !1; 367 }; 368 369 x.atRule = N; 370 371 var L = x.prefixed = function (e, n, t) { 372 return 0 === e.indexOf("@") ? N(e) : (-1 != e.indexOf("-") && (e = p(e)), n ? g(e, n, t) : g(e, "pfx")); 373 }; 374 375 Modernizr.addTest("objectfit", !!L("objectFit"), { 376 aliases: ["object-fit"] 377 }), Modernizr.addTest("backgroundcliptext", function () { 378 return y("backgroundClip", "text"); 379 }), o(), i(w), delete x.addTest, delete x.addAsyncTest; 380 381 for (var A = 0; A < Modernizr._q.length; A++) { 382 Modernizr._q[A](); 383 } 384 385 e.Modernizr = Modernizr; 386 }(window, document); 387 module.exports = window.Modernizr; 388 389 if (hadGlobal) { 390 window.Modernizr = oldGlobal; 391 } else { 392 delete window.Modernizr; 393 } 394})(window); 395 396/***/ }), 397
vendor: 68,791 bytes, lines 398-421
398/***/ "./node_modules/@fancyapps/fancybox/dist/jquery.fancybox.min.js": 399/*!**********************************************************************!*\ 400 !*** ./node_modules/@fancyapps/fancybox/dist/jquery.fancybox.min.js ***! 401 \**********************************************************************/ 402 /*! no static exports found */ 403 /***/ (function(module, exports, __webpack_require__) { 404 405/* WEBPACK VAR INJECTION */(function(jQuery) {// ================================================== 406// fancyBox v3.5.7 407// 408// Licensed GPLv3 for open source use 409// or fancyBox Commercial License for commercial use 410// 411// http://fancyapps.com/fancybox/ 412// Copyright 2019 fancyApps 413// 414// ================================================== 415!function(t,e,n,o){"use strict";function i(t,e){var o,i,a,s=[],r=0;t&&t.isDefaultPrevented()||(t.preventDefault(),e=e||{},t&&t.data&&(e=h(t.data.options,e)),o=e.$target||n(t.currentTarget).trigger("blur"),(a=n.fancybox.getInstance())&&a.$trigger&&a.$trigger.is(o)||(e.selector?s=n(e.selector):(i=o.attr("data-fancybox")||"",i?(s=t.data?t.data.items:[],s=s.length?s.filter('[data-fancybox="'+i+'"]'):n('[data-fancybox="'+i+'"]')):s=[o]),r=n(s).index(o),r<0&&(r=0),a=n.fancybox.open(s,e,r),a.$trigger=o))}if(t.console=t.console||{info:function(t){}},n){if(n.fn.fancybox)return void console.info("fancyBox already initialized");var a={closeExisting:!1,loop:!1,gutter:50,keyboard:!0,preventCaptionOverlap:!0,arrows:!0,infobar:!0,smallBtn:"auto",toolbar:"auto",buttons:["zoom","slideShow","thumbs","close"],idleTime:3,protect:!1,modal:!1,image:{preload:!1},ajax:{settings:{data:{fancybox:!0}}},iframe:{tpl:'<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" allowfullscreen="allowfullscreen" allow="autoplay; fullscreen" src=""></iframe>',preload:!0,css:{},attr:{scrolling:"auto"}},video:{tpl:'<video class="fancybox-video" controls controlsList="nodownload" poster="{{poster}}"><source src="{{src}}" type="{{format}}" />Sorry, your browser doesn\'t support embedded videos, <a href="{{src}}">download</a> and watch with your favorite video player!</video>',format:"",autoStart:!0},defaultType:"image",animationEffect:"zoom",animationDuration:366,zoomOpacity:"auto",transitionEffect:"fade",transitionDuration:366,slideClass:"",baseClass:"",baseTpl:'<div class="fancybox-container" role="dialog" tabindex="-1"><div class="fancybox-bg"></div><div class="fancybox-inner"><div class="fancybox-infobar"><span data-fancybox-index></span> / <span data-fancybox-count></span></div><div class="fancybox-toolbar">{{buttons}}</div><div class="fancybox-navigation">{{arrows}}</div><div class="fancybox-stage"></div><div class="fancybox-caption"><div class="fancybox-caption__body"></div></div></div></div>',spinnerTpl:'<div class="fancybox-loading"></div>',errorTpl:'<div class="fancybox-error"><p>{{ERROR}}</p></div>',btnTpl:{download:'<a download data-fancybox-download class="fancybox-button fancybox-button--download" title="{{DOWNLOAD}}" href="javascript:;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.62 17.09V19H5.38v-1.91zm-2.97-6.96L17 11.45l-5 4.87-5-4.87 1.36-1.32 2.68 2.64V5h1.92v7.77z"/></svg></a>',zoom:'<button data-fancybox-zoom class="fancybox-button fancybox-button--zoom" title="{{ZOOM}}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.7 17.3l-3-3a5.9 5.9 0 0 0-.6-7.6 5.9 5.9 0 0 0-8.4 0 5.9 5.9 0 0 0 0 8.4 5.9 5.9 0 0 0 7.7.7l3 3a1 1 0 0 0 1.3 0c.4-.5.4-1 0-1.5zM8.1 13.8a4 4 0 0 1 0-5.7 4 4 0 0 1 5.7 0 4 4 0 0 1 0 5.7 4 4 0 0 1-5.7 0z"/></svg></button>',close:'<button data-fancybox-close class="fancybox-button fancybox-button--close" title="{{CLOSE}}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 10.6L6.6 5.2 5.2 6.6l5.4 5.4-5.4 5.4 1.4 1.4 5.4-5.4 5.4 5.4 1.4-1.4-5.4-5.4 5.4-5.4-1.4-1.4-5.4 5.4z"/></svg></button>',arrowLeft:'<button data-fancybox-prev class="fancybox-button fancybox-button--arrow_left" title="{{PREV}}"><div><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.28 15.7l-1.34 1.37L5 12l4.94-5.07 1.34 1.38-2.68 2.72H19v1.94H8.6z"/></svg></div></button>',arrowRight:'<button data-fancybox-next class="fancybox-button fancybox-button--arrow_right" title="{{NEXT}}"><div><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.4 12.97l-2.68 2.72 1.34 1.38L19 12l-4.94-5.07-1.34 1.38 2.68 2.72H5v1.94z"/></svg></div></button>',smallBtn:'<button type="button" data-fancybox-close class="fancybox-button fancybox-close-small" title="{{CLOSE}}"><svg xmlns="http://www.w3.org/2000/svg" version="1" viewBox="0 0 24 24"><path d="M13 12l5-5-1-1-5 5-5-5-1 1 5 5-5 5 1 1 5-5 5 5 1-1z"/></svg></button>'},parentEl:"body",hideScrollbar:!0,autoFocus:!0,backFocus:!0,trapFocus:!0,fullScreen:{autoStart:!1},touch:{vertical:!0,momentum:!0},hash:null,media:{},slideShow:{autoStart:!1,speed:3e3},thumbs:{autoStart:!1,hideOnClose:!0,parentEl:".fancybox-container",axis:"y"},wheel:"auto",onInit:n.noop,beforeLoad:n.noop,afterLoad:n.noop,beforeShow:n.noop,afterShow:n.noop,beforeClose:n.noop,afterClose:n.noop,onActivate:n.noop,onDeactivate:n.noop,clickContent:function(t,e){return"image"===t.type&&"zoom"},clickSlide:"close",clickOutside:"close",dblclickContent:!1,dblclickSlide:!1,dblclickOutside:!1,mobile:{preventCaptionOverlap:!1,idleTime:!1,clickContent:function(t,e){return"image"===t.type&&"toggleControls"},clickSlide:function(t,e){return"image"===t.type?"toggleControls":"close"},dblclickContent:function(t,e){return"image"===t.type&&"zoom"},dblclickSlide:function(t,e){return"image"===t.type&&"zoom"}},lang:"en",i18n:{en:{CLOSE:"Close",NEXT:"Next",PREV:"Previous",ERROR:"The requested content cannot be loaded. <br/> Please try again later.",PLAY_START:"Start slideshow",PLAY_STOP:"Pause slideshow",FULL_SCREEN:"Full screen",THUMBS:"Thumbnails",DOWNLOAD:"Download",SHARE:"Share",ZOOM:"Zoom"},de:{CLOSE:"Schließen",NEXT:"Weiter",PREV:"Zurück",ERROR:"Die angeforderten Daten konnten nicht geladen werden. <br/> Bitte versuchen Sie es später nochmal.",PLAY_START:"Diaschau starten",PLAY_STOP:"Diaschau beenden",FULL_SCREEN:"Vollbild",THUMBS:"Vorschaubilder",DOWNLOAD:"Herunterladen",SHARE:"Teilen",ZOOM:"Vergrößern"}}},s=n(t),r=n(e),c=0,l=function(t){return t&&t.hasOwnProperty&&t instanceof n},d=function(){return t.requestAnimationFrame||t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||t.oRequestAnimationFrame||function(e){return t.setTimeout(e,1e3/60)}}(),u=function(){return t.cancelAnimationFrame||t.webkitCancelAnimationFrame||t.mozCancelAnimationFrame||t.oCancelAnimationFrame||function(e){t.clearTimeout(e)}}(),f=function(){var t,n=e.createElement("fakeelement"),o={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(t in o)if(void 0!==n.style[t])return o[t];return"transitionend"}(),p=function(t){return t&&t.length&&t[0].offsetHeight},h=function(t,e){var o=n.extend(!0,{},t,e);return n.each(e,function(t,e){n.isArray(e)&&(o[t]=e)}),o},g=function(t){var o,i;return!(!t||t.ownerDocument!==e)&&(n(".fancybox-container").css("pointer-events","none"),o={x:t.getBoundingClientRect().left+t.offsetWidth/2,y:t.getBoundingClientRect().top+t.offsetHeight/2},i=e.elementFromPoint(o.x,o.y)===t,n(".fancybox-container").css("pointer-events",""),i)},b=function(t,e,o){var i=this;i.opts=h({index:o},n.fancybox.defaults),n.isPlainObject(e)&&(i.opts=h(i.opts,e)),n.fancybox.isMobile&&(i.opts=h(i.opts,i.opts.mobile)),i.id=i.opts.id||++c,i.currIndex=parseInt(i.opts.index,10)||0,i.prevIndex=null,i.prevPos=null,i.currPos=0,i.firstRun=!0,i.group=[],i.slides={},i.addContent(t),i.group.length&&i.init()};n.extend(b.prototype,{init:function(){var o,i,a=this,s=a.group[a.currIndex],r=s.opts;r.closeExisting&&n.fancybox.close(!0),n("body").addClass("fancybox-active"),!n.fancybox.getInstance()&&!1!==r.hideScrollbar&&!n.fancybox.isMobile&&e.body.scrollHeight>t.innerHeight&&(n("head").append('<style id="fancybox-style-noscroll" type="text/css">.compensate-for-scrollbar{margin-right:'+(t.innerWidth-e.documentElement.clientWidth)+"px;}</style>"),n("body").addClass("compensate-for-scrollbar")),i="",n.each(r.buttons,function(t,e){i+=r.btnTpl[e]||""}),o=n(a.translate(a,r.baseTpl.replace("{{buttons}}",i).replace("{{arrows}}",r.btnTpl.arrowLeft+r.btnTpl.arrowRight))).attr("id","fancybox-container-"+a.id).addClass(r.baseClass).data("FancyBox",a).appendTo(r.parentEl),a.$refs={container:o},["bg","inner","infobar","toolbar","stage","caption","navigation"].forEach(function(t){a.$refs[t]=o.find(".fancybox-"+t)}),a.trigger("onInit"),a.activate(),a.jumpTo(a.currIndex)},translate:function(t,e){var n=t.opts.i18n[t.opts.lang]||t.opts.i18n.en;return e.replace(/\{\{(\w+)\}\}/g,function(t,e){return void 0===n[e]?t:n[e]})},addContent:function(t){var e,o=this,i=n.makeArray(t);n.each(i,function(t,e){var i,a,s,r,c,l={},d={};n.isPlainObject(e)?(l=e,d=e.opts||e):"object"===n.type(e)&&n(e).length?(i=n(e),d=i.data()||{},d=n.extend(!0,{},d,d.options),d.$orig=i,l.src=o.opts.src||d.src||i.attr("href"),l.type||l.src||(l.type="inline",l.src=e)):l={type:"html",src:e+""},l.opts=n.extend(!0,{},o.opts,d),n.isArray(d.buttons)&&(l.opts.buttons=d.buttons),n.fancybox.isMobile&&l.opts.mobile&&(l.opts=h(l.opts,l.opts.mobile)),a=l.type||l.opts.type,r=l.src||"",!a&&r&&((s=r.match(/\.(mp4|mov|ogv|webm)((\?|#).*)?$/i))?(a="video",l.opts.video.format||(l.opts.video.format="video/"+("ogv"===s[1]?"ogg":s[1]))):r.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i)?a="image":r.match(/\.(pdf)((\?|#).*)?$/i)?(a="iframe",l=n.extend(!0,l,{contentType:"pdf",opts:{iframe:{preload:!1}}})):"#"===r.charAt(0)&&(a="inline")),a?l.type=a:o.trigger("objectNeedsType",l),l.contentType||(l.contentType=n.inArray(l.type,["html","inline","ajax"])>-1?"html":l.type),l.index=o.group.length,"auto"==l.opts.smallBtn&&(l.opts.smallBtn=n.inArray(l.type,["html","inline","ajax"])>-1),"auto"===l.opts.toolbar&&(l.opts.toolbar=!l.opts.smallBtn),l.$thumb=l.opts.$thumb||null,l.opts.$trigger&&l.index===o.opts.index&&(l.$thumb=l.opts.$trigger.find("img:first"),l.$thumb.length&&(l.opts.$orig=l.opts.$trigger)),l.$thumb&&l.$thumb.length||!l.opts.$orig||(l.$thumb=l.opts.$orig.find("img:first")),l.$thumb&&!l.$thumb.length&&(l.$thumb=null),l.thumb=l.opts.thumb||(l.$thumb?l.$thumb[0].src:null),"function"===n.type(l.opts.caption)&&(l.opts.caption=l.opts.caption.apply(e,[o,l])),"function"===n.type(o.opts.caption)&&(l.opts.caption=o.opts.caption.apply(e,[o,l])),l.opts.caption instanceof n||(l.opts.caption=void 0===l.opts.caption?"":l.opts.caption+""),"ajax"===l.type&&(c=r.split(/\s+/,2),c.length>1&&(l.src=c.shift(),l.opts.filter=c.shift())),l.opts.modal&&(l.opts=n.extend(!0,l.opts,{trapFocus:!0,infobar:0,toolbar:0,smallBtn:0,keyboard:0,slideShow:0,fullScreen:0,thumbs:0,touch:0,clickContent:!1,clickSlide:!1,clickOutside:!1,dblclickContent:!1,dblclickSlide:!1,dblclickOutside:!1})),o.group.push(l)}),Object.keys(o.slides).length&&(o.updateControls(),(e=o.Thumbs)&&e.isActive&&(e.create(),e.focus()))},addEvents:function(){var e=this;e.removeEvents(),e.$refs.container.on("click.fb-close","[data-fancybox-close]",function(t){t.stopPropagation(),t.preventDefault(),e.close(t)}).on("touchstart.fb-prev click.fb-prev","[data-fancybox-prev]",function(t){t.stopPropagation(),t.preventDefault(),e.previous()}).on("touchstart.fb-next click.fb-next","[data-fancybox-next]",function(t){t.stopPropagation(),t.preventDefault(),e.next()}).on("click.fb","[data-fancybox-zoom]",function(t){e[e.isScaledDown()?"scaleToActual":"scaleToFit"]()}),s.on("orientationchange.fb resize.fb",function(t){t&&t.originalEvent&&"resize"===t.originalEvent.type?(e.requestId&&u(e.requestId),e.requestId=d(function(){e.update(t)})):(e.current&&"iframe"===e.current.type&&e.$refs.stage.hide(),setTimeout(function(){e.$refs.stage.show(),e.update(t)},n.fancybox.isMobile?600:250))}),r.on("keydown.fb",function(t){var o=n.fancybox?n.fancybox.getInstance():null,i=o.current,a=t.keyCode||t.which;if(9==a)return void(i.opts.trapFocus&&e.focus(t));if(!(!i.opts.keyboard||t.ctrlKey||t.altKey||t.shiftKey||n(t.target).is("input,textarea,video,audio,select")))return 8===a||27===a?(t.preventDefault(),void e.close(t)):37===a||38===a?(t.preventDefault(),void e.previous()):39===a||40===a?(t.preventDefault(),void e.next()):void e.trigger("afterKeydown",t,a)}),e.group[e.currIndex].opts.idleTime&&(e.idleSecondsCounter=0,r.on("mousemove.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle",function(t){e.idleSecondsCounter=0,e.isIdle&&e.showControls(),e.isIdle=!1}),e.idleInterval=t.setInterval(function(){++e.idleSecondsCounter>=e.group[e.currIndex].opts.idleTime&&!e.isDragging&&(e.isIdle=!0,e.idleSecondsCounter=0,e.hideControls())},1e3))},removeEvents:function(){var e=this;s.off("orientationchange.fb resize.fb"),r.off("keydown.fb .fb-idle"),this.$refs.container.off(".fb-close .fb-prev .fb-next"),e.idleInterval&&(t.clearInterval(e.idleInterval),e.idleInterval=null)},previous:function(t){return this.jumpTo(this.currPos-1,t)},next:function(t){return this.jumpTo(this.currPos+1,t)},jumpTo:function(t,e){var o,i,a,s,r,c,l,d,u,f=this,h=f.group.length;if(!(f.isDragging||f.isClosing||f.isAnimating&&f.firstRun)){if(t=parseInt(t,10),!(a=f.current?f.current.opts.loop:f.opts.loop)&&(t<0||t>=h))return!1;if(o=f.firstRun=!Object.keys(f.slides).length,r=f.current,f.prevIndex=f.currIndex,f.prevPos=f.currPos,s=f.createSlide(t),h>1&&((a||s.index<h-1)&&f.createSlide(t+1),(a||s.index>0)&&f.createSlide(t-1)),f.current=s,f.currIndex=s.index,f.currPos=s.pos,f.trigger("beforeShow",o),f.updateControls(),s.forcedDuration=void 0,n.isNumeric(e)?s.forcedDuration=e:e=s.opts[o?"animationDuration":"transitionDuration"],e=parseInt(e,10),i=f.isMoved(s),s.$slide.addClass("fancybox-slide--current"),o)return s.opts.animationEffect&&e&&f.$refs.container.css("transition-duration",e+"ms"),f.$refs.container.addClass("fancybox-is-open").trigger("focus"),f.loadSlide(s),void f.preload("image");c=n.fancybox.getTranslate(r.$slide),l=n.fancybox.getTranslate(f.$refs.stage),n.each(f.slides,function(t,e){n.fancybox.stop(e.$slide,!0)}),r.pos!==s.pos&&(r.isComplete=!1),r.$slide.removeClass("fancybox-slide--complete fancybox-slide--current"),i?(u=c.left-(r.pos*c.width+r.pos*r.opts.gutter),n.each(f.slides,function(t,o){o.$slide.removeClass("fancybox-animated").removeClass(function(t,e){return(e.match(/(^|\s)fancybox-fx-\S+/g)||[]).join(" ")});var i=o.pos*c.width+o.pos*o.opts.gutter;n.fancybox.setTranslate(o.$slide,{top:0,left:i-l.left+u}),o.pos!==s.pos&&o.$slide.addClass("fancybox-slide--"+(o.pos>s.pos?"next":"previous")),p(o.$slide),n.fancybox.animate(o.$slide,{top:0,left:(o.pos-s.pos)*c.width+(o.pos-s.pos)*o.opts.gutter},e,function(){o.$slide.css({transform:"",opacity:""}).removeClass("fancybox-slide--next fancybox-slide--previous"),o.pos===f.currPos&&f.complete()})})):e&&s.opts.transitionEffect&&(d="fancybox-animated fancybox-fx-"+s.opts.transitionEffect,r.$slide.addClass("fancybox-slide--"+(r.pos>s.pos?"next":"previous")),n.fancybox.animate(r.$slide,d,e,function(){r.$slide.removeClass(d).removeClass("fancybox-slide--next fancybox-slide--previous")},!1)),s.isLoaded?f.revealContent(s):f.loadSlide(s),f.preload("image")}},createSlide:function(t){var e,o,i=this;return o=t%i.group.length,o=o<0?i.group.length+o:o,!i.slides[t]&&i.group[o]&&(e=n('<div class="fancybox-slide"></div>').appendTo(i.$refs.stage),i.slides[t]=n.extend(!0,{},i.group[o],{pos:t,$slide:e,isLoaded:!1}),i.updateSlide(i.slides[t])),i.slides[t]},scaleToActual:function(t,e,o){var i,a,s,r,c,l=this,d=l.current,u=d.$content,f=n.fancybox.getTranslate(d.$slide).width,p=n.fancybox.getTranslate(d.$slide).height,h=d.width,g=d.height;l.isAnimating||l.isMoved()||!u||"image"!=d.type||!d.isLoaded||d.hasError||(l.isAnimating=!0,n.fancybox.stop(u),t=void 0===t?.5*f:t,e=void 0===e?.5*p:e,i=n.fancybox.getTranslate(u),i.top-=n.fancybox.getTranslate(d.$slide).top,i.left-=n.fancybox.getTranslate(d.$slide).left,r=h/i.width,c=g/i.height,a=.5*f-.5*h,s=.5*p-.5*g,h>f&&(a=i.left*r-(t*r-t),a>0&&(a=0),a<f-h&&(a=f-h)),g>p&&(s=i.top*c-(e*c-e),s>0&&(s=0),s<p-g&&(s=p-g)),l.updateCursor(h,g),n.fancybox.animate(u,{top:s,left:a,scaleX:r,scaleY:c},o||366,function(){l.isAnimating=!1}),l.SlideShow&&l.SlideShow.isActive&&l.SlideShow.stop())},scaleToFit:function(t){var e,o=this,i=o.current,a=i.$content;o.isAnimating||o.isMoved()||!a||"image"!=i.type||!i.isLoaded||i.hasError||(o.isAnimating=!0,n.fancybox.stop(a),e=o.getFitPos(i),o.updateCursor(e.width,e.height),n.fancybox.animate(a,{top:e.top,left:e.left,scaleX:e.width/a.width(),scaleY:e.height/a.height()},t||366,function(){o.isAnimating=!1}))},getFitPos:function(t){var e,o,i,a,s=this,r=t.$content,c=t.$slide,l=t.width||t.opts.width,d=t.height||t.opts.height,u={};return!!(t.isLoaded&&r&&r.length)&&(e=n.fancybox.getTranslate(s.$refs.stage).width,o=n.fancybox.getTranslate(s.$refs.stage).height,e-=parseFloat(c.css("paddingLeft"))+parseFloat(c.css("paddingRight"))+parseFloat(r.css("marginLeft"))+parseFloat(r.css("marginRight")),o-=parseFloat(c.css("paddingTop"))+parseFloat(c.css("paddingBottom"))+parseFloat(r.css("marginTop"))+parseFloat(r.css("marginBottom")),l&&d||(l=e,d=o),i=Math.min(1,e/l,o/d),l*=i,d*=i,l>e-.5&&(l=e),d>o-.5&&(d=o),"image"===t.type?(u.top=Math.floor(.5*(o-d))+parseFloat(c.css("paddingTop")),u.left=Math.floor(.5*(e-l))+parseFloat(c.css("paddingLeft"))):"video"===t.contentType&&(a=t.opts.width&&t.opts.height?l/d:t.opts.ratio||16/9,d>l/a?d=l/a:l>d*a&&(l=d*a)),u.width=l,u.height=d,u)},update:function(t){var e=this;n.each(e.slides,function(n,o){e.updateSlide(o,t)})},updateSlide:function(t,e){var o=this,i=t&&t.$content,a=t.width||t.opts.width,s=t.height||t.opts.height,r=t.$slide;o.adjustCaption(t),i&&(a||s||"video"===t.contentType)&&!t.hasError&&(n.fancybox.stop(i),n.fancybox.setTranslate(i,o.getFitPos(t)),t.pos===o.currPos&&(o.isAnimating=!1,o.updateCursor())),o.adjustLayout(t),r.length&&(r.trigger("refresh"),t.pos===o.currPos&&o.$refs.toolbar.add(o.$refs.navigation.find(".fancybox-button--arrow_right")).toggleClass("compensate-for-scrollbar",r.get(0).scrollHeight>r.get(0).clientHeight)),o.trigger("onUpdate",t,e)},centerSlide:function(t){var e=this,o=e.current,i=o.$slide;!e.isClosing&&o&&(i.siblings().css({transform:"",opacity:""}),i.parent().children().removeClass("fancybox-slide--previous fancybox-slide--next"),n.fancybox.animate(i,{top:0,left:0,opacity:1},void 0===t?0:t,function(){i.css({transform:"",opacity:""}),o.isComplete||e.complete()},!1))},isMoved:function(t){var e,o,i=t||this.current;return!!i&&(o=n.fancybox.getTranslate(this.$refs.stage),e=n.fancybox.getTranslate(i.$slide),!i.$slide.hasClass("fancybox-animated")&&(Math.abs(e.top-o.top)>.5||Math.abs(e.left-o.left)>.5))},updateCursor:function(t,e){var o,i,a=this,s=a.current,r=a.$refs.container;s&&!a.isClosing&&a.Guestures&&(r.removeClass("fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-zoomOut fancybox-can-swipe fancybox-can-pan"),o=a.canPan(t,e),i=!!o||a.isZoomable(),r.toggleClass("fancybox-is-zoomable",i),n("[data-fancybox-zoom]").prop("disabled",!i),o?r.addClass("fancybox-can-pan"):i&&("zoom"===s.opts.clickContent||n.isFunction(s.opts.clickContent)&&"zoom"==s.opts.clickContent(s))?r.addClass("fancybox-can-zoomIn"):s.opts.touch&&(s.opts.touch.vertical||a.group.length>1)&&"video"!==s.contentType&&r.addClass("fancybox-can-swipe"))},isZoomable:function(){var t,e=this,n=e.current;if(n&&!e.isClosing&&"image"===n.type&&!n.hasError){if(!n.isLoaded)return!0;if((t=e.getFitPos(n))&&(n.width>t.width||n.height>t.height))return!0}return!1},isScaledDown:function(t,e){var o=this,i=!1,a=o.current,s=a.$content;return void 0!==t&&void 0!==e?i=t<a.width&&e<a.height:s&&(i=n.fancybox.getTranslate(s),i=i.width<a.width&&i.height<a.height),i},canPan:function(t,e){var o=this,i=o.current,a=null,s=!1;return"image"===i.type&&(i.isComplete||t&&e)&&!i.hasError&&(s=o.getFitPos(i),void 0!==t&&void 0!==e?a={width:t,height:e}:i.isComplete&&(a=n.fancybox.getTranslate(i.$content)),a&&s&&(s=Math.abs(a.width-s.width)>1.5||Math.abs(a.height-s.height)>1.5)),s},loadSlide:function(t){var e,o,i,a=this;if(!t.isLoading&&!t.isLoaded){if(t.isLoading=!0,!1===a.trigger("beforeLoad",t))return t.isLoading=!1,!1;switch(e=t.type,o=t.$slide,o.off("refresh").trigger("onReset").addClass(t.opts.slideClass),e){case"image":a.setImage(t);break;case"iframe":a.setIframe(t);break;case"html":a.setContent(t,t.src||t.content);break;case"video":a.setContent(t,t.opts.video.tpl.replace(/\{\{src\}\}/gi,t.src).replace("{{format}}",t.opts.videoFormat||t.opts.video.format||"").replace("{{poster}}",t.thumb||""));break;case"inline":n(t.src).length?a.setContent(t,n(t.src)):a.setError(t);break;case"ajax":a.showLoading(t),i=n.ajax(n.extend({},t.opts.ajax.settings,{url:t.src,success:function(e,n){"success"===n&&a.setContent(t,e)},error:function(e,n){e&&"abort"!==n&&a.setError(t)}})),o.one("onReset",function(){i.abort()});break;default:a.setError(t)}return!0}},setImage:function(t){var o,i=this;setTimeout(function(){var e=t.$image;i.isClosing||!t.isLoading||e&&e.length&&e[0].complete||t.hasError||i.showLoading(t)},50),i.checkSrcset(t),t.$content=n('<div class="fancybox-content"></div>').addClass("fancybox-is-hidden").appendTo(t.$slide.addClass("fancybox-slide--image")),!1!==t.opts.preload&&t.opts.width&&t.opts.height&&t.thumb&&(t.width=t.opts.width,t.height=t.opts.height,o=e.createElement("img"),o.onerror=function(){n(this).remove(),t.$ghost=null},o.onload=function(){i.afterLoad(t)},t.$ghost=n(o).addClass("fancybox-image").appendTo(t.$content).attr("src",t.thumb)),i.setBigImage(t)},checkSrcset:function(e){var n,o,i,a,s=e.opts.srcset||e.opts.image.srcset;if(s){i=t.devicePixelRatio||1,a=t.innerWidth*i,o=s.split(",").map(function(t){var e={};return t.trim().split(/\s+/).forEach(function(t,n){var o=parseInt(t.substring(0,t.length-1),10);if(0===n)return e.url=t;o&&(e.value=o,e.postfix=t[t.length-1])}),e}),o.sort(function(t,e){return t.value-e.value});for(var r=0;r<o.length;r++){var c=o[r];if("w"===c.postfix&&c.value>=a||"x"===c.postfix&&c.value>=i){n=c;break}}!n&&o.length&&(n=o[o.length-1]),n&&(e.src=n.url,e.width&&e.height&&"w"==n.postfix&&(e.height=e.width/e.height*n.value,e.width=n.value),e.opts.srcset=s)}},setBigImage:function(t){var o=this,i=e.createElement("img"),a=n(i);t.$image=a.one("error",function(){o.setError(t)}).one("load",function(){var e;t.$ghost||(o.resolveImageSlideSize(t,this.naturalWidth,this.naturalHeight),o.afterLoad(t)),o.isClosing||(t.opts.srcset&&(e=t.opts.sizes,e&&"auto"!==e||(e=(t.width/t.height>1&&s.width()/s.height()>1?"100":Math.round(t.width/t.height*100))+"vw"),a.attr("sizes",e).attr("srcset",t.opts.srcset)),t.$ghost&&setTimeout(function(){t.$ghost&&!o.isClosing&&t.$ghost.hide()},Math.min(300,Math.max(1e3,t.height/1600))),o.hideLoading(t))}).addClass("fancybox-image").attr("src",t.src).appendTo(t.$content),(i.complete||"complete"==i.readyState)&&a.naturalWidth&&a.naturalHeight?a.trigger("load"):i.error&&a.trigger("error")},resolveImageSlideSize:function(t,e,n){var o=parseInt(t.opts.width,10),i=parseInt(t.opts.height,10);t.width=e,t.height=n,o>0&&(t.width=o,t.height=Math.floor(o*n/e)),i>0&&(t.width=Math.floor(i*e/n),t.height=i)},setIframe:function(t){var e,o=this,i=t.opts.iframe,a=t.$slide;t.$content=n('<div class="fancybox-content'+(i.preload?" fancybox-is-hidden":"")+'"></div>').css(i.css).appendTo(a),a.addClass("fancybox-slide--"+t.contentType),t.$iframe=e=n(i.tpl.replace(/\{rnd\}/g,(new Date).getTime())).attr(i.attr).appendTo(t.$content),i.preload?(o.showLoading(t),e.on("load.fb error.fb",function(e){this.isReady=1,t.$slide.trigger("refresh"),o.afterLoad(t)}),a.on("refresh.fb",function(){var n,o,s=t.$content,r=i.css.width,c=i.css.height;if(1===e[0].isReady){try{n=e.contents(),o=n.find("body")}catch(t){}o&&o.length&&o.children().length&&(a.css("overflow","visible"),s.css({width:"100%","max-width":"100%",height:"9999px"}),void 0===r&&(r=Math.ceil(Math.max(o[0].clientWidth,o.outerWidth(!0)))),s.css("width",r||"").css("max-width",""),void 0===c&&(c=Math.ceil(Math.max(o[0].clientHeight,o.outerHeight(!0)))),s.css("height",c||""),a.css("overflow","auto")),s.removeClass("fancybox-is-hidden")}})):o.afterLoad(t),e.attr("src",t.src),a.one("onReset",function(){try{n(this).find("iframe").hide().unbind().attr("src","//about:blank")}catch(t){}n(this).off("refresh.fb").empty(),t.isLoaded=!1,t.isRevealed=!1})},setContent:function(t,e){var o=this;o.isClosing||(o.hideLoading(t),t.$content&&n.fancybox.stop(t.$content),t.$slide.empty(),l(e)&&e.parent().length?((e.hasClass("fancybox-content")||e.parent().hasClass("fancybox-content"))&&e.parents(".fancybox-slide").trigger("onReset"),t.$placeholder=n("<div>").hide().insertAfter(e),e.css("display","inline-block")):t.hasError||("string"===n.type(e)&&(e=n("<div>").append(n.trim(e)).contents()),t.opts.filter&&(e=n("<div>").html(e).find(t.opts.filter))),t.$slide.one("onReset",function(){n(this).find("video,audio").trigger("pause"),t.$placeholder&&(t.$placeholder.after(e.removeClass("fancybox-content").hide()).remove(),t.$placeholder=null),t.$smallBtn&&(t.$smallBtn.remove(),t.$smallBtn=null),t.hasError||(n(this).empty(),t.isLoaded=!1,t.isRevealed=!1)}),n(e).appendTo(t.$slide),n(e).is("video,audio")&&(n(e).addClass("fancybox-video"),n(e).wrap("<div></div>"),t.contentType="video",t.opts.width=t.opts.width||n(e).attr("width"),t.opts.height=t.opts.height||n(e).attr("height")),t.$content=t.$slide.children().filter("div,form,main,video,audio,article,.fancybox-content").first(),t.$content.siblings().hide(),t.$content.length||(t.$content=t.$slide.wrapInner("<div></div>").children().first()),t.$content.addClass("fancybox-content"),t.$slide.addClass("fancybox-slide--"+t.contentType),o.afterLoad(t))},setError:function(t){t.hasError=!0,t.$slide.trigger("onReset").removeClass("fancybox-slide--"+t.contentType).addClass("fancybox-slide--error"),t.contentType="html",this.setContent(t,this.translate(t,t.opts.errorTpl)),t.pos===this.currPos&&(this.isAnimating=!1)},showLoading:function(t){var e=this;(t=t||e.current)&&!t.$spinner&&(t.$spinner=n(e.translate(e,e.opts.spinnerTpl)).appendTo(t.$slide).hide().fadeIn("fast"))},hideLoading:function(t){var e=this;(t=t||e.current)&&t.$spinner&&(t.$spinner.stop().remove(),delete t.$spinner)},afterLoad:function(t){var e=this;e.isClosing||(t.isLoading=!1,t.isLoaded=!0,e.trigger("afterLoad",t),e.hideLoading(t),!t.opts.smallBtn||t.$smallBtn&&t.$smallBtn.length||(t.$smallBtn=n(e.translate(t,t.opts.btnTpl.smallBtn)).appendTo(t.$content)),t.opts.protect&&t.$content&&!t.hasError&&(t.$content.on("contextmenu.fb",function(t){return 2==t.button&&t.preventDefault(),!0}),"image"===t.type&&n('<div class="fancybox-spaceball"></div>').appendTo(t.$content)),e.adjustCaption(t),e.adjustLayout(t),t.pos===e.currPos&&e.updateCursor(),e.revealContent(t))},adjustCaption:function(t){var e,n=this,o=t||n.current,i=o.opts.caption,a=o.opts.preventCaptionOverlap,s=n.$refs.caption,r=!1;s.toggleClass("fancybox-caption--separate",a),a&&i&&i.length&&(o.pos!==n.currPos?(e=s.clone().appendTo(s.parent()),e.children().eq(0).empty().html(i),r=e.outerHeight(!0),e.empty().remove()):n.$caption&&(r=n.$caption.outerHeight(!0)),o.$slide.css("padding-bottom",r||""))},adjustLayout:function(t){var e,n,o,i,a=this,s=t||a.current;s.isLoaded&&!0!==s.opts.disableLayoutFix&&(s.$content.css("margin-bottom",""),s.$content.outerHeight()>s.$slide.height()+.5&&(o=s.$slide[0].style["padding-bottom"],i=s.$slide.css("padding-bottom"),parseFloat(i)>0&&(e=s.$slide[0].scrollHeight,s.$slide.css("padding-bottom",0),Math.abs(e-s.$slide[0].scrollHeight)<1&&(n=i),s.$slide.css("padding-bottom",o))),s.$content.css("margin-bottom",n))},revealContent:function(t){var e,o,i,a,s=this,r=t.$slide,c=!1,l=!1,d=s.isMoved(t),u=t.isRevealed;return t.isRevealed=!0,e=t.opts[s.firstRun?"animationEffect":"transitionEffect"],i=t.opts[s.firstRun?"animationDuration":"transitionDuration"],i=parseInt(void 0===t.forcedDuration?i:t.forcedDuration,10),!d&&t.pos===s.currPos&&i||(e=!1),"zoom"===e&&(t.pos===s.currPos&&i&&"image"===t.type&&!t.hasError&&(l=s.getThumbPos(t))?c=s.getFitPos(t):e="fade"),"zoom"===e?(s.isAnimating=!0,c.scaleX=c.width/l.width,c.scaleY=c.height/l.height,a=t.opts.zoomOpacity,"auto"==a&&(a=Math.abs(t.width/t.height-l.width/l.height)>.1),a&&(l.opacity=.1,c.opacity=1),n.fancybox.setTranslate(t.$content.removeClass("fancybox-is-hidden"),l),p(t.$content),void n.fancybox.animate(t.$content,c,i,function(){s.isAnimating=!1,s.complete()})):(s.updateSlide(t),e?(n.fancybox.stop(r),o="fancybox-slide--"+(t.pos>=s.prevPos?"next":"previous")+" fancybox-animated fancybox-fx-"+e,r.addClass(o).removeClass("fancybox-slide--current"),t.$content.removeClass("fancybox-is-hidden"),p(r),"image"!==t.type&&t.$content.hide().show(0),void n.fancybox.animate(r,"fancybox-slide--current",i,function(){r.removeClass(o).css({transform:"",opacity:""}),t.pos===s.currPos&&s.complete()},!0)):(t.$content.removeClass("fancybox-is-hidden"),u||!d||"image"!==t.type||t.hasError||t.$content.hide().fadeIn("fast"),void(t.pos===s.currPos&&s.complete())))},getThumbPos:function(t){var e,o,i,a,s,r=!1,c=t.$thumb;return!(!c||!g(c[0]))&&(e=n.fancybox.getTranslate(c),o=parseFloat(c.css("border-top-width")||0),i=parseFloat(c.css("border-right-width")||0),a=parseFloat(c.css("border-bottom-width")||0),s=parseFloat(c.css("border-left-width")||0),r={top:e.top+o,left:e.left+s,width:e.width-i-s,height:e.height-o-a,scaleX:1,scaleY:1},e.width>0&&e.height>0&&r)},complete:function(){var t,e=this,o=e.current,i={};!e.isMoved()&&o.isLoaded&&(o.isComplete||(o.isComplete=!0,o.$slide.siblings().trigger("onReset"),e.preload("inline"),p(o.$slide),o.$slide.addClass("fancybox-slide--complete"),n.each(e.slides,function(t,o){o.pos>=e.currPos-1&&o.pos<=e.currPos+1?i[o.pos]=o:o&&(n.fancybox.stop(o.$slide),o.$slide.off().remove())}),e.slides=i),e.isAnimating=!1,e.updateCursor(),e.trigger("afterShow"),o.opts.video.autoStart&&o.$slide.find("video,audio").filter(":visible:first").trigger("play").one("ended",function(){Document.exitFullscreen?Document.exitFullscreen():this.webkitExitFullscreen&&this.webkitExitFullscreen(),e.next()}),o.opts.autoFocus&&"html"===o.contentType&&(t=o.$content.find("input[autofocus]:enabled:visible:first"),t.length?t.trigger("focus"):e.focus(null,!0)),o.$slide.scrollTop(0).scrollLeft(0))},preload:function(t){var e,n,o=this;o.group.length<2||(n=o.slides[o.currPos+1],e=o.slides[o.currPos-1],e&&e.type===t&&o.loadSlide(e),n&&n.type===t&&o.loadSlide(n))},focus:function(t,o){var i,a,s=this,r=["a[href]","area[href]",'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',"select:not([disabled]):not([aria-hidden])","textarea:not([disabled]):not([aria-hidden])","button:not([disabled]):not([aria-hidden])","iframe","object","embed","video","audio","[contenteditable]",'[tabindex]:not([tabindex^="-"])'].join(",");s.isClosing||(i=!t&&s.current&&s.current.isComplete?s.current.$slide.find("*:visible"+(o?":not(.fancybox-close-small)":"")):s.$refs.container.find("*:visible"),i=i.filter(r).filter(function(){return"hidden"!==n(this).css("visibility")&&!n(this).hasClass("disabled")}),i.length?(a=i.index(e.activeElement),t&&t.shiftKey?(a<0||0==a)&&(t.preventDefault(),i.eq(i.length-1).trigger("focus")):(a<0||a==i.length-1)&&(t&&t.preventDefault(),i.eq(0).trigger("focus"))):s.$refs.container.trigger("focus"))},activate:function(){var t=this;n(".fancybox-container").each(function(){var e=n(this).data("FancyBox");e&&e.id!==t.id&&!e.isClosing&&(e.trigger("onDeactivate"),e.removeEvents(),e.isVisible=!1)}),t.isVisible=!0,(t.current||t.isIdle)&&(t.update(),t.updateControls()),t.trigger("onActivate"),t.addEvents()},close:function(t,e){var o,i,a,s,r,c,l,u=this,f=u.current,h=function(){u.cleanUp(t)};return!u.isClosing&&(u.isClosing=!0,!1===u.trigger("beforeClose",t)?(u.isClosing=!1,d(function(){u.update()}),!1):(u.removeEvents(),a=f.$content,o=f.opts.animationEffect,i=n.isNumeric(e)?e:o?f.opts.animationDuration:0,f.$slide.removeClass("fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated"),!0!==t?n.fancybox.stop(f.$slide):o=!1,f.$slide.siblings().trigger("onReset").remove(),i&&u.$refs.container.removeClass("fancybox-is-open").addClass("fancybox-is-closing").css("transition-duration",i+"ms"),u.hideLoading(f),u.hideControls(!0),u.updateCursor(),"zoom"!==o||a&&i&&"image"===f.type&&!u.isMoved()&&!f.hasError&&(l=u.getThumbPos(f))||(o="fade"),"zoom"===o?(n.fancybox.stop(a),s=n.fancybox.getTranslate(a),c={top:s.top,left:s.left,scaleX:s.width/l.width,scaleY:s.height/l.height,width:l.width,height:l.height},r=f.opts.zoomOpacity, 416 "auto"==r&&(r=Math.abs(f.width/f.height-l.width/l.height)>.1),r&&(l.opacity=0),n.fancybox.setTranslate(a,c),p(a),n.fancybox.animate(a,l,i,h),!0):(o&&i?n.fancybox.animate(f.$slide.addClass("fancybox-slide--previous").removeClass("fancybox-slide--current"),"fancybox-animated fancybox-fx-"+o,i,h):!0===t?setTimeout(h,i):h(),!0)))},cleanUp:function(e){var o,i,a,s=this,r=s.current.opts.$orig;s.current.$slide.trigger("onReset"),s.$refs.container.empty().remove(),s.trigger("afterClose",e),s.current.opts.backFocus&&(r&&r.length&&r.is(":visible")||(r=s.$trigger),r&&r.length&&(i=t.scrollX,a=t.scrollY,r.trigger("focus"),n("html, body").scrollTop(a).scrollLeft(i))),s.current=null,o=n.fancybox.getInstance(),o?o.activate():(n("body").removeClass("fancybox-active compensate-for-scrollbar"),n("#fancybox-style-noscroll").remove())},trigger:function(t,e){var o,i=Array.prototype.slice.call(arguments,1),a=this,s=e&&e.opts?e:a.current;if(s?i.unshift(s):s=a,i.unshift(a),n.isFunction(s.opts[t])&&(o=s.opts[t].apply(s,i)),!1===o)return o;"afterClose"!==t&&a.$refs?a.$refs.container.trigger(t+".fb",i):r.trigger(t+".fb",i)},updateControls:function(){var t=this,o=t.current,i=o.index,a=t.$refs.container,s=t.$refs.caption,r=o.opts.caption;o.$slide.trigger("refresh"),r&&r.length?(t.$caption=s,s.children().eq(0).html(r)):t.$caption=null,t.hasHiddenControls||t.isIdle||t.showControls(),a.find("[data-fancybox-count]").html(t.group.length),a.find("[data-fancybox-index]").html(i+1),a.find("[data-fancybox-prev]").prop("disabled",!o.opts.loop&&i<=0),a.find("[data-fancybox-next]").prop("disabled",!o.opts.loop&&i>=t.group.length-1),"image"===o.type?a.find("[data-fancybox-zoom]").show().end().find("[data-fancybox-download]").attr("href",o.opts.image.src||o.src).show():o.opts.toolbar&&a.find("[data-fancybox-download],[data-fancybox-zoom]").hide(),n(e.activeElement).is(":hidden,[disabled]")&&t.$refs.container.trigger("focus")},hideControls:function(t){var e=this,n=["infobar","toolbar","nav"];!t&&e.current.opts.preventCaptionOverlap||n.push("caption"),this.$refs.container.removeClass(n.map(function(t){return"fancybox-show-"+t}).join(" ")),this.hasHiddenControls=!0},showControls:function(){var t=this,e=t.current?t.current.opts:t.opts,n=t.$refs.container;t.hasHiddenControls=!1,t.idleSecondsCounter=0,n.toggleClass("fancybox-show-toolbar",!(!e.toolbar||!e.buttons)).toggleClass("fancybox-show-infobar",!!(e.infobar&&t.group.length>1)).toggleClass("fancybox-show-caption",!!t.$caption).toggleClass("fancybox-show-nav",!!(e.arrows&&t.group.length>1)).toggleClass("fancybox-is-modal",!!e.modal)},toggleControls:function(){this.hasHiddenControls?this.showControls():this.hideControls()}}),n.fancybox={version:"3.5.7",defaults:a,getInstance:function(t){var e=n('.fancybox-container:not(".fancybox-is-closing"):last').data("FancyBox"),o=Array.prototype.slice.call(arguments,1);return e instanceof b&&("string"===n.type(t)?e[t].apply(e,o):"function"===n.type(t)&&t.apply(e,o),e)},open:function(t,e,n){return new b(t,e,n)},close:function(t){var e=this.getInstance();e&&(e.close(),!0===t&&this.close(t))},destroy:function(){this.close(!0),r.add("body").off("click.fb-start","**")},isMobile:/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),use3d:function(){var n=e.createElement("div");return t.getComputedStyle&&t.getComputedStyle(n)&&t.getComputedStyle(n).getPropertyValue("transform")&&!(e.documentMode&&e.documentMode<11)}(),getTranslate:function(t){var e;return!(!t||!t.length)&&(e=t[0].getBoundingClientRect(),{top:e.top||0,left:e.left||0,width:e.width,height:e.height,opacity:parseFloat(t.css("opacity"))})},setTranslate:function(t,e){var n="",o={};if(t&&e)return void 0===e.left&&void 0===e.top||(n=(void 0===e.left?t.position().left:e.left)+"px, "+(void 0===e.top?t.position().top:e.top)+"px",n=this.use3d?"translate3d("+n+", 0px)":"translate("+n+")"),void 0!==e.scaleX&&void 0!==e.scaleY?n+=" scale("+e.scaleX+", "+e.scaleY+")":void 0!==e.scaleX&&(n+=" scaleX("+e.scaleX+")"),n.length&&(o.transform=n),void 0!==e.opacity&&(o.opacity=e.opacity),void 0!==e.width&&(o.width=e.width),void 0!==e.height&&(o.height=e.height),t.css(o)},animate:function(t,e,o,i,a){var s,r=this;n.isFunction(o)&&(i=o,o=null),r.stop(t),s=r.getTranslate(t),t.on(f,function(c){(!c||!c.originalEvent||t.is(c.originalEvent.target)&&"z-index"!=c.originalEvent.propertyName)&&(r.stop(t),n.isNumeric(o)&&t.css("transition-duration",""),n.isPlainObject(e)?void 0!==e.scaleX&&void 0!==e.scaleY&&r.setTranslate(t,{top:e.top,left:e.left,width:s.width*e.scaleX,height:s.height*e.scaleY,scaleX:1,scaleY:1}):!0!==a&&t.removeClass(e),n.isFunction(i)&&i(c))}),n.isNumeric(o)&&t.css("transition-duration",o+"ms"),n.isPlainObject(e)?(void 0!==e.scaleX&&void 0!==e.scaleY&&(delete e.width,delete e.height,t.parent().hasClass("fancybox-slide--image")&&t.parent().addClass("fancybox-is-scaling")),n.fancybox.setTranslate(t,e)):t.addClass(e),t.data("timer",setTimeout(function(){t.trigger(f)},o+33))},stop:function(t,e){t&&t.length&&(clearTimeout(t.data("timer")),e&&t.trigger(f),t.off(f).css("transition-duration",""),t.parent().removeClass("fancybox-is-scaling"))}},n.fn.fancybox=function(t){var e;return t=t||{},e=t.selector||!1,e?n("body").off("click.fb-start",e).on("click.fb-start",e,{options:t},i):this.off("click.fb-start").on("click.fb-start",{items:this,options:t},i),this},r.on("click.fb-start","[data-fancybox]",i),r.on("click.fb-start","[data-fancybox-trigger]",function(t){n('[data-fancybox="'+n(this).attr("data-fancybox-trigger")+'"]').eq(n(this).attr("data-fancybox-index")||0).trigger("click.fb-start",{$trigger:n(this)})}),function(){var t=null;r.on("mousedown mouseup focus blur",".fancybox-button",function(e){switch(e.type){case"mousedown":t=n(this);break;case"mouseup":t=null;break;case"focusin":n(".fancybox-button").removeClass("fancybox-focus"),n(this).is(t)||n(this).is("[disabled]")||n(this).addClass("fancybox-focus");break;case"focusout":n(".fancybox-button").removeClass("fancybox-focus")}})}()}}(window,document,jQuery),function(t){"use strict";var e={youtube:{matcher:/(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i,params:{autoplay:1,autohide:1,fs:1,rel:0,hd:1,wmode:"transparent",enablejsapi:1,html5:1},paramPlace:8,type:"iframe",url:"https://www.youtube-nocookie.com/embed/$4",thumb:"https://img.youtube.com/vi/$4/hqdefault.jpg"},vimeo:{matcher:/^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/,params:{autoplay:1,hd:1,show_title:1,show_byline:1,show_portrait:0,fullscreen:1},paramPlace:3,type:"iframe",url:"//player.vimeo.com/video/$2"},instagram:{matcher:/(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,type:"image",url:"//$1/p/$2/media/?size=l"},gmap_place:{matcher:/(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(((maps\/(place\/(.*)\/)?\@(.*),(\d+.?\d+?)z))|(\?ll=))(.*)?/i,type:"iframe",url:function(t){return"//maps.google."+t[2]+"/?ll="+(t[9]?t[9]+"&z="+Math.floor(t[10])+(t[12]?t[12].replace(/^\//,"&"):""):t[12]+"").replace(/\?/,"&")+"&output="+(t[12]&&t[12].indexOf("layer=c")>0?"svembed":"embed")}},gmap_search:{matcher:/(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(maps\/search\/)(.*)/i,type:"iframe",url:function(t){return"//maps.google."+t[2]+"/maps?q="+t[5].replace("query=","q=").replace("api=1","")+"&output=embed"}}},n=function(e,n,o){if(e)return o=o||"","object"===t.type(o)&&(o=t.param(o,!0)),t.each(n,function(t,n){e=e.replace("$"+t,n||"")}),o.length&&(e+=(e.indexOf("?")>0?"&":"?")+o),e};t(document).on("objectNeedsType.fb",function(o,i,a){var s,r,c,l,d,u,f,p=a.src||"",h=!1;s=t.extend(!0,{},e,a.opts.media),t.each(s,function(e,o){if(c=p.match(o.matcher)){if(h=o.type,f=e,u={},o.paramPlace&&c[o.paramPlace]){d=c[o.paramPlace],"?"==d[0]&&(d=d.substring(1)),d=d.split("&");for(var i=0;i<d.length;++i){var s=d[i].split("=",2);2==s.length&&(u[s[0]]=decodeURIComponent(s[1].replace(/\+/g," ")))}}return l=t.extend(!0,{},o.params,a.opts[e],u),p="function"===t.type(o.url)?o.url.call(this,c,l,a):n(o.url,c,l),r="function"===t.type(o.thumb)?o.thumb.call(this,c,l,a):n(o.thumb,c),"youtube"===e?p=p.replace(/&t=((\d+)m)?(\d+)s/,function(t,e,n,o){return"&start="+((n?60*parseInt(n,10):0)+parseInt(o,10))}):"vimeo"===e&&(p=p.replace("&%23","#")),!1}}),h?(a.opts.thumb||a.opts.$thumb&&a.opts.$thumb.length||(a.opts.thumb=r),"iframe"===h&&(a.opts=t.extend(!0,a.opts,{iframe:{preload:!1,attr:{scrolling:"no"}}})),t.extend(a,{type:h,src:p,origSrc:a.src,contentSource:f,contentType:"image"===h?"image":"gmap_place"==f||"gmap_search"==f?"map":"video"})):p&&(a.type=a.opts.defaultType)});var o={youtube:{src:"https://www.youtube.com/iframe_api",class:"YT",loading:!1,loaded:!1},vimeo:{src:"https://player.vimeo.com/api/player.js",class:"Vimeo",loading:!1,loaded:!1},load:function(t){var e,n=this;if(this[t].loaded)return void setTimeout(function(){n.done(t)});this[t].loading||(this[t].loading=!0,e=document.createElement("script"),e.type="text/javascript",e.src=this[t].src,"youtube"===t?window.onYouTubeIframeAPIReady=function(){n[t].loaded=!0,n.done(t)}:e.onload=function(){n[t].loaded=!0,n.done(t)},document.body.appendChild(e))},done:function(e){var n,o,i;"youtube"===e&&delete window.onYouTubeIframeAPIReady,(n=t.fancybox.getInstance())&&(o=n.current.$content.find("iframe"),"youtube"===e&&void 0!==YT&&YT?i=new YT.Player(o.attr("id"),{events:{onStateChange:function(t){0==t.data&&n.next()}}}):"vimeo"===e&&void 0!==Vimeo&&Vimeo&&(i=new Vimeo.Player(o),i.on("ended",function(){n.next()})))}};t(document).on({"afterShow.fb":function(t,e,n){e.group.length>1&&("youtube"===n.contentSource||"vimeo"===n.contentSource)&&o.load(n.contentSource)}})}(jQuery),function(t,e,n){"use strict";var o=function(){return t.requestAnimationFrame||t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||t.oRequestAnimationFrame||function(e){return t.setTimeout(e,1e3/60)}}(),i=function(){return t.cancelAnimationFrame||t.webkitCancelAnimationFrame||t.mozCancelAnimationFrame||t.oCancelAnimationFrame||function(e){t.clearTimeout(e)}}(),a=function(e){var n=[];e=e.originalEvent||e||t.e,e=e.touches&&e.touches.length?e.touches:e.changedTouches&&e.changedTouches.length?e.changedTouches:[e];for(var o in e)e[o].pageX?n.push({x:e[o].pageX,y:e[o].pageY}):e[o].clientX&&n.push({x:e[o].clientX,y:e[o].clientY});return n},s=function(t,e,n){return e&&t?"x"===n?t.x-e.x:"y"===n?t.y-e.y:Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2)):0},r=function(t){if(t.is('a,area,button,[role="button"],input,label,select,summary,textarea,video,audio,iframe')||n.isFunction(t.get(0).onclick)||t.data("selectable"))return!0;for(var e=0,o=t[0].attributes,i=o.length;e<i;e++)if("data-fancybox-"===o[e].nodeName.substr(0,14))return!0;return!1},c=function(e){var n=t.getComputedStyle(e)["overflow-y"],o=t.getComputedStyle(e)["overflow-x"],i=("scroll"===n||"auto"===n)&&e.scrollHeight>e.clientHeight,a=("scroll"===o||"auto"===o)&&e.scrollWidth>e.clientWidth;return i||a},l=function(t){for(var e=!1;;){if(e=c(t.get(0)))break;if(t=t.parent(),!t.length||t.hasClass("fancybox-stage")||t.is("body"))break}return e},d=function(t){var e=this;e.instance=t,e.$bg=t.$refs.bg,e.$stage=t.$refs.stage,e.$container=t.$refs.container,e.destroy(),e.$container.on("touchstart.fb.touch mousedown.fb.touch",n.proxy(e,"ontouchstart"))};d.prototype.destroy=function(){var t=this;t.$container.off(".fb.touch"),n(e).off(".fb.touch"),t.requestId&&(i(t.requestId),t.requestId=null),t.tapped&&(clearTimeout(t.tapped),t.tapped=null)},d.prototype.ontouchstart=function(o){var i=this,c=n(o.target),d=i.instance,u=d.current,f=u.$slide,p=u.$content,h="touchstart"==o.type;if(h&&i.$container.off("mousedown.fb.touch"),(!o.originalEvent||2!=o.originalEvent.button)&&f.length&&c.length&&!r(c)&&!r(c.parent())&&(c.is("img")||!(o.originalEvent.clientX>c[0].clientWidth+c.offset().left))){if(!u||d.isAnimating||u.$slide.hasClass("fancybox-animated"))return o.stopPropagation(),void o.preventDefault();i.realPoints=i.startPoints=a(o),i.startPoints.length&&(u.touch&&o.stopPropagation(),i.startEvent=o,i.canTap=!0,i.$target=c,i.$content=p,i.opts=u.opts.touch,i.isPanning=!1,i.isSwiping=!1,i.isZooming=!1,i.isScrolling=!1,i.canPan=d.canPan(),i.startTime=(new Date).getTime(),i.distanceX=i.distanceY=i.distance=0,i.canvasWidth=Math.round(f[0].clientWidth),i.canvasHeight=Math.round(f[0].clientHeight),i.contentLastPos=null,i.contentStartPos=n.fancybox.getTranslate(i.$content)||{top:0,left:0},i.sliderStartPos=n.fancybox.getTranslate(f),i.stagePos=n.fancybox.getTranslate(d.$refs.stage),i.sliderStartPos.top-=i.stagePos.top,i.sliderStartPos.left-=i.stagePos.left,i.contentStartPos.top-=i.stagePos.top,i.contentStartPos.left-=i.stagePos.left,n(e).off(".fb.touch").on(h?"touchend.fb.touch touchcancel.fb.touch":"mouseup.fb.touch mouseleave.fb.touch",n.proxy(i,"ontouchend")).on(h?"touchmove.fb.touch":"mousemove.fb.touch",n.proxy(i,"ontouchmove")),n.fancybox.isMobile&&e.addEventListener("scroll",i.onscroll,!0),((i.opts||i.canPan)&&(c.is(i.$stage)||i.$stage.find(c).length)||(c.is(".fancybox-image")&&o.preventDefault(),n.fancybox.isMobile&&c.parents(".fancybox-caption").length))&&(i.isScrollable=l(c)||l(c.parent()),n.fancybox.isMobile&&i.isScrollable||o.preventDefault(),(1===i.startPoints.length||u.hasError)&&(i.canPan?(n.fancybox.stop(i.$content),i.isPanning=!0):i.isSwiping=!0,i.$container.addClass("fancybox-is-grabbing")),2===i.startPoints.length&&"image"===u.type&&(u.isLoaded||u.$ghost)&&(i.canTap=!1,i.isSwiping=!1,i.isPanning=!1,i.isZooming=!0,n.fancybox.stop(i.$content),i.centerPointStartX=.5*(i.startPoints[0].x+i.startPoints[1].x)-n(t).scrollLeft(),i.centerPointStartY=.5*(i.startPoints[0].y+i.startPoints[1].y)-n(t).scrollTop(),i.percentageOfImageAtPinchPointX=(i.centerPointStartX-i.contentStartPos.left)/i.contentStartPos.width,i.percentageOfImageAtPinchPointY=(i.centerPointStartY-i.contentStartPos.top)/i.contentStartPos.height,i.startDistanceBetweenFingers=s(i.startPoints[0],i.startPoints[1]))))}},d.prototype.onscroll=function(t){var n=this;n.isScrolling=!0,e.removeEventListener("scroll",n.onscroll,!0)},d.prototype.ontouchmove=function(t){var e=this;return void 0!==t.originalEvent.buttons&&0===t.originalEvent.buttons?void e.ontouchend(t):e.isScrolling?void(e.canTap=!1):(e.newPoints=a(t),void((e.opts||e.canPan)&&e.newPoints.length&&e.newPoints.length&&(e.isSwiping&&!0===e.isSwiping||t.preventDefault(),e.distanceX=s(e.newPoints[0],e.startPoints[0],"x"),e.distanceY=s(e.newPoints[0],e.startPoints[0],"y"),e.distance=s(e.newPoints[0],e.startPoints[0]),e.distance>0&&(e.isSwiping?e.onSwipe(t):e.isPanning?e.onPan():e.isZooming&&e.onZoom()))))},d.prototype.onSwipe=function(e){var a,s=this,r=s.instance,c=s.isSwiping,l=s.sliderStartPos.left||0;if(!0!==c)"x"==c&&(s.distanceX>0&&(s.instance.group.length<2||0===s.instance.current.index&&!s.instance.current.opts.loop)?l+=Math.pow(s.distanceX,.8):s.distanceX<0&&(s.instance.group.length<2||s.instance.current.index===s.instance.group.length-1&&!s.instance.current.opts.loop)?l-=Math.pow(-s.distanceX,.8):l+=s.distanceX),s.sliderLastPos={top:"x"==c?0:s.sliderStartPos.top+s.distanceY,left:l},s.requestId&&(i(s.requestId),s.requestId=null),s.requestId=o(function(){s.sliderLastPos&&(n.each(s.instance.slides,function(t,e){var o=e.pos-s.instance.currPos;n.fancybox.setTranslate(e.$slide,{top:s.sliderLastPos.top,left:s.sliderLastPos.left+o*s.canvasWidth+o*e.opts.gutter})}),s.$container.addClass("fancybox-is-sliding"))});else if(Math.abs(s.distance)>10){if(s.canTap=!1,r.group.length<2&&s.opts.vertical?s.isSwiping="y":r.isDragging||!1===s.opts.vertical||"auto"===s.opts.vertical&&n(t).width()>800?s.isSwiping="x":(a=Math.abs(180*Math.atan2(s.distanceY,s.distanceX)/Math.PI),s.isSwiping=a>45&&a<135?"y":"x"),"y"===s.isSwiping&&n.fancybox.isMobile&&s.isScrollable)return void(s.isScrolling=!0);r.isDragging=s.isSwiping,s.startPoints=s.newPoints,n.each(r.slides,function(t,e){var o,i;n.fancybox.stop(e.$slide),o=n.fancybox.getTranslate(e.$slide),i=n.fancybox.getTranslate(r.$refs.stage),e.$slide.css({transform:"",opacity:"","transition-duration":""}).removeClass("fancybox-animated").removeClass(function(t,e){return(e.match(/(^|\s)fancybox-fx-\S+/g)||[]).join(" ")}),e.pos===r.current.pos&&(s.sliderStartPos.top=o.top-i.top,s.sliderStartPos.left=o.left-i.left),n.fancybox.setTranslate(e.$slide,{top:o.top-i.top,left:o.left-i.left})}),r.SlideShow&&r.SlideShow.isActive&&r.SlideShow.stop()}},d.prototype.onPan=function(){var t=this;if(s(t.newPoints[0],t.realPoints[0])<(n.fancybox.isMobile?10:5))return void(t.startPoints=t.newPoints);t.canTap=!1,t.contentLastPos=t.limitMovement(),t.requestId&&i(t.requestId),t.requestId=o(function(){n.fancybox.setTranslate(t.$content,t.contentLastPos)})},d.prototype.limitMovement=function(){var t,e,n,o,i,a,s=this,r=s.canvasWidth,c=s.canvasHeight,l=s.distanceX,d=s.distanceY,u=s.contentStartPos,f=u.left,p=u.top,h=u.width,g=u.height;return i=h>r?f+l:f,a=p+d,t=Math.max(0,.5*r-.5*h),e=Math.max(0,.5*c-.5*g),n=Math.min(r-h,.5*r-.5*h),o=Math.min(c-g,.5*c-.5*g),l>0&&i>t&&(i=t-1+Math.pow(-t+f+l,.8)||0),l<0&&i<n&&(i=n+1-Math.pow(n-f-l,.8)||0),d>0&&a>e&&(a=e-1+Math.pow(-e+p+d,.8)||0),d<0&&a<o&&(a=o+1-Math.pow(o-p-d,.8)||0),{top:a,left:i}},d.prototype.limitPosition=function(t,e,n,o){var i=this,a=i.canvasWidth,s=i.canvasHeight;return n>a?(t=t>0?0:t,t=t<a-n?a-n:t):t=Math.max(0,a/2-n/2),o>s?(e=e>0?0:e,e=e<s-o?s-o:e):e=Math.max(0,s/2-o/2),{top:e,left:t}},d.prototype.onZoom=function(){var e=this,a=e.contentStartPos,r=a.width,c=a.height,l=a.left,d=a.top,u=s(e.newPoints[0],e.newPoints[1]),f=u/e.startDistanceBetweenFingers,p=Math.floor(r*f),h=Math.floor(c*f),g=(r-p)*e.percentageOfImageAtPinchPointX,b=(c-h)*e.percentageOfImageAtPinchPointY,m=(e.newPoints[0].x+e.newPoints[1].x)/2-n(t).scrollLeft(),v=(e.newPoints[0].y+e.newPoints[1].y)/2-n(t).scrollTop(),y=m-e.centerPointStartX,x=v-e.centerPointStartY,w=l+(g+y),$=d+(b+x),S={top:$,left:w,scaleX:f,scaleY:f};e.canTap=!1,e.newWidth=p,e.newHeight=h,e.contentLastPos=S,e.requestId&&i(e.requestId),e.requestId=o(function(){n.fancybox.setTranslate(e.$content,e.contentLastPos)})},d.prototype.ontouchend=function(t){var o=this,s=o.isSwiping,r=o.isPanning,c=o.isZooming,l=o.isScrolling;if(o.endPoints=a(t),o.dMs=Math.max((new Date).getTime()-o.startTime,1),o.$container.removeClass("fancybox-is-grabbing"),n(e).off(".fb.touch"),e.removeEventListener("scroll",o.onscroll,!0),o.requestId&&(i(o.requestId),o.requestId=null),o.isSwiping=!1,o.isPanning=!1,o.isZooming=!1,o.isScrolling=!1,o.instance.isDragging=!1,o.canTap)return o.onTap(t);o.speed=100,o.velocityX=o.distanceX/o.dMs*.5,o.velocityY=o.distanceY/o.dMs*.5,r?o.endPanning():c?o.endZooming():o.endSwiping(s,l)},d.prototype.endSwiping=function(t,e){var o=this,i=!1,a=o.instance.group.length,s=Math.abs(o.distanceX),r="x"==t&&a>1&&(o.dMs>130&&s>10||s>50);o.sliderLastPos=null,"y"==t&&!e&&Math.abs(o.distanceY)>50?(n.fancybox.animate(o.instance.current.$slide,{top:o.sliderStartPos.top+o.distanceY+150*o.velocityY,opacity:0},200),i=o.instance.close(!0,250)):r&&o.distanceX>0?i=o.instance.previous(300):r&&o.distanceX<0&&(i=o.instance.next(300)),!1!==i||"x"!=t&&"y"!=t||o.instance.centerSlide(200),o.$container.removeClass("fancybox-is-sliding")},d.prototype.endPanning=function(){var t,e,o,i=this;i.contentLastPos&&(!1===i.opts.momentum||i.dMs>350?(t=i.contentLastPos.left,e=i.contentLastPos.top):(t=i.contentLastPos.left+500*i.velocityX,e=i.contentLastPos.top+500*i.velocityY),o=i.limitPosition(t,e,i.contentStartPos.width,i.contentStartPos.height),o.width=i.contentStartPos.width,o.height=i.contentStartPos.height,n.fancybox.animate(i.$content,o,366))},d.prototype.endZooming=function(){var t,e,o,i,a=this,s=a.instance.current,r=a.newWidth,c=a.newHeight;a.contentLastPos&&(t=a.contentLastPos.left,e=a.contentLastPos.top,i={top:e,left:t,width:r,height:c,scaleX:1,scaleY:1},n.fancybox.setTranslate(a.$content,i),r<a.canvasWidth&&c<a.canvasHeight?a.instance.scaleToFit(150):r>s.width||c>s.height?a.instance.scaleToActual(a.centerPointStartX,a.centerPointStartY,150):(o=a.limitPosition(t,e,r,c),n.fancybox.animate(a.$content,o,150)))},d.prototype.onTap=function(e){var o,i=this,s=n(e.target),r=i.instance,c=r.current,l=e&&a(e)||i.startPoints,d=l[0]?l[0].x-n(t).scrollLeft()-i.stagePos.left:0,u=l[0]?l[0].y-n(t).scrollTop()-i.stagePos.top:0,f=function(t){var o=c.opts[t];if(n.isFunction(o)&&(o=o.apply(r,[c,e])),o)switch(o){case"close":r.close(i.startEvent);break;case"toggleControls":r.toggleControls();break;case"next":r.next();break;case"nextOrClose":r.group.length>1?r.next():r.close(i.startEvent);break;case"zoom":"image"==c.type&&(c.isLoaded||c.$ghost)&&(r.canPan()?r.scaleToFit():r.isScaledDown()?r.scaleToActual(d,u):r.group.length<2&&r.close(i.startEvent))}};if((!e.originalEvent||2!=e.originalEvent.button)&&(s.is("img")||!(d>s[0].clientWidth+s.offset().left))){if(s.is(".fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container"))o="Outside";else if(s.is(".fancybox-slide"))o="Slide";else{if(!r.current.$content||!r.current.$content.find(s).addBack().filter(s).length)return;o="Content"}if(i.tapped){if(clearTimeout(i.tapped),i.tapped=null,Math.abs(d-i.tapX)>50||Math.abs(u-i.tapY)>50)return this;f("dblclick"+o)}else i.tapX=d,i.tapY=u,c.opts["dblclick"+o]&&c.opts["dblclick"+o]!==c.opts["click"+o]?i.tapped=setTimeout(function(){i.tapped=null,r.isAnimating||f("click"+o)},500):f("click"+o);return this}},n(e).on("onActivate.fb",function(t,e){e&&!e.Guestures&&(e.Guestures=new d(e))}).on("beforeClose.fb",function(t,e){e&&e.Guestures&&e.Guestures.destroy()})}(window,document,jQuery),function(t,e){"use strict";e.extend(!0,e.fancybox.defaults,{btnTpl:{slideShow:'<button data-fancybox-play class="fancybox-button fancybox-button--play" title="{{PLAY_START}}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.5 5.4v13.2l11-6.6z"/></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.33 5.75h2.2v12.5h-2.2V5.75zm5.15 0h2.2v12.5h-2.2V5.75z"/></svg></button>'},slideShow:{autoStart:!1,speed:3e3,progress:!0}});var n=function(t){this.instance=t,this.init()};e.extend(n.prototype,{timer:null,isActive:!1,$button:null,init:function(){var t=this,n=t.instance,o=n.group[n.currIndex].opts.slideShow;t.$button=n.$refs.toolbar.find("[data-fancybox-play]").on("click",function(){t.toggle()}),n.group.length<2||!o?t.$button.hide():o.progress&&(t.$progress=e('<div class="fancybox-progress"></div>').appendTo(n.$refs.inner))},set:function(t){var n=this,o=n.instance,i=o.current;i&&(!0===t||i.opts.loop||o.currIndex<o.group.length-1)?n.isActive&&"video"!==i.contentType&&(n.$progress&&e.fancybox.animate(n.$progress.show(),{scaleX:1},i.opts.slideShow.speed),n.timer=setTimeout(function(){o.current.opts.loop||o.current.index!=o.group.length-1?o.next():o.jumpTo(0)},i.opts.slideShow.speed)):(n.stop(),o.idleSecondsCounter=0,o.showControls())},clear:function(){var t=this;clearTimeout(t.timer),t.timer=null,t.$progress&&t.$progress.removeAttr("style").hide()},start:function(){var t=this,e=t.instance.current;e&&(t.$button.attr("title",(e.opts.i18n[e.opts.lang]||e.opts.i18n.en).PLAY_STOP).removeClass("fancybox-button--play").addClass("fancybox-button--pause"),t.isActive=!0,e.isComplete&&t.set(!0),t.instance.trigger("onSlideShowChange",!0))},stop:function(){var t=this,e=t.instance.current;t.clear(),t.$button.attr("title",(e.opts.i18n[e.opts.lang]||e.opts.i18n.en).PLAY_START).removeClass("fancybox-button--pause").addClass("fancybox-button--play"),t.isActive=!1,t.instance.trigger("onSlideShowChange",!1),t.$progress&&t.$progress.removeAttr("style").hide()},toggle:function(){var t=this;t.isActive?t.stop():t.start()}}),e(t).on({"onInit.fb":function(t,e){e&&!e.SlideShow&&(e.SlideShow=new n(e))},"beforeShow.fb":function(t,e,n,o){var i=e&&e.SlideShow;o?i&&n.opts.slideShow.autoStart&&i.start():i&&i.isActive&&i.clear()},"afterShow.fb":function(t,e,n){var o=e&&e.SlideShow;o&&o.isActive&&o.set()},"afterKeydown.fb":function(n,o,i,a,s){var r=o&&o.SlideShow;!r||!i.opts.slideShow||80!==s&&32!==s||e(t.activeElement).is("button,a,input")||(a.preventDefault(),r.toggle())},"beforeClose.fb onDeactivate.fb":function(t,e){var n=e&&e.SlideShow;n&&n.stop()}}),e(t).on("visibilitychange",function(){var n=e.fancybox.getInstance(),o=n&&n.SlideShow;o&&o.isActive&&(t.hidden?o.clear():o.set())})}(document,jQuery),function(t,e){"use strict";var n=function(){for(var e=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],n={},o=0;o<e.length;o++){var i=e[o];if(i&&i[1]in t){for(var a=0;a<i.length;a++)n[e[0][a]]=i[a];return n}}return!1}();if(n){var o={request:function(e){e=e||t.documentElement,e[n.requestFullscreen](e.ALLOW_KEYBOARD_INPUT)},exit:function(){t[n.exitFullscreen]()},toggle:function(e){e=e||t.documentElement,this.isFullscreen()?this.exit():this.request(e)},isFullscreen:function(){return Boolean(t[n.fullscreenElement])},enabled:function(){return Boolean(t[n.fullscreenEnabled])}};e.extend(!0,e.fancybox.defaults,{btnTpl:{fullScreen:'<button data-fancybox-fullscreen class="fancybox-button fancybox-button--fsenter" title="{{FULL_SCREEN}}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 16h3v3h2v-5H5zm3-8H5v2h5V5H8zm6 11h2v-3h3v-2h-5zm2-11V5h-2v5h5V8z"/></svg></button>'},fullScreen:{autoStart:!1}}),e(t).on(n.fullscreenchange,function(){var t=o.isFullscreen(),n=e.fancybox.getInstance();n&&(n.current&&"image"===n.current.type&&n.isAnimating&&(n.isAnimating=!1,n.update(!0,!0,0),n.isComplete||n.complete()),n.trigger("onFullscreenChange",t),n.$refs.container.toggleClass("fancybox-is-fullscreen",t),n.$refs.toolbar.find("[data-fancybox-fullscreen]").toggleClass("fancybox-button--fsenter",!t).toggleClass("fancybox-button--fsexit",t))})}e(t).on({"onInit.fb":function(t,e){var i;if(!n)return void e.$refs.toolbar.find("[data-fancybox-fullscreen]").remove();e&&e.group[e.currIndex].opts.fullScreen?(i=e.$refs.container,i.on("click.fb-fullscreen","[data-fancybox-fullscreen]",function(t){t.stopPropagation(),t.preventDefault(),o.toggle()}),e.opts.fullScreen&&!0===e.opts.fullScreen.autoStart&&o.request(),e.FullScreen=o):e&&e.$refs.toolbar.find("[data-fancybox-fullscreen]").hide()},"afterKeydown.fb":function(t,e,n,o,i){e&&e.FullScreen&&70===i&&(o.preventDefault(),e.FullScreen.toggle())},"beforeClose.fb":function(t,e){e&&e.FullScreen&&e.$refs.container.hasClass("fancybox-is-fullscreen")&&o.exit()}})}(document,jQuery),function(t,e){"use strict";var n="fancybox-thumbs";e.fancybox.defaults=e.extend(!0,{btnTpl:{thumbs:'<button data-fancybox-thumbs class="fancybox-button fancybox-button--thumbs" title="{{THUMBS}}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14.59 14.59h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76H5.65V5.65z"/></svg></button>'},thumbs:{autoStart:!1,hideOnClose:!0,parentEl:".fancybox-container",axis:"y"}},e.fancybox.defaults);var o=function(t){this.init(t)};e.extend(o.prototype,{$button:null,$grid:null,$list:null,isVisible:!1,isActive:!1,init:function(t){var e=this,n=t.group,o=0;e.instance=t,e.opts=n[t.currIndex].opts.thumbs,t.Thumbs=e,e.$button=t.$refs.toolbar.find("[data-fancybox-thumbs]");for(var i=0,a=n.length;i<a&&(n[i].thumb&&o++,!(o>1));i++);o>1&&e.opts?(e.$button.removeAttr("style").on("click",function(){e.toggle()}),e.isActive=!0):e.$button.hide()},create:function(){var t,o=this,i=o.instance,a=o.opts.parentEl,s=[];o.$grid||(o.$grid=e('<div class="'+n+" "+n+"-"+o.opts.axis+'"></div>').appendTo(i.$refs.container.find(a).addBack().filter(a)),o.$grid.on("click","a",function(){i.jumpTo(e(this).attr("data-index"))})),o.$list||(o.$list=e('<div class="'+n+'__list">').appendTo(o.$grid)),e.each(i.group,function(e,n){t=n.thumb,t||"image"!==n.type||(t=n.src),s.push('<a href="javascript:;" tabindex="0" data-index="'+e+'"'+(t&&t.length?' style="background-image:url('+t+')"':'class="fancybox-thumbs-missing"')+"></a>")}),o.$list[0].innerHTML=s.join(""),"x"===o.opts.axis&&o.$list.width(parseInt(o.$grid.css("padding-right"),10)+i.group.length*o.$list.children().eq(0).outerWidth(!0))},focus:function(t){var e,n,o=this,i=o.$list,a=o.$grid;o.instance.current&&(e=i.children().removeClass("fancybox-thumbs-active").filter('[data-index="'+o.instance.current.index+'"]').addClass("fancybox-thumbs-active"),n=e.position(),"y"===o.opts.axis&&(n.top<0||n.top>i.height()-e.outerHeight())?i.stop().animate({scrollTop:i.scrollTop()+n.top},t):"x"===o.opts.axis&&(n.left<a.scrollLeft()||n.left>a.scrollLeft()+(a.width()-e.outerWidth()))&&i.parent().stop().animate({scrollLeft:n.left},t))},update:function(){var t=this;t.instance.$refs.container.toggleClass("fancybox-show-thumbs",this.isVisible),t.isVisible?(t.$grid||t.create(),t.instance.trigger("onThumbsShow"),t.focus(0)):t.$grid&&t.instance.trigger("onThumbsHide"),t.instance.update()},hide:function(){this.isVisible=!1,this.update()},show:function(){this.isVisible=!0,this.update()},toggle:function(){this.isVisible=!this.isVisible,this.update()}}),e(t).on({"onInit.fb":function(t,e){var n;e&&!e.Thumbs&&(n=new o(e),n.isActive&&!0===n.opts.autoStart&&n.show())},"beforeShow.fb":function(t,e,n,o){var i=e&&e.Thumbs;i&&i.isVisible&&i.focus(o?0:250)},"afterKeydown.fb":function(t,e,n,o,i){var a=e&&e.Thumbs;a&&a.isActive&&71===i&&(o.preventDefault(),a.toggle())},"beforeClose.fb":function(t,e){var n=e&&e.Thumbs;n&&n.isVisible&&!1!==n.opts.hideOnClose&&n.$grid.hide()}})}(document,jQuery),function(t,e){"use strict";function n(t){var e={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};return String(t).replace(/[&<>"'`=\/]/g,function(t){return e[t]})}e.extend(!0,e.fancybox.defaults,{btnTpl:{share:'<button data-fancybox-share class="fancybox-button fancybox-button--share" title="{{SHARE}}"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2.55 19c1.4-8.4 9.1-9.8 11.9-9.8V5l7 7-7 6.3v-3.5c-2.8 0-10.5 2.1-11.9 4.2z"/></svg></button>'},share:{url:function(t,e){return!t.currentHash&&"inline"!==e.type&&"html"!==e.type&&(e.origSrc||e.src)||window.location}, 417tpl:'<div class="fancybox-share"><h1>{{SHARE}}</h1><p><a class="fancybox-share__button fancybox-share__button--fb" href="https://www.facebook.com/sharer/sharer.php?u={{url}}"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m287 456v-299c0-21 6-35 35-35h38v-63c-7-1-29-3-55-3-54 0-91 33-91 94v306m143-254h-205v72h196" /></svg><span>Facebook</span></a><a class="fancybox-share__button fancybox-share__button--tw" href="https://twitter.com/intent/tweet?url={{url}}&text={{descr}}"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m456 133c-14 7-31 11-47 13 17-10 30-27 37-46-15 10-34 16-52 20-61-62-157-7-141 75-68-3-129-35-169-85-22 37-11 86 26 109-13 0-26-4-37-9 0 39 28 72 65 80-12 3-25 4-37 2 10 33 41 57 77 57-42 30-77 38-122 34 170 111 378-32 359-208 16-11 30-25 41-42z" /></svg><span>Twitter</span></a><a class="fancybox-share__button fancybox-share__button--pt" href="https://www.pinterest.com/pin/create/button/?url={{url}}&description={{descr}}&media={{media}}"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m265 56c-109 0-164 78-164 144 0 39 15 74 47 87 5 2 10 0 12-5l4-19c2-6 1-8-3-13-9-11-15-25-15-45 0-58 43-110 113-110 62 0 96 38 96 88 0 67-30 122-73 122-24 0-42-19-36-44 6-29 20-60 20-81 0-19-10-35-31-35-25 0-44 26-44 60 0 21 7 36 7 36l-30 125c-8 37-1 83 0 87 0 3 4 4 5 2 2-3 32-39 42-75l16-64c8 16 31 29 56 29 74 0 124-67 124-157 0-69-58-132-146-132z" fill="#fff"/></svg><span>Pinterest</span></a></p><p><input class="fancybox-share__input" type="text" value="{{url_raw}}" onclick="select()" /></p></div>'}}),e(t).on("click","[data-fancybox-share]",function(){var t,o,i=e.fancybox.getInstance(),a=i.current||null;a&&("function"===e.type(a.opts.share.url)&&(t=a.opts.share.url.apply(a,[i,a])),o=a.opts.share.tpl.replace(/\{\{media\}\}/g,"image"===a.type?encodeURIComponent(a.src):"").replace(/\{\{url\}\}/g,encodeURIComponent(t)).replace(/\{\{url_raw\}\}/g,n(t)).replace(/\{\{descr\}\}/g,i.$caption?encodeURIComponent(i.$caption.text()):""),e.fancybox.open({src:i.translate(i,o),type:"html",opts:{touch:!1,animationEffect:!1,afterLoad:function(t,e){i.$refs.container.one("beforeClose.fb",function(){t.close(null,0)}),e.$content.find(".fancybox-share__button").click(function(){return window.open(this.href,"Share","width=550, height=450"),!1})},mobile:{autoFocus:!1}}}))})}(document,jQuery),function(t,e,n){"use strict";function o(){var e=t.location.hash.substr(1),n=e.split("-"),o=n.length>1&&/^\+?\d+$/.test(n[n.length-1])?parseInt(n.pop(-1),10)||1:1,i=n.join("-");return{hash:e,index:o<1?1:o,gallery:i}}function i(t){""!==t.gallery&&n("[data-fancybox='"+n.escapeSelector(t.gallery)+"']").eq(t.index-1).focus().trigger("click.fb-start")}function a(t){var e,n;return!!t&&(e=t.current?t.current.opts:t.opts,""!==(n=e.hash||(e.$orig?e.$orig.data("fancybox")||e.$orig.data("fancybox-trigger"):""))&&n)}n.escapeSelector||(n.escapeSelector=function(t){return(t+"").replace(/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,function(t,e){return e?"\0"===t?"�":t.slice(0,-1)+"\\"+t.charCodeAt(t.length-1).toString(16)+" ":"\\"+t})}),n(function(){!1!==n.fancybox.defaults.hash&&(n(e).on({"onInit.fb":function(t,e){var n,i;!1!==e.group[e.currIndex].opts.hash&&(n=o(),(i=a(e))&&n.gallery&&i==n.gallery&&(e.currIndex=n.index-1))},"beforeShow.fb":function(n,o,i,s){var r;i&&!1!==i.opts.hash&&(r=a(o))&&(o.currentHash=r+(o.group.length>1?"-"+(i.index+1):""),t.location.hash!=="#"+o.currentHash&&(s&&!o.origHash&&(o.origHash=t.location.hash),o.hashTimer&&clearTimeout(o.hashTimer),o.hashTimer=setTimeout(function(){"replaceState"in t.history?(t.history[s?"pushState":"replaceState"]({},e.title,t.location.pathname+t.location.search+"#"+o.currentHash),s&&(o.hasCreatedHistory=!0)):t.location.hash=o.currentHash,o.hashTimer=null},300)))},"beforeClose.fb":function(n,o,i){i&&!1!==i.opts.hash&&(clearTimeout(o.hashTimer),o.currentHash&&o.hasCreatedHistory?t.history.back():o.currentHash&&("replaceState"in t.history?t.history.replaceState({},e.title,t.location.pathname+t.location.search+(o.origHash||"")):t.location.hash=o.origHash),o.currentHash=null)}}),n(t).on("hashchange.fb",function(){var t=o(),e=null;n.each(n(".fancybox-container").get().reverse(),function(t,o){var i=n(o).data("FancyBox");if(i&&i.currentHash)return e=i,!1}),e?e.currentHash===t.gallery+"-"+t.index||1===t.index&&e.currentHash==t.gallery||(e.currentHash=null,e.close()):""!==t.gallery&&i(t)}),setTimeout(function(){n.fancybox.getInstance()||i(o())},50))})}(window,document,jQuery),function(t,e){"use strict";var n=(new Date).getTime();e(t).on({"onInit.fb":function(t,e,o){e.$refs.stage.on("mousewheel DOMMouseScroll wheel MozMousePixelScroll",function(t){var o=e.current,i=(new Date).getTime();e.group.length<2||!1===o.opts.wheel||"auto"===o.opts.wheel&&"image"!==o.type||(t.preventDefault(),t.stopPropagation(),o.$slide.hasClass("fancybox-animated")||(t=t.originalEvent||t,i-n<250||(n=i,e[(-t.deltaY||-t.deltaX||t.wheelDelta||-t.detail)<0?"next":"previous"]())))})}})}(document,jQuery); 418/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 419 420/***/ }), 421
vendor: 6,678 bytes, lines 422-439
422/***/ "./node_modules/imagesloaded/imagesloaded.pkgd.min.js": 423/*!************************************************************!*\ 424 !*** ./node_modules/imagesloaded/imagesloaded.pkgd.min.js ***! 425 \************************************************************/ 426 /*! no static exports found */ 427 /***/ (function(module, exports, __webpack_require__) { 428 429var __WEBPACK_LOCAL_MODULE_0__, __WEBPACK_LOCAL_MODULE_0__factory, __WEBPACK_LOCAL_MODULE_0__module;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 430 * imagesLoaded PACKAGED v4.1.4 431 * JavaScript is all like "You images are done yet or what?" 432 * MIT License 433 */ 434 435 !function(e,t){ true?!(__WEBPACK_LOCAL_MODULE_0__factory = (t), (__WEBPACK_LOCAL_MODULE_0__module = { id: "ev-emitter/ev-emitter", exports: {}, loaded: false }), __WEBPACK_LOCAL_MODULE_0__ = (typeof __WEBPACK_LOCAL_MODULE_0__factory === 'function' ? (__WEBPACK_LOCAL_MODULE_0__factory.call(__WEBPACK_LOCAL_MODULE_0__module.exports, __webpack_require__, __WEBPACK_LOCAL_MODULE_0__module.exports, __WEBPACK_LOCAL_MODULE_0__module)) : __WEBPACK_LOCAL_MODULE_0__factory), (__WEBPACK_LOCAL_MODULE_0__module.loaded = true), __WEBPACK_LOCAL_MODULE_0__ === undefined && (__WEBPACK_LOCAL_MODULE_0__ = __WEBPACK_LOCAL_MODULE_0__module.exports)):undefined}("undefined"!=typeof window?window:this,function(){function e(){}var t=e.prototype;return t.on=function(e,t){if(e&&t){var i=this._events=this._events||{},n=i[e]=i[e]||[];return n.indexOf(t)==-1&&n.push(t),this}},t.once=function(e,t){if(e&&t){this.on(e,t);var i=this._onceEvents=this._onceEvents||{},n=i[e]=i[e]||{};return n[t]=!0,this}},t.off=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){var n=i.indexOf(t);return n!=-1&&i.splice(n,1),this}},t.emitEvent=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){i=i.slice(0),t=t||[];for(var n=this._onceEvents&&this._onceEvents[e],o=0;o<i.length;o++){var r=i[o],s=n&&n[r];s&&(this.off(e,r),delete n[r]),r.apply(this,t)}return this}},t.allOff=function(){delete this._events,delete this._onceEvents},e}),function(e,t){"use strict"; true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__WEBPACK_LOCAL_MODULE_0__], __WEBPACK_AMD_DEFINE_RESULT__ = (function(i){return t(e,i)}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 436 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):undefined}("undefined"!=typeof window?window:this,function(e,t){function i(e,t){for(var i in t)e[i]=t[i];return e}function n(e){if(Array.isArray(e))return e;var t="object"==typeof e&&"number"==typeof e.length;return t?d.call(e):[e]}function o(e,t,r){if(!(this instanceof o))return new o(e,t,r);var s=e;return"string"==typeof e&&(s=document.querySelectorAll(e)),s?(this.elements=n(s),this.options=i({},this.options),"function"==typeof t?r=t:i(this.options,t),r&&this.on("always",r),this.getImages(),h&&(this.jqDeferred=new h.Deferred),void setTimeout(this.check.bind(this))):void a.error("Bad element for imagesLoaded "+(s||e))}function r(e){this.img=e}function s(e,t){this.url=e,this.element=t,this.img=new Image}var h=e.jQuery,a=e.console,d=Array.prototype.slice;o.prototype=Object.create(t.prototype),o.prototype.options={},o.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)},o.prototype.addElementImages=function(e){"IMG"==e.nodeName&&this.addImage(e),this.options.background===!0&&this.addElementBackgroundImages(e);var t=e.nodeType;if(t&&u[t]){for(var i=e.querySelectorAll("img"),n=0;n<i.length;n++){var o=i[n];this.addImage(o)}if("string"==typeof this.options.background){var r=e.querySelectorAll(this.options.background);for(n=0;n<r.length;n++){var s=r[n];this.addElementBackgroundImages(s)}}}};var u={1:!0,9:!0,11:!0};return o.prototype.addElementBackgroundImages=function(e){var t=getComputedStyle(e);if(t)for(var i=/url\((['"])?(.*?)\1\)/gi,n=i.exec(t.backgroundImage);null!==n;){var o=n&&n[2];o&&this.addBackground(o,e),n=i.exec(t.backgroundImage)}},o.prototype.addImage=function(e){var t=new r(e);this.images.push(t)},o.prototype.addBackground=function(e,t){var i=new s(e,t);this.images.push(i)},o.prototype.check=function(){function e(e,i,n){setTimeout(function(){t.progress(e,i,n)})}var t=this;return this.progressedCount=0,this.hasAnyBroken=!1,this.images.length?void this.images.forEach(function(t){t.once("progress",e),t.check()}):void this.complete()},o.prototype.progress=function(e,t,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded,this.emitEvent("progress",[this,e,t]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,e),this.progressedCount==this.images.length&&this.complete(),this.options.debug&&a&&a.log("progress: "+i,e,t)},o.prototype.complete=function(){var e=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(e,[this]),this.emitEvent("always",[this]),this.jqDeferred){var t=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[t](this)}},r.prototype=Object.create(t.prototype),r.prototype.check=function(){var e=this.getIsImageComplete();return e?void this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),void(this.proxyImage.src=this.img.src))},r.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth},r.prototype.confirm=function(e,t){this.isLoaded=e,this.emitEvent("progress",[this,this.img,t])},r.prototype.handleEvent=function(e){var t="on"+e.type;this[t]&&this[t](e)},r.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},r.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},r.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype=Object.create(r.prototype),s.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url;var e=this.getIsImageComplete();e&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},s.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype.confirm=function(e,t){this.isLoaded=e,this.emitEvent("progress",[this,this.element,t])},o.makeJQueryPlugin=function(t){t=t||e.jQuery,t&&(h=t,h.fn.imagesLoaded=function(e,t){var i=new o(this,e,t);return i.jqDeferred.promise(h(this))})},o.makeJQueryPlugin(),o}); 437 438/***/ }), 439
vendor: 38,731 bytes, lines 440-477
440/***/ "./node_modules/isotope-layout/dist/isotope.pkgd.min.js": 441/*!**************************************************************!*\ 442 !*** ./node_modules/isotope-layout/dist/isotope.pkgd.min.js ***! 443 \**************************************************************/ 444 /*! no static exports found */ 445 /***/ (function(module, exports, __webpack_require__) { 446 447var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;var __WEBPACK_LOCAL_MODULE_1__, __WEBPACK_LOCAL_MODULE_1__factory, __WEBPACK_LOCAL_MODULE_1__module;var __WEBPACK_LOCAL_MODULE_2__, __WEBPACK_LOCAL_MODULE_2__factory, __WEBPACK_LOCAL_MODULE_2__module;var __WEBPACK_LOCAL_MODULE_3__, __WEBPACK_LOCAL_MODULE_3__factory, __WEBPACK_LOCAL_MODULE_3__module;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_LOCAL_MODULE_4__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_LOCAL_MODULE_5__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_LOCAL_MODULE_6__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_LOCAL_MODULE_7__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_LOCAL_MODULE_8__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_LOCAL_MODULE_9__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_LOCAL_MODULE_10__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_LOCAL_MODULE_11__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_LOCAL_MODULE_12__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 448 * Isotope PACKAGED v3.0.6 449 * 450 * Licensed GPLv3 for open source use 451 * or Isotope Commercial License for commercial use 452 * 453 * https://isotope.metafizzy.co 454 * Copyright 2010-2018 Metafizzy 455 */ 456 457 !function(t,e){ true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ "jquery")], __WEBPACK_AMD_DEFINE_RESULT__ = (function(i){return e(t,i)}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 458 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):undefined}(window,function(t,e){"use strict";function i(i,s,a){function u(t,e,o){var n,s="$()."+i+'("'+e+'")';return t.each(function(t,u){var h=a.data(u,i);if(!h)return void r(i+" not initialized. Cannot call methods, i.e. "+s);var d=h[e];if(!d||"_"==e.charAt(0))return void r(s+" is not a valid method");var l=d.apply(h,o);n=void 0===n?l:n}),void 0!==n?n:t}function h(t,e){t.each(function(t,o){var n=a.data(o,i);n?(n.option(e),n._init()):(n=new s(o,e),a.data(o,i,n))})}a=a||e||t.jQuery,a&&(s.prototype.option||(s.prototype.option=function(t){a.isPlainObject(t)&&(this.options=a.extend(!0,this.options,t))}),a.fn[i]=function(t){if("string"==typeof t){var e=n.call(arguments,1);return u(this,t,e)}return h(this,t),this},o(a))}function o(t){!t||t&&t.bridget||(t.bridget=i)}var n=Array.prototype.slice,s=t.console,r="undefined"==typeof s?function(){}:function(t){s.error(t)};return o(e||t.jQuery),i}),function(t,e){ true?!(__WEBPACK_LOCAL_MODULE_1__factory = (e), (__WEBPACK_LOCAL_MODULE_1__module = { id: "ev-emitter/ev-emitter", exports: {}, loaded: false }), __WEBPACK_LOCAL_MODULE_1__ = (typeof __WEBPACK_LOCAL_MODULE_1__factory === 'function' ? (__WEBPACK_LOCAL_MODULE_1__factory.call(__WEBPACK_LOCAL_MODULE_1__module.exports, __webpack_require__, __WEBPACK_LOCAL_MODULE_1__module.exports, __WEBPACK_LOCAL_MODULE_1__module)) : __WEBPACK_LOCAL_MODULE_1__factory), (__WEBPACK_LOCAL_MODULE_1__module.loaded = true), __WEBPACK_LOCAL_MODULE_1__ === undefined && (__WEBPACK_LOCAL_MODULE_1__ = __WEBPACK_LOCAL_MODULE_1__module.exports)):undefined}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},o=i[t]=i[t]||[];return o.indexOf(e)==-1&&o.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},o=i[t]=i[t]||{};return o[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var o=i.indexOf(e);return o!=-1&&i.splice(o,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){i=i.slice(0),e=e||[];for(var o=this._onceEvents&&this._onceEvents[t],n=0;n<i.length;n++){var s=i[n],r=o&&o[s];r&&(this.off(t,s),delete o[s]),s.apply(this,e)}return this}},e.allOff=function(){delete this._events,delete this._onceEvents},t}),function(t,e){ true?!(__WEBPACK_LOCAL_MODULE_2__factory = (e), (__WEBPACK_LOCAL_MODULE_2__module = { id: "get-size/get-size", exports: {}, loaded: false }), __WEBPACK_LOCAL_MODULE_2__ = (typeof __WEBPACK_LOCAL_MODULE_2__factory === 'function' ? (__WEBPACK_LOCAL_MODULE_2__factory.call(__WEBPACK_LOCAL_MODULE_2__module.exports, __webpack_require__, __WEBPACK_LOCAL_MODULE_2__module.exports, __WEBPACK_LOCAL_MODULE_2__module)) : __WEBPACK_LOCAL_MODULE_2__factory), (__WEBPACK_LOCAL_MODULE_2__module.loaded = true), __WEBPACK_LOCAL_MODULE_2__ === undefined && (__WEBPACK_LOCAL_MODULE_2__ = __WEBPACK_LOCAL_MODULE_2__module.exports)):undefined}(window,function(){"use strict";function t(t){var e=parseFloat(t),i=t.indexOf("%")==-1&&!isNaN(e);return i&&e}function e(){}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0;e<h;e++){var i=u[e];t[i]=0}return t}function o(t){var e=getComputedStyle(t);return e||a("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See https://bit.ly/getsizebug1"),e}function n(){if(!d){d=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var n=o(e);r=200==Math.round(t(n.width)),s.isBoxSizeOuter=r,i.removeChild(e)}}function s(e){if(n(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var s=o(e);if("none"==s.display)return i();var a={};a.width=e.offsetWidth,a.height=e.offsetHeight;for(var d=a.isBorderBox="border-box"==s.boxSizing,l=0;l<h;l++){var f=u[l],c=s[f],m=parseFloat(c);a[f]=isNaN(m)?0:m}var p=a.paddingLeft+a.paddingRight,y=a.paddingTop+a.paddingBottom,g=a.marginLeft+a.marginRight,v=a.marginTop+a.marginBottom,_=a.borderLeftWidth+a.borderRightWidth,z=a.borderTopWidth+a.borderBottomWidth,I=d&&r,x=t(s.width);x!==!1&&(a.width=x+(I?0:p+_));var S=t(s.height);return S!==!1&&(a.height=S+(I?0:y+z)),a.innerWidth=a.width-(p+_),a.innerHeight=a.height-(y+z),a.outerWidth=a.width+g,a.outerHeight=a.height+v,a}}var r,a="undefined"==typeof console?e:function(t){console.error(t)},u=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],h=u.length,d=!1;return s}),function(t,e){"use strict"; true?!(__WEBPACK_LOCAL_MODULE_3__factory = (e), (__WEBPACK_LOCAL_MODULE_3__module = { id: "desandro-matches-selector/matches-selector", exports: {}, loaded: false }), __WEBPACK_LOCAL_MODULE_3__ = (typeof __WEBPACK_LOCAL_MODULE_3__factory === 'function' ? (__WEBPACK_LOCAL_MODULE_3__factory.call(__WEBPACK_LOCAL_MODULE_3__module.exports, __webpack_require__, __WEBPACK_LOCAL_MODULE_3__module.exports, __WEBPACK_LOCAL_MODULE_3__module)) : __WEBPACK_LOCAL_MODULE_3__factory), (__WEBPACK_LOCAL_MODULE_3__module.loaded = true), __WEBPACK_LOCAL_MODULE_3__ === undefined && (__WEBPACK_LOCAL_MODULE_3__ = __WEBPACK_LOCAL_MODULE_3__module.exports)):undefined}(window,function(){"use strict";var t=function(){var t=window.Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;i<e.length;i++){var o=e[i],n=o+"MatchesSelector";if(t[n])return n}}();return function(e,i){return e[t](i)}}),function(t,e){ true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__WEBPACK_LOCAL_MODULE_3__], __WEBPACK_LOCAL_MODULE_4__ = ((function(i){return e(t,i)}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__))):undefined}(window,function(t,e){var i={};i.extend=function(t,e){for(var i in e)t[i]=e[i];return t},i.modulo=function(t,e){return(t%e+e)%e};var o=Array.prototype.slice;i.makeArray=function(t){if(Array.isArray(t))return t;if(null===t||void 0===t)return[];var e="object"==typeof t&&"number"==typeof t.length;return e?o.call(t):[t]},i.removeFrom=function(t,e){var i=t.indexOf(e);i!=-1&&t.splice(i,1)},i.getParent=function(t,i){for(;t.parentNode&&t!=document.body;)if(t=t.parentNode,e(t,i))return t},i.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},i.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},i.filterFindElements=function(t,o){t=i.makeArray(t);var n=[];return t.forEach(function(t){if(t instanceof HTMLElement){if(!o)return void n.push(t);e(t,o)&&n.push(t);for(var i=t.querySelectorAll(o),s=0;s<i.length;s++)n.push(i[s])}}),n},i.debounceMethod=function(t,e,i){i=i||100;var o=t.prototype[e],n=e+"Timeout";t.prototype[e]=function(){var t=this[n];clearTimeout(t);var e=arguments,s=this;this[n]=setTimeout(function(){o.apply(s,e),delete s[n]},i)}},i.docReady=function(t){var e=document.readyState;"complete"==e||"interactive"==e?setTimeout(t):document.addEventListener("DOMContentLoaded",t)},i.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var n=t.console;return i.htmlInit=function(e,o){i.docReady(function(){var s=i.toDashed(o),r="data-"+s,a=document.querySelectorAll("["+r+"]"),u=document.querySelectorAll(".js-"+s),h=i.makeArray(a).concat(i.makeArray(u)),d=r+"-options",l=t.jQuery;h.forEach(function(t){var i,s=t.getAttribute(r)||t.getAttribute(d);try{i=s&&JSON.parse(s)}catch(a){return void(n&&n.error("Error parsing "+r+" on "+t.className+": "+a))}var u=new e(t,i);l&&l.data(t,o,u)})})},i}),function(t,e){ true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__WEBPACK_LOCAL_MODULE_1__,__WEBPACK_LOCAL_MODULE_2__], __WEBPACK_AMD_DEFINE_FACTORY__ = (e), 459 __WEBPACK_LOCAL_MODULE_5__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 460 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__)):undefined}(window,function(t,e){"use strict";function i(t){for(var e in t)return!1;return e=null,!0}function o(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}function n(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}var s=document.documentElement.style,r="string"==typeof s.transition?"transition":"WebkitTransition",a="string"==typeof s.transform?"transform":"WebkitTransform",u={WebkitTransition:"webkitTransitionEnd",transition:"transitionend"}[r],h={transform:a,transition:r,transitionDuration:r+"Duration",transitionProperty:r+"Property",transitionDelay:r+"Delay"},d=o.prototype=Object.create(t.prototype);d.constructor=o,d._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},d.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},d.getSize=function(){this.size=e(this.element)},d.css=function(t){var e=this.element.style;for(var i in t){var o=h[i]||i;e[o]=t[i]}},d.getPosition=function(){var t=getComputedStyle(this.element),e=this.layout._getOption("originLeft"),i=this.layout._getOption("originTop"),o=t[e?"left":"right"],n=t[i?"top":"bottom"],s=parseFloat(o),r=parseFloat(n),a=this.layout.size;o.indexOf("%")!=-1&&(s=s/100*a.width),n.indexOf("%")!=-1&&(r=r/100*a.height),s=isNaN(s)?0:s,r=isNaN(r)?0:r,s-=e?a.paddingLeft:a.paddingRight,r-=i?a.paddingTop:a.paddingBottom,this.position.x=s,this.position.y=r},d.layoutPosition=function(){var t=this.layout.size,e={},i=this.layout._getOption("originLeft"),o=this.layout._getOption("originTop"),n=i?"paddingLeft":"paddingRight",s=i?"left":"right",r=i?"right":"left",a=this.position.x+t[n];e[s]=this.getXValue(a),e[r]="";var u=o?"paddingTop":"paddingBottom",h=o?"top":"bottom",d=o?"bottom":"top",l=this.position.y+t[u];e[h]=this.getYValue(l),e[d]="",this.css(e),this.emitEvent("layout",[this])},d.getXValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&!e?t/this.layout.size.width*100+"%":t+"px"},d.getYValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&e?t/this.layout.size.height*100+"%":t+"px"},d._transitionTo=function(t,e){this.getPosition();var i=this.position.x,o=this.position.y,n=t==this.position.x&&e==this.position.y;if(this.setPosition(t,e),n&&!this.isTransitioning)return void this.layoutPosition();var s=t-i,r=e-o,a={};a.transform=this.getTranslate(s,r),this.transition({to:a,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},d.getTranslate=function(t,e){var i=this.layout._getOption("originLeft"),o=this.layout._getOption("originTop");return t=i?t:-t,e=o?e:-e,"translate3d("+t+"px, "+e+"px, 0)"},d.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},d.moveTo=d._transitionTo,d.setPosition=function(t,e){this.position.x=parseFloat(t),this.position.y=parseFloat(e)},d._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},d.transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(t);var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var o=this.element.offsetHeight;o=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var l="opacity,"+n(a);d.enableTransition=function(){if(!this.isTransitioning){var t=this.layout.options.transitionDuration;t="number"==typeof t?t+"ms":t,this.css({transitionProperty:l,transitionDuration:t,transitionDelay:this.staggerDelay||0}),this.element.addEventListener(u,this,!1)}},d.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},d.onotransitionend=function(t){this.ontransitionend(t)};var f={"-webkit-transform":"transform"};d.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,o=f[t.propertyName]||t.propertyName;if(delete e.ingProperties[o],i(e.ingProperties)&&this.disableTransition(),o in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[o]),o in e.onEnd){var n=e.onEnd[o];n.call(this),delete e.onEnd[o]}this.emitEvent("transitionEnd",[this])}},d.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(u,this,!1),this.isTransitioning=!1},d._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var c={transitionProperty:"",transitionDuration:"",transitionDelay:""};return d.removeTransitionStyles=function(){this.css(c)},d.stagger=function(t){t=isNaN(t)?0:t,this.staggerDelay=t+"ms"},d.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},d.remove=function(){return r&&parseFloat(this.layout.options.transitionDuration)?(this.once("transitionEnd",function(){this.removeElem()}),void this.hide()):void this.removeElem()},d.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("visibleStyle");e[i]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},d.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},d.getHideRevealTransitionEndProperty=function(t){var e=this.layout.options[t];if(e.opacity)return"opacity";for(var i in e)return i},d.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("hiddenStyle");e[i]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},d.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},d.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},o}),function(t,e){"use strict"; true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__WEBPACK_LOCAL_MODULE_1__,__WEBPACK_LOCAL_MODULE_2__,__WEBPACK_LOCAL_MODULE_4__,__WEBPACK_LOCAL_MODULE_5__], __WEBPACK_LOCAL_MODULE_6__ = ((function(i,o,n,s){return e(t,i,o,n,s)}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__))):undefined}(window,function(t,e,i,o,n){"use strict";function s(t,e){var i=o.getQueryElement(t);if(!i)return void(u&&u.error("Bad element for "+this.constructor.namespace+": "+(i||t)));this.element=i,h&&(this.$element=h(this.element)),this.options=o.extend({},this.constructor.defaults),this.option(e);var n=++l;this.element.outlayerGUID=n,f[n]=this,this._create();var s=this._getOption("initLayout");s&&this.layout()}function r(t){function e(){t.apply(this,arguments)}return e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e}function a(t){if("number"==typeof t)return t;var e=t.match(/(^\d*\.?\d*)(\w*)/),i=e&&e[1],o=e&&e[2];if(!i.length)return 0;i=parseFloat(i);var n=m[o]||1;return i*n}var u=t.console,h=t.jQuery,d=function(){},l=0,f={};s.namespace="outlayer",s.Item=n,s.defaults={containerStyle:{position:"relative"},initLayout:!0,originLeft:!0,originTop:!0,resize:!0,resizeContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}};var c=s.prototype;o.extend(c,e.prototype),c.option=function(t){o.extend(this.options,t)},c._getOption=function(t){var e=this.constructor.compatOptions[t];return e&&void 0!==this.options[e]?this.options[e]:this.options[t]},s.compatOptions={initLayout:"isInitLayout",horizontal:"isHorizontal",layoutInstant:"isLayoutInstant",originLeft:"isOriginLeft",originTop:"isOriginTop",resize:"isResizeBound",resizeContainer:"isResizingContainer"},c._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),o.extend(this.element.style,this.options.containerStyle);var t=this._getOption("resize");t&&this.bindResize()},c.reloadItems=function(){this.items=this._itemize(this.element.children)},c._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,o=[],n=0;n<e.length;n++){var s=e[n],r=new i(s,this);o.push(r)}return o},c._filterFindItemElements=function(t){return o.filterFindElements(t,this.options.itemSelector)},c.getItemElements=function(){return this.items.map(function(t){return t.element})},c.layout=function(){this._resetLayout(),this._manageStamps();var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;this.layoutItems(this.items,e),this._isLayoutInited=!0},c._init=c.layout,c._resetLayout=function(){this.getSize()},c.getSize=function(){this.size=i(this.element)},c._getMeasurement=function(t,e){var o,n=this.options[t];n?("string"==typeof n?o=this.element.querySelector(n):n instanceof HTMLElement&&(o=n),this[t]=o?i(o)[e]:n):this[t]=0},c.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},c._getItemsForLayout=function(t){return t.filter(function(t){return!t.isIgnored})},c._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){var i=[];t.forEach(function(t){var o=this._getItemLayoutPosition(t);o.item=t,o.isInstant=e||t.isLayoutInstant,i.push(o)},this),this._processLayoutQueue(i)}},c._getItemLayoutPosition=function(){return{x:0,y:0}},c._processLayoutQueue=function(t){this.updateStagger(),t.forEach(function(t,e){this._positionItem(t.item,t.x,t.y,t.isInstant,e)},this)},c.updateStagger=function(){var t=this.options.stagger;return null===t||void 0===t?void(this.stagger=0):(this.stagger=a(t),this.stagger)},c._positionItem=function(t,e,i,o,n){o?t.goTo(e,i):(t.stagger(n*this.stagger),t.moveTo(e,i))},c._postLayout=function(){this.resizeContainer()},c.resizeContainer=function(){var t=this._getOption("resizeContainer");if(t){var e=this._getContainerSize();e&&(this._setContainerMeasure(e.width,!0),this._setContainerMeasure(e.height,!1))}},c._getContainerSize=d,c._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},c._emitCompleteOnItems=function(t,e){function i(){n.dispatchEvent(t+"Complete",null,[e])}function o(){r++,r==s&&i()}var n=this,s=e.length;if(!e||!s)return void i();var r=0;e.forEach(function(e){e.once(t,o)})},c.dispatchEvent=function(t,e,i){var o=e?[e].concat(i):i;if(this.emitEvent(t,o),h)if(this.$element=this.$element||h(this.element),e){var n=h.Event(e);n.type=t,this.$element.trigger(n,i)}else this.$element.trigger(t,i)},c.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},c.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},c.stamp=function(t){t=this._find(t),t&&(this.stamps=this.stamps.concat(t),t.forEach(this.ignore,this))},c.unstamp=function(t){t=this._find(t),t&&t.forEach(function(t){o.removeFrom(this.stamps,t),this.unignore(t)},this)},c._find=function(t){if(t)return"string"==typeof t&&(t=this.element.querySelectorAll(t)),t=o.makeArray(t)},c._manageStamps=function(){this.stamps&&this.stamps.length&&(this._getBoundingRect(),this.stamps.forEach(this._manageStamp,this))},c._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},c._manageStamp=d,c._getElementOffset=function(t){var e=t.getBoundingClientRect(),o=this._boundingRect,n=i(t),s={left:e.left-o.left-n.marginLeft,top:e.top-o.top-n.marginTop,right:o.right-e.right-n.marginRight,bottom:o.bottom-e.bottom-n.marginBottom};return s},c.handleEvent=o.handleEvent,c.bindResize=function(){t.addEventListener("resize",this),this.isResizeBound=!0},c.unbindResize=function(){t.removeEventListener("resize",this),this.isResizeBound=!1},c.onresize=function(){this.resize()},o.debounceMethod(s,"onresize",100),c.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},c.needsResizeLayout=function(){var t=i(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},c.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},c.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},c.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},c.reveal=function(t){if(this._emitCompleteOnItems("reveal",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.reveal()})}},c.hide=function(t){if(this._emitCompleteOnItems("hide",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.hide()})}},c.revealItemElements=function(t){var e=this.getItems(t);this.reveal(e)},c.hideItemElements=function(t){var e=this.getItems(t);this.hide(e)},c.getItem=function(t){for(var e=0;e<this.items.length;e++){var i=this.items[e];if(i.element==t)return i}},c.getItems=function(t){t=o.makeArray(t);var e=[];return t.forEach(function(t){var i=this.getItem(t);i&&e.push(i)},this),e},c.remove=function(t){var e=this.getItems(t);this._emitCompleteOnItems("remove",e),e&&e.length&&e.forEach(function(t){t.remove(),o.removeFrom(this.items,t)},this)},c.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="",this.items.forEach(function(t){t.destroy()}),this.unbindResize();var e=this.element.outlayerGUID;delete f[e],delete this.element.outlayerGUID,h&&h.removeData(this.element,this.constructor.namespace)},s.data=function(t){t=o.getQueryElement(t);var e=t&&t.outlayerGUID;return e&&f[e]},s.create=function(t,e){var i=r(s);return i.defaults=o.extend({},s.defaults),o.extend(i.defaults,e),i.compatOptions=o.extend({},s.compatOptions),i.namespace=t,i.data=s.data,i.Item=r(n),o.htmlInit(i,t),h&&h.bridget&&h.bridget(t,i),i};var m={ms:1,s:1e3};return s.Item=n,s}),function(t,e){ true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__WEBPACK_LOCAL_MODULE_6__], __WEBPACK_AMD_DEFINE_FACTORY__ = (e), 461 __WEBPACK_LOCAL_MODULE_7__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 462 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__)):undefined}(window,function(t){"use strict";function e(){t.Item.apply(this,arguments)}var i=e.prototype=Object.create(t.Item.prototype),o=i._create;i._create=function(){this.id=this.layout.itemGUID++,o.call(this),this.sortData={}},i.updateSortData=function(){if(!this.isIgnored){this.sortData.id=this.id,this.sortData["original-order"]=this.id,this.sortData.random=Math.random();var t=this.layout.options.getSortData,e=this.layout._sorters;for(var i in t){var o=e[i];this.sortData[i]=o(this.element,this)}}};var n=i.destroy;return i.destroy=function(){n.apply(this,arguments),this.css({display:""})},e}),function(t,e){ true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__WEBPACK_LOCAL_MODULE_2__,__WEBPACK_LOCAL_MODULE_6__], __WEBPACK_AMD_DEFINE_FACTORY__ = (e), 463 __WEBPACK_LOCAL_MODULE_8__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 464 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__)):undefined}(window,function(t,e){"use strict";function i(t){this.isotope=t,t&&(this.options=t.options[this.namespace],this.element=t.element,this.items=t.filteredItems,this.size=t.size)}var o=i.prototype,n=["_resetLayout","_getItemLayoutPosition","_manageStamp","_getContainerSize","_getElementOffset","needsResizeLayout","_getOption"];return n.forEach(function(t){o[t]=function(){return e.prototype[t].apply(this.isotope,arguments)}}),o.needsVerticalResizeLayout=function(){var e=t(this.isotope.element),i=this.isotope.size&&e;return i&&e.innerHeight!=this.isotope.size.innerHeight},o._getMeasurement=function(){this.isotope._getMeasurement.apply(this,arguments)},o.getColumnWidth=function(){this.getSegmentSize("column","Width")},o.getRowHeight=function(){this.getSegmentSize("row","Height")},o.getSegmentSize=function(t,e){var i=t+e,o="outer"+e;if(this._getMeasurement(i,o),!this[i]){var n=this.getFirstItemSize();this[i]=n&&n[o]||this.isotope.size["inner"+e]}},o.getFirstItemSize=function(){var e=this.isotope.filteredItems[0];return e&&e.element&&t(e.element)},o.layout=function(){this.isotope.layout.apply(this.isotope,arguments)},o.getSize=function(){this.isotope.getSize(),this.size=this.isotope.size},i.modes={},i.create=function(t,e){function n(){i.apply(this,arguments)}return n.prototype=Object.create(o),n.prototype.constructor=n,e&&(n.options=e),n.prototype.namespace=t,i.modes[t]=n,n},i}),function(t,e){ true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__WEBPACK_LOCAL_MODULE_6__,__WEBPACK_LOCAL_MODULE_2__], __WEBPACK_AMD_DEFINE_FACTORY__ = (e), 465 __WEBPACK_LOCAL_MODULE_9__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 466 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__)):undefined}(window,function(t,e){var i=t.create("masonry");i.compatOptions.fitWidth="isFitWidth";var o=i.prototype;return o._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns(),this.colYs=[];for(var t=0;t<this.cols;t++)this.colYs.push(0);this.maxY=0,this.horizontalColIndex=0},o.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}var o=this.columnWidth+=this.gutter,n=this.containerWidth+this.gutter,s=n/o,r=o-n%o,a=r&&r<1?"round":"floor";s=Math[a](s),this.cols=Math.max(s,1)},o.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,o=e(i);this.containerWidth=o&&o.innerWidth},o._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&e<1?"round":"ceil",o=Math[i](t.size.outerWidth/this.columnWidth);o=Math.min(o,this.cols);for(var n=this.options.horizontalOrder?"_getHorizontalColPosition":"_getTopColPosition",s=this[n](o,t),r={x:this.columnWidth*s.col,y:s.y},a=s.y+t.size.outerHeight,u=o+s.col,h=s.col;h<u;h++)this.colYs[h]=a;return r},o._getTopColPosition=function(t){var e=this._getTopColGroup(t),i=Math.min.apply(Math,e);return{col:e.indexOf(i),y:i}},o._getTopColGroup=function(t){if(t<2)return this.colYs;for(var e=[],i=this.cols+1-t,o=0;o<i;o++)e[o]=this._getColGroupY(o,t);return e},o._getColGroupY=function(t,e){if(e<2)return this.colYs[t];var i=this.colYs.slice(t,t+e);return Math.max.apply(Math,i)},o._getHorizontalColPosition=function(t,e){var i=this.horizontalColIndex%this.cols,o=t>1&&i+t>this.cols;i=o?0:i;var n=e.size.outerWidth&&e.size.outerHeight;return this.horizontalColIndex=n?i+t:this.horizontalColIndex,{col:i,y:this._getColGroupY(i,t)}},o._manageStamp=function(t){var i=e(t),o=this._getElementOffset(t),n=this._getOption("originLeft"),s=n?o.left:o.right,r=s+i.outerWidth,a=Math.floor(s/this.columnWidth);a=Math.max(0,a);var u=Math.floor(r/this.columnWidth);u-=r%this.columnWidth?0:1,u=Math.min(this.cols-1,u);for(var h=this._getOption("originTop"),d=(h?o.top:o.bottom)+i.outerHeight,l=a;l<=u;l++)this.colYs[l]=Math.max(d,this.colYs[l])},o._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},o._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},o.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i}),function(t,e){ true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__WEBPACK_LOCAL_MODULE_8__,__WEBPACK_LOCAL_MODULE_9__], __WEBPACK_AMD_DEFINE_FACTORY__ = (e), 467 __WEBPACK_LOCAL_MODULE_10__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 468 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__)):undefined}(window,function(t,e){"use strict";var i=t.create("masonry"),o=i.prototype,n={_getElementOffset:!0,layout:!0,_getMeasurement:!0};for(var s in e.prototype)n[s]||(o[s]=e.prototype[s]);var r=o.measureColumns;o.measureColumns=function(){this.items=this.isotope.filteredItems,r.call(this)};var a=o._getOption;return o._getOption=function(t){return"fitWidth"==t?void 0!==this.options.isFitWidth?this.options.isFitWidth:this.options.fitWidth:a.apply(this.isotope,arguments)},i}),function(t,e){ true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__WEBPACK_LOCAL_MODULE_8__], __WEBPACK_AMD_DEFINE_FACTORY__ = (e), 469 __WEBPACK_LOCAL_MODULE_11__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 470 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__)):undefined}(window,function(t){"use strict";var e=t.create("fitRows"),i=e.prototype;return i._resetLayout=function(){this.x=0,this.y=0,this.maxY=0,this._getMeasurement("gutter","outerWidth")},i._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth+this.gutter,i=this.isotope.size.innerWidth+this.gutter;0!==this.x&&e+this.x>i&&(this.x=0,this.y=this.maxY);var o={x:this.x,y:this.y};return this.maxY=Math.max(this.maxY,this.y+t.size.outerHeight),this.x+=e,o},i._getContainerSize=function(){return{height:this.maxY}},e}),function(t,e){ true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__WEBPACK_LOCAL_MODULE_8__], __WEBPACK_AMD_DEFINE_FACTORY__ = (e), 471 __WEBPACK_LOCAL_MODULE_12__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 472 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__)):undefined}(window,function(t){"use strict";var e=t.create("vertical",{horizontalAlignment:0}),i=e.prototype;return i._resetLayout=function(){this.y=0},i._getItemLayoutPosition=function(t){t.getSize();var e=(this.isotope.size.innerWidth-t.size.outerWidth)*this.options.horizontalAlignment,i=this.y;return this.y+=t.size.outerHeight,{x:e,y:i}},i._getContainerSize=function(){return{height:this.y}},e}),function(t,e){ true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__WEBPACK_LOCAL_MODULE_6__,__WEBPACK_LOCAL_MODULE_2__,__WEBPACK_LOCAL_MODULE_3__,__WEBPACK_LOCAL_MODULE_4__,__WEBPACK_LOCAL_MODULE_7__,__WEBPACK_LOCAL_MODULE_8__,__WEBPACK_LOCAL_MODULE_10__,__WEBPACK_LOCAL_MODULE_11__,__WEBPACK_LOCAL_MODULE_12__], __WEBPACK_AMD_DEFINE_RESULT__ = (function(i,o,n,s,r,a){return e(t,i,o,n,s,r,a)}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 473 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):undefined}(window,function(t,e,i,o,n,s,r){function a(t,e){return function(i,o){for(var n=0;n<t.length;n++){var s=t[n],r=i.sortData[s],a=o.sortData[s];if(r>a||r<a){var u=void 0!==e[s]?e[s]:e,h=u?1:-1;return(r>a?1:-1)*h}}return 0}}var u=t.jQuery,h=String.prototype.trim?function(t){return t.trim()}:function(t){return t.replace(/^\s+|\s+$/g,"")},d=e.create("isotope",{layoutMode:"masonry",isJQueryFiltering:!0,sortAscending:!0});d.Item=s,d.LayoutMode=r;var l=d.prototype;l._create=function(){this.itemGUID=0,this._sorters={},this._getSorters(),e.prototype._create.call(this),this.modes={},this.filteredItems=this.items,this.sortHistory=["original-order"];for(var t in r.modes)this._initLayoutMode(t)},l.reloadItems=function(){this.itemGUID=0,e.prototype.reloadItems.call(this)},l._itemize=function(){for(var t=e.prototype._itemize.apply(this,arguments),i=0;i<t.length;i++){var o=t[i];o.id=this.itemGUID++}return this._updateItemsSortData(t),t},l._initLayoutMode=function(t){var e=r.modes[t],i=this.options[t]||{};this.options[t]=e.options?n.extend(e.options,i):i,this.modes[t]=new e(this)},l.layout=function(){return!this._isLayoutInited&&this._getOption("initLayout")?void this.arrange():void this._layout()},l._layout=function(){var t=this._getIsInstant();this._resetLayout(),this._manageStamps(),this.layoutItems(this.filteredItems,t),this._isLayoutInited=!0},l.arrange=function(t){this.option(t),this._getIsInstant();var e=this._filter(this.items);this.filteredItems=e.matches,this._bindArrangeComplete(),this._isInstant?this._noTransition(this._hideReveal,[e]):this._hideReveal(e),this._sort(),this._layout()},l._init=l.arrange,l._hideReveal=function(t){this.reveal(t.needReveal),this.hide(t.needHide)},l._getIsInstant=function(){var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;return this._isInstant=e,e},l._bindArrangeComplete=function(){function t(){e&&i&&o&&n.dispatchEvent("arrangeComplete",null,[n.filteredItems])}var e,i,o,n=this;this.once("layoutComplete",function(){e=!0,t()}),this.once("hideComplete",function(){i=!0,t()}),this.once("revealComplete",function(){o=!0,t()})},l._filter=function(t){var e=this.options.filter;e=e||"*";for(var i=[],o=[],n=[],s=this._getFilterTest(e),r=0;r<t.length;r++){var a=t[r];if(!a.isIgnored){var u=s(a);u&&i.push(a),u&&a.isHidden?o.push(a):u||a.isHidden||n.push(a)}}return{matches:i,needReveal:o,needHide:n}},l._getFilterTest=function(t){return u&&this.options.isJQueryFiltering?function(e){return u(e.element).is(t); 474 }:"function"==typeof t?function(e){return t(e.element)}:function(e){return o(e.element,t)}},l.updateSortData=function(t){var e;t?(t=n.makeArray(t),e=this.getItems(t)):e=this.items,this._getSorters(),this._updateItemsSortData(e)},l._getSorters=function(){var t=this.options.getSortData;for(var e in t){var i=t[e];this._sorters[e]=f(i)}},l._updateItemsSortData=function(t){for(var e=t&&t.length,i=0;e&&i<e;i++){var o=t[i];o.updateSortData()}};var f=function(){function t(t){if("string"!=typeof t)return t;var i=h(t).split(" "),o=i[0],n=o.match(/^\[(.+)\]$/),s=n&&n[1],r=e(s,o),a=d.sortDataParsers[i[1]];return t=a?function(t){return t&&a(r(t))}:function(t){return t&&r(t)}}function e(t,e){return t?function(e){return e.getAttribute(t)}:function(t){var i=t.querySelector(e);return i&&i.textContent}}return t}();d.sortDataParsers={parseInt:function(t){return parseInt(t,10)},parseFloat:function(t){return parseFloat(t)}},l._sort=function(){if(this.options.sortBy){var t=n.makeArray(this.options.sortBy);this._getIsSameSortBy(t)||(this.sortHistory=t.concat(this.sortHistory));var e=a(this.sortHistory,this.options.sortAscending);this.filteredItems.sort(e)}},l._getIsSameSortBy=function(t){for(var e=0;e<t.length;e++)if(t[e]!=this.sortHistory[e])return!1;return!0},l._mode=function(){var t=this.options.layoutMode,e=this.modes[t];if(!e)throw new Error("No layout mode: "+t);return e.options=this.options[t],e},l._resetLayout=function(){e.prototype._resetLayout.call(this),this._mode()._resetLayout()},l._getItemLayoutPosition=function(t){return this._mode()._getItemLayoutPosition(t)},l._manageStamp=function(t){this._mode()._manageStamp(t)},l._getContainerSize=function(){return this._mode()._getContainerSize()},l.needsResizeLayout=function(){return this._mode().needsResizeLayout()},l.appended=function(t){var e=this.addItems(t);if(e.length){var i=this._filterRevealAdded(e);this.filteredItems=this.filteredItems.concat(i)}},l.prepended=function(t){var e=this._itemize(t);if(e.length){this._resetLayout(),this._manageStamps();var i=this._filterRevealAdded(e);this.layoutItems(this.filteredItems),this.filteredItems=i.concat(this.filteredItems),this.items=e.concat(this.items)}},l._filterRevealAdded=function(t){var e=this._filter(t);return this.hide(e.needHide),this.reveal(e.matches),this.layoutItems(e.matches,!0),e.matches},l.insert=function(t){var e=this.addItems(t);if(e.length){var i,o,n=e.length;for(i=0;i<n;i++)o=e[i],this.element.appendChild(o.element);var s=this._filter(e).matches;for(i=0;i<n;i++)e[i].isLayoutInstant=!0;for(this.arrange(),i=0;i<n;i++)delete e[i].isLayoutInstant;this.reveal(s)}};var c=l.remove;return l.remove=function(t){t=n.makeArray(t);var e=this.getItems(t);c.call(this,t);for(var i=e&&e.length,o=0;i&&o<i;o++){var s=e[o];n.removeFrom(this.filteredItems,s)}},l.shuffle=function(){for(var t=0;t<this.items.length;t++){var e=this.items[t];e.sortData.random=Math.random()}this.options.sortBy="random",this._sort(),this._layout()},l._noTransition=function(t,e){var i=this.options.transitionDuration;this.options.transitionDuration=0;var o=t.apply(this,e);return this.options.transitionDuration=i,o},l.getFilteredItemElements=function(){return this.filteredItems.map(function(t){return t.element})},d}); 475 476/***/ }), 477
vendor: 398,832 bytes, lines 478-14507
478/***/ "./node_modules/leaflet/dist/leaflet-src.js": 479/*!**************************************************!*\ 480 !*** ./node_modules/leaflet/dist/leaflet-src.js ***! 481 \**************************************************/ 482 /*! no static exports found */ 483 /***/ (function(module, exports, __webpack_require__) { 484 485/* @preserve 486 * Leaflet 1.5.1+build.2e3e0ff, a JS library for interactive maps. http://leafletjs.com 487 * (c) 2010-2018 Vladimir Agafonkin, (c) 2010-2011 CloudMade 488 */ 489 490 (function (global, factory) { 491 true ? factory(exports) : 492 undefined; 493}(this, (function (exports) { 'use strict'; 494 495 var version = "1.5.1+build.2e3e0ffb"; 496 497/* 498 * @namespace Util 499 * 500 * Various utility functions, used by Leaflet internally. 501 */ 502 503 var freeze = Object.freeze; 504 Object.freeze = function (obj) { return obj; }; 505 506// @function extend(dest: Object, src?: Object): Object 507// Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut. 508function extend(dest) { 509 var i, j, len, src; 510 511 for (j = 1, len = arguments.length; j < len; j++) { 512 src = arguments[j]; 513 for (i in src) { 514 dest[i] = src[i]; 515 } 516 } 517 return dest; 518} 519 520// @function create(proto: Object, properties?: Object): Object 521// Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create) 522var create = Object.create || (function () { 523 function F() {} 524 return function (proto) { 525 F.prototype = proto; 526 return new F(); 527 }; 528})(); 529 530// @function bind(fn: Function, …): Function 531// Returns a new function bound to the arguments passed, like [Function.prototype.bind](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Function/bind). 532// Has a `L.bind()` shortcut. 533function bind(fn, obj) { 534 var slice = Array.prototype.slice; 535 536 if (fn.bind) { 537 return fn.bind.apply(fn, slice.call(arguments, 1)); 538 } 539 540 var args = slice.call(arguments, 2); 541 542 return function () { 543 return fn.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments); 544 }; 545} 546 547// @property lastId: Number 548// Last unique ID used by [`stamp()`](#util-stamp) 549var lastId = 0; 550 551// @function stamp(obj: Object): Number 552// Returns the unique ID of an object, assigning it one if it doesn't have it. 553function stamp(obj) { 554 /*eslint-disable */ 555 obj._leaflet_id = obj._leaflet_id || ++lastId; 556 return obj._leaflet_id; 557 /* eslint-enable */ 558} 559 560// @function throttle(fn: Function, time: Number, context: Object): Function 561// Returns a function which executes function `fn` with the given scope `context` 562// (so that the `this` keyword refers to `context` inside `fn`'s code). The function 563// `fn` will be called no more than one time per given amount of `time`. The arguments 564// received by the bound function will be any arguments passed when binding the 565// function, followed by any arguments passed when invoking the bound function. 566// Has an `L.throttle` shortcut. 567function throttle(fn, time, context) { 568 var lock, args, wrapperFn, later; 569 570 later = function () { 571 // reset lock and call if queued 572 lock = false; 573 if (args) { 574 wrapperFn.apply(context, args); 575 args = false; 576 } 577 }; 578 579 wrapperFn = function () { 580 if (lock) { 581 // called too soon, queue to call later 582 args = arguments; 583 584 } else { 585 // call and lock until later 586 fn.apply(context, arguments); 587 setTimeout(later, time); 588 lock = true; 589 } 590 }; 591 592 return wrapperFn; 593} 594 595// @function wrapNum(num: Number, range: Number[], includeMax?: Boolean): Number 596// Returns the number `num` modulo `range` in such a way so it lies within 597// `range[0]` and `range[1]`. The returned value will be always smaller than 598// `range[1]` unless `includeMax` is set to `true`. 599function wrapNum(x, range, includeMax) { 600 var max = range[1], 601 min = range[0], 602 d = max - min; 603 return x === max && includeMax ? x : ((x - min) % d + d) % d + min; 604} 605 606// @function falseFn(): Function 607// Returns a function which always returns `false`. 608function falseFn() { return false; } 609 610// @function formatNum(num: Number, digits?: Number): Number 611// Returns the number `num` rounded to `digits` decimals, or to 6 decimals by default. 612function formatNum(num, digits) { 613 digits = (digits === undefined ? 6 : digits); 614 return +(Math.round(num + ('e+' + digits)) + ('e-' + digits)); 615} 616 617// @function trim(str: String): String 618// Compatibility polyfill for [String.prototype.trim](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim) 619function trim(str) { 620 return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, ''); 621} 622 623// @function splitWords(str: String): String[] 624// Trims and splits the string on whitespace and returns the array of parts. 625function splitWords(str) { 626 return trim(str).split(/\s+/); 627} 628 629// @function setOptions(obj: Object, options: Object): Object 630// Merges the given properties to the `options` of the `obj` object, returning the resulting options. See `Class options`. Has an `L.setOptions` shortcut. 631function setOptions(obj, options) { 632 if (!obj.hasOwnProperty('options')) { 633 obj.options = obj.options ? create(obj.options) : {}; 634 } 635 for (var i in options) { 636 obj.options[i] = options[i]; 637 } 638 return obj.options; 639} 640 641// @function getParamString(obj: Object, existingUrl?: String, uppercase?: Boolean): String 642// Converts an object into a parameter URL string, e.g. `{a: "foo", b: "bar"}` 643// translates to `'?a=foo&b=bar'`. If `existingUrl` is set, the parameters will 644// be appended at the end. If `uppercase` is `true`, the parameter names will 645// be uppercased (e.g. `'?A=foo&B=bar'`) 646function getParamString(obj, existingUrl, uppercase) { 647 var params = []; 648 for (var i in obj) { 649 params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i])); 650 } 651 return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&'); 652} 653 654var templateRe = /\{ *([\w_-]+) *\}/g; 655 656// @function template(str: String, data: Object): String 657// Simple templating facility, accepts a template string of the form `'Hello {a}, {b}'` 658// and a data object like `{a: 'foo', b: 'bar'}`, returns evaluated string 659// `('Hello foo, bar')`. You can also specify functions instead of strings for 660// data values — they will be evaluated passing `data` as an argument. 661function template(str, data) { 662 return str.replace(templateRe, function (str, key) { 663 var value = data[key]; 664 665 if (value === undefined) { 666 throw new Error('No value provided for variable ' + str); 667 668 } else if (typeof value === 'function') { 669 value = value(data); 670 } 671 return value; 672 }); 673} 674 675// @function isArray(obj): Boolean 676// Compatibility polyfill for [Array.isArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray) 677var isArray = Array.isArray || function (obj) { 678 return (Object.prototype.toString.call(obj) === '[object Array]'); 679}; 680 681// @function indexOf(array: Array, el: Object): Number 682// Compatibility polyfill for [Array.prototype.indexOf](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) 683function indexOf(array, el) { 684 for (var i = 0; i < array.length; i++) { 685 if (array[i] === el) { return i; } 686 } 687 return -1; 688} 689 690// @property emptyImageUrl: String 691// Data URI string containing a base64-encoded empty GIF image. 692// Used as a hack to free memory from unused images on WebKit-powered 693// mobile devices (by setting image `src` to this string). 694var emptyImageUrl = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='; 695 696// inspired by http://paulirish.com/2011/requestanimationframe-for-smart-animating/ 697 698function getPrefixed(name) { 699 return window['webkit' + name] || window['moz' + name] || window['ms' + name]; 700} 701 702var lastTime = 0; 703 704// fallback for IE 7-8 705function timeoutDefer(fn) { 706 var time = +new Date(), 707 timeToCall = Math.max(0, 16 - (time - lastTime)); 708 709 lastTime = time + timeToCall; 710 return window.setTimeout(fn, timeToCall); 711} 712 713var requestFn = window.requestAnimationFrame || getPrefixed('RequestAnimationFrame') || timeoutDefer; 714var cancelFn = window.cancelAnimationFrame || getPrefixed('CancelAnimationFrame') || 715getPrefixed('CancelRequestAnimationFrame') || function (id) { window.clearTimeout(id); }; 716 717// @function requestAnimFrame(fn: Function, context?: Object, immediate?: Boolean): Number 718// Schedules `fn` to be executed when the browser repaints. `fn` is bound to 719// `context` if given. When `immediate` is set, `fn` is called immediately if 720// the browser doesn't have native support for 721// [`window.requestAnimationFrame`](https://developer.mozilla.org/docs/Web/API/window/requestAnimationFrame), 722// otherwise it's delayed. Returns a request ID that can be used to cancel the request. 723function requestAnimFrame(fn, context, immediate) { 724 if (immediate && requestFn === timeoutDefer) { 725 fn.call(context); 726 } else { 727 return requestFn.call(window, bind(fn, context)); 728 } 729} 730 731// @function cancelAnimFrame(id: Number): undefined 732// Cancels a previous `requestAnimFrame`. See also [window.cancelAnimationFrame](https://developer.mozilla.org/docs/Web/API/window/cancelAnimationFrame). 733function cancelAnimFrame(id) { 734 if (id) { 735 cancelFn.call(window, id); 736 } 737} 738 739 740var Util = (Object.freeze || Object)({ 741 freeze: freeze, 742 extend: extend, 743 create: create, 744 bind: bind, 745 lastId: lastId, 746 stamp: stamp, 747 throttle: throttle, 748 wrapNum: wrapNum, 749 falseFn: falseFn, 750 formatNum: formatNum, 751 trim: trim, 752 splitWords: splitWords, 753 setOptions: setOptions, 754 getParamString: getParamString, 755 template: template, 756 isArray: isArray, 757 indexOf: indexOf, 758 emptyImageUrl: emptyImageUrl, 759 requestFn: requestFn, 760 cancelFn: cancelFn, 761 requestAnimFrame: requestAnimFrame, 762 cancelAnimFrame: cancelAnimFrame 763}); 764 765// @class Class 766// @aka L.Class 767 768// @section 769// @uninheritable 770 771// Thanks to John Resig and Dean Edwards for inspiration! 772 773function Class() {} 774 775Class.extend = function (props) { 776 777 // @function extend(props: Object): Function 778 // [Extends the current class](#class-inheritance) given the properties to be included. 779 // Returns a Javascript function that is a class constructor (to be called with `new`). 780 var NewClass = function () { 781 782 // call the constructor 783 if (this.initialize) { 784 this.initialize.apply(this, arguments); 785 } 786 787 // call all constructor hooks 788 this.callInitHooks(); 789 }; 790 791 var parentProto = NewClass.__super__ = this.prototype; 792 793 var proto = create(parentProto); 794 proto.constructor = NewClass; 795 796 NewClass.prototype = proto; 797 798 // inherit parent's statics 799 for (var i in this) { 800 if (this.hasOwnProperty(i) && i !== 'prototype' && i !== '__super__') { 801 NewClass[i] = this[i]; 802 } 803 } 804 805 // mix static properties into the class 806 if (props.statics) { 807 extend(NewClass, props.statics); 808 delete props.statics; 809 } 810 811 // mix includes into the prototype 812 if (props.includes) { 813 checkDeprecatedMixinEvents(props.includes); 814 extend.apply(null, [proto].concat(props.includes)); 815 delete props.includes; 816 } 817 818 // merge options 819 if (proto.options) { 820 props.options = extend(create(proto.options), props.options); 821 } 822 823 // mix given properties into the prototype 824 extend(proto, props); 825 826 proto._initHooks = []; 827 828 // add method for calling all hooks 829 proto.callInitHooks = function () { 830 831 if (this._initHooksCalled) { return; } 832 833 if (parentProto.callInitHooks) { 834 parentProto.callInitHooks.call(this); 835 } 836 837 this._initHooksCalled = true; 838 839 for (var i = 0, len = proto._initHooks.length; i < len; i++) { 840 proto._initHooks[i].call(this); 841 } 842 }; 843 844 return NewClass; 845}; 846 847 848// @function include(properties: Object): this 849// [Includes a mixin](#class-includes) into the current class. 850Class.include = function (props) { 851 extend(this.prototype, props); 852 return this; 853}; 854 855// @function mergeOptions(options: Object): this 856// [Merges `options`](#class-options) into the defaults of the class. 857Class.mergeOptions = function (options) { 858 extend(this.prototype.options, options); 859 return this; 860}; 861 862// @function addInitHook(fn: Function): this 863// Adds a [constructor hook](#class-constructor-hooks) to the class. 864Class.addInitHook = function (fn) { // (Function) || (String, args...) 865 var args = Array.prototype.slice.call(arguments, 1); 866 867 var init = typeof fn === 'function' ? fn : function () { 868 this[fn].apply(this, args); 869 }; 870 871 this.prototype._initHooks = this.prototype._initHooks || []; 872 this.prototype._initHooks.push(init); 873 return this; 874}; 875 876function checkDeprecatedMixinEvents(includes) { 877 if (typeof L === 'undefined' || !L || !L.Mixin) { return; } 878 879 includes = isArray(includes) ? includes : [includes]; 880 881 for (var i = 0; i < includes.length; i++) { 882 if (includes[i] === L.Mixin.Events) { 883 console.warn('Deprecated include of L.Mixin.Events: ' + 884 'this property will be removed in future releases, ' + 885 'please inherit from L.Evented instead.', new Error().stack); 886 } 887 } 888} 889 890/* 891 * @class Evented 892 * @aka L.Evented 893 * @inherits Class 894 * 895 * A set of methods shared between event-powered classes (like `Map` and `Marker`). Generally, events allow you to execute some function when something happens with an object (e.g. the user clicks on the map, causing the map to fire `'click'` event). 896 * 897 * @example 898 * 899 * ```js 900 * map.on('click', function(e) { 901 * alert(e.latlng); 902 * } ); 903 * ``` 904 * 905 * Leaflet deals with event listeners by reference, so if you want to add a listener and then remove it, define it as a function: 906 * 907 * ```js 908 * function onClick(e) { ... } 909 * 910 * map.on('click', onClick); 911 * map.off('click', onClick); 912 * ``` 913 */ 914 915 var Events = { 916 /* @method on(type: String, fn: Function, context?: Object): this 917 * Adds a listener function (`fn`) to a particular event type of the object. You can optionally specify the context of the listener (object the this keyword will point to). You can also pass several space-separated types (e.g. `'click dblclick'`). 918 * 919 * @alternative 920 * @method on(eventMap: Object): this 921 * Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}` 922 */ 923 on: function (types, fn, context) { 924 925 // types can be a map of types/handlers 926 if (typeof types === 'object') { 927 for (var type in types) { 928 // we don't process space-separated events here for performance; 929 // it's a hot path since Layer uses the on(obj) syntax 930 this._on(type, types[type], fn); 931 } 932 933 } else { 934 // types can be a string of space-separated words 935 types = splitWords(types); 936 937 for (var i = 0, len = types.length; i < len; i++) { 938 this._on(types[i], fn, context); 939 } 940 } 941 942 return this; 943 }, 944 945 /* @method off(type: String, fn?: Function, context?: Object): this 946 * Removes a previously added listener function. If no function is specified, it will remove all the listeners of that particular event from the object. Note that if you passed a custom context to `on`, you must pass the same context to `off` in order to remove the listener. 947 * 948 * @alternative 949 * @method off(eventMap: Object): this 950 * Removes a set of type/listener pairs. 951 * 952 * @alternative 953 * @method off: this 954 * Removes all listeners to all events on the object. This includes implicitly attached events. 955 */ 956 off: function (types, fn, context) { 957 958 if (!types) { 959 // clear all listeners if called without arguments 960 delete this._events; 961 962 } else if (typeof types === 'object') { 963 for (var type in types) { 964 this._off(type, types[type], fn); 965 } 966 967 } else { 968 types = splitWords(types); 969 970 for (var i = 0, len = types.length; i < len; i++) { 971 this._off(types[i], fn, context); 972 } 973 } 974 975 return this; 976 }, 977 978 // attach listener (without syntactic sugar now) 979 _on: function (type, fn, context) { 980 this._events = this._events || {}; 981 982 /* get/init listeners for type */ 983 var typeListeners = this._events[type]; 984 if (!typeListeners) { 985 typeListeners = []; 986 this._events[type] = typeListeners; 987 } 988 989 if (context === this) { 990 // Less memory footprint. 991 context = undefined; 992 } 993 var newListener = {fn: fn, ctx: context}, 994 listeners = typeListeners; 995 996 // check if fn already there 997 for (var i = 0, len = listeners.length; i < len; i++) { 998 if (listeners[i].fn === fn && listeners[i].ctx === context) { 999 return; 1000 } 1001 } 1002 1003 listeners.push(newListener); 1004 }, 1005 1006 _off: function (type, fn, context) { 1007 var listeners, 1008 i, 1009 len; 1010 1011 if (!this._events) { return; } 1012 1013 listeners = this._events[type]; 1014 1015 if (!listeners) { 1016 return; 1017 } 1018 1019 if (!fn) { 1020 // Set all removed listeners to noop so they are not called if remove happens in fire 1021 for (i = 0, len = listeners.length; i < len; i++) { 1022 listeners[i].fn = falseFn; 1023 } 1024 // clear all listeners for a type if function isn't specified 1025 delete this._events[type]; 1026 return; 1027 } 1028 1029 if (context === this) { 1030 context = undefined; 1031 } 1032 1033 if (listeners) { 1034 1035 // find fn and remove it 1036 for (i = 0, len = listeners.length; i < len; i++) { 1037 var l = listeners[i]; 1038 if (l.ctx !== context) { continue; } 1039 if (l.fn === fn) { 1040 1041 // set the removed listener to noop so that's not called if remove happens in fire 1042 l.fn = falseFn; 1043 1044 if (this._firingCount) { 1045 /* copy array in case events are being fired */ 1046 this._events[type] = listeners = listeners.slice(); 1047 } 1048 listeners.splice(i, 1); 1049 1050 return; 1051 } 1052 } 1053 } 1054 }, 1055 1056 // @method fire(type: String, data?: Object, propagate?: Boolean): this 1057 // Fires an event of the specified type. You can optionally provide an data 1058 // object — the first argument of the listener function will contain its 1059 // properties. The event can optionally be propagated to event parents. 1060 fire: function (type, data, propagate) { 1061 if (!this.listens(type, propagate)) { return this; } 1062 1063 var event = extend({}, data, { 1064 type: type, 1065 target: this, 1066 sourceTarget: data && data.sourceTarget || this 1067 }); 1068 1069 if (this._events) { 1070 var listeners = this._events[type]; 1071 1072 if (listeners) { 1073 this._firingCount = (this._firingCount + 1) || 1; 1074 for (var i = 0, len = listeners.length; i < len; i++) { 1075 var l = listeners[i]; 1076 l.fn.call(l.ctx || this, event); 1077 } 1078 1079 this._firingCount--; 1080 } 1081 } 1082 1083 if (propagate) { 1084 // propagate the event to parents (set with addEventParent) 1085 this._propagateEvent(event); 1086 } 1087 1088 return this; 1089 }, 1090 1091 // @method listens(type: String): Boolean 1092 // Returns `true` if a particular event type has any listeners attached to it. 1093 listens: function (type, propagate) { 1094 var listeners = this._events && this._events[type]; 1095 if (listeners && listeners.length) { return true; } 1096 1097 if (propagate) { 1098 // also check parents for listeners if event propagates 1099 for (var id in this._eventParents) { 1100 if (this._eventParents[id].listens(type, propagate)) { return true; } 1101 } 1102 } 1103 return false; 1104 }, 1105 1106 // @method once(…): this 1107 // Behaves as [`on(…)`](#evented-on), except the listener will only get fired once and then removed. 1108 once: function (types, fn, context) { 1109 1110 if (typeof types === 'object') { 1111 for (var type in types) { 1112 this.once(type, types[type], fn); 1113 } 1114 return this; 1115 } 1116 1117 var handler = bind(function () { 1118 this 1119 .off(types, fn, context) 1120 .off(types, handler, context); 1121 }, this); 1122 1123 // add a listener that's executed once and removed after that 1124 return this 1125 .on(types, fn, context) 1126 .on(types, handler, context); 1127 }, 1128 1129 // @method addEventParent(obj: Evented): this 1130 // Adds an event parent - an `Evented` that will receive propagated events 1131 addEventParent: function (obj) { 1132 this._eventParents = this._eventParents || {}; 1133 this._eventParents[stamp(obj)] = obj; 1134 return this; 1135 }, 1136 1137 // @method removeEventParent(obj: Evented): this 1138 // Removes an event parent, so it will stop receiving propagated events 1139 removeEventParent: function (obj) { 1140 if (this._eventParents) { 1141 delete this._eventParents[stamp(obj)]; 1142 } 1143 return this; 1144 }, 1145 1146 _propagateEvent: function (e) { 1147 for (var id in this._eventParents) { 1148 this._eventParents[id].fire(e.type, extend({ 1149 layer: e.target, 1150 propagatedFrom: e.target 1151 }, e), true); 1152 } 1153 } 1154}; 1155 1156// aliases; we should ditch those eventually 1157 1158// @method addEventListener(…): this 1159// Alias to [`on(…)`](#evented-on) 1160Events.addEventListener = Events.on; 1161 1162// @method removeEventListener(…): this 1163// Alias to [`off(…)`](#evented-off) 1164 1165// @method clearAllEventListeners(…): this 1166// Alias to [`off()`](#evented-off) 1167Events.removeEventListener = Events.clearAllEventListeners = Events.off; 1168 1169// @method addOneTimeEventListener(…): this 1170// Alias to [`once(…)`](#evented-once) 1171Events.addOneTimeEventListener = Events.once; 1172 1173// @method fireEvent(…): this 1174// Alias to [`fire(…)`](#evented-fire) 1175Events.fireEvent = Events.fire; 1176 1177// @method hasEventListeners(…): Boolean 1178// Alias to [`listens(…)`](#evented-listens) 1179Events.hasEventListeners = Events.listens; 1180 1181var Evented = Class.extend(Events); 1182 1183/* 1184 * @class Point 1185 * @aka L.Point 1186 * 1187 * Represents a point with `x` and `y` coordinates in pixels. 1188 * 1189 * @example 1190 * 1191 * ```js 1192 * var point = L.point(200, 300); 1193 * ``` 1194 * 1195 * All Leaflet methods and options that accept `Point` objects also accept them in a simple Array form (unless noted otherwise), so these lines are equivalent: 1196 * 1197 * ```js 1198 * map.panBy([200, 300]); 1199 * map.panBy(L.point(200, 300)); 1200 * ``` 1201 * 1202 * Note that `Point` does not inherit from Leafet's `Class` object, 1203 * which means new classes can't inherit from it, and new methods 1204 * can't be added to it with the `include` function. 1205 */ 1206 1207 function Point(x, y, round) { 1208 // @property x: Number; The `x` coordinate of the point 1209 this.x = (round ? Math.round(x) : x); 1210 // @property y: Number; The `y` coordinate of the point 1211 this.y = (round ? Math.round(y) : y); 1212} 1213 1214var trunc = Math.trunc || function (v) { 1215 return v > 0 ? Math.floor(v) : Math.ceil(v); 1216}; 1217 1218Point.prototype = { 1219 1220 // @method clone(): Point 1221 // Returns a copy of the current point. 1222 clone: function () { 1223 return new Point(this.x, this.y); 1224 }, 1225 1226 // @method add(otherPoint: Point): Point 1227 // Returns the result of addition of the current and the given points. 1228 add: function (point) { 1229 // non-destructive, returns a new point 1230 return this.clone()._add(toPoint(point)); 1231 }, 1232 1233 _add: function (point) { 1234 // destructive, used directly for performance in situations where it's safe to modify existing point 1235 this.x += point.x; 1236 this.y += point.y; 1237 return this; 1238 }, 1239 1240 // @method subtract(otherPoint: Point): Point 1241 // Returns the result of subtraction of the given point from the current. 1242 subtract: function (point) { 1243 return this.clone()._subtract(toPoint(point)); 1244 }, 1245 1246 _subtract: function (point) { 1247 this.x -= point.x; 1248 this.y -= point.y; 1249 return this; 1250 }, 1251 1252 // @method divideBy(num: Number): Point 1253 // Returns the result of division of the current point by the given number. 1254 divideBy: function (num) { 1255 return this.clone()._divideBy(num); 1256 }, 1257 1258 _divideBy: function (num) { 1259 this.x /= num; 1260 this.y /= num; 1261 return this; 1262 }, 1263 1264 // @method multiplyBy(num: Number): Point 1265 // Returns the result of multiplication of the current point by the given number. 1266 multiplyBy: function (num) { 1267 return this.clone()._multiplyBy(num); 1268 }, 1269 1270 _multiplyBy: function (num) { 1271 this.x *= num; 1272 this.y *= num; 1273 return this; 1274 }, 1275 1276 // @method scaleBy(scale: Point): Point 1277 // Multiply each coordinate of the current point by each coordinate of 1278 // `scale`. In linear algebra terms, multiply the point by the 1279 // [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation) 1280 // defined by `scale`. 1281 scaleBy: function (point) { 1282 return new Point(this.x * point.x, this.y * point.y); 1283 }, 1284 1285 // @method unscaleBy(scale: Point): Point 1286 // Inverse of `scaleBy`. Divide each coordinate of the current point by 1287 // each coordinate of `scale`. 1288 unscaleBy: function (point) { 1289 return new Point(this.x / point.x, this.y / point.y); 1290 }, 1291 1292 // @method round(): Point 1293 // Returns a copy of the current point with rounded coordinates. 1294 round: function () { 1295 return this.clone()._round(); 1296 }, 1297 1298 _round: function () { 1299 this.x = Math.round(this.x); 1300 this.y = Math.round(this.y); 1301 return this; 1302 }, 1303 1304 // @method floor(): Point 1305 // Returns a copy of the current point with floored coordinates (rounded down). 1306 floor: function () { 1307 return this.clone()._floor(); 1308 }, 1309 1310 _floor: function () { 1311 this.x = Math.floor(this.x); 1312 this.y = Math.floor(this.y); 1313 return this; 1314 }, 1315 1316 // @method ceil(): Point 1317 // Returns a copy of the current point with ceiled coordinates (rounded up). 1318 ceil: function () { 1319 return this.clone()._ceil(); 1320 }, 1321 1322 _ceil: function () { 1323 this.x = Math.ceil(this.x); 1324 this.y = Math.ceil(this.y); 1325 return this; 1326 }, 1327 1328 // @method trunc(): Point 1329 // Returns a copy of the current point with truncated coordinates (rounded towards zero). 1330 trunc: function () { 1331 return this.clone()._trunc(); 1332 }, 1333 1334 _trunc: function () { 1335 this.x = trunc(this.x); 1336 this.y = trunc(this.y); 1337 return this; 1338 }, 1339 1340 // @method distanceTo(otherPoint: Point): Number 1341 // Returns the cartesian distance between the current and the given points. 1342 distanceTo: function (point) { 1343 point = toPoint(point); 1344 1345 var x = point.x - this.x, 1346 y = point.y - this.y; 1347 1348 return Math.sqrt(x * x + y * y); 1349 }, 1350 1351 // @method equals(otherPoint: Point): Boolean 1352 // Returns `true` if the given point has the same coordinates. 1353 equals: function (point) { 1354 point = toPoint(point); 1355 1356 return point.x === this.x && 1357 point.y === this.y; 1358 }, 1359 1360 // @method contains(otherPoint: Point): Boolean 1361 // Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values). 1362 contains: function (point) { 1363 point = toPoint(point); 1364 1365 return Math.abs(point.x) <= Math.abs(this.x) && 1366 Math.abs(point.y) <= Math.abs(this.y); 1367 }, 1368 1369 // @method toString(): String 1370 // Returns a string representation of the point for debugging purposes. 1371 toString: function () { 1372 return 'Point(' + 1373 formatNum(this.x) + ', ' + 1374 formatNum(this.y) + ')'; 1375 } 1376}; 1377 1378// @factory L.point(x: Number, y: Number, round?: Boolean) 1379// Creates a Point object with the given `x` and `y` coordinates. If optional `round` is set to true, rounds the `x` and `y` values. 1380 1381// @alternative 1382// @factory L.point(coords: Number[]) 1383// Expects an array of the form `[x, y]` instead. 1384 1385// @alternative 1386// @factory L.point(coords: Object) 1387// Expects a plain object of the form `{x: Number, y: Number}` instead. 1388function toPoint(x, y, round) { 1389 if (x instanceof Point) { 1390 return x; 1391 } 1392 if (isArray(x)) { 1393 return new Point(x[0], x[1]); 1394 } 1395 if (x === undefined || x === null) { 1396 return x; 1397 } 1398 if (typeof x === 'object' && 'x' in x && 'y' in x) { 1399 return new Point(x.x, x.y); 1400 } 1401 return new Point(x, y, round); 1402} 1403 1404/* 1405 * @class Bounds 1406 * @aka L.Bounds 1407 * 1408 * Represents a rectangular area in pixel coordinates. 1409 * 1410 * @example 1411 * 1412 * ```js 1413 * var p1 = L.point(10, 10), 1414 * p2 = L.point(40, 60), 1415 * bounds = L.bounds(p1, p2); 1416 * ``` 1417 * 1418 * All Leaflet methods that accept `Bounds` objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this: 1419 * 1420 * ```js 1421 * otherBounds.intersects([[10, 10], [40, 60]]); 1422 * ``` 1423 * 1424 * Note that `Bounds` does not inherit from Leafet's `Class` object, 1425 * which means new classes can't inherit from it, and new methods 1426 * can't be added to it with the `include` function. 1427 */ 1428 1429 function Bounds(a, b) { 1430 if (!a) { return; } 1431 1432 var points = b ? [a, b] : a; 1433 1434 for (var i = 0, len = points.length; i < len; i++) { 1435 this.extend(points[i]); 1436 } 1437} 1438 1439Bounds.prototype = { 1440 // @method extend(point: Point): this 1441 // Extends the bounds to contain the given point. 1442 extend: function (point) { // (Point) 1443 point = toPoint(point); 1444 1445 // @property min: Point 1446 // The top left corner of the rectangle. 1447 // @property max: Point 1448 // The bottom right corner of the rectangle. 1449 if (!this.min && !this.max) { 1450 this.min = point.clone(); 1451 this.max = point.clone(); 1452 } else { 1453 this.min.x = Math.min(point.x, this.min.x); 1454 this.max.x = Math.max(point.x, this.max.x); 1455 this.min.y = Math.min(point.y, this.min.y); 1456 this.max.y = Math.max(point.y, this.max.y); 1457 } 1458 return this; 1459 }, 1460 1461 // @method getCenter(round?: Boolean): Point 1462 // Returns the center point of the bounds. 1463 getCenter: function (round) { 1464 return new Point( 1465 (this.min.x + this.max.x) / 2, 1466 (this.min.y + this.max.y) / 2, round); 1467 }, 1468 1469 // @method getBottomLeft(): Point 1470 // Returns the bottom-left point of the bounds. 1471 getBottomLeft: function () { 1472 return new Point(this.min.x, this.max.y); 1473 }, 1474 1475 // @method getTopRight(): Point 1476 // Returns the top-right point of the bounds. 1477 getTopRight: function () { // -> Point 1478 return new Point(this.max.x, this.min.y); 1479 }, 1480 1481 // @method getTopLeft(): Point 1482 // Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)). 1483 getTopLeft: function () { 1484 return this.min; // left, top 1485 }, 1486 1487 // @method getBottomRight(): Point 1488 // Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)). 1489 getBottomRight: function () { 1490 return this.max; // right, bottom 1491 }, 1492 1493 // @method getSize(): Point 1494 // Returns the size of the given bounds 1495 getSize: function () { 1496 return this.max.subtract(this.min); 1497 }, 1498 1499 // @method contains(otherBounds: Bounds): Boolean 1500 // Returns `true` if the rectangle contains the given one. 1501 // @alternative 1502 // @method contains(point: Point): Boolean 1503 // Returns `true` if the rectangle contains the given point. 1504 contains: function (obj) { 1505 var min, max; 1506 1507 if (typeof obj[0] === 'number' || obj instanceof Point) { 1508 obj = toPoint(obj); 1509 } else { 1510 obj = toBounds(obj); 1511 } 1512 1513 if (obj instanceof Bounds) { 1514 min = obj.min; 1515 max = obj.max; 1516 } else { 1517 min = max = obj; 1518 } 1519 1520 return (min.x >= this.min.x) && 1521 (max.x <= this.max.x) && 1522 (min.y >= this.min.y) && 1523 (max.y <= this.max.y); 1524 }, 1525 1526 // @method intersects(otherBounds: Bounds): Boolean 1527 // Returns `true` if the rectangle intersects the given bounds. Two bounds 1528 // intersect if they have at least one point in common. 1529 intersects: function (bounds) { // (Bounds) -> Boolean 1530 bounds = toBounds(bounds); 1531 1532 var min = this.min, 1533 max = this.max, 1534 min2 = bounds.min, 1535 max2 = bounds.max, 1536 xIntersects = (max2.x >= min.x) && (min2.x <= max.x), 1537 yIntersects = (max2.y >= min.y) && (min2.y <= max.y); 1538 1539 return xIntersects && yIntersects; 1540 }, 1541 1542 // @method overlaps(otherBounds: Bounds): Boolean 1543 // Returns `true` if the rectangle overlaps the given bounds. Two bounds 1544 // overlap if their intersection is an area. 1545 overlaps: function (bounds) { // (Bounds) -> Boolean 1546 bounds = toBounds(bounds); 1547 1548 var min = this.min, 1549 max = this.max, 1550 min2 = bounds.min, 1551 max2 = bounds.max, 1552 xOverlaps = (max2.x > min.x) && (min2.x < max.x), 1553 yOverlaps = (max2.y > min.y) && (min2.y < max.y); 1554 1555 return xOverlaps && yOverlaps; 1556 }, 1557 1558 isValid: function () { 1559 return !!(this.min && this.max); 1560 } 1561}; 1562 1563 1564// @factory L.bounds(corner1: Point, corner2: Point) 1565// Creates a Bounds object from two corners coordinate pairs. 1566// @alternative 1567// @factory L.bounds(points: Point[]) 1568// Creates a Bounds object from the given array of points. 1569function toBounds(a, b) { 1570 if (!a || a instanceof Bounds) { 1571 return a; 1572 } 1573 return new Bounds(a, b); 1574} 1575 1576/* 1577 * @class LatLngBounds 1578 * @aka L.LatLngBounds 1579 * 1580 * Represents a rectangular geographical area on a map. 1581 * 1582 * @example 1583 * 1584 * ```js 1585 * var corner1 = L.latLng(40.712, -74.227), 1586 * corner2 = L.latLng(40.774, -74.125), 1587 * bounds = L.latLngBounds(corner1, corner2); 1588 * ``` 1589 * 1590 * All Leaflet methods that accept LatLngBounds objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this: 1591 * 1592 * ```js 1593 * map.fitBounds([ 1594 * [40.712, -74.227], 1595 * [40.774, -74.125] 1596 * ]); 1597 * ``` 1598 * 1599 * Caution: if the area crosses the antimeridian (often confused with the International Date Line), you must specify corners _outside_ the [-180, 180] degrees longitude range. 1600 * 1601 * Note that `LatLngBounds` does not inherit from Leafet's `Class` object, 1602 * which means new classes can't inherit from it, and new methods 1603 * can't be added to it with the `include` function. 1604 */ 1605 1606function LatLngBounds(corner1, corner2) { // (LatLng, LatLng) or (LatLng[]) 1607 if (!corner1) { return; } 1608 1609 var latlngs = corner2 ? [corner1, corner2] : corner1; 1610 1611 for (var i = 0, len = latlngs.length; i < len; i++) { 1612 this.extend(latlngs[i]); 1613 } 1614} 1615 1616LatLngBounds.prototype = { 1617 1618 // @method extend(latlng: LatLng): this 1619 // Extend the bounds to contain the given point 1620 1621 // @alternative 1622 // @method extend(otherBounds: LatLngBounds): this 1623 // Extend the bounds to contain the given bounds 1624 extend: function (obj) { 1625 var sw = this._southWest, 1626 ne = this._northEast, 1627 sw2, ne2; 1628 1629 if (obj instanceof LatLng) { 1630 sw2 = obj; 1631 ne2 = obj; 1632 1633 } else if (obj instanceof LatLngBounds) { 1634 sw2 = obj._southWest; 1635 ne2 = obj._northEast; 1636 1637 if (!sw2 || !ne2) { return this; } 1638 1639 } else { 1640 return obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this; 1641 } 1642 1643 if (!sw && !ne) { 1644 this._southWest = new LatLng(sw2.lat, sw2.lng); 1645 this._northEast = new LatLng(ne2.lat, ne2.lng); 1646 } else { 1647 sw.lat = Math.min(sw2.lat, sw.lat); 1648 sw.lng = Math.min(sw2.lng, sw.lng); 1649 ne.lat = Math.max(ne2.lat, ne.lat); 1650 ne.lng = Math.max(ne2.lng, ne.lng); 1651 } 1652 1653 return this; 1654 }, 1655 1656 // @method pad(bufferRatio: Number): LatLngBounds 1657 // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction. 1658 // For example, a ratio of 0.5 extends the bounds by 50% in each direction. 1659 // Negative values will retract the bounds. 1660 pad: function (bufferRatio) { 1661 var sw = this._southWest, 1662 ne = this._northEast, 1663 heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio, 1664 widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio; 1665 1666 return new LatLngBounds( 1667 new LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer), 1668 new LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer)); 1669 }, 1670 1671 // @method getCenter(): LatLng 1672 // Returns the center point of the bounds. 1673 getCenter: function () { 1674 return new LatLng( 1675 (this._southWest.lat + this._northEast.lat) / 2, 1676 (this._southWest.lng + this._northEast.lng) / 2); 1677 }, 1678 1679 // @method getSouthWest(): LatLng 1680 // Returns the south-west point of the bounds. 1681 getSouthWest: function () { 1682 return this._southWest; 1683 }, 1684 1685 // @method getNorthEast(): LatLng 1686 // Returns the north-east point of the bounds. 1687 getNorthEast: function () { 1688 return this._northEast; 1689 }, 1690 1691 // @method getNorthWest(): LatLng 1692 // Returns the north-west point of the bounds. 1693 getNorthWest: function () { 1694 return new LatLng(this.getNorth(), this.getWest()); 1695 }, 1696 1697 // @method getSouthEast(): LatLng 1698 // Returns the south-east point of the bounds. 1699 getSouthEast: function () { 1700 return new LatLng(this.getSouth(), this.getEast()); 1701 }, 1702 1703 // @method getWest(): Number 1704 // Returns the west longitude of the bounds 1705 getWest: function () { 1706 return this._southWest.lng; 1707 }, 1708 1709 // @method getSouth(): Number 1710 // Returns the south latitude of the bounds 1711 getSouth: function () { 1712 return this._southWest.lat; 1713 }, 1714 1715 // @method getEast(): Number 1716 // Returns the east longitude of the bounds 1717 getEast: function () { 1718 return this._northEast.lng; 1719 }, 1720 1721 // @method getNorth(): Number 1722 // Returns the north latitude of the bounds 1723 getNorth: function () { 1724 return this._northEast.lat; 1725 }, 1726 1727 // @method contains(otherBounds: LatLngBounds): Boolean 1728 // Returns `true` if the rectangle contains the given one. 1729 1730 // @alternative 1731 // @method contains (latlng: LatLng): Boolean 1732 // Returns `true` if the rectangle contains the given point. 1733 contains: function (obj) { // (LatLngBounds) or (LatLng) -> Boolean 1734 if (typeof obj[0] === 'number' || obj instanceof LatLng || 'lat' in obj) { 1735 obj = toLatLng(obj); 1736 } else { 1737 obj = toLatLngBounds(obj); 1738 } 1739 1740 var sw = this._southWest, 1741 ne = this._northEast, 1742 sw2, ne2; 1743 1744 if (obj instanceof LatLngBounds) { 1745 sw2 = obj.getSouthWest(); 1746 ne2 = obj.getNorthEast(); 1747 } else { 1748 sw2 = ne2 = obj; 1749 } 1750 1751 return (sw2.lat >= sw.lat) && (ne2.lat <= ne.lat) && 1752 (sw2.lng >= sw.lng) && (ne2.lng <= ne.lng); 1753 }, 1754 1755 // @method intersects(otherBounds: LatLngBounds): Boolean 1756 // Returns `true` if the rectangle intersects the given bounds. Two bounds intersect if they have at least one point in common. 1757 intersects: function (bounds) { 1758 bounds = toLatLngBounds(bounds); 1759 1760 var sw = this._southWest, 1761 ne = this._northEast, 1762 sw2 = bounds.getSouthWest(), 1763 ne2 = bounds.getNorthEast(), 1764 1765 latIntersects = (ne2.lat >= sw.lat) && (sw2.lat <= ne.lat), 1766 lngIntersects = (ne2.lng >= sw.lng) && (sw2.lng <= ne.lng); 1767 1768 return latIntersects && lngIntersects; 1769 }, 1770 1771 // @method overlaps(otherBounds: Bounds): Boolean 1772 // Returns `true` if the rectangle overlaps the given bounds. Two bounds overlap if their intersection is an area. 1773 overlaps: function (bounds) { 1774 bounds = toLatLngBounds(bounds); 1775 1776 var sw = this._southWest, 1777 ne = this._northEast, 1778 sw2 = bounds.getSouthWest(), 1779 ne2 = bounds.getNorthEast(), 1780 1781 latOverlaps = (ne2.lat > sw.lat) && (sw2.lat < ne.lat), 1782 lngOverlaps = (ne2.lng > sw.lng) && (sw2.lng < ne.lng); 1783 1784 return latOverlaps && lngOverlaps; 1785 }, 1786 1787 // @method toBBoxString(): String 1788 // Returns a string with bounding box coordinates in a 'southwest_lng,southwest_lat,northeast_lng,northeast_lat' format. Useful for sending requests to web services that return geo data. 1789 toBBoxString: function () { 1790 return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(','); 1791 }, 1792 1793 // @method equals(otherBounds: LatLngBounds, maxMargin?: Number): Boolean 1794 // Returns `true` if the rectangle is equivalent (within a small margin of error) to the given bounds. The margin of error can be overridden by setting `maxMargin` to a small number. 1795 equals: function (bounds, maxMargin) { 1796 if (!bounds) { return false; } 1797 1798 bounds = toLatLngBounds(bounds); 1799 1800 return this._southWest.equals(bounds.getSouthWest(), maxMargin) && 1801 this._northEast.equals(bounds.getNorthEast(), maxMargin); 1802 }, 1803 1804 // @method isValid(): Boolean 1805 // Returns `true` if the bounds are properly initialized. 1806 isValid: function () { 1807 return !!(this._southWest && this._northEast); 1808 } 1809}; 1810 1811// TODO International date line? 1812 1813// @factory L.latLngBounds(corner1: LatLng, corner2: LatLng) 1814// Creates a `LatLngBounds` object by defining two diagonally opposite corners of the rectangle. 1815 1816// @alternative 1817// @factory L.latLngBounds(latlngs: LatLng[]) 1818// Creates a `LatLngBounds` object defined by the geographical points it contains. Very useful for zooming the map to fit a particular set of locations with [`fitBounds`](#map-fitbounds). 1819function toLatLngBounds(a, b) { 1820 if (a instanceof LatLngBounds) { 1821 return a; 1822 } 1823 return new LatLngBounds(a, b); 1824} 1825 1826/* @class LatLng 1827 * @aka L.LatLng 1828 * 1829 * Represents a geographical point with a certain latitude and longitude. 1830 * 1831 * @example 1832 * 1833 * ``` 1834 * var latlng = L.latLng(50.5, 30.5); 1835 * ``` 1836 * 1837 * All Leaflet methods that accept LatLng objects also accept them in a simple Array form and simple object form (unless noted otherwise), so these lines are equivalent: 1838 * 1839 * ``` 1840 * map.panTo([50, 30]); 1841 * map.panTo({lon: 30, lat: 50}); 1842 * map.panTo({lat: 50, lng: 30}); 1843 * map.panTo(L.latLng(50, 30)); 1844 * ``` 1845 * 1846 * Note that `LatLng` does not inherit from Leaflet's `Class` object, 1847 * which means new classes can't inherit from it, and new methods 1848 * can't be added to it with the `include` function. 1849 */ 1850 1851 function LatLng(lat, lng, alt) { 1852 if (isNaN(lat) || isNaN(lng)) { 1853 throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')'); 1854 } 1855 1856 // @property lat: Number 1857 // Latitude in degrees 1858 this.lat = +lat; 1859 1860 // @property lng: Number 1861 // Longitude in degrees 1862 this.lng = +lng; 1863 1864 // @property alt: Number 1865 // Altitude in meters (optional) 1866 if (alt !== undefined) { 1867 this.alt = +alt; 1868 } 1869} 1870 1871LatLng.prototype = { 1872 // @method equals(otherLatLng: LatLng, maxMargin?: Number): Boolean 1873 // Returns `true` if the given `LatLng` point is at the same position (within a small margin of error). The margin of error can be overridden by setting `maxMargin` to a small number. 1874 equals: function (obj, maxMargin) { 1875 if (!obj) { return false; } 1876 1877 obj = toLatLng(obj); 1878 1879 var margin = Math.max( 1880 Math.abs(this.lat - obj.lat), 1881 Math.abs(this.lng - obj.lng)); 1882 1883 return margin <= (maxMargin === undefined ? 1.0E-9 : maxMargin); 1884 }, 1885 1886 // @method toString(): String 1887 // Returns a string representation of the point (for debugging purposes). 1888 toString: function (precision) { 1889 return 'LatLng(' + 1890 formatNum(this.lat, precision) + ', ' + 1891 formatNum(this.lng, precision) + ')'; 1892 }, 1893 1894 // @method distanceTo(otherLatLng: LatLng): Number 1895 // Returns the distance (in meters) to the given `LatLng` calculated using the [Spherical Law of Cosines](https://en.wikipedia.org/wiki/Spherical_law_of_cosines). 1896 distanceTo: function (other) { 1897 return Earth.distance(this, toLatLng(other)); 1898 }, 1899 1900 // @method wrap(): LatLng 1901 // Returns a new `LatLng` object with the longitude wrapped so it's always between -180 and +180 degrees. 1902 wrap: function () { 1903 return Earth.wrapLatLng(this); 1904 }, 1905 1906 // @method toBounds(sizeInMeters: Number): LatLngBounds 1907 // Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`. 1908 toBounds: function (sizeInMeters) { 1909 var latAccuracy = 180 * sizeInMeters / 40075017, 1910 lngAccuracy = latAccuracy / Math.cos((Math.PI / 180) * this.lat); 1911 1912 return toLatLngBounds( 1913 [this.lat - latAccuracy, this.lng - lngAccuracy], 1914 [this.lat + latAccuracy, this.lng + lngAccuracy]); 1915 }, 1916 1917 clone: function () { 1918 return new LatLng(this.lat, this.lng, this.alt); 1919 } 1920}; 1921 1922 1923 1924// @factory L.latLng(latitude: Number, longitude: Number, altitude?: Number): LatLng 1925// Creates an object representing a geographical point with the given latitude and longitude (and optionally altitude). 1926 1927// @alternative 1928// @factory L.latLng(coords: Array): LatLng 1929// Expects an array of the form `[Number, Number]` or `[Number, Number, Number]` instead. 1930 1931// @alternative 1932// @factory L.latLng(coords: Object): LatLng 1933// Expects an plain object of the form `{lat: Number, lng: Number}` or `{lat: Number, lng: Number, alt: Number}` instead. 1934 1935function toLatLng(a, b, c) { 1936 if (a instanceof LatLng) { 1937 return a; 1938 } 1939 if (isArray(a) && typeof a[0] !== 'object') { 1940 if (a.length === 3) { 1941 return new LatLng(a[0], a[1], a[2]); 1942 } 1943 if (a.length === 2) { 1944 return new LatLng(a[0], a[1]); 1945 } 1946 return null; 1947 } 1948 if (a === undefined || a === null) { 1949 return a; 1950 } 1951 if (typeof a === 'object' && 'lat' in a) { 1952 return new LatLng(a.lat, 'lng' in a ? a.lng : a.lon, a.alt); 1953 } 1954 if (b === undefined) { 1955 return null; 1956 } 1957 return new LatLng(a, b, c); 1958} 1959 1960/* 1961 * @namespace CRS 1962 * @crs L.CRS.Base 1963 * Object that defines coordinate reference systems for projecting 1964 * geographical points into pixel (screen) coordinates and back (and to 1965 * coordinates in other units for [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services). See 1966 * [spatial reference system](http://en.wikipedia.org/wiki/Coordinate_reference_system). 1967 * 1968 * Leaflet defines the most usual CRSs by default. If you want to use a 1969 * CRS not defined by default, take a look at the 1970 * [Proj4Leaflet](https://github.com/kartena/Proj4Leaflet) plugin. 1971 * 1972 * Note that the CRS instances do not inherit from Leafet's `Class` object, 1973 * and can't be instantiated. Also, new classes can't inherit from them, 1974 * and methods can't be added to them with the `include` function. 1975 */ 1976 1977 var CRS = { 1978 // @method latLngToPoint(latlng: LatLng, zoom: Number): Point 1979 // Projects geographical coordinates into pixel coordinates for a given zoom. 1980 latLngToPoint: function (latlng, zoom) { 1981 var projectedPoint = this.projection.project(latlng), 1982 scale = this.scale(zoom); 1983 1984 return this.transformation._transform(projectedPoint, scale); 1985 }, 1986 1987 // @method pointToLatLng(point: Point, zoom: Number): LatLng 1988 // The inverse of `latLngToPoint`. Projects pixel coordinates on a given 1989 // zoom into geographical coordinates. 1990 pointToLatLng: function (point, zoom) { 1991 var scale = this.scale(zoom), 1992 untransformedPoint = this.transformation.untransform(point, scale); 1993 1994 return this.projection.unproject(untransformedPoint); 1995 }, 1996 1997 // @method project(latlng: LatLng): Point 1998 // Projects geographical coordinates into coordinates in units accepted for 1999 // this CRS (e.g. meters for EPSG:3857, for passing it to WMS services). 2000 project: function (latlng) { 2001 return this.projection.project(latlng); 2002 }, 2003 2004 // @method unproject(point: Point): LatLng 2005 // Given a projected coordinate returns the corresponding LatLng. 2006 // The inverse of `project`. 2007 unproject: function (point) { 2008 return this.projection.unproject(point); 2009 }, 2010 2011 // @method scale(zoom: Number): Number 2012 // Returns the scale used when transforming projected coordinates into 2013 // pixel coordinates for a particular zoom. For example, it returns 2014 // `256 * 2^zoom` for Mercator-based CRS. 2015 scale: function (zoom) { 2016 return 256 * Math.pow(2, zoom); 2017 }, 2018 2019 // @method zoom(scale: Number): Number 2020 // Inverse of `scale()`, returns the zoom level corresponding to a scale 2021 // factor of `scale`. 2022 zoom: function (scale) { 2023 return Math.log(scale / 256) / Math.LN2; 2024 }, 2025 2026 // @method getProjectedBounds(zoom: Number): Bounds 2027 // Returns the projection's bounds scaled and transformed for the provided `zoom`. 2028 getProjectedBounds: function (zoom) { 2029 if (this.infinite) { return null; } 2030 2031 var b = this.projection.bounds, 2032 s = this.scale(zoom), 2033 min = this.transformation.transform(b.min, s), 2034 max = this.transformation.transform(b.max, s); 2035 2036 return new Bounds(min, max); 2037 }, 2038 2039 // @method distance(latlng1: LatLng, latlng2: LatLng): Number 2040 // Returns the distance between two geographical coordinates. 2041 2042 // @property code: String 2043 // Standard code name of the CRS passed into WMS services (e.g. `'EPSG:3857'`) 2044 // 2045 // @property wrapLng: Number[] 2046 // An array of two numbers defining whether the longitude (horizontal) coordinate 2047 // axis wraps around a given range and how. Defaults to `[-180, 180]` in most 2048 // geographical CRSs. If `undefined`, the longitude axis does not wrap around. 2049 // 2050 // @property wrapLat: Number[] 2051 // Like `wrapLng`, but for the latitude (vertical) axis. 2052 2053 // wrapLng: [min, max], 2054 // wrapLat: [min, max], 2055 2056 // @property infinite: Boolean 2057 // If true, the coordinate space will be unbounded (infinite in both axes) 2058 infinite: false, 2059 2060 // @method wrapLatLng(latlng: LatLng): LatLng 2061 // Returns a `LatLng` where lat and lng has been wrapped according to the 2062 // CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds. 2063 wrapLatLng: function (latlng) { 2064 var lng = this.wrapLng ? wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng, 2065 lat = this.wrapLat ? wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat, 2066 alt = latlng.alt; 2067 2068 return new LatLng(lat, lng, alt); 2069 }, 2070 2071 // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds 2072 // Returns a `LatLngBounds` with the same size as the given one, ensuring 2073 // that its center is within the CRS's bounds. 2074 // Only accepts actual `L.LatLngBounds` instances, not arrays. 2075 wrapLatLngBounds: function (bounds) { 2076 var center = bounds.getCenter(), 2077 newCenter = this.wrapLatLng(center), 2078 latShift = center.lat - newCenter.lat, 2079 lngShift = center.lng - newCenter.lng; 2080 2081 if (latShift === 0 && lngShift === 0) { 2082 return bounds; 2083 } 2084 2085 var sw = bounds.getSouthWest(), 2086 ne = bounds.getNorthEast(), 2087 newSw = new LatLng(sw.lat - latShift, sw.lng - lngShift), 2088 newNe = new LatLng(ne.lat - latShift, ne.lng - lngShift); 2089 2090 return new LatLngBounds(newSw, newNe); 2091 } 2092}; 2093 2094/* 2095 * @namespace CRS 2096 * @crs L.CRS.Earth 2097 * 2098 * Serves as the base for CRS that are global such that they cover the earth. 2099 * Can only be used as the base for other CRS and cannot be used directly, 2100 * since it does not have a `code`, `projection` or `transformation`. `distance()` returns 2101 * meters. 2102 */ 2103 2104 var Earth = extend({}, CRS, { 2105 wrapLng: [-180, 180], 2106 2107 // Mean Earth Radius, as recommended for use by 2108 // the International Union of Geodesy and Geophysics, 2109 // see http://rosettacode.org/wiki/Haversine_formula 2110 R: 6371000, 2111 2112 // distance between two geographical points using spherical law of cosines approximation 2113 distance: function (latlng1, latlng2) { 2114 var rad = Math.PI / 180, 2115 lat1 = latlng1.lat * rad, 2116 lat2 = latlng2.lat * rad, 2117 sinDLat = Math.sin((latlng2.lat - latlng1.lat) * rad / 2), 2118 sinDLon = Math.sin((latlng2.lng - latlng1.lng) * rad / 2), 2119 a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon, 2120 c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 2121 return this.R * c; 2122 } 2123}); 2124 2125/* 2126 * @namespace Projection 2127 * @projection L.Projection.SphericalMercator 2128 * 2129 * Spherical Mercator projection — the most common projection for online maps, 2130 * used by almost all free and commercial tile providers. Assumes that Earth is 2131 * a sphere. Used by the `EPSG:3857` CRS. 2132 */ 2133 2134 var earthRadius = 6378137; 2135 2136 var SphericalMercator = { 2137 2138 R: earthRadius, 2139 MAX_LATITUDE: 85.0511287798, 2140 2141 project: function (latlng) { 2142 var d = Math.PI / 180, 2143 max = this.MAX_LATITUDE, 2144 lat = Math.max(Math.min(max, latlng.lat), -max), 2145 sin = Math.sin(lat * d); 2146 2147 return new Point( 2148 this.R * latlng.lng * d, 2149 this.R * Math.log((1 + sin) / (1 - sin)) / 2); 2150 }, 2151 2152 unproject: function (point) { 2153 var d = 180 / Math.PI; 2154 2155 return new LatLng( 2156 (2 * Math.atan(Math.exp(point.y / this.R)) - (Math.PI / 2)) * d, 2157 point.x * d / this.R); 2158 }, 2159 2160 bounds: (function () { 2161 var d = earthRadius * Math.PI; 2162 return new Bounds([-d, -d], [d, d]); 2163 })() 2164}; 2165 2166/* 2167 * @class Transformation 2168 * @aka L.Transformation 2169 * 2170 * Represents an affine transformation: a set of coefficients `a`, `b`, `c`, `d` 2171 * for transforming a point of a form `(x, y)` into `(a*x + b, c*y + d)` and doing 2172 * the reverse. Used by Leaflet in its projections code. 2173 * 2174 * @example 2175 * 2176 * ```js 2177 * var transformation = L.transformation(2, 5, -1, 10), 2178 * p = L.point(1, 2), 2179 * p2 = transformation.transform(p), // L.point(7, 8) 2180 * p3 = transformation.untransform(p2); // L.point(1, 2) 2181 * ``` 2182 */ 2183 2184 2185// factory new L.Transformation(a: Number, b: Number, c: Number, d: Number) 2186// Creates a `Transformation` object with the given coefficients. 2187function Transformation(a, b, c, d) { 2188 if (isArray(a)) { 2189 // use array properties 2190 this._a = a[0]; 2191 this._b = a[1]; 2192 this._c = a[2]; 2193 this._d = a[3]; 2194 return; 2195 } 2196 this._a = a; 2197 this._b = b; 2198 this._c = c; 2199 this._d = d; 2200} 2201 2202Transformation.prototype = { 2203 // @method transform(point: Point, scale?: Number): Point 2204 // Returns a transformed point, optionally multiplied by the given scale. 2205 // Only accepts actual `L.Point` instances, not arrays. 2206 transform: function (point, scale) { // (Point, Number) -> Point 2207 return this._transform(point.clone(), scale); 2208 }, 2209 2210 // destructive transform (faster) 2211 _transform: function (point, scale) { 2212 scale = scale || 1; 2213 point.x = scale * (this._a * point.x + this._b); 2214 point.y = scale * (this._c * point.y + this._d); 2215 return point; 2216 }, 2217 2218 // @method untransform(point: Point, scale?: Number): Point 2219 // Returns the reverse transformation of the given point, optionally divided 2220 // by the given scale. Only accepts actual `L.Point` instances, not arrays. 2221 untransform: function (point, scale) { 2222 scale = scale || 1; 2223 return new Point( 2224 (point.x / scale - this._b) / this._a, 2225 (point.y / scale - this._d) / this._c); 2226 } 2227}; 2228 2229// factory L.transformation(a: Number, b: Number, c: Number, d: Number) 2230 2231// @factory L.transformation(a: Number, b: Number, c: Number, d: Number) 2232// Instantiates a Transformation object with the given coefficients. 2233 2234// @alternative 2235// @factory L.transformation(coefficients: Array): Transformation 2236// Expects an coefficients array of the form 2237// `[a: Number, b: Number, c: Number, d: Number]`. 2238 2239function toTransformation(a, b, c, d) { 2240 return new Transformation(a, b, c, d); 2241} 2242 2243/* 2244 * @namespace CRS 2245 * @crs L.CRS.EPSG3857 2246 * 2247 * The most common CRS for online maps, used by almost all free and commercial 2248 * tile providers. Uses Spherical Mercator projection. Set in by default in 2249 * Map's `crs` option. 2250 */ 2251 2252 var EPSG3857 = extend({}, Earth, { 2253 code: 'EPSG:3857', 2254 projection: SphericalMercator, 2255 2256 transformation: (function () { 2257 var scale = 0.5 / (Math.PI * SphericalMercator.R); 2258 return toTransformation(scale, 0.5, -scale, 0.5); 2259 }()) 2260 }); 2261 2262 var EPSG900913 = extend({}, EPSG3857, { 2263 code: 'EPSG:900913' 2264 }); 2265 2266// @namespace SVG; @section 2267// There are several static functions which can be called without instantiating L.SVG: 2268 2269// @function create(name: String): SVGElement 2270// Returns a instance of [SVGElement](https://developer.mozilla.org/docs/Web/API/SVGElement), 2271// corresponding to the class name passed. For example, using 'line' will return 2272// an instance of [SVGLineElement](https://developer.mozilla.org/docs/Web/API/SVGLineElement). 2273function svgCreate(name) { 2274 return document.createElementNS('http://www.w3.org/2000/svg', name); 2275} 2276 2277// @function pointsToPath(rings: Point[], closed: Boolean): String 2278// Generates a SVG path string for multiple rings, with each ring turning 2279// into "M..L..L.." instructions 2280function pointsToPath(rings, closed) { 2281 var str = '', 2282 i, j, len, len2, points, p; 2283 2284 for (i = 0, len = rings.length; i < len; i++) { 2285 points = rings[i]; 2286 2287 for (j = 0, len2 = points.length; j < len2; j++) { 2288 p = points[j]; 2289 str += (j ? 'L' : 'M') + p.x + ' ' + p.y; 2290 } 2291 2292 // closes the ring for polygons; "x" is VML syntax 2293 str += closed ? (svg ? 'z' : 'x') : ''; 2294 } 2295 2296 // SVG complains about empty path strings 2297 return str || 'M0 0'; 2298} 2299 2300/* 2301 * @namespace Browser 2302 * @aka L.Browser 2303 * 2304 * A namespace with static properties for browser/feature detection used by Leaflet internally. 2305 * 2306 * @example 2307 * 2308 * ```js 2309 * if (L.Browser.ielt9) { 2310 * alert('Upgrade your browser, dude!'); 2311 * } 2312 * ``` 2313 */ 2314 2315 var style$1 = document.documentElement.style; 2316 2317// @property ie: Boolean; `true` for all Internet Explorer versions (not Edge). 2318var ie = 'ActiveXObject' in window; 2319 2320// @property ielt9: Boolean; `true` for Internet Explorer versions less than 9. 2321var ielt9 = ie && !document.addEventListener; 2322 2323// @property edge: Boolean; `true` for the Edge web browser. 2324var edge = 'msLaunchUri' in navigator && !('documentMode' in document); 2325 2326// @property webkit: Boolean; 2327// `true` for webkit-based browsers like Chrome and Safari (including mobile versions). 2328var webkit = userAgentContains('webkit'); 2329 2330// @property android: Boolean 2331// `true` for any browser running on an Android platform. 2332var android = userAgentContains('android'); 2333 2334// @property android23: Boolean; `true` for browsers running on Android 2 or Android 3. 2335var android23 = userAgentContains('android 2') || userAgentContains('android 3'); 2336 2337/* See https://stackoverflow.com/a/17961266 for details on detecting stock Android */ 2338var webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); // also matches AppleWebKit 2339// @property androidStock: Boolean; `true` for the Android stock browser (i.e. not Chrome) 2340var androidStock = android && userAgentContains('Google') && webkitVer < 537 && !('AudioNode' in window); 2341 2342// @property opera: Boolean; `true` for the Opera browser 2343var opera = !!window.opera; 2344 2345// @property chrome: Boolean; `true` for the Chrome browser. 2346var chrome = userAgentContains('chrome'); 2347 2348// @property gecko: Boolean; `true` for gecko-based browsers like Firefox. 2349var gecko = userAgentContains('gecko') && !webkit && !opera && !ie; 2350 2351// @property safari: Boolean; `true` for the Safari browser. 2352var safari = !chrome && userAgentContains('safari'); 2353 2354var phantom = userAgentContains('phantom'); 2355 2356// @property opera12: Boolean 2357// `true` for the Opera browser supporting CSS transforms (version 12 or later). 2358var opera12 = 'OTransition' in style$1; 2359 2360// @property win: Boolean; `true` when the browser is running in a Windows platform 2361var win = navigator.platform.indexOf('Win') === 0; 2362 2363// @property ie3d: Boolean; `true` for all Internet Explorer versions supporting CSS transforms. 2364var ie3d = ie && ('transition' in style$1); 2365 2366// @property webkit3d: Boolean; `true` for webkit-based browsers supporting CSS transforms. 2367var webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23; 2368 2369// @property gecko3d: Boolean; `true` for gecko-based browsers supporting CSS transforms. 2370var gecko3d = 'MozPerspective' in style$1; 2371 2372// @property any3d: Boolean 2373// `true` for all browsers supporting CSS transforms. 2374var any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d) && !opera12 && !phantom; 2375 2376// @property mobile: Boolean; `true` for all browsers running in a mobile device. 2377var mobile = typeof orientation !== 'undefined' || userAgentContains('mobile'); 2378 2379// @property mobileWebkit: Boolean; `true` for all webkit-based browsers in a mobile device. 2380var mobileWebkit = mobile && webkit; 2381 2382// @property mobileWebkit3d: Boolean 2383// `true` for all webkit-based browsers in a mobile device supporting CSS transforms. 2384var mobileWebkit3d = mobile && webkit3d; 2385 2386// @property msPointer: Boolean 2387// `true` for browsers implementing the Microsoft touch events model (notably IE10). 2388var msPointer = !window.PointerEvent && window.MSPointerEvent; 2389 2390// @property pointer: Boolean 2391// `true` for all browsers supporting [pointer events](https://msdn.microsoft.com/en-us/library/dn433244%28v=vs.85%29.aspx). 2392var pointer = !!(window.PointerEvent || msPointer); 2393 2394// @property touch: Boolean 2395// `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events). 2396// This does not necessarily mean that the browser is running in a computer with 2397// a touchscreen, it only means that the browser is capable of understanding 2398// touch events. 2399var touch = !window.L_NO_TOUCH && (pointer || 'ontouchstart' in window || 2400 (window.DocumentTouch && document instanceof window.DocumentTouch)); 2401 2402// @property mobileOpera: Boolean; `true` for the Opera browser in a mobile device. 2403var mobileOpera = mobile && opera; 2404 2405// @property mobileGecko: Boolean 2406// `true` for gecko-based browsers running in a mobile device. 2407var mobileGecko = mobile && gecko; 2408 2409// @property retina: Boolean 2410// `true` for browsers on a high-resolution "retina" screen or on any screen when browser's display zoom is more than 100%. 2411var retina = (window.devicePixelRatio || (window.screen.deviceXDPI / window.screen.logicalXDPI)) > 1; 2412 2413 2414// @property canvas: Boolean 2415// `true` when the browser supports [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API). 2416var canvas = (function () { 2417 return !!document.createElement('canvas').getContext; 2418}()); 2419 2420// @property svg: Boolean 2421// `true` when the browser supports [SVG](https://developer.mozilla.org/docs/Web/SVG). 2422var svg = !!(document.createElementNS && svgCreate('svg').createSVGRect); 2423 2424// @property vml: Boolean 2425// `true` if the browser supports [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language). 2426var vml = !svg && (function () { 2427 try { 2428 var div = document.createElement('div'); 2429 div.innerHTML = '<v:shape adj="1"/>'; 2430 2431 var shape = div.firstChild; 2432 shape.style.behavior = 'url(#default#VML)'; 2433 2434 return shape && (typeof shape.adj === 'object'); 2435 2436 } catch (e) { 2437 return false; 2438 } 2439}()); 2440 2441 2442function userAgentContains(str) { 2443 return navigator.userAgent.toLowerCase().indexOf(str) >= 0; 2444} 2445 2446 2447var Browser = (Object.freeze || Object)({ 2448 ie: ie, 2449 ielt9: ielt9, 2450 edge: edge, 2451 webkit: webkit, 2452 android: android, 2453 android23: android23, 2454 androidStock: androidStock, 2455 opera: opera, 2456 chrome: chrome, 2457 gecko: gecko, 2458 safari: safari, 2459 phantom: phantom, 2460 opera12: opera12, 2461 win: win, 2462 ie3d: ie3d, 2463 webkit3d: webkit3d, 2464 gecko3d: gecko3d, 2465 any3d: any3d, 2466 mobile: mobile, 2467 mobileWebkit: mobileWebkit, 2468 mobileWebkit3d: mobileWebkit3d, 2469 msPointer: msPointer, 2470 pointer: pointer, 2471 touch: touch, 2472 mobileOpera: mobileOpera, 2473 mobileGecko: mobileGecko, 2474 retina: retina, 2475 canvas: canvas, 2476 svg: svg, 2477 vml: vml 2478}); 2479 2480/* 2481 * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices. 2482 */ 2483 2484 2485 var POINTER_DOWN = msPointer ? 'MSPointerDown' : 'pointerdown'; 2486 var POINTER_MOVE = msPointer ? 'MSPointerMove' : 'pointermove'; 2487 var POINTER_UP = msPointer ? 'MSPointerUp' : 'pointerup'; 2488 var POINTER_CANCEL = msPointer ? 'MSPointerCancel' : 'pointercancel'; 2489 var TAG_WHITE_LIST = ['INPUT', 'SELECT', 'OPTION']; 2490 2491 var _pointers = {}; 2492 var _pointerDocListener = false; 2493 2494// DomEvent.DoubleTap needs to know about this 2495var _pointersCount = 0; 2496 2497// Provides a touch events wrapper for (ms)pointer events. 2498// ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890 2499 2500function addPointerListener(obj, type, handler, id) { 2501 if (type === 'touchstart') { 2502 _addPointerStart(obj, handler, id); 2503 2504 } else if (type === 'touchmove') { 2505 _addPointerMove(obj, handler, id); 2506 2507 } else if (type === 'touchend') { 2508 _addPointerEnd(obj, handler, id); 2509 } 2510 2511 return this; 2512} 2513 2514function removePointerListener(obj, type, id) { 2515 var handler = obj['_leaflet_' + type + id]; 2516 2517 if (type === 'touchstart') { 2518 obj.removeEventListener(POINTER_DOWN, handler, false); 2519 2520 } else if (type === 'touchmove') { 2521 obj.removeEventListener(POINTER_MOVE, handler, false); 2522 2523 } else if (type === 'touchend') { 2524 obj.removeEventListener(POINTER_UP, handler, false); 2525 obj.removeEventListener(POINTER_CANCEL, handler, false); 2526 } 2527 2528 return this; 2529} 2530 2531function _addPointerStart(obj, handler, id) { 2532 var onDown = bind(function (e) { 2533 if (e.pointerType !== 'mouse' && e.MSPOINTER_TYPE_MOUSE && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) { 2534 // In IE11, some touch events needs to fire for form controls, or 2535 // the controls will stop working. We keep a whitelist of tag names that 2536 // need these events. For other target tags, we prevent default on the event. 2537 if (TAG_WHITE_LIST.indexOf(e.target.tagName) < 0) { 2538 preventDefault(e); 2539 } else { 2540 return; 2541 } 2542 } 2543 2544 _handlePointer(e, handler); 2545 }); 2546 2547 obj['_leaflet_touchstart' + id] = onDown; 2548 obj.addEventListener(POINTER_DOWN, onDown, false); 2549 2550 // need to keep track of what pointers and how many are active to provide e.touches emulation 2551 if (!_pointerDocListener) { 2552 // we listen documentElement as any drags that end by moving the touch off the screen get fired there 2553 document.documentElement.addEventListener(POINTER_DOWN, _globalPointerDown, true); 2554 document.documentElement.addEventListener(POINTER_MOVE, _globalPointerMove, true); 2555 document.documentElement.addEventListener(POINTER_UP, _globalPointerUp, true); 2556 document.documentElement.addEventListener(POINTER_CANCEL, _globalPointerUp, true); 2557 2558 _pointerDocListener = true; 2559 } 2560} 2561 2562function _globalPointerDown(e) { 2563 _pointers[e.pointerId] = e; 2564 _pointersCount++; 2565} 2566 2567function _globalPointerMove(e) { 2568 if (_pointers[e.pointerId]) { 2569 _pointers[e.pointerId] = e; 2570 } 2571} 2572 2573function _globalPointerUp(e) { 2574 delete _pointers[e.pointerId]; 2575 _pointersCount--; 2576} 2577 2578function _handlePointer(e, handler) { 2579 e.touches = []; 2580 for (var i in _pointers) { 2581 e.touches.push(_pointers[i]); 2582 } 2583 e.changedTouches = [e]; 2584 2585 handler(e); 2586} 2587 2588function _addPointerMove(obj, handler, id) { 2589 var onMove = function (e) { 2590 // don't fire touch moves when mouse isn't down 2591 if ((e.pointerType === e.MSPOINTER_TYPE_MOUSE || e.pointerType === 'mouse') && e.buttons === 0) { return; } 2592 2593 _handlePointer(e, handler); 2594 }; 2595 2596 obj['_leaflet_touchmove' + id] = onMove; 2597 obj.addEventListener(POINTER_MOVE, onMove, false); 2598} 2599 2600function _addPointerEnd(obj, handler, id) { 2601 var onUp = function (e) { 2602 _handlePointer(e, handler); 2603 }; 2604 2605 obj['_leaflet_touchend' + id] = onUp; 2606 obj.addEventListener(POINTER_UP, onUp, false); 2607 obj.addEventListener(POINTER_CANCEL, onUp, false); 2608} 2609 2610/* 2611 * Extends the event handling code with double tap support for mobile browsers. 2612 */ 2613 2614 var _touchstart = msPointer ? 'MSPointerDown' : pointer ? 'pointerdown' : 'touchstart'; 2615 var _touchend = msPointer ? 'MSPointerUp' : pointer ? 'pointerup' : 'touchend'; 2616 var _pre = '_leaflet_'; 2617 2618// inspired by Zepto touch code by Thomas Fuchs 2619function addDoubleTapListener(obj, handler, id) { 2620 var last, touch$$1, 2621 doubleTap = false, 2622 delay = 250; 2623 2624 function onTouchStart(e) { 2625 var count; 2626 2627 if (pointer) { 2628 if ((!edge) || e.pointerType === 'mouse') { return; } 2629 count = _pointersCount; 2630 } else { 2631 count = e.touches.length; 2632 } 2633 2634 if (count > 1) { return; } 2635 2636 var now = Date.now(), 2637 delta = now - (last || now); 2638 2639 touch$$1 = e.touches ? e.touches[0] : e; 2640 doubleTap = (delta > 0 && delta <= delay); 2641 last = now; 2642} 2643 2644function onTouchEnd(e) { 2645 if (doubleTap && !touch$$1.cancelBubble) { 2646 if (pointer) { 2647 if ((!edge) || e.pointerType === 'mouse') { return; } 2648 // work around .type being readonly with MSPointer* events 2649 var newTouch = {}, 2650 prop, i; 2651 2652 for (i in touch$$1) { 2653 prop = touch$$1[i]; 2654 newTouch[i] = prop && prop.bind ? prop.bind(touch$$1) : prop; 2655 } 2656 touch$$1 = newTouch; 2657 } 2658 touch$$1.type = 'dblclick'; 2659 touch$$1.button = 0; 2660 handler(touch$$1); 2661 last = null; 2662 } 2663 } 2664 2665 obj[_pre + _touchstart + id] = onTouchStart; 2666 obj[_pre + _touchend + id] = onTouchEnd; 2667 obj[_pre + 'dblclick' + id] = handler; 2668 2669 obj.addEventListener(_touchstart, onTouchStart, false); 2670 obj.addEventListener(_touchend, onTouchEnd, false); 2671 2672 // On some platforms (notably, chrome<55 on win10 + touchscreen + mouse), 2673 // the browser doesn't fire touchend/pointerup events but does fire 2674 // native dblclicks. See #4127. 2675 // Edge 14 also fires native dblclicks, but only for pointerType mouse, see #5180. 2676 obj.addEventListener('dblclick', handler, false); 2677 2678 return this; 2679} 2680 2681function removeDoubleTapListener(obj, id) { 2682 var touchstart = obj[_pre + _touchstart + id], 2683 touchend = obj[_pre + _touchend + id], 2684 dblclick = obj[_pre + 'dblclick' + id]; 2685 2686 obj.removeEventListener(_touchstart, touchstart, false); 2687 obj.removeEventListener(_touchend, touchend, false); 2688 if (!edge) { 2689 obj.removeEventListener('dblclick', dblclick, false); 2690} 2691 2692return this; 2693} 2694 2695/* 2696 * @namespace DomUtil 2697 * 2698 * Utility functions to work with the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) 2699 * tree, used by Leaflet internally. 2700 * 2701 * Most functions expecting or returning a `HTMLElement` also work for 2702 * SVG elements. The only difference is that classes refer to CSS classes 2703 * in HTML and SVG classes in SVG. 2704 */ 2705 2706 2707// @property TRANSFORM: String 2708// Vendor-prefixed transform style name (e.g. `'webkitTransform'` for WebKit). 2709var TRANSFORM = testProp( 2710 ['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform']); 2711 2712// webkitTransition comes first because some browser versions that drop vendor prefix don't do 2713// the same for the transitionend event, in particular the Android 4.1 stock browser 2714 2715// @property TRANSITION: String 2716// Vendor-prefixed transition style name. 2717var TRANSITION = testProp( 2718 ['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']); 2719 2720// @property TRANSITION_END: String 2721// Vendor-prefixed transitionend event name. 2722var TRANSITION_END = 2723TRANSITION === 'webkitTransition' || TRANSITION === 'OTransition' ? TRANSITION + 'End' : 'transitionend'; 2724 2725 2726// @function get(id: String|HTMLElement): HTMLElement 2727// Returns an element given its DOM id, or returns the element itself 2728// if it was passed directly. 2729function get(id) { 2730 return typeof id === 'string' ? document.getElementById(id) : id; 2731} 2732 2733// @function getStyle(el: HTMLElement, styleAttrib: String): String 2734// Returns the value for a certain style attribute on an element, 2735// including computed values or values set through CSS. 2736function getStyle(el, style) { 2737 var value = el.style[style] || (el.currentStyle && el.currentStyle[style]); 2738 2739 if ((!value || value === 'auto') && document.defaultView) { 2740 var css = document.defaultView.getComputedStyle(el, null); 2741 value = css ? css[style] : null; 2742 } 2743 return value === 'auto' ? null : value; 2744} 2745 2746// @function create(tagName: String, className?: String, container?: HTMLElement): HTMLElement 2747// Creates an HTML element with `tagName`, sets its class to `className`, and optionally appends it to `container` element. 2748function create$1(tagName, className, container) { 2749 var el = document.createElement(tagName); 2750 el.className = className || ''; 2751 2752 if (container) { 2753 container.appendChild(el); 2754 } 2755 return el; 2756} 2757 2758// @function remove(el: HTMLElement) 2759// Removes `el` from its parent element 2760function remove(el) { 2761 var parent = el.parentNode; 2762 if (parent) { 2763 parent.removeChild(el); 2764 } 2765} 2766 2767// @function empty(el: HTMLElement) 2768// Removes all of `el`'s children elements from `el` 2769function empty(el) { 2770 while (el.firstChild) { 2771 el.removeChild(el.firstChild); 2772 } 2773} 2774 2775// @function toFront(el: HTMLElement) 2776// Makes `el` the last child of its parent, so it renders in front of the other children. 2777function toFront(el) { 2778 var parent = el.parentNode; 2779 if (parent && parent.lastChild !== el) { 2780 parent.appendChild(el); 2781 } 2782} 2783 2784// @function toBack(el: HTMLElement) 2785// Makes `el` the first child of its parent, so it renders behind the other children. 2786function toBack(el) { 2787 var parent = el.parentNode; 2788 if (parent && parent.firstChild !== el) { 2789 parent.insertBefore(el, parent.firstChild); 2790 } 2791} 2792 2793// @function hasClass(el: HTMLElement, name: String): Boolean 2794// Returns `true` if the element's class attribute contains `name`. 2795function hasClass(el, name) { 2796 if (el.classList !== undefined) { 2797 return el.classList.contains(name); 2798 } 2799 var className = getClass(el); 2800 return className.length > 0 && new RegExp('(^|\\s)' + name + '(\\s|$)').test(className); 2801} 2802 2803// @function addClass(el: HTMLElement, name: String) 2804// Adds `name` to the element's class attribute. 2805function addClass(el, name) { 2806 if (el.classList !== undefined) { 2807 var classes = splitWords(name); 2808 for (var i = 0, len = classes.length; i < len; i++) { 2809 el.classList.add(classes[i]); 2810 } 2811 } else if (!hasClass(el, name)) { 2812 var className = getClass(el); 2813 setClass(el, (className ? className + ' ' : '') + name); 2814 } 2815} 2816 2817// @function removeClass(el: HTMLElement, name: String) 2818// Removes `name` from the element's class attribute. 2819function removeClass(el, name) { 2820 if (el.classList !== undefined) { 2821 el.classList.remove(name); 2822 } else { 2823 setClass(el, trim((' ' + getClass(el) + ' ').replace(' ' + name + ' ', ' '))); 2824 } 2825} 2826 2827// @function setClass(el: HTMLElement, name: String) 2828// Sets the element's class. 2829function setClass(el, name) { 2830 if (el.className.baseVal === undefined) { 2831 el.className = name; 2832 } else { 2833 // in case of SVG element 2834 el.className.baseVal = name; 2835 } 2836} 2837 2838// @function getClass(el: HTMLElement): String 2839// Returns the element's class. 2840function getClass(el) { 2841 // Check if the element is an SVGElementInstance and use the correspondingElement instead 2842 // (Required for linked SVG elements in IE11.) 2843 if (el.correspondingElement) { 2844 el = el.correspondingElement; 2845 } 2846 return el.className.baseVal === undefined ? el.className : el.className.baseVal; 2847} 2848 2849// @function setOpacity(el: HTMLElement, opacity: Number) 2850// Set the opacity of an element (including old IE support). 2851// `opacity` must be a number from `0` to `1`. 2852function setOpacity(el, value) { 2853 if ('opacity' in el.style) { 2854 el.style.opacity = value; 2855 } else if ('filter' in el.style) { 2856 _setOpacityIE(el, value); 2857 } 2858} 2859 2860function _setOpacityIE(el, value) { 2861 var filter = false, 2862 filterName = 'DXImageTransform.Microsoft.Alpha'; 2863 2864 // filters collection throws an error if we try to retrieve a filter that doesn't exist 2865 try { 2866 filter = el.filters.item(filterName); 2867 } catch (e) { 2868 // don't set opacity to 1 if we haven't already set an opacity, 2869 // it isn't needed and breaks transparent pngs. 2870 if (value === 1) { return; } 2871 } 2872 2873 value = Math.round(value * 100); 2874 2875 if (filter) { 2876 filter.Enabled = (value !== 100); 2877 filter.Opacity = value; 2878 } else { 2879 el.style.filter += ' progid:' + filterName + '(opacity=' + value + ')'; 2880 } 2881} 2882 2883// @function testProp(props: String[]): String|false 2884// Goes through the array of style names and returns the first name 2885// that is a valid style name for an element. If no such name is found, 2886// it returns false. Useful for vendor-prefixed styles like `transform`. 2887function testProp(props) { 2888 var style = document.documentElement.style; 2889 2890 for (var i = 0; i < props.length; i++) { 2891 if (props[i] in style) { 2892 return props[i]; 2893 } 2894 } 2895 return false; 2896} 2897 2898// @function setTransform(el: HTMLElement, offset: Point, scale?: Number) 2899// Resets the 3D CSS transform of `el` so it is translated by `offset` pixels 2900// and optionally scaled by `scale`. Does not have an effect if the 2901// browser doesn't support 3D CSS transforms. 2902function setTransform(el, offset, scale) { 2903 var pos = offset || new Point(0, 0); 2904 2905 el.style[TRANSFORM] = 2906 (ie3d ? 2907 'translate(' + pos.x + 'px,' + pos.y + 'px)' : 2908 'translate3d(' + pos.x + 'px,' + pos.y + 'px,0)') + 2909 (scale ? ' scale(' + scale + ')' : ''); 2910} 2911 2912// @function setPosition(el: HTMLElement, position: Point) 2913// Sets the position of `el` to coordinates specified by `position`, 2914// using CSS translate or top/left positioning depending on the browser 2915// (used by Leaflet internally to position its layers). 2916function setPosition(el, point) { 2917 2918 /*eslint-disable */ 2919 el._leaflet_pos = point; 2920 /* eslint-enable */ 2921 2922 if (any3d) { 2923 setTransform(el, point); 2924 } else { 2925 el.style.left = point.x + 'px'; 2926 el.style.top = point.y + 'px'; 2927 } 2928} 2929 2930// @function getPosition(el: HTMLElement): Point 2931// Returns the coordinates of an element previously positioned with setPosition. 2932function getPosition(el) { 2933 // this method is only used for elements previously positioned using setPosition, 2934 // so it's safe to cache the position for performance 2935 2936 return el._leaflet_pos || new Point(0, 0); 2937} 2938 2939// @function disableTextSelection() 2940// Prevents the user from generating `selectstart` DOM events, usually generated 2941// when the user drags the mouse through a page with text. Used internally 2942// by Leaflet to override the behaviour of any click-and-drag interaction on 2943// the map. Affects drag interactions on the whole document. 2944 2945// @function enableTextSelection() 2946// Cancels the effects of a previous [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection). 2947var disableTextSelection; 2948var enableTextSelection; 2949var _userSelect; 2950if ('onselectstart' in document) { 2951 disableTextSelection = function () { 2952 on(window, 'selectstart', preventDefault); 2953 }; 2954 enableTextSelection = function () { 2955 off(window, 'selectstart', preventDefault); 2956 }; 2957} else { 2958 var userSelectProperty = testProp( 2959 ['userSelect', 'WebkitUserSelect', 'OUserSelect', 'MozUserSelect', 'msUserSelect']); 2960 2961 disableTextSelection = function () { 2962 if (userSelectProperty) { 2963 var style = document.documentElement.style; 2964 _userSelect = style[userSelectProperty]; 2965 style[userSelectProperty] = 'none'; 2966 } 2967 }; 2968 enableTextSelection = function () { 2969 if (userSelectProperty) { 2970 document.documentElement.style[userSelectProperty] = _userSelect; 2971 _userSelect = undefined; 2972 } 2973 }; 2974} 2975 2976// @function disableImageDrag() 2977// As [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection), but 2978// for `dragstart` DOM events, usually generated when the user drags an image. 2979function disableImageDrag() { 2980 on(window, 'dragstart', preventDefault); 2981} 2982 2983// @function enableImageDrag() 2984// Cancels the effects of a previous [`L.DomUtil.disableImageDrag`](#domutil-disabletextselection). 2985function enableImageDrag() { 2986 off(window, 'dragstart', preventDefault); 2987} 2988 2989var _outlineElement; 2990var _outlineStyle; 2991// @function preventOutline(el: HTMLElement) 2992// Makes the [outline](https://developer.mozilla.org/docs/Web/CSS/outline) 2993// of the element `el` invisible. Used internally by Leaflet to prevent 2994// focusable elements from displaying an outline when the user performs a 2995// drag interaction on them. 2996function preventOutline(element) { 2997 while (element.tabIndex === -1) { 2998 element = element.parentNode; 2999 } 3000 if (!element.style) { return; } 3001 restoreOutline(); 3002 _outlineElement = element; 3003 _outlineStyle = element.style.outline; 3004 element.style.outline = 'none'; 3005 on(window, 'keydown', restoreOutline); 3006} 3007 3008// @function restoreOutline() 3009// Cancels the effects of a previous [`L.DomUtil.preventOutline`](). 3010function restoreOutline() { 3011 if (!_outlineElement) { return; } 3012 _outlineElement.style.outline = _outlineStyle; 3013 _outlineElement = undefined; 3014 _outlineStyle = undefined; 3015 off(window, 'keydown', restoreOutline); 3016} 3017 3018// @function getSizedParentNode(el: HTMLElement): HTMLElement 3019// Finds the closest parent node which size (width and height) is not null. 3020function getSizedParentNode(element) { 3021 do { 3022 element = element.parentNode; 3023 } while ((!element.offsetWidth || !element.offsetHeight) && element !== document.body); 3024 return element; 3025} 3026 3027// @function getScale(el: HTMLElement): Object 3028// Computes the CSS scale currently applied on the element. 3029// Returns an object with `x` and `y` members as horizontal and vertical scales respectively, 3030// and `boundingClientRect` as the result of [`getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect). 3031function getScale(element) { 3032 var rect = element.getBoundingClientRect(); // Read-only in old browsers. 3033 3034 return { 3035 x: rect.width / element.offsetWidth || 1, 3036 y: rect.height / element.offsetHeight || 1, 3037 boundingClientRect: rect 3038 }; 3039} 3040 3041 3042var DomUtil = (Object.freeze || Object)({ 3043 TRANSFORM: TRANSFORM, 3044 TRANSITION: TRANSITION, 3045 TRANSITION_END: TRANSITION_END, 3046 get: get, 3047 getStyle: getStyle, 3048 create: create$1, 3049 remove: remove, 3050 empty: empty, 3051 toFront: toFront, 3052 toBack: toBack, 3053 hasClass: hasClass, 3054 addClass: addClass, 3055 removeClass: removeClass, 3056 setClass: setClass, 3057 getClass: getClass, 3058 setOpacity: setOpacity, 3059 testProp: testProp, 3060 setTransform: setTransform, 3061 setPosition: setPosition, 3062 getPosition: getPosition, 3063 disableTextSelection: disableTextSelection, 3064 enableTextSelection: enableTextSelection, 3065 disableImageDrag: disableImageDrag, 3066 enableImageDrag: enableImageDrag, 3067 preventOutline: preventOutline, 3068 restoreOutline: restoreOutline, 3069 getSizedParentNode: getSizedParentNode, 3070 getScale: getScale 3071}); 3072 3073/* 3074 * @namespace DomEvent 3075 * Utility functions to work with the [DOM events](https://developer.mozilla.org/docs/Web/API/Event), used by Leaflet internally. 3076 */ 3077 3078// Inspired by John Resig, Dean Edwards and YUI addEvent implementations. 3079 3080// @function on(el: HTMLElement, types: String, fn: Function, context?: Object): this 3081// Adds a listener function (`fn`) to a particular DOM event type of the 3082// element `el`. You can optionally specify the context of the listener 3083// (object the `this` keyword will point to). You can also pass several 3084// space-separated types (e.g. `'click dblclick'`). 3085 3086// @alternative 3087// @function on(el: HTMLElement, eventMap: Object, context?: Object): this 3088// Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}` 3089function on(obj, types, fn, context) { 3090 3091 if (typeof types === 'object') { 3092 for (var type in types) { 3093 addOne(obj, type, types[type], fn); 3094 } 3095 } else { 3096 types = splitWords(types); 3097 3098 for (var i = 0, len = types.length; i < len; i++) { 3099 addOne(obj, types[i], fn, context); 3100 } 3101 } 3102 3103 return this; 3104} 3105 3106var eventsKey = '_leaflet_events'; 3107 3108// @function off(el: HTMLElement, types: String, fn: Function, context?: Object): this 3109// Removes a previously added listener function. 3110// Note that if you passed a custom context to on, you must pass the same 3111// context to `off` in order to remove the listener. 3112 3113// @alternative 3114// @function off(el: HTMLElement, eventMap: Object, context?: Object): this 3115// Removes a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}` 3116function off(obj, types, fn, context) { 3117 3118 if (typeof types === 'object') { 3119 for (var type in types) { 3120 removeOne(obj, type, types[type], fn); 3121 } 3122 } else if (types) { 3123 types = splitWords(types); 3124 3125 for (var i = 0, len = types.length; i < len; i++) { 3126 removeOne(obj, types[i], fn, context); 3127 } 3128 } else { 3129 for (var j in obj[eventsKey]) { 3130 removeOne(obj, j, obj[eventsKey][j]); 3131 } 3132 delete obj[eventsKey]; 3133 } 3134 3135 return this; 3136} 3137 3138function addOne(obj, type, fn, context) { 3139 var id = type + stamp(fn) + (context ? '_' + stamp(context) : ''); 3140 3141 if (obj[eventsKey] && obj[eventsKey][id]) { return this; } 3142 3143 var handler = function (e) { 3144 return fn.call(context || obj, e || window.event); 3145 }; 3146 3147 var originalHandler = handler; 3148 3149 if (pointer && type.indexOf('touch') === 0) { 3150 // Needs DomEvent.Pointer.js 3151 addPointerListener(obj, type, handler, id); 3152 3153 } else if (touch && (type === 'dblclick') && addDoubleTapListener && 3154 !(pointer && chrome)) { 3155 // Chrome >55 does not need the synthetic dblclicks from addDoubleTapListener 3156 // See #5180 3157 addDoubleTapListener(obj, handler, id); 3158 3159 } else if ('addEventListener' in obj) { 3160 3161 if (type === 'mousewheel') { 3162 obj.addEventListener('onwheel' in obj ? 'wheel' : 'mousewheel', handler, false); 3163 3164 } else if ((type === 'mouseenter') || (type === 'mouseleave')) { 3165 handler = function (e) { 3166 e = e || window.event; 3167 if (isExternalTarget(obj, e)) { 3168 originalHandler(e); 3169 } 3170 }; 3171 obj.addEventListener(type === 'mouseenter' ? 'mouseover' : 'mouseout', handler, false); 3172 3173 } else { 3174 if (type === 'click' && android) { 3175 handler = function (e) { 3176 filterClick(e, originalHandler); 3177 }; 3178 } 3179 obj.addEventListener(type, handler, false); 3180 } 3181 3182 } else if ('attachEvent' in obj) { 3183 obj.attachEvent('on' + type, handler); 3184 } 3185 3186 obj[eventsKey] = obj[eventsKey] || {}; 3187 obj[eventsKey][id] = handler; 3188} 3189 3190function removeOne(obj, type, fn, context) { 3191 3192 var id = type + stamp(fn) + (context ? '_' + stamp(context) : ''), 3193 handler = obj[eventsKey] && obj[eventsKey][id]; 3194 3195 if (!handler) { return this; } 3196 3197 if (pointer && type.indexOf('touch') === 0) { 3198 removePointerListener(obj, type, id); 3199 3200} else if (touch && (type === 'dblclick') && removeDoubleTapListener && 3201 !(pointer && chrome)) { 3202 removeDoubleTapListener(obj, id); 3203 3204} else if ('removeEventListener' in obj) { 3205 3206 if (type === 'mousewheel') { 3207 obj.removeEventListener('onwheel' in obj ? 'wheel' : 'mousewheel', handler, false); 3208 3209 } else { 3210 obj.removeEventListener( 3211 type === 'mouseenter' ? 'mouseover' : 3212 type === 'mouseleave' ? 'mouseout' : type, handler, false); 3213 } 3214 3215} else if ('detachEvent' in obj) { 3216 obj.detachEvent('on' + type, handler); 3217} 3218 3219obj[eventsKey][id] = null; 3220} 3221 3222// @function stopPropagation(ev: DOMEvent): this 3223// Stop the given event from propagation to parent elements. Used inside the listener functions: 3224// ```js 3225// L.DomEvent.on(div, 'click', function (ev) { 3226// L.DomEvent.stopPropagation(ev); 3227// }); 3228// ``` 3229function stopPropagation(e) { 3230 3231 if (e.stopPropagation) { 3232 e.stopPropagation(); 3233 } else if (e.originalEvent) { // In case of Leaflet event. 3234 e.originalEvent._stopped = true; 3235 } else { 3236 e.cancelBubble = true; 3237 } 3238 skipped(e); 3239 3240 return this; 3241} 3242 3243// @function disableScrollPropagation(el: HTMLElement): this 3244// Adds `stopPropagation` to the element's `'mousewheel'` events (plus browser variants). 3245function disableScrollPropagation(el) { 3246 addOne(el, 'mousewheel', stopPropagation); 3247 return this; 3248} 3249 3250// @function disableClickPropagation(el: HTMLElement): this 3251// Adds `stopPropagation` to the element's `'click'`, `'doubleclick'`, 3252// `'mousedown'` and `'touchstart'` events (plus browser variants). 3253function disableClickPropagation(el) { 3254 on(el, 'mousedown touchstart dblclick', stopPropagation); 3255 addOne(el, 'click', fakeStop); 3256 return this; 3257} 3258 3259// @function preventDefault(ev: DOMEvent): this 3260// Prevents the default action of the DOM Event `ev` from happening (such as 3261// following a link in the href of the a element, or doing a POST request 3262// with page reload when a `<form>` is submitted). 3263// Use it inside listener functions. 3264function preventDefault(e) { 3265 if (e.preventDefault) { 3266 e.preventDefault(); 3267 } else { 3268 e.returnValue = false; 3269 } 3270 return this; 3271} 3272 3273// @function stop(ev: DOMEvent): this 3274// Does `stopPropagation` and `preventDefault` at the same time. 3275function stop(e) { 3276 preventDefault(e); 3277 stopPropagation(e); 3278 return this; 3279} 3280 3281// @function getMousePosition(ev: DOMEvent, container?: HTMLElement): Point 3282// Gets normalized mouse position from a DOM event relative to the 3283// `container` (border excluded) or to the whole page if not specified. 3284function getMousePosition(e, container) { 3285 if (!container) { 3286 return new Point(e.clientX, e.clientY); 3287 } 3288 3289 var scale = getScale(container), 3290 offset = scale.boundingClientRect; // left and top values are in page scale (like the event clientX/Y) 3291 3292 return new Point( 3293 // offset.left/top values are in page scale (like clientX/Y), 3294 // whereas clientLeft/Top (border width) values are the original values (before CSS scale applies). 3295 (e.clientX - offset.left) / scale.x - container.clientLeft, 3296 (e.clientY - offset.top) / scale.y - container.clientTop 3297 ); 3298 } 3299 3300// Chrome on Win scrolls double the pixels as in other platforms (see #4538), 3301// and Firefox scrolls device pixels, not CSS pixels 3302var wheelPxFactor = 3303(win && chrome) ? 2 * window.devicePixelRatio : 3304gecko ? window.devicePixelRatio : 1; 3305 3306// @function getWheelDelta(ev: DOMEvent): Number 3307// Gets normalized wheel delta from a mousewheel DOM event, in vertical 3308// pixels scrolled (negative if scrolling down). 3309// Events from pointing devices without precise scrolling are mapped to 3310// a best guess of 60 pixels. 3311function getWheelDelta(e) { 3312 return (edge) ? e.wheelDeltaY / 2 : // Don't trust window-geometry-based delta 3313 (e.deltaY && e.deltaMode === 0) ? -e.deltaY / wheelPxFactor : // Pixels 3314 (e.deltaY && e.deltaMode === 1) ? -e.deltaY * 20 : // Lines 3315 (e.deltaY && e.deltaMode === 2) ? -e.deltaY * 60 : // Pages 3316 (e.deltaX || e.deltaZ) ? 0 : // Skip horizontal/depth wheel events 3317 e.wheelDelta ? (e.wheelDeltaY || e.wheelDelta) / 2 : // Legacy IE pixels 3318 (e.detail && Math.abs(e.detail) < 32765) ? -e.detail * 20 : // Legacy Moz lines 3319 e.detail ? e.detail / -32765 * 60 : // Legacy Moz pages 3320 0; 3321 } 3322 3323 var skipEvents = {}; 3324 3325 function fakeStop(e) { 3326 // fakes stopPropagation by setting a special event flag, checked/reset with skipped(e) 3327 skipEvents[e.type] = true; 3328} 3329 3330function skipped(e) { 3331 var events = skipEvents[e.type]; 3332 // reset when checking, as it's only used in map container and propagates outside of the map 3333 skipEvents[e.type] = false; 3334 return events; 3335} 3336 3337// check if element really left/entered the event target (for mouseenter/mouseleave) 3338function isExternalTarget(el, e) { 3339 3340 var related = e.relatedTarget; 3341 3342 if (!related) { return true; } 3343 3344 try { 3345 while (related && (related !== el)) { 3346 related = related.parentNode; 3347 } 3348 } catch (err) { 3349 return false; 3350 } 3351 return (related !== el); 3352} 3353 3354var lastClick; 3355 3356// this is a horrible workaround for a bug in Android where a single touch triggers two click events 3357function filterClick(e, handler) { 3358 var timeStamp = (e.timeStamp || (e.originalEvent && e.originalEvent.timeStamp)), 3359 elapsed = lastClick && (timeStamp - lastClick); 3360 3361 // are they closer together than 500ms yet more than 100ms? 3362 // Android typically triggers them ~300ms apart while multiple listeners 3363 // on the same event should be triggered far faster; 3364 // or check if click is simulated on the element, and if it is, reject any non-simulated events 3365 3366 if ((elapsed && elapsed > 100 && elapsed < 500) || (e.target._simulatedClick && !e._simulated)) { 3367 stop(e); 3368 return; 3369 } 3370 lastClick = timeStamp; 3371 3372 handler(e); 3373} 3374 3375 3376 3377 3378var DomEvent = (Object.freeze || Object)({ 3379 on: on, 3380 off: off, 3381 stopPropagation: stopPropagation, 3382 disableScrollPropagation: disableScrollPropagation, 3383 disableClickPropagation: disableClickPropagation, 3384 preventDefault: preventDefault, 3385 stop: stop, 3386 getMousePosition: getMousePosition, 3387 getWheelDelta: getWheelDelta, 3388 fakeStop: fakeStop, 3389 skipped: skipped, 3390 isExternalTarget: isExternalTarget, 3391 addListener: on, 3392 removeListener: off 3393}); 3394 3395/* 3396 * @class PosAnimation 3397 * @aka L.PosAnimation 3398 * @inherits Evented 3399 * Used internally for panning animations, utilizing CSS3 Transitions for modern browsers and a timer fallback for IE6-9. 3400 * 3401 * @example 3402 * ```js 3403 * var fx = new L.PosAnimation(); 3404 * fx.run(el, [300, 500], 0.5); 3405 * ``` 3406 * 3407 * @constructor L.PosAnimation() 3408 * Creates a `PosAnimation` object. 3409 * 3410 */ 3411 3412 var PosAnimation = Evented.extend({ 3413 3414 // @method run(el: HTMLElement, newPos: Point, duration?: Number, easeLinearity?: Number) 3415 // Run an animation of a given element to a new position, optionally setting 3416 // duration in seconds (`0.25` by default) and easing linearity factor (3rd 3417 // argument of the [cubic bezier curve](http://cubic-bezier.com/#0,0,.5,1), 3418 // `0.5` by default). 3419 run: function (el, newPos, duration, easeLinearity) { 3420 this.stop(); 3421 3422 this._el = el; 3423 this._inProgress = true; 3424 this._duration = duration || 0.25; 3425 this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2); 3426 3427 this._startPos = getPosition(el); 3428 this._offset = newPos.subtract(this._startPos); 3429 this._startTime = +new Date(); 3430 3431 // @event start: Event 3432 // Fired when the animation starts 3433 this.fire('start'); 3434 3435 this._animate(); 3436 }, 3437 3438 // @method stop() 3439 // Stops the animation (if currently running). 3440 stop: function () { 3441 if (!this._inProgress) { return; } 3442 3443 this._step(true); 3444 this._complete(); 3445 }, 3446 3447 _animate: function () { 3448 // animation loop 3449 this._animId = requestAnimFrame(this._animate, this); 3450 this._step(); 3451 }, 3452 3453 _step: function (round) { 3454 var elapsed = (+new Date()) - this._startTime, 3455 duration = this._duration * 1000; 3456 3457 if (elapsed < duration) { 3458 this._runFrame(this._easeOut(elapsed / duration), round); 3459 } else { 3460 this._runFrame(1); 3461 this._complete(); 3462 } 3463 }, 3464 3465 _runFrame: function (progress, round) { 3466 var pos = this._startPos.add(this._offset.multiplyBy(progress)); 3467 if (round) { 3468 pos._round(); 3469 } 3470 setPosition(this._el, pos); 3471 3472 // @event step: Event 3473 // Fired continuously during the animation. 3474 this.fire('step'); 3475 }, 3476 3477 _complete: function () { 3478 cancelAnimFrame(this._animId); 3479 3480 this._inProgress = false; 3481 // @event end: Event 3482 // Fired when the animation ends. 3483 this.fire('end'); 3484 }, 3485 3486 _easeOut: function (t) { 3487 return 1 - Math.pow(1 - t, this._easeOutPower); 3488 } 3489}); 3490 3491/* 3492 * @class Map 3493 * @aka L.Map 3494 * @inherits Evented 3495 * 3496 * The central class of the API — it is used to create a map on a page and manipulate it. 3497 * 3498 * @example 3499 * 3500 * ```js 3501 * // initialize the map on the "map" div with a given center and zoom 3502 * var map = L.map('map', { 3503 * center: [51.505, -0.09], 3504 * zoom: 13 3505 * }); 3506 * ``` 3507 * 3508 */ 3509 3510 var Map = Evented.extend({ 3511 3512 options: { 3513 // @section Map State Options 3514 // @option crs: CRS = L.CRS.EPSG3857 3515 // The [Coordinate Reference System](#crs) to use. Don't change this if you're not 3516 // sure what it means. 3517 crs: EPSG3857, 3518 3519 // @option center: LatLng = undefined 3520 // Initial geographic center of the map 3521 center: undefined, 3522 3523 // @option zoom: Number = undefined 3524 // Initial map zoom level 3525 zoom: undefined, 3526 3527 // @option minZoom: Number = * 3528 // Minimum zoom level of the map. 3529 // If not specified and at least one `GridLayer` or `TileLayer` is in the map, 3530 // the lowest of their `minZoom` options will be used instead. 3531 minZoom: undefined, 3532 3533 // @option maxZoom: Number = * 3534 // Maximum zoom level of the map. 3535 // If not specified and at least one `GridLayer` or `TileLayer` is in the map, 3536 // the highest of their `maxZoom` options will be used instead. 3537 maxZoom: undefined, 3538 3539 // @option layers: Layer[] = [] 3540 // Array of layers that will be added to the map initially 3541 layers: [], 3542 3543 // @option maxBounds: LatLngBounds = null 3544 // When this option is set, the map restricts the view to the given 3545 // geographical bounds, bouncing the user back if the user tries to pan 3546 // outside the view. To set the restriction dynamically, use 3547 // [`setMaxBounds`](#map-setmaxbounds) method. 3548 maxBounds: undefined, 3549 3550 // @option renderer: Renderer = * 3551 // The default method for drawing vector layers on the map. `L.SVG` 3552 // or `L.Canvas` by default depending on browser support. 3553 renderer: undefined, 3554 3555 3556 // @section Animation Options 3557 // @option zoomAnimation: Boolean = true 3558 // Whether the map zoom animation is enabled. By default it's enabled 3559 // in all browsers that support CSS3 Transitions except Android. 3560 zoomAnimation: true, 3561 3562 // @option zoomAnimationThreshold: Number = 4 3563 // Won't animate zoom if the zoom difference exceeds this value. 3564 zoomAnimationThreshold: 4, 3565 3566 // @option fadeAnimation: Boolean = true 3567 // Whether the tile fade animation is enabled. By default it's enabled 3568 // in all browsers that support CSS3 Transitions except Android. 3569 fadeAnimation: true, 3570 3571 // @option markerZoomAnimation: Boolean = true 3572 // Whether markers animate their zoom with the zoom animation, if disabled 3573 // they will disappear for the length of the animation. By default it's 3574 // enabled in all browsers that support CSS3 Transitions except Android. 3575 markerZoomAnimation: true, 3576 3577 // @option transform3DLimit: Number = 2^23 3578 // Defines the maximum size of a CSS translation transform. The default 3579 // value should not be changed unless a web browser positions layers in 3580 // the wrong place after doing a large `panBy`. 3581 transform3DLimit: 8388608, // Precision limit of a 32-bit float 3582 3583 // @section Interaction Options 3584 // @option zoomSnap: Number = 1 3585 // Forces the map's zoom level to always be a multiple of this, particularly 3586 // right after a [`fitBounds()`](#map-fitbounds) or a pinch-zoom. 3587 // By default, the zoom level snaps to the nearest integer; lower values 3588 // (e.g. `0.5` or `0.1`) allow for greater granularity. A value of `0` 3589 // means the zoom level will not be snapped after `fitBounds` or a pinch-zoom. 3590 zoomSnap: 1, 3591 3592 // @option zoomDelta: Number = 1 3593 // Controls how much the map's zoom level will change after a 3594 // [`zoomIn()`](#map-zoomin), [`zoomOut()`](#map-zoomout), pressing `+` 3595 // or `-` on the keyboard, or using the [zoom controls](#control-zoom). 3596 // Values smaller than `1` (e.g. `0.5`) allow for greater granularity. 3597 zoomDelta: 1, 3598 3599 // @option trackResize: Boolean = true 3600 // Whether the map automatically handles browser window resize to update itself. 3601 trackResize: true 3602 }, 3603 3604 initialize: function (id, options) { // (HTMLElement or String, Object) 3605 options = setOptions(this, options); 3606 3607 // Make sure to assign internal flags at the beginning, 3608 // to avoid inconsistent state in some edge cases. 3609 this._handlers = []; 3610 this._layers = {}; 3611 this._zoomBoundLayers = {}; 3612 this._sizeChanged = true; 3613 3614 this._initContainer(id); 3615 this._initLayout(); 3616 3617 // hack for https://github.com/Leaflet/Leaflet/issues/1980 3618 this._onResize = bind(this._onResize, this); 3619 3620 this._initEvents(); 3621 3622 if (options.maxBounds) { 3623 this.setMaxBounds(options.maxBounds); 3624 } 3625 3626 if (options.zoom !== undefined) { 3627 this._zoom = this._limitZoom(options.zoom); 3628 } 3629 3630 if (options.center && options.zoom !== undefined) { 3631 this.setView(toLatLng(options.center), options.zoom, {reset: true}); 3632 } 3633 3634 this.callInitHooks(); 3635 3636 // don't animate on browsers without hardware-accelerated transitions or old Android/Opera 3637 this._zoomAnimated = TRANSITION && any3d && !mobileOpera && 3638 this.options.zoomAnimation; 3639 3640 // zoom transitions run with the same duration for all layers, so if one of transitionend events 3641 // happens after starting zoom animation (propagating to the map pane), we know that it ended globally 3642 if (this._zoomAnimated) { 3643 this._createAnimProxy(); 3644 on(this._proxy, TRANSITION_END, this._catchTransitionEnd, this); 3645 } 3646 3647 this._addLayers(this.options.layers); 3648 }, 3649 3650 3651 // @section Methods for modifying map state 3652 3653 // @method setView(center: LatLng, zoom: Number, options?: Zoom/pan options): this 3654 // Sets the view of the map (geographical center and zoom) with the given 3655 // animation options. 3656 setView: function (center, zoom, options) { 3657 3658 zoom = zoom === undefined ? this._zoom : this._limitZoom(zoom); 3659 center = this._limitCenter(toLatLng(center), zoom, this.options.maxBounds); 3660 options = options || {}; 3661 3662 this._stop(); 3663 3664 if (this._loaded && !options.reset && options !== true) { 3665 3666 if (options.animate !== undefined) { 3667 options.zoom = extend({animate: options.animate}, options.zoom); 3668 options.pan = extend({animate: options.animate, duration: options.duration}, options.pan); 3669 } 3670 3671 // try animating pan or zoom 3672 var moved = (this._zoom !== zoom) ? 3673 this._tryAnimatedZoom && this._tryAnimatedZoom(center, zoom, options.zoom) : 3674 this._tryAnimatedPan(center, options.pan); 3675 3676 if (moved) { 3677 // prevent resize handler call, the view will refresh after animation anyway 3678 clearTimeout(this._sizeTimer); 3679 return this; 3680 } 3681 } 3682 3683 // animation didn't start, just reset the map view 3684 this._resetView(center, zoom); 3685 3686 return this; 3687 }, 3688 3689 // @method setZoom(zoom: Number, options?: Zoom/pan options): this 3690 // Sets the zoom of the map. 3691 setZoom: function (zoom, options) { 3692 if (!this._loaded) { 3693 this._zoom = zoom; 3694 return this; 3695 } 3696 return this.setView(this.getCenter(), zoom, {zoom: options}); 3697 }, 3698 3699 // @method zoomIn(delta?: Number, options?: Zoom options): this 3700 // Increases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default). 3701 zoomIn: function (delta, options) { 3702 delta = delta || (any3d ? this.options.zoomDelta : 1); 3703 return this.setZoom(this._zoom + delta, options); 3704 }, 3705 3706 // @method zoomOut(delta?: Number, options?: Zoom options): this 3707 // Decreases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default). 3708 zoomOut: function (delta, options) { 3709 delta = delta || (any3d ? this.options.zoomDelta : 1); 3710 return this.setZoom(this._zoom - delta, options); 3711 }, 3712 3713 // @method setZoomAround(latlng: LatLng, zoom: Number, options: Zoom options): this 3714 // Zooms the map while keeping a specified geographical point on the map 3715 // stationary (e.g. used internally for scroll zoom and double-click zoom). 3716 // @alternative 3717 // @method setZoomAround(offset: Point, zoom: Number, options: Zoom options): this 3718 // Zooms the map while keeping a specified pixel on the map (relative to the top-left corner) stationary. 3719 setZoomAround: function (latlng, zoom, options) { 3720 var scale = this.getZoomScale(zoom), 3721 viewHalf = this.getSize().divideBy(2), 3722 containerPoint = latlng instanceof Point ? latlng : this.latLngToContainerPoint(latlng), 3723 3724 centerOffset = containerPoint.subtract(viewHalf).multiplyBy(1 - 1 / scale), 3725 newCenter = this.containerPointToLatLng(viewHalf.add(centerOffset)); 3726 3727 return this.setView(newCenter, zoom, {zoom: options}); 3728 }, 3729 3730 _getBoundsCenterZoom: function (bounds, options) { 3731 3732 options = options || {}; 3733 bounds = bounds.getBounds ? bounds.getBounds() : toLatLngBounds(bounds); 3734 3735 var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]), 3736 paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]), 3737 3738 zoom = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR)); 3739 3740 zoom = (typeof options.maxZoom === 'number') ? Math.min(options.maxZoom, zoom) : zoom; 3741 3742 if (zoom === Infinity) { 3743 return { 3744 center: bounds.getCenter(), 3745 zoom: zoom 3746 }; 3747 } 3748 3749 var paddingOffset = paddingBR.subtract(paddingTL).divideBy(2), 3750 3751 swPoint = this.project(bounds.getSouthWest(), zoom), 3752 nePoint = this.project(bounds.getNorthEast(), zoom), 3753 center = this.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom); 3754 3755 return { 3756 center: center, 3757 zoom: zoom 3758 }; 3759}, 3760 3761 // @method fitBounds(bounds: LatLngBounds, options?: fitBounds options): this 3762 // Sets a map view that contains the given geographical bounds with the 3763 // maximum zoom level possible. 3764 fitBounds: function (bounds, options) { 3765 3766 bounds = toLatLngBounds(bounds); 3767 3768 if (!bounds.isValid()) { 3769 throw new Error('Bounds are not valid.'); 3770 } 3771 3772 var target = this._getBoundsCenterZoom(bounds, options); 3773 return this.setView(target.center, target.zoom, options); 3774 }, 3775 3776 // @method fitWorld(options?: fitBounds options): this 3777 // Sets a map view that mostly contains the whole world with the maximum 3778 // zoom level possible. 3779 fitWorld: function (options) { 3780 return this.fitBounds([[-90, -180], [90, 180]], options); 3781 }, 3782 3783 // @method panTo(latlng: LatLng, options?: Pan options): this 3784 // Pans the map to a given center. 3785 panTo: function (center, options) { // (LatLng) 3786 return this.setView(center, this._zoom, {pan: options}); 3787 }, 3788 3789 // @method panBy(offset: Point, options?: Pan options): this 3790 // Pans the map by a given number of pixels (animated). 3791 panBy: function (offset, options) { 3792 offset = toPoint(offset).round(); 3793 options = options || {}; 3794 3795 if (!offset.x && !offset.y) { 3796 return this.fire('moveend'); 3797 } 3798 // If we pan too far, Chrome gets issues with tiles 3799 // and makes them disappear or appear in the wrong place (slightly offset) #2602 3800 if (options.animate !== true && !this.getSize().contains(offset)) { 3801 this._resetView(this.unproject(this.project(this.getCenter()).add(offset)), this.getZoom()); 3802 return this; 3803 } 3804 3805 if (!this._panAnim) { 3806 this._panAnim = new PosAnimation(); 3807 3808 this._panAnim.on({ 3809 'step': this._onPanTransitionStep, 3810 'end': this._onPanTransitionEnd 3811 }, this); 3812 } 3813 3814 // don't fire movestart if animating inertia 3815 if (!options.noMoveStart) { 3816 this.fire('movestart'); 3817 } 3818 3819 // animate pan unless animate: false specified 3820 if (options.animate !== false) { 3821 addClass(this._mapPane, 'leaflet-pan-anim'); 3822 3823 var newPos = this._getMapPanePos().subtract(offset).round(); 3824 this._panAnim.run(this._mapPane, newPos, options.duration || 0.25, options.easeLinearity); 3825 } else { 3826 this._rawPanBy(offset); 3827 this.fire('move').fire('moveend'); 3828 } 3829 3830 return this; 3831 }, 3832 3833 // @method flyTo(latlng: LatLng, zoom?: Number, options?: Zoom/pan options): this 3834 // Sets the view of the map (geographical center and zoom) performing a smooth 3835 // pan-zoom animation. 3836 flyTo: function (targetCenter, targetZoom, options) { 3837 3838 options = options || {}; 3839 if (options.animate === false || !any3d) { 3840 return this.setView(targetCenter, targetZoom, options); 3841 } 3842 3843 this._stop(); 3844 3845 var from = this.project(this.getCenter()), 3846 to = this.project(targetCenter), 3847 size = this.getSize(), 3848 startZoom = this._zoom; 3849 3850 targetCenter = toLatLng(targetCenter); 3851 targetZoom = targetZoom === undefined ? startZoom : targetZoom; 3852 3853 var w0 = Math.max(size.x, size.y), 3854 w1 = w0 * this.getZoomScale(startZoom, targetZoom), 3855 u1 = (to.distanceTo(from)) || 1, 3856 rho = 1.42, 3857 rho2 = rho * rho; 3858 3859 function r(i) { 3860 var s1 = i ? -1 : 1, 3861 s2 = i ? w1 : w0, 3862 t1 = w1 * w1 - w0 * w0 + s1 * rho2 * rho2 * u1 * u1, 3863 b1 = 2 * s2 * rho2 * u1, 3864 b = t1 / b1, 3865 sq = Math.sqrt(b * b + 1) - b; 3866 3867 // workaround for floating point precision bug when sq = 0, log = -Infinite, 3868 // thus triggering an infinite loop in flyTo 3869 var log = sq < 0.000000001 ? -18 : Math.log(sq); 3870 3871 return log; 3872 } 3873 3874 function sinh(n) { return (Math.exp(n) - Math.exp(-n)) / 2; } 3875 function cosh(n) { return (Math.exp(n) + Math.exp(-n)) / 2; } 3876 function tanh(n) { return sinh(n) / cosh(n); } 3877 3878 var r0 = r(0); 3879 3880 function w(s) { return w0 * (cosh(r0) / cosh(r0 + rho * s)); } 3881 function u(s) { return w0 * (cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2; } 3882 3883 function easeOut(t) { return 1 - Math.pow(1 - t, 1.5); } 3884 3885 var start = Date.now(), 3886 S = (r(1) - r0) / rho, 3887 duration = options.duration ? 1000 * options.duration : 1000 * S * 0.8; 3888 3889 function frame() { 3890 var t = (Date.now() - start) / duration, 3891 s = easeOut(t) * S; 3892 3893 if (t <= 1) { 3894 this._flyToFrame = requestAnimFrame(frame, this); 3895 3896 this._move( 3897 this.unproject(from.add(to.subtract(from).multiplyBy(u(s) / u1)), startZoom), 3898 this.getScaleZoom(w0 / w(s), startZoom), 3899 {flyTo: true}); 3900 3901 } else { 3902 this 3903 ._move(targetCenter, targetZoom) 3904 ._moveEnd(true); 3905 } 3906 } 3907 3908 this._moveStart(true, options.noMoveStart); 3909 3910 frame.call(this); 3911 return this; 3912 }, 3913 3914 // @method flyToBounds(bounds: LatLngBounds, options?: fitBounds options): this 3915 // Sets the view of the map with a smooth animation like [`flyTo`](#map-flyto), 3916 // but takes a bounds parameter like [`fitBounds`](#map-fitbounds). 3917 flyToBounds: function (bounds, options) { 3918 var target = this._getBoundsCenterZoom(bounds, options); 3919 return this.flyTo(target.center, target.zoom, options); 3920 }, 3921 3922 // @method setMaxBounds(bounds: Bounds): this 3923 // Restricts the map view to the given bounds (see the [maxBounds](#map-maxbounds) option). 3924 setMaxBounds: function (bounds) { 3925 bounds = toLatLngBounds(bounds); 3926 3927 if (!bounds.isValid()) { 3928 this.options.maxBounds = null; 3929 return this.off('moveend', this._panInsideMaxBounds); 3930 } else if (this.options.maxBounds) { 3931 this.off('moveend', this._panInsideMaxBounds); 3932 } 3933 3934 this.options.maxBounds = bounds; 3935 3936 if (this._loaded) { 3937 this._panInsideMaxBounds(); 3938 } 3939 3940 return this.on('moveend', this._panInsideMaxBounds); 3941 }, 3942 3943 // @method setMinZoom(zoom: Number): this 3944 // Sets the lower limit for the available zoom levels (see the [minZoom](#map-minzoom) option). 3945 setMinZoom: function (zoom) { 3946 var oldZoom = this.options.minZoom; 3947 this.options.minZoom = zoom; 3948 3949 if (this._loaded && oldZoom !== zoom) { 3950 this.fire('zoomlevelschange'); 3951 3952 if (this.getZoom() < this.options.minZoom) { 3953 return this.setZoom(zoom); 3954 } 3955 } 3956 3957 return this; 3958 }, 3959 3960 // @method setMaxZoom(zoom: Number): this 3961 // Sets the upper limit for the available zoom levels (see the [maxZoom](#map-maxzoom) option). 3962 setMaxZoom: function (zoom) { 3963 var oldZoom = this.options.maxZoom; 3964 this.options.maxZoom = zoom; 3965 3966 if (this._loaded && oldZoom !== zoom) { 3967 this.fire('zoomlevelschange'); 3968 3969 if (this.getZoom() > this.options.maxZoom) { 3970 return this.setZoom(zoom); 3971 } 3972 } 3973 3974 return this; 3975 }, 3976 3977 // @method panInsideBounds(bounds: LatLngBounds, options?: Pan options): this 3978 // Pans the map to the closest view that would lie inside the given bounds (if it's not already), controlling the animation using the options specific, if any. 3979 panInsideBounds: function (bounds, options) { 3980 this._enforcingBounds = true; 3981 var center = this.getCenter(), 3982 newCenter = this._limitCenter(center, this._zoom, toLatLngBounds(bounds)); 3983 3984 if (!center.equals(newCenter)) { 3985 this.panTo(newCenter, options); 3986 } 3987 3988 this._enforcingBounds = false; 3989 return this; 3990 }, 3991 3992 // @method panInside(latlng: LatLng, options?: options): this 3993 // Pans the map the minimum amount to make the `latlng` visible. Use 3994 // `padding`, `paddingTopLeft` and `paddingTopRight` options to fit 3995 // the display to more restricted bounds, like [`fitBounds`](#map-fitbounds). 3996 // If `latlng` is already within the (optionally padded) display bounds, 3997 // the map will not be panned. 3998 panInside: function (latlng, options) { 3999 options = options || {}; 4000 4001 var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]), 4002 paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]), 4003 center = this.getCenter(), 4004 pixelCenter = this.project(center), 4005 pixelPoint = this.project(latlng), 4006 pixelBounds = this.getPixelBounds(), 4007 halfPixelBounds = pixelBounds.getSize().divideBy(2), 4008 paddedBounds = toBounds([pixelBounds.min.add(paddingTL), pixelBounds.max.subtract(paddingBR)]); 4009 4010 if (!paddedBounds.contains(pixelPoint)) { 4011 this._enforcingBounds = true; 4012 var diff = pixelCenter.subtract(pixelPoint), 4013 newCenter = toPoint(pixelPoint.x + diff.x, pixelPoint.y + diff.y); 4014 4015 if (pixelPoint.x < paddedBounds.min.x || pixelPoint.x > paddedBounds.max.x) { 4016 newCenter.x = pixelCenter.x - diff.x; 4017 if (diff.x > 0) { 4018 newCenter.x += halfPixelBounds.x - paddingTL.x; 4019 } else { 4020 newCenter.x -= halfPixelBounds.x - paddingBR.x; 4021 } 4022 } 4023 if (pixelPoint.y < paddedBounds.min.y || pixelPoint.y > paddedBounds.max.y) { 4024 newCenter.y = pixelCenter.y - diff.y; 4025 if (diff.y > 0) { 4026 newCenter.y += halfPixelBounds.y - paddingTL.y; 4027 } else { 4028 newCenter.y -= halfPixelBounds.y - paddingBR.y; 4029 } 4030 } 4031 this.panTo(this.unproject(newCenter), options); 4032 this._enforcingBounds = false; 4033} 4034return this; 4035}, 4036 4037 // @method invalidateSize(options: Zoom/pan options): this 4038 // Checks if the map container size changed and updates the map if so — 4039 // call it after you've changed the map size dynamically, also animating 4040 // pan by default. If `options.pan` is `false`, panning will not occur. 4041 // If `options.debounceMoveend` is `true`, it will delay `moveend` event so 4042 // that it doesn't happen often even if the method is called many 4043 // times in a row. 4044 4045 // @alternative 4046 // @method invalidateSize(animate: Boolean): this 4047 // Checks if the map container size changed and updates the map if so — 4048 // call it after you've changed the map size dynamically, also animating 4049 // pan by default. 4050 invalidateSize: function (options) { 4051 if (!this._loaded) { return this; } 4052 4053 options = extend({ 4054 animate: false, 4055 pan: true 4056 }, options === true ? {animate: true} : options); 4057 4058 var oldSize = this.getSize(); 4059 this._sizeChanged = true; 4060 this._lastCenter = null; 4061 4062 var newSize = this.getSize(), 4063 oldCenter = oldSize.divideBy(2).round(), 4064 newCenter = newSize.divideBy(2).round(), 4065 offset = oldCenter.subtract(newCenter); 4066 4067 if (!offset.x && !offset.y) { return this; } 4068 4069 if (options.animate && options.pan) { 4070 this.panBy(offset); 4071 4072 } else { 4073 if (options.pan) { 4074 this._rawPanBy(offset); 4075 } 4076 4077 this.fire('move'); 4078 4079 if (options.debounceMoveend) { 4080 clearTimeout(this._sizeTimer); 4081 this._sizeTimer = setTimeout(bind(this.fire, this, 'moveend'), 200); 4082 } else { 4083 this.fire('moveend'); 4084 } 4085 } 4086 4087 // @section Map state change events 4088 // @event resize: ResizeEvent 4089 // Fired when the map is resized. 4090 return this.fire('resize', { 4091 oldSize: oldSize, 4092 newSize: newSize 4093 }); 4094 }, 4095 4096 // @section Methods for modifying map state 4097 // @method stop(): this 4098 // Stops the currently running `panTo` or `flyTo` animation, if any. 4099 stop: function () { 4100 this.setZoom(this._limitZoom(this._zoom)); 4101 if (!this.options.zoomSnap) { 4102 this.fire('viewreset'); 4103 } 4104 return this._stop(); 4105 }, 4106 4107 // @section Geolocation methods 4108 // @method locate(options?: Locate options): this 4109 // Tries to locate the user using the Geolocation API, firing a [`locationfound`](#map-locationfound) 4110 // event with location data on success or a [`locationerror`](#map-locationerror) event on failure, 4111 // and optionally sets the map view to the user's location with respect to 4112 // detection accuracy (or to the world view if geolocation failed). 4113 // Note that, if your page doesn't use HTTPS, this method will fail in 4114 // modern browsers ([Chrome 50 and newer](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins)) 4115 // See `Locate options` for more details. 4116 locate: function (options) { 4117 4118 options = this._locateOptions = extend({ 4119 timeout: 10000, 4120 watch: false 4121 // setView: false 4122 // maxZoom: <Number> 4123 // maximumAge: 0 4124 // enableHighAccuracy: false 4125 }, options); 4126 4127 if (!('geolocation' in navigator)) { 4128 this._handleGeolocationError({ 4129 code: 0, 4130 message: 'Geolocation not supported.' 4131 }); 4132 return this; 4133 } 4134 4135 var onResponse = bind(this._handleGeolocationResponse, this), 4136 onError = bind(this._handleGeolocationError, this); 4137 4138 if (options.watch) { 4139 this._locationWatchId = 4140 navigator.geolocation.watchPosition(onResponse, onError, options); 4141 } else { 4142 navigator.geolocation.getCurrentPosition(onResponse, onError, options); 4143 } 4144 return this; 4145 }, 4146 4147 // @method stopLocate(): this 4148 // Stops watching location previously initiated by `map.locate({watch: true})` 4149 // and aborts resetting the map view if map.locate was called with 4150 // `{setView: true}`. 4151 stopLocate: function () { 4152 if (navigator.geolocation && navigator.geolocation.clearWatch) { 4153 navigator.geolocation.clearWatch(this._locationWatchId); 4154 } 4155 if (this._locateOptions) { 4156 this._locateOptions.setView = false; 4157 } 4158 return this; 4159 }, 4160 4161 _handleGeolocationError: function (error) { 4162 var c = error.code, 4163 message = error.message || 4164 (c === 1 ? 'permission denied' : 4165 (c === 2 ? 'position unavailable' : 'timeout')); 4166 4167 if (this._locateOptions.setView && !this._loaded) { 4168 this.fitWorld(); 4169 } 4170 4171 // @section Location events 4172 // @event locationerror: ErrorEvent 4173 // Fired when geolocation (using the [`locate`](#map-locate) method) failed. 4174 this.fire('locationerror', { 4175 code: c, 4176 message: 'Geolocation error: ' + message + '.' 4177 }); 4178 }, 4179 4180 _handleGeolocationResponse: function (pos) { 4181 var lat = pos.coords.latitude, 4182 lng = pos.coords.longitude, 4183 latlng = new LatLng(lat, lng), 4184 bounds = latlng.toBounds(pos.coords.accuracy * 2), 4185 options = this._locateOptions; 4186 4187 if (options.setView) { 4188 var zoom = this.getBoundsZoom(bounds); 4189 this.setView(latlng, options.maxZoom ? Math.min(zoom, options.maxZoom) : zoom); 4190 } 4191 4192 var data = { 4193 latlng: latlng, 4194 bounds: bounds, 4195 timestamp: pos.timestamp 4196 }; 4197 4198 for (var i in pos.coords) { 4199 if (typeof pos.coords[i] === 'number') { 4200 data[i] = pos.coords[i]; 4201 } 4202 } 4203 4204 // @event locationfound: LocationEvent 4205 // Fired when geolocation (using the [`locate`](#map-locate) method) 4206 // went successfully. 4207 this.fire('locationfound', data); 4208 }, 4209 4210 // TODO Appropriate docs section? 4211 // @section Other Methods 4212 // @method addHandler(name: String, HandlerClass: Function): this 4213 // Adds a new `Handler` to the map, given its name and constructor function. 4214 addHandler: function (name, HandlerClass) { 4215 if (!HandlerClass) { return this; } 4216 4217 var handler = this[name] = new HandlerClass(this); 4218 4219 this._handlers.push(handler); 4220 4221 if (this.options[name]) { 4222 handler.enable(); 4223 } 4224 4225 return this; 4226 }, 4227 4228 // @method remove(): this 4229 // Destroys the map and clears all related event listeners. 4230 remove: function () { 4231 4232 this._initEvents(true); 4233 4234 if (this._containerId !== this._container._leaflet_id) { 4235 throw new Error('Map container is being reused by another instance'); 4236 } 4237 4238 try { 4239 // throws error in IE6-8 4240 delete this._container._leaflet_id; 4241 delete this._containerId; 4242 } catch (e) { 4243 /*eslint-disable */ 4244 this._container._leaflet_id = undefined; 4245 /* eslint-enable */ 4246 this._containerId = undefined; 4247 } 4248 4249 if (this._locationWatchId !== undefined) { 4250 this.stopLocate(); 4251 } 4252 4253 this._stop(); 4254 4255 remove(this._mapPane); 4256 4257 if (this._clearControlPos) { 4258 this._clearControlPos(); 4259 } 4260 if (this._resizeRequest) { 4261 cancelAnimFrame(this._resizeRequest); 4262 this._resizeRequest = null; 4263 } 4264 4265 this._clearHandlers(); 4266 4267 if (this._loaded) { 4268 // @section Map state change events 4269 // @event unload: Event 4270 // Fired when the map is destroyed with [remove](#map-remove) method. 4271 this.fire('unload'); 4272 } 4273 4274 var i; 4275 for (i in this._layers) { 4276 this._layers[i].remove(); 4277 } 4278 for (i in this._panes) { 4279 remove(this._panes[i]); 4280 } 4281 4282 this._layers = []; 4283 this._panes = []; 4284 delete this._mapPane; 4285 delete this._renderer; 4286 4287 return this; 4288 }, 4289 4290 // @section Other Methods 4291 // @method createPane(name: String, container?: HTMLElement): HTMLElement 4292 // Creates a new [map pane](#map-pane) with the given name if it doesn't exist already, 4293 // then returns it. The pane is created as a child of `container`, or 4294 // as a child of the main map pane if not set. 4295 createPane: function (name, container) { 4296 var className = 'leaflet-pane' + (name ? ' leaflet-' + name.replace('Pane', '') + '-pane' : ''), 4297 pane = create$1('div', className, container || this._mapPane); 4298 4299 if (name) { 4300 this._panes[name] = pane; 4301 } 4302 return pane; 4303 }, 4304 4305 // @section Methods for Getting Map State 4306 4307 // @method getCenter(): LatLng 4308 // Returns the geographical center of the map view 4309 getCenter: function () { 4310 this._checkIfLoaded(); 4311 4312 if (this._lastCenter && !this._moved()) { 4313 return this._lastCenter; 4314 } 4315 return this.layerPointToLatLng(this._getCenterLayerPoint()); 4316 }, 4317 4318 // @method getZoom(): Number 4319 // Returns the current zoom level of the map view 4320 getZoom: function () { 4321 return this._zoom; 4322 }, 4323 4324 // @method getBounds(): LatLngBounds 4325 // Returns the geographical bounds visible in the current map view 4326 getBounds: function () { 4327 var bounds = this.getPixelBounds(), 4328 sw = this.unproject(bounds.getBottomLeft()), 4329 ne = this.unproject(bounds.getTopRight()); 4330 4331 return new LatLngBounds(sw, ne); 4332 }, 4333 4334 // @method getMinZoom(): Number 4335 // Returns the minimum zoom level of the map (if set in the `minZoom` option of the map or of any layers), or `0` by default. 4336 getMinZoom: function () { 4337 return this.options.minZoom === undefined ? this._layersMinZoom || 0 : this.options.minZoom; 4338 }, 4339 4340 // @method getMaxZoom(): Number 4341 // Returns the maximum zoom level of the map (if set in the `maxZoom` option of the map or of any layers). 4342 getMaxZoom: function () { 4343 return this.options.maxZoom === undefined ? 4344 (this._layersMaxZoom === undefined ? Infinity : this._layersMaxZoom) : 4345 this.options.maxZoom; 4346 }, 4347 4348 // @method getBoundsZoom(bounds: LatLngBounds, inside?: Boolean, padding?: Point): Number 4349 // Returns the maximum zoom level on which the given bounds fit to the map 4350 // view in its entirety. If `inside` (optional) is set to `true`, the method 4351 // instead returns the minimum zoom level on which the map view fits into 4352 // the given bounds in its entirety. 4353 getBoundsZoom: function (bounds, inside, padding) { // (LatLngBounds[, Boolean, Point]) -> Number 4354 bounds = toLatLngBounds(bounds); 4355 padding = toPoint(padding || [0, 0]); 4356 4357 var zoom = this.getZoom() || 0, 4358 min = this.getMinZoom(), 4359 max = this.getMaxZoom(), 4360 nw = bounds.getNorthWest(), 4361 se = bounds.getSouthEast(), 4362 size = this.getSize().subtract(padding), 4363 boundsSize = toBounds(this.project(se, zoom), this.project(nw, zoom)).getSize(), 4364 snap = any3d ? this.options.zoomSnap : 1, 4365 scalex = size.x / boundsSize.x, 4366 scaley = size.y / boundsSize.y, 4367 scale = inside ? Math.max(scalex, scaley) : Math.min(scalex, scaley); 4368 4369 zoom = this.getScaleZoom(scale, zoom); 4370 4371 if (snap) { 4372 zoom = Math.round(zoom / (snap / 100)) * (snap / 100); // don't jump if within 1% of a snap level 4373 zoom = inside ? Math.ceil(zoom / snap) * snap : Math.floor(zoom / snap) * snap; 4374 } 4375 4376 return Math.max(min, Math.min(max, zoom)); 4377 }, 4378 4379 // @method getSize(): Point 4380 // Returns the current size of the map container (in pixels). 4381 getSize: function () { 4382 if (!this._size || this._sizeChanged) { 4383 this._size = new Point( 4384 this._container.clientWidth || 0, 4385 this._container.clientHeight || 0); 4386 4387 this._sizeChanged = false; 4388 } 4389 return this._size.clone(); 4390 }, 4391 4392 // @method getPixelBounds(): Bounds 4393 // Returns the bounds of the current map view in projected pixel 4394 // coordinates (sometimes useful in layer and overlay implementations). 4395 getPixelBounds: function (center, zoom) { 4396 var topLeftPoint = this._getTopLeftPoint(center, zoom); 4397 return new Bounds(topLeftPoint, topLeftPoint.add(this.getSize())); 4398 }, 4399 4400 // TODO: Check semantics - isn't the pixel origin the 0,0 coord relative to 4401 // the map pane? "left point of the map layer" can be confusing, specially 4402 // since there can be negative offsets. 4403 // @method getPixelOrigin(): Point 4404 // Returns the projected pixel coordinates of the top left point of 4405 // the map layer (useful in custom layer and overlay implementations). 4406 getPixelOrigin: function () { 4407 this._checkIfLoaded(); 4408 return this._pixelOrigin; 4409 }, 4410 4411 // @method getPixelWorldBounds(zoom?: Number): Bounds 4412 // Returns the world's bounds in pixel coordinates for zoom level `zoom`. 4413 // If `zoom` is omitted, the map's current zoom level is used. 4414 getPixelWorldBounds: function (zoom) { 4415 return this.options.crs.getProjectedBounds(zoom === undefined ? this.getZoom() : zoom); 4416 }, 4417 4418 // @section Other Methods 4419 4420 // @method getPane(pane: String|HTMLElement): HTMLElement 4421 // Returns a [map pane](#map-pane), given its name or its HTML element (its identity). 4422 getPane: function (pane) { 4423 return typeof pane === 'string' ? this._panes[pane] : pane; 4424 }, 4425 4426 // @method getPanes(): Object 4427 // Returns a plain object containing the names of all [panes](#map-pane) as keys and 4428 // the panes as values. 4429 getPanes: function () { 4430 return this._panes; 4431 }, 4432 4433 // @method getContainer: HTMLElement 4434 // Returns the HTML element that contains the map. 4435 getContainer: function () { 4436 return this._container; 4437 }, 4438 4439 4440 // @section Conversion Methods 4441 4442 // @method getZoomScale(toZoom: Number, fromZoom: Number): Number 4443 // Returns the scale factor to be applied to a map transition from zoom level 4444 // `fromZoom` to `toZoom`. Used internally to help with zoom animations. 4445 getZoomScale: function (toZoom, fromZoom) { 4446 // TODO replace with universal implementation after refactoring projections 4447 var crs = this.options.crs; 4448 fromZoom = fromZoom === undefined ? this._zoom : fromZoom; 4449 return crs.scale(toZoom) / crs.scale(fromZoom); 4450 }, 4451 4452 // @method getScaleZoom(scale: Number, fromZoom: Number): Number 4453 // Returns the zoom level that the map would end up at, if it is at `fromZoom` 4454 // level and everything is scaled by a factor of `scale`. Inverse of 4455 // [`getZoomScale`](#map-getZoomScale). 4456 getScaleZoom: function (scale, fromZoom) { 4457 var crs = this.options.crs; 4458 fromZoom = fromZoom === undefined ? this._zoom : fromZoom; 4459 var zoom = crs.zoom(scale * crs.scale(fromZoom)); 4460 return isNaN(zoom) ? Infinity : zoom; 4461 }, 4462 4463 // @method project(latlng: LatLng, zoom: Number): Point 4464 // Projects a geographical coordinate `LatLng` according to the projection 4465 // of the map's CRS, then scales it according to `zoom` and the CRS's 4466 // `Transformation`. The result is pixel coordinate relative to 4467 // the CRS origin. 4468 project: function (latlng, zoom) { 4469 zoom = zoom === undefined ? this._zoom : zoom; 4470 return this.options.crs.latLngToPoint(toLatLng(latlng), zoom); 4471 }, 4472 4473 // @method unproject(point: Point, zoom: Number): LatLng 4474 // Inverse of [`project`](#map-project). 4475 unproject: function (point, zoom) { 4476 zoom = zoom === undefined ? this._zoom : zoom; 4477 return this.options.crs.pointToLatLng(toPoint(point), zoom); 4478 }, 4479 4480 // @method layerPointToLatLng(point: Point): LatLng 4481 // Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin), 4482 // returns the corresponding geographical coordinate (for the current zoom level). 4483 layerPointToLatLng: function (point) { 4484 var projectedPoint = toPoint(point).add(this.getPixelOrigin()); 4485 return this.unproject(projectedPoint); 4486 }, 4487 4488 // @method latLngToLayerPoint(latlng: LatLng): Point 4489 // Given a geographical coordinate, returns the corresponding pixel coordinate 4490 // relative to the [origin pixel](#map-getpixelorigin). 4491 latLngToLayerPoint: function (latlng) { 4492 var projectedPoint = this.project(toLatLng(latlng))._round(); 4493 return projectedPoint._subtract(this.getPixelOrigin()); 4494 }, 4495 4496 // @method wrapLatLng(latlng: LatLng): LatLng 4497 // Returns a `LatLng` where `lat` and `lng` has been wrapped according to the 4498 // map's CRS's `wrapLat` and `wrapLng` properties, if they are outside the 4499 // CRS's bounds. 4500 // By default this means longitude is wrapped around the dateline so its 4501 // value is between -180 and +180 degrees. 4502 wrapLatLng: function (latlng) { 4503 return this.options.crs.wrapLatLng(toLatLng(latlng)); 4504 }, 4505 4506 // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds 4507 // Returns a `LatLngBounds` with the same size as the given one, ensuring that 4508 // its center is within the CRS's bounds. 4509 // By default this means the center longitude is wrapped around the dateline so its 4510 // value is between -180 and +180 degrees, and the majority of the bounds 4511 // overlaps the CRS's bounds. 4512 wrapLatLngBounds: function (latlng) { 4513 return this.options.crs.wrapLatLngBounds(toLatLngBounds(latlng)); 4514 }, 4515 4516 // @method distance(latlng1: LatLng, latlng2: LatLng): Number 4517 // Returns the distance between two geographical coordinates according to 4518 // the map's CRS. By default this measures distance in meters. 4519 distance: function (latlng1, latlng2) { 4520 return this.options.crs.distance(toLatLng(latlng1), toLatLng(latlng2)); 4521 }, 4522 4523 // @method containerPointToLayerPoint(point: Point): Point 4524 // Given a pixel coordinate relative to the map container, returns the corresponding 4525 // pixel coordinate relative to the [origin pixel](#map-getpixelorigin). 4526 containerPointToLayerPoint: function (point) { // (Point) 4527 return toPoint(point).subtract(this._getMapPanePos()); 4528 }, 4529 4530 // @method layerPointToContainerPoint(point: Point): Point 4531 // Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin), 4532 // returns the corresponding pixel coordinate relative to the map container. 4533 layerPointToContainerPoint: function (point) { // (Point) 4534 return toPoint(point).add(this._getMapPanePos()); 4535 }, 4536 4537 // @method containerPointToLatLng(point: Point): LatLng 4538 // Given a pixel coordinate relative to the map container, returns 4539 // the corresponding geographical coordinate (for the current zoom level). 4540 containerPointToLatLng: function (point) { 4541 var layerPoint = this.containerPointToLayerPoint(toPoint(point)); 4542 return this.layerPointToLatLng(layerPoint); 4543 }, 4544 4545 // @method latLngToContainerPoint(latlng: LatLng): Point 4546 // Given a geographical coordinate, returns the corresponding pixel coordinate 4547 // relative to the map container. 4548 latLngToContainerPoint: function (latlng) { 4549 return this.layerPointToContainerPoint(this.latLngToLayerPoint(toLatLng(latlng))); 4550 }, 4551 4552 // @method mouseEventToContainerPoint(ev: MouseEvent): Point 4553 // Given a MouseEvent object, returns the pixel coordinate relative to the 4554 // map container where the event took place. 4555 mouseEventToContainerPoint: function (e) { 4556 return getMousePosition(e, this._container); 4557 }, 4558 4559 // @method mouseEventToLayerPoint(ev: MouseEvent): Point 4560 // Given a MouseEvent object, returns the pixel coordinate relative to 4561 // the [origin pixel](#map-getpixelorigin) where the event took place. 4562 mouseEventToLayerPoint: function (e) { 4563 return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(e)); 4564 }, 4565 4566 // @method mouseEventToLatLng(ev: MouseEvent): LatLng 4567 // Given a MouseEvent object, returns geographical coordinate where the 4568 // event took place. 4569 mouseEventToLatLng: function (e) { // (MouseEvent) 4570 return this.layerPointToLatLng(this.mouseEventToLayerPoint(e)); 4571 }, 4572 4573 4574 // map initialization methods 4575 4576 _initContainer: function (id) { 4577 var container = this._container = get(id); 4578 4579 if (!container) { 4580 throw new Error('Map container not found.'); 4581 } else if (container._leaflet_id) { 4582 throw new Error('Map container is already initialized.'); 4583 } 4584 4585 on(container, 'scroll', this._onScroll, this); 4586 this._containerId = stamp(container); 4587 }, 4588 4589 _initLayout: function () { 4590 var container = this._container; 4591 4592 this._fadeAnimated = this.options.fadeAnimation && any3d; 4593 4594 addClass(container, 'leaflet-container' + 4595 (touch ? ' leaflet-touch' : '') + 4596 (retina ? ' leaflet-retina' : '') + 4597 (ielt9 ? ' leaflet-oldie' : '') + 4598 (safari ? ' leaflet-safari' : '') + 4599 (this._fadeAnimated ? ' leaflet-fade-anim' : '')); 4600 4601 var position = getStyle(container, 'position'); 4602 4603 if (position !== 'absolute' && position !== 'relative' && position !== 'fixed') { 4604 container.style.position = 'relative'; 4605 } 4606 4607 this._initPanes(); 4608 4609 if (this._initControlPos) { 4610 this._initControlPos(); 4611 } 4612 }, 4613 4614 _initPanes: function () { 4615 var panes = this._panes = {}; 4616 this._paneRenderers = {}; 4617 4618 // @section 4619 // 4620 // Panes are DOM elements used to control the ordering of layers on the map. You 4621 // can access panes with [`map.getPane`](#map-getpane) or 4622 // [`map.getPanes`](#map-getpanes) methods. New panes can be created with the 4623 // [`map.createPane`](#map-createpane) method. 4624 // 4625 // Every map has the following default panes that differ only in zIndex. 4626 // 4627 // @pane mapPane: HTMLElement = 'auto' 4628 // Pane that contains all other map panes 4629 4630 this._mapPane = this.createPane('mapPane', this._container); 4631 setPosition(this._mapPane, new Point(0, 0)); 4632 4633 // @pane tilePane: HTMLElement = 200 4634 // Pane for `GridLayer`s and `TileLayer`s 4635 this.createPane('tilePane'); 4636 // @pane overlayPane: HTMLElement = 400 4637 // Pane for vectors (`Path`s, like `Polyline`s and `Polygon`s), `ImageOverlay`s and `VideoOverlay`s 4638 this.createPane('shadowPane'); 4639 // @pane shadowPane: HTMLElement = 500 4640 // Pane for overlay shadows (e.g. `Marker` shadows) 4641 this.createPane('overlayPane'); 4642 // @pane markerPane: HTMLElement = 600 4643 // Pane for `Icon`s of `Marker`s 4644 this.createPane('markerPane'); 4645 // @pane tooltipPane: HTMLElement = 650 4646 // Pane for `Tooltip`s. 4647 this.createPane('tooltipPane'); 4648 // @pane popupPane: HTMLElement = 700 4649 // Pane for `Popup`s. 4650 this.createPane('popupPane'); 4651 4652 if (!this.options.markerZoomAnimation) { 4653 addClass(panes.markerPane, 'leaflet-zoom-hide'); 4654 addClass(panes.shadowPane, 'leaflet-zoom-hide'); 4655 } 4656 }, 4657 4658 4659 // private methods that modify map state 4660 4661 // @section Map state change events 4662 _resetView: function (center, zoom) { 4663 setPosition(this._mapPane, new Point(0, 0)); 4664 4665 var loading = !this._loaded; 4666 this._loaded = true; 4667 zoom = this._limitZoom(zoom); 4668 4669 this.fire('viewprereset'); 4670 4671 var zoomChanged = this._zoom !== zoom; 4672 this 4673 ._moveStart(zoomChanged, false) 4674 ._move(center, zoom) 4675 ._moveEnd(zoomChanged); 4676 4677 // @event viewreset: Event 4678 // Fired when the map needs to redraw its content (this usually happens 4679 // on map zoom or load). Very useful for creating custom overlays. 4680 this.fire('viewreset'); 4681 4682 // @event load: Event 4683 // Fired when the map is initialized (when its center and zoom are set 4684 // for the first time). 4685 if (loading) { 4686 this.fire('load'); 4687 } 4688 }, 4689 4690 _moveStart: function (zoomChanged, noMoveStart) { 4691 // @event zoomstart: Event 4692 // Fired when the map zoom is about to change (e.g. before zoom animation). 4693 // @event movestart: Event 4694 // Fired when the view of the map starts changing (e.g. user starts dragging the map). 4695 if (zoomChanged) { 4696 this.fire('zoomstart'); 4697 } 4698 if (!noMoveStart) { 4699 this.fire('movestart'); 4700 } 4701 return this; 4702 }, 4703 4704 _move: function (center, zoom, data) { 4705 if (zoom === undefined) { 4706 zoom = this._zoom; 4707 } 4708 var zoomChanged = this._zoom !== zoom; 4709 4710 this._zoom = zoom; 4711 this._lastCenter = center; 4712 this._pixelOrigin = this._getNewPixelOrigin(center); 4713 4714 // @event zoom: Event 4715 // Fired repeatedly during any change in zoom level, including zoom 4716 // and fly animations. 4717 if (zoomChanged || (data && data.pinch)) { // Always fire 'zoom' if pinching because #3530 4718 this.fire('zoom', data); 4719 } 4720 4721 // @event move: Event 4722 // Fired repeatedly during any movement of the map, including pan and 4723 // fly animations. 4724 return this.fire('move', data); 4725 }, 4726 4727 _moveEnd: function (zoomChanged) { 4728 // @event zoomend: Event 4729 // Fired when the map has changed, after any animations. 4730 if (zoomChanged) { 4731 this.fire('zoomend'); 4732 } 4733 4734 // @event moveend: Event 4735 // Fired when the center of the map stops changing (e.g. user stopped 4736 // dragging the map). 4737 return this.fire('moveend'); 4738 }, 4739 4740 _stop: function () { 4741 cancelAnimFrame(this._flyToFrame); 4742 if (this._panAnim) { 4743 this._panAnim.stop(); 4744 } 4745 return this; 4746 }, 4747 4748 _rawPanBy: function (offset) { 4749 setPosition(this._mapPane, this._getMapPanePos().subtract(offset)); 4750 }, 4751 4752 _getZoomSpan: function () { 4753 return this.getMaxZoom() - this.getMinZoom(); 4754 }, 4755 4756 _panInsideMaxBounds: function () { 4757 if (!this._enforcingBounds) { 4758 this.panInsideBounds(this.options.maxBounds); 4759 } 4760 }, 4761 4762 _checkIfLoaded: function () { 4763 if (!this._loaded) { 4764 throw new Error('Set map center and zoom first.'); 4765 } 4766 }, 4767 4768 // DOM event handling 4769 4770 // @section Interaction events 4771 _initEvents: function (remove$$1) { 4772 this._targets = {}; 4773 this._targets[stamp(this._container)] = this; 4774 4775 var onOff = remove$$1 ? off : on; 4776 4777 // @event click: MouseEvent 4778 // Fired when the user clicks (or taps) the map. 4779 // @event dblclick: MouseEvent 4780 // Fired when the user double-clicks (or double-taps) the map. 4781 // @event mousedown: MouseEvent 4782 // Fired when the user pushes the mouse button on the map. 4783 // @event mouseup: MouseEvent 4784 // Fired when the user releases the mouse button on the map. 4785 // @event mouseover: MouseEvent 4786 // Fired when the mouse enters the map. 4787 // @event mouseout: MouseEvent 4788 // Fired when the mouse leaves the map. 4789 // @event mousemove: MouseEvent 4790 // Fired while the mouse moves over the map. 4791 // @event contextmenu: MouseEvent 4792 // Fired when the user pushes the right mouse button on the map, prevents 4793 // default browser context menu from showing if there are listeners on 4794 // this event. Also fired on mobile when the user holds a single touch 4795 // for a second (also called long press). 4796 // @event keypress: KeyboardEvent 4797 // Fired when the user presses a key from the keyboard that produces a character value while the map is focused. 4798 // @event keydown: KeyboardEvent 4799 // Fired when the user presses a key from the keyboard while the map is focused. Unlike the `keypress` event, 4800 // the `keydown` event is fired for keys that produce a character value and for keys 4801 // that do not produce a character value. 4802 // @event keyup: KeyboardEvent 4803 // Fired when the user releases a key from the keyboard while the map is focused. 4804 onOff(this._container, 'click dblclick mousedown mouseup ' + 4805 'mouseover mouseout mousemove contextmenu keypress keydown keyup', this._handleDOMEvent, this); 4806 4807 if (this.options.trackResize) { 4808 onOff(window, 'resize', this._onResize, this); 4809 } 4810 4811 if (any3d && this.options.transform3DLimit) { 4812 (remove$$1 ? this.off : this.on).call(this, 'moveend', this._onMoveEnd); 4813 } 4814 }, 4815 4816 _onResize: function () { 4817 cancelAnimFrame(this._resizeRequest); 4818 this._resizeRequest = requestAnimFrame( 4819 function () { this.invalidateSize({debounceMoveend: true}); }, this); 4820 }, 4821 4822 _onScroll: function () { 4823 this._container.scrollTop = 0; 4824 this._container.scrollLeft = 0; 4825 }, 4826 4827 _onMoveEnd: function () { 4828 var pos = this._getMapPanePos(); 4829 if (Math.max(Math.abs(pos.x), Math.abs(pos.y)) >= this.options.transform3DLimit) { 4830 // https://bugzilla.mozilla.org/show_bug.cgi?id=1203873 but Webkit also have 4831 // a pixel offset on very high values, see: http://jsfiddle.net/dg6r5hhb/ 4832 this._resetView(this.getCenter(), this.getZoom()); 4833 } 4834 }, 4835 4836 _findEventTargets: function (e, type) { 4837 var targets = [], 4838 target, 4839 isHover = type === 'mouseout' || type === 'mouseover', 4840 src = e.target || e.srcElement, 4841 dragging = false; 4842 4843 while (src) { 4844 target = this._targets[stamp(src)]; 4845 if (target && (type === 'click' || type === 'preclick') && !e._simulated && this._draggableMoved(target)) { 4846 // Prevent firing click after you just dragged an object. 4847 dragging = true; 4848 break; 4849 } 4850 if (target && target.listens(type, true)) { 4851 if (isHover && !isExternalTarget(src, e)) { break; } 4852 targets.push(target); 4853 if (isHover) { break; } 4854 } 4855 if (src === this._container) { break; } 4856 src = src.parentNode; 4857 } 4858 if (!targets.length && !dragging && !isHover && isExternalTarget(src, e)) { 4859 targets = [this]; 4860 } 4861 return targets; 4862 }, 4863 4864 _handleDOMEvent: function (e) { 4865 if (!this._loaded || skipped(e)) { return; } 4866 4867 var type = e.type; 4868 4869 if (type === 'mousedown' || type === 'keypress' || type === 'keyup' || type === 'keydown') { 4870 // prevents outline when clicking on keyboard-focusable element 4871 preventOutline(e.target || e.srcElement); 4872 } 4873 4874 this._fireDOMEvent(e, type); 4875 }, 4876 4877 _mouseEvents: ['click', 'dblclick', 'mouseover', 'mouseout', 'contextmenu'], 4878 4879 _fireDOMEvent: function (e, type, targets) { 4880 4881 if (e.type === 'click') { 4882 // Fire a synthetic 'preclick' event which propagates up (mainly for closing popups). 4883 // @event preclick: MouseEvent 4884 // Fired before mouse click on the map (sometimes useful when you 4885 // want something to happen on click before any existing click 4886 // handlers start running). 4887 var synth = extend({}, e); 4888 synth.type = 'preclick'; 4889 this._fireDOMEvent(synth, synth.type, targets); 4890 } 4891 4892 if (e._stopped) { return; } 4893 4894 // Find the layer the event is propagating from and its parents. 4895 targets = (targets || []).concat(this._findEventTargets(e, type)); 4896 4897 if (!targets.length) { return; } 4898 4899 var target = targets[0]; 4900 if (type === 'contextmenu' && target.listens(type, true)) { 4901 preventDefault(e); 4902 } 4903 4904 var data = { 4905 originalEvent: e 4906 }; 4907 4908 if (e.type !== 'keypress' && e.type !== 'keydown' && e.type !== 'keyup') { 4909 var isMarker = target.getLatLng && (!target._radius || target._radius <= 10); 4910 data.containerPoint = isMarker ? 4911 this.latLngToContainerPoint(target.getLatLng()) : this.mouseEventToContainerPoint(e); 4912 data.layerPoint = this.containerPointToLayerPoint(data.containerPoint); 4913 data.latlng = isMarker ? target.getLatLng() : this.layerPointToLatLng(data.layerPoint); 4914 } 4915 4916 for (var i = 0; i < targets.length; i++) { 4917 targets[i].fire(type, data, true); 4918 if (data.originalEvent._stopped || 4919 (targets[i].options.bubblingMouseEvents === false && indexOf(this._mouseEvents, type) !== -1)) { return; } 4920 } 4921}, 4922 4923_draggableMoved: function (obj) { 4924 obj = obj.dragging && obj.dragging.enabled() ? obj : this; 4925 return (obj.dragging && obj.dragging.moved()) || (this.boxZoom && this.boxZoom.moved()); 4926}, 4927 4928_clearHandlers: function () { 4929 for (var i = 0, len = this._handlers.length; i < len; i++) { 4930 this._handlers[i].disable(); 4931 } 4932}, 4933 4934 // @section Other Methods 4935 4936 // @method whenReady(fn: Function, context?: Object): this 4937 // Runs the given function `fn` when the map gets initialized with 4938 // a view (center and zoom) and at least one layer, or immediately 4939 // if it's already initialized, optionally passing a function context. 4940 whenReady: function (callback, context) { 4941 if (this._loaded) { 4942 callback.call(context || this, {target: this}); 4943 } else { 4944 this.on('load', callback, context); 4945 } 4946 return this; 4947 }, 4948 4949 4950 // private methods for getting map state 4951 4952 _getMapPanePos: function () { 4953 return getPosition(this._mapPane) || new Point(0, 0); 4954 }, 4955 4956 _moved: function () { 4957 var pos = this._getMapPanePos(); 4958 return pos && !pos.equals([0, 0]); 4959 }, 4960 4961 _getTopLeftPoint: function (center, zoom) { 4962 var pixelOrigin = center && zoom !== undefined ? 4963 this._getNewPixelOrigin(center, zoom) : 4964 this.getPixelOrigin(); 4965 return pixelOrigin.subtract(this._getMapPanePos()); 4966 }, 4967 4968 _getNewPixelOrigin: function (center, zoom) { 4969 var viewHalf = this.getSize()._divideBy(2); 4970 return this.project(center, zoom)._subtract(viewHalf)._add(this._getMapPanePos())._round(); 4971}, 4972 4973_latLngToNewLayerPoint: function (latlng, zoom, center) { 4974 var topLeft = this._getNewPixelOrigin(center, zoom); 4975 return this.project(latlng, zoom)._subtract(topLeft); 4976}, 4977 4978_latLngBoundsToNewLayerBounds: function (latLngBounds, zoom, center) { 4979 var topLeft = this._getNewPixelOrigin(center, zoom); 4980 return toBounds([ 4981 this.project(latLngBounds.getSouthWest(), zoom)._subtract(topLeft), 4982 this.project(latLngBounds.getNorthWest(), zoom)._subtract(topLeft), 4983 this.project(latLngBounds.getSouthEast(), zoom)._subtract(topLeft), 4984 this.project(latLngBounds.getNorthEast(), zoom)._subtract(topLeft) 4985 ]); 4986}, 4987 4988 // layer point of the current center 4989 _getCenterLayerPoint: function () { 4990 return this.containerPointToLayerPoint(this.getSize()._divideBy(2)); 4991 }, 4992 4993 // offset of the specified place to the current center in pixels 4994 _getCenterOffset: function (latlng) { 4995 return this.latLngToLayerPoint(latlng).subtract(this._getCenterLayerPoint()); 4996 }, 4997 4998 // adjust center for view to get inside bounds 4999 _limitCenter: function (center, zoom, bounds) { 5000 5001 if (!bounds) { return center; } 5002 5003 var centerPoint = this.project(center, zoom), 5004 viewHalf = this.getSize().divideBy(2), 5005 viewBounds = new Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)), 5006 offset = this._getBoundsOffset(viewBounds, bounds, zoom); 5007 5008 // If offset is less than a pixel, ignore. 5009 // This prevents unstable projections from getting into 5010 // an infinite loop of tiny offsets. 5011 if (offset.round().equals([0, 0])) { 5012 return center; 5013 } 5014 5015 return this.unproject(centerPoint.add(offset), zoom); 5016 }, 5017 5018 // adjust offset for view to get inside bounds 5019 _limitOffset: function (offset, bounds) { 5020 if (!bounds) { return offset; } 5021 5022 var viewBounds = this.getPixelBounds(), 5023 newBounds = new Bounds(viewBounds.min.add(offset), viewBounds.max.add(offset)); 5024 5025 return offset.add(this._getBoundsOffset(newBounds, bounds)); 5026 }, 5027 5028 // returns offset needed for pxBounds to get inside maxBounds at a specified zoom 5029 _getBoundsOffset: function (pxBounds, maxBounds, zoom) { 5030 var projectedMaxBounds = toBounds( 5031 this.project(maxBounds.getNorthEast(), zoom), 5032 this.project(maxBounds.getSouthWest(), zoom) 5033 ), 5034 minOffset = projectedMaxBounds.min.subtract(pxBounds.min), 5035 maxOffset = projectedMaxBounds.max.subtract(pxBounds.max), 5036 5037 dx = this._rebound(minOffset.x, -maxOffset.x), 5038 dy = this._rebound(minOffset.y, -maxOffset.y); 5039 5040 return new Point(dx, dy); 5041 }, 5042 5043 _rebound: function (left, right) { 5044 return left + right > 0 ? 5045 Math.round(left - right) / 2 : 5046 Math.max(0, Math.ceil(left)) - Math.max(0, Math.floor(right)); 5047 }, 5048 5049 _limitZoom: function (zoom) { 5050 var min = this.getMinZoom(), 5051 max = this.getMaxZoom(), 5052 snap = any3d ? this.options.zoomSnap : 1; 5053 if (snap) { 5054 zoom = Math.round(zoom / snap) * snap; 5055 } 5056 return Math.max(min, Math.min(max, zoom)); 5057 }, 5058 5059 _onPanTransitionStep: function () { 5060 this.fire('move'); 5061}, 5062 5063_onPanTransitionEnd: function () { 5064 removeClass(this._mapPane, 'leaflet-pan-anim'); 5065 this.fire('moveend'); 5066}, 5067 5068_tryAnimatedPan: function (center, options) { 5069 // difference between the new and current centers in pixels 5070 var offset = this._getCenterOffset(center)._trunc(); 5071 5072 // don't animate too far unless animate: true specified in options 5073 if ((options && options.animate) !== true && !this.getSize().contains(offset)) { return false; } 5074 5075 this.panBy(offset, options); 5076 5077 return true; 5078 }, 5079 5080 _createAnimProxy: function () { 5081 5082 var proxy = this._proxy = create$1('div', 'leaflet-proxy leaflet-zoom-animated'); 5083 this._panes.mapPane.appendChild(proxy); 5084 5085 this.on('zoomanim', function (e) { 5086 var prop = TRANSFORM, 5087 transform = this._proxy.style[prop]; 5088 5089 setTransform(this._proxy, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1)); 5090 5091 // workaround for case when transform is the same and so transitionend event is not fired 5092 if (transform === this._proxy.style[prop] && this._animatingZoom) { 5093 this._onZoomTransitionEnd(); 5094 } 5095 }, this); 5096 5097 this.on('load moveend', function () { 5098 var c = this.getCenter(), 5099 z = this.getZoom(); 5100 setTransform(this._proxy, this.project(c, z), this.getZoomScale(z, 1)); 5101 }, this); 5102 5103 this._on('unload', this._destroyAnimProxy, this); 5104 }, 5105 5106 _destroyAnimProxy: function () { 5107 remove(this._proxy); 5108 delete this._proxy; 5109 }, 5110 5111 _catchTransitionEnd: function (e) { 5112 if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) { 5113 this._onZoomTransitionEnd(); 5114 } 5115 }, 5116 5117 _nothingToAnimate: function () { 5118 return !this._container.getElementsByClassName('leaflet-zoom-animated').length; 5119 }, 5120 5121 _tryAnimatedZoom: function (center, zoom, options) { 5122 5123 if (this._animatingZoom) { return true; } 5124 5125 options = options || {}; 5126 5127 // don't animate if disabled, not supported or zoom difference is too large 5128 if (!this._zoomAnimated || options.animate === false || this._nothingToAnimate() || 5129 Math.abs(zoom - this._zoom) > this.options.zoomAnimationThreshold) { return false; } 5130 5131 // offset is the pixel coords of the zoom origin relative to the current center 5132 var scale = this.getZoomScale(zoom), 5133 offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale); 5134 5135 // don't animate if the zoom origin isn't within one screen from the current center, unless forced 5136 if (options.animate !== true && !this.getSize().contains(offset)) { return false; } 5137 5138 requestAnimFrame(function () { 5139 this 5140 ._moveStart(true, false) 5141 ._animateZoom(center, zoom, true); 5142 }, this); 5143 5144 return true; 5145 }, 5146 5147 _animateZoom: function (center, zoom, startAnim, noUpdate) { 5148 if (!this._mapPane) { return; } 5149 5150 if (startAnim) { 5151 this._animatingZoom = true; 5152 5153 // remember what center/zoom to set after animation 5154 this._animateToCenter = center; 5155 this._animateToZoom = zoom; 5156 5157 addClass(this._mapPane, 'leaflet-zoom-anim'); 5158 } 5159 5160 // @event zoomanim: ZoomAnimEvent 5161 // Fired at least once per zoom animation. For continuous zoom, like pinch zooming, fired once per frame during zoom. 5162 this.fire('zoomanim', { 5163 center: center, 5164 zoom: zoom, 5165 noUpdate: noUpdate 5166 }); 5167 5168 // Work around webkit not firing 'transitionend', see https://github.com/Leaflet/Leaflet/issues/3689, 2693 5169 setTimeout(bind(this._onZoomTransitionEnd, this), 250); 5170 }, 5171 5172 _onZoomTransitionEnd: function () { 5173 if (!this._animatingZoom) { return; } 5174 5175 if (this._mapPane) { 5176 removeClass(this._mapPane, 'leaflet-zoom-anim'); 5177 } 5178 5179 this._animatingZoom = false; 5180 5181 this._move(this._animateToCenter, this._animateToZoom); 5182 5183 // This anim frame should prevent an obscure iOS webkit tile loading race condition. 5184 requestAnimFrame(function () { 5185 this._moveEnd(true); 5186 }, this); 5187 } 5188}); 5189 5190// @section 5191 5192// @factory L.map(id: String, options?: Map options) 5193// Instantiates a map object given the DOM ID of a `<div>` element 5194// and optionally an object literal with `Map options`. 5195// 5196// @alternative 5197// @factory L.map(el: HTMLElement, options?: Map options) 5198// Instantiates a map object given an instance of a `<div>` HTML element 5199// and optionally an object literal with `Map options`. 5200function createMap(id, options) { 5201 return new Map(id, options); 5202} 5203 5204/* 5205 * @class Control 5206 * @aka L.Control 5207 * @inherits Class 5208 * 5209 * L.Control is a base class for implementing map controls. Handles positioning. 5210 * All other controls extend from this class. 5211 */ 5212 5213 var Control = Class.extend({ 5214 // @section 5215 // @aka Control options 5216 options: { 5217 // @option position: String = 'topright' 5218 // The position of the control (one of the map corners). Possible values are `'topleft'`, 5219 // `'topright'`, `'bottomleft'` or `'bottomright'` 5220 position: 'topright' 5221 }, 5222 5223 initialize: function (options) { 5224 setOptions(this, options); 5225 }, 5226 5227 /* @section 5228 * Classes extending L.Control will inherit the following methods: 5229 * 5230 * @method getPosition: string 5231 * Returns the position of the control. 5232 */ 5233 getPosition: function () { 5234 return this.options.position; 5235 }, 5236 5237 // @method setPosition(position: string): this 5238 // Sets the position of the control. 5239 setPosition: function (position) { 5240 var map = this._map; 5241 5242 if (map) { 5243 map.removeControl(this); 5244 } 5245 5246 this.options.position = position; 5247 5248 if (map) { 5249 map.addControl(this); 5250 } 5251 5252 return this; 5253 }, 5254 5255 // @method getContainer: HTMLElement 5256 // Returns the HTMLElement that contains the control. 5257 getContainer: function () { 5258 return this._container; 5259 }, 5260 5261 // @method addTo(map: Map): this 5262 // Adds the control to the given map. 5263 addTo: function (map) { 5264 this.remove(); 5265 this._map = map; 5266 5267 var container = this._container = this.onAdd(map), 5268 pos = this.getPosition(), 5269 corner = map._controlCorners[pos]; 5270 5271 addClass(container, 'leaflet-control'); 5272 5273 if (pos.indexOf('bottom') !== -1) { 5274 corner.insertBefore(container, corner.firstChild); 5275 } else { 5276 corner.appendChild(container); 5277 } 5278 5279 this._map.on('unload', this.remove, this); 5280 5281 return this; 5282 }, 5283 5284 // @method remove: this 5285 // Removes the control from the map it is currently active on. 5286 remove: function () { 5287 if (!this._map) { 5288 return this; 5289 } 5290 5291 remove(this._container); 5292 5293 if (this.onRemove) { 5294 this.onRemove(this._map); 5295 } 5296 5297 this._map.off('unload', this.remove, this); 5298 this._map = null; 5299 5300 return this; 5301 }, 5302 5303 _refocusOnMap: function (e) { 5304 // if map exists and event is not a keyboard event 5305 if (this._map && e && e.screenX > 0 && e.screenY > 0) { 5306 this._map.getContainer().focus(); 5307 } 5308 } 5309}); 5310 5311 var control = function (options) { 5312 return new Control(options); 5313 }; 5314 5315/* @section Extension methods 5316 * @uninheritable 5317 * 5318 * Every control should extend from `L.Control` and (re-)implement the following methods. 5319 * 5320 * @method onAdd(map: Map): HTMLElement 5321 * Should return the container DOM element for the control and add listeners on relevant map events. Called on [`control.addTo(map)`](#control-addTo). 5322 * 5323 * @method onRemove(map: Map) 5324 * Optional method. Should contain all clean up code that removes the listeners previously added in [`onAdd`](#control-onadd). Called on [`control.remove()`](#control-remove). 5325 */ 5326 5327/* @namespace Map 5328 * @section Methods for Layers and Controls 5329 */ 5330 Map.include({ 5331 // @method addControl(control: Control): this 5332 // Adds the given control to the map 5333 addControl: function (control) { 5334 control.addTo(this); 5335 return this; 5336 }, 5337 5338 // @method removeControl(control: Control): this 5339 // Removes the given control from the map 5340 removeControl: function (control) { 5341 control.remove(); 5342 return this; 5343 }, 5344 5345 _initControlPos: function () { 5346 var corners = this._controlCorners = {}, 5347 l = 'leaflet-', 5348 container = this._controlContainer = 5349 create$1('div', l + 'control-container', this._container); 5350 5351 function createCorner(vSide, hSide) { 5352 var className = l + vSide + ' ' + l + hSide; 5353 5354 corners[vSide + hSide] = create$1('div', className, container); 5355 } 5356 5357 createCorner('top', 'left'); 5358 createCorner('top', 'right'); 5359 createCorner('bottom', 'left'); 5360 createCorner('bottom', 'right'); 5361 }, 5362 5363 _clearControlPos: function () { 5364 for (var i in this._controlCorners) { 5365 remove(this._controlCorners[i]); 5366 } 5367 remove(this._controlContainer); 5368 delete this._controlCorners; 5369 delete this._controlContainer; 5370} 5371}); 5372 5373/* 5374 * @class Control.Layers 5375 * @aka L.Control.Layers 5376 * @inherits Control 5377 * 5378 * The layers control gives users the ability to switch between different base layers and switch overlays on/off (check out the [detailed example](http://leafletjs.com/examples/layers-control/)). Extends `Control`. 5379 * 5380 * @example 5381 * 5382 * ```js 5383 * var baseLayers = { 5384 * "Mapbox": mapbox, 5385 * "OpenStreetMap": osm 5386 * }; 5387 * 5388 * var overlays = { 5389 * "Marker": marker, 5390 * "Roads": roadsLayer 5391 * }; 5392 * 5393 * L.control.layers(baseLayers, overlays).addTo(map); 5394 * ``` 5395 * 5396 * The `baseLayers` and `overlays` parameters are object literals with layer names as keys and `Layer` objects as values: 5397 * 5398 * ```js 5399 * { 5400 * "<someName1>": layer1, 5401 * "<someName2>": layer2 5402 * } 5403 * ``` 5404 * 5405 * The layer names can contain HTML, which allows you to add additional styling to the items: 5406 * 5407 * ```js 5408 * {"<img src='my-layer-icon' /> <span class='my-layer-item'>My Layer</span>": myLayer} 5409 * ``` 5410 */ 5411 5412 var Layers = Control.extend({ 5413 // @section 5414 // @aka Control.Layers options 5415 options: { 5416 // @option collapsed: Boolean = true 5417 // If `true`, the control will be collapsed into an icon and expanded on mouse hover or touch. 5418 collapsed: true, 5419 position: 'topright', 5420 5421 // @option autoZIndex: Boolean = true 5422 // If `true`, the control will assign zIndexes in increasing order to all of its layers so that the order is preserved when switching them on/off. 5423 autoZIndex: true, 5424 5425 // @option hideSingleBase: Boolean = false 5426 // If `true`, the base layers in the control will be hidden when there is only one. 5427 hideSingleBase: false, 5428 5429 // @option sortLayers: Boolean = false 5430 // Whether to sort the layers. When `false`, layers will keep the order 5431 // in which they were added to the control. 5432 sortLayers: false, 5433 5434 // @option sortFunction: Function = * 5435 // A [compare function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 5436 // that will be used for sorting the layers, when `sortLayers` is `true`. 5437 // The function receives both the `L.Layer` instances and their names, as in 5438 // `sortFunction(layerA, layerB, nameA, nameB)`. 5439 // By default, it sorts layers alphabetically by their name. 5440 sortFunction: function (layerA, layerB, nameA, nameB) { 5441 return nameA < nameB ? -1 : (nameB < nameA ? 1 : 0); 5442 } 5443 }, 5444 5445 initialize: function (baseLayers, overlays, options) { 5446 setOptions(this, options); 5447 5448 this._layerControlInputs = []; 5449 this._layers = []; 5450 this._lastZIndex = 0; 5451 this._handlingClick = false; 5452 5453 for (var i in baseLayers) { 5454 this._addLayer(baseLayers[i], i); 5455 } 5456 5457 for (i in overlays) { 5458 this._addLayer(overlays[i], i, true); 5459 } 5460 }, 5461 5462 onAdd: function (map) { 5463 this._initLayout(); 5464 this._update(); 5465 5466 this._map = map; 5467 map.on('zoomend', this._checkDisabledLayers, this); 5468 5469 for (var i = 0; i < this._layers.length; i++) { 5470 this._layers[i].layer.on('add remove', this._onLayerChange, this); 5471 } 5472 5473 return this._container; 5474 }, 5475 5476 addTo: function (map) { 5477 Control.prototype.addTo.call(this, map); 5478 // Trigger expand after Layers Control has been inserted into DOM so that is now has an actual height. 5479 return this._expandIfNotCollapsed(); 5480 }, 5481 5482 onRemove: function () { 5483 this._map.off('zoomend', this._checkDisabledLayers, this); 5484 5485 for (var i = 0; i < this._layers.length; i++) { 5486 this._layers[i].layer.off('add remove', this._onLayerChange, this); 5487 } 5488 }, 5489 5490 // @method addBaseLayer(layer: Layer, name: String): this 5491 // Adds a base layer (radio button entry) with the given name to the control. 5492 addBaseLayer: function (layer, name) { 5493 this._addLayer(layer, name); 5494 return (this._map) ? this._update() : this; 5495 }, 5496 5497 // @method addOverlay(layer: Layer, name: String): this 5498 // Adds an overlay (checkbox entry) with the given name to the control. 5499 addOverlay: function (layer, name) { 5500 this._addLayer(layer, name, true); 5501 return (this._map) ? this._update() : this; 5502 }, 5503 5504 // @method removeLayer(layer: Layer): this 5505 // Remove the given layer from the control. 5506 removeLayer: function (layer) { 5507 layer.off('add remove', this._onLayerChange, this); 5508 5509 var obj = this._getLayer(stamp(layer)); 5510 if (obj) { 5511 this._layers.splice(this._layers.indexOf(obj), 1); 5512 } 5513 return (this._map) ? this._update() : this; 5514 }, 5515 5516 // @method expand(): this 5517 // Expand the control container if collapsed. 5518 expand: function () { 5519 addClass(this._container, 'leaflet-control-layers-expanded'); 5520 this._section.style.height = null; 5521 var acceptableHeight = this._map.getSize().y - (this._container.offsetTop + 50); 5522 if (acceptableHeight < this._section.clientHeight) { 5523 addClass(this._section, 'leaflet-control-layers-scrollbar'); 5524 this._section.style.height = acceptableHeight + 'px'; 5525 } else { 5526 removeClass(this._section, 'leaflet-control-layers-scrollbar'); 5527 } 5528 this._checkDisabledLayers(); 5529 return this; 5530 }, 5531 5532 // @method collapse(): this 5533 // Collapse the control container if expanded. 5534 collapse: function () { 5535 removeClass(this._container, 'leaflet-control-layers-expanded'); 5536 return this; 5537 }, 5538 5539 _initLayout: function () { 5540 var className = 'leaflet-control-layers', 5541 container = this._container = create$1('div', className), 5542 collapsed = this.options.collapsed; 5543 5544 // makes this work on IE touch devices by stopping it from firing a mouseout event when the touch is released 5545 container.setAttribute('aria-haspopup', true); 5546 5547 disableClickPropagation(container); 5548 disableScrollPropagation(container); 5549 5550 var section = this._section = create$1('section', className + '-list'); 5551 5552 if (collapsed) { 5553 this._map.on('click', this.collapse, this); 5554 5555 if (!android) { 5556 on(container, { 5557 mouseenter: this.expand, 5558 mouseleave: this.collapse 5559 }, this); 5560 } 5561 } 5562 5563 var link = this._layersLink = create$1('a', className + '-toggle', container); 5564 link.href = '#'; 5565 link.title = 'Layers'; 5566 5567 if (touch) { 5568 on(link, 'click', stop); 5569 on(link, 'click', this.expand, this); 5570 } else { 5571 on(link, 'focus', this.expand, this); 5572 } 5573 5574 if (!collapsed) { 5575 this.expand(); 5576 } 5577 5578 this._baseLayersList = create$1('div', className + '-base', section); 5579 this._separator = create$1('div', className + '-separator', section); 5580 this._overlaysList = create$1('div', className + '-overlays', section); 5581 5582 container.appendChild(section); 5583 }, 5584 5585 _getLayer: function (id) { 5586 for (var i = 0; i < this._layers.length; i++) { 5587 5588 if (this._layers[i] && stamp(this._layers[i].layer) === id) { 5589 return this._layers[i]; 5590 } 5591 } 5592 }, 5593 5594 _addLayer: function (layer, name, overlay) { 5595 if (this._map) { 5596 layer.on('add remove', this._onLayerChange, this); 5597 } 5598 5599 this._layers.push({ 5600 layer: layer, 5601 name: name, 5602 overlay: overlay 5603 }); 5604 5605 if (this.options.sortLayers) { 5606 this._layers.sort(bind(function (a, b) { 5607 return this.options.sortFunction(a.layer, b.layer, a.name, b.name); 5608 }, this)); 5609 } 5610 5611 if (this.options.autoZIndex && layer.setZIndex) { 5612 this._lastZIndex++; 5613 layer.setZIndex(this._lastZIndex); 5614 } 5615 5616 this._expandIfNotCollapsed(); 5617 }, 5618 5619 _update: function () { 5620 if (!this._container) { return this; } 5621 5622 empty(this._baseLayersList); 5623 empty(this._overlaysList); 5624 5625 this._layerControlInputs = []; 5626 var baseLayersPresent, overlaysPresent, i, obj, baseLayersCount = 0; 5627 5628 for (i = 0; i < this._layers.length; i++) { 5629 obj = this._layers[i]; 5630 this._addItem(obj); 5631 overlaysPresent = overlaysPresent || obj.overlay; 5632 baseLayersPresent = baseLayersPresent || !obj.overlay; 5633 baseLayersCount += !obj.overlay ? 1 : 0; 5634 } 5635 5636 // Hide base layers section if there's only one layer. 5637 if (this.options.hideSingleBase) { 5638 baseLayersPresent = baseLayersPresent && baseLayersCount > 1; 5639 this._baseLayersList.style.display = baseLayersPresent ? '' : 'none'; 5640 } 5641 5642 this._separator.style.display = overlaysPresent && baseLayersPresent ? '' : 'none'; 5643 5644 return this; 5645 }, 5646 5647 _onLayerChange: function (e) { 5648 if (!this._handlingClick) { 5649 this._update(); 5650 } 5651 5652 var obj = this._getLayer(stamp(e.target)); 5653 5654 // @namespace Map 5655 // @section Layer events 5656 // @event baselayerchange: LayersControlEvent 5657 // Fired when the base layer is changed through the [layer control](#control-layers). 5658 // @event overlayadd: LayersControlEvent 5659 // Fired when an overlay is selected through the [layer control](#control-layers). 5660 // @event overlayremove: LayersControlEvent 5661 // Fired when an overlay is deselected through the [layer control](#control-layers). 5662 // @namespace Control.Layers 5663 var type = obj.overlay ? 5664 (e.type === 'add' ? 'overlayadd' : 'overlayremove') : 5665 (e.type === 'add' ? 'baselayerchange' : null); 5666 5667 if (type) { 5668 this._map.fire(type, obj); 5669 } 5670 }, 5671 5672 // IE7 bugs out if you create a radio dynamically, so you have to do it this hacky way (see http://bit.ly/PqYLBe) 5673 _createRadioElement: function (name, checked) { 5674 5675 var radioHtml = '<input type="radio" class="leaflet-control-layers-selector" name="' + 5676 name + '"' + (checked ? ' checked="checked"' : '') + '/>'; 5677 5678 var radioFragment = document.createElement('div'); 5679 radioFragment.innerHTML = radioHtml; 5680 5681 return radioFragment.firstChild; 5682 }, 5683 5684 _addItem: function (obj) { 5685 var label = document.createElement('label'), 5686 checked = this._map.hasLayer(obj.layer), 5687 input; 5688 5689 if (obj.overlay) { 5690 input = document.createElement('input'); 5691 input.type = 'checkbox'; 5692 input.className = 'leaflet-control-layers-selector'; 5693 input.defaultChecked = checked; 5694 } else { 5695 input = this._createRadioElement('leaflet-base-layers_' + stamp(this), checked); 5696 } 5697 5698 this._layerControlInputs.push(input); 5699 input.layerId = stamp(obj.layer); 5700 5701 on(input, 'click', this._onInputClick, this); 5702 5703 var name = document.createElement('span'); 5704 name.innerHTML = ' ' + obj.name; 5705 5706 // Helps from preventing layer control flicker when checkboxes are disabled 5707 // https://github.com/Leaflet/Leaflet/issues/2771 5708 var holder = document.createElement('div'); 5709 5710 label.appendChild(holder); 5711 holder.appendChild(input); 5712 holder.appendChild(name); 5713 5714 var container = obj.overlay ? this._overlaysList : this._baseLayersList; 5715 container.appendChild(label); 5716 5717 this._checkDisabledLayers(); 5718 return label; 5719 }, 5720 5721 _onInputClick: function () { 5722 var inputs = this._layerControlInputs, 5723 input, layer; 5724 var addedLayers = [], 5725 removedLayers = []; 5726 5727 this._handlingClick = true; 5728 5729 for (var i = inputs.length - 1; i >= 0; i--) { 5730 input = inputs[i]; 5731 layer = this._getLayer(input.layerId).layer; 5732 5733 if (input.checked) { 5734 addedLayers.push(layer); 5735 } else if (!input.checked) { 5736 removedLayers.push(layer); 5737 } 5738 } 5739 5740 // Bugfix issue 2318: Should remove all old layers before readding new ones 5741 for (i = 0; i < removedLayers.length; i++) { 5742 if (this._map.hasLayer(removedLayers[i])) { 5743 this._map.removeLayer(removedLayers[i]); 5744 } 5745 } 5746 for (i = 0; i < addedLayers.length; i++) { 5747 if (!this._map.hasLayer(addedLayers[i])) { 5748 this._map.addLayer(addedLayers[i]); 5749 } 5750 } 5751 5752 this._handlingClick = false; 5753 5754 this._refocusOnMap(); 5755 }, 5756 5757 _checkDisabledLayers: function () { 5758 var inputs = this._layerControlInputs, 5759 input, 5760 layer, 5761 zoom = this._map.getZoom(); 5762 5763 for (var i = inputs.length - 1; i >= 0; i--) { 5764 input = inputs[i]; 5765 layer = this._getLayer(input.layerId).layer; 5766 input.disabled = (layer.options.minZoom !== undefined && zoom < layer.options.minZoom) || 5767 (layer.options.maxZoom !== undefined && zoom > layer.options.maxZoom); 5768 5769 } 5770 }, 5771 5772 _expandIfNotCollapsed: function () { 5773 if (this._map && !this.options.collapsed) { 5774 this.expand(); 5775 } 5776 return this; 5777}, 5778 5779_expand: function () { 5780 // Backward compatibility, remove me in 1.1. 5781 return this.expand(); 5782 }, 5783 5784 _collapse: function () { 5785 // Backward compatibility, remove me in 1.1. 5786 return this.collapse(); 5787 } 5788 5789}); 5790 5791 5792// @factory L.control.layers(baselayers?: Object, overlays?: Object, options?: Control.Layers options) 5793// Creates an attribution control with the given layers. Base layers will be switched with radio buttons, while overlays will be switched with checkboxes. Note that all base layers should be passed in the base layers object, but only one should be added to the map during map instantiation. 5794var layers = function (baseLayers, overlays, options) { 5795 return new Layers(baseLayers, overlays, options); 5796}; 5797 5798/* 5799 * @class Control.Zoom 5800 * @aka L.Control.Zoom 5801 * @inherits Control 5802 * 5803 * A basic zoom control with two buttons (zoom in and zoom out). It is put on the map by default unless you set its [`zoomControl` option](#map-zoomcontrol) to `false`. Extends `Control`. 5804 */ 5805 5806 var Zoom = Control.extend({ 5807 // @section 5808 // @aka Control.Zoom options 5809 options: { 5810 position: 'topleft', 5811 5812 // @option zoomInText: String = '+' 5813 // The text set on the 'zoom in' button. 5814 zoomInText: '+', 5815 5816 // @option zoomInTitle: String = 'Zoom in' 5817 // The title set on the 'zoom in' button. 5818 zoomInTitle: 'Zoom in', 5819 5820 // @option zoomOutText: String = '−' 5821 // The text set on the 'zoom out' button. 5822 zoomOutText: '−', 5823 5824 // @option zoomOutTitle: String = 'Zoom out' 5825 // The title set on the 'zoom out' button. 5826 zoomOutTitle: 'Zoom out' 5827 }, 5828 5829 onAdd: function (map) { 5830 var zoomName = 'leaflet-control-zoom', 5831 container = create$1('div', zoomName + ' leaflet-bar'), 5832 options = this.options; 5833 5834 this._zoomInButton = this._createButton(options.zoomInText, options.zoomInTitle, 5835 zoomName + '-in', container, this._zoomIn); 5836 this._zoomOutButton = this._createButton(options.zoomOutText, options.zoomOutTitle, 5837 zoomName + '-out', container, this._zoomOut); 5838 5839 this._updateDisabled(); 5840 map.on('zoomend zoomlevelschange', this._updateDisabled, this); 5841 5842 return container; 5843 }, 5844 5845 onRemove: function (map) { 5846 map.off('zoomend zoomlevelschange', this._updateDisabled, this); 5847 }, 5848 5849 disable: function () { 5850 this._disabled = true; 5851 this._updateDisabled(); 5852 return this; 5853 }, 5854 5855 enable: function () { 5856 this._disabled = false; 5857 this._updateDisabled(); 5858 return this; 5859 }, 5860 5861 _zoomIn: function (e) { 5862 if (!this._disabled && this._map._zoom < this._map.getMaxZoom()) { 5863 this._map.zoomIn(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1)); 5864 } 5865 }, 5866 5867 _zoomOut: function (e) { 5868 if (!this._disabled && this._map._zoom > this._map.getMinZoom()) { 5869 this._map.zoomOut(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1)); 5870 } 5871}, 5872 5873_createButton: function (html, title, className, container, fn) { 5874 var link = create$1('a', className, container); 5875 link.innerHTML = html; 5876 link.href = '#'; 5877 link.title = title; 5878 5879 /* 5880 * Will force screen readers like VoiceOver to read this as "Zoom in - button" 5881 */ 5882 link.setAttribute('role', 'button'); 5883 link.setAttribute('aria-label', title); 5884 5885 disableClickPropagation(link); 5886 on(link, 'click', stop); 5887 on(link, 'click', fn, this); 5888 on(link, 'click', this._refocusOnMap, this); 5889 5890 return link; 5891 }, 5892 5893 _updateDisabled: function () { 5894 var map = this._map, 5895 className = 'leaflet-disabled'; 5896 5897 removeClass(this._zoomInButton, className); 5898 removeClass(this._zoomOutButton, className); 5899 5900 if (this._disabled || map._zoom === map.getMinZoom()) { 5901 addClass(this._zoomOutButton, className); 5902 } 5903 if (this._disabled || map._zoom === map.getMaxZoom()) { 5904 addClass(this._zoomInButton, className); 5905 } 5906 } 5907}); 5908 5909// @namespace Map 5910// @section Control options 5911// @option zoomControl: Boolean = true 5912// Whether a [zoom control](#control-zoom) is added to the map by default. 5913Map.mergeOptions({ 5914 zoomControl: true 5915}); 5916 5917Map.addInitHook(function () { 5918 if (this.options.zoomControl) { 5919 // @section Controls 5920 // @property zoomControl: Control.Zoom 5921 // The default zoom control (only available if the 5922 // [`zoomControl` option](#map-zoomcontrol) was `true` when creating the map). 5923 this.zoomControl = new Zoom(); 5924 this.addControl(this.zoomControl); 5925 } 5926}); 5927 5928// @namespace Control.Zoom 5929// @factory L.control.zoom(options: Control.Zoom options) 5930// Creates a zoom control 5931var zoom = function (options) { 5932 return new Zoom(options); 5933}; 5934 5935/* 5936 * @class Control.Scale 5937 * @aka L.Control.Scale 5938 * @inherits Control 5939 * 5940 * A simple scale control that shows the scale of the current center of screen in metric (m/km) and imperial (mi/ft) systems. Extends `Control`. 5941 * 5942 * @example 5943 * 5944 * ```js 5945 * L.control.scale().addTo(map); 5946 * ``` 5947 */ 5948 5949 var Scale = Control.extend({ 5950 // @section 5951 // @aka Control.Scale options 5952 options: { 5953 position: 'bottomleft', 5954 5955 // @option maxWidth: Number = 100 5956 // Maximum width of the control in pixels. The width is set dynamically to show round values (e.g. 100, 200, 500). 5957 maxWidth: 100, 5958 5959 // @option metric: Boolean = True 5960 // Whether to show the metric scale line (m/km). 5961 metric: true, 5962 5963 // @option imperial: Boolean = True 5964 // Whether to show the imperial scale line (mi/ft). 5965 imperial: true 5966 5967 // @option updateWhenIdle: Boolean = false 5968 // If `true`, the control is updated on [`moveend`](#map-moveend), otherwise it's always up-to-date (updated on [`move`](#map-move)). 5969 }, 5970 5971 onAdd: function (map) { 5972 var className = 'leaflet-control-scale', 5973 container = create$1('div', className), 5974 options = this.options; 5975 5976 this._addScales(options, className + '-line', container); 5977 5978 map.on(options.updateWhenIdle ? 'moveend' : 'move', this._update, this); 5979 map.whenReady(this._update, this); 5980 5981 return container; 5982 }, 5983 5984 onRemove: function (map) { 5985 map.off(this.options.updateWhenIdle ? 'moveend' : 'move', this._update, this); 5986 }, 5987 5988 _addScales: function (options, className, container) { 5989 if (options.metric) { 5990 this._mScale = create$1('div', className, container); 5991 } 5992 if (options.imperial) { 5993 this._iScale = create$1('div', className, container); 5994 } 5995 }, 5996 5997 _update: function () { 5998 var map = this._map, 5999 y = map.getSize().y / 2; 6000 6001 var maxMeters = map.distance( 6002 map.containerPointToLatLng([0, y]), 6003 map.containerPointToLatLng([this.options.maxWidth, y])); 6004 6005 this._updateScales(maxMeters); 6006}, 6007 6008_updateScales: function (maxMeters) { 6009 if (this.options.metric && maxMeters) { 6010 this._updateMetric(maxMeters); 6011 } 6012 if (this.options.imperial && maxMeters) { 6013 this._updateImperial(maxMeters); 6014 } 6015}, 6016 6017_updateMetric: function (maxMeters) { 6018 var meters = this._getRoundNum(maxMeters), 6019 label = meters < 1000 ? meters + ' m' : (meters / 1000) + ' km'; 6020 6021 this._updateScale(this._mScale, label, meters / maxMeters); 6022}, 6023 6024_updateImperial: function (maxMeters) { 6025 var maxFeet = maxMeters * 3.2808399, 6026 maxMiles, miles, feet; 6027 6028 if (maxFeet > 5280) { 6029 maxMiles = maxFeet / 5280; 6030 miles = this._getRoundNum(maxMiles); 6031 this._updateScale(this._iScale, miles + ' mi', miles / maxMiles); 6032 6033 } else { 6034 feet = this._getRoundNum(maxFeet); 6035 this._updateScale(this._iScale, feet + ' ft', feet / maxFeet); 6036 } 6037}, 6038 6039_updateScale: function (scale, text, ratio) { 6040 scale.style.width = Math.round(this.options.maxWidth * ratio) + 'px'; 6041 scale.innerHTML = text; 6042}, 6043 6044_getRoundNum: function (num) { 6045 var pow10 = Math.pow(10, (Math.floor(num) + '').length - 1), 6046 d = num / pow10; 6047 6048 d = d >= 10 ? 10 : 6049 d >= 5 ? 5 : 6050 d >= 3 ? 3 : 6051 d >= 2 ? 2 : 1; 6052 6053 return pow10 * d; 6054} 6055}); 6056 6057 6058// @factory L.control.scale(options?: Control.Scale options) 6059// Creates an scale control with the given options. 6060var scale = function (options) { 6061 return new Scale(options); 6062}; 6063 6064/* 6065 * @class Control.Attribution 6066 * @aka L.Control.Attribution 6067 * @inherits Control 6068 * 6069 * The attribution control allows you to display attribution data in a small text box on a map. It is put on the map by default unless you set its [`attributionControl` option](#map-attributioncontrol) to `false`, and it fetches attribution texts from layers with the [`getAttribution` method](#layer-getattribution) automatically. Extends Control. 6070 */ 6071 6072 var Attribution = Control.extend({ 6073 // @section 6074 // @aka Control.Attribution options 6075 options: { 6076 position: 'bottomright', 6077 6078 // @option prefix: String = 'Leaflet' 6079 // The HTML text shown before the attributions. Pass `false` to disable. 6080 prefix: '<a href="https://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>' 6081 }, 6082 6083 initialize: function (options) { 6084 setOptions(this, options); 6085 6086 this._attributions = {}; 6087 }, 6088 6089 onAdd: function (map) { 6090 map.attributionControl = this; 6091 this._container = create$1('div', 'leaflet-control-attribution'); 6092 disableClickPropagation(this._container); 6093 6094 // TODO ugly, refactor 6095 for (var i in map._layers) { 6096 if (map._layers[i].getAttribution) { 6097 this.addAttribution(map._layers[i].getAttribution()); 6098 } 6099 } 6100 6101 this._update(); 6102 6103 return this._container; 6104 }, 6105 6106 // @method setPrefix(prefix: String): this 6107 // Sets the text before the attributions. 6108 setPrefix: function (prefix) { 6109 this.options.prefix = prefix; 6110 this._update(); 6111 return this; 6112 }, 6113 6114 // @method addAttribution(text: String): this 6115 // Adds an attribution text (e.g. `'Vector data © Mapbox'`). 6116 addAttribution: function (text) { 6117 if (!text) { return this; } 6118 6119 if (!this._attributions[text]) { 6120 this._attributions[text] = 0; 6121 } 6122 this._attributions[text]++; 6123 6124 this._update(); 6125 6126 return this; 6127 }, 6128 6129 // @method removeAttribution(text: String): this 6130 // Removes an attribution text. 6131 removeAttribution: function (text) { 6132 if (!text) { return this; } 6133 6134 if (this._attributions[text]) { 6135 this._attributions[text]--; 6136 this._update(); 6137 } 6138 6139 return this; 6140 }, 6141 6142 _update: function () { 6143 if (!this._map) { return; } 6144 6145 var attribs = []; 6146 6147 for (var i in this._attributions) { 6148 if (this._attributions[i]) { 6149 attribs.push(i); 6150 } 6151 } 6152 6153 var prefixAndAttribs = []; 6154 6155 if (this.options.prefix) { 6156 prefixAndAttribs.push(this.options.prefix); 6157 } 6158 if (attribs.length) { 6159 prefixAndAttribs.push(attribs.join(', ')); 6160 } 6161 6162 this._container.innerHTML = prefixAndAttribs.join(' | '); 6163 } 6164}); 6165 6166// @namespace Map 6167// @section Control options 6168// @option attributionControl: Boolean = true 6169// Whether a [attribution control](#control-attribution) is added to the map by default. 6170Map.mergeOptions({ 6171 attributionControl: true 6172}); 6173 6174Map.addInitHook(function () { 6175 if (this.options.attributionControl) { 6176 new Attribution().addTo(this); 6177 } 6178}); 6179 6180// @namespace Control.Attribution 6181// @factory L.control.attribution(options: Control.Attribution options) 6182// Creates an attribution control. 6183var attribution = function (options) { 6184 return new Attribution(options); 6185}; 6186 6187Control.Layers = Layers; 6188Control.Zoom = Zoom; 6189Control.Scale = Scale; 6190Control.Attribution = Attribution; 6191 6192control.layers = layers; 6193control.zoom = zoom; 6194control.scale = scale; 6195control.attribution = attribution; 6196 6197/* 6198 L.Handler is a base class for handler classes that are used internally to inject 6199 interaction features like dragging to classes like Map and Marker. 6200 */ 6201 6202// @class Handler 6203// @aka L.Handler 6204// Abstract class for map interaction handlers 6205 6206var Handler = Class.extend({ 6207 initialize: function (map) { 6208 this._map = map; 6209 }, 6210 6211 // @method enable(): this 6212 // Enables the handler 6213 enable: function () { 6214 if (this._enabled) { return this; } 6215 6216 this._enabled = true; 6217 this.addHooks(); 6218 return this; 6219 }, 6220 6221 // @method disable(): this 6222 // Disables the handler 6223 disable: function () { 6224 if (!this._enabled) { return this; } 6225 6226 this._enabled = false; 6227 this.removeHooks(); 6228 return this; 6229 }, 6230 6231 // @method enabled(): Boolean 6232 // Returns `true` if the handler is enabled 6233 enabled: function () { 6234 return !!this._enabled; 6235 } 6236 6237 // @section Extension methods 6238 // Classes inheriting from `Handler` must implement the two following methods: 6239 // @method addHooks() 6240 // Called when the handler is enabled, should add event hooks. 6241 // @method removeHooks() 6242 // Called when the handler is disabled, should remove the event hooks added previously. 6243}); 6244 6245// @section There is static function which can be called without instantiating L.Handler: 6246// @function addTo(map: Map, name: String): this 6247// Adds a new Handler to the given map with the given name. 6248Handler.addTo = function (map, name) { 6249 map.addHandler(name, this); 6250 return this; 6251}; 6252 6253var Mixin = {Events: Events}; 6254 6255/* 6256 * @class Draggable 6257 * @aka L.Draggable 6258 * @inherits Evented 6259 * 6260 * A class for making DOM elements draggable (including touch support). 6261 * Used internally for map and marker dragging. Only works for elements 6262 * that were positioned with [`L.DomUtil.setPosition`](#domutil-setposition). 6263 * 6264 * @example 6265 * ```js 6266 * var draggable = new L.Draggable(elementToDrag); 6267 * draggable.enable(); 6268 * ``` 6269 */ 6270 6271 var START = touch ? 'touchstart mousedown' : 'mousedown'; 6272 var END = { 6273 mousedown: 'mouseup', 6274 touchstart: 'touchend', 6275 pointerdown: 'touchend', 6276 MSPointerDown: 'touchend' 6277 }; 6278 var MOVE = { 6279 mousedown: 'mousemove', 6280 touchstart: 'touchmove', 6281 pointerdown: 'touchmove', 6282 MSPointerDown: 'touchmove' 6283 }; 6284 6285 6286 var Draggable = Evented.extend({ 6287 6288 options: { 6289 // @section 6290 // @aka Draggable options 6291 // @option clickTolerance: Number = 3 6292 // The max number of pixels a user can shift the mouse pointer during a click 6293 // for it to be considered a valid click (as opposed to a mouse drag). 6294 clickTolerance: 3 6295 }, 6296 6297 // @constructor L.Draggable(el: HTMLElement, dragHandle?: HTMLElement, preventOutline?: Boolean, options?: Draggable options) 6298 // Creates a `Draggable` object for moving `el` when you start dragging the `dragHandle` element (equals `el` itself by default). 6299 initialize: function (element, dragStartTarget, preventOutline$$1, options) { 6300 setOptions(this, options); 6301 6302 this._element = element; 6303 this._dragStartTarget = dragStartTarget || element; 6304 this._preventOutline = preventOutline$$1; 6305 }, 6306 6307 // @method enable() 6308 // Enables the dragging ability 6309 enable: function () { 6310 if (this._enabled) { return; } 6311 6312 on(this._dragStartTarget, START, this._onDown, this); 6313 6314 this._enabled = true; 6315 }, 6316 6317 // @method disable() 6318 // Disables the dragging ability 6319 disable: function () { 6320 if (!this._enabled) { return; } 6321 6322 // If we're currently dragging this draggable, 6323 // disabling it counts as first ending the drag. 6324 if (Draggable._dragging === this) { 6325 this.finishDrag(); 6326 } 6327 6328 off(this._dragStartTarget, START, this._onDown, this); 6329 6330 this._enabled = false; 6331 this._moved = false; 6332 }, 6333 6334 _onDown: function (e) { 6335 // Ignore simulated events, since we handle both touch and 6336 // mouse explicitly; otherwise we risk getting duplicates of 6337 // touch events, see #4315. 6338 // Also ignore the event if disabled; this happens in IE11 6339 // under some circumstances, see #3666. 6340 if (e._simulated || !this._enabled) { return; } 6341 6342 this._moved = false; 6343 6344 if (hasClass(this._element, 'leaflet-zoom-anim')) { return; } 6345 6346 if (Draggable._dragging || e.shiftKey || ((e.which !== 1) && (e.button !== 1) && !e.touches)) { return; } 6347 Draggable._dragging = this; // Prevent dragging multiple objects at once. 6348 6349 if (this._preventOutline) { 6350 preventOutline(this._element); 6351 } 6352 6353 disableImageDrag(); 6354 disableTextSelection(); 6355 6356 if (this._moving) { return; } 6357 6358 // @event down: Event 6359 // Fired when a drag is about to start. 6360 this.fire('down'); 6361 6362 var first = e.touches ? e.touches[0] : e, 6363 sizedParent = getSizedParentNode(this._element); 6364 6365 this._startPoint = new Point(first.clientX, first.clientY); 6366 6367 // Cache the scale, so that we can continuously compensate for it during drag (_onMove). 6368 this._parentScale = getScale(sizedParent); 6369 6370 on(document, MOVE[e.type], this._onMove, this); 6371 on(document, END[e.type], this._onUp, this); 6372 }, 6373 6374 _onMove: function (e) { 6375 // Ignore simulated events, since we handle both touch and 6376 // mouse explicitly; otherwise we risk getting duplicates of 6377 // touch events, see #4315. 6378 // Also ignore the event if disabled; this happens in IE11 6379 // under some circumstances, see #3666. 6380 if (e._simulated || !this._enabled) { return; } 6381 6382 if (e.touches && e.touches.length > 1) { 6383 this._moved = true; 6384 return; 6385 } 6386 6387 var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e), 6388 offset = new Point(first.clientX, first.clientY)._subtract(this._startPoint); 6389 6390 if (!offset.x && !offset.y) { return; } 6391 if (Math.abs(offset.x) + Math.abs(offset.y) < this.options.clickTolerance) { return; } 6392 6393 // We assume that the parent container's position, border and scale do not change for the duration of the drag. 6394 // Therefore there is no need to account for the position and border (they are eliminated by the subtraction) 6395 // and we can use the cached value for the scale. 6396 offset.x /= this._parentScale.x; 6397 offset.y /= this._parentScale.y; 6398 6399 preventDefault(e); 6400 6401 if (!this._moved) { 6402 // @event dragstart: Event 6403 // Fired when a drag starts 6404 this.fire('dragstart'); 6405 6406 this._moved = true; 6407 this._startPos = getPosition(this._element).subtract(offset); 6408 6409 addClass(document.body, 'leaflet-dragging'); 6410 6411 this._lastTarget = e.target || e.srcElement; 6412 // IE and Edge do not give the <use> element, so fetch it 6413 // if necessary 6414 if ((window.SVGElementInstance) && (this._lastTarget instanceof SVGElementInstance)) { 6415 this._lastTarget = this._lastTarget.correspondingUseElement; 6416 } 6417 addClass(this._lastTarget, 'leaflet-drag-target'); 6418 } 6419 6420 this._newPos = this._startPos.add(offset); 6421 this._moving = true; 6422 6423 cancelAnimFrame(this._animRequest); 6424 this._lastEvent = e; 6425 this._animRequest = requestAnimFrame(this._updatePosition, this, true); 6426 }, 6427 6428 _updatePosition: function () { 6429 var e = {originalEvent: this._lastEvent}; 6430 6431 // @event predrag: Event 6432 // Fired continuously during dragging *before* each corresponding 6433 // update of the element's position. 6434 this.fire('predrag', e); 6435 setPosition(this._element, this._newPos); 6436 6437 // @event drag: Event 6438 // Fired continuously during dragging. 6439 this.fire('drag', e); 6440 }, 6441 6442 _onUp: function (e) { 6443 // Ignore simulated events, since we handle both touch and 6444 // mouse explicitly; otherwise we risk getting duplicates of 6445 // touch events, see #4315. 6446 // Also ignore the event if disabled; this happens in IE11 6447 // under some circumstances, see #3666. 6448 if (e._simulated || !this._enabled) { return; } 6449 this.finishDrag(); 6450 }, 6451 6452 finishDrag: function () { 6453 removeClass(document.body, 'leaflet-dragging'); 6454 6455 if (this._lastTarget) { 6456 removeClass(this._lastTarget, 'leaflet-drag-target'); 6457 this._lastTarget = null; 6458 } 6459 6460 for (var i in MOVE) { 6461 off(document, MOVE[i], this._onMove, this); 6462 off(document, END[i], this._onUp, this); 6463 } 6464 6465 enableImageDrag(); 6466 enableTextSelection(); 6467 6468 if (this._moved && this._moving) { 6469 // ensure drag is not fired after dragend 6470 cancelAnimFrame(this._animRequest); 6471 6472 // @event dragend: DragEndEvent 6473 // Fired when the drag ends. 6474 this.fire('dragend', { 6475 distance: this._newPos.distanceTo(this._startPos) 6476 }); 6477 } 6478 6479 this._moving = false; 6480 Draggable._dragging = false; 6481 } 6482 6483}); 6484 6485/* 6486 * @namespace LineUtil 6487 * 6488 * Various utility functions for polyline points processing, used by Leaflet internally to make polylines lightning-fast. 6489 */ 6490 6491// Simplify polyline with vertex reduction and Douglas-Peucker simplification. 6492// Improves rendering performance dramatically by lessening the number of points to draw. 6493 6494// @function simplify(points: Point[], tolerance: Number): Point[] 6495// Dramatically reduces the number of points in a polyline while retaining 6496// its shape and returns a new array of simplified points, using the 6497// [Douglas-Peucker algorithm](http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm). 6498// Used for a huge performance boost when processing/displaying Leaflet polylines for 6499// each zoom level and also reducing visual noise. tolerance affects the amount of 6500// simplification (lesser value means higher quality but slower and with more points). 6501// Also released as a separated micro-library [Simplify.js](http://mourner.github.com/simplify-js/). 6502function simplify(points, tolerance) { 6503 if (!tolerance || !points.length) { 6504 return points.slice(); 6505 } 6506 6507 var sqTolerance = tolerance * tolerance; 6508 6509 // stage 1: vertex reduction 6510 points = _reducePoints(points, sqTolerance); 6511 6512 // stage 2: Douglas-Peucker simplification 6513 points = _simplifyDP(points, sqTolerance); 6514 6515 return points; 6516 } 6517 6518// @function pointToSegmentDistance(p: Point, p1: Point, p2: Point): Number 6519// Returns the distance between point `p` and segment `p1` to `p2`. 6520function pointToSegmentDistance(p, p1, p2) { 6521 return Math.sqrt(_sqClosestPointOnSegment(p, p1, p2, true)); 6522} 6523 6524// @function closestPointOnSegment(p: Point, p1: Point, p2: Point): Number 6525// Returns the closest point from a point `p` on a segment `p1` to `p2`. 6526function closestPointOnSegment(p, p1, p2) { 6527 return _sqClosestPointOnSegment(p, p1, p2); 6528} 6529 6530// Douglas-Peucker simplification, see http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm 6531function _simplifyDP(points, sqTolerance) { 6532 6533 var len = points.length, 6534 ArrayConstructor = typeof Uint8Array !== undefined + '' ? Uint8Array : Array, 6535 markers = new ArrayConstructor(len); 6536 6537 markers[0] = markers[len - 1] = 1; 6538 6539 _simplifyDPStep(points, markers, sqTolerance, 0, len - 1); 6540 6541 var i, 6542 newPoints = []; 6543 6544 for (i = 0; i < len; i++) { 6545 if (markers[i]) { 6546 newPoints.push(points[i]); 6547 } 6548} 6549 6550return newPoints; 6551} 6552 6553function _simplifyDPStep(points, markers, sqTolerance, first, last) { 6554 6555 var maxSqDist = 0, 6556 index, i, sqDist; 6557 6558 for (i = first + 1; i <= last - 1; i++) { 6559 sqDist = _sqClosestPointOnSegment(points[i], points[first], points[last], true); 6560 6561 if (sqDist > maxSqDist) { 6562 index = i; 6563 maxSqDist = sqDist; 6564 } 6565 } 6566 6567 if (maxSqDist > sqTolerance) { 6568 markers[index] = 1; 6569 6570 _simplifyDPStep(points, markers, sqTolerance, first, index); 6571 _simplifyDPStep(points, markers, sqTolerance, index, last); 6572 } 6573} 6574 6575// reduce points that are too close to each other to a single point 6576function _reducePoints(points, sqTolerance) { 6577 var reducedPoints = [points[0]]; 6578 6579 for (var i = 1, prev = 0, len = points.length; i < len; i++) { 6580 if (_sqDist(points[i], points[prev]) > sqTolerance) { 6581 reducedPoints.push(points[i]); 6582 prev = i; 6583 } 6584 } 6585 if (prev < len - 1) { 6586 reducedPoints.push(points[len - 1]); 6587 } 6588 return reducedPoints; 6589} 6590 6591var _lastCode; 6592 6593// @function clipSegment(a: Point, b: Point, bounds: Bounds, useLastCode?: Boolean, round?: Boolean): Point[]|Boolean 6594// Clips the segment a to b by rectangular bounds with the 6595// [Cohen-Sutherland algorithm](https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm) 6596// (modifying the segment points directly!). Used by Leaflet to only show polyline 6597// points that are on the screen or near, increasing performance. 6598function clipSegment(a, b, bounds, useLastCode, round) { 6599 var codeA = useLastCode ? _lastCode : _getBitCode(a, bounds), 6600 codeB = _getBitCode(b, bounds), 6601 6602 codeOut, p, newCode; 6603 6604 // save 2nd code to avoid calculating it on the next segment 6605 _lastCode = codeB; 6606 6607 while (true) { 6608 // if a,b is inside the clip window (trivial accept) 6609 if (!(codeA | codeB)) { 6610 return [a, b]; 6611 } 6612 6613 // if a,b is outside the clip window (trivial reject) 6614 if (codeA & codeB) { 6615 return false; 6616 } 6617 6618 // other cases 6619 codeOut = codeA || codeB; 6620 p = _getEdgeIntersection(a, b, codeOut, bounds, round); 6621 newCode = _getBitCode(p, bounds); 6622 6623 if (codeOut === codeA) { 6624 a = p; 6625 codeA = newCode; 6626 } else { 6627 b = p; 6628 codeB = newCode; 6629 } 6630 } 6631} 6632 6633function _getEdgeIntersection(a, b, code, bounds, round) { 6634 var dx = b.x - a.x, 6635 dy = b.y - a.y, 6636 min = bounds.min, 6637 max = bounds.max, 6638 x, y; 6639 6640 if (code & 8) { // top 6641 x = a.x + dx * (max.y - a.y) / dy; 6642 y = max.y; 6643 6644 } else if (code & 4) { // bottom 6645 x = a.x + dx * (min.y - a.y) / dy; 6646 y = min.y; 6647 6648 } else if (code & 2) { // right 6649 x = max.x; 6650 y = a.y + dy * (max.x - a.x) / dx; 6651 6652 } else if (code & 1) { // left 6653 x = min.x; 6654 y = a.y + dy * (min.x - a.x) / dx; 6655 } 6656 6657 return new Point(x, y, round); 6658} 6659 6660function _getBitCode(p, bounds) { 6661 var code = 0; 6662 6663 if (p.x < bounds.min.x) { // left 6664 code |= 1; 6665 } else if (p.x > bounds.max.x) { // right 6666 code |= 2; 6667 } 6668 6669 if (p.y < bounds.min.y) { // bottom 6670 code |= 4; 6671 } else if (p.y > bounds.max.y) { // top 6672 code |= 8; 6673 } 6674 6675 return code; 6676} 6677 6678// square distance (to avoid unnecessary Math.sqrt calls) 6679function _sqDist(p1, p2) { 6680 var dx = p2.x - p1.x, 6681 dy = p2.y - p1.y; 6682 return dx * dx + dy * dy; 6683} 6684 6685// return closest point on segment or distance to that point 6686function _sqClosestPointOnSegment(p, p1, p2, sqDist) { 6687 var x = p1.x, 6688 y = p1.y, 6689 dx = p2.x - x, 6690 dy = p2.y - y, 6691 dot = dx * dx + dy * dy, 6692 t; 6693 6694 if (dot > 0) { 6695 t = ((p.x - x) * dx + (p.y - y) * dy) / dot; 6696 6697 if (t > 1) { 6698 x = p2.x; 6699 y = p2.y; 6700 } else if (t > 0) { 6701 x += dx * t; 6702 y += dy * t; 6703 } 6704} 6705 6706dx = p.x - x; 6707dy = p.y - y; 6708 6709return sqDist ? dx * dx + dy * dy : new Point(x, y); 6710} 6711 6712 6713// @function isFlat(latlngs: LatLng[]): Boolean 6714// Returns true if `latlngs` is a flat array, false is nested. 6715function isFlat(latlngs) { 6716 return !isArray(latlngs[0]) || (typeof latlngs[0][0] !== 'object' && typeof latlngs[0][0] !== 'undefined'); 6717} 6718 6719function _flat(latlngs) { 6720 console.warn('Deprecated use of _flat, please use L.LineUtil.isFlat instead.'); 6721 return isFlat(latlngs); 6722} 6723 6724 6725var LineUtil = (Object.freeze || Object)({ 6726 simplify: simplify, 6727 pointToSegmentDistance: pointToSegmentDistance, 6728 closestPointOnSegment: closestPointOnSegment, 6729 clipSegment: clipSegment, 6730 _getEdgeIntersection: _getEdgeIntersection, 6731 _getBitCode: _getBitCode, 6732 _sqClosestPointOnSegment: _sqClosestPointOnSegment, 6733 isFlat: isFlat, 6734 _flat: _flat 6735}); 6736 6737/* 6738 * @namespace PolyUtil 6739 * Various utility functions for polygon geometries. 6740 */ 6741 6742/* @function clipPolygon(points: Point[], bounds: Bounds, round?: Boolean): Point[] 6743 * Clips the polygon geometry defined by the given `points` by the given bounds (using the [Sutherland-Hodgman algorithm](https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm)). 6744 * Used by Leaflet to only show polygon points that are on the screen or near, increasing 6745 * performance. Note that polygon points needs different algorithm for clipping 6746 * than polyline, so there's a separate method for it. 6747 */ 6748 function clipPolygon(points, bounds, round) { 6749 var clippedPoints, 6750 edges = [1, 4, 2, 8], 6751 i, j, k, 6752 a, b, 6753 len, edge, p; 6754 6755 for (i = 0, len = points.length; i < len; i++) { 6756 points[i]._code = _getBitCode(points[i], bounds); 6757 } 6758 6759 // for each edge (left, bottom, right, top) 6760 for (k = 0; k < 4; k++) { 6761 edge = edges[k]; 6762 clippedPoints = []; 6763 6764 for (i = 0, len = points.length, j = len - 1; i < len; j = i++) { 6765 a = points[i]; 6766 b = points[j]; 6767 6768 // if a is inside the clip window 6769 if (!(a._code & edge)) { 6770 // if b is outside the clip window (a->b goes out of screen) 6771 if (b._code & edge) { 6772 p = _getEdgeIntersection(b, a, edge, bounds, round); 6773 p._code = _getBitCode(p, bounds); 6774 clippedPoints.push(p); 6775 } 6776 clippedPoints.push(a); 6777 6778 // else if b is inside the clip window (a->b enters the screen) 6779 } else if (!(b._code & edge)) { 6780 p = _getEdgeIntersection(b, a, edge, bounds, round); 6781 p._code = _getBitCode(p, bounds); 6782 clippedPoints.push(p); 6783 } 6784} 6785points = clippedPoints; 6786} 6787 6788return points; 6789} 6790 6791 6792var PolyUtil = (Object.freeze || Object)({ 6793 clipPolygon: clipPolygon 6794}); 6795 6796/* 6797 * @namespace Projection 6798 * @section 6799 * Leaflet comes with a set of already defined Projections out of the box: 6800 * 6801 * @projection L.Projection.LonLat 6802 * 6803 * Equirectangular, or Plate Carree projection — the most simple projection, 6804 * mostly used by GIS enthusiasts. Directly maps `x` as longitude, and `y` as 6805 * latitude. Also suitable for flat worlds, e.g. game maps. Used by the 6806 * `EPSG:4326` and `Simple` CRS. 6807 */ 6808 6809 var LonLat = { 6810 project: function (latlng) { 6811 return new Point(latlng.lng, latlng.lat); 6812 }, 6813 6814 unproject: function (point) { 6815 return new LatLng(point.y, point.x); 6816 }, 6817 6818 bounds: new Bounds([-180, -90], [180, 90]) 6819}; 6820 6821/* 6822 * @namespace Projection 6823 * @projection L.Projection.Mercator 6824 * 6825 * Elliptical Mercator projection — more complex than Spherical Mercator. Assumes that Earth is an ellipsoid. Used by the EPSG:3395 CRS. 6826 */ 6827 6828 var Mercator = { 6829 R: 6378137, 6830 R_MINOR: 6356752.314245179, 6831 6832 bounds: new Bounds([-20037508.34279, -15496570.73972], [20037508.34279, 18764656.23138]), 6833 6834 project: function (latlng) { 6835 var d = Math.PI / 180, 6836 r = this.R, 6837 y = latlng.lat * d, 6838 tmp = this.R_MINOR / r, 6839 e = Math.sqrt(1 - tmp * tmp), 6840 con = e * Math.sin(y); 6841 6842 var ts = Math.tan(Math.PI / 4 - y / 2) / Math.pow((1 - con) / (1 + con), e / 2); 6843 y = -r * Math.log(Math.max(ts, 1E-10)); 6844 6845 return new Point(latlng.lng * d * r, y); 6846 }, 6847 6848 unproject: function (point) { 6849 var d = 180 / Math.PI, 6850 r = this.R, 6851 tmp = this.R_MINOR / r, 6852 e = Math.sqrt(1 - tmp * tmp), 6853 ts = Math.exp(-point.y / r), 6854 phi = Math.PI / 2 - 2 * Math.atan(ts); 6855 6856 for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) { 6857 con = e * Math.sin(phi); 6858 con = Math.pow((1 - con) / (1 + con), e / 2); 6859 dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi; 6860 phi += dphi; 6861 } 6862 6863 return new LatLng(phi * d, point.x * d / r); 6864 } 6865}; 6866 6867/* 6868 * @class Projection 6869 6870 * An object with methods for projecting geographical coordinates of the world onto 6871 * a flat surface (and back). See [Map projection](http://en.wikipedia.org/wiki/Map_projection). 6872 6873 * @property bounds: Bounds 6874 * The bounds (specified in CRS units) where the projection is valid 6875 6876 * @method project(latlng: LatLng): Point 6877 * Projects geographical coordinates into a 2D point. 6878 * Only accepts actual `L.LatLng` instances, not arrays. 6879 6880 * @method unproject(point: Point): LatLng 6881 * The inverse of `project`. Projects a 2D point into a geographical location. 6882 * Only accepts actual `L.Point` instances, not arrays. 6883 6884 * Note that the projection instances do not inherit from Leafet's `Class` object, 6885 * and can't be instantiated. Also, new classes can't inherit from them, 6886 * and methods can't be added to them with the `include` function. 6887 6888 */ 6889 6890 6891 6892 6893 var index = (Object.freeze || Object)({ 6894 LonLat: LonLat, 6895 Mercator: Mercator, 6896 SphericalMercator: SphericalMercator 6897 }); 6898 6899/* 6900 * @namespace CRS 6901 * @crs L.CRS.EPSG3395 6902 * 6903 * Rarely used by some commercial tile providers. Uses Elliptical Mercator projection. 6904 */ 6905 var EPSG3395 = extend({}, Earth, { 6906 code: 'EPSG:3395', 6907 projection: Mercator, 6908 6909 transformation: (function () { 6910 var scale = 0.5 / (Math.PI * Mercator.R); 6911 return toTransformation(scale, 0.5, -scale, 0.5); 6912 }()) 6913 }); 6914 6915/* 6916 * @namespace CRS 6917 * @crs L.CRS.EPSG4326 6918 * 6919 * A common CRS among GIS enthusiasts. Uses simple Equirectangular projection. 6920 * 6921 * Leaflet 1.0.x complies with the [TMS coordinate scheme for EPSG:4326](https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification#global-geodetic), 6922 * which is a breaking change from 0.7.x behaviour. If you are using a `TileLayer` 6923 * with this CRS, ensure that there are two 256x256 pixel tiles covering the 6924 * whole earth at zoom level zero, and that the tile coordinate origin is (-180,+90), 6925 * or (-180,-90) for `TileLayer`s with [the `tms` option](#tilelayer-tms) set. 6926 */ 6927 6928 var EPSG4326 = extend({}, Earth, { 6929 code: 'EPSG:4326', 6930 projection: LonLat, 6931 transformation: toTransformation(1 / 180, 1, -1 / 180, 0.5) 6932 }); 6933 6934/* 6935 * @namespace CRS 6936 * @crs L.CRS.Simple 6937 * 6938 * A simple CRS that maps longitude and latitude into `x` and `y` directly. 6939 * May be used for maps of flat surfaces (e.g. game maps). Note that the `y` 6940 * axis should still be inverted (going from bottom to top). `distance()` returns 6941 * simple euclidean distance. 6942 */ 6943 6944 var Simple = extend({}, CRS, { 6945 projection: LonLat, 6946 transformation: toTransformation(1, 0, -1, 0), 6947 6948 scale: function (zoom) { 6949 return Math.pow(2, zoom); 6950 }, 6951 6952 zoom: function (scale) { 6953 return Math.log(scale) / Math.LN2; 6954 }, 6955 6956 distance: function (latlng1, latlng2) { 6957 var dx = latlng2.lng - latlng1.lng, 6958 dy = latlng2.lat - latlng1.lat; 6959 6960 return Math.sqrt(dx * dx + dy * dy); 6961 }, 6962 6963 infinite: true 6964}); 6965 6966 CRS.Earth = Earth; 6967 CRS.EPSG3395 = EPSG3395; 6968 CRS.EPSG3857 = EPSG3857; 6969 CRS.EPSG900913 = EPSG900913; 6970 CRS.EPSG4326 = EPSG4326; 6971 CRS.Simple = Simple; 6972 6973/* 6974 * @class Layer 6975 * @inherits Evented 6976 * @aka L.Layer 6977 * @aka ILayer 6978 * 6979 * A set of methods from the Layer base class that all Leaflet layers use. 6980 * Inherits all methods, options and events from `L.Evented`. 6981 * 6982 * @example 6983 * 6984 * ```js 6985 * var layer = L.marker(latlng).addTo(map); 6986 * layer.addTo(map); 6987 * layer.remove(); 6988 * ``` 6989 * 6990 * @event add: Event 6991 * Fired after the layer is added to a map 6992 * 6993 * @event remove: Event 6994 * Fired after the layer is removed from a map 6995 */ 6996 6997 6998 var Layer = Evented.extend({ 6999 7000 // Classes extending `L.Layer` will inherit the following options: 7001 options: { 7002 // @option pane: String = 'overlayPane' 7003 // By default the layer will be added to the map's [overlay pane](#map-overlaypane). Overriding this option will cause the layer to be placed on another pane by default. 7004 pane: 'overlayPane', 7005 7006 // @option attribution: String = null 7007 // String to be shown in the attribution control, e.g. "© OpenStreetMap contributors". It describes the layer data and is often a legal obligation towards copyright holders and tile providers. 7008 attribution: null, 7009 7010 bubblingMouseEvents: true 7011 }, 7012 7013 /* @section 7014 * Classes extending `L.Layer` will inherit the following methods: 7015 * 7016 * @method addTo(map: Map|LayerGroup): this 7017 * Adds the layer to the given map or layer group. 7018 */ 7019 addTo: function (map) { 7020 map.addLayer(this); 7021 return this; 7022 }, 7023 7024 // @method remove: this 7025 // Removes the layer from the map it is currently active on. 7026 remove: function () { 7027 return this.removeFrom(this._map || this._mapToAdd); 7028 }, 7029 7030 // @method removeFrom(map: Map): this 7031 // Removes the layer from the given map 7032 removeFrom: function (obj) { 7033 if (obj) { 7034 obj.removeLayer(this); 7035 } 7036 return this; 7037 }, 7038 7039 // @method getPane(name? : String): HTMLElement 7040 // Returns the `HTMLElement` representing the named pane on the map. If `name` is omitted, returns the pane for this layer. 7041 getPane: function (name) { 7042 return this._map.getPane(name ? (this.options[name] || name) : this.options.pane); 7043 }, 7044 7045 addInteractiveTarget: function (targetEl) { 7046 this._map._targets[stamp(targetEl)] = this; 7047 return this; 7048 }, 7049 7050 removeInteractiveTarget: function (targetEl) { 7051 delete this._map._targets[stamp(targetEl)]; 7052 return this; 7053 }, 7054 7055 // @method getAttribution: String 7056 // Used by the `attribution control`, returns the [attribution option](#gridlayer-attribution). 7057 getAttribution: function () { 7058 return this.options.attribution; 7059 }, 7060 7061 _layerAdd: function (e) { 7062 var map = e.target; 7063 7064 // check in case layer gets added and then removed before the map is ready 7065 if (!map.hasLayer(this)) { return; } 7066 7067 this._map = map; 7068 this._zoomAnimated = map._zoomAnimated; 7069 7070 if (this.getEvents) { 7071 var events = this.getEvents(); 7072 map.on(events, this); 7073 this.once('remove', function () { 7074 map.off(events, this); 7075 }, this); 7076 } 7077 7078 this.onAdd(map); 7079 7080 if (this.getAttribution && map.attributionControl) { 7081 map.attributionControl.addAttribution(this.getAttribution()); 7082 } 7083 7084 this.fire('add'); 7085 map.fire('layeradd', {layer: this}); 7086 } 7087}); 7088 7089/* @section Extension methods 7090 * @uninheritable 7091 * 7092 * Every layer should extend from `L.Layer` and (re-)implement the following methods. 7093 * 7094 * @method onAdd(map: Map): this 7095 * Should contain code that creates DOM elements for the layer, adds them to `map panes` where they should belong and puts listeners on relevant map events. Called on [`map.addLayer(layer)`](#map-addlayer). 7096 * 7097 * @method onRemove(map: Map): this 7098 * Should contain all clean up code that removes the layer's elements from the DOM and removes listeners previously added in [`onAdd`](#layer-onadd). Called on [`map.removeLayer(layer)`](#map-removelayer). 7099 * 7100 * @method getEvents(): Object 7101 * This optional method should return an object like `{ viewreset: this._reset }` for [`addEventListener`](#evented-addeventlistener). The event handlers in this object will be automatically added and removed from the map with your layer. 7102 * 7103 * @method getAttribution(): String 7104 * This optional method should return a string containing HTML to be shown on the `Attribution control` whenever the layer is visible. 7105 * 7106 * @method beforeAdd(map: Map): this 7107 * Optional method. Called on [`map.addLayer(layer)`](#map-addlayer), before the layer is added to the map, before events are initialized, without waiting until the map is in a usable state. Use for early initialization only. 7108 */ 7109 7110 7111/* @namespace Map 7112 * @section Layer events 7113 * 7114 * @event layeradd: LayerEvent 7115 * Fired when a new layer is added to the map. 7116 * 7117 * @event layerremove: LayerEvent 7118 * Fired when some layer is removed from the map 7119 * 7120 * @section Methods for Layers and Controls 7121 */ 7122 Map.include({ 7123 // @method addLayer(layer: Layer): this 7124 // Adds the given layer to the map 7125 addLayer: function (layer) { 7126 if (!layer._layerAdd) { 7127 throw new Error('The provided object is not a Layer.'); 7128 } 7129 7130 var id = stamp(layer); 7131 if (this._layers[id]) { return this; } 7132 this._layers[id] = layer; 7133 7134 layer._mapToAdd = this; 7135 7136 if (layer.beforeAdd) { 7137 layer.beforeAdd(this); 7138 } 7139 7140 this.whenReady(layer._layerAdd, layer); 7141 7142 return this; 7143 }, 7144 7145 // @method removeLayer(layer: Layer): this 7146 // Removes the given layer from the map. 7147 removeLayer: function (layer) { 7148 var id = stamp(layer); 7149 7150 if (!this._layers[id]) { return this; } 7151 7152 if (this._loaded) { 7153 layer.onRemove(this); 7154 } 7155 7156 if (layer.getAttribution && this.attributionControl) { 7157 this.attributionControl.removeAttribution(layer.getAttribution()); 7158 } 7159 7160 delete this._layers[id]; 7161 7162 if (this._loaded) { 7163 this.fire('layerremove', {layer: layer}); 7164 layer.fire('remove'); 7165 } 7166 7167 layer._map = layer._mapToAdd = null; 7168 7169 return this; 7170 }, 7171 7172 // @method hasLayer(layer: Layer): Boolean 7173 // Returns `true` if the given layer is currently added to the map 7174 hasLayer: function (layer) { 7175 return !!layer && (stamp(layer) in this._layers); 7176 }, 7177 7178 /* @method eachLayer(fn: Function, context?: Object): this 7179 * Iterates over the layers of the map, optionally specifying context of the iterator function. 7180 * ``` 7181 * map.eachLayer(function(layer){ 7182 * layer.bindPopup('Hello'); 7183 * }); 7184 * ``` 7185 */ 7186 eachLayer: function (method, context) { 7187 for (var i in this._layers) { 7188 method.call(context, this._layers[i]); 7189 } 7190 return this; 7191 }, 7192 7193 _addLayers: function (layers) { 7194 layers = layers ? (isArray(layers) ? layers : [layers]) : []; 7195 7196 for (var i = 0, len = layers.length; i < len; i++) { 7197 this.addLayer(layers[i]); 7198 } 7199}, 7200 7201_addZoomLimit: function (layer) { 7202 if (isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom)) { 7203 this._zoomBoundLayers[stamp(layer)] = layer; 7204 this._updateZoomLevels(); 7205 } 7206}, 7207 7208_removeZoomLimit: function (layer) { 7209 var id = stamp(layer); 7210 7211 if (this._zoomBoundLayers[id]) { 7212 delete this._zoomBoundLayers[id]; 7213 this._updateZoomLevels(); 7214 } 7215}, 7216 7217_updateZoomLevels: function () { 7218 var minZoom = Infinity, 7219 maxZoom = -Infinity, 7220 oldZoomSpan = this._getZoomSpan(); 7221 7222 for (var i in this._zoomBoundLayers) { 7223 var options = this._zoomBoundLayers[i].options; 7224 7225 minZoom = options.minZoom === undefined ? minZoom : Math.min(minZoom, options.minZoom); 7226 maxZoom = options.maxZoom === undefined ? maxZoom : Math.max(maxZoom, options.maxZoom); 7227 } 7228 7229 this._layersMaxZoom = maxZoom === -Infinity ? undefined : maxZoom; 7230 this._layersMinZoom = minZoom === Infinity ? undefined : minZoom; 7231 7232 // @section Map state change events 7233 // @event zoomlevelschange: Event 7234 // Fired when the number of zoomlevels on the map is changed due 7235 // to adding or removing a layer. 7236 if (oldZoomSpan !== this._getZoomSpan()) { 7237 this.fire('zoomlevelschange'); 7238 } 7239 7240 if (this.options.maxZoom === undefined && this._layersMaxZoom && this.getZoom() > this._layersMaxZoom) { 7241 this.setZoom(this._layersMaxZoom); 7242 } 7243 if (this.options.minZoom === undefined && this._layersMinZoom && this.getZoom() < this._layersMinZoom) { 7244 this.setZoom(this._layersMinZoom); 7245 } 7246 } 7247}); 7248 7249/* 7250 * @class LayerGroup 7251 * @aka L.LayerGroup 7252 * @inherits Layer 7253 * 7254 * Used to group several layers and handle them as one. If you add it to the map, 7255 * any layers added or removed from the group will be added/removed on the map as 7256 * well. Extends `Layer`. 7257 * 7258 * @example 7259 * 7260 * ```js 7261 * L.layerGroup([marker1, marker2]) 7262 * .addLayer(polyline) 7263 * .addTo(map); 7264 * ``` 7265 */ 7266 7267 var LayerGroup = Layer.extend({ 7268 7269 initialize: function (layers, options) { 7270 setOptions(this, options); 7271 7272 this._layers = {}; 7273 7274 var i, len; 7275 7276 if (layers) { 7277 for (i = 0, len = layers.length; i < len; i++) { 7278 this.addLayer(layers[i]); 7279 } 7280 } 7281}, 7282 7283 // @method addLayer(layer: Layer): this 7284 // Adds the given layer to the group. 7285 addLayer: function (layer) { 7286 var id = this.getLayerId(layer); 7287 7288 this._layers[id] = layer; 7289 7290 if (this._map) { 7291 this._map.addLayer(layer); 7292 } 7293 7294 return this; 7295 }, 7296 7297 // @method removeLayer(layer: Layer): this 7298 // Removes the given layer from the group. 7299 // @alternative 7300 // @method removeLayer(id: Number): this 7301 // Removes the layer with the given internal ID from the group. 7302 removeLayer: function (layer) { 7303 var id = layer in this._layers ? layer : this.getLayerId(layer); 7304 7305 if (this._map && this._layers[id]) { 7306 this._map.removeLayer(this._layers[id]); 7307 } 7308 7309 delete this._layers[id]; 7310 7311 return this; 7312 }, 7313 7314 // @method hasLayer(layer: Layer): Boolean 7315 // Returns `true` if the given layer is currently added to the group. 7316 // @alternative 7317 // @method hasLayer(id: Number): Boolean 7318 // Returns `true` if the given internal ID is currently added to the group. 7319 hasLayer: function (layer) { 7320 return !!layer && (layer in this._layers || this.getLayerId(layer) in this._layers); 7321 }, 7322 7323 // @method clearLayers(): this 7324 // Removes all the layers from the group. 7325 clearLayers: function () { 7326 return this.eachLayer(this.removeLayer, this); 7327 }, 7328 7329 // @method invoke(methodName: String, …): this 7330 // Calls `methodName` on every layer contained in this group, passing any 7331 // additional parameters. Has no effect if the layers contained do not 7332 // implement `methodName`. 7333 invoke: function (methodName) { 7334 var args = Array.prototype.slice.call(arguments, 1), 7335 i, layer; 7336 7337 for (i in this._layers) { 7338 layer = this._layers[i]; 7339 7340 if (layer[methodName]) { 7341 layer[methodName].apply(layer, args); 7342 } 7343 } 7344 7345 return this; 7346}, 7347 7348onAdd: function (map) { 7349 this.eachLayer(map.addLayer, map); 7350}, 7351 7352onRemove: function (map) { 7353 this.eachLayer(map.removeLayer, map); 7354}, 7355 7356 // @method eachLayer(fn: Function, context?: Object): this 7357 // Iterates over the layers of the group, optionally specifying context of the iterator function. 7358 // ```js 7359 // group.eachLayer(function (layer) { 7360 // layer.bindPopup('Hello'); 7361 // }); 7362 // ``` 7363 eachLayer: function (method, context) { 7364 for (var i in this._layers) { 7365 method.call(context, this._layers[i]); 7366 } 7367 return this; 7368 }, 7369 7370 // @method getLayer(id: Number): Layer 7371 // Returns the layer with the given internal ID. 7372 getLayer: function (id) { 7373 return this._layers[id]; 7374 }, 7375 7376 // @method getLayers(): Layer[] 7377 // Returns an array of all the layers added to the group. 7378 getLayers: function () { 7379 var layers = []; 7380 this.eachLayer(layers.push, layers); 7381 return layers; 7382 }, 7383 7384 // @method setZIndex(zIndex: Number): this 7385 // Calls `setZIndex` on every layer contained in this group, passing the z-index. 7386 setZIndex: function (zIndex) { 7387 return this.invoke('setZIndex', zIndex); 7388 }, 7389 7390 // @method getLayerId(layer: Layer): Number 7391 // Returns the internal ID for a layer 7392 getLayerId: function (layer) { 7393 return stamp(layer); 7394 } 7395}); 7396 7397 7398// @factory L.layerGroup(layers?: Layer[], options?: Object) 7399// Create a layer group, optionally given an initial set of layers and an `options` object. 7400var layerGroup = function (layers, options) { 7401 return new LayerGroup(layers, options); 7402}; 7403 7404/* 7405 * @class FeatureGroup 7406 * @aka L.FeatureGroup 7407 * @inherits LayerGroup 7408 * 7409 * Extended `LayerGroup` that makes it easier to do the same thing to all its member layers: 7410 * * [`bindPopup`](#layer-bindpopup) binds a popup to all of the layers at once (likewise with [`bindTooltip`](#layer-bindtooltip)) 7411 * * Events are propagated to the `FeatureGroup`, so if the group has an event 7412 * handler, it will handle events from any of the layers. This includes mouse events 7413 * and custom events. 7414 * * Has `layeradd` and `layerremove` events 7415 * 7416 * @example 7417 * 7418 * ```js 7419 * L.featureGroup([marker1, marker2, polyline]) 7420 * .bindPopup('Hello world!') 7421 * .on('click', function() { alert('Clicked on a member of the group!'); }) 7422 * .addTo(map); 7423 * ``` 7424 */ 7425 7426 var FeatureGroup = LayerGroup.extend({ 7427 7428 addLayer: function (layer) { 7429 if (this.hasLayer(layer)) { 7430 return this; 7431 } 7432 7433 layer.addEventParent(this); 7434 7435 LayerGroup.prototype.addLayer.call(this, layer); 7436 7437 // @event layeradd: LayerEvent 7438 // Fired when a layer is added to this `FeatureGroup` 7439 return this.fire('layeradd', {layer: layer}); 7440 }, 7441 7442 removeLayer: function (layer) { 7443 if (!this.hasLayer(layer)) { 7444 return this; 7445 } 7446 if (layer in this._layers) { 7447 layer = this._layers[layer]; 7448 } 7449 7450 layer.removeEventParent(this); 7451 7452 LayerGroup.prototype.removeLayer.call(this, layer); 7453 7454 // @event layerremove: LayerEvent 7455 // Fired when a layer is removed from this `FeatureGroup` 7456 return this.fire('layerremove', {layer: layer}); 7457 }, 7458 7459 // @method setStyle(style: Path options): this 7460 // Sets the given path options to each layer of the group that has a `setStyle` method. 7461 setStyle: function (style) { 7462 return this.invoke('setStyle', style); 7463 }, 7464 7465 // @method bringToFront(): this 7466 // Brings the layer group to the top of all other layers 7467 bringToFront: function () { 7468 return this.invoke('bringToFront'); 7469 }, 7470 7471 // @method bringToBack(): this 7472 // Brings the layer group to the back of all other layers 7473 bringToBack: function () { 7474 return this.invoke('bringToBack'); 7475 }, 7476 7477 // @method getBounds(): LatLngBounds 7478 // Returns the LatLngBounds of the Feature Group (created from bounds and coordinates of its children). 7479 getBounds: function () { 7480 var bounds = new LatLngBounds(); 7481 7482 for (var id in this._layers) { 7483 var layer = this._layers[id]; 7484 bounds.extend(layer.getBounds ? layer.getBounds() : layer.getLatLng()); 7485 } 7486 return bounds; 7487 } 7488}); 7489 7490// @factory L.featureGroup(layers: Layer[]) 7491// Create a feature group, optionally given an initial set of layers. 7492var featureGroup = function (layers) { 7493 return new FeatureGroup(layers); 7494}; 7495 7496/* 7497 * @class Icon 7498 * @aka L.Icon 7499 * 7500 * Represents an icon to provide when creating a marker. 7501 * 7502 * @example 7503 * 7504 * ```js 7505 * var myIcon = L.icon({ 7506 * iconUrl: 'my-icon.png', 7507 * iconRetinaUrl: '[email protected]', 7508 * iconSize: [38, 95], 7509 * iconAnchor: [22, 94], 7510 * popupAnchor: [-3, -76], 7511 * shadowUrl: 'my-icon-shadow.png', 7512 * shadowRetinaUrl: '[email protected]', 7513 * shadowSize: [68, 95], 7514 * shadowAnchor: [22, 94] 7515 * }); 7516 * 7517 * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map); 7518 * ``` 7519 * 7520 * `L.Icon.Default` extends `L.Icon` and is the blue icon Leaflet uses for markers by default. 7521 * 7522 */ 7523 7524 var Icon = Class.extend({ 7525 7526 /* @section 7527 * @aka Icon options 7528 * 7529 * @option iconUrl: String = null 7530 * **(required)** The URL to the icon image (absolute or relative to your script path). 7531 * 7532 * @option iconRetinaUrl: String = null 7533 * The URL to a retina sized version of the icon image (absolute or relative to your 7534 * script path). Used for Retina screen devices. 7535 * 7536 * @option iconSize: Point = null 7537 * Size of the icon image in pixels. 7538 * 7539 * @option iconAnchor: Point = null 7540 * The coordinates of the "tip" of the icon (relative to its top left corner). The icon 7541 * will be aligned so that this point is at the marker's geographical location. Centered 7542 * by default if size is specified, also can be set in CSS with negative margins. 7543 * 7544 * @option popupAnchor: Point = [0, 0] 7545 * The coordinates of the point from which popups will "open", relative to the icon anchor. 7546 * 7547 * @option tooltipAnchor: Point = [0, 0] 7548 * The coordinates of the point from which tooltips will "open", relative to the icon anchor. 7549 * 7550 * @option shadowUrl: String = null 7551 * The URL to the icon shadow image. If not specified, no shadow image will be created. 7552 * 7553 * @option shadowRetinaUrl: String = null 7554 * 7555 * @option shadowSize: Point = null 7556 * Size of the shadow image in pixels. 7557 * 7558 * @option shadowAnchor: Point = null 7559 * The coordinates of the "tip" of the shadow (relative to its top left corner) (the same 7560 * as iconAnchor if not specified). 7561 * 7562 * @option className: String = '' 7563 * A custom class name to assign to both icon and shadow images. Empty by default. 7564 */ 7565 7566 options: { 7567 popupAnchor: [0, 0], 7568 tooltipAnchor: [0, 0] 7569 }, 7570 7571 initialize: function (options) { 7572 setOptions(this, options); 7573 }, 7574 7575 // @method createIcon(oldIcon?: HTMLElement): HTMLElement 7576 // Called internally when the icon has to be shown, returns a `<img>` HTML element 7577 // styled according to the options. 7578 createIcon: function (oldIcon) { 7579 return this._createIcon('icon', oldIcon); 7580 }, 7581 7582 // @method createShadow(oldIcon?: HTMLElement): HTMLElement 7583 // As `createIcon`, but for the shadow beneath it. 7584 createShadow: function (oldIcon) { 7585 return this._createIcon('shadow', oldIcon); 7586 }, 7587 7588 _createIcon: function (name, oldIcon) { 7589 var src = this._getIconUrl(name); 7590 7591 if (!src) { 7592 if (name === 'icon') { 7593 throw new Error('iconUrl not set in Icon options (see the docs).'); 7594 } 7595 return null; 7596 } 7597 7598 var img = this._createImg(src, oldIcon && oldIcon.tagName === 'IMG' ? oldIcon : null); 7599 this._setIconStyles(img, name); 7600 7601 return img; 7602 }, 7603 7604 _setIconStyles: function (img, name) { 7605 var options = this.options; 7606 var sizeOption = options[name + 'Size']; 7607 7608 if (typeof sizeOption === 'number') { 7609 sizeOption = [sizeOption, sizeOption]; 7610 } 7611 7612 var size = toPoint(sizeOption), 7613 anchor = toPoint(name === 'shadow' && options.shadowAnchor || options.iconAnchor || 7614 size && size.divideBy(2, true)); 7615 7616 img.className = 'leaflet-marker-' + name + ' ' + (options.className || ''); 7617 7618 if (anchor) { 7619 img.style.marginLeft = (-anchor.x) + 'px'; 7620 img.style.marginTop = (-anchor.y) + 'px'; 7621 } 7622 7623 if (size) { 7624 img.style.width = size.x + 'px'; 7625 img.style.height = size.y + 'px'; 7626 } 7627 }, 7628 7629 _createImg: function (src, el) { 7630 el = el || document.createElement('img'); 7631 el.src = src; 7632 return el; 7633}, 7634 7635_getIconUrl: function (name) { 7636 return retina && this.options[name + 'RetinaUrl'] || this.options[name + 'Url']; 7637} 7638}); 7639 7640 7641// @factory L.icon(options: Icon options) 7642// Creates an icon instance with the given options. 7643function icon(options) { 7644 return new Icon(options); 7645} 7646 7647/* 7648 * @miniclass Icon.Default (Icon) 7649 * @aka L.Icon.Default 7650 * @section 7651 * 7652 * A trivial subclass of `Icon`, represents the icon to use in `Marker`s when 7653 * no icon is specified. Points to the blue marker image distributed with Leaflet 7654 * releases. 7655 * 7656 * In order to customize the default icon, just change the properties of `L.Icon.Default.prototype.options` 7657 * (which is a set of `Icon options`). 7658 * 7659 * If you want to _completely_ replace the default icon, override the 7660 * `L.Marker.prototype.options.icon` with your own icon instead. 7661 */ 7662 7663 var IconDefault = Icon.extend({ 7664 7665 options: { 7666 iconUrl: 'marker-icon.png', 7667 iconRetinaUrl: 'marker-icon-2x.png', 7668 shadowUrl: 'marker-shadow.png', 7669 iconSize: [25, 41], 7670 iconAnchor: [12, 41], 7671 popupAnchor: [1, -34], 7672 tooltipAnchor: [16, -28], 7673 shadowSize: [41, 41] 7674 }, 7675 7676 _getIconUrl: function (name) { 7677 if (!IconDefault.imagePath) { // Deprecated, backwards-compatibility only 7678 IconDefault.imagePath = this._detectIconPath(); 7679 } 7680 7681 // @option imagePath: String 7682 // `Icon.Default` will try to auto-detect the location of the 7683 // blue icon images. If you are placing these images in a non-standard 7684 // way, set this option to point to the right path. 7685 return (this.options.imagePath || IconDefault.imagePath) + Icon.prototype._getIconUrl.call(this, name); 7686 }, 7687 7688 _detectIconPath: function () { 7689 var el = create$1('div', 'leaflet-default-icon-path', document.body); 7690 var path = getStyle(el, 'background-image') || 7691 getStyle(el, 'backgroundImage'); // IE8 7692 7693 document.body.removeChild(el); 7694 7695 if (path === null || path.indexOf('url') !== 0) { 7696 path = ''; 7697 } else { 7698 path = path.replace(/^url\(["']?/, '').replace(/marker-icon\.png["']?\)$/, ''); 7699 } 7700 7701 return path; 7702 } 7703 }); 7704 7705/* 7706 * L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable. 7707 */ 7708 7709 7710/* @namespace Marker 7711 * @section Interaction handlers 7712 * 7713 * Interaction handlers are properties of a marker instance that allow you to control interaction behavior in runtime, enabling or disabling certain features such as dragging (see `Handler` methods). Example: 7714 * 7715 * ```js 7716 * marker.dragging.disable(); 7717 * ``` 7718 * 7719 * @property dragging: Handler 7720 * Marker dragging handler (by both mouse and touch). Only valid when the marker is on the map (Otherwise set [`marker.options.draggable`](#marker-draggable)). 7721 */ 7722 7723 var MarkerDrag = Handler.extend({ 7724 initialize: function (marker) { 7725 this._marker = marker; 7726 }, 7727 7728 addHooks: function () { 7729 var icon = this._marker._icon; 7730 7731 if (!this._draggable) { 7732 this._draggable = new Draggable(icon, icon, true); 7733 } 7734 7735 this._draggable.on({ 7736 dragstart: this._onDragStart, 7737 predrag: this._onPreDrag, 7738 drag: this._onDrag, 7739 dragend: this._onDragEnd 7740 }, this).enable(); 7741 7742 addClass(icon, 'leaflet-marker-draggable'); 7743 }, 7744 7745 removeHooks: function () { 7746 this._draggable.off({ 7747 dragstart: this._onDragStart, 7748 predrag: this._onPreDrag, 7749 drag: this._onDrag, 7750 dragend: this._onDragEnd 7751 }, this).disable(); 7752 7753 if (this._marker._icon) { 7754 removeClass(this._marker._icon, 'leaflet-marker-draggable'); 7755 } 7756}, 7757 7758moved: function () { 7759 return this._draggable && this._draggable._moved; 7760}, 7761 7762_adjustPan: function (e) { 7763 var marker = this._marker, 7764 map = marker._map, 7765 speed = this._marker.options.autoPanSpeed, 7766 padding = this._marker.options.autoPanPadding, 7767 iconPos = getPosition(marker._icon), 7768 bounds = map.getPixelBounds(), 7769 origin = map.getPixelOrigin(); 7770 7771 var panBounds = toBounds( 7772 bounds.min._subtract(origin).add(padding), 7773 bounds.max._subtract(origin).subtract(padding) 7774 ); 7775 7776 if (!panBounds.contains(iconPos)) { 7777 // Compute incremental movement 7778 var movement = toPoint( 7779 (Math.max(panBounds.max.x, iconPos.x) - panBounds.max.x) / (bounds.max.x - panBounds.max.x) - 7780 (Math.min(panBounds.min.x, iconPos.x) - panBounds.min.x) / (bounds.min.x - panBounds.min.x), 7781 7782 (Math.max(panBounds.max.y, iconPos.y) - panBounds.max.y) / (bounds.max.y - panBounds.max.y) - 7783 (Math.min(panBounds.min.y, iconPos.y) - panBounds.min.y) / (bounds.min.y - panBounds.min.y) 7784 ).multiplyBy(speed); 7785 7786 map.panBy(movement, {animate: false}); 7787 7788 this._draggable._newPos._add(movement); 7789 this._draggable._startPos._add(movement); 7790 7791 setPosition(marker._icon, this._draggable._newPos); 7792 this._onDrag(e); 7793 7794 this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e)); 7795 } 7796 }, 7797 7798 _onDragStart: function () { 7799 // @section Dragging events 7800 // @event dragstart: Event 7801 // Fired when the user starts dragging the marker. 7802 7803 // @event movestart: Event 7804 // Fired when the marker starts moving (because of dragging). 7805 7806 this._oldLatLng = this._marker.getLatLng(); 7807 this._marker 7808 .closePopup() 7809 .fire('movestart') 7810 .fire('dragstart'); 7811 }, 7812 7813 _onPreDrag: function (e) { 7814 if (this._marker.options.autoPan) { 7815 cancelAnimFrame(this._panRequest); 7816 this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e)); 7817 } 7818 }, 7819 7820 _onDrag: function (e) { 7821 var marker = this._marker, 7822 shadow = marker._shadow, 7823 iconPos = getPosition(marker._icon), 7824 latlng = marker._map.layerPointToLatLng(iconPos); 7825 7826 // update shadow position 7827 if (shadow) { 7828 setPosition(shadow, iconPos); 7829 } 7830 7831 marker._latlng = latlng; 7832 e.latlng = latlng; 7833 e.oldLatLng = this._oldLatLng; 7834 7835 // @event drag: Event 7836 // Fired repeatedly while the user drags the marker. 7837 marker 7838 .fire('move', e) 7839 .fire('drag', e); 7840 }, 7841 7842 _onDragEnd: function (e) { 7843 // @event dragend: DragEndEvent 7844 // Fired when the user stops dragging the marker. 7845 7846 cancelAnimFrame(this._panRequest); 7847 7848 // @event moveend: Event 7849 // Fired when the marker stops moving (because of dragging). 7850 delete this._oldLatLng; 7851 this._marker 7852 .fire('moveend') 7853 .fire('dragend', e); 7854 } 7855}); 7856 7857/* 7858 * @class Marker 7859 * @inherits Interactive layer 7860 * @aka L.Marker 7861 * L.Marker is used to display clickable/draggable icons on the map. Extends `Layer`. 7862 * 7863 * @example 7864 * 7865 * ```js 7866 * L.marker([50.5, 30.5]).addTo(map); 7867 * ``` 7868 */ 7869 7870 var Marker = Layer.extend({ 7871 7872 // @section 7873 // @aka Marker options 7874 options: { 7875 // @option icon: Icon = * 7876 // Icon instance to use for rendering the marker. 7877 // See [Icon documentation](#L.Icon) for details on how to customize the marker icon. 7878 // If not specified, a common instance of `L.Icon.Default` is used. 7879 icon: new IconDefault(), 7880 7881 // Option inherited from "Interactive layer" abstract class 7882 interactive: true, 7883 7884 // @option keyboard: Boolean = true 7885 // Whether the marker can be tabbed to with a keyboard and clicked by pressing enter. 7886 keyboard: true, 7887 7888 // @option title: String = '' 7889 // Text for the browser tooltip that appear on marker hover (no tooltip by default). 7890 title: '', 7891 7892 // @option alt: String = '' 7893 // Text for the `alt` attribute of the icon image (useful for accessibility). 7894 alt: '', 7895 7896 // @option zIndexOffset: Number = 0 7897 // By default, marker images zIndex is set automatically based on its latitude. Use this option if you want to put the marker on top of all others (or below), specifying a high value like `1000` (or high negative value, respectively). 7898 zIndexOffset: 0, 7899 7900 // @option opacity: Number = 1.0 7901 // The opacity of the marker. 7902 opacity: 1, 7903 7904 // @option riseOnHover: Boolean = false 7905 // If `true`, the marker will get on top of others when you hover the mouse over it. 7906 riseOnHover: false, 7907 7908 // @option riseOffset: Number = 250 7909 // The z-index offset used for the `riseOnHover` feature. 7910 riseOffset: 250, 7911 7912 // @option pane: String = 'markerPane' 7913 // `Map pane` where the markers icon will be added. 7914 pane: 'markerPane', 7915 7916 // @option pane: String = 'shadowPane' 7917 // `Map pane` where the markers shadow will be added. 7918 shadowPane: 'shadowPane', 7919 7920 // @option bubblingMouseEvents: Boolean = false 7921 // When `true`, a mouse event on this marker will trigger the same event on the map 7922 // (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used). 7923 bubblingMouseEvents: false, 7924 7925 // @section Draggable marker options 7926 // @option draggable: Boolean = false 7927 // Whether the marker is draggable with mouse/touch or not. 7928 draggable: false, 7929 7930 // @option autoPan: Boolean = false 7931 // Whether to pan the map when dragging this marker near its edge or not. 7932 autoPan: false, 7933 7934 // @option autoPanPadding: Point = Point(50, 50) 7935 // Distance (in pixels to the left/right and to the top/bottom) of the 7936 // map edge to start panning the map. 7937 autoPanPadding: [50, 50], 7938 7939 // @option autoPanSpeed: Number = 10 7940 // Number of pixels the map should pan by. 7941 autoPanSpeed: 10 7942 }, 7943 7944 /* @section 7945 * 7946 * In addition to [shared layer methods](#Layer) like `addTo()` and `remove()` and [popup methods](#Popup) like bindPopup() you can also use the following methods: 7947 */ 7948 7949 initialize: function (latlng, options) { 7950 setOptions(this, options); 7951 this._latlng = toLatLng(latlng); 7952 }, 7953 7954 onAdd: function (map) { 7955 this._zoomAnimated = this._zoomAnimated && map.options.markerZoomAnimation; 7956 7957 if (this._zoomAnimated) { 7958 map.on('zoomanim', this._animateZoom, this); 7959 } 7960 7961 this._initIcon(); 7962 this.update(); 7963 }, 7964 7965 onRemove: function (map) { 7966 if (this.dragging && this.dragging.enabled()) { 7967 this.options.draggable = true; 7968 this.dragging.removeHooks(); 7969 } 7970 delete this.dragging; 7971 7972 if (this._zoomAnimated) { 7973 map.off('zoomanim', this._animateZoom, this); 7974 } 7975 7976 this._removeIcon(); 7977 this._removeShadow(); 7978}, 7979 7980getEvents: function () { 7981 return { 7982 zoom: this.update, 7983 viewreset: this.update 7984 }; 7985}, 7986 7987 // @method getLatLng: LatLng 7988 // Returns the current geographical position of the marker. 7989 getLatLng: function () { 7990 return this._latlng; 7991 }, 7992 7993 // @method setLatLng(latlng: LatLng): this 7994 // Changes the marker position to the given point. 7995 setLatLng: function (latlng) { 7996 var oldLatLng = this._latlng; 7997 this._latlng = toLatLng(latlng); 7998 this.update(); 7999 8000 // @event move: Event 8001 // Fired when the marker is moved via [`setLatLng`](#marker-setlatlng) or by [dragging](#marker-dragging). Old and new coordinates are included in event arguments as `oldLatLng`, `latlng`. 8002 return this.fire('move', {oldLatLng: oldLatLng, latlng: this._latlng}); 8003 }, 8004 8005 // @method setZIndexOffset(offset: Number): this 8006 // Changes the [zIndex offset](#marker-zindexoffset) of the marker. 8007 setZIndexOffset: function (offset) { 8008 this.options.zIndexOffset = offset; 8009 return this.update(); 8010 }, 8011 8012 // @method getIcon: Icon 8013 // Returns the current icon used by the marker 8014 getIcon: function () { 8015 return this.options.icon; 8016 }, 8017 8018 // @method setIcon(icon: Icon): this 8019 // Changes the marker icon. 8020 setIcon: function (icon) { 8021 8022 this.options.icon = icon; 8023 8024 if (this._map) { 8025 this._initIcon(); 8026 this.update(); 8027 } 8028 8029 if (this._popup) { 8030 this.bindPopup(this._popup, this._popup.options); 8031 } 8032 8033 return this; 8034 }, 8035 8036 getElement: function () { 8037 return this._icon; 8038 }, 8039 8040 update: function () { 8041 8042 if (this._icon && this._map) { 8043 var pos = this._map.latLngToLayerPoint(this._latlng).round(); 8044 this._setPos(pos); 8045 } 8046 8047 return this; 8048 }, 8049 8050 _initIcon: function () { 8051 var options = this.options, 8052 classToAdd = 'leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide'); 8053 8054 var icon = options.icon.createIcon(this._icon), 8055 addIcon = false; 8056 8057 // if we're not reusing the icon, remove the old one and init new one 8058 if (icon !== this._icon) { 8059 if (this._icon) { 8060 this._removeIcon(); 8061 } 8062 addIcon = true; 8063 8064 if (options.title) { 8065 icon.title = options.title; 8066 } 8067 8068 if (icon.tagName === 'IMG') { 8069 icon.alt = options.alt || ''; 8070 } 8071 } 8072 8073 addClass(icon, classToAdd); 8074 8075 if (options.keyboard) { 8076 icon.tabIndex = '0'; 8077 } 8078 8079 this._icon = icon; 8080 8081 if (options.riseOnHover) { 8082 this.on({ 8083 mouseover: this._bringToFront, 8084 mouseout: this._resetZIndex 8085 }); 8086 } 8087 8088 var newShadow = options.icon.createShadow(this._shadow), 8089 addShadow = false; 8090 8091 if (newShadow !== this._shadow) { 8092 this._removeShadow(); 8093 addShadow = true; 8094 } 8095 8096 if (newShadow) { 8097 addClass(newShadow, classToAdd); 8098 newShadow.alt = ''; 8099 } 8100 this._shadow = newShadow; 8101 8102 8103 if (options.opacity < 1) { 8104 this._updateOpacity(); 8105 } 8106 8107 8108 if (addIcon) { 8109 this.getPane().appendChild(this._icon); 8110 } 8111 this._initInteraction(); 8112 if (newShadow && addShadow) { 8113 this.getPane(options.shadowPane).appendChild(this._shadow); 8114 } 8115 }, 8116 8117 _removeIcon: function () { 8118 if (this.options.riseOnHover) { 8119 this.off({ 8120 mouseover: this._bringToFront, 8121 mouseout: this._resetZIndex 8122 }); 8123 } 8124 8125 remove(this._icon); 8126 this.removeInteractiveTarget(this._icon); 8127 8128 this._icon = null; 8129}, 8130 8131_removeShadow: function () { 8132 if (this._shadow) { 8133 remove(this._shadow); 8134 } 8135 this._shadow = null; 8136}, 8137 8138_setPos: function (pos) { 8139 setPosition(this._icon, pos); 8140 8141 if (this._shadow) { 8142 setPosition(this._shadow, pos); 8143 } 8144 8145 this._zIndex = pos.y + this.options.zIndexOffset; 8146 8147 this._resetZIndex(); 8148}, 8149 8150_updateZIndex: function (offset) { 8151 this._icon.style.zIndex = this._zIndex + offset; 8152}, 8153 8154_animateZoom: function (opt) { 8155 var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round(); 8156 8157 this._setPos(pos); 8158}, 8159 8160_initInteraction: function () { 8161 8162 if (!this.options.interactive) { return; } 8163 8164 addClass(this._icon, 'leaflet-interactive'); 8165 8166 this.addInteractiveTarget(this._icon); 8167 8168 if (MarkerDrag) { 8169 var draggable = this.options.draggable; 8170 if (this.dragging) { 8171 draggable = this.dragging.enabled(); 8172 this.dragging.disable(); 8173 } 8174 8175 this.dragging = new MarkerDrag(this); 8176 8177 if (draggable) { 8178 this.dragging.enable(); 8179 } 8180} 8181}, 8182 8183 // @method setOpacity(opacity: Number): this 8184 // Changes the opacity of the marker. 8185 setOpacity: function (opacity) { 8186 this.options.opacity = opacity; 8187 if (this._map) { 8188 this._updateOpacity(); 8189 } 8190 8191 return this; 8192 }, 8193 8194 _updateOpacity: function () { 8195 var opacity = this.options.opacity; 8196 8197 if (this._icon) { 8198 setOpacity(this._icon, opacity); 8199 } 8200 8201 if (this._shadow) { 8202 setOpacity(this._shadow, opacity); 8203 } 8204 }, 8205 8206 _bringToFront: function () { 8207 this._updateZIndex(this.options.riseOffset); 8208 }, 8209 8210 _resetZIndex: function () { 8211 this._updateZIndex(0); 8212 }, 8213 8214 _getPopupAnchor: function () { 8215 return this.options.icon.options.popupAnchor; 8216 }, 8217 8218 _getTooltipAnchor: function () { 8219 return this.options.icon.options.tooltipAnchor; 8220 } 8221}); 8222 8223 8224// factory L.marker(latlng: LatLng, options? : Marker options) 8225 8226// @factory L.marker(latlng: LatLng, options? : Marker options) 8227// Instantiates a Marker object given a geographical point and optionally an options object. 8228function marker(latlng, options) { 8229 return new Marker(latlng, options); 8230} 8231 8232/* 8233 * @class Path 8234 * @aka L.Path 8235 * @inherits Interactive layer 8236 * 8237 * An abstract class that contains options and constants shared between vector 8238 * overlays (Polygon, Polyline, Circle). Do not use it directly. Extends `Layer`. 8239 */ 8240 8241 var Path = Layer.extend({ 8242 8243 // @section 8244 // @aka Path options 8245 options: { 8246 // @option stroke: Boolean = true 8247 // Whether to draw stroke along the path. Set it to `false` to disable borders on polygons or circles. 8248 stroke: true, 8249 8250 // @option color: String = '#3388ff' 8251 // Stroke color 8252 color: '#3388ff', 8253 8254 // @option weight: Number = 3 8255 // Stroke width in pixels 8256 weight: 3, 8257 8258 // @option opacity: Number = 1.0 8259 // Stroke opacity 8260 opacity: 1, 8261 8262 // @option lineCap: String= 'round' 8263 // A string that defines [shape to be used at the end](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linecap) of the stroke. 8264 lineCap: 'round', 8265 8266 // @option lineJoin: String = 'round' 8267 // A string that defines [shape to be used at the corners](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linejoin) of the stroke. 8268 lineJoin: 'round', 8269 8270 // @option dashArray: String = null 8271 // A string that defines the stroke [dash pattern](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-dasharray). Doesn't work on `Canvas`-powered layers in [some old browsers](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility). 8272 dashArray: null, 8273 8274 // @option dashOffset: String = null 8275 // A string that defines the [distance into the dash pattern to start the dash](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-dashoffset). Doesn't work on `Canvas`-powered layers in [some old browsers](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility). 8276 dashOffset: null, 8277 8278 // @option fill: Boolean = depends 8279 // Whether to fill the path with color. Set it to `false` to disable filling on polygons or circles. 8280 fill: false, 8281 8282 // @option fillColor: String = * 8283 // Fill color. Defaults to the value of the [`color`](#path-color) option 8284 fillColor: null, 8285 8286 // @option fillOpacity: Number = 0.2 8287 // Fill opacity. 8288 fillOpacity: 0.2, 8289 8290 // @option fillRule: String = 'evenodd' 8291 // A string that defines [how the inside of a shape](https://developer.mozilla.org/docs/Web/SVG/Attribute/fill-rule) is determined. 8292 fillRule: 'evenodd', 8293 8294 // className: '', 8295 8296 // Option inherited from "Interactive layer" abstract class 8297 interactive: true, 8298 8299 // @option bubblingMouseEvents: Boolean = true 8300 // When `true`, a mouse event on this path will trigger the same event on the map 8301 // (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used). 8302 bubblingMouseEvents: true 8303 }, 8304 8305 beforeAdd: function (map) { 8306 // Renderer is set here because we need to call renderer.getEvents 8307 // before this.getEvents. 8308 this._renderer = map.getRenderer(this); 8309 }, 8310 8311 onAdd: function () { 8312 this._renderer._initPath(this); 8313 this._reset(); 8314 this._renderer._addPath(this); 8315 }, 8316 8317 onRemove: function () { 8318 this._renderer._removePath(this); 8319 }, 8320 8321 // @method redraw(): this 8322 // Redraws the layer. Sometimes useful after you changed the coordinates that the path uses. 8323 redraw: function () { 8324 if (this._map) { 8325 this._renderer._updatePath(this); 8326 } 8327 return this; 8328 }, 8329 8330 // @method setStyle(style: Path options): this 8331 // Changes the appearance of a Path based on the options in the `Path options` object. 8332 setStyle: function (style) { 8333 setOptions(this, style); 8334 if (this._renderer) { 8335 this._renderer._updateStyle(this); 8336 if (this.options.stroke && style.hasOwnProperty('weight')) { 8337 this._updateBounds(); 8338 } 8339 } 8340 return this; 8341 }, 8342 8343 // @method bringToFront(): this 8344 // Brings the layer to the top of all path layers. 8345 bringToFront: function () { 8346 if (this._renderer) { 8347 this._renderer._bringToFront(this); 8348 } 8349 return this; 8350 }, 8351 8352 // @method bringToBack(): this 8353 // Brings the layer to the bottom of all path layers. 8354 bringToBack: function () { 8355 if (this._renderer) { 8356 this._renderer._bringToBack(this); 8357 } 8358 return this; 8359 }, 8360 8361 getElement: function () { 8362 return this._path; 8363 }, 8364 8365 _reset: function () { 8366 // defined in child classes 8367 this._project(); 8368 this._update(); 8369 }, 8370 8371 _clickTolerance: function () { 8372 // used when doing hit detection for Canvas layers 8373 return (this.options.stroke ? this.options.weight / 2 : 0) + this._renderer.options.tolerance; 8374 } 8375}); 8376 8377/* 8378 * @class CircleMarker 8379 * @aka L.CircleMarker 8380 * @inherits Path 8381 * 8382 * A circle of a fixed size with radius specified in pixels. Extends `Path`. 8383 */ 8384 8385 var CircleMarker = Path.extend({ 8386 8387 // @section 8388 // @aka CircleMarker options 8389 options: { 8390 fill: true, 8391 8392 // @option radius: Number = 10 8393 // Radius of the circle marker, in pixels 8394 radius: 10 8395 }, 8396 8397 initialize: function (latlng, options) { 8398 setOptions(this, options); 8399 this._latlng = toLatLng(latlng); 8400 this._radius = this.options.radius; 8401 }, 8402 8403 // @method setLatLng(latLng: LatLng): this 8404 // Sets the position of a circle marker to a new location. 8405 setLatLng: function (latlng) { 8406 this._latlng = toLatLng(latlng); 8407 this.redraw(); 8408 return this.fire('move', {latlng: this._latlng}); 8409 }, 8410 8411 // @method getLatLng(): LatLng 8412 // Returns the current geographical position of the circle marker 8413 getLatLng: function () { 8414 return this._latlng; 8415 }, 8416 8417 // @method setRadius(radius: Number): this 8418 // Sets the radius of a circle marker. Units are in pixels. 8419 setRadius: function (radius) { 8420 this.options.radius = this._radius = radius; 8421 return this.redraw(); 8422 }, 8423 8424 // @method getRadius(): Number 8425 // Returns the current radius of the circle 8426 getRadius: function () { 8427 return this._radius; 8428 }, 8429 8430 setStyle : function (options) { 8431 var radius = options && options.radius || this._radius; 8432 Path.prototype.setStyle.call(this, options); 8433 this.setRadius(radius); 8434 return this; 8435 }, 8436 8437 _project: function () { 8438 this._point = this._map.latLngToLayerPoint(this._latlng); 8439 this._updateBounds(); 8440 }, 8441 8442 _updateBounds: function () { 8443 var r = this._radius, 8444 r2 = this._radiusY || r, 8445 w = this._clickTolerance(), 8446 p = [r + w, r2 + w]; 8447 this._pxBounds = new Bounds(this._point.subtract(p), this._point.add(p)); 8448 }, 8449 8450 _update: function () { 8451 if (this._map) { 8452 this._updatePath(); 8453 } 8454 }, 8455 8456 _updatePath: function () { 8457 this._renderer._updateCircle(this); 8458}, 8459 8460_empty: function () { 8461 return this._radius && !this._renderer._bounds.intersects(this._pxBounds); 8462}, 8463 8464 // Needed by the `Canvas` renderer for interactivity 8465 _containsPoint: function (p) { 8466 return p.distanceTo(this._point) <= this._radius + this._clickTolerance(); 8467 } 8468}); 8469 8470 8471// @factory L.circleMarker(latlng: LatLng, options?: CircleMarker options) 8472// Instantiates a circle marker object given a geographical point, and an optional options object. 8473function circleMarker(latlng, options) { 8474 return new CircleMarker(latlng, options); 8475} 8476 8477/* 8478 * @class Circle 8479 * @aka L.Circle 8480 * @inherits CircleMarker 8481 * 8482 * A class for drawing circle overlays on a map. Extends `CircleMarker`. 8483 * 8484 * It's an approximation and starts to diverge from a real circle closer to poles (due to projection distortion). 8485 * 8486 * @example 8487 * 8488 * ```js 8489 * L.circle([50.5, 30.5], {radius: 200}).addTo(map); 8490 * ``` 8491 */ 8492 8493 var Circle = CircleMarker.extend({ 8494 8495 initialize: function (latlng, options, legacyOptions) { 8496 if (typeof options === 'number') { 8497 // Backwards compatibility with 0.7.x factory (latlng, radius, options?) 8498 options = extend({}, legacyOptions, {radius: options}); 8499 } 8500 setOptions(this, options); 8501 this._latlng = toLatLng(latlng); 8502 8503 if (isNaN(this.options.radius)) { throw new Error('Circle radius cannot be NaN'); } 8504 8505 // @section 8506 // @aka Circle options 8507 // @option radius: Number; Radius of the circle, in meters. 8508 this._mRadius = this.options.radius; 8509 }, 8510 8511 // @method setRadius(radius: Number): this 8512 // Sets the radius of a circle. Units are in meters. 8513 setRadius: function (radius) { 8514 this._mRadius = radius; 8515 return this.redraw(); 8516 }, 8517 8518 // @method getRadius(): Number 8519 // Returns the current radius of a circle. Units are in meters. 8520 getRadius: function () { 8521 return this._mRadius; 8522 }, 8523 8524 // @method getBounds(): LatLngBounds 8525 // Returns the `LatLngBounds` of the path. 8526 getBounds: function () { 8527 var half = [this._radius, this._radiusY || this._radius]; 8528 8529 return new LatLngBounds( 8530 this._map.layerPointToLatLng(this._point.subtract(half)), 8531 this._map.layerPointToLatLng(this._point.add(half))); 8532 }, 8533 8534 setStyle: Path.prototype.setStyle, 8535 8536 _project: function () { 8537 8538 var lng = this._latlng.lng, 8539 lat = this._latlng.lat, 8540 map = this._map, 8541 crs = map.options.crs; 8542 8543 if (crs.distance === Earth.distance) { 8544 var d = Math.PI / 180, 8545 latR = (this._mRadius / Earth.R) / d, 8546 top = map.project([lat + latR, lng]), 8547 bottom = map.project([lat - latR, lng]), 8548 p = top.add(bottom).divideBy(2), 8549 lat2 = map.unproject(p).lat, 8550 lngR = Math.acos((Math.cos(latR * d) - Math.sin(lat * d) * Math.sin(lat2 * d)) / 8551 (Math.cos(lat * d) * Math.cos(lat2 * d))) / d; 8552 8553 if (isNaN(lngR) || lngR === 0) { 8554 lngR = latR / Math.cos(Math.PI / 180 * lat); // Fallback for edge case, #2425 8555 } 8556 8557 this._point = p.subtract(map.getPixelOrigin()); 8558 this._radius = isNaN(lngR) ? 0 : p.x - map.project([lat2, lng - lngR]).x; 8559 this._radiusY = p.y - top.y; 8560 8561 } else { 8562 var latlng2 = crs.unproject(crs.project(this._latlng).subtract([this._mRadius, 0])); 8563 8564 this._point = map.latLngToLayerPoint(this._latlng); 8565 this._radius = this._point.x - map.latLngToLayerPoint(latlng2).x; 8566 } 8567 8568 this._updateBounds(); 8569 } 8570}); 8571 8572// @factory L.circle(latlng: LatLng, options?: Circle options) 8573// Instantiates a circle object given a geographical point, and an options object 8574// which contains the circle radius. 8575// @alternative 8576// @factory L.circle(latlng: LatLng, radius: Number, options?: Circle options) 8577// Obsolete way of instantiating a circle, for compatibility with 0.7.x code. 8578// Do not use in new applications or plugins. 8579function circle(latlng, options, legacyOptions) { 8580 return new Circle(latlng, options, legacyOptions); 8581} 8582 8583/* 8584 * @class Polyline 8585 * @aka L.Polyline 8586 * @inherits Path 8587 * 8588 * A class for drawing polyline overlays on a map. Extends `Path`. 8589 * 8590 * @example 8591 * 8592 * ```js 8593 * // create a red polyline from an array of LatLng points 8594 * var latlngs = [ 8595 * [45.51, -122.68], 8596 * [37.77, -122.43], 8597 * [34.04, -118.2] 8598 * ]; 8599 * 8600 * var polyline = L.polyline(latlngs, {color: 'red'}).addTo(map); 8601 * 8602 * // zoom the map to the polyline 8603 * map.fitBounds(polyline.getBounds()); 8604 * ``` 8605 * 8606 * You can also pass a multi-dimensional array to represent a `MultiPolyline` shape: 8607 * 8608 * ```js 8609 * // create a red polyline from an array of arrays of LatLng points 8610 * var latlngs = [ 8611 * [[45.51, -122.68], 8612 * [37.77, -122.43], 8613 * [34.04, -118.2]], 8614 * [[40.78, -73.91], 8615 * [41.83, -87.62], 8616 * [32.76, -96.72]] 8617 * ]; 8618 * ``` 8619 */ 8620 8621 8622 var Polyline = Path.extend({ 8623 8624 // @section 8625 // @aka Polyline options 8626 options: { 8627 // @option smoothFactor: Number = 1.0 8628 // How much to simplify the polyline on each zoom level. More means 8629 // better performance and smoother look, and less means more accurate representation. 8630 smoothFactor: 1.0, 8631 8632 // @option noClip: Boolean = false 8633 // Disable polyline clipping. 8634 noClip: false 8635 }, 8636 8637 initialize: function (latlngs, options) { 8638 setOptions(this, options); 8639 this._setLatLngs(latlngs); 8640 }, 8641 8642 // @method getLatLngs(): LatLng[] 8643 // Returns an array of the points in the path, or nested arrays of points in case of multi-polyline. 8644 getLatLngs: function () { 8645 return this._latlngs; 8646 }, 8647 8648 // @method setLatLngs(latlngs: LatLng[]): this 8649 // Replaces all the points in the polyline with the given array of geographical points. 8650 setLatLngs: function (latlngs) { 8651 this._setLatLngs(latlngs); 8652 return this.redraw(); 8653 }, 8654 8655 // @method isEmpty(): Boolean 8656 // Returns `true` if the Polyline has no LatLngs. 8657 isEmpty: function () { 8658 return !this._latlngs.length; 8659 }, 8660 8661 // @method closestLayerPoint(p: Point): Point 8662 // Returns the point closest to `p` on the Polyline. 8663 closestLayerPoint: function (p) { 8664 var minDistance = Infinity, 8665 minPoint = null, 8666 closest = _sqClosestPointOnSegment, 8667 p1, p2; 8668 8669 for (var j = 0, jLen = this._parts.length; j < jLen; j++) { 8670 var points = this._parts[j]; 8671 8672 for (var i = 1, len = points.length; i < len; i++) { 8673 p1 = points[i - 1]; 8674 p2 = points[i]; 8675 8676 var sqDist = closest(p, p1, p2, true); 8677 8678 if (sqDist < minDistance) { 8679 minDistance = sqDist; 8680 minPoint = closest(p, p1, p2); 8681 } 8682 } 8683 } 8684 if (minPoint) { 8685 minPoint.distance = Math.sqrt(minDistance); 8686 } 8687 return minPoint; 8688}, 8689 8690 // @method getCenter(): LatLng 8691 // Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the polyline. 8692 getCenter: function () { 8693 // throws error when not yet added to map as this center calculation requires projected coordinates 8694 if (!this._map) { 8695 throw new Error('Must add layer to map before using getCenter()'); 8696 } 8697 8698 var i, halfDist, segDist, dist, p1, p2, ratio, 8699 points = this._rings[0], 8700 len = points.length; 8701 8702 if (!len) { return null; } 8703 8704 // polyline centroid algorithm; only uses the first ring if there are multiple 8705 8706 for (i = 0, halfDist = 0; i < len - 1; i++) { 8707 halfDist += points[i].distanceTo(points[i + 1]) / 2; 8708 } 8709 8710 // The line is so small in the current view that all points are on the same pixel. 8711 if (halfDist === 0) { 8712 return this._map.layerPointToLatLng(points[0]); 8713 } 8714 8715 for (i = 0, dist = 0; i < len - 1; i++) { 8716 p1 = points[i]; 8717 p2 = points[i + 1]; 8718 segDist = p1.distanceTo(p2); 8719 dist += segDist; 8720 8721 if (dist > halfDist) { 8722 ratio = (dist - halfDist) / segDist; 8723 return this._map.layerPointToLatLng([ 8724 p2.x - ratio * (p2.x - p1.x), 8725 p2.y - ratio * (p2.y - p1.y) 8726 ]); 8727 } 8728 } 8729 }, 8730 8731 // @method getBounds(): LatLngBounds 8732 // Returns the `LatLngBounds` of the path. 8733 getBounds: function () { 8734 return this._bounds; 8735 }, 8736 8737 // @method addLatLng(latlng: LatLng, latlngs? LatLng[]): this 8738 // Adds a given point to the polyline. By default, adds to the first ring of 8739 // the polyline in case of a multi-polyline, but can be overridden by passing 8740 // a specific ring as a LatLng array (that you can earlier access with [`getLatLngs`](#polyline-getlatlngs)). 8741 addLatLng: function (latlng, latlngs) { 8742 latlngs = latlngs || this._defaultShape(); 8743 latlng = toLatLng(latlng); 8744 latlngs.push(latlng); 8745 this._bounds.extend(latlng); 8746 return this.redraw(); 8747 }, 8748 8749 _setLatLngs: function (latlngs) { 8750 this._bounds = new LatLngBounds(); 8751 this._latlngs = this._convertLatLngs(latlngs); 8752 }, 8753 8754 _defaultShape: function () { 8755 return isFlat(this._latlngs) ? this._latlngs : this._latlngs[0]; 8756 }, 8757 8758 // recursively convert latlngs input into actual LatLng instances; calculate bounds along the way 8759 _convertLatLngs: function (latlngs) { 8760 var result = [], 8761 flat = isFlat(latlngs); 8762 8763 for (var i = 0, len = latlngs.length; i < len; i++) { 8764 if (flat) { 8765 result[i] = toLatLng(latlngs[i]); 8766 this._bounds.extend(result[i]); 8767 } else { 8768 result[i] = this._convertLatLngs(latlngs[i]); 8769 } 8770 } 8771 8772 return result; 8773}, 8774 8775_project: function () { 8776 var pxBounds = new Bounds(); 8777 this._rings = []; 8778 this._projectLatlngs(this._latlngs, this._rings, pxBounds); 8779 8780 if (this._bounds.isValid() && pxBounds.isValid()) { 8781 this._rawPxBounds = pxBounds; 8782 this._updateBounds(); 8783 } 8784}, 8785 8786_updateBounds: function () { 8787 var w = this._clickTolerance(), 8788 p = new Point(w, w); 8789 this._pxBounds = new Bounds([ 8790 this._rawPxBounds.min.subtract(p), 8791 this._rawPxBounds.max.add(p) 8792 ]); 8793}, 8794 8795 // recursively turns latlngs into a set of rings with projected coordinates 8796 _projectLatlngs: function (latlngs, result, projectedBounds) { 8797 var flat = latlngs[0] instanceof LatLng, 8798 len = latlngs.length, 8799 i, ring; 8800 8801 if (flat) { 8802 ring = []; 8803 for (i = 0; i < len; i++) { 8804 ring[i] = this._map.latLngToLayerPoint(latlngs[i]); 8805 projectedBounds.extend(ring[i]); 8806 } 8807 result.push(ring); 8808 } else { 8809 for (i = 0; i < len; i++) { 8810 this._projectLatlngs(latlngs[i], result, projectedBounds); 8811 } 8812} 8813}, 8814 8815 // clip polyline by renderer bounds so that we have less to render for performance 8816 _clipPoints: function () { 8817 var bounds = this._renderer._bounds; 8818 8819 this._parts = []; 8820 if (!this._pxBounds || !this._pxBounds.intersects(bounds)) { 8821 return; 8822 } 8823 8824 if (this.options.noClip) { 8825 this._parts = this._rings; 8826 return; 8827 } 8828 8829 var parts = this._parts, 8830 i, j, k, len, len2, segment, points; 8831 8832 for (i = 0, k = 0, len = this._rings.length; i < len; i++) { 8833 points = this._rings[i]; 8834 8835 for (j = 0, len2 = points.length; j < len2 - 1; j++) { 8836 segment = clipSegment(points[j], points[j + 1], bounds, j, true); 8837 8838 if (!segment) { continue; } 8839 8840 parts[k] = parts[k] || []; 8841 parts[k].push(segment[0]); 8842 8843 // if segment goes out of screen, or it's the last one, it's the end of the line part 8844 if ((segment[1] !== points[j + 1]) || (j === len2 - 2)) { 8845 parts[k].push(segment[1]); 8846 k++; 8847 } 8848 } 8849 } 8850 }, 8851 8852 // simplify each clipped part of the polyline for performance 8853 _simplifyPoints: function () { 8854 var parts = this._parts, 8855 tolerance = this.options.smoothFactor; 8856 8857 for (var i = 0, len = parts.length; i < len; i++) { 8858 parts[i] = simplify(parts[i], tolerance); 8859 } 8860 }, 8861 8862 _update: function () { 8863 if (!this._map) { return; } 8864 8865 this._clipPoints(); 8866 this._simplifyPoints(); 8867 this._updatePath(); 8868}, 8869 8870_updatePath: function () { 8871 this._renderer._updatePoly(this); 8872}, 8873 8874 // Needed by the `Canvas` renderer for interactivity 8875 _containsPoint: function (p, closed) { 8876 var i, j, k, len, len2, part, 8877 w = this._clickTolerance(); 8878 8879 if (!this._pxBounds || !this._pxBounds.contains(p)) { return false; } 8880 8881 // hit detection for polylines 8882 for (i = 0, len = this._parts.length; i < len; i++) { 8883 part = this._parts[i]; 8884 8885 for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) { 8886 if (!closed && (j === 0)) { continue; } 8887 8888 if (pointToSegmentDistance(p, part[k], part[j]) <= w) { 8889 return true; 8890 } 8891 } 8892 } 8893 return false; 8894 } 8895}); 8896 8897// @factory L.polyline(latlngs: LatLng[], options?: Polyline options) 8898// Instantiates a polyline object given an array of geographical points and 8899// optionally an options object. You can create a `Polyline` object with 8900// multiple separate lines (`MultiPolyline`) by passing an array of arrays 8901// of geographic points. 8902function polyline(latlngs, options) { 8903 return new Polyline(latlngs, options); 8904} 8905 8906// Retrocompat. Allow plugins to support Leaflet versions before and after 1.1. 8907Polyline._flat = _flat; 8908 8909/* 8910 * @class Polygon 8911 * @aka L.Polygon 8912 * @inherits Polyline 8913 * 8914 * A class for drawing polygon overlays on a map. Extends `Polyline`. 8915 * 8916 * Note that points you pass when creating a polygon shouldn't have an additional last point equal to the first one — it's better to filter out such points. 8917 * 8918 * 8919 * @example 8920 * 8921 * ```js 8922 * // create a red polygon from an array of LatLng points 8923 * var latlngs = [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]]; 8924 * 8925 * var polygon = L.polygon(latlngs, {color: 'red'}).addTo(map); 8926 * 8927 * // zoom the map to the polygon 8928 * map.fitBounds(polygon.getBounds()); 8929 * ``` 8930 * 8931 * You can also pass an array of arrays of latlngs, with the first array representing the outer shape and the other arrays representing holes in the outer shape: 8932 * 8933 * ```js 8934 * var latlngs = [ 8935 * [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring 8936 * [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole 8937 * ]; 8938 * ``` 8939 * 8940 * Additionally, you can pass a multi-dimensional array to represent a MultiPolygon shape. 8941 * 8942 * ```js 8943 * var latlngs = [ 8944 * [ // first polygon 8945 * [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring 8946 * [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole 8947 * ], 8948 * [ // second polygon 8949 * [[41, -111.03],[45, -111.04],[45, -104.05],[41, -104.05]] 8950 * ] 8951 * ]; 8952 * ``` 8953 */ 8954 8955 var Polygon = Polyline.extend({ 8956 8957 options: { 8958 fill: true 8959 }, 8960 8961 isEmpty: function () { 8962 return !this._latlngs.length || !this._latlngs[0].length; 8963 }, 8964 8965 getCenter: function () { 8966 // throws error when not yet added to map as this center calculation requires projected coordinates 8967 if (!this._map) { 8968 throw new Error('Must add layer to map before using getCenter()'); 8969 } 8970 8971 var i, j, p1, p2, f, area, x, y, center, 8972 points = this._rings[0], 8973 len = points.length; 8974 8975 if (!len) { return null; } 8976 8977 // polygon centroid algorithm; only uses the first ring if there are multiple 8978 8979 area = x = y = 0; 8980 8981 for (i = 0, j = len - 1; i < len; j = i++) { 8982 p1 = points[i]; 8983 p2 = points[j]; 8984 8985 f = p1.y * p2.x - p2.y * p1.x; 8986 x += (p1.x + p2.x) * f; 8987 y += (p1.y + p2.y) * f; 8988 area += f * 3; 8989 } 8990 8991 if (area === 0) { 8992 // Polygon is so small that all points are on same pixel. 8993 center = points[0]; 8994 } else { 8995 center = [x / area, y / area]; 8996 } 8997 return this._map.layerPointToLatLng(center); 8998 }, 8999 9000 _convertLatLngs: function (latlngs) { 9001 var result = Polyline.prototype._convertLatLngs.call(this, latlngs), 9002 len = result.length; 9003 9004 // remove last point if it equals first one 9005 if (len >= 2 && result[0] instanceof LatLng && result[0].equals(result[len - 1])) { 9006 result.pop(); 9007 } 9008 return result; 9009 }, 9010 9011 _setLatLngs: function (latlngs) { 9012 Polyline.prototype._setLatLngs.call(this, latlngs); 9013 if (isFlat(this._latlngs)) { 9014 this._latlngs = [this._latlngs]; 9015 } 9016 }, 9017 9018 _defaultShape: function () { 9019 return isFlat(this._latlngs[0]) ? this._latlngs[0] : this._latlngs[0][0]; 9020 }, 9021 9022 _clipPoints: function () { 9023 // polygons need a different clipping algorithm so we redefine that 9024 9025 var bounds = this._renderer._bounds, 9026 w = this.options.weight, 9027 p = new Point(w, w); 9028 9029 // increase clip padding by stroke width to avoid stroke on clip edges 9030 bounds = new Bounds(bounds.min.subtract(p), bounds.max.add(p)); 9031 9032 this._parts = []; 9033 if (!this._pxBounds || !this._pxBounds.intersects(bounds)) { 9034 return; 9035 } 9036 9037 if (this.options.noClip) { 9038 this._parts = this._rings; 9039 return; 9040 } 9041 9042 for (var i = 0, len = this._rings.length, clipped; i < len; i++) { 9043 clipped = clipPolygon(this._rings[i], bounds, true); 9044 if (clipped.length) { 9045 this._parts.push(clipped); 9046 } 9047 } 9048 }, 9049 9050 _updatePath: function () { 9051 this._renderer._updatePoly(this, true); 9052 }, 9053 9054 // Needed by the `Canvas` renderer for interactivity 9055 _containsPoint: function (p) { 9056 var inside = false, 9057 part, p1, p2, i, j, k, len, len2; 9058 9059 if (!this._pxBounds || !this._pxBounds.contains(p)) { return false; } 9060 9061 // ray casting algorithm for detecting if point is in polygon 9062 for (i = 0, len = this._parts.length; i < len; i++) { 9063 part = this._parts[i]; 9064 9065 for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) { 9066 p1 = part[j]; 9067 p2 = part[k]; 9068 9069 if (((p1.y > p.y) !== (p2.y > p.y)) && (p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x)) { 9070 inside = !inside; 9071 } 9072 } 9073 } 9074 9075 // also check if it's on polygon stroke 9076 return inside || Polyline.prototype._containsPoint.call(this, p, true); 9077 } 9078 9079}); 9080 9081 9082// @factory L.polygon(latlngs: LatLng[], options?: Polyline options) 9083function polygon(latlngs, options) { 9084 return new Polygon(latlngs, options); 9085} 9086 9087/* 9088 * @class GeoJSON 9089 * @aka L.GeoJSON 9090 * @inherits FeatureGroup 9091 * 9092 * Represents a GeoJSON object or an array of GeoJSON objects. Allows you to parse 9093 * GeoJSON data and display it on the map. Extends `FeatureGroup`. 9094 * 9095 * @example 9096 * 9097 * ```js 9098 * L.geoJSON(data, { 9099 * style: function (feature) { 9100 * return {color: feature.properties.color}; 9101 * } 9102 * }).bindPopup(function (layer) { 9103 * return layer.feature.properties.description; 9104 * }).addTo(map); 9105 * ``` 9106 */ 9107 9108 var GeoJSON = FeatureGroup.extend({ 9109 9110 /* @section 9111 * @aka GeoJSON options 9112 * 9113 * @option pointToLayer: Function = * 9114 * A `Function` defining how GeoJSON points spawn Leaflet layers. It is internally 9115 * called when data is added, passing the GeoJSON point feature and its `LatLng`. 9116 * The default is to spawn a default `Marker`: 9117 * ```js 9118 * function(geoJsonPoint, latlng) { 9119 * return L.marker(latlng); 9120 * } 9121 * ``` 9122 * 9123 * @option style: Function = * 9124 * A `Function` defining the `Path options` for styling GeoJSON lines and polygons, 9125 * called internally when data is added. 9126 * The default value is to not override any defaults: 9127 * ```js 9128 * function (geoJsonFeature) { 9129 * return {} 9130 * } 9131 * ``` 9132 * 9133 * @option onEachFeature: Function = * 9134 * A `Function` that will be called once for each created `Feature`, after it has 9135 * been created and styled. Useful for attaching events and popups to features. 9136 * The default is to do nothing with the newly created layers: 9137 * ```js 9138 * function (feature, layer) {} 9139 * ``` 9140 * 9141 * @option filter: Function = * 9142 * A `Function` that will be used to decide whether to include a feature or not. 9143 * The default is to include all features: 9144 * ```js 9145 * function (geoJsonFeature) { 9146 * return true; 9147 * } 9148 * ``` 9149 * Note: dynamically changing the `filter` option will have effect only on newly 9150 * added data. It will _not_ re-evaluate already included features. 9151 * 9152 * @option coordsToLatLng: Function = * 9153 * A `Function` that will be used for converting GeoJSON coordinates to `LatLng`s. 9154 * The default is the `coordsToLatLng` static method. 9155 */ 9156 9157 initialize: function (geojson, options) { 9158 setOptions(this, options); 9159 9160 this._layers = {}; 9161 9162 if (geojson) { 9163 this.addData(geojson); 9164 } 9165 }, 9166 9167 // @method addData( <GeoJSON> data ): this 9168 // Adds a GeoJSON object to the layer. 9169 addData: function (geojson) { 9170 var features = isArray(geojson) ? geojson : geojson.features, 9171 i, len, feature; 9172 9173 if (features) { 9174 for (i = 0, len = features.length; i < len; i++) { 9175 // only add this if geometry or geometries are set and not null 9176 feature = features[i]; 9177 if (feature.geometries || feature.geometry || feature.features || feature.coordinates) { 9178 this.addData(feature); 9179 } 9180 } 9181 return this; 9182 } 9183 9184 var options = this.options; 9185 9186 if (options.filter && !options.filter(geojson)) { return this; } 9187 9188 var layer = geometryToLayer(geojson, options); 9189 if (!layer) { 9190 return this; 9191 } 9192 layer.feature = asFeature(geojson); 9193 9194 layer.defaultOptions = layer.options; 9195 this.resetStyle(layer); 9196 9197 if (options.onEachFeature) { 9198 options.onEachFeature(geojson, layer); 9199 } 9200 9201 return this.addLayer(layer); 9202 }, 9203 9204 // @method resetStyle( <Path> layer ): this 9205 // Resets the given vector layer's style to the original GeoJSON style, useful for resetting style after hover events. 9206 resetStyle: function (layer) { 9207 // reset any custom styles 9208 layer.options = extend({}, layer.defaultOptions); 9209 this._setLayerStyle(layer, this.options.style); 9210 return this; 9211 }, 9212 9213 // @method setStyle( <Function> style ): this 9214 // Changes styles of GeoJSON vector layers with the given style function. 9215 setStyle: function (style) { 9216 return this.eachLayer(function (layer) { 9217 this._setLayerStyle(layer, style); 9218 }, this); 9219 }, 9220 9221 _setLayerStyle: function (layer, style) { 9222 if (layer.setStyle) { 9223 if (typeof style === 'function') { 9224 style = style(layer.feature); 9225 } 9226 layer.setStyle(style); 9227 } 9228 } 9229}); 9230 9231// @section 9232// There are several static functions which can be called without instantiating L.GeoJSON: 9233 9234// @function geometryToLayer(featureData: Object, options?: GeoJSON options): Layer 9235// Creates a `Layer` from a given GeoJSON feature. Can use a custom 9236// [`pointToLayer`](#geojson-pointtolayer) and/or [`coordsToLatLng`](#geojson-coordstolatlng) 9237// functions if provided as options. 9238function geometryToLayer(geojson, options) { 9239 9240 var geometry = geojson.type === 'Feature' ? geojson.geometry : geojson, 9241 coords = geometry ? geometry.coordinates : null, 9242 layers = [], 9243 pointToLayer = options && options.pointToLayer, 9244 _coordsToLatLng = options && options.coordsToLatLng || coordsToLatLng, 9245 latlng, latlngs, i, len; 9246 9247 if (!coords && !geometry) { 9248 return null; 9249} 9250 9251switch (geometry.type) { 9252 case 'Point': 9253 latlng = _coordsToLatLng(coords); 9254 return pointToLayer ? pointToLayer(geojson, latlng) : new Marker(latlng); 9255 9256 case 'MultiPoint': 9257 for (i = 0, len = coords.length; i < len; i++) { 9258 latlng = _coordsToLatLng(coords[i]); 9259 layers.push(pointToLayer ? pointToLayer(geojson, latlng) : new Marker(latlng)); 9260 } 9261 return new FeatureGroup(layers); 9262 9263 case 'LineString': 9264 case 'MultiLineString': 9265 latlngs = coordsToLatLngs(coords, geometry.type === 'LineString' ? 0 : 1, _coordsToLatLng); 9266 return new Polyline(latlngs, options); 9267 9268 case 'Polygon': 9269 case 'MultiPolygon': 9270 latlngs = coordsToLatLngs(coords, geometry.type === 'Polygon' ? 1 : 2, _coordsToLatLng); 9271 return new Polygon(latlngs, options); 9272 9273 case 'GeometryCollection': 9274 for (i = 0, len = geometry.geometries.length; i < len; i++) { 9275 var layer = geometryToLayer({ 9276 geometry: geometry.geometries[i], 9277 type: 'Feature', 9278 properties: geojson.properties 9279 }, options); 9280 9281 if (layer) { 9282 layers.push(layer); 9283 } 9284} 9285return new FeatureGroup(layers); 9286 9287default: 9288throw new Error('Invalid GeoJSON object.'); 9289} 9290} 9291 9292// @function coordsToLatLng(coords: Array): LatLng 9293// Creates a `LatLng` object from an array of 2 numbers (longitude, latitude) 9294// or 3 numbers (longitude, latitude, altitude) used in GeoJSON for points. 9295function coordsToLatLng(coords) { 9296 return new LatLng(coords[1], coords[0], coords[2]); 9297} 9298 9299// @function coordsToLatLngs(coords: Array, levelsDeep?: Number, coordsToLatLng?: Function): Array 9300// Creates a multidimensional array of `LatLng`s from a GeoJSON coordinates array. 9301// `levelsDeep` specifies the nesting level (0 is for an array of points, 1 for an array of arrays of points, etc., 0 by default). 9302// Can use a custom [`coordsToLatLng`](#geojson-coordstolatlng) function. 9303function coordsToLatLngs(coords, levelsDeep, _coordsToLatLng) { 9304 var latlngs = []; 9305 9306 for (var i = 0, len = coords.length, latlng; i < len; i++) { 9307 latlng = levelsDeep ? 9308 coordsToLatLngs(coords[i], levelsDeep - 1, _coordsToLatLng) : 9309 (_coordsToLatLng || coordsToLatLng)(coords[i]); 9310 9311 latlngs.push(latlng); 9312 } 9313 9314 return latlngs; 9315} 9316 9317// @function latLngToCoords(latlng: LatLng, precision?: Number): Array 9318// Reverse of [`coordsToLatLng`](#geojson-coordstolatlng) 9319function latLngToCoords(latlng, precision) { 9320 precision = typeof precision === 'number' ? precision : 6; 9321 return latlng.alt !== undefined ? 9322 [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision), formatNum(latlng.alt, precision)] : 9323 [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision)]; 9324} 9325 9326// @function latLngsToCoords(latlngs: Array, levelsDeep?: Number, closed?: Boolean): Array 9327// Reverse of [`coordsToLatLngs`](#geojson-coordstolatlngs) 9328// `closed` determines whether the first point should be appended to the end of the array to close the feature, only used when `levelsDeep` is 0. False by default. 9329function latLngsToCoords(latlngs, levelsDeep, closed, precision) { 9330 var coords = []; 9331 9332 for (var i = 0, len = latlngs.length; i < len; i++) { 9333 coords.push(levelsDeep ? 9334 latLngsToCoords(latlngs[i], levelsDeep - 1, closed, precision) : 9335 latLngToCoords(latlngs[i], precision)); 9336 } 9337 9338 if (!levelsDeep && closed) { 9339 coords.push(coords[0]); 9340 } 9341 9342 return coords; 9343} 9344 9345function getFeature(layer, newGeometry) { 9346 return layer.feature ? 9347 extend({}, layer.feature, {geometry: newGeometry}) : 9348 asFeature(newGeometry); 9349} 9350 9351// @function asFeature(geojson: Object): Object 9352// Normalize GeoJSON geometries/features into GeoJSON features. 9353function asFeature(geojson) { 9354 if (geojson.type === 'Feature' || geojson.type === 'FeatureCollection') { 9355 return geojson; 9356 } 9357 9358 return { 9359 type: 'Feature', 9360 properties: {}, 9361 geometry: geojson 9362 }; 9363} 9364 9365var PointToGeoJSON = { 9366 toGeoJSON: function (precision) { 9367 return getFeature(this, { 9368 type: 'Point', 9369 coordinates: latLngToCoords(this.getLatLng(), precision) 9370 }); 9371 } 9372}; 9373 9374// @namespace Marker 9375// @method toGeoJSON(precision?: Number): Object 9376// `precision` is the number of decimal places for coordinates. 9377// The default value is 6 places. 9378// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the marker (as a GeoJSON `Point` Feature). 9379Marker.include(PointToGeoJSON); 9380 9381// @namespace CircleMarker 9382// @method toGeoJSON(precision?: Number): Object 9383// `precision` is the number of decimal places for coordinates. 9384// The default value is 6 places. 9385// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the circle marker (as a GeoJSON `Point` Feature). 9386Circle.include(PointToGeoJSON); 9387CircleMarker.include(PointToGeoJSON); 9388 9389 9390// @namespace Polyline 9391// @method toGeoJSON(precision?: Number): Object 9392// `precision` is the number of decimal places for coordinates. 9393// The default value is 6 places. 9394// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the polyline (as a GeoJSON `LineString` or `MultiLineString` Feature). 9395Polyline.include({ 9396 toGeoJSON: function (precision) { 9397 var multi = !isFlat(this._latlngs); 9398 9399 var coords = latLngsToCoords(this._latlngs, multi ? 1 : 0, false, precision); 9400 9401 return getFeature(this, { 9402 type: (multi ? 'Multi' : '') + 'LineString', 9403 coordinates: coords 9404 }); 9405 } 9406}); 9407 9408// @namespace Polygon 9409// @method toGeoJSON(precision?: Number): Object 9410// `precision` is the number of decimal places for coordinates. 9411// The default value is 6 places. 9412// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the polygon (as a GeoJSON `Polygon` or `MultiPolygon` Feature). 9413Polygon.include({ 9414 toGeoJSON: function (precision) { 9415 var holes = !isFlat(this._latlngs), 9416 multi = holes && !isFlat(this._latlngs[0]); 9417 9418 var coords = latLngsToCoords(this._latlngs, multi ? 2 : holes ? 1 : 0, true, precision); 9419 9420 if (!holes) { 9421 coords = [coords]; 9422 } 9423 9424 return getFeature(this, { 9425 type: (multi ? 'Multi' : '') + 'Polygon', 9426 coordinates: coords 9427 }); 9428 } 9429}); 9430 9431 9432// @namespace LayerGroup 9433LayerGroup.include({ 9434 toMultiPoint: function (precision) { 9435 var coords = []; 9436 9437 this.eachLayer(function (layer) { 9438 coords.push(layer.toGeoJSON(precision).geometry.coordinates); 9439 }); 9440 9441 return getFeature(this, { 9442 type: 'MultiPoint', 9443 coordinates: coords 9444 }); 9445 }, 9446 9447 // @method toGeoJSON(precision?: Number): Object 9448 // `precision` is the number of decimal places for coordinates. 9449 // The default value is 6 places. 9450 // Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the layer group (as a GeoJSON `FeatureCollection`, `GeometryCollection`, or `MultiPoint`). 9451 toGeoJSON: function (precision) { 9452 9453 var type = this.feature && this.feature.geometry && this.feature.geometry.type; 9454 9455 if (type === 'MultiPoint') { 9456 return this.toMultiPoint(precision); 9457 } 9458 9459 var isGeometryCollection = type === 'GeometryCollection', 9460 jsons = []; 9461 9462 this.eachLayer(function (layer) { 9463 if (layer.toGeoJSON) { 9464 var json = layer.toGeoJSON(precision); 9465 if (isGeometryCollection) { 9466 jsons.push(json.geometry); 9467 } else { 9468 var feature = asFeature(json); 9469 // Squash nested feature collections 9470 if (feature.type === 'FeatureCollection') { 9471 jsons.push.apply(jsons, feature.features); 9472 } else { 9473 jsons.push(feature); 9474 } 9475 } 9476 } 9477 }); 9478 9479 if (isGeometryCollection) { 9480 return getFeature(this, { 9481 geometries: jsons, 9482 type: 'GeometryCollection' 9483 }); 9484 } 9485 9486 return { 9487 type: 'FeatureCollection', 9488 features: jsons 9489 }; 9490 } 9491}); 9492 9493// @namespace GeoJSON 9494// @factory L.geoJSON(geojson?: Object, options?: GeoJSON options) 9495// Creates a GeoJSON layer. Optionally accepts an object in 9496// [GeoJSON format](https://tools.ietf.org/html/rfc7946) to display on the map 9497// (you can alternatively add it later with `addData` method) and an `options` object. 9498function geoJSON(geojson, options) { 9499 return new GeoJSON(geojson, options); 9500} 9501 9502// Backward compatibility. 9503var geoJson = geoJSON; 9504 9505/* 9506 * @class ImageOverlay 9507 * @aka L.ImageOverlay 9508 * @inherits Interactive layer 9509 * 9510 * Used to load and display a single image over specific bounds of the map. Extends `Layer`. 9511 * 9512 * @example 9513 * 9514 * ```js 9515 * var imageUrl = 'http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg', 9516 * imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]]; 9517 * L.imageOverlay(imageUrl, imageBounds).addTo(map); 9518 * ``` 9519 */ 9520 9521 var ImageOverlay = Layer.extend({ 9522 9523 // @section 9524 // @aka ImageOverlay options 9525 options: { 9526 // @option opacity: Number = 1.0 9527 // The opacity of the image overlay. 9528 opacity: 1, 9529 9530 // @option alt: String = '' 9531 // Text for the `alt` attribute of the image (useful for accessibility). 9532 alt: '', 9533 9534 // @option interactive: Boolean = false 9535 // If `true`, the image overlay will emit [mouse events](#interactive-layer) when clicked or hovered. 9536 interactive: false, 9537 9538 // @option crossOrigin: Boolean|String = false 9539 // Whether the crossOrigin attribute will be added to the image. 9540 // If a String is provided, the image will have its crossOrigin attribute set to the String provided. This is needed if you want to access image pixel data. 9541 // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values. 9542 crossOrigin: false, 9543 9544 // @option errorOverlayUrl: String = '' 9545 // URL to the overlay image to show in place of the overlay that failed to load. 9546 errorOverlayUrl: '', 9547 9548 // @option zIndex: Number = 1 9549 // The explicit [zIndex](https://developer.mozilla.org/docs/Web/CSS/CSS_Positioning/Understanding_z_index) of the overlay layer. 9550 zIndex: 1, 9551 9552 // @option className: String = '' 9553 // A custom class name to assign to the image. Empty by default. 9554 className: '' 9555 }, 9556 9557 initialize: function (url, bounds, options) { // (String, LatLngBounds, Object) 9558 this._url = url; 9559 this._bounds = toLatLngBounds(bounds); 9560 9561 setOptions(this, options); 9562 }, 9563 9564 onAdd: function () { 9565 if (!this._image) { 9566 this._initImage(); 9567 9568 if (this.options.opacity < 1) { 9569 this._updateOpacity(); 9570 } 9571 } 9572 9573 if (this.options.interactive) { 9574 addClass(this._image, 'leaflet-interactive'); 9575 this.addInteractiveTarget(this._image); 9576 } 9577 9578 this.getPane().appendChild(this._image); 9579 this._reset(); 9580 }, 9581 9582 onRemove: function () { 9583 remove(this._image); 9584 if (this.options.interactive) { 9585 this.removeInteractiveTarget(this._image); 9586 } 9587 }, 9588 9589 // @method setOpacity(opacity: Number): this 9590 // Sets the opacity of the overlay. 9591 setOpacity: function (opacity) { 9592 this.options.opacity = opacity; 9593 9594 if (this._image) { 9595 this._updateOpacity(); 9596 } 9597 return this; 9598 }, 9599 9600 setStyle: function (styleOpts) { 9601 if (styleOpts.opacity) { 9602 this.setOpacity(styleOpts.opacity); 9603 } 9604 return this; 9605 }, 9606 9607 // @method bringToFront(): this 9608 // Brings the layer to the top of all overlays. 9609 bringToFront: function () { 9610 if (this._map) { 9611 toFront(this._image); 9612 } 9613 return this; 9614 }, 9615 9616 // @method bringToBack(): this 9617 // Brings the layer to the bottom of all overlays. 9618 bringToBack: function () { 9619 if (this._map) { 9620 toBack(this._image); 9621 } 9622 return this; 9623 }, 9624 9625 // @method setUrl(url: String): this 9626 // Changes the URL of the image. 9627 setUrl: function (url) { 9628 this._url = url; 9629 9630 if (this._image) { 9631 this._image.src = url; 9632 } 9633 return this; 9634 }, 9635 9636 // @method setBounds(bounds: LatLngBounds): this 9637 // Update the bounds that this ImageOverlay covers 9638 setBounds: function (bounds) { 9639 this._bounds = toLatLngBounds(bounds); 9640 9641 if (this._map) { 9642 this._reset(); 9643 } 9644 return this; 9645 }, 9646 9647 getEvents: function () { 9648 var events = { 9649 zoom: this._reset, 9650 viewreset: this._reset 9651 }; 9652 9653 if (this._zoomAnimated) { 9654 events.zoomanim = this._animateZoom; 9655 } 9656 9657 return events; 9658 }, 9659 9660 // @method setZIndex(value: Number): this 9661 // Changes the [zIndex](#imageoverlay-zindex) of the image overlay. 9662 setZIndex: function (value) { 9663 this.options.zIndex = value; 9664 this._updateZIndex(); 9665 return this; 9666 }, 9667 9668 // @method getBounds(): LatLngBounds 9669 // Get the bounds that this ImageOverlay covers 9670 getBounds: function () { 9671 return this._bounds; 9672 }, 9673 9674 // @method getElement(): HTMLElement 9675 // Returns the instance of [`HTMLImageElement`](https://developer.mozilla.org/docs/Web/API/HTMLImageElement) 9676 // used by this overlay. 9677 getElement: function () { 9678 return this._image; 9679 }, 9680 9681 _initImage: function () { 9682 var wasElementSupplied = this._url.tagName === 'IMG'; 9683 var img = this._image = wasElementSupplied ? this._url : create$1('img'); 9684 9685 addClass(img, 'leaflet-image-layer'); 9686 if (this._zoomAnimated) { addClass(img, 'leaflet-zoom-animated'); } 9687 if (this.options.className) { addClass(img, this.options.className); } 9688 9689 img.onselectstart = falseFn; 9690 img.onmousemove = falseFn; 9691 9692 // @event load: Event 9693 // Fired when the ImageOverlay layer has loaded its image 9694 img.onload = bind(this.fire, this, 'load'); 9695 img.onerror = bind(this._overlayOnError, this, 'error'); 9696 9697 if (this.options.crossOrigin || this.options.crossOrigin === '') { 9698 img.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin; 9699 } 9700 9701 if (this.options.zIndex) { 9702 this._updateZIndex(); 9703 } 9704 9705 if (wasElementSupplied) { 9706 this._url = img.src; 9707 return; 9708 } 9709 9710 img.src = this._url; 9711 img.alt = this.options.alt; 9712 }, 9713 9714 _animateZoom: function (e) { 9715 var scale = this._map.getZoomScale(e.zoom), 9716 offset = this._map._latLngBoundsToNewLayerBounds(this._bounds, e.zoom, e.center).min; 9717 9718 setTransform(this._image, offset, scale); 9719 }, 9720 9721 _reset: function () { 9722 var image = this._image, 9723 bounds = new Bounds( 9724 this._map.latLngToLayerPoint(this._bounds.getNorthWest()), 9725 this._map.latLngToLayerPoint(this._bounds.getSouthEast())), 9726 size = bounds.getSize(); 9727 9728 setPosition(image, bounds.min); 9729 9730 image.style.width = size.x + 'px'; 9731 image.style.height = size.y + 'px'; 9732 }, 9733 9734 _updateOpacity: function () { 9735 setOpacity(this._image, this.options.opacity); 9736 }, 9737 9738 _updateZIndex: function () { 9739 if (this._image && this.options.zIndex !== undefined && this.options.zIndex !== null) { 9740 this._image.style.zIndex = this.options.zIndex; 9741 } 9742 }, 9743 9744 _overlayOnError: function () { 9745 // @event error: Event 9746 // Fired when the ImageOverlay layer fails to load its image 9747 this.fire('error'); 9748 9749 var errorUrl = this.options.errorOverlayUrl; 9750 if (errorUrl && this._url !== errorUrl) { 9751 this._url = errorUrl; 9752 this._image.src = errorUrl; 9753 } 9754 } 9755}); 9756 9757// @factory L.imageOverlay(imageUrl: String, bounds: LatLngBounds, options?: ImageOverlay options) 9758// Instantiates an image overlay object given the URL of the image and the 9759// geographical bounds it is tied to. 9760var imageOverlay = function (url, bounds, options) { 9761 return new ImageOverlay(url, bounds, options); 9762}; 9763 9764/* 9765 * @class VideoOverlay 9766 * @aka L.VideoOverlay 9767 * @inherits ImageOverlay 9768 * 9769 * Used to load and display a video player over specific bounds of the map. Extends `ImageOverlay`. 9770 * 9771 * A video overlay uses the [`<video>`](https://developer.mozilla.org/docs/Web/HTML/Element/video) 9772 * HTML5 element. 9773 * 9774 * @example 9775 * 9776 * ```js 9777 * var videoUrl = 'https://www.mapbox.com/bites/00188/patricia_nasa.webm', 9778 * videoBounds = [[ 32, -130], [ 13, -100]]; 9779 * L.videoOverlay(videoUrl, videoBounds ).addTo(map); 9780 * ``` 9781 */ 9782 9783 var VideoOverlay = ImageOverlay.extend({ 9784 9785 // @section 9786 // @aka VideoOverlay options 9787 options: { 9788 // @option autoplay: Boolean = true 9789 // Whether the video starts playing automatically when loaded. 9790 autoplay: true, 9791 9792 // @option loop: Boolean = true 9793 // Whether the video will loop back to the beginning when played. 9794 loop: true, 9795 9796 // @option keepAspectRatio: Boolean = true 9797 // Whether the video will save aspect ratio after the projection. 9798 // Relevant for supported browsers. Browser compatibility- https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit 9799 keepAspectRatio: true 9800 }, 9801 9802 _initImage: function () { 9803 var wasElementSupplied = this._url.tagName === 'VIDEO'; 9804 var vid = this._image = wasElementSupplied ? this._url : create$1('video'); 9805 9806 addClass(vid, 'leaflet-image-layer'); 9807 if (this._zoomAnimated) { addClass(vid, 'leaflet-zoom-animated'); } 9808 9809 vid.onselectstart = falseFn; 9810 vid.onmousemove = falseFn; 9811 9812 // @event load: Event 9813 // Fired when the video has finished loading the first frame 9814 vid.onloadeddata = bind(this.fire, this, 'load'); 9815 9816 if (wasElementSupplied) { 9817 var sourceElements = vid.getElementsByTagName('source'); 9818 var sources = []; 9819 for (var j = 0; j < sourceElements.length; j++) { 9820 sources.push(sourceElements[j].src); 9821 } 9822 9823 this._url = (sourceElements.length > 0) ? sources : [vid.src]; 9824 return; 9825 } 9826 9827 if (!isArray(this._url)) { this._url = [this._url]; } 9828 9829 if (!this.options.keepAspectRatio && vid.style.hasOwnProperty('objectFit')) { vid.style['objectFit'] = 'fill'; } 9830 vid.autoplay = !!this.options.autoplay; 9831 vid.loop = !!this.options.loop; 9832 for (var i = 0; i < this._url.length; i++) { 9833 var source = create$1('source'); 9834 source.src = this._url[i]; 9835 vid.appendChild(source); 9836 } 9837 } 9838 9839 // @method getElement(): HTMLVideoElement 9840 // Returns the instance of [`HTMLVideoElement`](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement) 9841 // used by this overlay. 9842}); 9843 9844 9845// @factory L.videoOverlay(video: String|Array|HTMLVideoElement, bounds: LatLngBounds, options?: VideoOverlay options) 9846// Instantiates an image overlay object given the URL of the video (or array of URLs, or even a video element) and the 9847// geographical bounds it is tied to. 9848 9849function videoOverlay(video, bounds, options) { 9850 return new VideoOverlay(video, bounds, options); 9851} 9852 9853/* 9854 * @class SVGOverlay 9855 * @aka L.SVGOverlay 9856 * @inherits ImageOverlay 9857 * 9858 * Used to load, display and provide DOM access to an SVG file over specific bounds of the map. Extends `ImageOverlay`. 9859 * 9860 * An SVG overlay uses the [`<svg>`](https://developer.mozilla.org/docs/Web/SVG/Element/svg) element. 9861 * 9862 * @example 9863 * 9864 * ```js 9865 * var element = '<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png" height="200" width="200"/></svg>', 9866 * elementBounds = [ [ 32, -130 ], [ 13, -100 ] ]; 9867 * L.svgOverlay(element, elementBounds).addTo(map); 9868 * ``` 9869 */ 9870 9871 var SVGOverlay = ImageOverlay.extend({ 9872 _initImage: function () { 9873 var el = this._image = this._url; 9874 9875 addClass(el, 'leaflet-image-layer'); 9876 if (this._zoomAnimated) { addClass(el, 'leaflet-zoom-animated'); } 9877 9878 el.onselectstart = falseFn; 9879 el.onmousemove = falseFn; 9880 } 9881 9882 // @method getElement(): SVGElement 9883 // Returns the instance of [`SVGElement`](https://developer.mozilla.org/docs/Web/API/SVGElement) 9884 // used by this overlay. 9885}); 9886 9887 9888// @factory L.svgOverlay(svg: String|SVGElement, bounds: LatLngBounds, options?: SVGOverlay options) 9889// Instantiates an image overlay object given an SVG element and the geographical bounds it is tied to. 9890// A viewBox attribute is required on the SVG element to zoom in and out properly. 9891 9892function svgOverlay(el, bounds, options) { 9893 return new SVGOverlay(el, bounds, options); 9894} 9895 9896/* 9897 * @class DivOverlay 9898 * @inherits Layer 9899 * @aka L.DivOverlay 9900 * Base model for L.Popup and L.Tooltip. Inherit from it for custom popup like plugins. 9901 */ 9902 9903// @namespace DivOverlay 9904var DivOverlay = Layer.extend({ 9905 9906 // @section 9907 // @aka DivOverlay options 9908 options: { 9909 // @option offset: Point = Point(0, 7) 9910 // The offset of the popup position. Useful to control the anchor 9911 // of the popup when opening it on some overlays. 9912 offset: [0, 7], 9913 9914 // @option className: String = '' 9915 // A custom CSS class name to assign to the popup. 9916 className: '', 9917 9918 // @option pane: String = 'popupPane' 9919 // `Map pane` where the popup will be added. 9920 pane: 'popupPane' 9921 }, 9922 9923 initialize: function (options, source) { 9924 setOptions(this, options); 9925 9926 this._source = source; 9927 }, 9928 9929 onAdd: function (map) { 9930 this._zoomAnimated = map._zoomAnimated; 9931 9932 if (!this._container) { 9933 this._initLayout(); 9934 } 9935 9936 if (map._fadeAnimated) { 9937 setOpacity(this._container, 0); 9938 } 9939 9940 clearTimeout(this._removeTimeout); 9941 this.getPane().appendChild(this._container); 9942 this.update(); 9943 9944 if (map._fadeAnimated) { 9945 setOpacity(this._container, 1); 9946 } 9947 9948 this.bringToFront(); 9949 }, 9950 9951 onRemove: function (map) { 9952 if (map._fadeAnimated) { 9953 setOpacity(this._container, 0); 9954 this._removeTimeout = setTimeout(bind(remove, undefined, this._container), 200); 9955 } else { 9956 remove(this._container); 9957 } 9958 }, 9959 9960 // @namespace Popup 9961 // @method getLatLng: LatLng 9962 // Returns the geographical point of popup. 9963 getLatLng: function () { 9964 return this._latlng; 9965 }, 9966 9967 // @method setLatLng(latlng: LatLng): this 9968 // Sets the geographical point where the popup will open. 9969 setLatLng: function (latlng) { 9970 this._latlng = toLatLng(latlng); 9971 if (this._map) { 9972 this._updatePosition(); 9973 this._adjustPan(); 9974 } 9975 return this; 9976 }, 9977 9978 // @method getContent: String|HTMLElement 9979 // Returns the content of the popup. 9980 getContent: function () { 9981 return this._content; 9982 }, 9983 9984 // @method setContent(htmlContent: String|HTMLElement|Function): this 9985 // Sets the HTML content of the popup. If a function is passed the source layer will be passed to the function. The function should return a `String` or `HTMLElement` to be used in the popup. 9986 setContent: function (content) { 9987 this._content = content; 9988 this.update(); 9989 return this; 9990 }, 9991 9992 // @method getElement: String|HTMLElement 9993 // Alias for [getContent()](#popup-getcontent) 9994 getElement: function () { 9995 return this._container; 9996 }, 9997 9998 // @method update: null 9999 // Updates the popup content, layout and position. Useful for updating the popup after something inside changed, e.g. image loaded. 10000 update: function () { 10001 if (!this._map) { return; } 10002 10003 this._container.style.visibility = 'hidden'; 10004 10005 this._updateContent(); 10006 this._updateLayout(); 10007 this._updatePosition(); 10008 10009 this._container.style.visibility = ''; 10010 10011 this._adjustPan(); 10012 }, 10013 10014 getEvents: function () { 10015 var events = { 10016 zoom: this._updatePosition, 10017 viewreset: this._updatePosition 10018 }; 10019 10020 if (this._zoomAnimated) { 10021 events.zoomanim = this._animateZoom; 10022 } 10023 return events; 10024 }, 10025 10026 // @method isOpen: Boolean 10027 // Returns `true` when the popup is visible on the map. 10028 isOpen: function () { 10029 return !!this._map && this._map.hasLayer(this); 10030 }, 10031 10032 // @method bringToFront: this 10033 // Brings this popup in front of other popups (in the same map pane). 10034 bringToFront: function () { 10035 if (this._map) { 10036 toFront(this._container); 10037 } 10038 return this; 10039 }, 10040 10041 // @method bringToBack: this 10042 // Brings this popup to the back of other popups (in the same map pane). 10043 bringToBack: function () { 10044 if (this._map) { 10045 toBack(this._container); 10046 } 10047 return this; 10048 }, 10049 10050 _prepareOpen: function (parent, layer, latlng) { 10051 if (!(layer instanceof Layer)) { 10052 latlng = layer; 10053 layer = parent; 10054 } 10055 10056 if (layer instanceof FeatureGroup) { 10057 for (var id in parent._layers) { 10058 layer = parent._layers[id]; 10059 break; 10060 } 10061 } 10062 10063 if (!latlng) { 10064 if (layer.getCenter) { 10065 latlng = layer.getCenter(); 10066 } else if (layer.getLatLng) { 10067 latlng = layer.getLatLng(); 10068 } else { 10069 throw new Error('Unable to get source layer LatLng.'); 10070 } 10071 } 10072 10073 // set overlay source to this layer 10074 this._source = layer; 10075 10076 // update the overlay (content, layout, ect...) 10077 this.update(); 10078 10079 return latlng; 10080 }, 10081 10082 _updateContent: function () { 10083 if (!this._content) { return; } 10084 10085 var node = this._contentNode; 10086 var content = (typeof this._content === 'function') ? this._content(this._source || this) : this._content; 10087 10088 if (typeof content === 'string') { 10089 node.innerHTML = content; 10090 } else { 10091 while (node.hasChildNodes()) { 10092 node.removeChild(node.firstChild); 10093 } 10094 node.appendChild(content); 10095 } 10096 this.fire('contentupdate'); 10097 }, 10098 10099 _updatePosition: function () { 10100 if (!this._map) { return; } 10101 10102 var pos = this._map.latLngToLayerPoint(this._latlng), 10103 offset = toPoint(this.options.offset), 10104 anchor = this._getAnchor(); 10105 10106 if (this._zoomAnimated) { 10107 setPosition(this._container, pos.add(anchor)); 10108 } else { 10109 offset = offset.add(pos).add(anchor); 10110 } 10111 10112 var bottom = this._containerBottom = -offset.y, 10113 left = this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x; 10114 10115 // bottom position the popup in case the height of the popup changes (images loading etc) 10116 this._container.style.bottom = bottom + 'px'; 10117 this._container.style.left = left + 'px'; 10118 }, 10119 10120 _getAnchor: function () { 10121 return [0, 0]; 10122 } 10123 10124}); 10125 10126/* 10127 * @class Popup 10128 * @inherits DivOverlay 10129 * @aka L.Popup 10130 * Used to open popups in certain places of the map. Use [Map.openPopup](#map-openpopup) to 10131 * open popups while making sure that only one popup is open at one time 10132 * (recommended for usability), or use [Map.addLayer](#map-addlayer) to open as many as you want. 10133 * 10134 * @example 10135 * 10136 * If you want to just bind a popup to marker click and then open it, it's really easy: 10137 * 10138 * ```js 10139 * marker.bindPopup(popupContent).openPopup(); 10140 * ``` 10141 * Path overlays like polylines also have a `bindPopup` method. 10142 * Here's a more complicated way to open a popup on a map: 10143 * 10144 * ```js 10145 * var popup = L.popup() 10146 * .setLatLng(latlng) 10147 * .setContent('<p>Hello world!<br />This is a nice popup.</p>') 10148 * .openOn(map); 10149 * ``` 10150 */ 10151 10152 10153// @namespace Popup 10154var Popup = DivOverlay.extend({ 10155 10156 // @section 10157 // @aka Popup options 10158 options: { 10159 // @option maxWidth: Number = 300 10160 // Max width of the popup, in pixels. 10161 maxWidth: 300, 10162 10163 // @option minWidth: Number = 50 10164 // Min width of the popup, in pixels. 10165 minWidth: 50, 10166 10167 // @option maxHeight: Number = null 10168 // If set, creates a scrollable container of the given height 10169 // inside a popup if its content exceeds it. 10170 maxHeight: null, 10171 10172 // @option autoPan: Boolean = true 10173 // Set it to `false` if you don't want the map to do panning animation 10174 // to fit the opened popup. 10175 autoPan: true, 10176 10177 // @option autoPanPaddingTopLeft: Point = null 10178 // The margin between the popup and the top left corner of the map 10179 // view after autopanning was performed. 10180 autoPanPaddingTopLeft: null, 10181 10182 // @option autoPanPaddingBottomRight: Point = null 10183 // The margin between the popup and the bottom right corner of the map 10184 // view after autopanning was performed. 10185 autoPanPaddingBottomRight: null, 10186 10187 // @option autoPanPadding: Point = Point(5, 5) 10188 // Equivalent of setting both top left and bottom right autopan padding to the same value. 10189 autoPanPadding: [5, 5], 10190 10191 // @option keepInView: Boolean = false 10192 // Set it to `true` if you want to prevent users from panning the popup 10193 // off of the screen while it is open. 10194 keepInView: false, 10195 10196 // @option closeButton: Boolean = true 10197 // Controls the presence of a close button in the popup. 10198 closeButton: true, 10199 10200 // @option autoClose: Boolean = true 10201 // Set it to `false` if you want to override the default behavior of 10202 // the popup closing when another popup is opened. 10203 autoClose: true, 10204 10205 // @option closeOnEscapeKey: Boolean = true 10206 // Set it to `false` if you want to override the default behavior of 10207 // the ESC key for closing of the popup. 10208 closeOnEscapeKey: true, 10209 10210 // @option closeOnClick: Boolean = * 10211 // Set it if you want to override the default behavior of the popup closing when user clicks 10212 // on the map. Defaults to the map's [`closePopupOnClick`](#map-closepopuponclick) option. 10213 10214 // @option className: String = '' 10215 // A custom CSS class name to assign to the popup. 10216 className: '' 10217 }, 10218 10219 // @namespace Popup 10220 // @method openOn(map: Map): this 10221 // Adds the popup to the map and closes the previous one. The same as `map.openPopup(popup)`. 10222 openOn: function (map) { 10223 map.openPopup(this); 10224 return this; 10225 }, 10226 10227 onAdd: function (map) { 10228 DivOverlay.prototype.onAdd.call(this, map); 10229 10230 // @namespace Map 10231 // @section Popup events 10232 // @event popupopen: PopupEvent 10233 // Fired when a popup is opened in the map 10234 map.fire('popupopen', {popup: this}); 10235 10236 if (this._source) { 10237 // @namespace Layer 10238 // @section Popup events 10239 // @event popupopen: PopupEvent 10240 // Fired when a popup bound to this layer is opened 10241 this._source.fire('popupopen', {popup: this}, true); 10242 // For non-path layers, we toggle the popup when clicking 10243 // again the layer, so prevent the map to reopen it. 10244 if (!(this._source instanceof Path)) { 10245 this._source.on('preclick', stopPropagation); 10246 } 10247 } 10248 }, 10249 10250 onRemove: function (map) { 10251 DivOverlay.prototype.onRemove.call(this, map); 10252 10253 // @namespace Map 10254 // @section Popup events 10255 // @event popupclose: PopupEvent 10256 // Fired when a popup in the map is closed 10257 map.fire('popupclose', {popup: this}); 10258 10259 if (this._source) { 10260 // @namespace Layer 10261 // @section Popup events 10262 // @event popupclose: PopupEvent 10263 // Fired when a popup bound to this layer is closed 10264 this._source.fire('popupclose', {popup: this}, true); 10265 if (!(this._source instanceof Path)) { 10266 this._source.off('preclick', stopPropagation); 10267 } 10268 } 10269 }, 10270 10271 getEvents: function () { 10272 var events = DivOverlay.prototype.getEvents.call(this); 10273 10274 if (this.options.closeOnClick !== undefined ? this.options.closeOnClick : this._map.options.closePopupOnClick) { 10275 events.preclick = this._close; 10276 } 10277 10278 if (this.options.keepInView) { 10279 events.moveend = this._adjustPan; 10280 } 10281 10282 return events; 10283 }, 10284 10285 _close: function () { 10286 if (this._map) { 10287 this._map.closePopup(this); 10288 } 10289 }, 10290 10291 _initLayout: function () { 10292 var prefix = 'leaflet-popup', 10293 container = this._container = create$1('div', 10294 prefix + ' ' + (this.options.className || '') + 10295 ' leaflet-zoom-animated'); 10296 10297 var wrapper = this._wrapper = create$1('div', prefix + '-content-wrapper', container); 10298 this._contentNode = create$1('div', prefix + '-content', wrapper); 10299 10300 disableClickPropagation(wrapper); 10301 disableScrollPropagation(this._contentNode); 10302 on(wrapper, 'contextmenu', stopPropagation); 10303 10304 this._tipContainer = create$1('div', prefix + '-tip-container', container); 10305 this._tip = create$1('div', prefix + '-tip', this._tipContainer); 10306 10307 if (this.options.closeButton) { 10308 var closeButton = this._closeButton = create$1('a', prefix + '-close-button', container); 10309 closeButton.href = '#close'; 10310 closeButton.innerHTML = '×'; 10311 10312 on(closeButton, 'click', this._onCloseButtonClick, this); 10313 } 10314 }, 10315 10316 _updateLayout: function () { 10317 var container = this._contentNode, 10318 style = container.style; 10319 10320 style.width = ''; 10321 style.whiteSpace = 'nowrap'; 10322 10323 var width = container.offsetWidth; 10324 width = Math.min(width, this.options.maxWidth); 10325 width = Math.max(width, this.options.minWidth); 10326 10327 style.width = (width + 1) + 'px'; 10328 style.whiteSpace = ''; 10329 10330 style.height = ''; 10331 10332 var height = container.offsetHeight, 10333 maxHeight = this.options.maxHeight, 10334 scrolledClass = 'leaflet-popup-scrolled'; 10335 10336 if (maxHeight && height > maxHeight) { 10337 style.height = maxHeight + 'px'; 10338 addClass(container, scrolledClass); 10339 } else { 10340 removeClass(container, scrolledClass); 10341 } 10342 10343 this._containerWidth = this._container.offsetWidth; 10344}, 10345 10346_animateZoom: function (e) { 10347 var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center), 10348 anchor = this._getAnchor(); 10349 setPosition(this._container, pos.add(anchor)); 10350}, 10351 10352_adjustPan: function () { 10353 if (!this.options.autoPan) { return; } 10354 if (this._map._panAnim) { this._map._panAnim.stop(); } 10355 10356 var map = this._map, 10357 marginBottom = parseInt(getStyle(this._container, 'marginBottom'), 10) || 0, 10358 containerHeight = this._container.offsetHeight + marginBottom, 10359 containerWidth = this._containerWidth, 10360 layerPos = new Point(this._containerLeft, -containerHeight - this._containerBottom); 10361 10362 layerPos._add(getPosition(this._container)); 10363 10364 var containerPos = map.layerPointToContainerPoint(layerPos), 10365 padding = toPoint(this.options.autoPanPadding), 10366 paddingTL = toPoint(this.options.autoPanPaddingTopLeft || padding), 10367 paddingBR = toPoint(this.options.autoPanPaddingBottomRight || padding), 10368 size = map.getSize(), 10369 dx = 0, 10370 dy = 0; 10371 10372 if (containerPos.x + containerWidth + paddingBR.x > size.x) { // right 10373 dx = containerPos.x + containerWidth - size.x + paddingBR.x; 10374 } 10375 if (containerPos.x - dx - paddingTL.x < 0) { // left 10376 dx = containerPos.x - paddingTL.x; 10377 } 10378 if (containerPos.y + containerHeight + paddingBR.y > size.y) { // bottom 10379 dy = containerPos.y + containerHeight - size.y + paddingBR.y; 10380 } 10381 if (containerPos.y - dy - paddingTL.y < 0) { // top 10382 dy = containerPos.y - paddingTL.y; 10383 } 10384 10385 // @namespace Map 10386 // @section Popup events 10387 // @event autopanstart: Event 10388 // Fired when the map starts autopanning when opening a popup. 10389 if (dx || dy) { 10390 map 10391 .fire('autopanstart') 10392 .panBy([dx, dy]); 10393 } 10394 }, 10395 10396 _onCloseButtonClick: function (e) { 10397 this._close(); 10398 stop(e); 10399}, 10400 10401_getAnchor: function () { 10402 // Where should we anchor the popup on the source layer? 10403 return toPoint(this._source && this._source._getPopupAnchor ? this._source._getPopupAnchor() : [0, 0]); 10404 } 10405 10406}); 10407 10408// @namespace Popup 10409// @factory L.popup(options?: Popup options, source?: Layer) 10410// Instantiates a `Popup` object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the popup with a reference to the Layer to which it refers. 10411var popup = function (options, source) { 10412 return new Popup(options, source); 10413}; 10414 10415 10416/* @namespace Map 10417 * @section Interaction Options 10418 * @option closePopupOnClick: Boolean = true 10419 * Set it to `false` if you don't want popups to close when user clicks the map. 10420 */ 10421 Map.mergeOptions({ 10422 closePopupOnClick: true 10423 }); 10424 10425 10426// @namespace Map 10427// @section Methods for Layers and Controls 10428Map.include({ 10429 // @method openPopup(popup: Popup): this 10430 // Opens the specified popup while closing the previously opened (to make sure only one is opened at one time for usability). 10431 // @alternative 10432 // @method openPopup(content: String|HTMLElement, latlng: LatLng, options?: Popup options): this 10433 // Creates a popup with the specified content and options and opens it in the given point on a map. 10434 openPopup: function (popup, latlng, options) { 10435 if (!(popup instanceof Popup)) { 10436 popup = new Popup(options).setContent(popup); 10437 } 10438 10439 if (latlng) { 10440 popup.setLatLng(latlng); 10441 } 10442 10443 if (this.hasLayer(popup)) { 10444 return this; 10445 } 10446 10447 if (this._popup && this._popup.options.autoClose) { 10448 this.closePopup(); 10449 } 10450 10451 this._popup = popup; 10452 return this.addLayer(popup); 10453 }, 10454 10455 // @method closePopup(popup?: Popup): this 10456 // Closes the popup previously opened with [openPopup](#map-openpopup) (or the given one). 10457 closePopup: function (popup) { 10458 if (!popup || popup === this._popup) { 10459 popup = this._popup; 10460 this._popup = null; 10461 } 10462 if (popup) { 10463 this.removeLayer(popup); 10464 } 10465 return this; 10466 } 10467}); 10468 10469/* 10470 * @namespace Layer 10471 * @section Popup methods example 10472 * 10473 * All layers share a set of methods convenient for binding popups to it. 10474 * 10475 * ```js 10476 * var layer = L.Polygon(latlngs).bindPopup('Hi There!').addTo(map); 10477 * layer.openPopup(); 10478 * layer.closePopup(); 10479 * ``` 10480 * 10481 * Popups will also be automatically opened when the layer is clicked on and closed when the layer is removed from the map or another popup is opened. 10482 */ 10483 10484// @section Popup methods 10485Layer.include({ 10486 10487 // @method bindPopup(content: String|HTMLElement|Function|Popup, options?: Popup options): this 10488 // Binds a popup to the layer with the passed `content` and sets up the 10489 // necessary event listeners. If a `Function` is passed it will receive 10490 // the layer as the first argument and should return a `String` or `HTMLElement`. 10491 bindPopup: function (content, options) { 10492 10493 if (content instanceof Popup) { 10494 setOptions(content, options); 10495 this._popup = content; 10496 content._source = this; 10497 } else { 10498 if (!this._popup || options) { 10499 this._popup = new Popup(options, this); 10500 } 10501 this._popup.setContent(content); 10502 } 10503 10504 if (!this._popupHandlersAdded) { 10505 this.on({ 10506 click: this._openPopup, 10507 keypress: this._onKeyPress, 10508 remove: this.closePopup, 10509 move: this._movePopup 10510 }); 10511 this._popupHandlersAdded = true; 10512 } 10513 10514 return this; 10515 }, 10516 10517 // @method unbindPopup(): this 10518 // Removes the popup previously bound with `bindPopup`. 10519 unbindPopup: function () { 10520 if (this._popup) { 10521 this.off({ 10522 click: this._openPopup, 10523 keypress: this._onKeyPress, 10524 remove: this.closePopup, 10525 move: this._movePopup 10526 }); 10527 this._popupHandlersAdded = false; 10528 this._popup = null; 10529 } 10530 return this; 10531 }, 10532 10533 // @method openPopup(latlng?: LatLng): this 10534 // Opens the bound popup at the specified `latlng` or at the default popup anchor if no `latlng` is passed. 10535 openPopup: function (layer, latlng) { 10536 if (this._popup && this._map) { 10537 latlng = this._popup._prepareOpen(this, layer, latlng); 10538 10539 // open the popup on the map 10540 this._map.openPopup(this._popup, latlng); 10541 } 10542 10543 return this; 10544 }, 10545 10546 // @method closePopup(): this 10547 // Closes the popup bound to this layer if it is open. 10548 closePopup: function () { 10549 if (this._popup) { 10550 this._popup._close(); 10551 } 10552 return this; 10553 }, 10554 10555 // @method togglePopup(): this 10556 // Opens or closes the popup bound to this layer depending on its current state. 10557 togglePopup: function (target) { 10558 if (this._popup) { 10559 if (this._popup._map) { 10560 this.closePopup(); 10561 } else { 10562 this.openPopup(target); 10563 } 10564 } 10565 return this; 10566 }, 10567 10568 // @method isPopupOpen(): boolean 10569 // Returns `true` if the popup bound to this layer is currently open. 10570 isPopupOpen: function () { 10571 return (this._popup ? this._popup.isOpen() : false); 10572 }, 10573 10574 // @method setPopupContent(content: String|HTMLElement|Popup): this 10575 // Sets the content of the popup bound to this layer. 10576 setPopupContent: function (content) { 10577 if (this._popup) { 10578 this._popup.setContent(content); 10579 } 10580 return this; 10581 }, 10582 10583 // @method getPopup(): Popup 10584 // Returns the popup bound to this layer. 10585 getPopup: function () { 10586 return this._popup; 10587 }, 10588 10589 _openPopup: function (e) { 10590 var layer = e.layer || e.target; 10591 10592 if (!this._popup) { 10593 return; 10594 } 10595 10596 if (!this._map) { 10597 return; 10598 } 10599 10600 // prevent map click 10601 stop(e); 10602 10603 // if this inherits from Path its a vector and we can just 10604 // open the popup at the new location 10605 if (layer instanceof Path) { 10606 this.openPopup(e.layer || e.target, e.latlng); 10607 return; 10608 } 10609 10610 // otherwise treat it like a marker and figure out 10611 // if we should toggle it open/closed 10612 if (this._map.hasLayer(this._popup) && this._popup._source === layer) { 10613 this.closePopup(); 10614 } else { 10615 this.openPopup(layer, e.latlng); 10616 } 10617 }, 10618 10619 _movePopup: function (e) { 10620 this._popup.setLatLng(e.latlng); 10621 }, 10622 10623 _onKeyPress: function (e) { 10624 if (e.originalEvent.keyCode === 13) { 10625 this._openPopup(e); 10626 } 10627 } 10628}); 10629 10630/* 10631 * @class Tooltip 10632 * @inherits DivOverlay 10633 * @aka L.Tooltip 10634 * Used to display small texts on top of map layers. 10635 * 10636 * @example 10637 * 10638 * ```js 10639 * marker.bindTooltip("my tooltip text").openTooltip(); 10640 * ``` 10641 * Note about tooltip offset. Leaflet takes two options in consideration 10642 * for computing tooltip offsetting: 10643 * - the `offset` Tooltip option: it defaults to [0, 0], and it's specific to one tooltip. 10644 * Add a positive x offset to move the tooltip to the right, and a positive y offset to 10645 * move it to the bottom. Negatives will move to the left and top. 10646 * - the `tooltipAnchor` Icon option: this will only be considered for Marker. You 10647 * should adapt this value if you use a custom icon. 10648 */ 10649 10650 10651// @namespace Tooltip 10652var Tooltip = DivOverlay.extend({ 10653 10654 // @section 10655 // @aka Tooltip options 10656 options: { 10657 // @option pane: String = 'tooltipPane' 10658 // `Map pane` where the tooltip will be added. 10659 pane: 'tooltipPane', 10660 10661 // @option offset: Point = Point(0, 0) 10662 // Optional offset of the tooltip position. 10663 offset: [0, 0], 10664 10665 // @option direction: String = 'auto' 10666 // Direction where to open the tooltip. Possible values are: `right`, `left`, 10667 // `top`, `bottom`, `center`, `auto`. 10668 // `auto` will dynamically switch between `right` and `left` according to the tooltip 10669 // position on the map. 10670 direction: 'auto', 10671 10672 // @option permanent: Boolean = false 10673 // Whether to open the tooltip permanently or only on mouseover. 10674 permanent: false, 10675 10676 // @option sticky: Boolean = false 10677 // If true, the tooltip will follow the mouse instead of being fixed at the feature center. 10678 sticky: false, 10679 10680 // @option interactive: Boolean = false 10681 // If true, the tooltip will listen to the feature events. 10682 interactive: false, 10683 10684 // @option opacity: Number = 0.9 10685 // Tooltip container opacity. 10686 opacity: 0.9 10687 }, 10688 10689 onAdd: function (map) { 10690 DivOverlay.prototype.onAdd.call(this, map); 10691 this.setOpacity(this.options.opacity); 10692 10693 // @namespace Map 10694 // @section Tooltip events 10695 // @event tooltipopen: TooltipEvent 10696 // Fired when a tooltip is opened in the map. 10697 map.fire('tooltipopen', {tooltip: this}); 10698 10699 if (this._source) { 10700 // @namespace Layer 10701 // @section Tooltip events 10702 // @event tooltipopen: TooltipEvent 10703 // Fired when a tooltip bound to this layer is opened. 10704 this._source.fire('tooltipopen', {tooltip: this}, true); 10705 } 10706 }, 10707 10708 onRemove: function (map) { 10709 DivOverlay.prototype.onRemove.call(this, map); 10710 10711 // @namespace Map 10712 // @section Tooltip events 10713 // @event tooltipclose: TooltipEvent 10714 // Fired when a tooltip in the map is closed. 10715 map.fire('tooltipclose', {tooltip: this}); 10716 10717 if (this._source) { 10718 // @namespace Layer 10719 // @section Tooltip events 10720 // @event tooltipclose: TooltipEvent 10721 // Fired when a tooltip bound to this layer is closed. 10722 this._source.fire('tooltipclose', {tooltip: this}, true); 10723 } 10724 }, 10725 10726 getEvents: function () { 10727 var events = DivOverlay.prototype.getEvents.call(this); 10728 10729 if (touch && !this.options.permanent) { 10730 events.preclick = this._close; 10731 } 10732 10733 return events; 10734 }, 10735 10736 _close: function () { 10737 if (this._map) { 10738 this._map.closeTooltip(this); 10739 } 10740 }, 10741 10742 _initLayout: function () { 10743 var prefix = 'leaflet-tooltip', 10744 className = prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide'); 10745 10746 this._contentNode = this._container = create$1('div', className); 10747 }, 10748 10749 _updateLayout: function () {}, 10750 10751 _adjustPan: function () {}, 10752 10753 _setPosition: function (pos) { 10754 var map = this._map, 10755 container = this._container, 10756 centerPoint = map.latLngToContainerPoint(map.getCenter()), 10757 tooltipPoint = map.layerPointToContainerPoint(pos), 10758 direction = this.options.direction, 10759 tooltipWidth = container.offsetWidth, 10760 tooltipHeight = container.offsetHeight, 10761 offset = toPoint(this.options.offset), 10762 anchor = this._getAnchor(); 10763 10764 if (direction === 'top') { 10765 pos = pos.add(toPoint(-tooltipWidth / 2 + offset.x, -tooltipHeight + offset.y + anchor.y, true)); 10766 } else if (direction === 'bottom') { 10767 pos = pos.subtract(toPoint(tooltipWidth / 2 - offset.x, -offset.y, true)); 10768 } else if (direction === 'center') { 10769 pos = pos.subtract(toPoint(tooltipWidth / 2 + offset.x, tooltipHeight / 2 - anchor.y + offset.y, true)); 10770 } else if (direction === 'right' || direction === 'auto' && tooltipPoint.x < centerPoint.x) { 10771 direction = 'right'; 10772 pos = pos.add(toPoint(offset.x + anchor.x, anchor.y - tooltipHeight / 2 + offset.y, true)); 10773 } else { 10774 direction = 'left'; 10775 pos = pos.subtract(toPoint(tooltipWidth + anchor.x - offset.x, tooltipHeight / 2 - anchor.y - offset.y, true)); 10776 } 10777 10778 removeClass(container, 'leaflet-tooltip-right'); 10779 removeClass(container, 'leaflet-tooltip-left'); 10780 removeClass(container, 'leaflet-tooltip-top'); 10781 removeClass(container, 'leaflet-tooltip-bottom'); 10782 addClass(container, 'leaflet-tooltip-' + direction); 10783 setPosition(container, pos); 10784 }, 10785 10786 _updatePosition: function () { 10787 var pos = this._map.latLngToLayerPoint(this._latlng); 10788 this._setPosition(pos); 10789}, 10790 10791setOpacity: function (opacity) { 10792 this.options.opacity = opacity; 10793 10794 if (this._container) { 10795 setOpacity(this._container, opacity); 10796 } 10797}, 10798 10799_animateZoom: function (e) { 10800 var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center); 10801 this._setPosition(pos); 10802}, 10803 10804_getAnchor: function () { 10805 // Where should we anchor the tooltip on the source layer? 10806 return toPoint(this._source && this._source._getTooltipAnchor && !this.options.sticky ? this._source._getTooltipAnchor() : [0, 0]); 10807 } 10808 10809}); 10810 10811// @namespace Tooltip 10812// @factory L.tooltip(options?: Tooltip options, source?: Layer) 10813// Instantiates a Tooltip object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the tooltip with a reference to the Layer to which it refers. 10814var tooltip = function (options, source) { 10815 return new Tooltip(options, source); 10816}; 10817 10818// @namespace Map 10819// @section Methods for Layers and Controls 10820Map.include({ 10821 10822 // @method openTooltip(tooltip: Tooltip): this 10823 // Opens the specified tooltip. 10824 // @alternative 10825 // @method openTooltip(content: String|HTMLElement, latlng: LatLng, options?: Tooltip options): this 10826 // Creates a tooltip with the specified content and options and open it. 10827 openTooltip: function (tooltip, latlng, options) { 10828 if (!(tooltip instanceof Tooltip)) { 10829 tooltip = new Tooltip(options).setContent(tooltip); 10830 } 10831 10832 if (latlng) { 10833 tooltip.setLatLng(latlng); 10834 } 10835 10836 if (this.hasLayer(tooltip)) { 10837 return this; 10838 } 10839 10840 return this.addLayer(tooltip); 10841 }, 10842 10843 // @method closeTooltip(tooltip?: Tooltip): this 10844 // Closes the tooltip given as parameter. 10845 closeTooltip: function (tooltip) { 10846 if (tooltip) { 10847 this.removeLayer(tooltip); 10848 } 10849 return this; 10850 } 10851 10852}); 10853 10854/* 10855 * @namespace Layer 10856 * @section Tooltip methods example 10857 * 10858 * All layers share a set of methods convenient for binding tooltips to it. 10859 * 10860 * ```js 10861 * var layer = L.Polygon(latlngs).bindTooltip('Hi There!').addTo(map); 10862 * layer.openTooltip(); 10863 * layer.closeTooltip(); 10864 * ``` 10865 */ 10866 10867// @section Tooltip methods 10868Layer.include({ 10869 10870 // @method bindTooltip(content: String|HTMLElement|Function|Tooltip, options?: Tooltip options): this 10871 // Binds a tooltip to the layer with the passed `content` and sets up the 10872 // necessary event listeners. If a `Function` is passed it will receive 10873 // the layer as the first argument and should return a `String` or `HTMLElement`. 10874 bindTooltip: function (content, options) { 10875 10876 if (content instanceof Tooltip) { 10877 setOptions(content, options); 10878 this._tooltip = content; 10879 content._source = this; 10880 } else { 10881 if (!this._tooltip || options) { 10882 this._tooltip = new Tooltip(options, this); 10883 } 10884 this._tooltip.setContent(content); 10885 10886 } 10887 10888 this._initTooltipInteractions(); 10889 10890 if (this._tooltip.options.permanent && this._map && this._map.hasLayer(this)) { 10891 this.openTooltip(); 10892 } 10893 10894 return this; 10895 }, 10896 10897 // @method unbindTooltip(): this 10898 // Removes the tooltip previously bound with `bindTooltip`. 10899 unbindTooltip: function () { 10900 if (this._tooltip) { 10901 this._initTooltipInteractions(true); 10902 this.closeTooltip(); 10903 this._tooltip = null; 10904 } 10905 return this; 10906 }, 10907 10908 _initTooltipInteractions: function (remove$$1) { 10909 if (!remove$$1 && this._tooltipHandlersAdded) { return; } 10910 var onOff = remove$$1 ? 'off' : 'on', 10911 events = { 10912 remove: this.closeTooltip, 10913 move: this._moveTooltip 10914 }; 10915 if (!this._tooltip.options.permanent) { 10916 events.mouseover = this._openTooltip; 10917 events.mouseout = this.closeTooltip; 10918 if (this._tooltip.options.sticky) { 10919 events.mousemove = this._moveTooltip; 10920 } 10921 if (touch) { 10922 events.click = this._openTooltip; 10923 } 10924 } else { 10925 events.add = this._openTooltip; 10926 } 10927 this[onOff](events); 10928 this._tooltipHandlersAdded = !remove$$1; 10929}, 10930 10931 // @method openTooltip(latlng?: LatLng): this 10932 // Opens the bound tooltip at the specified `latlng` or at the default tooltip anchor if no `latlng` is passed. 10933 openTooltip: function (layer, latlng) { 10934 if (this._tooltip && this._map) { 10935 latlng = this._tooltip._prepareOpen(this, layer, latlng); 10936 10937 // open the tooltip on the map 10938 this._map.openTooltip(this._tooltip, latlng); 10939 10940 // Tooltip container may not be defined if not permanent and never 10941 // opened. 10942 if (this._tooltip.options.interactive && this._tooltip._container) { 10943 addClass(this._tooltip._container, 'leaflet-clickable'); 10944 this.addInteractiveTarget(this._tooltip._container); 10945 } 10946 } 10947 10948 return this; 10949 }, 10950 10951 // @method closeTooltip(): this 10952 // Closes the tooltip bound to this layer if it is open. 10953 closeTooltip: function () { 10954 if (this._tooltip) { 10955 this._tooltip._close(); 10956 if (this._tooltip.options.interactive && this._tooltip._container) { 10957 removeClass(this._tooltip._container, 'leaflet-clickable'); 10958 this.removeInteractiveTarget(this._tooltip._container); 10959 } 10960 } 10961 return this; 10962 }, 10963 10964 // @method toggleTooltip(): this 10965 // Opens or closes the tooltip bound to this layer depending on its current state. 10966 toggleTooltip: function (target) { 10967 if (this._tooltip) { 10968 if (this._tooltip._map) { 10969 this.closeTooltip(); 10970 } else { 10971 this.openTooltip(target); 10972 } 10973 } 10974 return this; 10975 }, 10976 10977 // @method isTooltipOpen(): boolean 10978 // Returns `true` if the tooltip bound to this layer is currently open. 10979 isTooltipOpen: function () { 10980 return this._tooltip.isOpen(); 10981 }, 10982 10983 // @method setTooltipContent(content: String|HTMLElement|Tooltip): this 10984 // Sets the content of the tooltip bound to this layer. 10985 setTooltipContent: function (content) { 10986 if (this._tooltip) { 10987 this._tooltip.setContent(content); 10988 } 10989 return this; 10990 }, 10991 10992 // @method getTooltip(): Tooltip 10993 // Returns the tooltip bound to this layer. 10994 getTooltip: function () { 10995 return this._tooltip; 10996 }, 10997 10998 _openTooltip: function (e) { 10999 var layer = e.layer || e.target; 11000 11001 if (!this._tooltip || !this._map) { 11002 return; 11003 } 11004 this.openTooltip(layer, this._tooltip.options.sticky ? e.latlng : undefined); 11005 }, 11006 11007 _moveTooltip: function (e) { 11008 var latlng = e.latlng, containerPoint, layerPoint; 11009 if (this._tooltip.options.sticky && e.originalEvent) { 11010 containerPoint = this._map.mouseEventToContainerPoint(e.originalEvent); 11011 layerPoint = this._map.containerPointToLayerPoint(containerPoint); 11012 latlng = this._map.layerPointToLatLng(layerPoint); 11013 } 11014 this._tooltip.setLatLng(latlng); 11015 } 11016}); 11017 11018/* 11019 * @class DivIcon 11020 * @aka L.DivIcon 11021 * @inherits Icon 11022 * 11023 * Represents a lightweight icon for markers that uses a simple `<div>` 11024 * element instead of an image. Inherits from `Icon` but ignores the `iconUrl` and shadow options. 11025 * 11026 * @example 11027 * ```js 11028 * var myIcon = L.divIcon({className: 'my-div-icon'}); 11029 * // you can set .my-div-icon styles in CSS 11030 * 11031 * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map); 11032 * ``` 11033 * 11034 * By default, it has a 'leaflet-div-icon' CSS class and is styled as a little white square with a shadow. 11035 */ 11036 11037 var DivIcon = Icon.extend({ 11038 options: { 11039 // @section 11040 // @aka DivIcon options 11041 iconSize: [12, 12], // also can be set through CSS 11042 11043 // iconAnchor: (Point), 11044 // popupAnchor: (Point), 11045 11046 // @option html: String|HTMLElement = '' 11047 // Custom HTML code to put inside the div element, empty by default. Alternatively, 11048 // an instance of `HTMLElement`. 11049 html: false, 11050 11051 // @option bgPos: Point = [0, 0] 11052 // Optional relative position of the background, in pixels 11053 bgPos: null, 11054 11055 className: 'leaflet-div-icon' 11056 }, 11057 11058 createIcon: function (oldIcon) { 11059 var div = (oldIcon && oldIcon.tagName === 'DIV') ? oldIcon : document.createElement('div'), 11060 options = this.options; 11061 11062 if (options.html instanceof Element) { 11063 empty(div); 11064 div.appendChild(options.html); 11065 } else { 11066 div.innerHTML = options.html !== false ? options.html : ''; 11067 } 11068 11069 if (options.bgPos) { 11070 var bgPos = toPoint(options.bgPos); 11071 div.style.backgroundPosition = (-bgPos.x) + 'px ' + (-bgPos.y) + 'px'; 11072 } 11073 this._setIconStyles(div, 'icon'); 11074 11075 return div; 11076 }, 11077 11078 createShadow: function () { 11079 return null; 11080} 11081}); 11082 11083// @factory L.divIcon(options: DivIcon options) 11084// Creates a `DivIcon` instance with the given options. 11085function divIcon(options) { 11086 return new DivIcon(options); 11087} 11088 11089Icon.Default = IconDefault; 11090 11091/* 11092 * @class GridLayer 11093 * @inherits Layer 11094 * @aka L.GridLayer 11095 * 11096 * Generic class for handling a tiled grid of HTML elements. This is the base class for all tile layers and replaces `TileLayer.Canvas`. 11097 * GridLayer can be extended to create a tiled grid of HTML elements like `<canvas>`, `<img>` or `<div>`. GridLayer will handle creating and animating these DOM elements for you. 11098 * 11099 * 11100 * @section Synchronous usage 11101 * @example 11102 * 11103 * To create a custom layer, extend GridLayer and implement the `createTile()` method, which will be passed a `Point` object with the `x`, `y`, and `z` (zoom level) coordinates to draw your tile. 11104 * 11105 * ```js 11106 * var CanvasLayer = L.GridLayer.extend({ 11107 * createTile: function(coords){ 11108 * // create a <canvas> element for drawing 11109 * var tile = L.DomUtil.create('canvas', 'leaflet-tile'); 11110 * 11111 * // setup tile width and height according to the options 11112 * var size = this.getTileSize(); 11113 * tile.width = size.x; 11114 * tile.height = size.y; 11115 * 11116 * // get a canvas context and draw something on it using coords.x, coords.y and coords.z 11117 * var ctx = tile.getContext('2d'); 11118 * 11119 * // return the tile so it can be rendered on screen 11120 * return tile; 11121 * } 11122 * }); 11123 * ``` 11124 * 11125 * @section Asynchronous usage 11126 * @example 11127 * 11128 * Tile creation can also be asynchronous, this is useful when using a third-party drawing library. Once the tile is finished drawing it can be passed to the `done()` callback. 11129 * 11130 * ```js 11131 * var CanvasLayer = L.GridLayer.extend({ 11132 * createTile: function(coords, done){ 11133 * var error; 11134 * 11135 * // create a <canvas> element for drawing 11136 * var tile = L.DomUtil.create('canvas', 'leaflet-tile'); 11137 * 11138 * // setup tile width and height according to the options 11139 * var size = this.getTileSize(); 11140 * tile.width = size.x; 11141 * tile.height = size.y; 11142 * 11143 * // draw something asynchronously and pass the tile to the done() callback 11144 * setTimeout(function() { 11145 * done(error, tile); 11146 * }, 1000); 11147 * 11148 * return tile; 11149 * } 11150 * }); 11151 * ``` 11152 * 11153 * @section 11154 */ 11155 11156 11157 var GridLayer = Layer.extend({ 11158 11159 // @section 11160 // @aka GridLayer options 11161 options: { 11162 // @option tileSize: Number|Point = 256 11163 // Width and height of tiles in the grid. Use a number if width and height are equal, or `L.point(width, height)` otherwise. 11164 tileSize: 256, 11165 11166 // @option opacity: Number = 1.0 11167 // Opacity of the tiles. Can be used in the `createTile()` function. 11168 opacity: 1, 11169 11170 // @option updateWhenIdle: Boolean = (depends) 11171 // Load new tiles only when panning ends. 11172 // `true` by default on mobile browsers, in order to avoid too many requests and keep smooth navigation. 11173 // `false` otherwise in order to display new tiles _during_ panning, since it is easy to pan outside the 11174 // [`keepBuffer`](#gridlayer-keepbuffer) option in desktop browsers. 11175 updateWhenIdle: mobile, 11176 11177 // @option updateWhenZooming: Boolean = true 11178 // By default, a smooth zoom animation (during a [touch zoom](#map-touchzoom) or a [`flyTo()`](#map-flyto)) will update grid layers every integer zoom level. Setting this option to `false` will update the grid layer only when the smooth animation ends. 11179 updateWhenZooming: true, 11180 11181 // @option updateInterval: Number = 200 11182 // Tiles will not update more than once every `updateInterval` milliseconds when panning. 11183 updateInterval: 200, 11184 11185 // @option zIndex: Number = 1 11186 // The explicit zIndex of the tile layer. 11187 zIndex: 1, 11188 11189 // @option bounds: LatLngBounds = undefined 11190 // If set, tiles will only be loaded inside the set `LatLngBounds`. 11191 bounds: null, 11192 11193 // @option minZoom: Number = 0 11194 // The minimum zoom level down to which this layer will be displayed (inclusive). 11195 minZoom: 0, 11196 11197 // @option maxZoom: Number = undefined 11198 // The maximum zoom level up to which this layer will be displayed (inclusive). 11199 maxZoom: undefined, 11200 11201 // @option maxNativeZoom: Number = undefined 11202 // Maximum zoom number the tile source has available. If it is specified, 11203 // the tiles on all zoom levels higher than `maxNativeZoom` will be loaded 11204 // from `maxNativeZoom` level and auto-scaled. 11205 maxNativeZoom: undefined, 11206 11207 // @option minNativeZoom: Number = undefined 11208 // Minimum zoom number the tile source has available. If it is specified, 11209 // the tiles on all zoom levels lower than `minNativeZoom` will be loaded 11210 // from `minNativeZoom` level and auto-scaled. 11211 minNativeZoom: undefined, 11212 11213 // @option noWrap: Boolean = false 11214 // Whether the layer is wrapped around the antimeridian. If `true`, the 11215 // GridLayer will only be displayed once at low zoom levels. Has no 11216 // effect when the [map CRS](#map-crs) doesn't wrap around. Can be used 11217 // in combination with [`bounds`](#gridlayer-bounds) to prevent requesting 11218 // tiles outside the CRS limits. 11219 noWrap: false, 11220 11221 // @option pane: String = 'tilePane' 11222 // `Map pane` where the grid layer will be added. 11223 pane: 'tilePane', 11224 11225 // @option className: String = '' 11226 // A custom class name to assign to the tile layer. Empty by default. 11227 className: '', 11228 11229 // @option keepBuffer: Number = 2 11230 // When panning the map, keep this many rows and columns of tiles before unloading them. 11231 keepBuffer: 2 11232 }, 11233 11234 initialize: function (options) { 11235 setOptions(this, options); 11236 }, 11237 11238 onAdd: function () { 11239 this._initContainer(); 11240 11241 this._levels = {}; 11242 this._tiles = {}; 11243 11244 this._resetView(); 11245 this._update(); 11246 }, 11247 11248 beforeAdd: function (map) { 11249 map._addZoomLimit(this); 11250 }, 11251 11252 onRemove: function (map) { 11253 this._removeAllTiles(); 11254 remove(this._container); 11255 map._removeZoomLimit(this); 11256 this._container = null; 11257 this._tileZoom = undefined; 11258 }, 11259 11260 // @method bringToFront: this 11261 // Brings the tile layer to the top of all tile layers. 11262 bringToFront: function () { 11263 if (this._map) { 11264 toFront(this._container); 11265 this._setAutoZIndex(Math.max); 11266 } 11267 return this; 11268 }, 11269 11270 // @method bringToBack: this 11271 // Brings the tile layer to the bottom of all tile layers. 11272 bringToBack: function () { 11273 if (this._map) { 11274 toBack(this._container); 11275 this._setAutoZIndex(Math.min); 11276 } 11277 return this; 11278 }, 11279 11280 // @method getContainer: HTMLElement 11281 // Returns the HTML element that contains the tiles for this layer. 11282 getContainer: function () { 11283 return this._container; 11284 }, 11285 11286 // @method setOpacity(opacity: Number): this 11287 // Changes the [opacity](#gridlayer-opacity) of the grid layer. 11288 setOpacity: function (opacity) { 11289 this.options.opacity = opacity; 11290 this._updateOpacity(); 11291 return this; 11292 }, 11293 11294 // @method setZIndex(zIndex: Number): this 11295 // Changes the [zIndex](#gridlayer-zindex) of the grid layer. 11296 setZIndex: function (zIndex) { 11297 this.options.zIndex = zIndex; 11298 this._updateZIndex(); 11299 11300 return this; 11301 }, 11302 11303 // @method isLoading: Boolean 11304 // Returns `true` if any tile in the grid layer has not finished loading. 11305 isLoading: function () { 11306 return this._loading; 11307 }, 11308 11309 // @method redraw: this 11310 // Causes the layer to clear all the tiles and request them again. 11311 redraw: function () { 11312 if (this._map) { 11313 this._removeAllTiles(); 11314 this._update(); 11315 } 11316 return this; 11317 }, 11318 11319 getEvents: function () { 11320 var events = { 11321 viewprereset: this._invalidateAll, 11322 viewreset: this._resetView, 11323 zoom: this._resetView, 11324 moveend: this._onMoveEnd 11325 }; 11326 11327 if (!this.options.updateWhenIdle) { 11328 // update tiles on move, but not more often than once per given interval 11329 if (!this._onMove) { 11330 this._onMove = throttle(this._onMoveEnd, this.options.updateInterval, this); 11331 } 11332 11333 events.move = this._onMove; 11334 } 11335 11336 if (this._zoomAnimated) { 11337 events.zoomanim = this._animateZoom; 11338 } 11339 11340 return events; 11341 }, 11342 11343 // @section Extension methods 11344 // Layers extending `GridLayer` shall reimplement the following method. 11345 // @method createTile(coords: Object, done?: Function): HTMLElement 11346 // Called only internally, must be overridden by classes extending `GridLayer`. 11347 // Returns the `HTMLElement` corresponding to the given `coords`. If the `done` callback 11348 // is specified, it must be called when the tile has finished loading and drawing. 11349 createTile: function () { 11350 return document.createElement('div'); 11351 }, 11352 11353 // @section 11354 // @method getTileSize: Point 11355 // Normalizes the [tileSize option](#gridlayer-tilesize) into a point. Used by the `createTile()` method. 11356 getTileSize: function () { 11357 var s = this.options.tileSize; 11358 return s instanceof Point ? s : new Point(s, s); 11359 }, 11360 11361 _updateZIndex: function () { 11362 if (this._container && this.options.zIndex !== undefined && this.options.zIndex !== null) { 11363 this._container.style.zIndex = this.options.zIndex; 11364 } 11365 }, 11366 11367 _setAutoZIndex: function (compare) { 11368 // go through all other layers of the same pane, set zIndex to max + 1 (front) or min - 1 (back) 11369 11370 var layers = this.getPane().children, 11371 edgeZIndex = -compare(-Infinity, Infinity); // -Infinity for max, Infinity for min 11372 11373 for (var i = 0, len = layers.length, zIndex; i < len; i++) { 11374 11375 zIndex = layers[i].style.zIndex; 11376 11377 if (layers[i] !== this._container && zIndex) { 11378 edgeZIndex = compare(edgeZIndex, +zIndex); 11379 } 11380 } 11381 11382 if (isFinite(edgeZIndex)) { 11383 this.options.zIndex = edgeZIndex + compare(-1, 1); 11384 this._updateZIndex(); 11385 } 11386 }, 11387 11388 _updateOpacity: function () { 11389 if (!this._map) { return; } 11390 11391 // IE doesn't inherit filter opacity properly, so we're forced to set it on tiles 11392 if (ielt9) { return; } 11393 11394 setOpacity(this._container, this.options.opacity); 11395 11396 var now = +new Date(), 11397 nextFrame = false, 11398 willPrune = false; 11399 11400 for (var key in this._tiles) { 11401 var tile = this._tiles[key]; 11402 if (!tile.current || !tile.loaded) { continue; } 11403 11404 var fade = Math.min(1, (now - tile.loaded) / 200); 11405 11406 setOpacity(tile.el, fade); 11407 if (fade < 1) { 11408 nextFrame = true; 11409 } else { 11410 if (tile.active) { 11411 willPrune = true; 11412 } else { 11413 this._onOpaqueTile(tile); 11414 } 11415 tile.active = true; 11416 } 11417 } 11418 11419 if (willPrune && !this._noPrune) { this._pruneTiles(); } 11420 11421 if (nextFrame) { 11422 cancelAnimFrame(this._fadeFrame); 11423 this._fadeFrame = requestAnimFrame(this._updateOpacity, this); 11424 } 11425}, 11426 11427_onOpaqueTile: falseFn, 11428 11429_initContainer: function () { 11430 if (this._container) { return; } 11431 11432 this._container = create$1('div', 'leaflet-layer ' + (this.options.className || '')); 11433 this._updateZIndex(); 11434 11435 if (this.options.opacity < 1) { 11436 this._updateOpacity(); 11437 } 11438 11439 this.getPane().appendChild(this._container); 11440}, 11441 11442_updateLevels: function () { 11443 11444 var zoom = this._tileZoom, 11445 maxZoom = this.options.maxZoom; 11446 11447 if (zoom === undefined) { return undefined; } 11448 11449 for (var z in this._levels) { 11450 if (this._levels[z].el.children.length || z === zoom) { 11451 this._levels[z].el.style.zIndex = maxZoom - Math.abs(zoom - z); 11452 this._onUpdateLevel(z); 11453 } else { 11454 remove(this._levels[z].el); 11455 this._removeTilesAtZoom(z); 11456 this._onRemoveLevel(z); 11457 delete this._levels[z]; 11458 } 11459} 11460 11461var level = this._levels[zoom], 11462map = this._map; 11463 11464if (!level) { 11465 level = this._levels[zoom] = {}; 11466 11467 level.el = create$1('div', 'leaflet-tile-container leaflet-zoom-animated', this._container); 11468 level.el.style.zIndex = maxZoom; 11469 11470 level.origin = map.project(map.unproject(map.getPixelOrigin()), zoom).round(); 11471 level.zoom = zoom; 11472 11473 this._setZoomTransform(level, map.getCenter(), map.getZoom()); 11474 11475 // force the browser to consider the newly added element for transition 11476 falseFn(level.el.offsetWidth); 11477 11478 this._onCreateLevel(level); 11479 } 11480 11481 this._level = level; 11482 11483 return level; 11484 }, 11485 11486 _onUpdateLevel: falseFn, 11487 11488 _onRemoveLevel: falseFn, 11489 11490 _onCreateLevel: falseFn, 11491 11492 _pruneTiles: function () { 11493 if (!this._map) { 11494 return; 11495 } 11496 11497 var key, tile; 11498 11499 var zoom = this._map.getZoom(); 11500 if (zoom > this.options.maxZoom || 11501 zoom < this.options.minZoom) { 11502 this._removeAllTiles(); 11503 return; 11504 } 11505 11506 for (key in this._tiles) { 11507 tile = this._tiles[key]; 11508 tile.retain = tile.current; 11509 } 11510 11511 for (key in this._tiles) { 11512 tile = this._tiles[key]; 11513 if (tile.current && !tile.active) { 11514 var coords = tile.coords; 11515 if (!this._retainParent(coords.x, coords.y, coords.z, coords.z - 5)) { 11516 this._retainChildren(coords.x, coords.y, coords.z, coords.z + 2); 11517 } 11518 } 11519} 11520 11521for (key in this._tiles) { 11522 if (!this._tiles[key].retain) { 11523 this._removeTile(key); 11524} 11525} 11526}, 11527 11528_removeTilesAtZoom: function (zoom) { 11529 for (var key in this._tiles) { 11530 if (this._tiles[key].coords.z !== zoom) { 11531 continue; 11532 } 11533 this._removeTile(key); 11534} 11535}, 11536 11537_removeAllTiles: function () { 11538 for (var key in this._tiles) { 11539 this._removeTile(key); 11540 } 11541}, 11542 11543_invalidateAll: function () { 11544 for (var z in this._levels) { 11545 remove(this._levels[z].el); 11546 this._onRemoveLevel(z); 11547 delete this._levels[z]; 11548 } 11549 this._removeAllTiles(); 11550 11551 this._tileZoom = undefined; 11552}, 11553 11554_retainParent: function (x, y, z, minZoom) { 11555 var x2 = Math.floor(x / 2), 11556 y2 = Math.floor(y / 2), 11557 z2 = z - 1, 11558 coords2 = new Point(+x2, +y2); 11559 coords2.z = +z2; 11560 11561 var key = this._tileCoordsToKey(coords2), 11562 tile = this._tiles[key]; 11563 11564 if (tile && tile.active) { 11565 tile.retain = true; 11566 return true; 11567 11568 } else if (tile && tile.loaded) { 11569 tile.retain = true; 11570 } 11571 11572 if (z2 > minZoom) { 11573 return this._retainParent(x2, y2, z2, minZoom); 11574 } 11575 11576 return false; 11577}, 11578 11579_retainChildren: function (x, y, z, maxZoom) { 11580 11581 for (var i = 2 * x; i < 2 * x + 2; i++) { 11582 for (var j = 2 * y; j < 2 * y + 2; j++) { 11583 11584 var coords = new Point(i, j); 11585 coords.z = z + 1; 11586 11587 var key = this._tileCoordsToKey(coords), 11588 tile = this._tiles[key]; 11589 11590 if (tile && tile.active) { 11591 tile.retain = true; 11592 continue; 11593 11594 } else if (tile && tile.loaded) { 11595 tile.retain = true; 11596 } 11597 11598 if (z + 1 < maxZoom) { 11599 this._retainChildren(i, j, z + 1, maxZoom); 11600 } 11601 } 11602} 11603}, 11604 11605_resetView: function (e) { 11606 var animating = e && (e.pinch || e.flyTo); 11607 this._setView(this._map.getCenter(), this._map.getZoom(), animating, animating); 11608}, 11609 11610_animateZoom: function (e) { 11611 this._setView(e.center, e.zoom, true, e.noUpdate); 11612}, 11613 11614_clampZoom: function (zoom) { 11615 var options = this.options; 11616 11617 if (undefined !== options.minNativeZoom && zoom < options.minNativeZoom) { 11618 return options.minNativeZoom; 11619 } 11620 11621 if (undefined !== options.maxNativeZoom && options.maxNativeZoom < zoom) { 11622 return options.maxNativeZoom; 11623 } 11624 11625 return zoom; 11626}, 11627 11628_setView: function (center, zoom, noPrune, noUpdate) { 11629 var tileZoom = this._clampZoom(Math.round(zoom)); 11630 if ((this.options.maxZoom !== undefined && tileZoom > this.options.maxZoom) || 11631 (this.options.minZoom !== undefined && tileZoom < this.options.minZoom)) { 11632 tileZoom = undefined; 11633} 11634 11635var tileZoomChanged = this.options.updateWhenZooming && (tileZoom !== this._tileZoom); 11636 11637if (!noUpdate || tileZoomChanged) { 11638 11639 this._tileZoom = tileZoom; 11640 11641 if (this._abortLoading) { 11642 this._abortLoading(); 11643} 11644 11645this._updateLevels(); 11646this._resetGrid(); 11647 11648if (tileZoom !== undefined) { 11649 this._update(center); 11650} 11651 11652if (!noPrune) { 11653 this._pruneTiles(); 11654} 11655 11656 // Flag to prevent _updateOpacity from pruning tiles during 11657 // a zoom anim or a pinch gesture 11658 this._noPrune = !!noPrune; 11659 } 11660 11661 this._setZoomTransforms(center, zoom); 11662 }, 11663 11664 _setZoomTransforms: function (center, zoom) { 11665 for (var i in this._levels) { 11666 this._setZoomTransform(this._levels[i], center, zoom); 11667 } 11668 }, 11669 11670 _setZoomTransform: function (level, center, zoom) { 11671 var scale = this._map.getZoomScale(zoom, level.zoom), 11672 translate = level.origin.multiplyBy(scale) 11673 .subtract(this._map._getNewPixelOrigin(center, zoom)).round(); 11674 11675 if (any3d) { 11676 setTransform(level.el, translate, scale); 11677 } else { 11678 setPosition(level.el, translate); 11679 } 11680 }, 11681 11682 _resetGrid: function () { 11683 var map = this._map, 11684 crs = map.options.crs, 11685 tileSize = this._tileSize = this.getTileSize(), 11686 tileZoom = this._tileZoom; 11687 11688 var bounds = this._map.getPixelWorldBounds(this._tileZoom); 11689 if (bounds) { 11690 this._globalTileRange = this._pxBoundsToTileRange(bounds); 11691 } 11692 11693 this._wrapX = crs.wrapLng && !this.options.noWrap && [ 11694 Math.floor(map.project([0, crs.wrapLng[0]], tileZoom).x / tileSize.x), 11695 Math.ceil(map.project([0, crs.wrapLng[1]], tileZoom).x / tileSize.y) 11696 ]; 11697 this._wrapY = crs.wrapLat && !this.options.noWrap && [ 11698 Math.floor(map.project([crs.wrapLat[0], 0], tileZoom).y / tileSize.x), 11699 Math.ceil(map.project([crs.wrapLat[1], 0], tileZoom).y / tileSize.y) 11700 ]; 11701}, 11702 11703_onMoveEnd: function () { 11704 if (!this._map || this._map._animatingZoom) { return; } 11705 11706 this._update(); 11707}, 11708 11709_getTiledPixelBounds: function (center) { 11710 var map = this._map, 11711 mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(), 11712 scale = map.getZoomScale(mapZoom, this._tileZoom), 11713 pixelCenter = map.project(center, this._tileZoom).floor(), 11714 halfSize = map.getSize().divideBy(scale * 2); 11715 11716 return new Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize)); 11717}, 11718 11719 // Private method to load tiles in the grid's active zoom level according to map bounds 11720 _update: function (center) { 11721 var map = this._map; 11722 if (!map) { return; } 11723 var zoom = this._clampZoom(map.getZoom()); 11724 11725 if (center === undefined) { center = map.getCenter(); } 11726 if (this._tileZoom === undefined) { return; } // if out of minzoom/maxzoom 11727 11728 var pixelBounds = this._getTiledPixelBounds(center), 11729 tileRange = this._pxBoundsToTileRange(pixelBounds), 11730 tileCenter = tileRange.getCenter(), 11731 queue = [], 11732 margin = this.options.keepBuffer, 11733 noPruneRange = new Bounds(tileRange.getBottomLeft().subtract([margin, -margin]), 11734 tileRange.getTopRight().add([margin, -margin])); 11735 11736 // Sanity check: panic if the tile range contains Infinity somewhere. 11737 if (!(isFinite(tileRange.min.x) && 11738 isFinite(tileRange.min.y) && 11739 isFinite(tileRange.max.x) && 11740 isFinite(tileRange.max.y))) { throw new Error('Attempted to load an infinite number of tiles'); } 11741 11742 for (var key in this._tiles) { 11743 var c = this._tiles[key].coords; 11744 if (c.z !== this._tileZoom || !noPruneRange.contains(new Point(c.x, c.y))) { 11745 this._tiles[key].current = false; 11746 } 11747 } 11748 11749 // _update just loads more tiles. If the tile zoom level differs too much 11750 // from the map's, let _setView reset levels and prune old tiles. 11751 if (Math.abs(zoom - this._tileZoom) > 1) { this._setView(center, zoom); return; } 11752 11753 // create a queue of coordinates to load tiles from 11754 for (var j = tileRange.min.y; j <= tileRange.max.y; j++) { 11755 for (var i = tileRange.min.x; i <= tileRange.max.x; i++) { 11756 var coords = new Point(i, j); 11757 coords.z = this._tileZoom; 11758 11759 if (!this._isValidTile(coords)) { continue; } 11760 11761 var tile = this._tiles[this._tileCoordsToKey(coords)]; 11762 if (tile) { 11763 tile.current = true; 11764 } else { 11765 queue.push(coords); 11766 } 11767 } 11768 } 11769 11770 // sort tile queue to load tiles in order of their distance to center 11771 queue.sort(function (a, b) { 11772 return a.distanceTo(tileCenter) - b.distanceTo(tileCenter); 11773 }); 11774 11775 if (queue.length !== 0) { 11776 // if it's the first batch of tiles to load 11777 if (!this._loading) { 11778 this._loading = true; 11779 // @event loading: Event 11780 // Fired when the grid layer starts loading tiles. 11781 this.fire('loading'); 11782 } 11783 11784 // create DOM fragment to append tiles in one batch 11785 var fragment = document.createDocumentFragment(); 11786 11787 for (i = 0; i < queue.length; i++) { 11788 this._addTile(queue[i], fragment); 11789 } 11790 11791 this._level.el.appendChild(fragment); 11792 } 11793 }, 11794 11795 _isValidTile: function (coords) { 11796 var crs = this._map.options.crs; 11797 11798 if (!crs.infinite) { 11799 // don't load tile if it's out of bounds and not wrapped 11800 var bounds = this._globalTileRange; 11801 if ((!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x)) || 11802 (!crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y))) { return false; } 11803 } 11804 11805 if (!this.options.bounds) { return true; } 11806 11807 // don't load tile if it doesn't intersect the bounds in options 11808 var tileBounds = this._tileCoordsToBounds(coords); 11809 return toLatLngBounds(this.options.bounds).overlaps(tileBounds); 11810 }, 11811 11812 _keyToBounds: function (key) { 11813 return this._tileCoordsToBounds(this._keyToTileCoords(key)); 11814 }, 11815 11816 _tileCoordsToNwSe: function (coords) { 11817 var map = this._map, 11818 tileSize = this.getTileSize(), 11819 nwPoint = coords.scaleBy(tileSize), 11820 sePoint = nwPoint.add(tileSize), 11821 nw = map.unproject(nwPoint, coords.z), 11822 se = map.unproject(sePoint, coords.z); 11823 return [nw, se]; 11824 }, 11825 11826 // converts tile coordinates to its geographical bounds 11827 _tileCoordsToBounds: function (coords) { 11828 var bp = this._tileCoordsToNwSe(coords), 11829 bounds = new LatLngBounds(bp[0], bp[1]); 11830 11831 if (!this.options.noWrap) { 11832 bounds = this._map.wrapLatLngBounds(bounds); 11833 } 11834 return bounds; 11835 }, 11836 // converts tile coordinates to key for the tile cache 11837 _tileCoordsToKey: function (coords) { 11838 return coords.x + ':' + coords.y + ':' + coords.z; 11839 }, 11840 11841 // converts tile cache key to coordinates 11842 _keyToTileCoords: function (key) { 11843 var k = key.split(':'), 11844 coords = new Point(+k[0], +k[1]); 11845 coords.z = +k[2]; 11846 return coords; 11847 }, 11848 11849 _removeTile: function (key) { 11850 var tile = this._tiles[key]; 11851 if (!tile) { return; } 11852 11853 remove(tile.el); 11854 11855 delete this._tiles[key]; 11856 11857 // @event tileunload: TileEvent 11858 // Fired when a tile is removed (e.g. when a tile goes off the screen). 11859 this.fire('tileunload', { 11860 tile: tile.el, 11861 coords: this._keyToTileCoords(key) 11862 }); 11863 }, 11864 11865 _initTile: function (tile) { 11866 addClass(tile, 'leaflet-tile'); 11867 11868 var tileSize = this.getTileSize(); 11869 tile.style.width = tileSize.x + 'px'; 11870 tile.style.height = tileSize.y + 'px'; 11871 11872 tile.onselectstart = falseFn; 11873 tile.onmousemove = falseFn; 11874 11875 // update opacity on tiles in IE7-8 because of filter inheritance problems 11876 if (ielt9 && this.options.opacity < 1) { 11877 setOpacity(tile, this.options.opacity); 11878 } 11879 11880 // without this hack, tiles disappear after zoom on Chrome for Android 11881 // https://github.com/Leaflet/Leaflet/issues/2078 11882 if (android && !android23) { 11883 tile.style.WebkitBackfaceVisibility = 'hidden'; 11884 } 11885 }, 11886 11887 _addTile: function (coords, container) { 11888 var tilePos = this._getTilePos(coords), 11889 key = this._tileCoordsToKey(coords); 11890 11891 var tile = this.createTile(this._wrapCoords(coords), bind(this._tileReady, this, coords)); 11892 11893 this._initTile(tile); 11894 11895 // if createTile is defined with a second argument ("done" callback), 11896 // we know that tile is async and will be ready later; otherwise 11897 if (this.createTile.length < 2) { 11898 // mark tile as ready, but delay one frame for opacity animation to happen 11899 requestAnimFrame(bind(this._tileReady, this, coords, null, tile)); 11900 } 11901 11902 setPosition(tile, tilePos); 11903 11904 // save tile in cache 11905 this._tiles[key] = { 11906 el: tile, 11907 coords: coords, 11908 current: true 11909 }; 11910 11911 container.appendChild(tile); 11912 // @event tileloadstart: TileEvent 11913 // Fired when a tile is requested and starts loading. 11914 this.fire('tileloadstart', { 11915 tile: tile, 11916 coords: coords 11917 }); 11918 }, 11919 11920 _tileReady: function (coords, err, tile) { 11921 if (err) { 11922 // @event tileerror: TileErrorEvent 11923 // Fired when there is an error loading a tile. 11924 this.fire('tileerror', { 11925 error: err, 11926 tile: tile, 11927 coords: coords 11928 }); 11929 } 11930 11931 var key = this._tileCoordsToKey(coords); 11932 11933 tile = this._tiles[key]; 11934 if (!tile) { return; } 11935 11936 tile.loaded = +new Date(); 11937 if (this._map._fadeAnimated) { 11938 setOpacity(tile.el, 0); 11939 cancelAnimFrame(this._fadeFrame); 11940 this._fadeFrame = requestAnimFrame(this._updateOpacity, this); 11941 } else { 11942 tile.active = true; 11943 this._pruneTiles(); 11944 } 11945 11946 if (!err) { 11947 addClass(tile.el, 'leaflet-tile-loaded'); 11948 11949 // @event tileload: TileEvent 11950 // Fired when a tile loads. 11951 this.fire('tileload', { 11952 tile: tile.el, 11953 coords: coords 11954 }); 11955 } 11956 11957 if (this._noTilesToLoad()) { 11958 this._loading = false; 11959 // @event load: Event 11960 // Fired when the grid layer loaded all visible tiles. 11961 this.fire('load'); 11962 11963 if (ielt9 || !this._map._fadeAnimated) { 11964 requestAnimFrame(this._pruneTiles, this); 11965 } else { 11966 // Wait a bit more than 0.2 secs (the duration of the tile fade-in) 11967 // to trigger a pruning. 11968 setTimeout(bind(this._pruneTiles, this), 250); 11969 } 11970 } 11971 }, 11972 11973 _getTilePos: function (coords) { 11974 return coords.scaleBy(this.getTileSize()).subtract(this._level.origin); 11975 }, 11976 11977 _wrapCoords: function (coords) { 11978 var newCoords = new Point( 11979 this._wrapX ? wrapNum(coords.x, this._wrapX) : coords.x, 11980 this._wrapY ? wrapNum(coords.y, this._wrapY) : coords.y); 11981 newCoords.z = coords.z; 11982 return newCoords; 11983 }, 11984 11985 _pxBoundsToTileRange: function (bounds) { 11986 var tileSize = this.getTileSize(); 11987 return new Bounds( 11988 bounds.min.unscaleBy(tileSize).floor(), 11989 bounds.max.unscaleBy(tileSize).ceil().subtract([1, 1])); 11990 }, 11991 11992 _noTilesToLoad: function () { 11993 for (var key in this._tiles) { 11994 if (!this._tiles[key].loaded) { return false; } 11995 } 11996 return true; 11997 } 11998}); 11999 12000// @factory L.gridLayer(options?: GridLayer options) 12001// Creates a new instance of GridLayer with the supplied options. 12002function gridLayer(options) { 12003 return new GridLayer(options); 12004} 12005 12006/* 12007 * @class TileLayer 12008 * @inherits GridLayer 12009 * @aka L.TileLayer 12010 * Used to load and display tile layers on the map. Note that most tile servers require attribution, which you can set under `Layer`. Extends `GridLayer`. 12011 * 12012 * @example 12013 * 12014 * ```js 12015 * L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?{foo}', {foo: 'bar', attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'}).addTo(map); 12016 * ``` 12017 * 12018 * @section URL template 12019 * @example 12020 * 12021 * A string of the following form: 12022 * 12023 * ``` 12024 * 'http://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png' 12025 * ``` 12026 * 12027 * `{s}` means one of the available subdomains (used sequentially to help with browser parallel requests per domain limitation; subdomain values are specified in options; `a`, `b` or `c` by default, can be omitted), `{z}` — zoom level, `{x}` and `{y}` — tile coordinates. `{r}` can be used to add "@2x" to the URL to load retina tiles. 12028 * 12029 * You can use custom keys in the template, which will be [evaluated](#util-template) from TileLayer options, like this: 12030 * 12031 * ``` 12032 * L.tileLayer('http://{s}.somedomain.com/{foo}/{z}/{x}/{y}.png', {foo: 'bar'}); 12033 * ``` 12034 */ 12035 12036 12037 var TileLayer = GridLayer.extend({ 12038 12039 // @section 12040 // @aka TileLayer options 12041 options: { 12042 // @option minZoom: Number = 0 12043 // The minimum zoom level down to which this layer will be displayed (inclusive). 12044 minZoom: 0, 12045 12046 // @option maxZoom: Number = 18 12047 // The maximum zoom level up to which this layer will be displayed (inclusive). 12048 maxZoom: 18, 12049 12050 // @option subdomains: String|String[] = 'abc' 12051 // Subdomains of the tile service. Can be passed in the form of one string (where each letter is a subdomain name) or an array of strings. 12052 subdomains: 'abc', 12053 12054 // @option errorTileUrl: String = '' 12055 // URL to the tile image to show in place of the tile that failed to load. 12056 errorTileUrl: '', 12057 12058 // @option zoomOffset: Number = 0 12059 // The zoom number used in tile URLs will be offset with this value. 12060 zoomOffset: 0, 12061 12062 // @option tms: Boolean = false 12063 // If `true`, inverses Y axis numbering for tiles (turn this on for [TMS](https://en.wikipedia.org/wiki/Tile_Map_Service) services). 12064 tms: false, 12065 12066 // @option zoomReverse: Boolean = false 12067 // If set to true, the zoom number used in tile URLs will be reversed (`maxZoom - zoom` instead of `zoom`) 12068 zoomReverse: false, 12069 12070 // @option detectRetina: Boolean = false 12071 // If `true` and user is on a retina display, it will request four tiles of half the specified size and a bigger zoom level in place of one to utilize the high resolution. 12072 detectRetina: false, 12073 12074 // @option crossOrigin: Boolean|String = false 12075 // Whether the crossOrigin attribute will be added to the tiles. 12076 // If a String is provided, all tiles will have their crossOrigin attribute set to the String provided. This is needed if you want to access tile pixel data. 12077 // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values. 12078 crossOrigin: false 12079 }, 12080 12081 initialize: function (url, options) { 12082 12083 this._url = url; 12084 12085 options = setOptions(this, options); 12086 12087 // detecting retina displays, adjusting tileSize and zoom levels 12088 if (options.detectRetina && retina && options.maxZoom > 0) { 12089 12090 options.tileSize = Math.floor(options.tileSize / 2); 12091 12092 if (!options.zoomReverse) { 12093 options.zoomOffset++; 12094 options.maxZoom--; 12095 } else { 12096 options.zoomOffset--; 12097 options.minZoom++; 12098 } 12099 12100 options.minZoom = Math.max(0, options.minZoom); 12101 } 12102 12103 if (typeof options.subdomains === 'string') { 12104 options.subdomains = options.subdomains.split(''); 12105 } 12106 12107 // for https://github.com/Leaflet/Leaflet/issues/137 12108 if (!android) { 12109 this.on('tileunload', this._onTileRemove); 12110 } 12111 }, 12112 12113 // @method setUrl(url: String, noRedraw?: Boolean): this 12114 // Updates the layer's URL template and redraws it (unless `noRedraw` is set to `true`). 12115 // If the URL does not change, the layer will not be redrawn unless 12116 // the noRedraw parameter is set to false. 12117 setUrl: function (url, noRedraw) { 12118 if (this._url === url && noRedraw === undefined) { 12119 noRedraw = true; 12120 } 12121 12122 this._url = url; 12123 12124 if (!noRedraw) { 12125 this.redraw(); 12126 } 12127 return this; 12128 }, 12129 12130 // @method createTile(coords: Object, done?: Function): HTMLElement 12131 // Called only internally, overrides GridLayer's [`createTile()`](#gridlayer-createtile) 12132 // to return an `<img>` HTML element with the appropriate image URL given `coords`. The `done` 12133 // callback is called when the tile has been loaded. 12134 createTile: function (coords, done) { 12135 var tile = document.createElement('img'); 12136 12137 on(tile, 'load', bind(this._tileOnLoad, this, done, tile)); 12138 on(tile, 'error', bind(this._tileOnError, this, done, tile)); 12139 12140 if (this.options.crossOrigin || this.options.crossOrigin === '') { 12141 tile.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin; 12142 } 12143 12144 /* 12145 Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons 12146 http://www.w3.org/TR/WCAG20-TECHS/H67 12147 */ 12148 tile.alt = ''; 12149 12150 /* 12151 Set role="presentation" to force screen readers to ignore this 12152 https://www.w3.org/TR/wai-aria/roles#textalternativecomputation 12153 */ 12154 tile.setAttribute('role', 'presentation'); 12155 12156 tile.src = this.getTileUrl(coords); 12157 12158 return tile; 12159 }, 12160 12161 // @section Extension methods 12162 // @uninheritable 12163 // Layers extending `TileLayer` might reimplement the following method. 12164 // @method getTileUrl(coords: Object): String 12165 // Called only internally, returns the URL for a tile given its coordinates. 12166 // Classes extending `TileLayer` can override this function to provide custom tile URL naming schemes. 12167 getTileUrl: function (coords) { 12168 var data = { 12169 r: retina ? '@2x' : '', 12170 s: this._getSubdomain(coords), 12171 x: coords.x, 12172 y: coords.y, 12173 z: this._getZoomForUrl() 12174 }; 12175 if (this._map && !this._map.options.crs.infinite) { 12176 var invertedY = this._globalTileRange.max.y - coords.y; 12177 if (this.options.tms) { 12178 data['y'] = invertedY; 12179 } 12180 data['-y'] = invertedY; 12181 } 12182 12183 return template(this._url, extend(data, this.options)); 12184 }, 12185 12186 _tileOnLoad: function (done, tile) { 12187 // For https://github.com/Leaflet/Leaflet/issues/3332 12188 if (ielt9) { 12189 setTimeout(bind(done, this, null, tile), 0); 12190 } else { 12191 done(null, tile); 12192 } 12193 }, 12194 12195 _tileOnError: function (done, tile, e) { 12196 var errorUrl = this.options.errorTileUrl; 12197 if (errorUrl && tile.getAttribute('src') !== errorUrl) { 12198 tile.src = errorUrl; 12199 } 12200 done(e, tile); 12201 }, 12202 12203 _onTileRemove: function (e) { 12204 e.tile.onload = null; 12205 }, 12206 12207 _getZoomForUrl: function () { 12208 var zoom = this._tileZoom, 12209 maxZoom = this.options.maxZoom, 12210 zoomReverse = this.options.zoomReverse, 12211 zoomOffset = this.options.zoomOffset; 12212 12213 if (zoomReverse) { 12214 zoom = maxZoom - zoom; 12215 } 12216 12217 return zoom + zoomOffset; 12218 }, 12219 12220 _getSubdomain: function (tilePoint) { 12221 var index = Math.abs(tilePoint.x + tilePoint.y) % this.options.subdomains.length; 12222 return this.options.subdomains[index]; 12223 }, 12224 12225 // stops loading all tiles in the background layer 12226 _abortLoading: function () { 12227 var i, tile; 12228 for (i in this._tiles) { 12229 if (this._tiles[i].coords.z !== this._tileZoom) { 12230 tile = this._tiles[i].el; 12231 12232 tile.onload = falseFn; 12233 tile.onerror = falseFn; 12234 12235 if (!tile.complete) { 12236 tile.src = emptyImageUrl; 12237 remove(tile); 12238 delete this._tiles[i]; 12239 } 12240 } 12241 } 12242 }, 12243 12244 _removeTile: function (key) { 12245 var tile = this._tiles[key]; 12246 if (!tile) { return; } 12247 12248 // Cancels any pending http requests associated with the tile 12249 // unless we're on Android's stock browser, 12250 // see https://github.com/Leaflet/Leaflet/issues/137 12251 if (!androidStock) { 12252 tile.el.setAttribute('src', emptyImageUrl); 12253 } 12254 12255 return GridLayer.prototype._removeTile.call(this, key); 12256 }, 12257 12258 _tileReady: function (coords, err, tile) { 12259 if (!this._map || (tile && tile.getAttribute('src') === emptyImageUrl)) { 12260 return; 12261 } 12262 12263 return GridLayer.prototype._tileReady.call(this, coords, err, tile); 12264 } 12265}); 12266 12267 12268// @factory L.tilelayer(urlTemplate: String, options?: TileLayer options) 12269// Instantiates a tile layer object given a `URL template` and optionally an options object. 12270 12271function tileLayer(url, options) { 12272 return new TileLayer(url, options); 12273} 12274 12275/* 12276 * @class TileLayer.WMS 12277 * @inherits TileLayer 12278 * @aka L.TileLayer.WMS 12279 * Used to display [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services as tile layers on the map. Extends `TileLayer`. 12280 * 12281 * @example 12282 * 12283 * ```js 12284 * var nexrad = L.tileLayer.wms("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", { 12285 * layers: 'nexrad-n0r-900913', 12286 * format: 'image/png', 12287 * transparent: true, 12288 * attribution: "Weather data © 2012 IEM Nexrad" 12289 * }); 12290 * ``` 12291 */ 12292 12293 var TileLayerWMS = TileLayer.extend({ 12294 12295 // @section 12296 // @aka TileLayer.WMS options 12297 // If any custom options not documented here are used, they will be sent to the 12298 // WMS server as extra parameters in each request URL. This can be useful for 12299 // [non-standard vendor WMS parameters](http://docs.geoserver.org/stable/en/user/services/wms/vendor.html). 12300 defaultWmsParams: { 12301 service: 'WMS', 12302 request: 'GetMap', 12303 12304 // @option layers: String = '' 12305 // **(required)** Comma-separated list of WMS layers to show. 12306 layers: '', 12307 12308 // @option styles: String = '' 12309 // Comma-separated list of WMS styles. 12310 styles: '', 12311 12312 // @option format: String = 'image/jpeg' 12313 // WMS image format (use `'image/png'` for layers with transparency). 12314 format: 'image/jpeg', 12315 12316 // @option transparent: Boolean = false 12317 // If `true`, the WMS service will return images with transparency. 12318 transparent: false, 12319 12320 // @option version: String = '1.1.1' 12321 // Version of the WMS service to use 12322 version: '1.1.1' 12323 }, 12324 12325 options: { 12326 // @option crs: CRS = null 12327 // Coordinate Reference System to use for the WMS requests, defaults to 12328 // map CRS. Don't change this if you're not sure what it means. 12329 crs: null, 12330 12331 // @option uppercase: Boolean = false 12332 // If `true`, WMS request parameter keys will be uppercase. 12333 uppercase: false 12334 }, 12335 12336 initialize: function (url, options) { 12337 12338 this._url = url; 12339 12340 var wmsParams = extend({}, this.defaultWmsParams); 12341 12342 // all keys that are not TileLayer options go to WMS params 12343 for (var i in options) { 12344 if (!(i in this.options)) { 12345 wmsParams[i] = options[i]; 12346 } 12347 } 12348 12349 options = setOptions(this, options); 12350 12351 var realRetina = options.detectRetina && retina ? 2 : 1; 12352 var tileSize = this.getTileSize(); 12353 wmsParams.width = tileSize.x * realRetina; 12354 wmsParams.height = tileSize.y * realRetina; 12355 12356 this.wmsParams = wmsParams; 12357 }, 12358 12359 onAdd: function (map) { 12360 12361 this._crs = this.options.crs || map.options.crs; 12362 this._wmsVersion = parseFloat(this.wmsParams.version); 12363 12364 var projectionKey = this._wmsVersion >= 1.3 ? 'crs' : 'srs'; 12365 this.wmsParams[projectionKey] = this._crs.code; 12366 12367 TileLayer.prototype.onAdd.call(this, map); 12368 }, 12369 12370 getTileUrl: function (coords) { 12371 12372 var tileBounds = this._tileCoordsToNwSe(coords), 12373 crs = this._crs, 12374 bounds = toBounds(crs.project(tileBounds[0]), crs.project(tileBounds[1])), 12375 min = bounds.min, 12376 max = bounds.max, 12377 bbox = (this._wmsVersion >= 1.3 && this._crs === EPSG4326 ? 12378 [min.y, min.x, max.y, max.x] : 12379 [min.x, min.y, max.x, max.y]).join(','), 12380 url = TileLayer.prototype.getTileUrl.call(this, coords); 12381 return url + 12382 getParamString(this.wmsParams, url, this.options.uppercase) + 12383 (this.options.uppercase ? '&BBOX=' : '&bbox=') + bbox; 12384 }, 12385 12386 // @method setParams(params: Object, noRedraw?: Boolean): this 12387 // Merges an object with the new parameters and re-requests tiles on the current screen (unless `noRedraw` was set to true). 12388 setParams: function (params, noRedraw) { 12389 12390 extend(this.wmsParams, params); 12391 12392 if (!noRedraw) { 12393 this.redraw(); 12394 } 12395 12396 return this; 12397 } 12398}); 12399 12400 12401// @factory L.tileLayer.wms(baseUrl: String, options: TileLayer.WMS options) 12402// Instantiates a WMS tile layer object given a base URL of the WMS service and a WMS parameters/options object. 12403function tileLayerWMS(url, options) { 12404 return new TileLayerWMS(url, options); 12405} 12406 12407TileLayer.WMS = TileLayerWMS; 12408tileLayer.wms = tileLayerWMS; 12409 12410/* 12411 * @class Renderer 12412 * @inherits Layer 12413 * @aka L.Renderer 12414 * 12415 * Base class for vector renderer implementations (`SVG`, `Canvas`). Handles the 12416 * DOM container of the renderer, its bounds, and its zoom animation. 12417 * 12418 * A `Renderer` works as an implicit layer group for all `Path`s - the renderer 12419 * itself can be added or removed to the map. All paths use a renderer, which can 12420 * be implicit (the map will decide the type of renderer and use it automatically) 12421 * or explicit (using the [`renderer`](#path-renderer) option of the path). 12422 * 12423 * Do not use this class directly, use `SVG` and `Canvas` instead. 12424 * 12425 * @event update: Event 12426 * Fired when the renderer updates its bounds, center and zoom, for example when 12427 * its map has moved 12428 */ 12429 12430 var Renderer = Layer.extend({ 12431 12432 // @section 12433 // @aka Renderer options 12434 options: { 12435 // @option padding: Number = 0.1 12436 // How much to extend the clip area around the map view (relative to its size) 12437 // e.g. 0.1 would be 10% of map view in each direction 12438 padding: 0.1, 12439 12440 // @option tolerance: Number = 0 12441 // How much to extend click tolerance round a path/object on the map 12442 tolerance : 0 12443 }, 12444 12445 initialize: function (options) { 12446 setOptions(this, options); 12447 stamp(this); 12448 this._layers = this._layers || {}; 12449 }, 12450 12451 onAdd: function () { 12452 if (!this._container) { 12453 this._initContainer(); // defined by renderer implementations 12454 12455 if (this._zoomAnimated) { 12456 addClass(this._container, 'leaflet-zoom-animated'); 12457 } 12458 } 12459 12460 this.getPane().appendChild(this._container); 12461 this._update(); 12462 this.on('update', this._updatePaths, this); 12463 }, 12464 12465 onRemove: function () { 12466 this.off('update', this._updatePaths, this); 12467 this._destroyContainer(); 12468 }, 12469 12470 getEvents: function () { 12471 var events = { 12472 viewreset: this._reset, 12473 zoom: this._onZoom, 12474 moveend: this._update, 12475 zoomend: this._onZoomEnd 12476 }; 12477 if (this._zoomAnimated) { 12478 events.zoomanim = this._onAnimZoom; 12479 } 12480 return events; 12481 }, 12482 12483 _onAnimZoom: function (ev) { 12484 this._updateTransform(ev.center, ev.zoom); 12485 }, 12486 12487 _onZoom: function () { 12488 this._updateTransform(this._map.getCenter(), this._map.getZoom()); 12489 }, 12490 12491 _updateTransform: function (center, zoom) { 12492 var scale = this._map.getZoomScale(zoom, this._zoom), 12493 position = getPosition(this._container), 12494 viewHalf = this._map.getSize().multiplyBy(0.5 + this.options.padding), 12495 currentCenterPoint = this._map.project(this._center, zoom), 12496 destCenterPoint = this._map.project(center, zoom), 12497 centerOffset = destCenterPoint.subtract(currentCenterPoint), 12498 12499 topLeftOffset = viewHalf.multiplyBy(-scale).add(position).add(viewHalf).subtract(centerOffset); 12500 12501 if (any3d) { 12502 setTransform(this._container, topLeftOffset, scale); 12503 } else { 12504 setPosition(this._container, topLeftOffset); 12505 } 12506 }, 12507 12508 _reset: function () { 12509 this._update(); 12510 this._updateTransform(this._center, this._zoom); 12511 12512 for (var id in this._layers) { 12513 this._layers[id]._reset(); 12514 } 12515}, 12516 12517_onZoomEnd: function () { 12518 for (var id in this._layers) { 12519 this._layers[id]._project(); 12520 } 12521}, 12522 12523_updatePaths: function () { 12524 for (var id in this._layers) { 12525 this._layers[id]._update(); 12526 } 12527}, 12528 12529_update: function () { 12530 // Update pixel bounds of renderer container (for positioning/sizing/clipping later) 12531 // Subclasses are responsible of firing the 'update' event. 12532 var p = this.options.padding, 12533 size = this._map.getSize(), 12534 min = this._map.containerPointToLayerPoint(size.multiplyBy(-p)).round(); 12535 12536 this._bounds = new Bounds(min, min.add(size.multiplyBy(1 + p * 2)).round()); 12537 12538 this._center = this._map.getCenter(); 12539 this._zoom = this._map.getZoom(); 12540 } 12541}); 12542 12543/* 12544 * @class Canvas 12545 * @inherits Renderer 12546 * @aka L.Canvas 12547 * 12548 * Allows vector layers to be displayed with [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API). 12549 * Inherits `Renderer`. 12550 * 12551 * Due to [technical limitations](http://caniuse.com/#search=canvas), Canvas is not 12552 * available in all web browsers, notably IE8, and overlapping geometries might 12553 * not display properly in some edge cases. 12554 * 12555 * @example 12556 * 12557 * Use Canvas by default for all paths in the map: 12558 * 12559 * ```js 12560 * var map = L.map('map', { 12561 * renderer: L.canvas() 12562 * }); 12563 * ``` 12564 * 12565 * Use a Canvas renderer with extra padding for specific vector geometries: 12566 * 12567 * ```js 12568 * var map = L.map('map'); 12569 * var myRenderer = L.canvas({ padding: 0.5 }); 12570 * var line = L.polyline( coordinates, { renderer: myRenderer } ); 12571 * var circle = L.circle( center, { renderer: myRenderer } ); 12572 * ``` 12573 */ 12574 12575 var Canvas = Renderer.extend({ 12576 getEvents: function () { 12577 var events = Renderer.prototype.getEvents.call(this); 12578 events.viewprereset = this._onViewPreReset; 12579 return events; 12580 }, 12581 12582 _onViewPreReset: function () { 12583 // Set a flag so that a viewprereset+moveend+viewreset only updates&redraws once 12584 this._postponeUpdatePaths = true; 12585 }, 12586 12587 onAdd: function () { 12588 Renderer.prototype.onAdd.call(this); 12589 12590 // Redraw vectors since canvas is cleared upon removal, 12591 // in case of removing the renderer itself from the map. 12592 this._draw(); 12593 }, 12594 12595 _initContainer: function () { 12596 var container = this._container = document.createElement('canvas'); 12597 12598 on(container, 'mousemove', throttle(this._onMouseMove, 32, this), this); 12599 on(container, 'click dblclick mousedown mouseup contextmenu', this._onClick, this); 12600 on(container, 'mouseout', this._handleMouseOut, this); 12601 12602 this._ctx = container.getContext('2d'); 12603 }, 12604 12605 _destroyContainer: function () { 12606 cancelAnimFrame(this._redrawRequest); 12607 delete this._ctx; 12608 remove(this._container); 12609 off(this._container); 12610 delete this._container; 12611 }, 12612 12613 _updatePaths: function () { 12614 if (this._postponeUpdatePaths) { return; } 12615 12616 var layer; 12617 this._redrawBounds = null; 12618 for (var id in this._layers) { 12619 layer = this._layers[id]; 12620 layer._update(); 12621 } 12622 this._redraw(); 12623 }, 12624 12625 _update: function () { 12626 if (this._map._animatingZoom && this._bounds) { return; } 12627 12628 Renderer.prototype._update.call(this); 12629 12630 var b = this._bounds, 12631 container = this._container, 12632 size = b.getSize(), 12633 m = retina ? 2 : 1; 12634 12635 setPosition(container, b.min); 12636 12637 // set canvas size (also clearing it); use double size on retina 12638 container.width = m * size.x; 12639 container.height = m * size.y; 12640 container.style.width = size.x + 'px'; 12641 container.style.height = size.y + 'px'; 12642 12643 if (retina) { 12644 this._ctx.scale(2, 2); 12645 } 12646 12647 // translate so we use the same path coordinates after canvas element moves 12648 this._ctx.translate(-b.min.x, -b.min.y); 12649 12650 // Tell paths to redraw themselves 12651 this.fire('update'); 12652 }, 12653 12654 _reset: function () { 12655 Renderer.prototype._reset.call(this); 12656 12657 if (this._postponeUpdatePaths) { 12658 this._postponeUpdatePaths = false; 12659 this._updatePaths(); 12660 } 12661 }, 12662 12663 _initPath: function (layer) { 12664 this._updateDashArray(layer); 12665 this._layers[stamp(layer)] = layer; 12666 12667 var order = layer._order = { 12668 layer: layer, 12669 prev: this._drawLast, 12670 next: null 12671 }; 12672 if (this._drawLast) { this._drawLast.next = order; } 12673 this._drawLast = order; 12674 this._drawFirst = this._drawFirst || this._drawLast; 12675 }, 12676 12677 _addPath: function (layer) { 12678 this._requestRedraw(layer); 12679 }, 12680 12681 _removePath: function (layer) { 12682 var order = layer._order; 12683 var next = order.next; 12684 var prev = order.prev; 12685 12686 if (next) { 12687 next.prev = prev; 12688 } else { 12689 this._drawLast = prev; 12690 } 12691 if (prev) { 12692 prev.next = next; 12693 } else { 12694 this._drawFirst = next; 12695 } 12696 12697 delete layer._order; 12698 12699 delete this._layers[stamp(layer)]; 12700 12701 this._requestRedraw(layer); 12702 }, 12703 12704 _updatePath: function (layer) { 12705 // Redraw the union of the layer's old pixel 12706 // bounds and the new pixel bounds. 12707 this._extendRedrawBounds(layer); 12708 layer._project(); 12709 layer._update(); 12710 // The redraw will extend the redraw bounds 12711 // with the new pixel bounds. 12712 this._requestRedraw(layer); 12713 }, 12714 12715 _updateStyle: function (layer) { 12716 this._updateDashArray(layer); 12717 this._requestRedraw(layer); 12718 }, 12719 12720 _updateDashArray: function (layer) { 12721 if (typeof layer.options.dashArray === 'string') { 12722 var parts = layer.options.dashArray.split(/[, ]+/), 12723 dashArray = [], 12724 dashValue, 12725 i; 12726 for (i = 0; i < parts.length; i++) { 12727 dashValue = Number(parts[i]); 12728 // Ignore dash array containing invalid lengths 12729 if (isNaN(dashValue)) { return; } 12730 dashArray.push(dashValue); 12731 } 12732 layer.options._dashArray = dashArray; 12733 } else { 12734 layer.options._dashArray = layer.options.dashArray; 12735 } 12736 }, 12737 12738 _requestRedraw: function (layer) { 12739 if (!this._map) { return; } 12740 12741 this._extendRedrawBounds(layer); 12742 this._redrawRequest = this._redrawRequest || requestAnimFrame(this._redraw, this); 12743 }, 12744 12745 _extendRedrawBounds: function (layer) { 12746 if (layer._pxBounds) { 12747 var padding = (layer.options.weight || 0) + 1; 12748 this._redrawBounds = this._redrawBounds || new Bounds(); 12749 this._redrawBounds.extend(layer._pxBounds.min.subtract([padding, padding])); 12750 this._redrawBounds.extend(layer._pxBounds.max.add([padding, padding])); 12751 } 12752 }, 12753 12754 _redraw: function () { 12755 this._redrawRequest = null; 12756 12757 if (this._redrawBounds) { 12758 this._redrawBounds.min._floor(); 12759 this._redrawBounds.max._ceil(); 12760 } 12761 12762 this._clear(); // clear layers in redraw bounds 12763 this._draw(); // draw layers 12764 12765 this._redrawBounds = null; 12766 }, 12767 12768 _clear: function () { 12769 var bounds = this._redrawBounds; 12770 if (bounds) { 12771 var size = bounds.getSize(); 12772 this._ctx.clearRect(bounds.min.x, bounds.min.y, size.x, size.y); 12773 } else { 12774 this._ctx.clearRect(0, 0, this._container.width, this._container.height); 12775 } 12776 }, 12777 12778 _draw: function () { 12779 var layer, bounds = this._redrawBounds; 12780 this._ctx.save(); 12781 if (bounds) { 12782 var size = bounds.getSize(); 12783 this._ctx.beginPath(); 12784 this._ctx.rect(bounds.min.x, bounds.min.y, size.x, size.y); 12785 this._ctx.clip(); 12786 } 12787 12788 this._drawing = true; 12789 12790 for (var order = this._drawFirst; order; order = order.next) { 12791 layer = order.layer; 12792 if (!bounds || (layer._pxBounds && layer._pxBounds.intersects(bounds))) { 12793 layer._updatePath(); 12794 } 12795 } 12796 12797 this._drawing = false; 12798 12799 this._ctx.restore(); // Restore state before clipping. 12800 }, 12801 12802 _updatePoly: function (layer, closed) { 12803 if (!this._drawing) { return; } 12804 12805 var i, j, len2, p, 12806 parts = layer._parts, 12807 len = parts.length, 12808 ctx = this._ctx; 12809 12810 if (!len) { return; } 12811 12812 ctx.beginPath(); 12813 12814 for (i = 0; i < len; i++) { 12815 for (j = 0, len2 = parts[i].length; j < len2; j++) { 12816 p = parts[i][j]; 12817 ctx[j ? 'lineTo' : 'moveTo'](p.x, p.y); 12818 } 12819 if (closed) { 12820 ctx.closePath(); 12821 } 12822 } 12823 12824 this._fillStroke(ctx, layer); 12825 12826 // TODO optimization: 1 fill/stroke for all features with equal style instead of 1 for each feature 12827 }, 12828 12829 _updateCircle: function (layer) { 12830 12831 if (!this._drawing || layer._empty()) { return; } 12832 12833 var p = layer._point, 12834 ctx = this._ctx, 12835 r = Math.max(Math.round(layer._radius), 1), 12836 s = (Math.max(Math.round(layer._radiusY), 1) || r) / r; 12837 12838 if (s !== 1) { 12839 ctx.save(); 12840 ctx.scale(1, s); 12841 } 12842 12843 ctx.beginPath(); 12844 ctx.arc(p.x, p.y / s, r, 0, Math.PI * 2, false); 12845 12846 if (s !== 1) { 12847 ctx.restore(); 12848 } 12849 12850 this._fillStroke(ctx, layer); 12851 }, 12852 12853 _fillStroke: function (ctx, layer) { 12854 var options = layer.options; 12855 12856 if (options.fill) { 12857 ctx.globalAlpha = options.fillOpacity; 12858 ctx.fillStyle = options.fillColor || options.color; 12859 ctx.fill(options.fillRule || 'evenodd'); 12860 } 12861 12862 if (options.stroke && options.weight !== 0) { 12863 if (ctx.setLineDash) { 12864 ctx.setLineDash(layer.options && layer.options._dashArray || []); 12865 } 12866 ctx.globalAlpha = options.opacity; 12867 ctx.lineWidth = options.weight; 12868 ctx.strokeStyle = options.color; 12869 ctx.lineCap = options.lineCap; 12870 ctx.lineJoin = options.lineJoin; 12871 ctx.stroke(); 12872} 12873}, 12874 12875 // Canvas obviously doesn't have mouse events for individual drawn objects, 12876 // so we emulate that by calculating what's under the mouse on mousemove/click manually 12877 12878 _onClick: function (e) { 12879 var point = this._map.mouseEventToLayerPoint(e), layer, clickedLayer; 12880 12881 for (var order = this._drawFirst; order; order = order.next) { 12882 layer = order.layer; 12883 if (layer.options.interactive && layer._containsPoint(point) && !this._map._draggableMoved(layer)) { 12884 clickedLayer = layer; 12885 } 12886 } 12887 if (clickedLayer) { 12888 fakeStop(e); 12889 this._fireEvent([clickedLayer], e); 12890 } 12891 }, 12892 12893 _onMouseMove: function (e) { 12894 if (!this._map || this._map.dragging.moving() || this._map._animatingZoom) { return; } 12895 12896 var point = this._map.mouseEventToLayerPoint(e); 12897 this._handleMouseHover(e, point); 12898 }, 12899 12900 12901 _handleMouseOut: function (e) { 12902 var layer = this._hoveredLayer; 12903 if (layer) { 12904 // if we're leaving the layer, fire mouseout 12905 removeClass(this._container, 'leaflet-interactive'); 12906 this._fireEvent([layer], e, 'mouseout'); 12907 this._hoveredLayer = null; 12908 } 12909 }, 12910 12911 _handleMouseHover: function (e, point) { 12912 var layer, candidateHoveredLayer; 12913 12914 for (var order = this._drawFirst; order; order = order.next) { 12915 layer = order.layer; 12916 if (layer.options.interactive && layer._containsPoint(point)) { 12917 candidateHoveredLayer = layer; 12918 } 12919 } 12920 12921 if (candidateHoveredLayer !== this._hoveredLayer) { 12922 this._handleMouseOut(e); 12923 12924 if (candidateHoveredLayer) { 12925 addClass(this._container, 'leaflet-interactive'); // change cursor 12926 this._fireEvent([candidateHoveredLayer], e, 'mouseover'); 12927 this._hoveredLayer = candidateHoveredLayer; 12928 } 12929 } 12930 12931 if (this._hoveredLayer) { 12932 this._fireEvent([this._hoveredLayer], e); 12933 } 12934 }, 12935 12936 _fireEvent: function (layers, e, type) { 12937 this._map._fireDOMEvent(e, type || e.type, layers); 12938 }, 12939 12940 _bringToFront: function (layer) { 12941 var order = layer._order; 12942 12943 if (!order) { return; } 12944 12945 var next = order.next; 12946 var prev = order.prev; 12947 12948 if (next) { 12949 next.prev = prev; 12950 } else { 12951 // Already last 12952 return; 12953 } 12954 if (prev) { 12955 prev.next = next; 12956 } else if (next) { 12957 // Update first entry unless this is the 12958 // single entry 12959 this._drawFirst = next; 12960 } 12961 12962 order.prev = this._drawLast; 12963 this._drawLast.next = order; 12964 12965 order.next = null; 12966 this._drawLast = order; 12967 12968 this._requestRedraw(layer); 12969 }, 12970 12971 _bringToBack: function (layer) { 12972 var order = layer._order; 12973 12974 if (!order) { return; } 12975 12976 var next = order.next; 12977 var prev = order.prev; 12978 12979 if (prev) { 12980 prev.next = next; 12981 } else { 12982 // Already first 12983 return; 12984 } 12985 if (next) { 12986 next.prev = prev; 12987 } else if (prev) { 12988 // Update last entry unless this is the 12989 // single entry 12990 this._drawLast = prev; 12991 } 12992 12993 order.prev = null; 12994 12995 order.next = this._drawFirst; 12996 this._drawFirst.prev = order; 12997 this._drawFirst = order; 12998 12999 this._requestRedraw(layer); 13000 } 13001}); 13002 13003// @factory L.canvas(options?: Renderer options) 13004// Creates a Canvas renderer with the given options. 13005function canvas$1(options) { 13006 return canvas ? new Canvas(options) : null; 13007} 13008 13009/* 13010 * Thanks to Dmitry Baranovsky and his Raphael library for inspiration! 13011 */ 13012 13013 13014 var vmlCreate = (function () { 13015 try { 13016 document.namespaces.add('lvml', 'urn:schemas-microsoft-com:vml'); 13017 return function (name) { 13018 return document.createElement('<lvml:' + name + ' class="lvml">'); 13019 }; 13020 } catch (e) { 13021 return function (name) { 13022 return document.createElement('<' + name + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">'); 13023 }; 13024} 13025})(); 13026 13027 13028/* 13029 * @class SVG 13030 * 13031 * 13032 * VML was deprecated in 2012, which means VML functionality exists only for backwards compatibility 13033 * with old versions of Internet Explorer. 13034 */ 13035 13036// mixin to redefine some SVG methods to handle VML syntax which is similar but with some differences 13037var vmlMixin = { 13038 13039 _initContainer: function () { 13040 this._container = create$1('div', 'leaflet-vml-container'); 13041 }, 13042 13043 _update: function () { 13044 if (this._map._animatingZoom) { return; } 13045 Renderer.prototype._update.call(this); 13046 this.fire('update'); 13047 }, 13048 13049 _initPath: function (layer) { 13050 var container = layer._container = vmlCreate('shape'); 13051 13052 addClass(container, 'leaflet-vml-shape ' + (this.options.className || '')); 13053 13054 container.coordsize = '1 1'; 13055 13056 layer._path = vmlCreate('path'); 13057 container.appendChild(layer._path); 13058 13059 this._updateStyle(layer); 13060 this._layers[stamp(layer)] = layer; 13061 }, 13062 13063 _addPath: function (layer) { 13064 var container = layer._container; 13065 this._container.appendChild(container); 13066 13067 if (layer.options.interactive) { 13068 layer.addInteractiveTarget(container); 13069 } 13070 }, 13071 13072 _removePath: function (layer) { 13073 var container = layer._container; 13074 remove(container); 13075 layer.removeInteractiveTarget(container); 13076 delete this._layers[stamp(layer)]; 13077 }, 13078 13079 _updateStyle: function (layer) { 13080 var stroke = layer._stroke, 13081 fill = layer._fill, 13082 options = layer.options, 13083 container = layer._container; 13084 13085 container.stroked = !!options.stroke; 13086 container.filled = !!options.fill; 13087 13088 if (options.stroke) { 13089 if (!stroke) { 13090 stroke = layer._stroke = vmlCreate('stroke'); 13091 } 13092 container.appendChild(stroke); 13093 stroke.weight = options.weight + 'px'; 13094 stroke.color = options.color; 13095 stroke.opacity = options.opacity; 13096 13097 if (options.dashArray) { 13098 stroke.dashStyle = isArray(options.dashArray) ? 13099 options.dashArray.join(' ') : 13100 options.dashArray.replace(/( *, *)/g, ' '); 13101 } else { 13102 stroke.dashStyle = ''; 13103 } 13104 stroke.endcap = options.lineCap.replace('butt', 'flat'); 13105 stroke.joinstyle = options.lineJoin; 13106 13107 } else if (stroke) { 13108 container.removeChild(stroke); 13109 layer._stroke = null; 13110 } 13111 13112 if (options.fill) { 13113 if (!fill) { 13114 fill = layer._fill = vmlCreate('fill'); 13115 } 13116 container.appendChild(fill); 13117 fill.color = options.fillColor || options.color; 13118 fill.opacity = options.fillOpacity; 13119 13120} else if (fill) { 13121 container.removeChild(fill); 13122 layer._fill = null; 13123} 13124}, 13125 13126_updateCircle: function (layer) { 13127 var p = layer._point.round(), 13128 r = Math.round(layer._radius), 13129 r2 = Math.round(layer._radiusY || r); 13130 13131 this._setPath(layer, layer._empty() ? 'M0 0' : 13132 'AL ' + p.x + ',' + p.y + ' ' + r + ',' + r2 + ' 0,' + (65535 * 360)); 13133}, 13134 13135_setPath: function (layer, path) { 13136 layer._path.v = path; 13137}, 13138 13139_bringToFront: function (layer) { 13140 toFront(layer._container); 13141}, 13142 13143_bringToBack: function (layer) { 13144 toBack(layer._container); 13145} 13146}; 13147 13148var create$2 = vml ? vmlCreate : svgCreate; 13149 13150/* 13151 * @class SVG 13152 * @inherits Renderer 13153 * @aka L.SVG 13154 * 13155 * Allows vector layers to be displayed with [SVG](https://developer.mozilla.org/docs/Web/SVG). 13156 * Inherits `Renderer`. 13157 * 13158 * Due to [technical limitations](http://caniuse.com/#search=svg), SVG is not 13159 * available in all web browsers, notably Android 2.x and 3.x. 13160 * 13161 * Although SVG is not available on IE7 and IE8, these browsers support 13162 * [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language) 13163 * (a now deprecated technology), and the SVG renderer will fall back to VML in 13164 * this case. 13165 * 13166 * @example 13167 * 13168 * Use SVG by default for all paths in the map: 13169 * 13170 * ```js 13171 * var map = L.map('map', { 13172 * renderer: L.svg() 13173 * }); 13174 * ``` 13175 * 13176 * Use a SVG renderer with extra padding for specific vector geometries: 13177 * 13178 * ```js 13179 * var map = L.map('map'); 13180 * var myRenderer = L.svg({ padding: 0.5 }); 13181 * var line = L.polyline( coordinates, { renderer: myRenderer } ); 13182 * var circle = L.circle( center, { renderer: myRenderer } ); 13183 * ``` 13184 */ 13185 13186 var SVG = Renderer.extend({ 13187 13188 getEvents: function () { 13189 var events = Renderer.prototype.getEvents.call(this); 13190 events.zoomstart = this._onZoomStart; 13191 return events; 13192 }, 13193 13194 _initContainer: function () { 13195 this._container = create$2('svg'); 13196 13197 // makes it possible to click through svg root; we'll reset it back in individual paths 13198 this._container.setAttribute('pointer-events', 'none'); 13199 13200 this._rootGroup = create$2('g'); 13201 this._container.appendChild(this._rootGroup); 13202 }, 13203 13204 _destroyContainer: function () { 13205 remove(this._container); 13206 off(this._container); 13207 delete this._container; 13208 delete this._rootGroup; 13209 delete this._svgSize; 13210 }, 13211 13212 _onZoomStart: function () { 13213 // Drag-then-pinch interactions might mess up the center and zoom. 13214 // In this case, the easiest way to prevent this is re-do the renderer 13215 // bounds and padding when the zooming starts. 13216 this._update(); 13217 }, 13218 13219 _update: function () { 13220 if (this._map._animatingZoom && this._bounds) { return; } 13221 13222 Renderer.prototype._update.call(this); 13223 13224 var b = this._bounds, 13225 size = b.getSize(), 13226 container = this._container; 13227 13228 // set size of svg-container if changed 13229 if (!this._svgSize || !this._svgSize.equals(size)) { 13230 this._svgSize = size; 13231 container.setAttribute('width', size.x); 13232 container.setAttribute('height', size.y); 13233 } 13234 13235 // movement: update container viewBox so that we don't have to change coordinates of individual layers 13236 setPosition(container, b.min); 13237 container.setAttribute('viewBox', [b.min.x, b.min.y, size.x, size.y].join(' ')); 13238 13239 this.fire('update'); 13240 }, 13241 13242 // methods below are called by vector layers implementations 13243 13244 _initPath: function (layer) { 13245 var path = layer._path = create$2('path'); 13246 13247 // @namespace Path 13248 // @option className: String = null 13249 // Custom class name set on an element. Only for SVG renderer. 13250 if (layer.options.className) { 13251 addClass(path, layer.options.className); 13252 } 13253 13254 if (layer.options.interactive) { 13255 addClass(path, 'leaflet-interactive'); 13256 } 13257 13258 this._updateStyle(layer); 13259 this._layers[stamp(layer)] = layer; 13260 }, 13261 13262 _addPath: function (layer) { 13263 if (!this._rootGroup) { this._initContainer(); } 13264 this._rootGroup.appendChild(layer._path); 13265 layer.addInteractiveTarget(layer._path); 13266 }, 13267 13268 _removePath: function (layer) { 13269 remove(layer._path); 13270 layer.removeInteractiveTarget(layer._path); 13271 delete this._layers[stamp(layer)]; 13272 }, 13273 13274 _updatePath: function (layer) { 13275 layer._project(); 13276 layer._update(); 13277 }, 13278 13279 _updateStyle: function (layer) { 13280 var path = layer._path, 13281 options = layer.options; 13282 13283 if (!path) { return; } 13284 13285 if (options.stroke) { 13286 path.setAttribute('stroke', options.color); 13287 path.setAttribute('stroke-opacity', options.opacity); 13288 path.setAttribute('stroke-width', options.weight); 13289 path.setAttribute('stroke-linecap', options.lineCap); 13290 path.setAttribute('stroke-linejoin', options.lineJoin); 13291 13292 if (options.dashArray) { 13293 path.setAttribute('stroke-dasharray', options.dashArray); 13294 } else { 13295 path.removeAttribute('stroke-dasharray'); 13296 } 13297 13298 if (options.dashOffset) { 13299 path.setAttribute('stroke-dashoffset', options.dashOffset); 13300 } else { 13301 path.removeAttribute('stroke-dashoffset'); 13302 } 13303 } else { 13304 path.setAttribute('stroke', 'none'); 13305 } 13306 13307 if (options.fill) { 13308 path.setAttribute('fill', options.fillColor || options.color); 13309 path.setAttribute('fill-opacity', options.fillOpacity); 13310 path.setAttribute('fill-rule', options.fillRule || 'evenodd'); 13311 } else { 13312 path.setAttribute('fill', 'none'); 13313 } 13314}, 13315 13316_updatePoly: function (layer, closed) { 13317 this._setPath(layer, pointsToPath(layer._parts, closed)); 13318}, 13319 13320_updateCircle: function (layer) { 13321 var p = layer._point, 13322 r = Math.max(Math.round(layer._radius), 1), 13323 r2 = Math.max(Math.round(layer._radiusY), 1) || r, 13324 arc = 'a' + r + ',' + r2 + ' 0 1,0 '; 13325 13326 // drawing a circle with two half-arcs 13327 var d = layer._empty() ? 'M0 0' : 13328 'M' + (p.x - r) + ',' + p.y + 13329 arc + (r * 2) + ',0 ' + 13330 arc + (-r * 2) + ',0 '; 13331 13332 this._setPath(layer, d); 13333 }, 13334 13335 _setPath: function (layer, path) { 13336 layer._path.setAttribute('d', path); 13337}, 13338 13339 // SVG does not have the concept of zIndex so we resort to changing the DOM order of elements 13340 _bringToFront: function (layer) { 13341 toFront(layer._path); 13342 }, 13343 13344 _bringToBack: function (layer) { 13345 toBack(layer._path); 13346 } 13347}); 13348 13349if (vml) { 13350 SVG.include(vmlMixin); 13351} 13352 13353// @namespace SVG 13354// @factory L.svg(options?: Renderer options) 13355// Creates a SVG renderer with the given options. 13356function svg$1(options) { 13357 return svg || vml ? new SVG(options) : null; 13358} 13359 13360Map.include({ 13361 // @namespace Map; @method getRenderer(layer: Path): Renderer 13362 // Returns the instance of `Renderer` that should be used to render the given 13363 // `Path`. It will ensure that the `renderer` options of the map and paths 13364 // are respected, and that the renderers do exist on the map. 13365 getRenderer: function (layer) { 13366 // @namespace Path; @option renderer: Renderer 13367 // Use this specific instance of `Renderer` for this path. Takes 13368 // precedence over the map's [default renderer](#map-renderer). 13369 var renderer = layer.options.renderer || this._getPaneRenderer(layer.options.pane) || this.options.renderer || this._renderer; 13370 13371 if (!renderer) { 13372 renderer = this._renderer = this._createRenderer(); 13373 } 13374 13375 if (!this.hasLayer(renderer)) { 13376 this.addLayer(renderer); 13377 } 13378 return renderer; 13379 }, 13380 13381 _getPaneRenderer: function (name) { 13382 if (name === 'overlayPane' || name === undefined) { 13383 return false; 13384 } 13385 13386 var renderer = this._paneRenderers[name]; 13387 if (renderer === undefined) { 13388 renderer = this._createRenderer({pane: name}); 13389 this._paneRenderers[name] = renderer; 13390 } 13391 return renderer; 13392 }, 13393 13394 _createRenderer: function (options) { 13395 // @namespace Map; @option preferCanvas: Boolean = false 13396 // Whether `Path`s should be rendered on a `Canvas` renderer. 13397 // By default, all `Path`s are rendered in a `SVG` renderer. 13398 return (this.options.preferCanvas && canvas$1(options)) || svg$1(options); 13399 } 13400}); 13401 13402/* 13403 * L.Rectangle extends Polygon and creates a rectangle when passed a LatLngBounds object. 13404 */ 13405 13406/* 13407 * @class Rectangle 13408 * @aka L.Rectangle 13409 * @inherits Polygon 13410 * 13411 * A class for drawing rectangle overlays on a map. Extends `Polygon`. 13412 * 13413 * @example 13414 * 13415 * ```js 13416 * // define rectangle geographical bounds 13417 * var bounds = [[54.559322, -5.767822], [56.1210604, -3.021240]]; 13418 * 13419 * // create an orange rectangle 13420 * L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(map); 13421 * 13422 * // zoom the map to the rectangle bounds 13423 * map.fitBounds(bounds); 13424 * ``` 13425 * 13426 */ 13427 13428 13429 var Rectangle = Polygon.extend({ 13430 initialize: function (latLngBounds, options) { 13431 Polygon.prototype.initialize.call(this, this._boundsToLatLngs(latLngBounds), options); 13432 }, 13433 13434 // @method setBounds(latLngBounds: LatLngBounds): this 13435 // Redraws the rectangle with the passed bounds. 13436 setBounds: function (latLngBounds) { 13437 return this.setLatLngs(this._boundsToLatLngs(latLngBounds)); 13438 }, 13439 13440 _boundsToLatLngs: function (latLngBounds) { 13441 latLngBounds = toLatLngBounds(latLngBounds); 13442 return [ 13443 latLngBounds.getSouthWest(), 13444 latLngBounds.getNorthWest(), 13445 latLngBounds.getNorthEast(), 13446 latLngBounds.getSouthEast() 13447 ]; 13448 } 13449}); 13450 13451 13452// @factory L.rectangle(latLngBounds: LatLngBounds, options?: Polyline options) 13453function rectangle(latLngBounds, options) { 13454 return new Rectangle(latLngBounds, options); 13455} 13456 13457SVG.create = create$2; 13458SVG.pointsToPath = pointsToPath; 13459 13460GeoJSON.geometryToLayer = geometryToLayer; 13461GeoJSON.coordsToLatLng = coordsToLatLng; 13462GeoJSON.coordsToLatLngs = coordsToLatLngs; 13463GeoJSON.latLngToCoords = latLngToCoords; 13464GeoJSON.latLngsToCoords = latLngsToCoords; 13465GeoJSON.getFeature = getFeature; 13466GeoJSON.asFeature = asFeature; 13467 13468/* 13469 * L.Handler.BoxZoom is used to add shift-drag zoom interaction to the map 13470 * (zoom to a selected bounding box), enabled by default. 13471 */ 13472 13473// @namespace Map 13474// @section Interaction Options 13475Map.mergeOptions({ 13476 // @option boxZoom: Boolean = true 13477 // Whether the map can be zoomed to a rectangular area specified by 13478 // dragging the mouse while pressing the shift key. 13479 boxZoom: true 13480}); 13481 13482var BoxZoom = Handler.extend({ 13483 initialize: function (map) { 13484 this._map = map; 13485 this._container = map._container; 13486 this._pane = map._panes.overlayPane; 13487 this._resetStateTimeout = 0; 13488 map.on('unload', this._destroy, this); 13489 }, 13490 13491 addHooks: function () { 13492 on(this._container, 'mousedown', this._onMouseDown, this); 13493 }, 13494 13495 removeHooks: function () { 13496 off(this._container, 'mousedown', this._onMouseDown, this); 13497 }, 13498 13499 moved: function () { 13500 return this._moved; 13501 }, 13502 13503 _destroy: function () { 13504 remove(this._pane); 13505 delete this._pane; 13506 }, 13507 13508 _resetState: function () { 13509 this._resetStateTimeout = 0; 13510 this._moved = false; 13511 }, 13512 13513 _clearDeferredResetState: function () { 13514 if (this._resetStateTimeout !== 0) { 13515 clearTimeout(this._resetStateTimeout); 13516 this._resetStateTimeout = 0; 13517 } 13518 }, 13519 13520 _onMouseDown: function (e) { 13521 if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; } 13522 13523 // Clear the deferred resetState if it hasn't executed yet, otherwise it 13524 // will interrupt the interaction and orphan a box element in the container. 13525 this._clearDeferredResetState(); 13526 this._resetState(); 13527 13528 disableTextSelection(); 13529 disableImageDrag(); 13530 13531 this._startPoint = this._map.mouseEventToContainerPoint(e); 13532 13533 on(document, { 13534 contextmenu: stop, 13535 mousemove: this._onMouseMove, 13536 mouseup: this._onMouseUp, 13537 keydown: this._onKeyDown 13538 }, this); 13539 }, 13540 13541 _onMouseMove: function (e) { 13542 if (!this._moved) { 13543 this._moved = true; 13544 13545 this._box = create$1('div', 'leaflet-zoom-box', this._container); 13546 addClass(this._container, 'leaflet-crosshair'); 13547 13548 this._map.fire('boxzoomstart'); 13549 } 13550 13551 this._point = this._map.mouseEventToContainerPoint(e); 13552 13553 var bounds = new Bounds(this._point, this._startPoint), 13554 size = bounds.getSize(); 13555 13556 setPosition(this._box, bounds.min); 13557 13558 this._box.style.width = size.x + 'px'; 13559 this._box.style.height = size.y + 'px'; 13560 }, 13561 13562 _finish: function () { 13563 if (this._moved) { 13564 remove(this._box); 13565 removeClass(this._container, 'leaflet-crosshair'); 13566 } 13567 13568 enableTextSelection(); 13569 enableImageDrag(); 13570 13571 off(document, { 13572 contextmenu: stop, 13573 mousemove: this._onMouseMove, 13574 mouseup: this._onMouseUp, 13575 keydown: this._onKeyDown 13576 }, this); 13577 }, 13578 13579 _onMouseUp: function (e) { 13580 if ((e.which !== 1) && (e.button !== 1)) { return; } 13581 13582 this._finish(); 13583 13584 if (!this._moved) { return; } 13585 // Postpone to next JS tick so internal click event handling 13586 // still see it as "moved". 13587 this._clearDeferredResetState(); 13588 this._resetStateTimeout = setTimeout(bind(this._resetState, this), 0); 13589 13590 var bounds = new LatLngBounds( 13591 this._map.containerPointToLatLng(this._startPoint), 13592 this._map.containerPointToLatLng(this._point)); 13593 13594 this._map 13595 .fitBounds(bounds) 13596 .fire('boxzoomend', {boxZoomBounds: bounds}); 13597 }, 13598 13599 _onKeyDown: function (e) { 13600 if (e.keyCode === 27) { 13601 this._finish(); 13602 } 13603} 13604}); 13605 13606// @section Handlers 13607// @property boxZoom: Handler 13608// Box (shift-drag with mouse) zoom handler. 13609Map.addInitHook('addHandler', 'boxZoom', BoxZoom); 13610 13611/* 13612 * L.Handler.DoubleClickZoom is used to handle double-click zoom on the map, enabled by default. 13613 */ 13614 13615// @namespace Map 13616// @section Interaction Options 13617 13618Map.mergeOptions({ 13619 // @option doubleClickZoom: Boolean|String = true 13620 // Whether the map can be zoomed in by double clicking on it and 13621 // zoomed out by double clicking while holding shift. If passed 13622 // `'center'`, double-click zoom will zoom to the center of the 13623 // view regardless of where the mouse was. 13624 doubleClickZoom: true 13625}); 13626 13627var DoubleClickZoom = Handler.extend({ 13628 addHooks: function () { 13629 this._map.on('dblclick', this._onDoubleClick, this); 13630 }, 13631 13632 removeHooks: function () { 13633 this._map.off('dblclick', this._onDoubleClick, this); 13634 }, 13635 13636 _onDoubleClick: function (e) { 13637 var map = this._map, 13638 oldZoom = map.getZoom(), 13639 delta = map.options.zoomDelta, 13640 zoom = e.originalEvent.shiftKey ? oldZoom - delta : oldZoom + delta; 13641 13642 if (map.options.doubleClickZoom === 'center') { 13643 map.setZoom(zoom); 13644 } else { 13645 map.setZoomAround(e.containerPoint, zoom); 13646 } 13647 } 13648}); 13649 13650// @section Handlers 13651// 13652// Map properties include interaction handlers that allow you to control 13653// interaction behavior in runtime, enabling or disabling certain features such 13654// as dragging or touch zoom (see `Handler` methods). For example: 13655// 13656// ```js 13657// map.doubleClickZoom.disable(); 13658// ``` 13659// 13660// @property doubleClickZoom: Handler 13661// Double click zoom handler. 13662Map.addInitHook('addHandler', 'doubleClickZoom', DoubleClickZoom); 13663 13664/* 13665 * L.Handler.MapDrag is used to make the map draggable (with panning inertia), enabled by default. 13666 */ 13667 13668// @namespace Map 13669// @section Interaction Options 13670Map.mergeOptions({ 13671 // @option dragging: Boolean = true 13672 // Whether the map be draggable with mouse/touch or not. 13673 dragging: true, 13674 13675 // @section Panning Inertia Options 13676 // @option inertia: Boolean = * 13677 // If enabled, panning of the map will have an inertia effect where 13678 // the map builds momentum while dragging and continues moving in 13679 // the same direction for some time. Feels especially nice on touch 13680 // devices. Enabled by default unless running on old Android devices. 13681 inertia: !android23, 13682 13683 // @option inertiaDeceleration: Number = 3000 13684 // The rate with which the inertial movement slows down, in pixels/second². 13685 inertiaDeceleration: 3400, // px/s^2 13686 13687 // @option inertiaMaxSpeed: Number = Infinity 13688 // Max speed of the inertial movement, in pixels/second. 13689 inertiaMaxSpeed: Infinity, // px/s 13690 13691 // @option easeLinearity: Number = 0.2 13692 easeLinearity: 0.2, 13693 13694 // TODO refactor, move to CRS 13695 // @option worldCopyJump: Boolean = false 13696 // With this option enabled, the map tracks when you pan to another "copy" 13697 // of the world and seamlessly jumps to the original one so that all overlays 13698 // like markers and vector layers are still visible. 13699 worldCopyJump: false, 13700 13701 // @option maxBoundsViscosity: Number = 0.0 13702 // If `maxBounds` is set, this option will control how solid the bounds 13703 // are when dragging the map around. The default value of `0.0` allows the 13704 // user to drag outside the bounds at normal speed, higher values will 13705 // slow down map dragging outside bounds, and `1.0` makes the bounds fully 13706 // solid, preventing the user from dragging outside the bounds. 13707 maxBoundsViscosity: 0.0 13708}); 13709 13710var Drag = Handler.extend({ 13711 addHooks: function () { 13712 if (!this._draggable) { 13713 var map = this._map; 13714 13715 this._draggable = new Draggable(map._mapPane, map._container); 13716 13717 this._draggable.on({ 13718 dragstart: this._onDragStart, 13719 drag: this._onDrag, 13720 dragend: this._onDragEnd 13721 }, this); 13722 13723 this._draggable.on('predrag', this._onPreDragLimit, this); 13724 if (map.options.worldCopyJump) { 13725 this._draggable.on('predrag', this._onPreDragWrap, this); 13726 map.on('zoomend', this._onZoomEnd, this); 13727 13728 map.whenReady(this._onZoomEnd, this); 13729 } 13730 } 13731 addClass(this._map._container, 'leaflet-grab leaflet-touch-drag'); 13732 this._draggable.enable(); 13733 this._positions = []; 13734 this._times = []; 13735 }, 13736 13737 removeHooks: function () { 13738 removeClass(this._map._container, 'leaflet-grab'); 13739 removeClass(this._map._container, 'leaflet-touch-drag'); 13740 this._draggable.disable(); 13741 }, 13742 13743 moved: function () { 13744 return this._draggable && this._draggable._moved; 13745 }, 13746 13747 moving: function () { 13748 return this._draggable && this._draggable._moving; 13749 }, 13750 13751 _onDragStart: function () { 13752 var map = this._map; 13753 13754 map._stop(); 13755 if (this._map.options.maxBounds && this._map.options.maxBoundsViscosity) { 13756 var bounds = toLatLngBounds(this._map.options.maxBounds); 13757 13758 this._offsetLimit = toBounds( 13759 this._map.latLngToContainerPoint(bounds.getNorthWest()).multiplyBy(-1), 13760 this._map.latLngToContainerPoint(bounds.getSouthEast()).multiplyBy(-1) 13761 .add(this._map.getSize())); 13762 13763 this._viscosity = Math.min(1.0, Math.max(0.0, this._map.options.maxBoundsViscosity)); 13764 } else { 13765 this._offsetLimit = null; 13766 } 13767 13768 map 13769 .fire('movestart') 13770 .fire('dragstart'); 13771 13772 if (map.options.inertia) { 13773 this._positions = []; 13774 this._times = []; 13775 } 13776 }, 13777 13778 _onDrag: function (e) { 13779 if (this._map.options.inertia) { 13780 var time = this._lastTime = +new Date(), 13781 pos = this._lastPos = this._draggable._absPos || this._draggable._newPos; 13782 13783 this._positions.push(pos); 13784 this._times.push(time); 13785 13786 this._prunePositions(time); 13787 } 13788 13789 this._map 13790 .fire('move', e) 13791 .fire('drag', e); 13792}, 13793 13794_prunePositions: function (time) { 13795 while (this._positions.length > 1 && time - this._times[0] > 50) { 13796 this._positions.shift(); 13797 this._times.shift(); 13798 } 13799}, 13800 13801_onZoomEnd: function () { 13802 var pxCenter = this._map.getSize().divideBy(2), 13803 pxWorldCenter = this._map.latLngToLayerPoint([0, 0]); 13804 13805 this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x; 13806 this._worldWidth = this._map.getPixelWorldBounds().getSize().x; 13807}, 13808 13809_viscousLimit: function (value, threshold) { 13810 return value - (value - threshold) * this._viscosity; 13811}, 13812 13813_onPreDragLimit: function () { 13814 if (!this._viscosity || !this._offsetLimit) { return; } 13815 13816 var offset = this._draggable._newPos.subtract(this._draggable._startPos); 13817 13818 var limit = this._offsetLimit; 13819 if (offset.x < limit.min.x) { offset.x = this._viscousLimit(offset.x, limit.min.x); } 13820 if (offset.y < limit.min.y) { offset.y = this._viscousLimit(offset.y, limit.min.y); } 13821 if (offset.x > limit.max.x) { offset.x = this._viscousLimit(offset.x, limit.max.x); } 13822 if (offset.y > limit.max.y) { offset.y = this._viscousLimit(offset.y, limit.max.y); } 13823 13824 this._draggable._newPos = this._draggable._startPos.add(offset); 13825}, 13826 13827_onPreDragWrap: function () { 13828 // TODO refactor to be able to adjust map pane position after zoom 13829 var worldWidth = this._worldWidth, 13830 halfWidth = Math.round(worldWidth / 2), 13831 dx = this._initialWorldOffset, 13832 x = this._draggable._newPos.x, 13833 newX1 = (x - halfWidth + dx) % worldWidth + halfWidth - dx, 13834 newX2 = (x + halfWidth + dx) % worldWidth - halfWidth - dx, 13835 newX = Math.abs(newX1 + dx) < Math.abs(newX2 + dx) ? newX1 : newX2; 13836 13837 this._draggable._absPos = this._draggable._newPos.clone(); 13838 this._draggable._newPos.x = newX; 13839 }, 13840 13841 _onDragEnd: function (e) { 13842 var map = this._map, 13843 options = map.options, 13844 13845 noInertia = !options.inertia || this._times.length < 2; 13846 13847 map.fire('dragend', e); 13848 13849 if (noInertia) { 13850 map.fire('moveend'); 13851 13852 } else { 13853 this._prunePositions(+new Date()); 13854 13855 var direction = this._lastPos.subtract(this._positions[0]), 13856 duration = (this._lastTime - this._times[0]) / 1000, 13857 ease = options.easeLinearity, 13858 13859 speedVector = direction.multiplyBy(ease / duration), 13860 speed = speedVector.distanceTo([0, 0]), 13861 13862 limitedSpeed = Math.min(options.inertiaMaxSpeed, speed), 13863 limitedSpeedVector = speedVector.multiplyBy(limitedSpeed / speed), 13864 13865 decelerationDuration = limitedSpeed / (options.inertiaDeceleration * ease), 13866 offset = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round(); 13867 13868 if (!offset.x && !offset.y) { 13869 map.fire('moveend'); 13870 13871 } else { 13872 offset = map._limitOffset(offset, map.options.maxBounds); 13873 13874 requestAnimFrame(function () { 13875 map.panBy(offset, { 13876 duration: decelerationDuration, 13877 easeLinearity: ease, 13878 noMoveStart: true, 13879 animate: true 13880 }); 13881 }); 13882 } 13883 } 13884} 13885}); 13886 13887// @section Handlers 13888// @property dragging: Handler 13889// Map dragging handler (by both mouse and touch). 13890Map.addInitHook('addHandler', 'dragging', Drag); 13891 13892/* 13893 * L.Map.Keyboard is handling keyboard interaction with the map, enabled by default. 13894 */ 13895 13896// @namespace Map 13897// @section Keyboard Navigation Options 13898Map.mergeOptions({ 13899 // @option keyboard: Boolean = true 13900 // Makes the map focusable and allows users to navigate the map with keyboard 13901 // arrows and `+`/`-` keys. 13902 keyboard: true, 13903 13904 // @option keyboardPanDelta: Number = 80 13905 // Amount of pixels to pan when pressing an arrow key. 13906 keyboardPanDelta: 80 13907}); 13908 13909var Keyboard = Handler.extend({ 13910 13911 keyCodes: { 13912 left: [37], 13913 right: [39], 13914 down: [40], 13915 up: [38], 13916 zoomIn: [187, 107, 61, 171], 13917 zoomOut: [189, 109, 54, 173] 13918 }, 13919 13920 initialize: function (map) { 13921 this._map = map; 13922 13923 this._setPanDelta(map.options.keyboardPanDelta); 13924 this._setZoomDelta(map.options.zoomDelta); 13925 }, 13926 13927 addHooks: function () { 13928 var container = this._map._container; 13929 13930 // make the container focusable by tabbing 13931 if (container.tabIndex <= 0) { 13932 container.tabIndex = '0'; 13933 } 13934 13935 on(container, { 13936 focus: this._onFocus, 13937 blur: this._onBlur, 13938 mousedown: this._onMouseDown 13939 }, this); 13940 13941 this._map.on({ 13942 focus: this._addHooks, 13943 blur: this._removeHooks 13944 }, this); 13945 }, 13946 13947 removeHooks: function () { 13948 this._removeHooks(); 13949 13950 off(this._map._container, { 13951 focus: this._onFocus, 13952 blur: this._onBlur, 13953 mousedown: this._onMouseDown 13954 }, this); 13955 13956 this._map.off({ 13957 focus: this._addHooks, 13958 blur: this._removeHooks 13959 }, this); 13960 }, 13961 13962 _onMouseDown: function () { 13963 if (this._focused) { return; } 13964 13965 var body = document.body, 13966 docEl = document.documentElement, 13967 top = body.scrollTop || docEl.scrollTop, 13968 left = body.scrollLeft || docEl.scrollLeft; 13969 13970 this._map._container.focus(); 13971 13972 window.scrollTo(left, top); 13973 }, 13974 13975 _onFocus: function () { 13976 this._focused = true; 13977 this._map.fire('focus'); 13978 }, 13979 13980 _onBlur: function () { 13981 this._focused = false; 13982 this._map.fire('blur'); 13983 }, 13984 13985 _setPanDelta: function (panDelta) { 13986 var keys = this._panKeys = {}, 13987 codes = this.keyCodes, 13988 i, len; 13989 13990 for (i = 0, len = codes.left.length; i < len; i++) { 13991 keys[codes.left[i]] = [-1 * panDelta, 0]; 13992 } 13993 for (i = 0, len = codes.right.length; i < len; i++) { 13994 keys[codes.right[i]] = [panDelta, 0]; 13995 } 13996 for (i = 0, len = codes.down.length; i < len; i++) { 13997 keys[codes.down[i]] = [0, panDelta]; 13998 } 13999 for (i = 0, len = codes.up.length; i < len; i++) { 14000 keys[codes.up[i]] = [0, -1 * panDelta]; 14001 } 14002 }, 14003 14004 _setZoomDelta: function (zoomDelta) { 14005 var keys = this._zoomKeys = {}, 14006 codes = this.keyCodes, 14007 i, len; 14008 14009 for (i = 0, len = codes.zoomIn.length; i < len; i++) { 14010 keys[codes.zoomIn[i]] = zoomDelta; 14011 } 14012 for (i = 0, len = codes.zoomOut.length; i < len; i++) { 14013 keys[codes.zoomOut[i]] = -zoomDelta; 14014 } 14015}, 14016 14017_addHooks: function () { 14018 on(document, 'keydown', this._onKeyDown, this); 14019}, 14020 14021_removeHooks: function () { 14022 off(document, 'keydown', this._onKeyDown, this); 14023}, 14024 14025_onKeyDown: function (e) { 14026 if (e.altKey || e.ctrlKey || e.metaKey) { return; } 14027 14028 var key = e.keyCode, 14029 map = this._map, 14030 offset; 14031 14032 if (key in this._panKeys) { 14033 if (!map._panAnim || !map._panAnim._inProgress) { 14034 offset = this._panKeys[key]; 14035 if (e.shiftKey) { 14036 offset = toPoint(offset).multiplyBy(3); 14037 } 14038 14039 map.panBy(offset); 14040 14041 if (map.options.maxBounds) { 14042 map.panInsideBounds(map.options.maxBounds); 14043 } 14044 } 14045} else if (key in this._zoomKeys) { 14046 map.setZoom(map.getZoom() + (e.shiftKey ? 3 : 1) * this._zoomKeys[key]); 14047 14048} else if (key === 27 && map._popup && map._popup.options.closeOnEscapeKey) { 14049 map.closePopup(); 14050 14051} else { 14052 return; 14053} 14054 14055stop(e); 14056} 14057}); 14058 14059// @section Handlers 14060// @section Handlers 14061// @property keyboard: Handler 14062// Keyboard navigation handler. 14063Map.addInitHook('addHandler', 'keyboard', Keyboard); 14064 14065/* 14066 * L.Handler.ScrollWheelZoom is used by L.Map to enable mouse scroll wheel zoom on the map. 14067 */ 14068 14069// @namespace Map 14070// @section Interaction Options 14071Map.mergeOptions({ 14072 // @section Mousewheel options 14073 // @option scrollWheelZoom: Boolean|String = true 14074 // Whether the map can be zoomed by using the mouse wheel. If passed `'center'`, 14075 // it will zoom to the center of the view regardless of where the mouse was. 14076 scrollWheelZoom: true, 14077 14078 // @option wheelDebounceTime: Number = 40 14079 // Limits the rate at which a wheel can fire (in milliseconds). By default 14080 // user can't zoom via wheel more often than once per 40 ms. 14081 wheelDebounceTime: 40, 14082 14083 // @option wheelPxPerZoomLevel: Number = 60 14084 // How many scroll pixels (as reported by [L.DomEvent.getWheelDelta](#domevent-getwheeldelta)) 14085 // mean a change of one full zoom level. Smaller values will make wheel-zooming 14086 // faster (and vice versa). 14087 wheelPxPerZoomLevel: 60 14088}); 14089 14090var ScrollWheelZoom = Handler.extend({ 14091 addHooks: function () { 14092 on(this._map._container, 'mousewheel', this._onWheelScroll, this); 14093 14094 this._delta = 0; 14095 }, 14096 14097 removeHooks: function () { 14098 off(this._map._container, 'mousewheel', this._onWheelScroll, this); 14099 }, 14100 14101 _onWheelScroll: function (e) { 14102 var delta = getWheelDelta(e); 14103 14104 var debounce = this._map.options.wheelDebounceTime; 14105 14106 this._delta += delta; 14107 this._lastMousePos = this._map.mouseEventToContainerPoint(e); 14108 14109 if (!this._startTime) { 14110 this._startTime = +new Date(); 14111 } 14112 14113 var left = Math.max(debounce - (+new Date() - this._startTime), 0); 14114 14115 clearTimeout(this._timer); 14116 this._timer = setTimeout(bind(this._performZoom, this), left); 14117 14118 stop(e); 14119 }, 14120 14121 _performZoom: function () { 14122 var map = this._map, 14123 zoom = map.getZoom(), 14124 snap = this._map.options.zoomSnap || 0; 14125 14126 map._stop(); // stop panning and fly animations if any 14127 14128 // map the delta with a sigmoid function to -4..4 range leaning on -1..1 14129 var d2 = this._delta / (this._map.options.wheelPxPerZoomLevel * 4), 14130 d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2, 14131 d4 = snap ? Math.ceil(d3 / snap) * snap : d3, 14132 delta = map._limitZoom(zoom + (this._delta > 0 ? d4 : -d4)) - zoom; 14133 14134 this._delta = 0; 14135 this._startTime = null; 14136 14137 if (!delta) { return; } 14138 14139 if (map.options.scrollWheelZoom === 'center') { 14140 map.setZoom(zoom + delta); 14141 } else { 14142 map.setZoomAround(this._lastMousePos, zoom + delta); 14143 } 14144 } 14145}); 14146 14147// @section Handlers 14148// @property scrollWheelZoom: Handler 14149// Scroll wheel zoom handler. 14150Map.addInitHook('addHandler', 'scrollWheelZoom', ScrollWheelZoom); 14151 14152/* 14153 * L.Map.Tap is used to enable mobile hacks like quick taps and long hold. 14154 */ 14155 14156// @namespace Map 14157// @section Interaction Options 14158Map.mergeOptions({ 14159 // @section Touch interaction options 14160 // @option tap: Boolean = true 14161 // Enables mobile hacks for supporting instant taps (fixing 200ms click 14162 // delay on iOS/Android) and touch holds (fired as `contextmenu` events). 14163 tap: true, 14164 14165 // @option tapTolerance: Number = 15 14166 // The max number of pixels a user can shift his finger during touch 14167 // for it to be considered a valid tap. 14168 tapTolerance: 15 14169}); 14170 14171var Tap = Handler.extend({ 14172 addHooks: function () { 14173 on(this._map._container, 'touchstart', this._onDown, this); 14174 }, 14175 14176 removeHooks: function () { 14177 off(this._map._container, 'touchstart', this._onDown, this); 14178 }, 14179 14180 _onDown: function (e) { 14181 if (!e.touches) { return; } 14182 14183 preventDefault(e); 14184 14185 this._fireClick = true; 14186 14187 // don't simulate click or track longpress if more than 1 touch 14188 if (e.touches.length > 1) { 14189 this._fireClick = false; 14190 clearTimeout(this._holdTimeout); 14191 return; 14192 } 14193 14194 var first = e.touches[0], 14195 el = first.target; 14196 14197 this._startPos = this._newPos = new Point(first.clientX, first.clientY); 14198 14199 // if touching a link, highlight it 14200 if (el.tagName && el.tagName.toLowerCase() === 'a') { 14201 addClass(el, 'leaflet-active'); 14202 } 14203 14204 // simulate long hold but setting a timeout 14205 this._holdTimeout = setTimeout(bind(function () { 14206 if (this._isTapValid()) { 14207 this._fireClick = false; 14208 this._onUp(); 14209 this._simulateEvent('contextmenu', first); 14210 } 14211 }, this), 1000); 14212 14213 this._simulateEvent('mousedown', first); 14214 14215 on(document, { 14216 touchmove: this._onMove, 14217 touchend: this._onUp 14218 }, this); 14219 }, 14220 14221 _onUp: function (e) { 14222 clearTimeout(this._holdTimeout); 14223 14224 off(document, { 14225 touchmove: this._onMove, 14226 touchend: this._onUp 14227 }, this); 14228 14229 if (this._fireClick && e && e.changedTouches) { 14230 14231 var first = e.changedTouches[0], 14232 el = first.target; 14233 14234 if (el && el.tagName && el.tagName.toLowerCase() === 'a') { 14235 removeClass(el, 'leaflet-active'); 14236 } 14237 14238 this._simulateEvent('mouseup', first); 14239 14240 // simulate click if the touch didn't move too much 14241 if (this._isTapValid()) { 14242 this._simulateEvent('click', first); 14243 } 14244 } 14245 }, 14246 14247 _isTapValid: function () { 14248 return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance; 14249 }, 14250 14251 _onMove: function (e) { 14252 var first = e.touches[0]; 14253 this._newPos = new Point(first.clientX, first.clientY); 14254 this._simulateEvent('mousemove', first); 14255 }, 14256 14257 _simulateEvent: function (type, e) { 14258 var simulatedEvent = document.createEvent('MouseEvents'); 14259 14260 simulatedEvent._simulated = true; 14261 e.target._simulatedClick = true; 14262 14263 simulatedEvent.initMouseEvent( 14264 type, true, true, window, 1, 14265 e.screenX, e.screenY, 14266 e.clientX, e.clientY, 14267 false, false, false, false, 0, null); 14268 14269 e.target.dispatchEvent(simulatedEvent); 14270 } 14271}); 14272 14273// @section Handlers 14274// @property tap: Handler 14275// Mobile touch hacks (quick tap and touch hold) handler. 14276if (touch && !pointer) { 14277 Map.addInitHook('addHandler', 'tap', Tap); 14278} 14279 14280/* 14281 * L.Handler.TouchZoom is used by L.Map to add pinch zoom on supported mobile browsers. 14282 */ 14283 14284// @namespace Map 14285// @section Interaction Options 14286Map.mergeOptions({ 14287 // @section Touch interaction options 14288 // @option touchZoom: Boolean|String = * 14289 // Whether the map can be zoomed by touch-dragging with two fingers. If 14290 // passed `'center'`, it will zoom to the center of the view regardless of 14291 // where the touch events (fingers) were. Enabled for touch-capable web 14292 // browsers except for old Androids. 14293 touchZoom: touch && !android23, 14294 14295 // @option bounceAtZoomLimits: Boolean = true 14296 // Set it to false if you don't want the map to zoom beyond min/max zoom 14297 // and then bounce back when pinch-zooming. 14298 bounceAtZoomLimits: true 14299}); 14300 14301var TouchZoom = Handler.extend({ 14302 addHooks: function () { 14303 addClass(this._map._container, 'leaflet-touch-zoom'); 14304 on(this._map._container, 'touchstart', this._onTouchStart, this); 14305 }, 14306 14307 removeHooks: function () { 14308 removeClass(this._map._container, 'leaflet-touch-zoom'); 14309 off(this._map._container, 'touchstart', this._onTouchStart, this); 14310 }, 14311 14312 _onTouchStart: function (e) { 14313 var map = this._map; 14314 if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming) { return; } 14315 14316 var p1 = map.mouseEventToContainerPoint(e.touches[0]), 14317 p2 = map.mouseEventToContainerPoint(e.touches[1]); 14318 14319 this._centerPoint = map.getSize()._divideBy(2); 14320 this._startLatLng = map.containerPointToLatLng(this._centerPoint); 14321 if (map.options.touchZoom !== 'center') { 14322 this._pinchStartLatLng = map.containerPointToLatLng(p1.add(p2)._divideBy(2)); 14323 } 14324 14325 this._startDist = p1.distanceTo(p2); 14326 this._startZoom = map.getZoom(); 14327 14328 this._moved = false; 14329 this._zooming = true; 14330 14331 map._stop(); 14332 14333 on(document, 'touchmove', this._onTouchMove, this); 14334 on(document, 'touchend', this._onTouchEnd, this); 14335 14336 preventDefault(e); 14337 }, 14338 14339 _onTouchMove: function (e) { 14340 if (!e.touches || e.touches.length !== 2 || !this._zooming) { return; } 14341 14342 var map = this._map, 14343 p1 = map.mouseEventToContainerPoint(e.touches[0]), 14344 p2 = map.mouseEventToContainerPoint(e.touches[1]), 14345 scale = p1.distanceTo(p2) / this._startDist; 14346 14347 this._zoom = map.getScaleZoom(scale, this._startZoom); 14348 14349 if (!map.options.bounceAtZoomLimits && ( 14350 (this._zoom < map.getMinZoom() && scale < 1) || 14351 (this._zoom > map.getMaxZoom() && scale > 1))) { 14352 this._zoom = map._limitZoom(this._zoom); 14353} 14354 14355if (map.options.touchZoom === 'center') { 14356 this._center = this._startLatLng; 14357 if (scale === 1) { return; } 14358} else { 14359 // Get delta from pinch to center, so centerLatLng is delta applied to initial pinchLatLng 14360 var delta = p1._add(p2)._divideBy(2)._subtract(this._centerPoint); 14361 if (scale === 1 && delta.x === 0 && delta.y === 0) { return; } 14362 this._center = map.unproject(map.project(this._pinchStartLatLng, this._zoom).subtract(delta), this._zoom); 14363 } 14364 14365 if (!this._moved) { 14366 map._moveStart(true, false); 14367 this._moved = true; 14368 } 14369 14370 cancelAnimFrame(this._animRequest); 14371 14372 var moveFn = bind(map._move, map, this._center, this._zoom, {pinch: true, round: false}); 14373 this._animRequest = requestAnimFrame(moveFn, this, true); 14374 14375 preventDefault(e); 14376 }, 14377 14378 _onTouchEnd: function () { 14379 if (!this._moved || !this._zooming) { 14380 this._zooming = false; 14381 return; 14382 } 14383 14384 this._zooming = false; 14385 cancelAnimFrame(this._animRequest); 14386 14387 off(document, 'touchmove', this._onTouchMove); 14388 off(document, 'touchend', this._onTouchEnd); 14389 14390 // Pinch updates GridLayers' levels only when zoomSnap is off, so zoomSnap becomes noUpdate. 14391 if (this._map.options.zoomAnimation) { 14392 this._map._animateZoom(this._center, this._map._limitZoom(this._zoom), true, this._map.options.zoomSnap); 14393 } else { 14394 this._map._resetView(this._center, this._map._limitZoom(this._zoom)); 14395 } 14396 } 14397}); 14398 14399// @section Handlers 14400// @property touchZoom: Handler 14401// Touch zoom handler. 14402Map.addInitHook('addHandler', 'touchZoom', TouchZoom); 14403 14404Map.BoxZoom = BoxZoom; 14405Map.DoubleClickZoom = DoubleClickZoom; 14406Map.Drag = Drag; 14407Map.Keyboard = Keyboard; 14408Map.ScrollWheelZoom = ScrollWheelZoom; 14409Map.Tap = Tap; 14410Map.TouchZoom = TouchZoom; 14411 14412Object.freeze = freeze; 14413 14414exports.version = version; 14415exports.Control = Control; 14416exports.control = control; 14417exports.Browser = Browser; 14418exports.Evented = Evented; 14419exports.Mixin = Mixin; 14420exports.Util = Util; 14421exports.Class = Class; 14422exports.Handler = Handler; 14423exports.extend = extend; 14424exports.bind = bind; 14425exports.stamp = stamp; 14426exports.setOptions = setOptions; 14427exports.DomEvent = DomEvent; 14428exports.DomUtil = DomUtil; 14429exports.PosAnimation = PosAnimation; 14430exports.Draggable = Draggable; 14431exports.LineUtil = LineUtil; 14432exports.PolyUtil = PolyUtil; 14433exports.Point = Point; 14434exports.point = toPoint; 14435exports.Bounds = Bounds; 14436exports.bounds = toBounds; 14437exports.Transformation = Transformation; 14438exports.transformation = toTransformation; 14439exports.Projection = index; 14440exports.LatLng = LatLng; 14441exports.latLng = toLatLng; 14442exports.LatLngBounds = LatLngBounds; 14443exports.latLngBounds = toLatLngBounds; 14444exports.CRS = CRS; 14445exports.GeoJSON = GeoJSON; 14446exports.geoJSON = geoJSON; 14447exports.geoJson = geoJson; 14448exports.Layer = Layer; 14449exports.LayerGroup = LayerGroup; 14450exports.layerGroup = layerGroup; 14451exports.FeatureGroup = FeatureGroup; 14452exports.featureGroup = featureGroup; 14453exports.ImageOverlay = ImageOverlay; 14454exports.imageOverlay = imageOverlay; 14455exports.VideoOverlay = VideoOverlay; 14456exports.videoOverlay = videoOverlay; 14457exports.SVGOverlay = SVGOverlay; 14458exports.svgOverlay = svgOverlay; 14459exports.DivOverlay = DivOverlay; 14460exports.Popup = Popup; 14461exports.popup = popup; 14462exports.Tooltip = Tooltip; 14463exports.tooltip = tooltip; 14464exports.Icon = Icon; 14465exports.icon = icon; 14466exports.DivIcon = DivIcon; 14467exports.divIcon = divIcon; 14468exports.Marker = Marker; 14469exports.marker = marker; 14470exports.TileLayer = TileLayer; 14471exports.tileLayer = tileLayer; 14472exports.GridLayer = GridLayer; 14473exports.gridLayer = gridLayer; 14474exports.SVG = SVG; 14475exports.svg = svg$1; 14476exports.Renderer = Renderer; 14477exports.Canvas = Canvas; 14478exports.canvas = canvas$1; 14479exports.Path = Path; 14480exports.CircleMarker = CircleMarker; 14481exports.circleMarker = circleMarker; 14482exports.Circle = Circle; 14483exports.circle = circle; 14484exports.Polyline = Polyline; 14485exports.polyline = polyline; 14486exports.Polygon = Polygon; 14487exports.polygon = polygon; 14488exports.Rectangle = Rectangle; 14489exports.rectangle = rectangle; 14490exports.Map = Map; 14491exports.map = createMap; 14492 14493var oldL = window.L; 14494exports.noConflict = function() { 14495 window.L = oldL; 14496 return this; 14497} 14498 14499// Always export us to window global (see #2364) 14500window.L = exports; 14501 14502}))); 14503//# sourceMappingURL=leaflet-src.js.map 14504 14505 14506/***/ }), 14507
vendor: 43,632 bytes, lines 14508-14522
14508/***/ "./node_modules/slick-carousel/slick/slick.min.js": 14509/*!********************************************************!*\ 14510 !*** ./node_modules/slick-carousel/slick/slick.min.js ***! 14511 \********************************************************/ 14512 /*! no static exports found */ 14513 /***/ (function(module, exports, __webpack_require__) { 14514 14515 var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!function(i){"use strict"; true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ "jquery")], __WEBPACK_AMD_DEFINE_FACTORY__ = (i), 14516 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 14517 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 14518 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):undefined}(function(i){"use strict";var e=window.Slick||{};(e=function(){var e=0;return function(t,o){var s,n=this;n.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:i(t),appendDots:i(t),arrows:!0,asNavFor:null,prevArrow:'<button class="slick-prev" aria-label="Previous" type="button">Previous</button>',nextArrow:'<button class="slick-next" aria-label="Next" type="button">Next</button>',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(e,t){return i('<button type="button" />').text(t+1)},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",edgeFriction:.35,fade:!1,focusOnSelect:!1,focusOnChange:!1,infinite:!0,initialSlide:0,lazyLoad:"ondemand",mobileFirst:!1,pauseOnHover:!0,pauseOnFocus:!0,pauseOnDotsHover:!1,respondTo:"window",responsive:null,rows:1,rtl:!1,slide:"",slidesPerRow:1,slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,useTransform:!0,variableWidth:!1,vertical:!1,verticalSwiping:!1,waitForAnimate:!0,zIndex:1e3},n.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,scrolling:!1,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,sliding:!1,slideOffset:0,swipeLeft:null,swiping:!1,$list:null,touchObject:{},transformsEnabled:!1,unslicked:!1},i.extend(n,n.initials),n.activeBreakpoint=null,n.animType=null,n.animProp=null,n.breakpoints=[],n.breakpointSettings=[],n.cssTransitions=!1,n.focussed=!1,n.interrupted=!1,n.hidden="hidden",n.paused=!0,n.positionProp=null,n.respondTo=null,n.rowCount=1,n.shouldClick=!0,n.$slider=i(t),n.$slidesCache=null,n.transformType=null,n.transitionType=null,n.visibilityChange="visibilitychange",n.windowWidth=0,n.windowTimer=null,s=i(t).data("slick")||{},n.options=i.extend({},n.defaults,o,s),n.currentSlide=n.options.initialSlide,n.originalSettings=n.options,void 0!==document.mozHidden?(n.hidden="mozHidden",n.visibilityChange="mozvisibilitychange"):void 0!==document.webkitHidden&&(n.hidden="webkitHidden",n.visibilityChange="webkitvisibilitychange"),n.autoPlay=i.proxy(n.autoPlay,n),n.autoPlayClear=i.proxy(n.autoPlayClear,n),n.autoPlayIterator=i.proxy(n.autoPlayIterator,n),n.changeSlide=i.proxy(n.changeSlide,n),n.clickHandler=i.proxy(n.clickHandler,n),n.selectHandler=i.proxy(n.selectHandler,n),n.setPosition=i.proxy(n.setPosition,n),n.swipeHandler=i.proxy(n.swipeHandler,n),n.dragHandler=i.proxy(n.dragHandler,n),n.keyHandler=i.proxy(n.keyHandler,n),n.instanceUid=e++,n.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,n.registerBreakpoints(),n.init(!0)}}()).prototype.activateADA=function(){this.$slideTrack.find(".slick-active").attr({"aria-hidden":"false"}).find("a, input, button, select").attr({tabindex:"0"})},e.prototype.addSlide=e.prototype.slickAdd=function(e,t,o){var s=this;if("boolean"==typeof t)o=t,t=null;else if(t<0||t>=s.slideCount)return!1;s.unload(),"number"==typeof t?0===t&&0===s.$slides.length?i(e).appendTo(s.$slideTrack):o?i(e).insertBefore(s.$slides.eq(t)):i(e).insertAfter(s.$slides.eq(t)):!0===o?i(e).prependTo(s.$slideTrack):i(e).appendTo(s.$slideTrack),s.$slides=s.$slideTrack.children(this.options.slide),s.$slideTrack.children(this.options.slide).detach(),s.$slideTrack.append(s.$slides),s.$slides.each(function(e,t){i(t).attr("data-slick-index",e)}),s.$slidesCache=s.$slides,s.reinit()},e.prototype.animateHeight=function(){var i=this;if(1===i.options.slidesToShow&&!0===i.options.adaptiveHeight&&!1===i.options.vertical){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.animate({height:e},i.options.speed)}},e.prototype.animateSlide=function(e,t){var o={},s=this;s.animateHeight(),!0===s.options.rtl&&!1===s.options.vertical&&(e=-e),!1===s.transformsEnabled?!1===s.options.vertical?s.$slideTrack.animate({left:e},s.options.speed,s.options.easing,t):s.$slideTrack.animate({top:e},s.options.speed,s.options.easing,t):!1===s.cssTransitions?(!0===s.options.rtl&&(s.currentLeft=-s.currentLeft),i({animStart:s.currentLeft}).animate({animStart:e},{duration:s.options.speed,easing:s.options.easing,step:function(i){i=Math.ceil(i),!1===s.options.vertical?(o[s.animType]="translate("+i+"px, 0px)",s.$slideTrack.css(o)):(o[s.animType]="translate(0px,"+i+"px)",s.$slideTrack.css(o))},complete:function(){t&&t.call()}})):(s.applyTransition(),e=Math.ceil(e),!1===s.options.vertical?o[s.animType]="translate3d("+e+"px, 0px, 0px)":o[s.animType]="translate3d(0px,"+e+"px, 0px)",s.$slideTrack.css(o),t&&setTimeout(function(){s.disableTransition(),t.call()},s.options.speed))},e.prototype.getNavTarget=function(){var e=this,t=e.options.asNavFor;return t&&null!==t&&(t=i(t).not(e.$slider)),t},e.prototype.asNavFor=function(e){var t=this.getNavTarget();null!==t&&"object"==typeof t&&t.each(function(){var t=i(this).slick("getSlick");t.unslicked||t.slideHandler(e,!0)})},e.prototype.applyTransition=function(i){var e=this,t={};!1===e.options.fade?t[e.transitionType]=e.transformType+" "+e.options.speed+"ms "+e.options.cssEase:t[e.transitionType]="opacity "+e.options.speed+"ms "+e.options.cssEase,!1===e.options.fade?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.autoPlay=function(){var i=this;i.autoPlayClear(),i.slideCount>i.options.slidesToShow&&(i.autoPlayTimer=setInterval(i.autoPlayIterator,i.options.autoplaySpeed))},e.prototype.autoPlayClear=function(){var i=this;i.autoPlayTimer&&clearInterval(i.autoPlayTimer)},e.prototype.autoPlayIterator=function(){var i=this,e=i.currentSlide+i.options.slidesToScroll;i.paused||i.interrupted||i.focussed||(!1===i.options.infinite&&(1===i.direction&&i.currentSlide+1===i.slideCount-1?i.direction=0:0===i.direction&&(e=i.currentSlide-i.options.slidesToScroll,i.currentSlide-1==0&&(i.direction=1))),i.slideHandler(e))},e.prototype.buildArrows=function(){var e=this;!0===e.options.arrows&&(e.$prevArrow=i(e.options.prevArrow).addClass("slick-arrow"),e.$nextArrow=i(e.options.nextArrow).addClass("slick-arrow"),e.slideCount>e.options.slidesToShow?(e.$prevArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),e.$nextArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.prependTo(e.options.appendArrows),e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.appendTo(e.options.appendArrows),!0!==e.options.infinite&&e.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true")):e.$prevArrow.add(e.$nextArrow).addClass("slick-hidden").attr({"aria-disabled":"true",tabindex:"-1"}))},e.prototype.buildDots=function(){var e,t,o=this;if(!0===o.options.dots){for(o.$slider.addClass("slick-dotted"),t=i("<ul />").addClass(o.options.dotsClass),e=0;e<=o.getDotCount();e+=1)t.append(i("<li />").append(o.options.customPaging.call(this,o,e)));o.$dots=t.appendTo(o.options.appendDots),o.$dots.find("li").first().addClass("slick-active")}},e.prototype.buildOut=function(){var e=this;e.$slides=e.$slider.children(e.options.slide+":not(.slick-cloned)").addClass("slick-slide"),e.slideCount=e.$slides.length,e.$slides.each(function(e,t){i(t).attr("data-slick-index",e).data("originalStyling",i(t).attr("style")||"")}),e.$slider.addClass("slick-slider"),e.$slideTrack=0===e.slideCount?i('<div class="slick-track"/>').appendTo(e.$slider):e.$slides.wrapAll('<div class="slick-track"/>').parent(),e.$list=e.$slideTrack.wrap('<div class="slick-list"/>').parent(),e.$slideTrack.css("opacity",0),!0!==e.options.centerMode&&!0!==e.options.swipeToSlide||(e.options.slidesToScroll=1),i("img[data-lazy]",e.$slider).not("[src]").addClass("slick-loading"),e.setupInfinite(),e.buildArrows(),e.buildDots(),e.updateDots(),e.setSlideClasses("number"==typeof e.currentSlide?e.currentSlide:0),!0===e.options.draggable&&e.$list.addClass("draggable")},e.prototype.buildRows=function(){var i,e,t,o,s,n,r,l=this;if(o=document.createDocumentFragment(),n=l.$slider.children(),l.options.rows>1){for(r=l.options.slidesPerRow*l.options.rows,s=Math.ceil(n.length/r),i=0;i<s;i++){var d=document.createElement("div");for(e=0;e<l.options.rows;e++){var a=document.createElement("div");for(t=0;t<l.options.slidesPerRow;t++){var c=i*r+(e*l.options.slidesPerRow+t);n.get(c)&&a.appendChild(n.get(c))}d.appendChild(a)}o.appendChild(d)}l.$slider.empty().append(o),l.$slider.children().children().children().css({width:100/l.options.slidesPerRow+"%",display:"inline-block"})}},e.prototype.checkResponsive=function(e,t){var o,s,n,r=this,l=!1,d=r.$slider.width(),a=window.innerWidth||i(window).width();if("window"===r.respondTo?n=a:"slider"===r.respondTo?n=d:"min"===r.respondTo&&(n=Math.min(a,d)),r.options.responsive&&r.options.responsive.length&&null!==r.options.responsive){s=null;for(o in r.breakpoints)r.breakpoints.hasOwnProperty(o)&&(!1===r.originalSettings.mobileFirst?n<r.breakpoints[o]&&(s=r.breakpoints[o]):n>r.breakpoints[o]&&(s=r.breakpoints[o]));null!==s?null!==r.activeBreakpoint?(s!==r.activeBreakpoint||t)&&(r.activeBreakpoint=s,"unslick"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):(r.activeBreakpoint=s,"unslick"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):null!==r.activeBreakpoint&&(r.activeBreakpoint=null,r.options=r.originalSettings,!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e),l=s),e||!1===l||r.$slider.trigger("breakpoint",[r,l])}},e.prototype.changeSlide=function(e,t){var o,s,n,r=this,l=i(e.currentTarget);switch(l.is("a")&&e.preventDefault(),l.is("li")||(l=l.closest("li")),n=r.slideCount%r.options.slidesToScroll!=0,o=n?0:(r.slideCount-r.currentSlide)%r.options.slidesToScroll,e.data.message){case"previous":s=0===o?r.options.slidesToScroll:r.options.slidesToShow-o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide-s,!1,t);break;case"next":s=0===o?r.options.slidesToScroll:o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide+s,!1,t);break;case"index":var d=0===e.data.index?0:e.data.index||l.index()*r.options.slidesToScroll;r.slideHandler(r.checkNavigable(d),!1,t),l.children().trigger("focus");break;default:return}},e.prototype.checkNavigable=function(i){var e,t;if(e=this.getNavigableIndexes(),t=0,i>e[e.length-1])i=e[e.length-1];else for(var o in e){if(i<e[o]){i=t;break}t=e[o]}return i},e.prototype.cleanUpEvents=function(){var e=this;e.options.dots&&null!==e.$dots&&(i("li",e.$dots).off("click.slick",e.changeSlide).off("mouseenter.slick",i.proxy(e.interrupt,e,!0)).off("mouseleave.slick",i.proxy(e.interrupt,e,!1)),!0===e.options.accessibility&&e.$dots.off("keydown.slick",e.keyHandler)),e.$slider.off("focus.slick blur.slick"),!0===e.options.arrows&&e.slideCount>e.options.slidesToShow&&(e.$prevArrow&&e.$prevArrow.off("click.slick",e.changeSlide),e.$nextArrow&&e.$nextArrow.off("click.slick",e.changeSlide),!0===e.options.accessibility&&(e.$prevArrow&&e.$prevArrow.off("keydown.slick",e.keyHandler),e.$nextArrow&&e.$nextArrow.off("keydown.slick",e.keyHandler))),e.$list.off("touchstart.slick mousedown.slick",e.swipeHandler),e.$list.off("touchmove.slick mousemove.slick",e.swipeHandler),e.$list.off("touchend.slick mouseup.slick",e.swipeHandler),e.$list.off("touchcancel.slick mouseleave.slick",e.swipeHandler),e.$list.off("click.slick",e.clickHandler),i(document).off(e.visibilityChange,e.visibility),e.cleanUpSlideEvents(),!0===e.options.accessibility&&e.$list.off("keydown.slick",e.keyHandler),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().off("click.slick",e.selectHandler),i(window).off("orientationchange.slick.slick-"+e.instanceUid,e.orientationChange),i(window).off("resize.slick.slick-"+e.instanceUid,e.resize),i("[draggable!=true]",e.$slideTrack).off("dragstart",e.preventDefault),i(window).off("load.slick.slick-"+e.instanceUid,e.setPosition)},e.prototype.cleanUpSlideEvents=function(){var e=this;e.$list.off("mouseenter.slick",i.proxy(e.interrupt,e,!0)),e.$list.off("mouseleave.slick",i.proxy(e.interrupt,e,!1))},e.prototype.cleanUpRows=function(){var i,e=this;e.options.rows>1&&((i=e.$slides.children().children()).removeAttr("style"),e.$slider.empty().append(i))},e.prototype.clickHandler=function(i){!1===this.shouldClick&&(i.stopImmediatePropagation(),i.stopPropagation(),i.preventDefault())},e.prototype.destroy=function(e){var t=this;t.autoPlayClear(),t.touchObject={},t.cleanUpEvents(),i(".slick-cloned",t.$slider).detach(),t.$dots&&t.$dots.remove(),t.$prevArrow&&t.$prevArrow.length&&(t.$prevArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),t.htmlExpr.test(t.options.prevArrow)&&t.$prevArrow.remove()),t.$nextArrow&&t.$nextArrow.length&&(t.$nextArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),t.htmlExpr.test(t.options.nextArrow)&&t.$nextArrow.remove()),t.$slides&&(t.$slides.removeClass("slick-slide slick-active slick-center slick-visible slick-current").removeAttr("aria-hidden").removeAttr("data-slick-index").each(function(){i(this).attr("style",i(this).data("originalStyling"))}),t.$slideTrack.children(this.options.slide).detach(),t.$slideTrack.detach(),t.$list.detach(),t.$slider.append(t.$slides)),t.cleanUpRows(),t.$slider.removeClass("slick-slider"),t.$slider.removeClass("slick-initialized"),t.$slider.removeClass("slick-dotted"),t.unslicked=!0,e||t.$slider.trigger("destroy",[t])},e.prototype.disableTransition=function(i){var e=this,t={};t[e.transitionType]="",!1===e.options.fade?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.fadeSlide=function(i,e){var t=this;!1===t.cssTransitions?(t.$slides.eq(i).css({zIndex:t.options.zIndex}),t.$slides.eq(i).animate({opacity:1},t.options.speed,t.options.easing,e)):(t.applyTransition(i),t.$slides.eq(i).css({opacity:1,zIndex:t.options.zIndex}),e&&setTimeout(function(){t.disableTransition(i),e.call()},t.options.speed))},e.prototype.fadeSlideOut=function(i){var e=this;!1===e.cssTransitions?e.$slides.eq(i).animate({opacity:0,zIndex:e.options.zIndex-2},e.options.speed,e.options.easing):(e.applyTransition(i),e.$slides.eq(i).css({opacity:0,zIndex:e.options.zIndex-2}))},e.prototype.filterSlides=e.prototype.slickFilter=function(i){var e=this;null!==i&&(e.$slidesCache=e.$slides,e.unload(),e.$slideTrack.children(this.options.slide).detach(),e.$slidesCache.filter(i).appendTo(e.$slideTrack),e.reinit())},e.prototype.focusHandler=function(){var e=this;e.$slider.off("focus.slick blur.slick").on("focus.slick blur.slick","*",function(t){t.stopImmediatePropagation();var o=i(this);setTimeout(function(){e.options.pauseOnFocus&&(e.focussed=o.is(":focus"),e.autoPlay())},0)})},e.prototype.getCurrent=e.prototype.slickCurrentSlide=function(){return this.currentSlide},e.prototype.getDotCount=function(){var i=this,e=0,t=0,o=0;if(!0===i.options.infinite)if(i.slideCount<=i.options.slidesToShow)++o;else for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else if(!0===i.options.centerMode)o=i.slideCount;else if(i.options.asNavFor)for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else o=1+Math.ceil((i.slideCount-i.options.slidesToShow)/i.options.slidesToScroll);return o-1},e.prototype.getLeft=function(i){var e,t,o,s,n=this,r=0;return n.slideOffset=0,t=n.$slides.first().outerHeight(!0),!0===n.options.infinite?(n.slideCount>n.options.slidesToShow&&(n.slideOffset=n.slideWidth*n.options.slidesToShow*-1,s=-1,!0===n.options.vertical&&!0===n.options.centerMode&&(2===n.options.slidesToShow?s=-1.5:1===n.options.slidesToShow&&(s=-2)),r=t*n.options.slidesToShow*s),n.slideCount%n.options.slidesToScroll!=0&&i+n.options.slidesToScroll>n.slideCount&&n.slideCount>n.options.slidesToShow&&(i>n.slideCount?(n.slideOffset=(n.options.slidesToShow-(i-n.slideCount))*n.slideWidth*-1,r=(n.options.slidesToShow-(i-n.slideCount))*t*-1):(n.slideOffset=n.slideCount%n.options.slidesToScroll*n.slideWidth*-1,r=n.slideCount%n.options.slidesToScroll*t*-1))):i+n.options.slidesToShow>n.slideCount&&(n.slideOffset=(i+n.options.slidesToShow-n.slideCount)*n.slideWidth,r=(i+n.options.slidesToShow-n.slideCount)*t),n.slideCount<=n.options.slidesToShow&&(n.slideOffset=0,r=0),!0===n.options.centerMode&&n.slideCount<=n.options.slidesToShow?n.slideOffset=n.slideWidth*Math.floor(n.options.slidesToShow)/2-n.slideWidth*n.slideCount/2:!0===n.options.centerMode&&!0===n.options.infinite?n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)-n.slideWidth:!0===n.options.centerMode&&(n.slideOffset=0,n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)),e=!1===n.options.vertical?i*n.slideWidth*-1+n.slideOffset:i*t*-1+r,!0===n.options.variableWidth&&(o=n.slideCount<=n.options.slidesToShow||!1===n.options.infinite?n.$slideTrack.children(".slick-slide").eq(i):n.$slideTrack.children(".slick-slide").eq(i+n.options.slidesToShow),e=!0===n.options.rtl?o[0]?-1*(n.$slideTrack.width()-o[0].offsetLeft-o.width()):0:o[0]?-1*o[0].offsetLeft:0,!0===n.options.centerMode&&(o=n.slideCount<=n.options.slidesToShow||!1===n.options.infinite?n.$slideTrack.children(".slick-slide").eq(i):n.$slideTrack.children(".slick-slide").eq(i+n.options.slidesToShow+1),e=!0===n.options.rtl?o[0]?-1*(n.$slideTrack.width()-o[0].offsetLeft-o.width()):0:o[0]?-1*o[0].offsetLeft:0,e+=(n.$list.width()-o.outerWidth())/2)),e},e.prototype.getOption=e.prototype.slickGetOption=function(i){return this.options[i]},e.prototype.getNavigableIndexes=function(){var i,e=this,t=0,o=0,s=[];for(!1===e.options.infinite?i=e.slideCount:(t=-1*e.options.slidesToScroll,o=-1*e.options.slidesToScroll,i=2*e.slideCount);t<i;)s.push(t),t=o+e.options.slidesToScroll,o+=e.options.slidesToScroll<=e.options.slidesToShow?e.options.slidesToScroll:e.options.slidesToShow;return s},e.prototype.getSlick=function(){return this},e.prototype.getSlideCount=function(){var e,t,o=this;return t=!0===o.options.centerMode?o.slideWidth*Math.floor(o.options.slidesToShow/2):0,!0===o.options.swipeToSlide?(o.$slideTrack.find(".slick-slide").each(function(s,n){if(n.offsetLeft-t+i(n).outerWidth()/2>-1*o.swipeLeft)return e=n,!1}),Math.abs(i(e).attr("data-slick-index")-o.currentSlide)||1):o.options.slidesToScroll},e.prototype.goTo=e.prototype.slickGoTo=function(i,e){this.changeSlide({data:{message:"index",index:parseInt(i)}},e)},e.prototype.init=function(e){var t=this;i(t.$slider).hasClass("slick-initialized")||(i(t.$slider).addClass("slick-initialized"),t.buildRows(),t.buildOut(),t.setProps(),t.startLoad(),t.loadSlider(),t.initializeEvents(),t.updateArrows(),t.updateDots(),t.checkResponsive(!0),t.focusHandler()),e&&t.$slider.trigger("init",[t]),!0===t.options.accessibility&&t.initADA(),t.options.autoplay&&(t.paused=!1,t.autoPlay())},e.prototype.initADA=function(){var e=this,t=Math.ceil(e.slideCount/e.options.slidesToShow),o=e.getNavigableIndexes().filter(function(i){return i>=0&&i<e.slideCount});e.$slides.add(e.$slideTrack.find(".slick-cloned")).attr({"aria-hidden":"true",tabindex:"-1"}).find("a, input, button, select").attr({tabindex:"-1"}),null!==e.$dots&&(e.$slides.not(e.$slideTrack.find(".slick-cloned")).each(function(t){var s=o.indexOf(t);i(this).attr({role:"tabpanel",id:"slick-slide"+e.instanceUid+t,tabindex:-1}),-1!==s&&i(this).attr({"aria-describedby":"slick-slide-control"+e.instanceUid+s})}),e.$dots.attr("role","tablist").find("li").each(function(s){var n=o[s];i(this).attr({role:"presentation"}),i(this).find("button").first().attr({role:"tab",id:"slick-slide-control"+e.instanceUid+s,"aria-controls":"slick-slide"+e.instanceUid+n,"aria-label":s+1+" of "+t,"aria-selected":null,tabindex:"-1"})}).eq(e.currentSlide).find("button").attr({"aria-selected":"true",tabindex:"0"}).end());for(var s=e.currentSlide,n=s+e.options.slidesToShow;s<n;s++)e.$slides.eq(s).attr("tabindex",0);e.activateADA()},e.prototype.initArrowEvents=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.off("click.slick").on("click.slick",{message:"previous"},i.changeSlide),i.$nextArrow.off("click.slick").on("click.slick",{message:"next"},i.changeSlide),!0===i.options.accessibility&&(i.$prevArrow.on("keydown.slick",i.keyHandler),i.$nextArrow.on("keydown.slick",i.keyHandler)))},e.prototype.initDotEvents=function(){var e=this;!0===e.options.dots&&(i("li",e.$dots).on("click.slick",{message:"index"},e.changeSlide),!0===e.options.accessibility&&e.$dots.on("keydown.slick",e.keyHandler)),!0===e.options.dots&&!0===e.options.pauseOnDotsHover&&i("li",e.$dots).on("mouseenter.slick",i.proxy(e.interrupt,e,!0)).on("mouseleave.slick",i.proxy(e.interrupt,e,!1))},e.prototype.initSlideEvents=function(){var e=this;e.options.pauseOnHover&&(e.$list.on("mouseenter.slick",i.proxy(e.interrupt,e,!0)),e.$list.on("mouseleave.slick",i.proxy(e.interrupt,e,!1)))},e.prototype.initializeEvents=function(){var e=this;e.initArrowEvents(),e.initDotEvents(),e.initSlideEvents(),e.$list.on("touchstart.slick mousedown.slick",{action:"start"},e.swipeHandler),e.$list.on("touchmove.slick mousemove.slick",{action:"move"},e.swipeHandler),e.$list.on("touchend.slick mouseup.slick",{action:"end"},e.swipeHandler),e.$list.on("touchcancel.slick mouseleave.slick",{action:"end"},e.swipeHandler),e.$list.on("click.slick",e.clickHandler),i(document).on(e.visibilityChange,i.proxy(e.visibility,e)),!0===e.options.accessibility&&e.$list.on("keydown.slick",e.keyHandler),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().on("click.slick",e.selectHandler),i(window).on("orientationchange.slick.slick-"+e.instanceUid,i.proxy(e.orientationChange,e)),i(window).on("resize.slick.slick-"+e.instanceUid,i.proxy(e.resize,e)),i("[draggable!=true]",e.$slideTrack).on("dragstart",e.preventDefault),i(window).on("load.slick.slick-"+e.instanceUid,e.setPosition),i(e.setPosition)},e.prototype.initUI=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.show(),i.$nextArrow.show()),!0===i.options.dots&&i.slideCount>i.options.slidesToShow&&i.$dots.show()},e.prototype.keyHandler=function(i){var e=this;i.target.tagName.match("TEXTAREA|INPUT|SELECT")||(37===i.keyCode&&!0===e.options.accessibility?e.changeSlide({data:{message:!0===e.options.rtl?"next":"previous"}}):39===i.keyCode&&!0===e.options.accessibility&&e.changeSlide({data:{message:!0===e.options.rtl?"previous":"next"}}))},e.prototype.lazyLoad=function(){function e(e){i("img[data-lazy]",e).each(function(){var e=i(this),t=i(this).attr("data-lazy"),o=i(this).attr("data-srcset"),s=i(this).attr("data-sizes")||n.$slider.attr("data-sizes"),r=document.createElement("img");r.onload=function(){e.animate({opacity:0},100,function(){o&&(e.attr("srcset",o),s&&e.attr("sizes",s)),e.attr("src",t).animate({opacity:1},200,function(){e.removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading")}),n.$slider.trigger("lazyLoaded",[n,e,t])})},r.onerror=function(){e.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),n.$slider.trigger("lazyLoadError",[n,e,t])},r.src=t})}var t,o,s,n=this;if(!0===n.options.centerMode?!0===n.options.infinite?s=(o=n.currentSlide+(n.options.slidesToShow/2+1))+n.options.slidesToShow+2:(o=Math.max(0,n.currentSlide-(n.options.slidesToShow/2+1)),s=n.options.slidesToShow/2+1+2+n.currentSlide):(o=n.options.infinite?n.options.slidesToShow+n.currentSlide:n.currentSlide,s=Math.ceil(o+n.options.slidesToShow),!0===n.options.fade&&(o>0&&o--,s<=n.slideCount&&s++)),t=n.$slider.find(".slick-slide").slice(o,s),"anticipated"===n.options.lazyLoad)for(var r=o-1,l=s,d=n.$slider.find(".slick-slide"),a=0;a<n.options.slidesToScroll;a++)r<0&&(r=n.slideCount-1),t=(t=t.add(d.eq(r))).add(d.eq(l)),r--,l++;e(t),n.slideCount<=n.options.slidesToShow?e(n.$slider.find(".slick-slide")):n.currentSlide>=n.slideCount-n.options.slidesToShow?e(n.$slider.find(".slick-cloned").slice(0,n.options.slidesToShow)):0===n.currentSlide&&e(n.$slider.find(".slick-cloned").slice(-1*n.options.slidesToShow))},e.prototype.loadSlider=function(){var i=this;i.setPosition(),i.$slideTrack.css({opacity:1}),i.$slider.removeClass("slick-loading"),i.initUI(),"progressive"===i.options.lazyLoad&&i.progressiveLazyLoad()},e.prototype.next=e.prototype.slickNext=function(){this.changeSlide({data:{message:"next"}})},e.prototype.orientationChange=function(){var i=this;i.checkResponsive(),i.setPosition()},e.prototype.pause=e.prototype.slickPause=function(){var i=this;i.autoPlayClear(),i.paused=!0},e.prototype.play=e.prototype.slickPlay=function(){var i=this;i.autoPlay(),i.options.autoplay=!0,i.paused=!1,i.focussed=!1,i.interrupted=!1},e.prototype.postSlide=function(e){var t=this;t.unslicked||(t.$slider.trigger("afterChange",[t,e]),t.animating=!1,t.slideCount>t.options.slidesToShow&&t.setPosition(),t.swipeLeft=null,t.options.autoplay&&t.autoPlay(),!0===t.options.accessibility&&(t.initADA(),t.options.focusOnChange&&i(t.$slides.get(t.currentSlide)).attr("tabindex",0).focus()))},e.prototype.prev=e.prototype.slickPrev=function(){this.changeSlide({data:{message:"previous"}})},e.prototype.preventDefault=function(i){i.preventDefault()},e.prototype.progressiveLazyLoad=function(e){e=e||1;var t,o,s,n,r,l=this,d=i("img[data-lazy]",l.$slider);d.length?(t=d.first(),o=t.attr("data-lazy"),s=t.attr("data-srcset"),n=t.attr("data-sizes")||l.$slider.attr("data-sizes"),(r=document.createElement("img")).onload=function(){s&&(t.attr("srcset",s),n&&t.attr("sizes",n)),t.attr("src",o).removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading"),!0===l.options.adaptiveHeight&&l.setPosition(),l.$slider.trigger("lazyLoaded",[l,t,o]),l.progressiveLazyLoad()},r.onerror=function(){e<3?setTimeout(function(){l.progressiveLazyLoad(e+1)},500):(t.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),l.$slider.trigger("lazyLoadError",[l,t,o]),l.progressiveLazyLoad())},r.src=o):l.$slider.trigger("allImagesLoaded",[l])},e.prototype.refresh=function(e){var t,o,s=this;o=s.slideCount-s.options.slidesToShow,!s.options.infinite&&s.currentSlide>o&&(s.currentSlide=o),s.slideCount<=s.options.slidesToShow&&(s.currentSlide=0),t=s.currentSlide,s.destroy(!0),i.extend(s,s.initials,{currentSlide:t}),s.init(),e||s.changeSlide({data:{message:"index",index:t}},!1)},e.prototype.registerBreakpoints=function(){var e,t,o,s=this,n=s.options.responsive||null;if("array"===i.type(n)&&n.length){s.respondTo=s.options.respondTo||"window";for(e in n)if(o=s.breakpoints.length-1,n.hasOwnProperty(e)){for(t=n[e].breakpoint;o>=0;)s.breakpoints[o]&&s.breakpoints[o]===t&&s.breakpoints.splice(o,1),o--;s.breakpoints.push(t),s.breakpointSettings[t]=n[e].settings}s.breakpoints.sort(function(i,e){return s.options.mobileFirst?i-e:e-i})}},e.prototype.reinit=function(){var e=this;e.$slides=e.$slideTrack.children(e.options.slide).addClass("slick-slide"),e.slideCount=e.$slides.length,e.currentSlide>=e.slideCount&&0!==e.currentSlide&&(e.currentSlide=e.currentSlide-e.options.slidesToScroll),e.slideCount<=e.options.slidesToShow&&(e.currentSlide=0),e.registerBreakpoints(),e.setProps(),e.setupInfinite(),e.buildArrows(),e.updateArrows(),e.initArrowEvents(),e.buildDots(),e.updateDots(),e.initDotEvents(),e.cleanUpSlideEvents(),e.initSlideEvents(),e.checkResponsive(!1,!0),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().on("click.slick",e.selectHandler),e.setSlideClasses("number"==typeof e.currentSlide?e.currentSlide:0),e.setPosition(),e.focusHandler(),e.paused=!e.options.autoplay,e.autoPlay(),e.$slider.trigger("reInit",[e])},e.prototype.resize=function(){var e=this;i(window).width()!==e.windowWidth&&(clearTimeout(e.windowDelay),e.windowDelay=window.setTimeout(function(){e.windowWidth=i(window).width(),e.checkResponsive(),e.unslicked||e.setPosition()},50))},e.prototype.removeSlide=e.prototype.slickRemove=function(i,e,t){var o=this;if(i="boolean"==typeof i?!0===(e=i)?0:o.slideCount-1:!0===e?--i:i,o.slideCount<1||i<0||i>o.slideCount-1)return!1;o.unload(),!0===t?o.$slideTrack.children().remove():o.$slideTrack.children(this.options.slide).eq(i).remove(),o.$slides=o.$slideTrack.children(this.options.slide),o.$slideTrack.children(this.options.slide).detach(),o.$slideTrack.append(o.$slides),o.$slidesCache=o.$slides,o.reinit()},e.prototype.setCSS=function(i){var e,t,o=this,s={};!0===o.options.rtl&&(i=-i),e="left"==o.positionProp?Math.ceil(i)+"px":"0px",t="top"==o.positionProp?Math.ceil(i)+"px":"0px",s[o.positionProp]=i,!1===o.transformsEnabled?o.$slideTrack.css(s):(s={},!1===o.cssTransitions?(s[o.animType]="translate("+e+", "+t+")",o.$slideTrack.css(s)):(s[o.animType]="translate3d("+e+", "+t+", 0px)",o.$slideTrack.css(s)))},e.prototype.setDimensions=function(){var i=this;!1===i.options.vertical?!0===i.options.centerMode&&i.$list.css({padding:"0px "+i.options.centerPadding}):(i.$list.height(i.$slides.first().outerHeight(!0)*i.options.slidesToShow),!0===i.options.centerMode&&i.$list.css({padding:i.options.centerPadding+" 0px"})),i.listWidth=i.$list.width(),i.listHeight=i.$list.height(),!1===i.options.vertical&&!1===i.options.variableWidth?(i.slideWidth=Math.ceil(i.listWidth/i.options.slidesToShow),i.$slideTrack.width(Math.ceil(i.slideWidth*i.$slideTrack.children(".slick-slide").length))):!0===i.options.variableWidth?i.$slideTrack.width(5e3*i.slideCount):(i.slideWidth=Math.ceil(i.listWidth),i.$slideTrack.height(Math.ceil(i.$slides.first().outerHeight(!0)*i.$slideTrack.children(".slick-slide").length)));var e=i.$slides.first().outerWidth(!0)-i.$slides.first().width();!1===i.options.variableWidth&&i.$slideTrack.children(".slick-slide").width(i.slideWidth-e)},e.prototype.setFade=function(){var e,t=this;t.$slides.each(function(o,s){e=t.slideWidth*o*-1,!0===t.options.rtl?i(s).css({position:"relative",right:e,top:0,zIndex:t.options.zIndex-2,opacity:0}):i(s).css({position:"relative",left:e,top:0,zIndex:t.options.zIndex-2,opacity:0})}),t.$slides.eq(t.currentSlide).css({zIndex:t.options.zIndex-1,opacity:1})},e.prototype.setHeight=function(){var i=this;if(1===i.options.slidesToShow&&!0===i.options.adaptiveHeight&&!1===i.options.vertical){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.css("height",e)}},e.prototype.setOption=e.prototype.slickSetOption=function(){var e,t,o,s,n,r=this,l=!1;if("object"===i.type(arguments[0])?(o=arguments[0],l=arguments[1],n="multiple"):"string"===i.type(arguments[0])&&(o=arguments[0],s=arguments[1],l=arguments[2],"responsive"===arguments[0]&&"array"===i.type(arguments[1])?n="responsive":void 0!==arguments[1]&&(n="single")),"single"===n)r.options[o]=s;else if("multiple"===n)i.each(o,function(i,e){r.options[i]=e});else if("responsive"===n)for(t in s)if("array"!==i.type(r.options.responsive))r.options.responsive=[s[t]];else{for(e=r.options.responsive.length-1;e>=0;)r.options.responsive[e].breakpoint===s[t].breakpoint&&r.options.responsive.splice(e,1),e--;r.options.responsive.push(s[t])}l&&(r.unload(),r.reinit())},e.prototype.setPosition=function(){var i=this;i.setDimensions(),i.setHeight(),!1===i.options.fade?i.setCSS(i.getLeft(i.currentSlide)):i.setFade(),i.$slider.trigger("setPosition",[i])},e.prototype.setProps=function(){var i=this,e=document.body.style;i.positionProp=!0===i.options.vertical?"top":"left","top"===i.positionProp?i.$slider.addClass("slick-vertical"):i.$slider.removeClass("slick-vertical"),void 0===e.WebkitTransition&&void 0===e.MozTransition&&void 0===e.msTransition||!0===i.options.useCSS&&(i.cssTransitions=!0),i.options.fade&&("number"==typeof i.options.zIndex?i.options.zIndex<3&&(i.options.zIndex=3):i.options.zIndex=i.defaults.zIndex),void 0!==e.OTransform&&(i.animType="OTransform",i.transformType="-o-transform",i.transitionType="OTransition",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.MozTransform&&(i.animType="MozTransform",i.transformType="-moz-transform",i.transitionType="MozTransition",void 0===e.perspectiveProperty&&void 0===e.MozPerspective&&(i.animType=!1)),void 0!==e.webkitTransform&&(i.animType="webkitTransform",i.transformType="-webkit-transform",i.transitionType="webkitTransition",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.msTransform&&(i.animType="msTransform",i.transformType="-ms-transform",i.transitionType="msTransition",void 0===e.msTransform&&(i.animType=!1)),void 0!==e.transform&&!1!==i.animType&&(i.animType="transform",i.transformType="transform",i.transitionType="transition"),i.transformsEnabled=i.options.useTransform&&null!==i.animType&&!1!==i.animType},e.prototype.setSlideClasses=function(i){var e,t,o,s,n=this;if(t=n.$slider.find(".slick-slide").removeClass("slick-active slick-center slick-current").attr("aria-hidden","true"),n.$slides.eq(i).addClass("slick-current"),!0===n.options.centerMode){var r=n.options.slidesToShow%2==0?1:0;e=Math.floor(n.options.slidesToShow/2),!0===n.options.infinite&&(i>=e&&i<=n.slideCount-1-e?n.$slides.slice(i-e+r,i+e+1).addClass("slick-active").attr("aria-hidden","false"):(o=n.options.slidesToShow+i,t.slice(o-e+1+r,o+e+2).addClass("slick-active").attr("aria-hidden","false")),0===i?t.eq(t.length-1-n.options.slidesToShow).addClass("slick-center"):i===n.slideCount-1&&t.eq(n.options.slidesToShow).addClass("slick-center")),n.$slides.eq(i).addClass("slick-center")}else i>=0&&i<=n.slideCount-n.options.slidesToShow?n.$slides.slice(i,i+n.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"):t.length<=n.options.slidesToShow?t.addClass("slick-active").attr("aria-hidden","false"):(s=n.slideCount%n.options.slidesToShow,o=!0===n.options.infinite?n.options.slidesToShow+i:i,n.options.slidesToShow==n.options.slidesToScroll&&n.slideCount-i<n.options.slidesToShow?t.slice(o-(n.options.slidesToShow-s),o+s).addClass("slick-active").attr("aria-hidden","false"):t.slice(o,o+n.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"));"ondemand"!==n.options.lazyLoad&&"anticipated"!==n.options.lazyLoad||n.lazyLoad()},e.prototype.setupInfinite=function(){var e,t,o,s=this;if(!0===s.options.fade&&(s.options.centerMode=!1),!0===s.options.infinite&&!1===s.options.fade&&(t=null,s.slideCount>s.options.slidesToShow)){for(o=!0===s.options.centerMode?s.options.slidesToShow+1:s.options.slidesToShow,e=s.slideCount;e>s.slideCount-o;e-=1)t=e-1,i(s.$slides[t]).clone(!0).attr("id","").attr("data-slick-index",t-s.slideCount).prependTo(s.$slideTrack).addClass("slick-cloned");for(e=0;e<o+s.slideCount;e+=1)t=e,i(s.$slides[t]).clone(!0).attr("id","").attr("data-slick-index",t+s.slideCount).appendTo(s.$slideTrack).addClass("slick-cloned");s.$slideTrack.find(".slick-cloned").find("[id]").each(function(){i(this).attr("id","")})}},e.prototype.interrupt=function(i){var e=this;i||e.autoPlay(),e.interrupted=i},e.prototype.selectHandler=function(e){var t=this,o=i(e.target).is(".slick-slide")?i(e.target):i(e.target).parents(".slick-slide"),s=parseInt(o.attr("data-slick-index"));s||(s=0),t.slideCount<=t.options.slidesToShow?t.slideHandler(s,!1,!0):t.slideHandler(s)},e.prototype.slideHandler=function(i,e,t){var o,s,n,r,l,d=null,a=this;if(e=e||!1,!(!0===a.animating&&!0===a.options.waitForAnimate||!0===a.options.fade&&a.currentSlide===i))if(!1===e&&a.asNavFor(i),o=i,d=a.getLeft(o),r=a.getLeft(a.currentSlide),a.currentLeft=null===a.swipeLeft?r:a.swipeLeft,!1===a.options.infinite&&!1===a.options.centerMode&&(i<0||i>a.getDotCount()*a.options.slidesToScroll))!1===a.options.fade&&(o=a.currentSlide,!0!==t?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o));else if(!1===a.options.infinite&&!0===a.options.centerMode&&(i<0||i>a.slideCount-a.options.slidesToScroll))!1===a.options.fade&&(o=a.currentSlide,!0!==t?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o));else{if(a.options.autoplay&&clearInterval(a.autoPlayTimer),s=o<0?a.slideCount%a.options.slidesToScroll!=0?a.slideCount-a.slideCount%a.options.slidesToScroll:a.slideCount+o:o>=a.slideCount?a.slideCount%a.options.slidesToScroll!=0?0:o-a.slideCount:o,a.animating=!0,a.$slider.trigger("beforeChange",[a,a.currentSlide,s]),n=a.currentSlide,a.currentSlide=s,a.setSlideClasses(a.currentSlide),a.options.asNavFor&&(l=(l=a.getNavTarget()).slick("getSlick")).slideCount<=l.options.slidesToShow&&l.setSlideClasses(a.currentSlide),a.updateDots(),a.updateArrows(),!0===a.options.fade)return!0!==t?(a.fadeSlideOut(n),a.fadeSlide(s,function(){a.postSlide(s)})):a.postSlide(s),void a.animateHeight();!0!==t?a.animateSlide(d,function(){a.postSlide(s)}):a.postSlide(s)}},e.prototype.startLoad=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.hide(),i.$nextArrow.hide()),!0===i.options.dots&&i.slideCount>i.options.slidesToShow&&i.$dots.hide(),i.$slider.addClass("slick-loading")},e.prototype.swipeDirection=function(){var i,e,t,o,s=this;return i=s.touchObject.startX-s.touchObject.curX,e=s.touchObject.startY-s.touchObject.curY,t=Math.atan2(e,i),(o=Math.round(180*t/Math.PI))<0&&(o=360-Math.abs(o)),o<=45&&o>=0?!1===s.options.rtl?"left":"right":o<=360&&o>=315?!1===s.options.rtl?"left":"right":o>=135&&o<=225?!1===s.options.rtl?"right":"left":!0===s.options.verticalSwiping?o>=35&&o<=135?"down":"up":"vertical"},e.prototype.swipeEnd=function(i){var e,t,o=this;if(o.dragging=!1,o.swiping=!1,o.scrolling)return o.scrolling=!1,!1;if(o.interrupted=!1,o.shouldClick=!(o.touchObject.swipeLength>10),void 0===o.touchObject.curX)return!1;if(!0===o.touchObject.edgeHit&&o.$slider.trigger("edge",[o,o.swipeDirection()]),o.touchObject.swipeLength>=o.touchObject.minSwipe){switch(t=o.swipeDirection()){case"left":case"down":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide+o.getSlideCount()):o.currentSlide+o.getSlideCount(),o.currentDirection=0;break;case"right":case"up":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide-o.getSlideCount()):o.currentSlide-o.getSlideCount(),o.currentDirection=1}"vertical"!=t&&(o.slideHandler(e),o.touchObject={},o.$slider.trigger("swipe",[o,t]))}else o.touchObject.startX!==o.touchObject.curX&&(o.slideHandler(o.currentSlide),o.touchObject={})},e.prototype.swipeHandler=function(i){var e=this;if(!(!1===e.options.swipe||"ontouchend"in document&&!1===e.options.swipe||!1===e.options.draggable&&-1!==i.type.indexOf("mouse")))switch(e.touchObject.fingerCount=i.originalEvent&&void 0!==i.originalEvent.touches?i.originalEvent.touches.length:1,e.touchObject.minSwipe=e.listWidth/e.options.touchThreshold,!0===e.options.verticalSwiping&&(e.touchObject.minSwipe=e.listHeight/e.options.touchThreshold),i.data.action){case"start":e.swipeStart(i);break;case"move":e.swipeMove(i);break;case"end":e.swipeEnd(i)}},e.prototype.swipeMove=function(i){var e,t,o,s,n,r,l=this;return n=void 0!==i.originalEvent?i.originalEvent.touches:null,!(!l.dragging||l.scrolling||n&&1!==n.length)&&(e=l.getLeft(l.currentSlide),l.touchObject.curX=void 0!==n?n[0].pageX:i.clientX,l.touchObject.curY=void 0!==n?n[0].pageY:i.clientY,l.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(l.touchObject.curX-l.touchObject.startX,2))),r=Math.round(Math.sqrt(Math.pow(l.touchObject.curY-l.touchObject.startY,2))),!l.options.verticalSwiping&&!l.swiping&&r>4?(l.scrolling=!0,!1):(!0===l.options.verticalSwiping&&(l.touchObject.swipeLength=r),t=l.swipeDirection(),void 0!==i.originalEvent&&l.touchObject.swipeLength>4&&(l.swiping=!0,i.preventDefault()),s=(!1===l.options.rtl?1:-1)*(l.touchObject.curX>l.touchObject.startX?1:-1),!0===l.options.verticalSwiping&&(s=l.touchObject.curY>l.touchObject.startY?1:-1),o=l.touchObject.swipeLength,l.touchObject.edgeHit=!1,!1===l.options.infinite&&(0===l.currentSlide&&"right"===t||l.currentSlide>=l.getDotCount()&&"left"===t)&&(o=l.touchObject.swipeLength*l.options.edgeFriction,l.touchObject.edgeHit=!0),!1===l.options.vertical?l.swipeLeft=e+o*s:l.swipeLeft=e+o*(l.$list.height()/l.listWidth)*s,!0===l.options.verticalSwiping&&(l.swipeLeft=e+o*s),!0!==l.options.fade&&!1!==l.options.touchMove&&(!0===l.animating?(l.swipeLeft=null,!1):void l.setCSS(l.swipeLeft))))},e.prototype.swipeStart=function(i){var e,t=this;if(t.interrupted=!0,1!==t.touchObject.fingerCount||t.slideCount<=t.options.slidesToShow)return t.touchObject={},!1;void 0!==i.originalEvent&&void 0!==i.originalEvent.touches&&(e=i.originalEvent.touches[0]),t.touchObject.startX=t.touchObject.curX=void 0!==e?e.pageX:i.clientX,t.touchObject.startY=t.touchObject.curY=void 0!==e?e.pageY:i.clientY,t.dragging=!0},e.prototype.unfilterSlides=e.prototype.slickUnfilter=function(){var i=this;null!==i.$slidesCache&&(i.unload(),i.$slideTrack.children(this.options.slide).detach(),i.$slidesCache.appendTo(i.$slideTrack),i.reinit())},e.prototype.unload=function(){var e=this;i(".slick-cloned",e.$slider).remove(),e.$dots&&e.$dots.remove(),e.$prevArrow&&e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.remove(),e.$nextArrow&&e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.remove(),e.$slides.removeClass("slick-slide slick-active slick-visible slick-current").attr("aria-hidden","true").css("width","")},e.prototype.unslick=function(i){var e=this;e.$slider.trigger("unslick",[e,i]),e.destroy()},e.prototype.updateArrows=function(){var i=this;Math.floor(i.options.slidesToShow/2),!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&!i.options.infinite&&(i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false"),i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false"),0===i.currentSlide?(i.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false")):i.currentSlide>=i.slideCount-i.options.slidesToShow&&!1===i.options.centerMode?(i.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")):i.currentSlide>=i.slideCount-1&&!0===i.options.centerMode&&(i.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")))},e.prototype.updateDots=function(){var i=this;null!==i.$dots&&(i.$dots.find("li").removeClass("slick-active").end(),i.$dots.find("li").eq(Math.floor(i.currentSlide/i.options.slidesToScroll)).addClass("slick-active"))},e.prototype.visibility=function(){var i=this;i.options.autoplay&&(document[i.hidden]?i.interrupted=!0:i.interrupted=!1)},i.fn.slick=function(){var i,t,o=this,s=arguments[0],n=Array.prototype.slice.call(arguments,1),r=o.length;for(i=0;i<r;i++)if("object"==typeof s||void 0===s?o[i].slick=new e(o[i],s):t=o[i].slick[s].apply(o[i].slick,n),void 0!==t)return t;return o}}); 14519 14520 14521 /***/ }), 14522
vendor: 6,010 bytes, lines 14523-14539
14523/***/ "./node_modules/vanilla-lazyload/dist/lazyload.min.js": 14524/*!************************************************************!*\ 14525 !*** ./node_modules/vanilla-lazyload/dist/lazyload.min.js ***! 14526 \************************************************************/ 14527 /*! no static exports found */ 14528 /***/ (function(module, exports, __webpack_require__) { 14529 14530 var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;function _extends(){return(_extends=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&(t[o]=n[o])}return t}).apply(this,arguments)}function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function(t,e){"object"===( false?undefined:_typeof(exports))&&"undefined"!=typeof module?module.exports=e(): true?!(__WEBPACK_AMD_DEFINE_FACTORY__ = (e), 14531 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 14532 (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : 14533 __WEBPACK_AMD_DEFINE_FACTORY__), 14534 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):undefined}(this,function(){"use strict";var t="undefined"!=typeof window,e=t&&!("onscroll"in window)||"undefined"!=typeof navigator&&/(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent),n=t&&"IntersectionObserver"in window,o=t&&"classList"in document.createElement("p"),r={elements_selector:"img",container:e||t?document:null,threshold:300,thresholds:null,data_src:"src",data_srcset:"srcset",data_sizes:"sizes",data_bg:"bg",class_loading:"loading",class_loaded:"loaded",class_error:"error",load_delay:0,auto_unobserve:!0,callback_enter:null,callback_exit:null,callback_reveal:null,callback_loaded:null,callback_error:null,callback_finish:null},a=function(t,e){return t.getAttribute("data-"+e)},s=function(t,e,n){var o="data-"+e;null!==n?t.setAttribute(o,n):t.removeAttribute(o)},i=function(t){return"true"===a(t,"was-processed")},c=function(t,e){return s(t,"ll-timeout",e)},l=function(t){return a(t,"ll-timeout")},u=function(t,e){var n,o=new t(e);try{n=new CustomEvent("LazyLoad::Initialized",{detail:{instance:o}})}catch(t){(n=document.createEvent("CustomEvent")).initCustomEvent("LazyLoad::Initialized",!1,!1,{instance:o})}window.dispatchEvent(n)};var d=function(t,e){t&&t(e)},f=function(t,e){t._loadingCount+=e,0===t._elements.length&&0===t._loadingCount&&d(t._settings.callback_finish)},_=function(t){for(var e,n=[],o=0;e=t.children[o];o+=1)"SOURCE"===e.tagName&&n.push(e);return n},v=function(t,e,n){n&&t.setAttribute(e,n)},b=function(t,e){v(t,"sizes",a(t,e.data_sizes)),v(t,"srcset",a(t,e.data_srcset)),v(t,"src",a(t,e.data_src))},g={IMG:function(t,e){var n=t.parentNode;n&&"PICTURE"===n.tagName&&_(n).forEach(function(t){b(t,e)});b(t,e)},IFRAME:function(t,e){v(t,"src",a(t,e.data_src))},VIDEO:function(t,e){_(t).forEach(function(t){v(t,"src",a(t,e.data_src))}),v(t,"src",a(t,e.data_src)),t.load()}},m=function(t,e){var n,o,r=e._settings,s=t.tagName,i=g[s];if(i)return i(t,r),f(e,1),void(e._elements=(n=e._elements,o=t,n.filter(function(t){return t!==o})));!function(t,e){var n=a(t,e.data_src),o=a(t,e.data_bg);n&&(t.style.backgroundImage='url("'.concat(n,'")')),o&&(t.style.backgroundImage=o)}(t,r)},h=function(t,e){o?t.classList.add(e):t.className+=(t.className?" ":"")+e},p=function(t,e,n){t.addEventListener(e,n)},y=function(t,e,n){t.removeEventListener(e,n)},E=function(t,e,n){y(t,"load",e),y(t,"loadeddata",e),y(t,"error",n)},w=function(t,e,n){var r=n._settings,a=e?r.class_loaded:r.class_error,s=e?r.callback_loaded:r.callback_error,i=t.target;!function(t,e){o?t.classList.remove(e):t.className=t.className.replace(new RegExp("(^|\\s+)"+e+"(\\s+|$)")," ").replace(/^\s+/,"").replace(/\s+$/,"")}(i,r.class_loading),h(i,a),d(s,i),f(n,-1)},k=function(t,e){var n=function n(r){w(r,!0,e),E(t,n,o)},o=function o(r){w(r,!1,e),E(t,n,o)};!function(t,e,n){p(t,"load",e),p(t,"loadeddata",e),p(t,"error",n)}(t,n,o)},I=["IMG","IFRAME","VIDEO"],L=function(t,e){var n=e._observer;z(t,e),n&&e._settings.auto_unobserve&&n.unobserve(t)},x=function(t){var e=l(t);e&&(clearTimeout(e),c(t,null))},A=function(t,e){var n=e._settings.load_delay,o=l(t);o||(o=setTimeout(function(){L(t,e),x(t)},n),c(t,o))},z=function(t,e,n){var o=e._settings;!n&&i(t)||(I.indexOf(t.tagName)>-1&&(k(t,e),h(t,o.class_loading)),m(t,e),function(t){s(t,"was-processed","true")}(t),d(o.callback_reveal,t),d(o.callback_set,t))},O=function(t){return!!n&&(t._observer=new IntersectionObserver(function(e){e.forEach(function(e){return function(t){return t.isIntersecting||t.intersectionRatio>0}(e)?function(t,e){var n=e._settings;d(n.callback_enter,t),n.load_delay?A(t,e):L(t,e)}(e.target,t):function(t,e){var n=e._settings;d(n.callback_exit,t),n.load_delay&&x(t)}(e.target,t)})},{root:(e=t._settings).container===document?null:e.container,rootMargin:e.thresholds||e.threshold+"px"}),!0);var e},N=function(t,e){this._settings=function(t){return _extends({},r,t)}(t),this._loadingCount=0,O(this),this.update(e)};return N.prototype={update:function(t){var n=this,o=this._settings,r=t||o.container.querySelectorAll(o.elements_selector);this._elements=function(t){return t.filter(function(t){return!i(t)})}(Array.prototype.slice.call(r)),!e&&this._observer?this._elements.forEach(function(t){n._observer.observe(t)}):this.loadAll()},destroy:function(){var t=this;this._observer&&(this._elements.forEach(function(e){t._observer.unobserve(e)}),this._observer=null),this._elements=null,this._settings=null},load:function(t,e){z(t,this,e)},loadAll:function(){var t=this;this._elements.forEach(function(e){L(e,t)})}},t&&function(t,e){if(e)if(e.length)for(var n,o=0;n=e[o];o+=1)u(t,n);else u(t,e)}(N,window.lazyLoadOptions),N}); 14535//# sourceMappingURL=lazyload.min.js.map 14536 14537 14538/***/ }), 14539
14540/***/ "./wp-content/themes/pnr/assets/src/js/app.js": 14541/*!****************************************************!*\ 14542 !*** ./wp-content/themes/pnr/assets/src/js/app.js ***! 14543 \****************************************************/ 14544 /*! no exports provided */ 14545 /***/ (function(module, __webpack_exports__, __webpack_require__) { 14546 14547 "use strict"; 14548 __webpack_require__.r(__webpack_exports__); 14549 /* harmony import */ var _pnr_scss_castagnades_scss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @pnr/scss/castagnades.scss */ "./wp-content/themes/pnr/assets/src/scss/castagnades.scss"); 14550 /* harmony import */ var _pnr_scss_castagnades_scss__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_pnr_scss_castagnades_scss__WEBPACK_IMPORTED_MODULE_0__); 14551 /* harmony import */ var _pnr_scss_castagnades_editor_scss__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @pnr/scss/castagnades-editor.scss */ "./wp-content/themes/pnr/assets/src/scss/castagnades-editor.scss"); 14552 /* harmony import */ var _pnr_scss_castagnades_editor_scss__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_pnr_scss_castagnades_editor_scss__WEBPACK_IMPORTED_MODULE_1__); 14553 /* harmony import */ var _pnr_scss_partage_scss__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @pnr/scss/partage.scss */ "./wp-content/themes/pnr/assets/src/scss/partage.scss"); 14554 /* harmony import */ var _pnr_scss_partage_scss__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_pnr_scss_partage_scss__WEBPACK_IMPORTED_MODULE_2__); 14555 /* harmony import */ var _pnr_scss_partage_editor_scss__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @pnr/scss/partage-editor.scss */ "./wp-content/themes/pnr/assets/src/scss/partage-editor.scss"); 14556 /* harmony import */ var _pnr_scss_partage_editor_scss__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_pnr_scss_partage_editor_scss__WEBPACK_IMPORTED_MODULE_3__); 14557 /* harmony import */ var _pnr_scss_pnr_scss__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @pnr/scss/pnr.scss */ "./wp-content/themes/pnr/assets/src/scss/pnr.scss"); 14558 /* harmony import */ var _pnr_scss_pnr_scss__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_pnr_scss_pnr_scss__WEBPACK_IMPORTED_MODULE_4__); 14559 /* harmony import */ var _pnr_scss_pnr_editor_scss__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @pnr/scss/pnr-editor.scss */ "./wp-content/themes/pnr/assets/src/scss/pnr-editor.scss"); 14560 /* harmony import */ var _pnr_scss_pnr_editor_scss__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_pnr_scss_pnr_editor_scss__WEBPACK_IMPORTED_MODULE_5__); 14561 /* harmony import */ var _pnr_js_bootstrap_bundle_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @pnr/js/bootstrap.bundle.js */ "./wp-content/themes/pnr/assets/src/js/bootstrap.bundle.js"); 14562 /* harmony import */ var _pnr_js_bootstrap_bundle_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_pnr_js_bootstrap_bundle_js__WEBPACK_IMPORTED_MODULE_6__); 14563 /* harmony import */ var _pnr_js_components_ux_cpnt__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @pnr/js/components/ux_cpnt */ "./wp-content/themes/pnr/assets/src/js/components/ux_cpnt.js"); 14564 /* harmony import */ var _pnr_js_components_AutoHiddingNav__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @pnr/js/components/AutoHiddingNav */ "./wp-content/themes/pnr/assets/src/js/components/AutoHiddingNav.js"); 14565 /* harmony import */ var _pnr_js_components_form_cpnt__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @pnr/js/components/form_cpnt */ "./wp-content/themes/pnr/assets/src/js/components/form_cpnt.js"); 14566 /* harmony import */ var _pnr_js_components_map_cpnt__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @pnr/js/components/map_cpnt */ "./wp-content/themes/pnr/assets/src/js/components/map_cpnt.js"); 14567 /* harmony import */ var _pnr_js_components_Slider__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @pnr/js/components/Slider */ "./wp-content/themes/pnr/assets/src/js/components/Slider.js"); 14568 /* harmony import */ var _pnr_js_components_blocMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @pnr/js/components/blocMap */ "./wp-content/themes/pnr/assets/src/js/components/blocMap.js"); 14569 /* harmony import */ var _pnr_js_components_Gallery__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @pnr/js/components/Gallery */ "./wp-content/themes/pnr/assets/src/js/components/Gallery.js"); 14570 /* harmony import */ var _pnr_js_components_Api__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @pnr/js/components/Api */ "./wp-content/themes/pnr/assets/src/js/components/Api.js"); 14571 14572 14573 14574 14575 14576 14577 14578 14579 14580 14581 14582 14583 14584 14585 14586 document.addEventListener("DOMContentLoaded", function () { 14587 var ObjUxCpnt = new _pnr_js_components_ux_cpnt__WEBPACK_IMPORTED_MODULE_7__["UxCpnt"](); 14588 var ObjFormCpnt = new _pnr_js_components_form_cpnt__WEBPACK_IMPORTED_MODULE_9__["FormCpnt"](); 14589 var ObjMapCpnt = new _pnr_js_components_map_cpnt__WEBPACK_IMPORTED_MODULE_10__["MapCpnt"](); 14590 var ObjAutoHiddingNav = new _pnr_js_components_AutoHiddingNav__WEBPACK_IMPORTED_MODULE_8__["AutoHiddingNav"]();
14591 var ObjSlider = new _pnr_js_components_Slider__WEBPACK_IMPORTED_MODULE_11__["Slider"](); 14592 var ObjblocMap = new _pnr_js_components_blocMap__WEBPACK_IMPORTED_MODULE_12__["blocMap"](); 14593 var ObjGalleryCpnt = new _pnr_js_components_Gallery__WEBPACK_IMPORTED_MODULE_13__["GalleryCpnt"](); 14594 var ObjApiCpnt = new _pnr_js_components_Api__WEBPACK_IMPORTED_MODULE_14__["ApiCpnt"](); 14595 }); 14596 14597 /***/ }), 14598
14599/***/ "./wp-content/themes/pnr/assets/src/js/bootstrap.bundle.js": 14600/*!*****************************************************************!*\ 14601 !*** ./wp-content/themes/pnr/assets/src/js/bootstrap.bundle.js ***! 14602 \*****************************************************************/ 14603 /*! no static exports found */ 14604 /***/ (function(module, exports, __webpack_require__) { 14605 14606 /* WEBPACK VAR INJECTION */(function(jQuery) {function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 14607 14608/*! 14609 * Generated using the Bootstrap Customizer (https://getbootstrap.com/docs/3.4/customize/) 14610 */ 14611 14612/*! 14613 * Bootstrap v3.4.1 (https://getbootstrap.com/) 14614 * Copyright 2011-2019 Twitter, Inc. 14615 * Licensed under the MIT license 14616 */ 14617 if ("undefined" == typeof jQuery) throw new Error("Bootstrap's JavaScript requires jQuery"); 14618 +function (t) { 14619 "use strict"; 14620 14621 var e = t.fn.jquery.split(" ")[0].split("."); 14622 if (e[0] < 2 && e[1] < 9 || 1 == e[0] && 9 == e[1] && e[2] < 1 || e[0] > 3) throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4"); 14623}(jQuery), +function (t) { 14624 "use strict"; 14625 14626 function e(e) { 14627 return this.each(function () { 14628 var i = t(this), 14629 n = i.data("bs.alert"); 14630 n || i.data("bs.alert", n = new o(this)), "string" == typeof e && n[e].call(i); 14631 }); 14632 } 14633 14634 var i = '[data-dismiss="alert"]', 14635 o = function o(e) { 14636 t(e).on("click", i, this.close); 14637 }; 14638 14639 o.VERSION = "3.4.1", o.TRANSITION_DURATION = 150, o.prototype.close = function (e) { 14640 function i() { 14641 a.detach().trigger("closed.bs.alert").remove(); 14642 } 14643 14644 var n = t(this), 14645 s = n.attr("data-target"); 14646 s || (s = n.attr("href"), s = s && s.replace(/.*(?=#[^\s]*$)/, "")), s = "#" === s ? [] : s; 14647 var a = t(document).find(s); 14648 e && e.preventDefault(), a.length || (a = n.closest(".alert")), a.trigger(e = t.Event("close.bs.alert")), e.isDefaultPrevented() || (a.removeClass("in"), t.support.transition && a.hasClass("fade") ? a.one("bsTransitionEnd", i).emulateTransitionEnd(o.TRANSITION_DURATION) : i()); 14649 }; 14650 var n = t.fn.alert; 14651 t.fn.alert = e, t.fn.alert.Constructor = o, t.fn.alert.noConflict = function () { 14652 return t.fn.alert = n, this; 14653 }, t(document).on("click.bs.alert.data-api", i, o.prototype.close); 14654}(jQuery), +function (t) { 14655 "use strict"; 14656 14657 function e(e) { 14658 return this.each(function () { 14659 var o = t(this), 14660 n = o.data("bs.button"), 14661 s = "object" == _typeof(e) && e; 14662 n || o.data("bs.button", n = new i(this, s)), "toggle" == e ? n.toggle() : e && n.setState(e); 14663 }); 14664 } 14665 14666 var i = function i(e, o) { 14667 this.$element = t(e), this.options = t.extend({}, i.DEFAULTS, o), this.isLoading = !1; 14668 }; 14669 14670 i.VERSION = "3.4.1", i.DEFAULTS = { 14671 loadingText: "loading..." 14672 }, i.prototype.setState = function (e) { 14673 var i = "disabled", 14674 o = this.$element, 14675 n = o.is("input") ? "val" : "html", 14676 s = o.data(); 14677 e += "Text", null == s.resetText && o.data("resetText", o[n]()), setTimeout(t.proxy(function () { 14678 o[n](null == s[e] ? this.options[e] : s[e]), "loadingText" == e ? (this.isLoading = !0, o.addClass(i).attr(i, i).prop(i, !0)) : this.isLoading && (this.isLoading = !1, o.removeClass(i).removeAttr(i).prop(i, !1)); 14679 }, this), 0); 14680 }, i.prototype.toggle = function () { 14681 var t = !0, 14682 e = this.$element.closest('[data-toggle="buttons"]'); 14683 14684 if (e.length) { 14685 var i = this.$element.find("input"); 14686 "radio" == i.prop("type") ? (i.prop("checked") && (t = !1), e.find(".active").removeClass("active"), this.$element.addClass("active")) : "checkbox" == i.prop("type") && (i.prop("checked") !== this.$element.hasClass("active") && (t = !1), this.$element.toggleClass("active")), i.prop("checked", this.$element.hasClass("active")), t && i.trigger("change"); 14687 } else this.$element.attr("aria-pressed", !this.$element.hasClass("active")), this.$element.toggleClass("active"); 14688 }; 14689 var o = t.fn.button; 14690 t.fn.button = e, t.fn.button.Constructor = i, t.fn.button.noConflict = function () { 14691 return t.fn.button = o, this; 14692 }, t(document).on("click.bs.button.data-api", '[data-toggle^="button"]', function (i) { 14693 var o = t(i.target).closest(".btn"); 14694 e.call(o, "toggle"), t(i.target).is('input[type="radio"], input[type="checkbox"]') || (i.preventDefault(), o.is("input,button") ? o.trigger("focus") : o.find("input:visible,button:visible").first().trigger("focus")); 14695 }).on("focus.bs.button.data-api blur.bs.button.data-api", '[data-toggle^="button"]', function (e) { 14696 t(e.target).closest(".btn").toggleClass("focus", /^focus(in)?$/.test(e.type)); 14697 }); 14698}(jQuery), +function (t) { 14699 "use strict"; 14700 14701 function e(e) { 14702 return this.each(function () { 14703 var o = t(this), 14704 n = o.data("bs.carousel"), 14705 s = t.extend({}, i.DEFAULTS, o.data(), "object" == _typeof(e) && e), 14706 a = "string" == typeof e ? e : s.slide; 14707 n || o.data("bs.carousel", n = new i(this, s)), "number" == typeof e ? n.to(e) : a ? n[a]() : s.interval && n.pause().cycle(); 14708 }); 14709 } 14710 14711 var i = function i(e, _i) { 14712 this.$element = t(e), this.$indicators = this.$element.find(".carousel-indicators"), this.options = _i, this.paused = null, this.sliding = null, this.interval = null, this.$active = null, this.$items = null, this.options.keyboard && this.$element.on("key
14712down.bs.carousel", t.proxy(this.keydown, this)), "hover" == this.options.pause && !("ontouchstart" in document.documentElement) && this.$element.on("mouseenter.bs.carousel", t.proxy(this.pause, this)).on("mouseleave.bs.carousel", t.proxy(this.cycle, this)); 14713 }; 14714 14715 i.VERSION = "3.4.1", i.TRANSITION_DURATION = 600, i.DEFAULTS = { 14716 interval: 5e3, 14717 pause: "hover", 14718 wrap: !0, 14719 keyboard: !0 14720 }, i.prototype.keydown = function (t) { 14721 if (!/input|textarea/i.test(t.target.tagName)) { 14722 switch (t.which) { 14723 case 37: 14724 this.prev(); 14725 break; 14726 14727 case 39: 14728 this.next(); 14729 break; 14730 14731 default: 14732 return; 14733 } 14734 14735 t.preventDefault(); 14736 } 14737 }, i.prototype.cycle = function (e) { 14738 return e || (this.paused = !1), this.interval && clearInterval(this.interval), this.options.interval && !this.paused && (this.interval = setInterval(t.proxy(this.next, this), this.options.interval)), this; 14739 }, i.prototype.getItemIndex = function (t) { 14740 return this.$items = t.parent().children(".item"), this.$items.index(t || this.$active); 14741 }, i.prototype.getItemForDirection = function (t, e) { 14742 var i = this.getItemIndex(e), 14743 o = "prev" == t && 0 === i || "next" == t && i == this.$items.length - 1; 14744 if (o && !this.options.wrap) return e; 14745 var n = "prev" == t ? -1 : 1, 14746 s = (i + n) % this.$items.length; 14747 return this.$items.eq(s); 14748 }, i.prototype.to = function (t) { 14749 var e = this, 14750 i = this.getItemIndex(this.$active = this.$element.find(".item.active")); 14751 return t > this.$items.length - 1 || 0 > t ? void 0 : this.sliding ? this.$element.one("slid.bs.carousel", function () { 14752 e.to(t); 14753 }) : i == t ? this.pause().cycle() : this.slide(t > i ? "next" : "prev", this.$items.eq(t)); 14754 }, i.prototype.pause = function (e) { 14755 return e || (this.paused = !0), this.$element.find(".next, .prev").length && t.support.transition && (this.$element.trigger(t.support.transition.end), this.cycle(!0)), this.interval = clearInterval(this.interval), this; 14756 }, i.prototype.next = function () { 14757 return this.sliding ? void 0 : this.slide("next"); 14758 }, i.prototype.prev = function () { 14759 return this.sliding ? void 0 : this.slide("prev"); 14760 }, i.prototype.slide = function (e, o) { 14761 var n = this.$element.find(".item.active"), 14762 s = o || this.getItemForDirection(e, n), 14763 a = this.interval, 14764 r = "next" == e ? "left" : "right", 14765 l = this; 14766 if (s.hasClass("active")) return this.sliding = !1; 14767 var h = s[0], 14768 d = t.Event("slide.bs.carousel", { 14769 relatedTarget: h, 14770 direction: r 14771 }); 14772 14773 if (this.$element.trigger(d), !d.isDefaultPrevented()) { 14774 if (this.sliding = !0, a && this.pause(), this.$indicators.length) { 14775 this.$indicators.find(".active").removeClass("active"); 14776 var p = t(this.$indicators.children()[this.getItemIndex(s)]); 14777 p && p.addClass("active"); 14778 } 14779 14780 var c = t.Event("slid.bs.carousel", { 14781 relatedTarget: h, 14782 direction: r 14783 }); 14784 return t.support.transition && this.$element.hasClass("slide") ? (s.addClass(e), "object" == _typeof(s) && s.length && s[0].offsetWidth, n.addClass(r), s.addClass(r), n.one("bsTransitionEnd", function () { 14785 s.removeClass([e, r].join(" ")).addClass("active"), n.removeClass(["active", r].join(" ")), l.sliding = !1, setTimeout(function () { 14786 l.$element.trigger(c); 14787 }, 0); 14788 }).emulateTransitionEnd(i.TRANSITION_DURATION)) : (n.removeClass("active"), s.addClass("active"), this.sliding = !1, this.$element.trigger(c)), a && this.cycle(), this; 14789 } 14790 }; 14791 var o = t.fn.carousel; 14792 t.fn.carousel = e, t.fn.carousel.Constructor = i, t.fn.carousel.noConflict = function () { 14793 return t.fn.carousel = o, this; 14794 }; 14795 14796 var n = function n(i) { 14797 var o = t(this), 14798 n = o.attr("href"); 14799 n && (n = n.replace(/.*(?=#[^\s]+$)/, "")); 14800 var s = o.attr("data-target") || n, 14801 a = t(document).find(s); 14802 14803 if (a.hasClass("carousel")) { 14804 var r = t.extend({}, a.data(), o.data()), 14805 l = o.attr("data-slide-to"); 14806 l && (r.interval = !1), e.call(a, r), l && a.data("bs.carousel").to(l), i.preventDefault(); 14807 } 14808 }; 14809
14810 t(document).on("click.bs.carousel.data-api", "[data-slide]", n).on("click.bs.carousel.data-api", "[data-slide-to]", n), t(window).on("load", function () { 14811 t('[data-ride="carousel"]').each(function () { 14812 var i = t(this); 14813 e.call(i, i.data()); 14814 }); 14815 }); 14816}(jQuery), +function (t) { 14817 "use strict"; 14818 14819 function e(e) { 14820 var i = e.attr("data-target"); 14821 i || (i = e.attr("href"), i = i && /#[A-Za-z]/.test(i) && i.replace(/.*(?=#[^\s]*$)/, "")); 14822 var o = "#" !== i ? t(document).find(i) : null; 14823 return o && o.length ? o : e.parent(); 14824 } 14825 14826 function i(i) { 14827 i && 3 === i.which || (t(n).remove(), t(s).each(function () { 14828 var o = t(this), 14829 n = e(o), 14830 s = { 14831 relatedTarget: this 14832 }; 14833 n.hasClass("open") && (i && "click" == i.type && /input|textarea/i.test(i.target.tagName) && t.contains(n[0], i.target) || (n.trigger(i = t.Event("hide.bs.dropdown", s)), i.isDefaultPrevented() || (o.attr("aria-expanded", "false"), n.removeClass("open").trigger(t.Event("hidden.bs.dropdown", s))))); 14834 })); 14835 } 14836 14837 function o(e) { 14838 return this.each(function () { 14839 var i = t(this), 14840 o = i.data("bs.dropdown"); 14841 o || i.data("bs.dropdown", o = new a(this)), "string" == typeof e && o[e].call(i); 14842 }); 14843 } 14844 14845 var n = ".dropdown-backdrop", 14846 s = '[data-toggle="dropdown"]', 14847 a = function a(e) { 14848 t(e).on("click.bs.dropdown", this.toggle); 14849 }; 14850 14851 a.VERSION = "3.4.1", a.prototype.toggle = function (o) { 14852 var n = t(this); 14853 14854 if (!n.is(".disabled, :disabled")) { 14855 var s = e(n), 14856 a = s.hasClass("open"); 14857 14858 if (i(), !a) { 14859 "ontouchstart" in document.documentElement && !s.closest(".navbar-nav").length && t(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(t(this)).on("click", i); 14860 var r = { 14861 relatedTarget: this 14862 }; 14863 if (s.trigger(o = t.Event("show.bs.dropdown", r)), o.isDefaultPrevented()) return; 14864 n.trigger("focus").attr("aria-expanded", "true"), s.toggleClass("open").trigger(t.Event("shown.bs.dropdown", r)); 14865 } 14866 14867 return !1; 14868 } 14869 }, a.prototype.keydown = function (i) { 14870 if (/(38|40|27|32)/.test(i.which) && !/input|textarea/i.test(i.target.tagName)) { 14871 var o = t(this); 14872 14873 if (i.preventDefault(), i.stopPropagation(), !o.is(".disabled, :disabled")) { 14874 var n = e(o), 14875 a = n.hasClass("open"); 14876 if (!a && 27 != i.which || a && 27 == i.which) return 27 == i.which && n.find(s).trigger("focus"), o.trigger("click"); 14877 var r = " li:not(.disabled):visible a", 14878 l = n.find(".dropdown-menu" + r); 14879 14880 if (l.length) { 14881 var h = l.index(i.target); 14882 38 == i.which && h > 0 && h--, 40 == i.which && h < l.length - 1 && h++, ~h || (h = 0), l.eq(h).trigger("focus"); 14883 } 14884 } 14885 } 14886 }; 14887 var r = t.fn.dropdown; 14888 t.fn.dropdown = o, t.fn.dropdown.Constructor = a, t.fn.dropdown.noConflict = function () { 14889 return t.fn.dropdown = r, this; 14890 }, t(document).on("click.bs.dropdown.data-api", i).on("click.bs.dropdown.data-api", ".dropdown form", function (t) { 14891 t.stopPropagation(); 14892 }).on("click.bs.dropdown.data-api", s, a.prototype.toggle).on("keydown.bs.dropdown.data-api", s, a.prototype.keydown).on("keydown.bs.dropdown.data-api", ".dropdown-menu", a.prototype.keydown); 14893}(jQuery), +function (t) { 14894 "use strict"; 14895 14896 function e(e, o) { 14897 return this.each(function () { 14898 var n = t(this), 14899 s = n.data("bs.modal"), 14900 a = t.extend({}, i.DEFAULTS, n.data(), "object" == _typeof(e) && e); 14901 s || n.data("bs.modal", s = new i(this, a)), "string" == typeof e ? s[e](o) : a.show && s.show(o); 14902 }); 14903 } 14904 14905 var i = function i(e, _i2) { 14906 this.options = _i2, this.$body = t(document.body), this.$element = t(e), this.$dialog = this.$element.find(".modal-dialog"), this.$backdrop = null, this.isShown = null, this.originalBodyPad = null, this.scrollbarWidth = 0, this.ignoreBackdropClick = !1, this.fixedContent = ".navbar-fixed-top, .navbar-fixed-bottom", this.options.remote && this.$element.find(".modal-content").load(this.options.remote, t.proxy(function () { 14907 this.$element.trigger("loaded.bs.modal"); 14908 }, this)); 14909 }; 14910 14911 i.VERSION = "3.4.1", i.TRANSITION_DURATION = 300, i.BACKDROP_TRANSITION_DURATION = 150, i.DEFAULTS = { 14912 backdrop: !0, 14913 keyboard: !0, 14914 show: !0 14915 }, i.prototype.toggle = function (t) { 14916 return this.isShown ? this.hide() : this.show(t); 14917 }, i.prototype.show = function (e) { 14918 var o = this, 14919 n = t.Event("show.bs.modal", { 14920 relatedTarget: e 14921 }); 14922 this.$element.trigger(n), this.isShown || n.isDefaultPrevented() || (this.isShown = !0, this.checkScrollbar(), this.setScrollbar(), this.$body.addClass("modal-open"), this.escape(), this.resize(), this.$element.on("click.dismiss.bs.modal", '[data-dismiss="modal"]', t.proxy(this.hide, this)), this.$dialog.on("mousedown.dismiss.bs.modal", function () { 14923 o.$element.one("mouseup.dismiss.bs.modal", function (e) {
14924 t(e.target).is(o.$element) && (o.ignoreBackdropClick = !0); 14925 }); 14926 }), this.backdrop(function () { 14927 var n = t.support.transition && o.$element.hasClass("fade"); 14928 o.$element.parent().length || o.$element.appendTo(o.$body), o.$element.show().scrollTop(0), o.adjustDialog(), n && o.$element[0].offsetWidth, o.$element.addClass("in"), o.enforceFocus(); 14929 var s = t.Event("shown.bs.modal", { 14930 relatedTarget: e 14931 }); 14932 n ? o.$dialog.one("bsTransitionEnd", function () { 14933 o.$element.trigger("focus").trigger(s); 14934 }).emulateTransitionEnd(i.TRANSITION_DURATION) : o.$element.trigger("focus").trigger(s); 14935 })); 14936 }, i.prototype.hide = function (e) { 14937 e && e.preventDefault(), e = t.Event("hide.bs.modal"), this.$element.trigger(e), this.isShown && !e.isDefaultPrevented() && (this.isShown = !1, this.escape(), this.resize(), t(document).off("focusin.bs.modal"), this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"), this.$dialog.off("mousedown.dismiss.bs.modal"), t.support.transition && this.$element.hasClass("fade") ? this.$element.one("bsTransitionEnd", t.proxy(this.hideModal, this)).emulateTransitionEnd(i.TRANSITION_DURATION) : this.hideModal()); 14938 }, i.prototype.enforceFocus = function () { 14939 t(document).off("focusin.bs.modal").on("focusin.bs.modal", t.proxy(function (t) { 14940 document === t.target || this.$element[0] === t.target || this.$element.has(t.target).length || this.$element.trigger("focus"); 14941 }, this)); 14942 }, i.prototype.escape = function () { 14943 this.isShown && this.options.keyboard ? this.$element.on("keydown.dismiss.bs.modal", t.proxy(function (t) { 14944 27 == t.which && this.hide(); 14945 }, this)) : this.isShown || this.$element.off("keydown.dismiss.bs.modal"); 14946 }, i.prototype.resize = function () { 14947 this.isShown ? t(window).on("resize.bs.modal", t.proxy(this.handleUpdate, this)) : t(window).off("resize.bs.modal"); 14948 }, i.prototype.hideModal = function () { 14949 var t = this; 14950 this.$element.hide(), this.backdrop(function () { 14951 t.$body.removeClass("modal-open"), t.resetAdjustments(), t.resetScrollbar(), t.$element.trigger("hidden.bs.modal"); 14952 }); 14953 }, i.prototype.removeBackdrop = function () { 14954 this.$backdrop && this.$backdrop.remove(), this.$backdrop = null; 14955 }, i.prototype.backdrop = function (e) { 14956 var o = this, 14957 n = this.$element.hasClass("fade") ? "fade" : ""; 14958 14959 if (this.isShown && this.options.backdrop) { 14960 var s = t.support.transition && n; 14961 if (this.$backdrop = t(document.createElement("div")).addClass("modal-backdrop " + n).appendTo(this.$body), this.$element.on("click.dismiss.bs.modal", t.proxy(function (t) { 14962 return this.ignoreBackdropClick ? void (this.ignoreBackdropClick = !1) : void (t.target === t.currentTarget && ("static" == this.options.backdrop ? this.$element[0].focus() : this.hide())); 14963 }, this)), s && this.$backdrop[0].offsetWidth, this.$backdrop.addClass("in"), !e) return; 14964 s ? this.$backdrop.one("bsTransitionEnd", e).emulateTransitionEnd(i.BACKDROP_TRANSITION_DURATION) : e(); 14965 } else if (!this.isShown && this.$backdrop) { 14966 this.$backdrop.removeClass("in"); 14967 14968 var a = function a() { 14969 o.removeBackdrop(), e && e(); 14970 }; 14971 14972 t.support.transition && this.$element.hasClass("fade") ? this.$backdrop.one("bsTransitionEnd", a).emulateTransitionEnd(i.BACKDROP_TRANSITION_DURATION) : a(); 14973 } else e && e(); 14974 }, i.prototype.handleUpdate = function () { 14975 this.adjustDialog(); 14976 }, i.prototype.adjustDialog = function () { 14977 var t = this.$element[0].scrollHeight > document.documentElement.clientHeight; 14978 this.$element.css({ 14979 paddingLeft: !this.bodyIsOverflowing && t ? this.scrollbarWidth : "", 14980 paddingRight: this.bodyIsOverflowing && !t ? this.scrollbarWidth : "" 14981 }); 14982 }, i.prototype.resetAdjustments = function () { 14983 this.$element.css({ 14984 paddingLeft: "", 14985 paddingRight: "" 14986 }); 14987 }, i.prototype.checkScrollbar = function () { 14988 var t = window.innerWidth; 14989 14990 if (!t) { 14991 var e = document.documentElement.getBoundingClientRect(); 14992 t = e.right - Math.abs(e.left); 14993 } 14994 14995 this.bodyIsOverflowing = document.body.clientWidth < t, this.scrollbarWidth = this.measureScrollbar(); 14996 }, i.prototype.setScrollbar = function () { 14997 var e = parseInt(this.$body.css("padding-right") || 0, 10); 14998 this.originalBodyPad = document.body.style.paddingRight || ""; 14999 var i = this.scrollbarWidth; 15000 this.bodyIsOverflowing && (this.$body.css("padding-right", e + i), t(this.fixedContent).each(function (e, o) { 15001 var n = o.style.paddingRight, 15002 s = t(o).css("padding-right"); 15003 t(o).data("padding-right", n).css("padding-right", parseFloat(s) + i + "px"); 15004 })); 15005 }, i.prototype.resetScrollbar = function () { 15006 this.$body.css("padding-right", this.originalBodyPad), t(this.fixedContent).each(function (e, i) { 15007 var o = t(i).data("padding-right"); 15008 t(i).removeData("padding-right"), i.style.paddingRight = o ? o : ""; 15009 }); 15010 }, i.prototype.measureScrollbar = function () { 15011 var t = document.createElement("div");
15012 t.className = "modal-scrollbar-measure", this.$body.append(t); 15013 var e = t.offsetWidth - t.clientWidth; 15014 return this.$body[0].removeChild(t), e; 15015 }; 15016 var o = t.fn.modal; 15017 t.fn.modal = e, t.fn.modal.Constructor = i, t.fn.modal.noConflict = function () { 15018 return t.fn.modal = o, this; 15019 }, t(document).on("click.bs.modal.data-api", '[data-toggle="modal"]', function (i) { 15020 var o = t(this), 15021 n = o.attr("href"), 15022 s = o.attr("data-target") || n && n.replace(/.*(?=#[^\s]+$)/, ""), 15023 a = t(document).find(s), 15024 r = a.data("bs.modal") ? "toggle" : t.extend({ 15025 remote: !/#/.test(n) && n 15026 }, a.data(), o.data()); 15027 o.is("a") && i.preventDefault(), a.one("show.bs.modal", function (t) { 15028 t.isDefaultPrevented() || a.one("hidden.bs.modal", function () { 15029 o.is(":visible") && o.trigger("focus"); 15030 }); 15031 }), e.call(a, r, this); 15032 }); 15033 }(jQuery), +function (t) { 15034 "use strict"; 15035 15036 function e(e, i) { 15037 var o = e.nodeName.toLowerCase(); 15038 if (-1 !== t.inArray(o, i)) return -1 !== t.inArray(o, s) ? Boolean(e.nodeValue.match(l) || e.nodeValue.match(h)) : !0; 15039 15040 for (var n = t(i).filter(function (t, e) { 15041 return e instanceof RegExp; 15042 }), a = 0, r = n.length; r > a; a++) { 15043 if (o.match(n[a])) return !0; 15044 } 15045 15046 return !1; 15047 } 15048 15049 function i(i, o, n) { 15050 if (0 === i.length) return i; 15051 if (n && "function" == typeof n) return n(i); 15052 if (!document.implementation || !document.implementation.createHTMLDocument) return i; 15053 var s = document.implementation.createHTMLDocument("sanitization"); 15054 s.body.innerHTML = i; 15055 15056 for (var a = t.map(o, function (t, e) { 15057 return e; 15058 }), r = t(s.body).find("*"), l = 0, h = r.length; h > l; l++) { 15059 var d = r[l], 15060 p = d.nodeName.toLowerCase(); 15061 if (-1 !== t.inArray(p, a)) for (var c = t.map(d.attributes, function (t) { 15062 return t; 15063 }), f = [].concat(o["*"] || [], o[p] || []), u = 0, g = c.length; g > u; u++) { 15064 e(c[u], f) || d.removeAttribute(c[u].nodeName); 15065 } else d.parentNode.removeChild(d); 15066 } 15067 15068 return s.body.innerHTML; 15069 } 15070 15071 function o(e) { 15072 return this.each(function () { 15073 var i = t(this), 15074 o = i.data("bs.tooltip"), 15075 n = "object" == _typeof(e) && e; 15076 !o && /destroy|hide/.test(e) || (o || i.data("bs.tooltip", o = new d(this, n)), "string" == typeof e && o[e]()); 15077 }); 15078 } 15079 15080 var n = ["sanitize", "whiteList", "sanitizeFn"], 15081 s = ["background", "cite", "href", "itemtype", "longdesc", "poster", "src", "xlink:href"], 15082 a = /^aria-[\w-]*$/i, 15083 r = { 15084 "*": ["class", "dir", "id", "lang", "role", a], 15085 a: ["target", "href", "title", "rel"], 15086 area: [], 15087 b: [], 15088 br: [], 15089 col: [], 15090 code: [], 15091 div: [], 15092 em: [], 15093 hr: [], 15094 h1: [], 15095 h2: [], 15096 h3: [], 15097 h4: [], 15098 h5: [], 15099 h6: [], 15100 i: [], 15101 img: ["src", "alt", "title", "width", "height"], 15102 li: [], 15103 ol: [], 15104 p: [], 15105 pre: [], 15106 s: [], 15107 small: [], 15108 span: [], 15109 sub: [], 15110 sup: [], 15111 strong: [], 15112 u: [], 15113 ul: [] 15114 }, 15115 l = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi, 15116 h = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i, 15117 d = function d(t, e) { 15118 this.type = null, this.options = null, this.enabled = null, this.timeout = null, this.hoverState = null, this.$element = null, this.inState = null, this.init("tooltip", t, e); 15119 }; 15120 15121 d.VERSION = "3.4.1", d.TRANSITION_DURATION = 150, d.DEFAULTS = { 15122 animation: !0, 15123 placement: "top", 15124 selector: !1, 15125 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 15126 trigger: "hover focus", 15127 title: "", 15128 delay: 0, 15129 html: !1, 15130 container: !1, 15131 viewport: { 15132 selector: "body", 15133 padding: 0 15134 }, 15135 sanitize: !0, 15136 sanitizeFn: null, 15137 whiteList: r 15138 }, d.prototype.init = function (e, i, o) { 15139 if (this.enabled = !0, this.type = e, this.$element = t(i), this.options = this.getOptions(o), this.$viewport = this.options.viewport && t(document).find(t.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : this.options.viewport.selector || this.options.viewport), this.inState = { 15140 click: !1, 15141 hover: !1, 15142 focus: !1 15143 }, this.$element[0] instanceof document.constructor && !this.options.selector) throw new Error("`selector` option must be specified when initializing " + this.type + " on the window.document object!"); 15144 15145 for (var n = this.options.trigger.split(" "), s = n.length; s--;) { 15146 var a = n[s]; 15147 if ("click" == a) this.$element.on("click." + this.type, this.options.selector, t.proxy(this.toggle, this));else if ("manual" != a) { 15148 var r = "hover" == a ? "mouseenter" : "focusin", 15149 l = "hover" == a ? "mouseleave" : "focusout"; 15150 this.$element.on(r + "." + this.type, this.options.selector, t.proxy(this.enter, this)), this.$element.on(l + "." + this.type, this.options.selector, t.proxy(this.leave, this)); 15151 } 15152 } 15153 15154 this.options.selector ? this._options = t.extend({}, this.options, { 15155 trigger: "manual", 15156 selector: "" 15157 }) : this.fixTitle(); 15158 }, d.prototype.getDefaults = function () { 15159 return d.DEFAULTS; 15160 }, d.prototype.getOptions = function (e) { 15161 var o = this.$element.data(); 15162 15163 for (var s in o) { 15164 o.hasOwnProperty(s) && -1 !== t.inArray(s, n) && delete o[s]; 15165 } 15166 15167 return e = t.extend({}, this.getDefaults(), o, e), e.delay && "number" == typeof e.delay && (e.delay = { 15168 show: e.delay, 15169 hide: e.delay 15170 }), e.sanitize && (e.template = i(e.template, e.whiteList, e.sanitizeFn)), e; 15171 }, d.prototype.getDelegateOptions = function () { 15172 var e = {}, 15173 i = this.getDefaults(); 15174 return this._options && t.each(this._options, function (t, o) { 15175 i[t] != o && (e[t] = o); 15176 }), e; 15177 }, d.prototype.enter = function (e) { 15178 var i = e instanceof this.constructor ? e : t(e.currentTarget).data("bs." + this.type); 15179 return i || (i = new this.constructor(e.currentTarget, this.getDelegateOptions()), t(e.currentTarget).data("bs." + this.type, i)), e instanceof t.Event && (i.inState["focusin" == e.type ? "focus" : "hover"] = !0), i.tip().hasClass("in") || "in" == i.hoverState ? void (i.hoverState = "in") : (clearTimeout(i.timeout), i.hoverState = "in", i.options.delay && i.options.delay.show ? void (i.timeout = setTimeout(function () { 15180 "in" == i.hoverState && i.show(); 15181 }, i.options.delay.show)) : i.show()); 15182 }, d.prototype.isInStateTrue = function () { 15183 for (var t in this.inState) { 15184 if (this.inState[t]) return !0; 15185 } 15186 15187 return !1; 15188 }, d.prototype.leave = function (e) { 15189 var i = e instanceof this.constructor ? e : t(e.currentTarget).data("bs." + this.type); 15190 return i || (i = new this.constructor(e.currentTarget, this.getDelegateOptions()), t(e.currentTarget).data("bs." + this.type, i)), e instanceof t.Event && (i.inState["focusout" == e.type ? "focus" : "hover"] = !1), i.isInStateTrue() ? void 0 : (clearTimeout(i.timeout), i.hoverState = "out", i.options.delay && i.options.delay.hide ? void (i.timeout = setTimeout(function () { 15191 "out" == i.hoverState && i.hide(); 15192 }, i.options.delay.hide)) : i.hide()); 15193 }, d.prototype.show = function () { 15194 var e = t.Event("show.bs." + this.type); 15195 15196 if (this.hasContent() && this.enabled) { 15197 this.$element.trigger(e); 15198 var i = t.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]); 15199 if (e.isDefaultPrevented() || !i) return; 15200 var o = this, 15201 n = this.tip(), 15202 s = this.getUID(this.type); 15203 this.setContent(), n.attr("id", s), this.$element.attr("aria-describedby", s), this.options.animation && n.addClass("fade"); 15204 var a = "function" == typeof this.options.placement ? this.options.placement.call(this, n[0], this.$element[0]) : this.options.placement, 15205 r = /\s?auto?\s?/i, 15206 l = r.test(a); 15207 l && (a = a.replace(r, "") || "top"), n.detach().css({ 15208 top: 0, 15209 left: 0, 15210 display: "block" 15211 }).addClass(a).data("bs." + this.type, this), this.options.container ? n.appendTo(t(document).find(this.options.container)) : n.insertAfter(this.$element), this.$element.trigger("inserted.bs." + this.type); 15212 var h = this.getPosition(), 15213 p = n[0].offsetWidth, 15214 c = n[0].offsetHeight; 15215 15216 if (l) { 15217 var f = a, 15218 u = this.getPosition(this.$viewport); 15219 a = "bottom" == a && h.bottom + c > u.bottom ? "top" : "top" == a && h.top - c < u.top ? "bottom" : "right" == a && h.right + p > u.width ? "left" : "left" == a && h.left - p < u.left ? "right" : a, n.removeClass(f).addClass(a); 15220 } 15221 15222 var g = this.getCalculatedOffset(a, h, p, c); 15223 this.applyPlacement(g, a); 15224 15225 var m = function m() { 15226 var t = o.hoverState; 15227 o.$element.trigger("shown.bs." + o.type), o.hoverState = null, "out" == t && o.leave(o); 15228 }; 15229 15230 t.support.transition && this.$tip.hasClass("fade") ? n.one("bsTransitionEnd", m).emulateTransitionEnd(d.TRANSITION_DURATION) : m(); 15231 } 15232 }, d.prototype.applyPlacement = function (e, i) { 15233 var o = this.tip(), 15234 n = o[0].offsetWidth, 15235 s = o[0].offsetHeight, 15236 a = parseInt(o.css("margin-top"), 10), 15237 r = parseInt(o.css("margin-left"), 10); 15238 isNaN(a) && (a = 0), isNaN(r) && (r = 0), e.top += a, e.left += r, t.offset.setOffset(o[0], t.extend({ 15239 using: function using(t) { 15240 o.css({ 15241 top: Math.round(t.top), 15242 left: Math.round(t.left) 15243 }); 15244 } 15245 }, e), 0), o.addClass("in"); 15246 var l = o[0].offsetWidth, 15247 h = o[0].offsetHeight; 15248 "top" == i && h != s && (e.top = e.top + s - h); 15249 var d = this.getViewportAdjustedDelta(i, e, l, h); 15250 d.left ? e.left += d.left : e.top += d.top; 15251 var p = /top|bottom/.test(i), 15252 c = p ? 2 * d.left - n + l : 2 * d.top - s + h, 15253 f = p ? "offsetWidth" : "offsetHeight"; 15254 o.offset(e), this.replaceArrow(c, o[0][f], p); 15255 }, d.prototype.replaceArrow = function (t, e, i) { 15256 this.arrow().css(i ? "left" : "top", 50 * (1 - t / e) + "%").css(i ? "top" : "left", ""); 15257 }, d.prototype.setContent = function () { 15258 var t = this.tip(), 15259 e = this.getTitle(); 15260 this.options.html ? (this.options.sanitize && (e = i(e, this.options.whiteList, this.options.sanitizeFn)), t.find(".tooltip-inner").html(e)) : t.find(".tooltip-inner").text(e), t.removeClass("fade in top bottom left right"); 15261 }, d.prototype.hide = function (e) { 15262 function i() { 15263 "in" != o.hoverState && n.detach(), o.$element && o.$element.removeAttr("aria-describedby").trigger("hidden.bs." + o.type), e && e(); 15264 } 15265 15266 var o = this, 15267 n = t(this.$tip), 15268 s = t.Event("hide.bs." + this.type); 15269 return this.$element.trigger(s), s.isDefaultPrevented() ? void 0 : (n.removeClass("in"), t.support.transition && n.hasClass("fade") ? n.one("bsTransitionEnd", i).emulateTransitionEnd(d.TRANSITION_DURATION) : i(), this.hoverState = null, this); 15270 }, d.prototype.fixTitle = function () { 15271 var t = this.$element; 15272 (t.attr("title") || "string" != typeof t.attr("data-original-title")) && t.attr("data-original-title", t.attr("title") || "").attr("title", ""); 15273 }, d.prototype.hasContent = function () { 15274 return this.getTitle(); 15275 }, d.prototype.getPosition = function (e) { 15276 e = e || this.$element; 15277 var i = e[0], 15278 o = "BODY" == i.tagName, 15279 n = i.getBoundingClientRect(); 15280 null == n.width && (n = t.extend({}, n, { 15281 width: n.right - n.left, 15282 height: n.bottom - n.top 15283 })); 15284 var s = window.SVGElement && i instanceof window.SVGElement, 15285 a = o ? { 15286 top: 0, 15287 left: 0 15288 } : s ? null : e.offset(), 15289 r = { 15290 scroll: o ? document.documentElement.scrollTop || document.body.scrollTop : e.scrollTop() 15291 }, 15292 l = o ? {
15293 width: t(window).width(), 15294 height: t(window).height() 15295 } : null; 15296 return t.extend({}, n, r, l, a); 15297 }, d.prototype.getCalculatedOffset = function (t, e, i, o) { 15298 return "bottom" == t ? { 15299 top: e.top + e.height, 15300 left: e.left + e.width / 2 - i / 2 15301 } : "top" == t ? { 15302 top: e.top - o, 15303 left: e.left + e.width / 2 - i / 2 15304 } : "left" == t ? { 15305 top: e.top + e.height / 2 - o / 2, 15306 left: e.left - i 15307 } : { 15308 top: e.top + e.height / 2 - o / 2, 15309 left: e.left + e.width 15310 }; 15311 }, d.prototype.getViewportAdjustedDelta = function (t, e, i, o) { 15312 var n = { 15313 top: 0, 15314 left: 0 15315 }; 15316 if (!this.$viewport) return n; 15317 var s = this.options.viewport && this.options.viewport.padding || 0, 15318 a = this.getPosition(this.$viewport); 15319 15320 if (/right|left/.test(t)) { 15321 var r = e.top - s - a.scroll, 15322 l = e.top + s - a.scroll + o; 15323 r < a.top ? n.top = a.top - r : l > a.top + a.height && (n.top = a.top + a.height - l); 15324 } else { 15325 var h = e.left - s, 15326 d = e.left + s + i; 15327 h < a.left ? n.left = a.left - h : d > a.right && (n.left = a.left + a.width - d); 15328 } 15329 15330 return n; 15331 }, d.prototype.getTitle = function () { 15332 var t, 15333 e = this.$element, 15334 i = this.options; 15335 return t = e.attr("data-original-title") || ("function" == typeof i.title ? i.title.call(e[0]) : i.title); 15336 }, d.prototype.getUID = function (t) { 15337 do { 15338 t += ~~(1e6 * Math.random()); 15339 } while (document.getElementById(t)); 15340 15341 return t; 15342 }, d.prototype.tip = function () { 15343 if (!this.$tip && (this.$tip = t(this.options.template), 1 != this.$tip.length)) throw new Error(this.type + " `template` option must consist of exactly 1 top-level element!"); 15344 return this.$tip; 15345 }, d.prototype.arrow = function () { 15346 return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow"); 15347 }, d.prototype.enable = function () { 15348 this.enabled = !0; 15349 }, d.prototype.disable = function () { 15350 this.enabled = !1; 15351 }, d.prototype.toggleEnabled = function () { 15352 this.enabled = !this.enabled; 15353 }, d.prototype.toggle = function (e) { 15354 var i = this; 15355 e && (i = t(e.currentTarget).data("bs." + this.type), i || (i = new this.constructor(e.currentTarget, this.getDelegateOptions()), t(e.currentTarget).data("bs." + this.type, i))), e ? (i.inState.click = !i.inState.click, i.isInStateTrue() ? i.enter(i) : i.leave(i)) : i.tip().hasClass("in") ? i.leave(i) : i.enter(i); 15356 }, d.prototype.destroy = function () { 15357 var t = this; 15358 clearTimeout(this.timeout), this.hide(function () { 15359 t.$element.off("." + t.type).removeData("bs." + t.type), t.$tip && t.$tip.detach(), t.$tip = null, t.$arrow = null, t.$viewport = null, t.$element = null; 15360 }); 15361 }, d.prototype.sanitizeHtml = function (t) { 15362 return i(t, this.options.whiteList, this.options.sanitizeFn); 15363 }; 15364 var p = t.fn.tooltip; 15365 t.fn.tooltip = o, t.fn.tooltip.Constructor = d, t.fn.tooltip.noConflict = function () { 15366 return t.fn.tooltip = p, this; 15367 }; 15368 }(jQuery), +function (t) { 15369 "use strict"; 15370 15371 function e(e) { 15372 return this.each(function () { 15373 var o = t(this), 15374 n = o.data("bs.popover"), 15375 s = "object" == _typeof(e) && e; 15376 !n && /destroy|hide/.test(e) || (n || o.data("bs.popover", n = new i(this, s)), "string" == typeof e && n[e]()); 15377 }); 15378 } 15379 15380 var i = function i(t, e) { 15381 this.init("popover", t, e); 15382 }; 15383 15384 if (!t.fn.tooltip) throw new Error("Popover requires tooltip.js"); 15385 i.VERSION = "3.4.1", i.DEFAULTS = t.extend({}, t.fn.tooltip.Constructor.DEFAULTS, { 15386 placement: "right", 15387 trigger: "click", 15388 content: "", 15389 template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>' 15390 }), i.prototype = t.extend({}, t.fn.tooltip.Constructor.prototype), i.prototype.constructor = i, i.prototype.getDefaults = function () { 15391 return i.DEFAULTS; 15392 }, i.prototype.setContent = function () { 15393 var t = this.tip(), 15394 e = this.getTitle(), 15395 i = this.getContent(); 15396 15397 if (this.options.html) { 15398 var o = _typeof(i); 15399 15400 this.options.sanitize && (e = this.sanitizeHtml(e), "string" === o && (i = this.sanitizeHtml(i))), t.find(".popover-title").html(e), t.find(".popover-content").children().detach().end()["string" === o ? "html" : "append"](i); 15401 } else t.find(".popover-title").text(e), t.find(".popover-content").children().detach().end().text(i); 15402 15403 t.removeClass("fade top bottom left right in"), t.find(".popover-title").html() || t.find(".popover-title").hide(); 15404 }, i.prototype.hasContent = function () { 15405 return this.getTitle() || this.getContent(); 15406 }, i.prototype.getContent = function () { 15407 var t = this.$element, 15408 e = this.options; 15409 return t.attr("data-content") || ("function" == typeof e.content ? e.content.call(t[0]) : e.content); 15410 }, i.prototype.arrow = function () { 15411 return this.$arrow = this.$arrow || this.tip().find(".arrow"); 15412 }; 15413 var o = t.fn.popover; 15414 t.fn.popover = e, t.fn.popover.Constructor = i, t.fn.popover.noConflict = function () { 15415 return t.fn.popover = o, this; 15416 }; 15417 }(jQuery), +function (t) { 15418 "use strict"; 15419 15420 function e(e) { 15421 return this.each(function () { 15422 var o = t(this), 15423 n = o.data("bs.tab"); 15424 n || o.data("bs.tab", n = new i(this)), "string" == typeof e && n[e](); 15425 }); 15426 } 15427 15428 var i = function i(e) { 15429 this.element = t(e); 15430 }; 15431 15432 i.VERSION = "3.4.1", i.TRANSITION_DURATION = 150, i.prototype.show = function () { 15433 var e = this.element, 15434 i = e.closest("ul:not(.dropdown-menu)"), 15435 o = e.data("target"); 15436 15437 if (o || (o = e.attr("href"), o = o && o.replace(/.*(?=#[^\s]*$)/, "")), !e.parent("li").hasClass("active")) { 15438 var n = i.find(".active:last a"), 15439 s = t.Event("hide.bs.tab", { 15440 relatedTarget: e[0] 15441 }), 15442 a = t.Event("show.bs.tab", { 15443 relatedTarget: n[0] 15444 }); 15445 15446 if (n.trigger(s), e.trigger(a), !a.isDefaultPrevented() && !s.isDefaultPrevented()) { 15447 var r = t(document).find(o); 15448 this.activate(e.closest("li"), i), this.activate(r, r.parent(), function () { 15449 n.trigger({ 15450 type: "hidden.bs.tab", 15451 relatedTarget: e[0] 15452 }), e.trigger({ 15453 type: "shown.bs.tab", 15454 relatedTarget: n[0] 15455 }); 15456 }); 15457 } 15458 } 15459 }, i.prototype.activate = function (e, o, n) { 15460 function s() { 15461 a.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded", !1), e.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded", !0), r ? (e[0].offsetWidth, e.addClass("in")) : e.removeClass("fade"), e.parent(".dropdown-menu").length && e.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded", !0), n && n(); 15462 } 15463 15464 var a = o.find("> .active"), 15465 r = n && t.support.transition && (a.length && a.hasClass("fade") || !!o.find("> .fade").length); 15466 a.length && r ? a.one("bsTransitionEnd", s).emulateTransitionEnd(i.TRANSITION_DURATION) : s(), a.removeClass("in"); 15467 }; 15468 var o = t.fn.tab; 15469 t.fn.tab = e, t.fn.tab.Constructor = i, t.fn.tab.noConflict = function () { 15470 return t.fn.tab = o, this; 15471 }; 15472 15473 var n = function n(i) { 15474 i.preventDefault(), e.call(t(this), "show"); 15475 }; 15476 15477 t(document).on("click.bs.tab.data-api", '[data-toggle="tab"]', n).on("click.bs.tab.data-api", '[data-toggle="pill"]', n); 15478 }(jQuery), +function (t) { 15479 "use strict"; 15480 15481 function e(e) { 15482 return this.each(function () { 15483 var o = t(this), 15484 n = o.data("bs.affix"), 15485 s = "object" == _typeof(e) && e; 15486 n || o.data("bs.affix", n = new i(this, s)), "string" == typeof e && n[e](); 15487 }); 15488 } 15489 15490 var i = function i(e, o) { 15491 this.options = t.extend({}, i.DEFAULTS, o); 15492 var n = this.options.target === i.DEFAULTS.target ? t(this.options.target) : t(document).find(this.options.target); 15493 this.$target = n.on("scroll.bs.affix.data-api", t.proxy(this.checkPosition, this)).on("click.bs.affix.data-api", t.proxy(this.checkPositionWithEventLoop, this)), this.$element = t(e), this.affixed = null, this.unpin = null, this.pinnedOffset = null, this.checkPosition(); 15494 }; 15495 15496 i.VERSION = "3.4.1", i.RESET = "affix affix-top affix-bottom", i.DEFAULTS = { 15497 offset: 0, 15498 target: window 15499 }, i.prototype.getState = function (t, e, i, o) { 15500 var n = this.$target.scrollTop(), 15501 s = this.$element.offset(), 15502 a = this.$target.height(); 15503 if (null != i && "top" == this.affixed) return i > n ? "top" : !1; 15504 if ("bottom" == this.affixed) return null != i ? n + this.unpin <= s.top ? !1 : "bottom" : t - o >= n + a ? !1 : "bottom"; 15505 var r = null == this.affixed, 15506 l = r ? n : s.top, 15507 h = r ? a : e; 15508 return null != i && i >= n ? "top" : null != o && l + h >= t - o ? "bottom" : !1; 15509 }, i.prototype.getPinnedOffset = function () { 15510 if (this.pinnedOffset) return this.pinnedOffset; 15511 this.$element.removeClass(i.RESET).addClass("affix"); 15512 var t = this.$target.scrollTop(), 15513 e = this.$element.offset(); 15514 return this.pinnedOffset = e.top - t; 15515 }, i.prototype.checkPositionWithEventLoop = function () { 15516 setTimeout(t.proxy(this.checkPosition, this), 1); 15517 }, i.prototype.checkPosition = function () { 15518 if (this.$element.is(":visible")) { 15519 var e = this.$element.height(), 15520 o = this.options.offset, 15521 n = o.top, 15522 s = o.bottom, 15523 a = Math.max(t(document).height(), t(document.body).height()); 15524 "object" != _typeof(o) && (s = n = o), "function" == typeof n && (n = o.top(this.$element)), "function" == typeof s && (s = o.bottom(this.$element));
15525 var r = this.getState(a, e, n, s); 15526 15527 if (this.affixed != r) { 15528 null != this.unpin && this.$element.css("top", ""); 15529 var l = "affix" + (r ? "-" + r : ""), 15530 h = t.Event(l + ".bs.affix"); 15531 if (this.$element.trigger(h), h.isDefaultPrevented()) return; 15532 this.affixed = r, this.unpin = "bottom" == r ? this.getPinnedOffset() : null, this.$element.removeClass(i.RESET).addClass(l).trigger(l.replace("affix", "affixed") + ".bs.affix"); 15533 } 15534 15535 "bottom" == r && this.$element.offset({ 15536 top: a - e - s 15537 }); 15538 } 15539 }; 15540 var o = t.fn.affix; 15541 t.fn.affix = e, t.fn.affix.Constructor = i, t.fn.affix.noConflict = function () { 15542 return t.fn.affix = o, this; 15543 }, t(window).on("load", function () { 15544 t('[data-spy="affix"]').each(function () { 15545 var i = t(this), 15546 o = i.data(); 15547 o.offset = o.offset || {}, null != o.offsetBottom && (o.offset.bottom = o.offsetBottom), null != o.offsetTop && (o.offset.top = o.offsetTop), e.call(i, o); 15548 }); 15549 }); 15550 }(jQuery), +function (t) { 15551 "use strict"; 15552 15553 function e(e) { 15554 var i, 15555 o = e.attr("data-target") || (i = e.attr("href")) && i.replace(/.*(?=#[^\s]+$)/, ""); 15556 return t(document).find(o); 15557 } 15558 15559 function i(e) { 15560 return this.each(function () { 15561 var i = t(this), 15562 n = i.data("bs.collapse"), 15563 s = t.extend({}, o.DEFAULTS, i.data(), "object" == _typeof(e) && e); 15564 !n && s.toggle && /show|hide/.test(e) && (s.toggle = !1), n || i.data("bs.collapse", n = new o(this, s)), "string" == typeof e && n[e](); 15565 }); 15566 } 15567 15568 var o = function o(e, i) { 15569 this.$element = t(e), this.options = t.extend({}, o.DEFAULTS, i), this.$trigger = t('[data-toggle="collapse"][href="#' + e.id + '"],[data-toggle="collapse"][data-target="#' + e.id + '"]'), this.transitioning = null, this.options.parent ? this.$parent = this.getParent() : this.addAriaAndCollapsedClass(this.$element, this.$trigger), this.options.toggle && this.toggle(); 15570 }; 15571 15572 o.VERSION = "3.4.1", o.TRANSITION_DURATION = 350, o.DEFAULTS = { 15573 toggle: !0 15574 }, o.prototype.dimension = function () { 15575 var t = this.$element.hasClass("width"); 15576 return t ? "width" : "height"; 15577 }, o.prototype.show = function () { 15578 if (!this.transitioning && !this.$element.hasClass("in")) { 15579 var e, 15580 n = this.$parent && this.$parent.children(".panel").children(".in, .collapsing"); 15581 15582 if (!(n && n.length && (e = n.data("bs.collapse"), e && e.transitioning))) { 15583 var s = t.Event("show.bs.collapse"); 15584 15585 if (this.$element.trigger(s), !s.isDefaultPrevented()) { 15586 n && n.length && (i.call(n, "hide"), e || n.data("bs.collapse", null)); 15587 var a = this.dimension(); 15588 this.$element.removeClass("collapse").addClass("collapsing")[a](0).attr("aria-expanded", !0), this.$trigger.removeClass("collapsed").attr("aria-expanded", !0), this.transitioning = 1; 15589 15590 var r = function r() { 15591 this.$element.removeClass("collapsing").addClass("collapse in")[a](""), this.transitioning = 0, this.$element.trigger("shown.bs.collapse"); 15592 }; 15593 15594 if (!t.support.transition) return r.call(this); 15595 var l = t.camelCase(["scroll", a].join("-")); 15596 this.$element.one("bsTransitionEnd", t.proxy(r, this)).emulateTransitionEnd(o.TRANSITION_DURATION)[a](this.$element[0][l]); 15597 } 15598 } 15599 } 15600 }, o.prototype.hide = function () { 15601 if (!this.transitioning && this.$element.hasClass("in")) { 15602 var e = t.Event("hide.bs.collapse"); 15603 15604 if (this.$element.trigger(e), !e.isDefaultPrevented()) { 15605 var i = this.dimension(); 15606 this.$element[i](this.$element[i]())[0].offsetHeight, this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded", !1), this.$trigger.addClass("collapsed").attr("aria-expanded", !1), this.transitioning = 1; 15607 15608 var n = function n() { 15609 this.transitioning = 0, this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse"); 15610 }; 15611 15612 return t.support.transition ? void this.$element[i](0).one("bsTransitionEnd", t.proxy(n, this)).emulateTransitionEnd(o.TRANSITION_DURATION) : n.call(this); 15613 } 15614 } 15615 }, o.prototype.toggle = function () { 15616 this[this.$element.hasClass("in") ? "hide" : "show"](); 15617 }, o.prototype.getParent = function () { 15618 return t(document).find(this.options.parent).find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]').each(t.proxy(function (i, o) { 15619 var n = t(o); 15620 this.addAriaAndCollapsedClass(e(n), n); 15621 }, this)).end(); 15622 }, o.prototype.addAriaAndCollapsedClass = function (t, e) { 15623 var i = t.hasClass("in"); 15624 t.attr("aria-expanded", i), e.toggleClass("collapsed", !i).attr("aria-expanded", i); 15625 }; 15626 var n = t.fn.collapse; 15627 t.fn.collapse = i, t.fn.collapse.Constructor = o, t.fn.collapse.noConflict = function () { 15628 return t.fn.collapse = n, this; 15629 }, t(document).on("click.bs.collapse.data-api", '[data-toggle="collapse"]', function (o) { 15630 var n = t(this); 15631 n.attr("data-target") || o.preventDefault(); 15632 var s = e(n), 15633 a = s.data("bs.collapse"), 15634 r = a ? "toggle" : n.data(); 15635 i.call(s, r); 15636 }); 15637 }(jQuery), +function (t) { 15638 "use strict"; 15639 15640 function e(i, o) { 15641 this.$body = t(document.body), this.$scrollElement = t(t(i).is(document.body) ? window : i), this.options = t.extend({}, e.DEFAULTS, o), this.selector = (this.options.target || "") + " .nav li > a", this.offsets = [], this.targets = [], this.activeTarget = null, this.scrollHeight = 0, this.$scrollElement.on("scroll.bs.scrollspy", t.proxy(this.process, this)), this.refresh(), this.process(); 15642 } 15643 15644 function i(i) { 15645 return this.each(function () { 15646 var o = t(this), 15647 n = o.data("bs.scrollspy"), 15648 s = "object" == _typeof(i) && i; 15649 n || o.data("bs.scrollspy", n = new e(this, s)), "string" == typeof i && n[i](); 15650 }); 15651 } 15652 15653 e.VERSION = "3.4.1", e.DEFAULTS = { 15654 offset: 10 15655 }, e.prototype.getScrollHeight = function () { 15656 return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight); 15657 }, e.prototype.refresh = function () { 15658 var e = this, 15659 i = "offset", 15660 o = 0; 15661 this.offsets = [], this.targets = [], this.scrollHeight = this.get
15661ScrollHeight(), t.isWindow(this.$scrollElement[0]) || (i = "position", o = this.$scrollElement.scrollTop()), this.$body.find(this.selector).map(function () { 15662 var e = t(this), 15663 n = e.data("target") || e.attr("href"), 15664 s = /^#./.test(n) && t(n); 15665 return s && s.length && s.is(":visible") && [[s[i]().top + o, n]] || null; 15666 }).sort(function (t, e) { 15667 return t[0] - e[0]; 15668 }).each(function () { 15669 e.offsets.push(this[0]), e.targets.push(this[1]); 15670 }); 15671 }, e.prototype.process = function () { 15672 var t, 15673 e = this.$scrollElement.scrollTop() + this.options.offset, 15674 i = this.getScrollHeight(), 15675 o = this.options.offset + i - this.$scrollElement.height(), 15676 n = this.offsets, 15677 s = this.targets, 15678 a = this.activeTarget; 15679 if (this.scrollHeight != i && this.refresh(), e >= o) return a != (t = s[s.length - 1]) && this.activate(t); 15680 if (a && e < n[0]) return this.activeTarget = null, this.clear(); 15681 15682 for (t = n.length; t--;) { 15683 a != s[t] && e >= n[t] && (void 0 === n[t + 1] || e < n[t + 1]) && this.activate(s[t]); 15684 } 15685 }, e.prototype.activate = function (e) { 15686 this.activeTarget = e, this.clear(); 15687 var i = this.selector + '[data-target="' + e + '"],' + this.selector + '[href="' + e + '"]', 15688 o = t(i).parents("li").addClass("active"); 15689 o.parent(".dropdown-menu").length && (o = o.closest("li.dropdown").addClass("active")), o.trigger("activate.bs.scrollspy"); 15690 }, e.prototype.clear = function () { 15691 t(this.selector).parentsUntil(this.options.target, ".active").removeClass("active"); 15692 }; 15693 var o = t.fn.scrollspy; 15694 t.fn.scrollspy = i, t.fn.scrollspy.Constructor = e, t.fn.scrollspy.noConflict = function () { 15695 return t.fn.scrollspy = o, this; 15696 }, t(window).on("load.bs.scrollspy.data-api", function () { 15697 t('[data-spy="scroll"]').each(function () { 15698 var e = t(this); 15699 i.call(e, e.data()); 15700 }); 15701 }); 15702 }(jQuery), +function (t) { 15703 "use strict"; 15704 15705 function e() { 15706 var t = document.createElement("bootstrap"), 15707 e = { 15708 WebkitTransition: "webkitTransitionEnd", 15709 MozTransition: "transitionend", 15710 OTransition: "oTransitionEnd otransitionend", 15711 transition: "transitionend" 15712 }; 15713 15714 for (var i in e) { 15715 if (void 0 !== t.style[i]) return { 15716 end: e[i] 15717 }; 15718 } 15719 15720 return !1; 15721 } 15722 15723 t.fn.emulateTransitionEnd = function (e) { 15724 var i = !1, 15725 o = this; 15726 t(this).one("bsTransitionEnd", function () { 15727 i = !0; 15728 }); 15729 15730 var n = function n() { 15731 i || t(o).trigger(t.support.transition.end); 15732 }; 15733 15734 return setTimeout(n, e), this; 15735 }, t(function () { 15736 t.support.transition = e(), t.support.transition && (t.event.special.bsTransitionEnd = { 15737 bindType: t.support.transition.end, 15738 delegateType: t.support.transition.end, 15739 handle: function handle(e) { 15740 return t(e.target).is(this) ? e.handleObj.handler.apply(this, arguments) : void 0; 15741 } 15742 }); 15743 }); 15744 }(jQuery); 15745 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 15746 15747/***/ }), 15748
15749/***/ "./wp-content/themes/pnr/assets/src/js/components/Api.js": 15750/*!***************************************************************!*\ 15751 !*** ./wp-content/themes/pnr/assets/src/js/components/Api.js ***! 15752 \***************************************************************/ 15753 /*! exports provided: ApiCpnt */ 15754 /***/ (function(module, __webpack_exports__, __webpack_require__) { 15755 15756 "use strict"; 15757 __webpack_require__.r(__webpack_exports__); 15758 /* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ApiCpnt", function() { return ApiCpnt; }); 15759 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 15760 15761 function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 15762 15763 function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 15764 15765 var ApiCpnt = 15766 /*#__PURE__*/ 15767 function () { 15768 function ApiCpnt() { 15769 _classCallCheck(this, ApiCpnt); 15770 15771 this.initContactRequestRoute(); 15772 } 15773 15774 _createClass(ApiCpnt, [{ 15775 key: "initContactRequestRoute", 15776 value: function initContactRequestRoute() { 15777 var contactCalls = $('[data-role="get-contact"]'); 15778 contactCalls.each(function () { 15779 var contact = $(this); 15780 $(this).click(function () { 15781 var cid = $(this).attr('data-cid'); 15782 $(contact).unbind('click').append('...'); // Make the request 15783 15784 $.post({ 15785 url: Theme.rest_url + "pnr/v1/directory/gcid", 15786 data: { 15787 cid: cid 15788 } 15789 }).done(function (data) { 15790 if (data.eid) { 15791 $(contact).unbind('click').hide().after('<p><a class="button clear" href="mailto:' + data.eid + '"><span>' + data.eid + '</span></a></p>'); 15792 } 15793 }); 15794 }); 15795 }); 15796 } 15797 }]); 15798 15799 return ApiCpnt; 15800 }(); 15801 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 15802 15803 /***/ }), 15804 15805
15805/***/ "./wp-content/themes/pnr/assets/src/js/components/AutoHiddingNav.js": 15806/*!**************************************************************************!*\ 15807 !*** ./wp-content/themes/pnr/assets/src/js/components/AutoHiddingNav.js ***! 15808 \**************************************************************************/ 15809 /*! exports provided: AutoHiddingNav */ 15810 /***/ (function(module, __webpack_exports__, __webpack_require__) { 15811 15812 "use strict"; 15813 __webpack_require__.r(__webpack_exports__); 15814 /* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AutoHiddingNav", function() { return AutoHiddingNav; }); 15815 /* harmony import */ var modernizr__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! modernizr */ "./.modernizrrc.js"); 15816 /* harmony import */ var modernizr__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(modernizr__WEBPACK_IMPORTED_MODULE_0__); 15817 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 15818 15819 function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 15820 15821 function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 15822 15823 15824 var AutoHiddingNav = 15825 /*#__PURE__*/ 15826 function () { 15827 function AutoHiddingNav() { 15828 _classCallCheck(this, AutoHiddingNav); 15829 15830 this.hiddingNav(); 15831 } 15832 15833 _createClass(AutoHiddingNav, [{ 15834 key: "hiddingNav", 15835 value: function hiddingNav() { 15836 var mainHeader = $('.navbar'), 15837 secondaryNavigation = $('.cd-secondary-nav'), 15838 //this applies only if secondary nav is below intro section 15839 belowNavHeroContent = $('.sub-nav-hero'), 15840 headerHeight = mainHeader.height(); //set scrolling variables 15841 15842 var scrolling = false, 15843 previousTop = 0, 15844 currentTop = 0, 15845 scrollDelta = 10, 15846 scrollOffset = 150; 15847 mainHeader.on('click', '.nav-trigger', function (event) { 15848 // open primary navigation on mobile 15849 event.preventDefault(); 15850 mainHeader.toggleClass('nav-open'); 15851 }); 15852 var imgLogo = mainHeader.find('.logo img'); 15853 15854 var styleHeader = function styleHeader(currentTop) { 15855 if (mainHeader.hasClass('navbar--with-image')) { 15856 imgLogo.attr('src', Theme.themeURL + '/assets/dist/images/logo.svg'); 15857 } 15858 }; 15859 15860 styleHeader(currentTop); 15861 $(window).on('scroll', function () { 15862 var currentTop = $(window).scrollTop(); 15863 styleHeader(currentTop); 15864 15865 if (!scrolling) { 15866 scrolling = true; 15867 !window.requestAnimationFrame ? setTimeout(autoHideHeader, 250) : requestAnimationFrame(autoHideHeader); 15868 } 15869 }); 15870 $(window).on('resize', function () { 15871 headerHeight = mainHeader.height(); 15872 }); 15873 15874 function autoHideHeader() { 15875 var currentTop = $(window).scrollTop(); 15876 belowNavHeroContent.length > 0 ? checkStickyNavigation(currentTop) // secondary navigation below intro 15877 : checkSimpleNavigation(currentTop); 15878 colorNavigation(currentTop); 15879 previousTop = currentTop; 15880 scrolling = false; 15881 } 15882 15883 function checkSimpleNavigation(currentTop) { 15884 //there's no secondary nav or secondary nav is below primary nav 15885 if (previousTop - currentTop > scrollDelta) { 15886 //if scrolling up... 15887 mainHeader.removeClass('is-hidden'); 15888 } else if (currentTop - previousTop > scrollDelta && currentTop > scrollOffset) { 15889 //if scrolling down... 15890 mainHeader.addClass('is-hidden'); 15891 } 15892 } 15893 15894 function checkStickyNavigation(currentTop) { 15895 //secondary nav below intro section - sticky secondary nav 15896 var secondaryNavOffsetTop = belowNavHeroContent.offset().top - secondaryNavigation.height() - mainHeader.height(); 15897 15898 if (previousTop >= currentTop) { 15899 //if scrolling up... 15900 if (currentTop < secondaryNavOffsetTop) { 15901 //secondary nav is not fixed 15902 mainHeader.removeClass('is-hidden'); 15903 secondaryNavigation.removeClass('fixed slide-up'); 15904 belowNavHeroContent.removeClass('secondary-nav-fixed'); 15905 } else if (previousTop - currentTop > scrollDelta) { 15906 //secondary nav is fixed 15907 mainHeader.removeClass('is-hidden'); 15908 secondaryNavigation.removeClass('slide-up').addClass('fixed'); 15909 belowNavHeroContent.addClass('secondary-nav-fixed'); 15910 } 15911 } else { 15912 //if scrolling down... 15913 if (currentTop > secondaryNavOffsetTop + scrollOffset) { 15914 //hide primary nav 15915 mainHeader.addClass('is-hidden'); 15916 secondaryNavigation.addClass('fixed slide-up'); 15917 belowNavHeroContent.addClass('secondary-nav-fixed'); 15918 } else if (currentTop > secondaryNavOffsetTop) { 15919 //once the secondary nav is fixed, do not hide primary nav if you haven't scrolled more than scrollOffset 15920 mainHeader.removeClass('is-hidden'); 15921 secondaryNavigation.addClass('fixed').removeClass('slide-up'); 15922 belowNavHeroContent.addClass('secondary-nav-fixed'); 15923 } 15924 } 15925 } 15926 15927 function colorNavigation(currentTop) { 15928 if (currentTop > 50) { 15929 mainHeader.addClass('is-colored'); 15930 } else { 15931 mainHeader.removeClass('is-colored'); 15932 } 15933 } 15934 } 15935 }]); 15936 15937return AutoHiddingNav; 15938}(); 15939/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 15940 15941/***/ }), 15942
15943/***/ "./wp-content/themes/pnr/assets/src/js/components/Gallery.js": 15944/*!*******************************************************************!*\ 15945 !*** ./wp-content/themes/pnr/assets/src/js/components/Gallery.js ***! 15946 \*******************************************************************/ 15947 /*! exports provided: GalleryCpnt */ 15948 /***/ (function(module, __webpack_exports__, __webpack_require__) { 15949 15950 "use strict"; 15951 __webpack_require__.r(__webpack_exports__); 15952 /* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GalleryCpnt", function() { return GalleryCpnt; }); 15953 /* harmony import */ var isotope_layout_dist_isotope_pkgd_min__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! isotope-layout/dist/isotope.pkgd.min */ "./node_modules/isotope-layout/dist/isotope.pkgd.min.js"); 15954 /* harmony import */ var isotope_layout_dist_isotope_pkgd_min__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(isotope_layout_dist_isotope_pkgd_min__WEBPACK_IMPORTED_MODULE_0__); 15955 /* harmony import */ var imagesloaded_imagesloaded_pkgd_min__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! imagesloaded/imagesloaded.pkgd.min */ "./node_modules/imagesloaded/imagesloaded.pkgd.min.js"); 15956 /* harmony import */ var imagesloaded_imagesloaded_pkgd_min__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(imagesloaded_imagesloaded_pkgd_min__WEBPACK_IMPORTED_MODULE_1__); 15957 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 15958 15959 function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 15960 15961 function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 15962 15963/* 15964 * IRIS Interactive 15965 * 15966 * NOTICE OF LICENSE 15967 * 15968 * This source file is no subject to a specific license 15969 * but it belongs to the company IRIS Interactive. 15970 * You can contact IRIS Interactive at the following 15971 * address: [email protected] 15972 * 15973 * @author Maëlle MONTINERI 15974 * @date 22/10/2019 11:49 15975 * @copyright Copyright (c) 2002-2019 IRIS Interactive, Inc. (http://www.iris-interactive.fr) 15976 */ 15977 15978 15979 15980 15981 var GalleryCpnt = 15982 /*#__PURE__*/ 15983 function () { 15984 function GalleryCpnt() { 15985 _classCallCheck(this, GalleryCpnt); 15986 15987 this.initializeGallery(); 15988 } 15989 15990 15991 15992 _createClass(GalleryCpnt, [{ 15993 key: "initializeGallery", 15994 value: function initializeGallery() { 15995 var grid = document.querySelector('.js-grid'), 15996 item = '.js-gridItem', 15997 filterList = $('.js-filterList'), 15998 active = 'active'; 15999 16000 16001 function GetURLParameter(sParam) 16002 { 16003 var sPageURL = window.location.search.substring(1); 16004 var sURLVariables = sPageURL.split('&'); 16005 for (var i = 0; i < sURLVariables.length; i++) 16006 { 16007 var sParameterName = sURLVariables[i].split('='); 16008 if (sParameterName[0] == sParam) 16009 { 16010 return sParameterName[1]; 16011 } 16012 } 16013 } 16014 var filterOnLoad = ''; 16015 var filterParam = GetURLParameter('categorie'); 16016 16017 if(filterParam != null){ 16018 filterOnLoad = filterParam; 16019 } 16020 16021 16022 if ($('.grid-sizer').length > 0) { 16023 if (document.body.contains(grid)) { 16024 $('.blog .postItem').addClass('js-gridItem'); 16025 var iso = new isotope_layout_dist_isotope_pkgd_min__WEBPACK_IMPORTED_MODULE_0___default.a(grid, { 16026 masonry: { 16027 columnWidth: '.grid-sizer', 16028 gutter: 20, 16029 itemSelector: item, 16030 percentPosition: true 16031 } 16032 }); // Layout Isotope after each image loads 16033 16034 var imgLoad = new imagesloaded_imagesloaded_pkgd_min__WEBPACK_IMPORTED_MODULE_1___default.a(iso); 16035 imgLoad.on('progress', function () { 16036 new isotope_layout_dist_isotope_pkgd_min__WEBPACK_IMPORTED_MODULE_0___default.a(grid, 'layout'); 16037 }); 16038 16039 16040 16041 if(filterOnLoad.length > 0){ 16042 16043 var filterValue = '.' + filterOnLoad; 16044 iso.arrange({ 16045 filter: filterValue 16046 }); 16047 16048 filterList.each(function (i, buttonGroup) { 16049 var $buttonGroup = $(buttonGroup); 16050 $buttonGroup.on('click', 'li', function () { 16051 $buttonGroup.find('.' + active).removeClass(active); 16052 $(this).addClass(active); 16053 }); 16054 }); 16055 } 16056 16057 if (filterList.length > 0) { 16058 // Filter items on button click 16059 filterList.on('click', 'li', function () { 16060 var filterValue = $(this).attr('data-filter'); 16061 iso.arrange({ 16062 filter: filterValue 16063 }); 16064 }); // Change class on click 16065 16066 filterList.each(function (i, buttonGroup) { 16067 var $buttonGroup = $(buttonGroup); 16068 $buttonGroup.on('click', 'li', function () { 16069 $buttonGroup.find('.' + active).removeClass(active); 16070 $(this).addClass(active); 16071 }); 16072 }); 16073 } 16074 } 16075 } 16076 } 16077 }]); 16078 16079 return GalleryCpnt; 16080}(); 16081/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 16082 16083/***/ }), 16084
16085/***/ "./wp-content/themes/pnr/assets/src/js/components/Slider.js": 16086/*!******************************************************************!*\ 16087 !*** ./wp-content/themes/pnr/assets/src/js/components/Slider.js ***! 16088 \******************************************************************/ 16089 /*! exports provided: Slider */ 16090 /***/ (function(module, __webpack_exports__, __webpack_require__) { 16091 16092 "use strict"; 16093 __webpack_require__.r(__webpack_exports__); 16094 /* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Slider", function() { return Slider; }); 16095 /* harmony import */ var slick_carousel_slick_slick_min__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! slick-carousel/slick/slick.min */ "./node_modules/slick-carousel/slick/slick.min.js"); 16096 /* harmony import */ var slick_carousel_slick_slick_min__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(slick_carousel_slick_slick_min__WEBPACK_IMPORTED_MODULE_0__); 16097 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 16098 16099 function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 16100 16101 function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 16102 16103/* 16104 * IRIS Interactive 16105 * 16106 * NOTICE OF LICENSE 16107 * 16108 * This source file is no subject to a specific license 16109 * but it belongs to the company IRIS Interactive. 16110 * You can contact IRIS Interactive at the following 16111 * address: [email protected] 16112 * 16113 * @author Maëlle MONTINERIb 16114 * @date 15/10/2019 12:15 16115 * @copyright Copyright (c) 2002-2019 IRIS Interactive, Inc. (http://www.iris-interactive.fr) 16116 */ 16117 16118 var Slider = 16119 /*#__PURE__*/ 16120 function () { 16121 function Slider() { 16122 _classCallCheck(this, Slider); 16123 16124 this.initializeSlider(); 16125 } 16126 16127 _createClass(Slider, [{ 16128 key: "initializeSlider", 16129 value: function initializeSlider() { 16130 var wrapper = $('.js-slick'); 16131 16132 if (window.matchMedia("(max-width: 739px)").matches && wrapper.length > 0) { 16133 wrapper.slick({ 16134 slidesToShow: 2, 16135 slidesToScroll: 1, 16136 arrows: false, 16137 autoplay: true, 16138 autoplaySpeed: 2500, 16139 dots: false 16140 }); 16141 } 16142 16143 if (window.matchMedia("(max-width: 739px)").matches && wrapper.length > 0) { 16144 $('.strateNews .postList').slick({ 16145 slide: '.postItem', 16146 accessibility: false, 16147 speed: 1000, 16148 autoplay: true, 16149 autoplaySpeed: 5000, 16150 slidesToShow: 1, 16151 arrows: false, 16152 dots: true, 16153 fade: false, 16154 pauseOnHover: false 16155 }); 16156 } 16157 16158 if (window.matchMedia("(max-width: 739px)").matches && wrapper.length > 0) { 16159 $('.strateAgenda .eventsList').slick({ 16160 slide: '.eventsListItem', 16161 accessibility: false, 16162 speed: 1000, 16163 autoplay: true, 16164 autoplaySpeed: 5000, 16165 slidesToShow: 1, 16166 arrows: false, 16167 dots: true, 16168 fade: false, 16169 pauseOnHover: false 16170 }); 16171 } 16172 16173 if ($('.home').length > 0) { 16174 //Slider principal 16175 $('#sliderList').slick({ 16176 slide: '.sliderItem', 16177 accessibility: false, 16178 speed: 1000, 16179 autoplay: true, 16180 autoplaySpeed: 5000, 16181 slidesToShow: 1, 16182 arrows: true, 16183 dots: false, 16184 fade: true, 16185 pauseOnHover: false, 16186 responsive: [{ 16187 breakpoint: 739, 16188 settings: { 16189 arrows: false, 16190 dots: true, 16191 swipe: true 16192 } 16193 }] 16194 }); // Slider Best OF 16195 16196 $('#bestOfList').slick({ 16197 infinite: false, 16198 speed: 1000, 16199 autoplay: false, 16200 autoplaySpeed: 5000, 16201 arrows: true, 16202 dots: false, 16203 pauseOnHover: true, 16204 centerMode: true, 16205 slidesToShow: 1, 16206 focusOnSelect: true, 16207 variableWidth: true, 16208 swipe: false, 16209 responsive: [{ 16210 breakpoint: 739, 16211 settings: {
16212 arrows: false, 16213 dots: true, 16214 initialSlide: 1, 16215 variableWidth: true, 16216 centerMode: true, 16217 swipe: true 16218 } 16219 }] 16220 }); 16221 } 16222 } 16223 }]); 16224 16225 return Slider; 16226}(); 16227/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 16228 16229/***/ }), 16230
16231/***/ "./wp-content/themes/pnr/assets/src/js/components/blocMap.js": 16232/*!*******************************************************************!*\ 16233 !*** ./wp-content/themes/pnr/assets/src/js/components/blocMap.js ***! 16234 \*******************************************************************/ 16235 /*! exports provided: blocMap */ 16236 /***/ (function(module, __webpack_exports__, __webpack_require__) { 16237 16238 "use strict"; 16239 __webpack_require__.r(__webpack_exports__); 16240 /* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "blocMap", function() { return blocMap; }); 16241 /* harmony import */ var leaflet__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! leaflet */ "./node_modules/leaflet/dist/leaflet-src.js"); 16242 /* harmony import */ var leaflet__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(leaflet__WEBPACK_IMPORTED_MODULE_0__); 16243 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 16244 16245 function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 16246 16247 function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 16248 16249/* 16250 * IRIS Interactive 16251 * 16252 * NOTICE OF LICENSE 16253 * 16254 * This source file is no subject to a specific license 16255 * but it belongs to the company IRIS Interactive. 16256 * You can contact IRIS Interactive at the following 16257 * address: [email protected] 16258 * 16259 * @author Maëlle MONTINERI 16260 * @date 25/10/2019 14:58 16261 * @copyright Copyright (c) 2002-2019 IRIS Interactive, Inc. (http://www.iris-interactive.fr) 16262 */ 16263 16264 var blocMap = 16265 /*#__PURE__*/ 16266 function () { 16267 function blocMap() { 16268 _classCallCheck(this, blocMap); 16269 16270 this.initializeBlocMap(); 16271 } 16272 16273 _createClass(blocMap, [{ 16274 key: "initializeBlocMap", 16275 value: function initializeBlocMap() { 16276 if ($('.wp-block-map').length > 0) { 16277 var markers = []; 16278 var initPositions = []; 16279 var positions = []; 16280 var $markers = $('#map').find('.marker'); // create map 16281 16282 var map = leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.map('map').setView([0, 0], 5); 16283 leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.tileLayer('https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', { 16284 attribution: 'données © <a href="//osm.org/copyright">OpenStreetMap</a>/ODbL - rendu <a href="//openstreetmap.fr">OSM France</a>', 16285 minZoom: 1, 16286 maxZoom: 20 16287 }).addTo(map); 16288 var markerIcon = leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.icon({ 16289 iconUrl: Theme.themeURL + '/assets/dist/images/markers/marker.svg', 16290 iconSize: [24, 40], 16291 iconAnchor: [10, 15], 16292 // point of the icon which will correspond to marker's location 16293 popupAnchor: [0, -15] // point from which the popup should open relative to the iconAnchor 16294 16295 }); // add markers 16296 16297 $markers.each(function () { 16298 var marker = leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.marker([$(this).data('lat'), $(this).data('lng')], { 16299 icon: markerIcon 16300 }).addTo(map); 16301 marker.bindPopup($(this).html()).openPopup(); 16302 marker.bindPopup($(this).html()).closePopup(); 16303 markers.push(marker); 16304 positions.push([$(this).data('lat'), $(this).data('lng')]); 16305 initPositions.push([$(this).data('lat'), $(this).data('lng')]); 16306 }); 16307 var group = leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.featureGroup(markers); //add markers array to featureGroup 16308 // Marker center on map 16309 16310 map.fitBounds(group.getBounds()); // KML 16311 16312 var kml = $("#map-kml").attr('data-kml'); 16313 var customLayer = leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.geoJson(null, { 16314 style: function style(feature) { 16315 return { 16316 color: '#171717' 16317 }; 16318 } 16319 }); 16320 var runLayer = omnivore.kml(kml, null, customLayer).addTo(map); // Disable zoom on map on scroll 16321 16322 map.scrollWheelZoom.disable(); 16323 return map; 16324 } 16325 } 16326 }]); 16327 16328 return blocMap; 16329}(); 16330/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 16331 16332/***/ }), 16333
16334/***/ "./wp-content/themes/pnr/assets/src/js/components/form_cpnt.js": 16335/*!*********************************************************************!*\ 16336 !*** ./wp-content/themes/pnr/assets/src/js/components/form_cpnt.js ***! 16337 \*********************************************************************/ 16338 /*! exports provided: FormCpnt */ 16339 /***/ (function(module, __webpack_exports__, __webpack_require__) { 16340 16341 "use strict"; 16342 __webpack_require__.r(__webpack_exports__); 16343 /* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FormCpnt", function() { return FormCpnt; }); 16344 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 16345 16346 function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 16347 16348 function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 16349 16350 var FormCpnt = 16351 /*#__PURE__*/ 16352 function () { 16353 function FormCpnt() { 16354 _classCallCheck(this, FormCpnt); 16355 16356 this.customizeInput(); 16357 this.customizeSelect(); 16358 } 16359 16360 _createClass(FormCpnt, [{ 16361 key: "customizeInput", 16362 value: function customizeInput() { 16363 var form_items = $('.wpcf7 [type="checkbox"], .wpcf7 [type="radio"]'); 16364 $(form_items).each(function (i, elm) { 16365 var id = $(elm).attr('name') + '-' + i; 16366 var label_text = $(elm).siblings('.wpcf7-list-item-label').text(); 16367 var label = '<label for="' + id + '">' + label_text + '</label>'; 16368 $(elm).siblings('.wpcf7-list-item-label').remove(); 16369 $(elm).parent().append(label); 16370 }); 16371 } 16372 }, { 16373 key: "customizeSelect", 16374 value: function customizeSelect() { 16375 $('select').parent().not('.formSelect').children('select').wrap('<div class="formSelect"></div>'); 16376 } 16377 }]); 16378 16379 return FormCpnt; 16380 }(); 16381 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 16382 16383 /***/ }), 16384 16385
16385/***/ "./wp-content/themes/pnr/assets/src/js/components/map_cpnt.js": 16386/*!********************************************************************!*\ 16387 !*** ./wp-content/themes/pnr/assets/src/js/components/map_cpnt.js ***! 16388 \********************************************************************/ 16389 /*! exports provided: MapCpnt */ 16390 /***/ (function(module, __webpack_exports__, __webpack_require__) { 16391 16392 "use strict"; 16393 __webpack_require__.r(__webpack_exports__); 16394 /* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MapCpnt", function() { return MapCpnt; }); 16395 /* harmony import */ var leaflet__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! leaflet */ "./node_modules/leaflet/dist/leaflet-src.js"); 16396 /* harmony import */ var leaflet__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(leaflet__WEBPACK_IMPORTED_MODULE_0__); 16397 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 16398 16399 function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 16400 16401 function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 16402 16403 16404 var MapCpnt = 16405 /*#__PURE__*/ 16406 function () { 16407 function MapCpnt() { 16408 _classCallCheck(this, MapCpnt); 16409 16410 this.initializeMap(); 16411 } 16412 16413 _createClass(MapCpnt, [{ 16414 key: "initializeMap", 16415 value: function initializeMap() { 16416 this.initializeApi('js-map'); 16417 } 16418 }, { 16419 key: "initializeApi", 16420 value: function initializeApi($el) { 16421 if (document.body.contains(document.getElementById($el))) { 16422 var addresses = [{ 16423 latitude: Theme.latitude, 16424 longitude: Theme.longitude, 16425 title: Theme.name, 16426 street: Theme.street, 16427 postalcode: Theme.postalcode, 16428 city: Theme.city 16429 }]; 16430 var map = leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.map($el, { 16431 center: [parseFloat(Theme.latitude), parseFloat(Theme.longitude)], 16432 zoom: 11, 16433 scrollWheelZoom: false 16434 }); 16435 leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { 16436 attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' 16437 }).addTo(map); 16438 var marker_bounds = []; 16439 var self = this; 16440 $.each(addresses, function (index, data) { 16441 var marker_icon = leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.icon({ 16442 iconUrl: Theme.themeURL + '/assets/dist/images/markers/marker.svg', 16443 iconSize: [33, 33] 16444 }); 16445 var marker = leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.featureGroup().addLayer(leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.marker([parseFloat(data.latitude), parseFloat(data.longitude)], { 16446 icon: marker_icon 16447 })).bindPopup(self.getInfoboxContent(data), { 16448 className: 'light', 16449 autoPanPadding: leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.point(30, 30) 16450 }).addTo(map).openPopup(); 16451 marker_bounds.push([parseFloat(data.latitude), parseFloat(data.longitude)]); 16452 }); 16453 } 16454 } 16455 }, { 16456 key: "getInfoboxContent", 16457 value: function getInfoboxContent(data) { 16458 var html = '<div class="infoBoxContent">' + '<p class="infoBoxContentTitle">' + data.title + '</p>'; 16459 16460 if (data.street || data.postalcode || data.city) { 16461 html += '<p class="infoBoxContentExcerpt"><i class="fas fa-map-marker-alt"></i> ' + data.street + '<br>' + data.postalcode + ' ' + data.city + '<br>' + '</p>'; 16462 } 16463 16464 html += '<p>' + '<a class="itinerary" href="https://www.google.com/maps/dir/Ma+position/' + parseFloat(data.latitude) + ',' + parseFloat(data.longitude) + '" target="_blank"><i class="fas fa-location-arrow"></i>' + Theme.translate.calculate_my_itinerary + '</a>' + '</p>' + '</div>'; 16465 return html; 16466 } 16467 }]); 16468 16469 return MapCpnt; 16470 }(); 16471 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 16472 16473/***/ }), 16474
16475/***/ "./wp-content/themes/pnr/assets/src/js/components/ux_cpnt.js": 16476/*!*******************************************************************!*\ 16477 !*** ./wp-content/themes/pnr/assets/src/js/components/ux_cpnt.js ***! 16478 \*******************************************************************/ 16479 /*! exports provided: UxCpnt */ 16480 /***/ (function(module, __webpack_exports__, __webpack_require__) { 16481 16482 "use strict"; 16483 __webpack_require__.r(__webpack_exports__); 16484 /* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UxCpnt", function() { return UxCpnt; }); 16485 /* harmony import */ var slick_carousel_slick_slick_min__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! slick-carousel/slick/slick.min */ "./node_modules/slick-carousel/slick/slick.min.js"); 16486 /* harmony import */ var slick_carousel_slick_slick_min__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(slick_carousel_slick_slick_min__WEBPACK_IMPORTED_MODULE_0__); 16487 /* harmony import */ var _fancyapps_fancybox_dist_jquery_fancybox_min__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fancyapps/fancybox/dist/jquery.fancybox.min */ "./node_modules/@fancyapps/fancybox/dist/jquery.fancybox.min.js"); 16488 /* harmony import */ var _fancyapps_fancybox_dist_jquery_fancybox_min__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_fancyapps_fancybox_dist_jquery_fancybox_min__WEBPACK_IMPORTED_MODULE_1__); 16489 /* harmony import */ var modernizr__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! modernizr */ "./.modernizrrc.js"); 16490 /* harmony import */ var modernizr__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(modernizr__WEBPACK_IMPORTED_MODULE_2__); 16491 /* harmony import */ var vanilla_lazyload__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! vanilla-lazyload */ "./node_modules/vanilla-lazyload/dist/lazyload.min.js"); 16492 /* harmony import */ var vanilla_lazyload__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(vanilla_lazyload__WEBPACK_IMPORTED_MODULE_3__); 16493 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 16494 16495 function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 16496 16497 function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 16498 16499 16500 16501 16502 16503 var UxCpnt = 16504 /*#__PURE__*/ 16505 function () { 16506 function UxCpnt() { 16507 _classCallCheck(this, UxCpnt); 16508 16509 this.initializeHoverNav(); 16510 this.initializeJsClick(); 16511 this.initializeBootstrpTooltip(); 16512 this.initializeFancybox(); 16513 this.initializeCookieOptIn(); 16514 this.initializeSearchBox(); 16515 this.initializeBackToTop(); 16516 this.initializeSmoothScroll(); 16517 this.initializeLazy(); 16518 this.newsletterEmail(); 16519 this.journalEmail(); 16520 this.menuMobile(); 16521 this.instagramWall(); 16522 } 16523 16524 _createClass(UxCpnt, [{ 16525 key: "initializeHoverNav", 16526 value: function initializeHoverNav() { 16527 var $menuItem = $('.navbarContent .navmain .menu-item'); 16528 $menuItem.each(function () { 16529 $(this).on('mouseover', function () { 16530 $('body').addClass('menuHover'); 16531 }).on('mouseout', function () { 16532 $('body').removeClass('menuHover'); 16533 }); 16534 }); 16535 } 16536 }, { 16537 key: "initializeJsClick", 16538 value: function initializeJsClick() { 16539 if (!modernizr__WEBPACK_IMPORTED_MODULE_2___default.a.touchevents) { 16540 var ctrl = 0; 16541 $(window).on('keydown', function (e) { 16542 if (e.which == 17 || e.which == 91) { 16543 ctrl = true; 16544 } 16545 }); 16546 $(window).on('keyup', function () { 16547 ctrl = false;
16548 }); 16549 $(document).on('mouseup', '.js-click', function (e) { 16550 if (e.which == 1 || e.which == 2) { 16551 var blank = false; 16552 var url = $(this).find("a").attr("href"); 16553 16554 if (e.which == 2) { 16555 blank = true; 16556 } // Clic molette 16557 16558 16559 if ($(this).find("a").attr("target") == "_blank") { 16560 blank = true; 16561 } 16562 16563 if (blank || ctrl) { 16564 window.open(url, '_blank'); 16565 } else { 16566 window.location = url; 16567 } 16568 16569 return false; 16570 } 16571 16572 return false; 16573 }); 16574 } else { 16575 $(document).on('click', '.js-click', function (e) { 16576 var blank = false; 16577 var url = $(this).find("a").attr("href"); 16578 16579 if ($(this).find("a").attr("target") == "_blank") { 16580 blank = true; 16581 } 16582 16583 if (blank) { 16584 window.open(url, '_blank'); 16585 } else { 16586 window.location = url; 16587 } 16588 16589 return false; 16590 }); 16591 } 16592 } 16593 }, { 16594 key: "initializeBootstrpTooltip", 16595 value: function initializeBootstrpTooltip() { 16596 if (!modernizr__WEBPACK_IMPORTED_MODULE_2___default.a.touchevents) { 16597 $('[data-toggle="tooltip"]').tooltip({ 16598 trigger: "hover" 16599 }); 16600 } 16601 } 16602 }, { 16603 key: "initializeFancybox", 16604 value: function initializeFancybox() { 16605 $('.article a:has(>img):not([target="_blank"]):not(".no-fancybox")').attr('data-fancybox', 'fancybox'); 16606 $("[data-fancybox='fancybox']").fancybox({ 16607 buttons: ["zoom", //"share", 16608 "slideShow", //"fullScreen", 16609 //"download", 16610 //"thumbs", 16611 "close"], 16612 lang: "fr", 16613 i18n: { 16614 fr: { 16615 CLOSE: Theme.translate.fancyboxClose, 16616 NEXT: Theme.translate.fancyboxNext, 16617 PREV: Theme.translate.fancyboxPrev, 16618 ERROR: Theme.translate.fancyboxError, 16619 PLAY_START: Theme.translate.fancyboxStart, 16620 PLAY_STOP: Theme.translate.fancyboxStop, 16621 FULL_SCREEN: Theme.translate.fancyboxFullScreen, 16622 THUMBS: Theme.translate.fancyboxThumbs, 16623 DOWNLOAD: Theme.translate.fancyboxDownload, 16624 SHARE: Theme.translate.fancyboxShare, 16625 ZOOM: Theme.translate.fancyboxZoom 16626 } 16627 }, 16628 caption: function caption(instance, item) { 16629 var caption = $(this).closest('figure').find('figcaption').html(); 16630 16631 if (!caption) { 16632 caption = $(this).find('img').attr('title'); 16633 } 16634 16635 if (!caption) { 16636 caption = $(this).find('img').attr('alt'); 16637 } 16638 16639 return caption; 16640 } 16641 }); 16642 } 16643 }, { 16644 key: "initializeCookieOptIn", 16645 value: function initializeCookieOptIn() { 16646 tarteaucitron.init({ 16647 "useExternalCss": false, 16648 "privacyUrl": Theme.privacyPolicyURL, 16649 "hashtag": "", 16650 "cookieName": "tartaucitron", 16651 "orientation": "bottom", 16652 "showAlertSmall": false, 16653 "cookieslist": true, 16654 "adblocker": false, 16655 "AcceptAllCta": true, 16656 "highPrivacy": true, 16657 "handleBrowserDNTRequest": false, 16658 "removeCredit": true, 16659 "moreInfoLink": true, 16660 "showExitButton": true 16661 }); 16662 tarteaucitronForceLanguage = Theme.current_locale; 16663 (tarteaucitron.job = tarteaucitron.job || []).push('wordpress'); 16664 (tarteaucitron.job = tarteaucitron.job || []).push('recaptcha'); 16665 (tarteaucitron.job = tarteaucitron.job || []).push('gtag'); 16666 } 16667 }, { 16668 key: "initializeSearchBox", 16669 value: function initializeSearchBox() { 16670 $('.js-wpSearchLayoutOpen').on('click', function (e) { 16671 e.preventDefault(); 16672 $('.wpSearchLayout').fadeIn(); 16673 setTimeout(function () { 16674 $('.wpSearchFormItem--input').focus(); 16675 }, 100); 16676 }); 16677 $('.js-wpSearchLayoutClose').on('click', function (e) { 16678 e.preventDefault(); 16679 $('.wpSearchLayout').fadeOut(); 16680 }); 16681 } 16682 }, { 16683 key: "initializeBackToTop", 16684 value: function initializeBackToTop() { 16685 $('.js-backToTop').on('click', function (e) { 16686 e.preventDefault(); 16687 16688 if ($(window).scrollTop() != 0) { 16689 $('html, body').animate({ 16690 scrollTop: 0 16691 }, 300); 16692 } 16693 }); 16694 $(window).on('scroll', function (e) { 16695 if ($(this).scrollTop() > 250) { 16696 $('.js-backToTop').addClass('backToTop--show'); 16697 } else { 16698 $('.js-backToTop').removeClass('backToTop--show'); 16699 } 16700 }); 16701 } 16702 }, { 16703 key: "initializeSmoothScroll", 16704 value: function initializeSmoothScroll() { 16705 $('.js-scroll').click(function () {
16706 if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) { 16707 var target = $(this.hash); 16708 target = target.length ? target : $('[name=' + this.hash.slice(1) + ']'); 16709 16710 if (target.length) { 16711 $('html,body').animate({ 16712 scrollTop: target.offset().top 16713 }, 750); 16714 return false; 16715 } 16716 } 16717 }); 16718 } 16719 }, { 16720 key: "initializeLazy", 16721 value: function initializeLazy() { 16722 var lazyLoadInstance = new vanilla_lazyload__WEBPACK_IMPORTED_MODULE_3___default.a({ 16723 elements_selector: "[data-src], [data-bg]" 16724 }); 16725 } 16726 }, { 16727 key: "newsletterEmail", 16728 value: function newsletterEmail() { 16729 if ($('.page-id-66').length > 0) { 16730 var email = $POST_EMAIL; 16731 $('input[name="email"]').attr('value', email); 16732 $('input[name="email"]').parent().parent().addClass('is-focused'); 16733 } 16734 } 16735 }, { 16736 key: "journalEmail", 16737 value: function journalEmail() { 16738 if ($('.page-id-893').length > 0) { 16739 var email = $POST_EMAIL; 16740 $('input[name="email"]').attr('value', email); 16741 $('input[name="email"]').parent().parent().addClass('is-focused'); 16742 } 16743 } 16744 }, { 16745 key: "menuMobile", 16746 value: function menuMobile() { 16747 $('#trigger-menu').on('click', function (e) { 16748 e.preventDefault(); 16749 $(this).toggleClass('is-active'); 16750 $('body').toggleClass('menu-revealed overlay-active'); 16751 }); 16752 $('#site-overlay').on('click', function (e) { 16753 e.preventDefault(); 16754 $('#trigger-menu').toggleClass('is-active'); 16755 $('body').removeClass('menu-revealed overlay-active'); 16756 }); 16757 $('.menuMobile .menu-item-has-children').prepend('<span class="trigger-nav-subcat"><i class="fa fa-angle-down"></i></span>'); 16758 $('.menuMobile .menu-item-has-children').on('click', '.trigger-nav-subcat', function (e) { 16759 $(this).parent().toggleClass('is-active-subcat'); 16760 $(this).parent().find('.sub-menu').slideToggle(); 16761 }); 16762 } 16763 }, { 16764 key: "instagramWall", 16765 value: function instagramWall() { 16766 if ($('.strateInstagram').length > 0) { 16767 $.ajax({ 16768 url: Theme.ajaxURL, 16769 data: { 16770 'action': 'social_wall' 16771 }, 16772 type: 'POST', 16773 success: function success(socialData) { 16774 $('.instagramWall').removeClass('loading').append(socialData); 16775 } 16776 }); 16777 } 16778 } 16779 }]); 16780 16781return UxCpnt; 16782}(); 16783/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 16784 16785/***/ }), 16786
16787/***/ "./wp-content/themes/pnr/assets/src/scss/castagnades-editor.scss": 16788/*!***********************************************************************!*\ 16789 !*** ./wp-content/themes/pnr/assets/src/scss/castagnades-editor.scss ***! 16790 \***********************************************************************/ 16791 /*! no static exports found */ 16792 /***/ (function(module, exports) { 16793 16794// removed by extract-text-webpack-plugin 16795 16796/***/ }), 16797 16798
16798/***/ "./wp-content/themes/pnr/assets/src/scss/castagnades.scss": 16799/*!****************************************************************!*\ 16800 !*** ./wp-content/themes/pnr/assets/src/scss/castagnades.scss ***! 16801 \****************************************************************/ 16802 /*! no static exports found */ 16803 /***/ (function(module, exports) { 16804 16805// removed by extract-text-webpack-plugin 16806 16807/***/ }), 16808 16809
16809/***/ "./wp-content/themes/pnr/assets/src/scss/partage-editor.scss": 16810/*!*******************************************************************!*\ 16811 !*** ./wp-content/themes/pnr/assets/src/scss/partage-editor.scss ***! 16812 \*******************************************************************/ 16813 /*! no static exports found */ 16814 /***/ (function(module, exports) { 16815 16816// removed by extract-text-webpack-plugin 16817 16818/***/ }), 16819 16820
16820/***/ "./wp-content/themes/pnr/assets/src/scss/partage.scss": 16821/*!************************************************************!*\ 16822 !*** ./wp-content/themes/pnr/assets/src/scss/partage.scss ***! 16823 \************************************************************/ 16824 /*! no static exports found */ 16825 /***/ (function(module, exports) { 16826 16827// removed by extract-text-webpack-plugin 16828 16829/***/ }), 16830 16831
16831/***/ "./wp-content/themes/pnr/assets/src/scss/pnr-editor.scss": 16832/*!***************************************************************!*\ 16833 !*** ./wp-content/themes/pnr/assets/src/scss/pnr-editor.scss ***! 16834 \***************************************************************/ 16835 /*! no static exports found */ 16836 /***/ (function(module, exports) { 16837 16838// removed by extract-text-webpack-plugin 16839 16840/***/ }), 16841 16842
16842/***/ "./wp-content/themes/pnr/assets/src/scss/pnr.scss": 16843/*!********************************************************!*\ 16844 !*** ./wp-content/themes/pnr/assets/src/scss/pnr.scss ***! 16845 \********************************************************/ 16846 /*! no static exports found */ 16847 /***/ (function(module, exports) { 16848 16849// removed by extract-text-webpack-plugin 16850 16851/***/ })
16851, 16852 16853 /***/ "jquery": 16854/*!*************************!*\ 16855 !*** external "jQuery" ***! 16856 \*************************/ 16857 /*! no static exports found */ 16858 /***/ (function(module, exports) { 16859 16860 module.exports = jQuery; 16861 16862 /***/ }) 16863 16864/******/ }); 16865//# sourceMappingURL=app.min.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.