vendor: 3,643 bytes, lines 1-88
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/camiers/assets/src/js/app.js"); 85/******/ }) 86/************************************************************************/ 87/******/ ({ 88
89/***/ "./.modernizrrc.js": 90/*!*************************!*\ 91 !*** ./.modernizrrc.js ***! 92 \*************************/ 93/*! no static exports found */ 94/***/ (function(module, exports) { 95 96function _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,785 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,675 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,618 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: 4,184 bytes, lines 478-502
478/***/ "./node_modules/jquery-match-height/dist/jquery.matchHeight-min.js": 479/*!*************************************************************************!*\ 480 !*** ./node_modules/jquery-match-height/dist/jquery.matchHeight-min.js ***! 481 \*************************************************************************/ 482/*! no static exports found */ 483/***/ (function(module, exports, __webpack_require__) { 484 485var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* 486* jquery-match-height 0.7.2 by @liabru 487* http://brm.io/jquery-match-height/ 488* License MIT 489*/ 490!function(t){"use strict"; true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ "jquery")], __WEBPACK_AMD_DEFINE_FACTORY__ = (t), 491 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 492 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 493 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):undefined}(function(t){var e=-1,o=-1,n=function(t){return parseFloat(t)||0},a=function(e){var o=1,a=t(e),i=null,r=[];return a.each(function(){var e=t(this),a=e.offset().top-n(e.css("margin-top")),s=r.length>0?r[r.length-1]:null;null===s?r.push(e):Math.floor(Math.abs(i-a))<=o?r[r.length-1]=s.add(e):r.push(e),i=a}),r},i=function(e){var o={ 494byRow:!0,property:"height",target:null,remove:!1};return"object"==typeof e?t.extend(o,e):("boolean"==typeof e?o.byRow=e:"remove"===e&&(o.remove=!0),o)},r=t.fn.matchHeight=function(e){var o=i(e);if(o.remove){var n=this;return this.css(o.property,""),t.each(r._groups,function(t,e){e.elements=e.elements.not(n)}),this}return this.length<=1&&!o.target?this:(r._groups.push({elements:this,options:o}),r._apply(this,o),this)};r.version="0.7.2",r._groups=[],r._throttle=80,r._maintainScroll=!1,r._beforeUpdate=null, 495r._afterUpdate=null,r._rows=a,r._parse=n,r._parseOptions=i,r._apply=function(e,o){var s=i(o),h=t(e),l=[h],c=t(window).scrollTop(),p=t("html").outerHeight(!0),u=h.parents().filter(":hidden");return u.each(function(){var e=t(this);e.data("style-cache",e.attr("style"))}),u.css("display","block"),s.byRow&&!s.target&&(h.each(function(){var e=t(this),o=e.css("display");"inline-block"!==o&&"flex"!==o&&"inline-flex"!==o&&(o="block"),e.data("style-cache",e.attr("style")),e.css({display:o,"padding-top":"0", 496"padding-bottom":"0","margin-top":"0","margin-bottom":"0","border-top-width":"0","border-bottom-width":"0",height:"100px",overflow:"hidden"})}),l=a(h),h.each(function(){var e=t(this);e.attr("style",e.data("style-cache")||"")})),t.each(l,function(e,o){var a=t(o),i=0;if(s.target)i=s.target.outerHeight(!1);else{if(s.byRow&&a.length<=1)return void a.css(s.property,"");a.each(function(){var e=t(this),o=e.attr("style"),n=e.css("display");"inline-block"!==n&&"flex"!==n&&"inline-flex"!==n&&(n="block");var a={ 497display:n};a[s.property]="",e.css(a),e.outerHeight(!1)>i&&(i=e.outerHeight(!1)),o?e.attr("style",o):e.css("display","")})}a.each(function(){var e=t(this),o=0;s.target&&e.is(s.target)||("border-box"!==e.css("box-sizing")&&(o+=n(e.css("border-top-width"))+n(e.css("border-bottom-width")),o+=n(e.css("padding-top"))+n(e.css("padding-bottom"))),e.css(s.property,i-o+"px"))})}),u.each(function(){var e=t(this);e.attr("style",e.data("style-cache")||null)}),r._maintainScroll&&t(window).scrollTop(c/p*t("html").outerHeight(!0)), 498this},r._applyDataApi=function(){var e={};t("[data-match-height], [data-mh]").each(function(){var o=t(this),n=o.attr("data-mh")||o.attr("data-match-height");n in e?e[n]=e[n].add(o):e[n]=o}),t.each(e,function(){this.matchHeight(!0)})};var s=function(e){r._beforeUpdate&&r._beforeUpdate(e,r._groups),t.each(r._groups,function(){r._apply(this.elements,this.options)}),r._afterUpdate&&r._afterUpdate(e,r._groups)};r._update=function(n,a){if(a&&"resize"===a.type){var i=t(window).width();if(i===e)return;e=i; 499}n?o===-1&&(o=setTimeout(function(){s(a),o=-1},r._throttle)):s(a)},t(r._applyDataApi);var h=t.fn.on?"on":"bind";t(window)[h]("load",function(t){r._update(!1,t)}),t(window)[h]("resize orientationchange",function(t){r._update(!0,t)})}); 500 501/***/ }), 502
vendor: 398,580 bytes, lines 503-14532
503/***/ "./node_modules/leaflet/dist/leaflet-src.js": 504/*!**************************************************!*\ 505 !*** ./node_modules/leaflet/dist/leaflet-src.js ***! 506 \**************************************************/ 507/*! no static exports found */ 508/***/ (function(module, exports, __webpack_require__) { 509 510/* @preserve 511 * Leaflet 1.5.1+build.2e3e0ff, a JS library for interactive maps. http://leafletjs.com 512 * (c) 2010-2018 Vladimir Agafonkin, (c) 2010-2011 CloudMade 513 */ 514 515(function (global, factory) { 516 true ? factory(exports) : 517 undefined; 518}(this, (function (exports) { 'use strict'; 519 520var version = "1.5.1+build.2e3e0ffb"; 521 522/* 523 * @namespace Util 524 * 525 * Various utility functions, used by Leaflet internally. 526 */ 527 528var freeze = Object.freeze; 529Object.freeze = function (obj) { return obj; }; 530 531// @function extend(dest: Object, src?: Object): Object 532// Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut. 533function extend(dest) { 534 var i, j, len, src; 535 536 for (j = 1, len = arguments.length; j < len; j++) { 537 src = arguments[j]; 538 for (i in src) { 539 dest[i] = src[i]; 540 } 541 } 542 return dest; 543} 544 545// @function create(proto: Object, properties?: Object): Object 546// Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create) 547var create = Object.create || (function () { 548 function F() {} 549 return function (proto) { 550 F.prototype = proto; 551 return new F(); 552 }; 553})(); 554 555// @function bind(fn: Function, …): Function 556// 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). 557// Has a `L.bind()` shortcut. 558function bind(fn, obj) { 559 var slice = Array.prototype.slice; 560 561 if (fn.bind) { 562 return fn.bind.apply(fn, slice.call(arguments, 1)); 563 } 564 565 var args = slice.call(arguments, 2); 566 567 return function () { 568 return fn.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments); 569 }; 570} 571 572// @property lastId: Number 573// Last unique ID used by [`stamp()`](#util-stamp) 574var lastId = 0; 575 576// @function stamp(obj: Object): Number 577// Returns the unique ID of an object, assigning it one if it doesn't have it. 578function stamp(obj) { 579 /*eslint-disable */ 580 obj._leaflet_id = obj._leaflet_id || ++lastId; 581 return obj._leaflet_id; 582 /* eslint-enable */ 583} 584 585// @function throttle(fn: Function, time: Number, context: Object): Function 586// Returns a function which executes function `fn` with the given scope `context` 587// (so that the `this` keyword refers to `context` inside `fn`'s code). The function 588// `fn` will be called no more than one time per given amount of `time`. The arguments 589// received by the bound function will be any arguments passed when binding the 590// function, followed by any arguments passed when invoking the bound function. 591// Has an `L.throttle` shortcut. 592function throttle(fn, time, context) { 593 var lock, args, wrapperFn, later; 594 595 later = function () { 596 // reset lock and call if queued 597 lock = false; 598 if (args) { 599 wrapperFn.apply(context, args); 600 args = false; 601 } 602 }; 603 604 wrapperFn = function () { 605 if (lock) { 606 // called too soon, queue to call later 607 args = arguments; 608 609 } else { 610 // call and lock until later 611 fn.apply(context, arguments); 612 setTimeout(later, time); 613 lock = true; 614 } 615 }; 616 617 return wrapperFn; 618} 619 620// @function wrapNum(num: Number, range: Number[], includeMax?: Boolean): Number 621// Returns the number `num` modulo `range` in such a way so it lies within 622// `range[0]` and `range[1]`. The returned value will be always smaller than 623// `range[1]` unless `includeMax` is set to `true`. 624function wrapNum(x, range, includeMax) { 625 var max = range[1], 626 min = range[0], 627 d = max - min; 628 return x === max && includeMax ? x : ((x - min) % d + d) % d + min; 629} 630 631// @function falseFn(): Function 632// Returns a function which always returns `false`. 633function falseFn() { return false; } 634 635// @function formatNum(num: Number, digits?: Number): Number 636// Returns the number `num` rounded to `digits` decimals, or to 6 decimals by default. 637function formatNum(num, digits) { 638 digits = (digits === undefined ? 6 : digits); 639 return +(Math.round(num + ('e+' + digits)) + ('e-' + digits)); 640} 641 642// @function trim(str: String): String 643// Compatibility polyfill for [String.prototype.trim](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim) 644function trim(str) { 645 return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, ''); 646} 647 648// @function splitWords(str: String): String[] 649// Trims and splits the string on whitespace and returns the array of parts. 650function splitWords(str) { 651 return trim(str).split(/\s+/); 652} 653 654// @function setOptions(obj: Object, options: Object): Object 655// Merges the given properties to the `options` of the `obj` object, returning the resulting options. See `Class options`. Has an `L.setOptions` shortcut. 656function setOptions(obj, options) { 657 if (!obj.hasOwnProperty('options')) { 658 obj.options = obj.options ? create(obj.options) : {}; 659 } 660 for (var i in options) { 661 obj.options[i] = options[i]; 662 } 663 return obj.options; 664} 665 666// @function getParamString(obj: Object, existingUrl?: String, uppercase?: Boolean): String 667// Converts an object into a parameter URL string, e.g. `{a: "foo", b: "bar"}` 668// translates to `'?a=foo&b=bar'`. If `existingUrl` is set, the parameters will 669// be appended at the end. If `uppercase` is `true`, the parameter names will 670// be uppercased (e.g. `'?A=foo&B=bar'`) 671function getParamString(obj, existingUrl, uppercase) { 672 var params = []; 673 for (var i in obj) { 674 params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i])); 675 } 676 return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&'); 677} 678 679var templateRe = /\{ *([\w_-]+) *\}/g; 680 681// @function template(str: String, data: Object): String 682// Simple templating facility, accepts a template string of the form `'Hello {a}, {b}'` 683// and a data object like `{a: 'foo', b: 'bar'}`, returns evaluated string 684// `('Hello foo, bar')`. You can also specify functions instead of strings for 685// data values — they will be evaluated passing `data` as an argument. 686function template(str, data) { 687 return str.replace(templateRe, function (str, key) { 688 var value = data[key]; 689 690 if (value === undefined) { 691 throw new Error('No value provided for variable ' + str); 692 693 } else if (typeof value === 'function') { 694 value = value(data); 695 } 696 return value; 697 }); 698} 699 700// @function isArray(obj): Boolean 701// Compatibility polyfill for [Array.isArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray) 702var isArray = Array.isArray || function (obj) { 703 return (Object.prototype.toString.call(obj) === '[object Array]'); 704}; 705 706// @function indexOf(array: Array, el: Object): Number 707// Compatibility polyfill for [Array.prototype.indexOf](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) 708function indexOf(array, el) { 709 for (var i = 0; i < array.length; i++) { 710 if (array[i] === el) { return i; } 711 } 712 return -1; 713} 714 715// @property emptyImageUrl: String 716// Data URI string containing a base64-encoded empty GIF image. 717// Used as a hack to free memory from unused images on WebKit-powered 718// mobile devices (by setting image `src` to this string). 719var emptyImageUrl = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='; 720 721// inspired by http://paulirish.com/2011/requestanimationframe-for-smart-animating/ 722 723function getPrefixed(name) { 724 return window['webkit' + name] || window['moz' + name] || window['ms' + name]; 725} 726 727var lastTime = 0; 728 729// fallback for IE 7-8 730function timeoutDefer(fn) { 731 var time = +new Date(), 732 timeToCall = Math.max(0, 16 - (time - lastTime)); 733 734 lastTime = time + timeToCall; 735 return window.setTimeout(fn, timeToCall); 736} 737 738var requestFn = window.requestAnimationFrame || getPrefixed('RequestAnimationFrame') || timeoutDefer; 739var cancelFn = window.cancelAnimationFrame || getPrefixed('CancelAnimationFrame') || 740 getPrefixed('CancelRequestAnimationFrame') || function (id) { window.clearTimeout(id); }; 741 742// @function requestAnimFrame(fn: Function, context?: Object, immediate?: Boolean): Number 743// Schedules `fn` to be executed when the browser repaints. `fn` is bound to 744// `context` if given. When `immediate` is set, `fn` is called immediately if 745// the browser doesn't have native support for 746// [`window.requestAnimationFrame`](https://developer.mozilla.org/docs/Web/API/window/requestAnimationFrame), 747// otherwise it's delayed. Returns a request ID that can be used to cancel the request. 748function requestAnimFrame(fn, context, immediate) { 749 if (immediate && requestFn === timeoutDefer) { 750 fn.call(context); 751 } else { 752 return requestFn.call(window, bind(fn, context)); 753 } 754} 755 756// @function cancelAnimFrame(id: Number): undefined 757// Cancels a previous `requestAnimFrame`. See also [window.cancelAnimationFrame](https://developer.mozilla.org/docs/Web/API/window/cancelAnimationFrame). 758function cancelAnimFrame(id) { 759 if (id) { 760 cancelFn.call(window, id); 761 } 762} 763 764 765var Util = (Object.freeze || Object)({ 766 freeze: freeze, 767 extend: extend, 768 create: create, 769 bind: bind, 770 lastId: lastId, 771 stamp: stamp, 772 throttle: throttle, 773 wrapNum: wrapNum, 774 falseFn: falseFn, 775 formatNum: formatNum, 776 trim: trim, 777 splitWords: splitWords, 778 setOptions: setOptions, 779 getParamString: getParamString, 780 template: template, 781 isArray: isArray, 782 indexOf: indexOf, 783 emptyImageUrl: emptyImageUrl, 784 requestFn: requestFn, 785 cancelFn: cancelFn, 786 requestAnimFrame: requestAnimFrame, 787 cancelAnimFrame: cancelAnimFrame 788}); 789 790// @class Class 791// @aka L.Class 792 793// @section 794// @uninheritable 795 796// Thanks to John Resig and Dean Edwards for inspiration! 797 798function Class() {} 799 800Class.extend = function (props) { 801 802 // @function extend(props: Object): Function 803 // [Extends the current class](#class-inheritance) given the properties to be included. 804 // Returns a Javascript function that is a class constructor (to be called with `new`). 805 var NewClass = function () { 806 807 // call the constructor 808 if (this.initialize) { 809 this.initialize.apply(this, arguments); 810 } 811 812 // call all constructor hooks 813 this.callInitHooks(); 814 }; 815 816 var parentProto = NewClass.__super__ = this.prototype; 817 818 var proto = create(parentProto); 819 proto.constructor = NewClass; 820 821 NewClass.prototype = proto; 822 823 // inherit parent's statics 824 for (var i in this) { 825 if (this.hasOwnProperty(i) && i !== 'prototype' && i !== '__super__') { 826 NewClass[i] = this[i]; 827 } 828 } 829 830 // mix static properties into the class 831 if (props.statics) { 832 extend(NewClass, props.statics); 833 delete props.statics; 834 } 835 836 // mix includes into the prototype 837 if (props.includes) { 838 checkDeprecatedMixinEvents(props.includes); 839 extend.apply(null, [proto].concat(props.includes)); 840 delete props.includes; 841 } 842 843 // merge options 844 if (proto.options) { 845 props.options = extend(create(proto.options), props.options); 846 } 847 848 // mix given properties into the prototype 849 extend(proto, props); 850 851 proto._initHooks = []; 852 853 // add method for calling all hooks 854 proto.callInitHooks = function () { 855 856 if (this._initHooksCalled) { return; } 857 858 if (parentProto.callInitHooks) { 859 parentProto.callInitHooks.call(this); 860 } 861 862 this._initHooksCalled = true; 863 864 for (var i = 0, len = proto._initHooks.length; i < len; i++) { 865 proto._initHooks[i].call(this); 866 } 867 }; 868 869 return NewClass; 870}; 871 872 873// @function include(properties: Object): this 874// [Includes a mixin](#class-includes) into the current class. 875Class.include = function (props) { 876 extend(this.prototype, props); 877 return this; 878}; 879 880// @function mergeOptions(options: Object): this 881// [Merges `options`](#class-options) into the defaults of the class. 882Class.mergeOptions = function (options) { 883 extend(this.prototype.options, options); 884 return this; 885}; 886 887// @function addInitHook(fn: Function): this 888// Adds a [constructor hook](#class-constructor-hooks) to the class. 889Class.addInitHook = function (fn) { // (Function) || (String, args...) 890 var args = Array.prototype.slice.call(arguments, 1); 891 892 var init = typeof fn === 'function' ? fn : function () { 893 this[fn].apply(this, args); 894 }; 895 896 this.prototype._initHooks = this.prototype._initHooks || []; 897 this.prototype._initHooks.push(init); 898 return this; 899}; 900 901function checkDeprecatedMixinEvents(includes) { 902 if (typeof L === 'undefined' || !L || !L.Mixin) { return; } 903 904 includes = isArray(includes) ? includes : [includes]; 905 906 for (var i = 0; i < includes.length; i++) { 907 if (includes[i] === L.Mixin.Events) { 908 console.warn('Deprecated include of L.Mixin.Events: ' + 909 'this property will be removed in future releases, ' + 910 'please inherit from L.Evented instead.', new Error().stack); 911 } 912 } 913} 914 915/* 916 * @class Evented 917 * @aka L.Evented 918 * @inherits Class 919 * 920 * 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). 921 * 922 * @example 923 * 924 * ```js 925 * map.on('click', function(e) { 926 * alert(e.latlng); 927 * } ); 928 * ``` 929 * 930 * Leaflet deals with event listeners by reference, so if you want to add a listener and then remove it, define it as a function: 931 * 932 * ```js 933 * function onClick(e) { ... } 934 * 935 * map.on('click', onClick); 936 * map.off('click', onClick); 937 * ``` 938 */ 939 940var Events = { 941 /* @method on(type: String, fn: Function, context?: Object): this 942 * 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'`). 943 * 944 * @alternative 945 * @method on(eventMap: Object): this 946 * Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}` 947 */ 948 on: function (types, fn, context) { 949 950 // types can be a map of types/handlers 951 if (typeof types === 'object') { 952 for (var type in types) { 953 // we don't process space-separated events here for performance; 954 // it's a hot path since Layer uses the on(obj) syntax 955 this._on(type, types[type], fn); 956 } 957 958 } else { 959 // types can be a string of space-separated words 960 types = splitWords(types); 961 962 for (var i = 0, len = types.length; i < len; i++) { 963 this._on(types[i], fn, context); 964 } 965 } 966 967 return this; 968 }, 969 970 /* @method off(type: String, fn?: Function, context?: Object): this 971 * 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. 972 * 973 * @alternative 974 * @method off(eventMap: Object): this 975 * Removes a set of type/listener pairs. 976 * 977 * @alternative 978 * @method off: this 979 * Removes all listeners to all events on the object. This includes implicitly attached events. 980 */ 981 off: function (types, fn, context) { 982 983 if (!types) { 984 // clear all listeners if called without arguments 985 delete this._events; 986 987 } else if (typeof types === 'object') { 988 for (var type in types) { 989 this._off(type, types[type], fn); 990 } 991 992 } else { 993 types = splitWords(types); 994 995 for (var i = 0, len = types.length; i < len; i++) { 996 this._off(types[i], fn, context); 997 } 998 } 999 1000 return this; 1001 }, 1002 1003 // attach listener (without syntactic sugar now) 1004 _on: function (type, fn, context) { 1005 this._events = this._events || {}; 1006 1007 /* get/init listeners for type */ 1008 var typeListeners = this._events[type]; 1009 if (!typeListeners) { 1010 typeListeners = []; 1011 this._events[type] = typeListeners; 1012 } 1013 1014 if (context === this) { 1015 // Less memory footprint. 1016 context = undefined; 1017 } 1018 var newListener = {fn: fn, ctx: context}, 1019 listeners = typeListeners; 1020 1021 // check if fn already there 1022 for (var i = 0, len = listeners.length; i < len; i++) { 1023 if (listeners[i].fn === fn && listeners[i].ctx === context) { 1024 return; 1025 } 1026 } 1027 1028 listeners.push(newListener); 1029 }, 1030 1031 _off: function (type, fn, context) { 1032 var listeners, 1033 i, 1034 len; 1035 1036 if (!this._events) { return; } 1037 1038 listeners = this._events[type]; 1039 1040 if (!listeners) { 1041 return; 1042 } 1043 1044 if (!fn) { 1045 // Set all removed listeners to noop so they are not called if remove happens in fire 1046 for (i = 0, len = listeners.length; i < len; i++) { 1047 listeners[i].fn = falseFn; 1048 } 1049 // clear all listeners for a type if function isn't specified 1050 delete this._events[type]; 1051 return; 1052 } 1053 1054 if (context === this) { 1055 context = undefined; 1056 } 1057 1058 if (listeners) { 1059 1060 // find fn and remove it 1061 for (i = 0, len = listeners.length; i < len; i++) { 1062 var l = listeners[i]; 1063 if (l.ctx !== context) { continue; } 1064 if (l.fn === fn) { 1065 1066 // set the removed listener to noop so that's not called if remove happens in fire 1067 l.fn = falseFn; 1068 1069 if (this._firingCount) { 1070 /* copy array in case events are being fired */ 1071 this._events[type] = listeners = listeners.slice(); 1072 } 1073 listeners.splice(i, 1); 1074 1075 return; 1076 } 1077 } 1078 } 1079 }, 1080 1081 // @method fire(type: String, data?: Object, propagate?: Boolean): this 1082 // Fires an event of the specified type. You can optionally provide an data 1083 // object — the first argument of the listener function will contain its 1084 // properties. The event can optionally be propagated to event parents. 1085 fire: function (type, data, propagate) { 1086 if (!this.listens(type, propagate)) { return this; } 1087 1088 var event = extend({}, data, { 1089 type: type, 1090 target: this, 1091 sourceTarget: data && data.sourceTarget || this 1092 }); 1093 1094 if (this._events) { 1095 var listeners = this._events[type]; 1096 1097 if (listeners) { 1098 this._firingCount = (this._firingCount + 1) || 1; 1099 for (var i = 0, len = listeners.length; i < len; i++) { 1100 var l = listeners[i]; 1101 l.fn.call(l.ctx || this, event); 1102 } 1103 1104 this._firingCount--; 1105 } 1106 } 1107 1108 if (propagate) { 1109 // propagate the event to parents (set with addEventParent) 1110 this._propagateEvent(event); 1111 } 1112 1113 return this; 1114 }, 1115 1116 // @method listens(type: String): Boolean 1117 // Returns `true` if a particular event type has any listeners attached to it. 1118 listens: function (type, propagate) { 1119 var listeners = this._events && this._events[type]; 1120 if (listeners && listeners.length) { return true; } 1121 1122 if (propagate) { 1123 // also check parents for listeners if event propagates 1124 for (var id in this._eventParents) { 1125 if (this._eventParents[id].listens(type, propagate)) { return true; } 1126 } 1127 } 1128 return false; 1129 }, 1130 1131 // @method once(…): this 1132 // Behaves as [`on(…)`](#evented-on), except the listener will only get fired once and then removed. 1133 once: function (types, fn, context) { 1134 1135 if (typeof types === 'object') { 1136 for (var type in types) { 1137 this.once(type, types[type], fn); 1138 } 1139 return this; 1140 } 1141 1142 var handler = bind(function () { 1143 this 1144 .off(types, fn, context) 1145 .off(types, handler, context); 1146 }, this); 1147 1148 // add a listener that's executed once and removed after that 1149 return this 1150 .on(types, fn, context) 1151 .on(types, handler, context); 1152 }, 1153 1154 // @method addEventParent(obj: Evented): this 1155 // Adds an event parent - an `Evented` that will receive propagated events 1156 addEventParent: function (obj) { 1157 this._eventParents = this._eventParents || {}; 1158 this._eventParents[stamp(obj)] = obj; 1159 return this; 1160 }, 1161 1162 // @method removeEventParent(obj: Evented): this 1163 // Removes an event parent, so it will stop receiving propagated events 1164 removeEventParent: function (obj) { 1165 if (this._eventParents) { 1166 delete this._eventParents[stamp(obj)]; 1167 } 1168 return this; 1169 }, 1170 1171 _propagateEvent: function (e) { 1172 for (var id in this._eventParents) { 1173 this._eventParents[id].fire(e.type, extend({ 1174 layer: e.target, 1175 propagatedFrom: e.target 1176 }, e), true); 1177 } 1178 } 1179}; 1180 1181// aliases; we should ditch those eventually 1182 1183// @method addEventListener(…): this 1184// Alias to [`on(…)`](#evented-on) 1185Events.addEventListener = Events.on; 1186 1187// @method removeEventListener(…): this 1188// Alias to [`off(…)`](#evented-off) 1189 1190// @method clearAllEventListeners(…): this 1191// Alias to [`off()`](#evented-off) 1192Events.removeEventListener = Events.clearAllEventListeners = Events.off; 1193 1194// @method addOneTimeEventListener(…): this 1195// Alias to [`once(…)`](#evented-once) 1196Events.addOneTimeEventListener = Events.once; 1197 1198// @method fireEvent(…): this 1199// Alias to [`fire(…)`](#evented-fire) 1200Events.fireEvent = Events.fire; 1201 1202// @method hasEventListeners(…): Boolean 1203// Alias to [`listens(…)`](#evented-listens) 1204Events.hasEventListeners = Events.listens; 1205 1206var Evented = Class.extend(Events); 1207 1208/* 1209 * @class Point 1210 * @aka L.Point 1211 * 1212 * Represents a point with `x` and `y` coordinates in pixels. 1213 * 1214 * @example 1215 * 1216 * ```js 1217 * var point = L.point(200, 300); 1218 * ``` 1219 * 1220 * 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: 1221 * 1222 * ```js 1223 * map.panBy([200, 300]); 1224 * map.panBy(L.point(200, 300)); 1225 * ``` 1226 * 1227 * Note that `Point` does not inherit from Leafet's `Class` object, 1228 * which means new classes can't inherit from it, and new methods 1229 * can't be added to it with the `include` function. 1230 */ 1231 1232function Point(x, y, round) { 1233 // @property x: Number; The `x` coordinate of the point 1234 this.x = (round ? Math.round(x) : x); 1235 // @property y: Number; The `y` coordinate of the point 1236 this.y = (round ? Math.round(y) : y); 1237} 1238 1239var trunc = Math.trunc || function (v) { 1240 return v > 0 ? Math.floor(v) : Math.ceil(v); 1241}; 1242 1243Point.prototype = { 1244 1245 // @method clone(): Point 1246 // Returns a copy of the current point. 1247 clone: function () { 1248 return new Point(this.x, this.y); 1249 }, 1250 1251 // @method add(otherPoint: Point): Point 1252 // Returns the result of addition of the current and the given points. 1253 add: function (point) { 1254 // non-destructive, returns a new point 1255 return this.clone()._add(toPoint(point)); 1256 }, 1257 1258 _add: function (point) { 1259 // destructive, used directly for performance in situations where it's safe to modify existing point 1260 this.x += point.x; 1261 this.y += point.y; 1262 return this; 1263 }, 1264 1265 // @method subtract(otherPoint: Point): Point 1266 // Returns the result of subtraction of the given point from the current. 1267 subtract: function (point) { 1268 return this.clone()._subtract(toPoint(point)); 1269 }, 1270 1271 _subtract: function (point) { 1272 this.x -= point.x; 1273 this.y -= point.y; 1274 return this; 1275 }, 1276 1277 // @method divideBy(num: Number): Point 1278 // Returns the result of division of the current point by the given number. 1279 divideBy: function (num) { 1280 return this.clone()._divideBy(num); 1281 }, 1282 1283 _divideBy: function (num) { 1284 this.x /= num; 1285 this.y /= num; 1286 return this; 1287 }, 1288 1289 // @method multiplyBy(num: Number): Point 1290 // Returns the result of multiplication of the current point by the given number. 1291 multiplyBy: function (num) { 1292 return this.clone()._multiplyBy(num); 1293 }, 1294 1295 _multiplyBy: function (num) { 1296 this.x *= num; 1297 this.y *= num; 1298 return this; 1299 }, 1300 1301 // @method scaleBy(scale: Point): Point 1302 // Multiply each coordinate of the current point by each coordinate of 1303 // `scale`. In linear algebra terms, multiply the point by the 1304 // [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation) 1305 // defined by `scale`. 1306 scaleBy: function (point) { 1307 return new Point(this.x * point.x, this.y * point.y); 1308 }, 1309 1310 // @method unscaleBy(scale: Point): Point 1311 // Inverse of `scaleBy`. Divide each coordinate of the current point by 1312 // each coordinate of `scale`. 1313 unscaleBy: function (point) { 1314 return new Point(this.x / point.x, this.y / point.y); 1315 }, 1316 1317 // @method round(): Point 1318 // Returns a copy of the current point with rounded coordinates. 1319 round: function () { 1320 return this.clone()._round(); 1321 }, 1322 1323 _round: function () { 1324 this.x = Math.round(this.x); 1325 this.y = Math.round(this.y); 1326 return this; 1327 }, 1328 1329 // @method floor(): Point 1330 // Returns a copy of the current point with floored coordinates (rounded down). 1331 floor: function () { 1332 return this.clone()._floor(); 1333 }, 1334 1335 _floor: function () { 1336 this.x = Math.floor(this.x); 1337 this.y = Math.floor(this.y); 1338 return this; 1339 }, 1340 1341 // @method ceil(): Point 1342 // Returns a copy of the current point with ceiled coordinates (rounded up). 1343 ceil: function () { 1344 return this.clone()._ceil(); 1345 }, 1346 1347 _ceil: function () { 1348 this.x = Math.ceil(this.x); 1349 this.y = Math.ceil(this.y); 1350 return this; 1351 }, 1352 1353 // @method trunc(): Point 1354 // Returns a copy of the current point with truncated coordinates (rounded towards zero). 1355 trunc: function () { 1356 return this.clone()._trunc(); 1357 }, 1358 1359 _trunc: function () { 1360 this.x = trunc(this.x); 1361 this.y = trunc(this.y); 1362 return this; 1363 }, 1364 1365 // @method distanceTo(otherPoint: Point): Number 1366 // Returns the cartesian distance between the current and the given points. 1367 distanceTo: function (point) { 1368 point = toPoint(point); 1369 1370 var x = point.x - this.x, 1371 y = point.y - this.y; 1372 1373 return Math.sqrt(x * x + y * y); 1374 }, 1375 1376 // @method equals(otherPoint: Point): Boolean 1377 // Returns `true` if the given point has the same coordinates. 1378 equals: function (point) { 1379 point = toPoint(point); 1380 1381 return point.x === this.x && 1382 point.y === this.y; 1383 }, 1384 1385 // @method contains(otherPoint: Point): Boolean 1386 // Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values). 1387 contains: function (point) { 1388 point = toPoint(point); 1389 1390 return Math.abs(point.x) <= Math.abs(this.x) && 1391 Math.abs(point.y) <= Math.abs(this.y); 1392 }, 1393 1394 // @method toString(): String 1395 // Returns a string representation of the point for debugging purposes. 1396 toString: function () { 1397 return 'Point(' + 1398 formatNum(this.x) + ', ' + 1399 formatNum(this.y) + ')'; 1400 } 1401}; 1402 1403// @factory L.point(x: Number, y: Number, round?: Boolean) 1404// Creates a Point object with the given `x` and `y` coordinates. If optional `round` is set to true, rounds the `x` and `y` values. 1405 1406// @alternative 1407// @factory L.point(coords: Number[]) 1408// Expects an array of the form `[x, y]` instead. 1409 1410// @alternative 1411// @factory L.point(coords: Object) 1412// Expects a plain object of the form `{x: Number, y: Number}` instead. 1413function toPoint(x, y, round) { 1414 if (x instanceof Point) { 1415 return x; 1416 } 1417 if (isArray(x)) { 1418 return new Point(x[0], x[1]); 1419 } 1420 if (x === undefined || x === null) { 1421 return x; 1422 } 1423 if (typeof x === 'object' && 'x' in x && 'y' in x) { 1424 return new Point(x.x, x.y); 1425 } 1426 return new Point(x, y, round); 1427} 1428 1429/* 1430 * @class Bounds 1431 * @aka L.Bounds 1432 * 1433 * Represents a rectangular area in pixel coordinates. 1434 * 1435 * @example 1436 * 1437 * ```js 1438 * var p1 = L.point(10, 10), 1439 * p2 = L.point(40, 60), 1440 * bounds = L.bounds(p1, p2); 1441 * ``` 1442 * 1443 * 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: 1444 * 1445 * ```js 1446 * otherBounds.intersects([[10, 10], [40, 60]]); 1447 * ``` 1448 * 1449 * Note that `Bounds` does not inherit from Leafet's `Class` object, 1450 * which means new classes can't inherit from it, and new methods 1451 * can't be added to it with the `include` function. 1452 */ 1453 1454function Bounds(a, b) { 1455 if (!a) { return; } 1456 1457 var points = b ? [a, b] : a; 1458 1459 for (var i = 0, len = points.length; i < len; i++) { 1460 this.extend(points[i]); 1461 } 1462} 1463 1464Bounds.prototype = { 1465 // @method extend(point: Point): this 1466 // Extends the bounds to contain the given point. 1467 extend: function (point) { // (Point) 1468 point = toPoint(point); 1469 1470 // @property min: Point 1471 // The top left corner of the rectangle. 1472 // @property max: Point 1473 // The bottom right corner of the rectangle. 1474 if (!this.min && !this.max) { 1475 this.min = point.clone(); 1476 this.max = point.clone(); 1477 } else { 1478 this.min.x = Math.min(point.x, this.min.x); 1479 this.max.x = Math.max(point.x, this.max.x); 1480 this.min.y = Math.min(point.y, this.min.y); 1481 this.max.y = Math.max(point.y, this.max.y); 1482 } 1483 return this; 1484 }, 1485 1486 // @method getCenter(round?: Boolean): Point 1487 // Returns the center point of the bounds. 1488 getCenter: function (round) { 1489 return new Point( 1490 (this.min.x + this.max.x) / 2, 1491 (this.min.y + this.max.y) / 2, round); 1492 }, 1493 1494 // @method getBottomLeft(): Point 1495 // Returns the bottom-left point of the bounds. 1496 getBottomLeft: function () { 1497 return new Point(this.min.x, this.max.y); 1498 }, 1499 1500 // @method getTopRight(): Point 1501 // Returns the top-right point of the bounds. 1502 getTopRight: function () { // -> Point 1503 return new Point(this.max.x, this.min.y); 1504 }, 1505 1506 // @method getTopLeft(): Point 1507 // Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)). 1508 getTopLeft: function () { 1509 return this.min; // left, top 1510 }, 1511 1512 // @method getBottomRight(): Point 1513 // Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)). 1514 getBottomRight: function () { 1515 return this.max; // right, bottom 1516 }, 1517 1518 // @method getSize(): Point 1519 // Returns the size of the given bounds 1520 getSize: function () { 1521 return this.max.subtract(this.min); 1522 }, 1523 1524 // @method contains(otherBounds: Bounds): Boolean 1525 // Returns `true` if the rectangle contains the given one. 1526 // @alternative 1527 // @method contains(point: Point): Boolean 1528 // Returns `true` if the rectangle contains the given point. 1529 contains: function (obj) { 1530 var min, max; 1531 1532 if (typeof obj[0] === 'number' || obj instanceof Point) { 1533 obj = toPoint(obj); 1534 } else { 1535 obj = toBounds(obj); 1536 } 1537 1538 if (obj instanceof Bounds) { 1539 min = obj.min; 1540 max = obj.max; 1541 } else { 1542 min = max = obj; 1543 } 1544 1545 return (min.x >= this.min.x) && 1546 (max.x <= this.max.x) && 1547 (min.y >= this.min.y) && 1548 (max.y <= this.max.y); 1549 }, 1550 1551 // @method intersects(otherBounds: Bounds): Boolean 1552 // Returns `true` if the rectangle intersects the given bounds. Two bounds 1553 // intersect if they have at least one point in common. 1554 intersects: function (bounds) { // (Bounds) -> Boolean 1555 bounds = toBounds(bounds); 1556 1557 var min = this.min, 1558 max = this.max, 1559 min2 = bounds.min, 1560 max2 = bounds.max, 1561 xIntersects = (max2.x >= min.x) && (min2.x <= max.x), 1562 yIntersects = (max2.y >= min.y) && (min2.y <= max.y); 1563 1564 return xIntersects && yIntersects; 1565 }, 1566 1567 // @method overlaps(otherBounds: Bounds): Boolean 1568 // Returns `true` if the rectangle overlaps the given bounds. Two bounds 1569 // overlap if their intersection is an area. 1570 overlaps: function (bounds) { // (Bounds) -> Boolean 1571 bounds = toBounds(bounds); 1572 1573 var min = this.min, 1574 max = this.max, 1575 min2 = bounds.min, 1576 max2 = bounds.max, 1577 xOverlaps = (max2.x > min.x) && (min2.x < max.x), 1578 yOverlaps = (max2.y > min.y) && (min2.y < max.y); 1579 1580 return xOverlaps && yOverlaps; 1581 }, 1582 1583 isValid: function () { 1584 return !!(this.min && this.max); 1585 } 1586}; 1587 1588 1589// @factory L.bounds(corner1: Point, corner2: Point) 1590// Creates a Bounds object from two corners coordinate pairs. 1591// @alternative 1592// @factory L.bounds(points: Point[]) 1593// Creates a Bounds object from the given array of points. 1594function toBounds(a, b) { 1595 if (!a || a instanceof Bounds) { 1596 return a; 1597 } 1598 return new Bounds(a, b); 1599} 1600 1601/* 1602 * @class LatLngBounds 1603 * @aka L.LatLngBounds 1604 * 1605 * Represents a rectangular geographical area on a map. 1606 * 1607 * @example 1608 * 1609 * ```js 1610 * var corner1 = L.latLng(40.712, -74.227), 1611 * corner2 = L.latLng(40.774, -74.125), 1612 * bounds = L.latLngBounds(corner1, corner2); 1613 * ``` 1614 * 1615 * 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: 1616 * 1617 * ```js 1618 * map.fitBounds([ 1619 * [40.712, -74.227], 1620 * [40.774, -74.125] 1621 * ]); 1622 * ``` 1623 * 1624 * 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. 1625 * 1626 * Note that `LatLngBounds` does not inherit from Leafet's `Class` object, 1627 * which means new classes can't inherit from it, and new methods 1628 * can't be added to it with the `include` function. 1629 */ 1630 1631function LatLngBounds(corner1, corner2) { // (LatLng, LatLng) or (LatLng[]) 1632 if (!corner1) { return; } 1633 1634 var latlngs = corner2 ? [corner1, corner2] : corner1; 1635 1636 for (var i = 0, len = latlngs.length; i < len; i++) { 1637 this.extend(latlngs[i]); 1638 } 1639} 1640 1641LatLngBounds.prototype = { 1642 1643 // @method extend(latlng: LatLng): this 1644 // Extend the bounds to contain the given point 1645 1646 // @alternative 1647 // @method extend(otherBounds: LatLngBounds): this 1648 // Extend the bounds to contain the given bounds 1649 extend: function (obj) { 1650 var sw = this._southWest, 1651 ne = this._northEast, 1652 sw2, ne2; 1653 1654 if (obj instanceof LatLng) { 1655 sw2 = obj; 1656 ne2 = obj; 1657 1658 } else if (obj instanceof LatLngBounds) { 1659 sw2 = obj._southWest; 1660 ne2 = obj._northEast; 1661 1662 if (!sw2 || !ne2) { return this; } 1663 1664 } else { 1665 return obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this; 1666 } 1667 1668 if (!sw && !ne) { 1669 this._southWest = new LatLng(sw2.lat, sw2.lng); 1670 this._northEast = new LatLng(ne2.lat, ne2.lng); 1671 } else { 1672 sw.lat = Math.min(sw2.lat, sw.lat); 1673 sw.lng = Math.min(sw2.lng, sw.lng); 1674 ne.lat = Math.max(ne2.lat, ne.lat); 1675 ne.lng = Math.max(ne2.lng, ne.lng); 1676 } 1677 1678 return this; 1679 }, 1680 1681 // @method pad(bufferRatio: Number): LatLngBounds 1682 // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction. 1683 // For example, a ratio of 0.5 extends the bounds by 50% in each direction. 1684 // Negative values will retract the bounds. 1685 pad: function (bufferRatio) { 1686 var sw = this._southWest, 1687 ne = this._northEast, 1688 heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio, 1689 widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio; 1690 1691 return new LatLngBounds( 1692 new LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer), 1693 new LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer)); 1694 }, 1695 1696 // @method getCenter(): LatLng 1697 // Returns the center point of the bounds. 1698 getCenter: function () { 1699 return new LatLng( 1700 (this._southWest.lat + this._northEast.lat) / 2, 1701 (this._southWest.lng + this._northEast.lng) / 2); 1702 }, 1703 1704 // @method getSouthWest(): LatLng 1705 // Returns the south-west point of the bounds. 1706 getSouthWest: function () { 1707 return this._southWest; 1708 }, 1709 1710 // @method getNorthEast(): LatLng 1711 // Returns the north-east point of the bounds. 1712 getNorthEast: function () { 1713 return this._northEast; 1714 }, 1715 1716 // @method getNorthWest(): LatLng 1717 // Returns the north-west point of the bounds. 1718 getNorthWest: function () { 1719 return new LatLng(this.getNorth(), this.getWest()); 1720 }, 1721 1722 // @method getSouthEast(): LatLng 1723 // Returns the south-east point of the bounds. 1724 getSouthEast: function () { 1725 return new LatLng(this.getSouth(), this.getEast()); 1726 }, 1727 1728 // @method getWest(): Number 1729 // Returns the west longitude of the bounds 1730 getWest: function () { 1731 return this._southWest.lng; 1732 }, 1733 1734 // @method getSouth(): Number 1735 // Returns the south latitude of the bounds 1736 getSouth: function () { 1737 return this._southWest.lat; 1738 }, 1739 1740 // @method getEast(): Number 1741 // Returns the east longitude of the bounds 1742 getEast: function () { 1743 return this._northEast.lng; 1744 }, 1745 1746 // @method getNorth(): Number 1747 // Returns the north latitude of the bounds 1748 getNorth: function () { 1749 return this._northEast.lat; 1750 }, 1751 1752 // @method contains(otherBounds: LatLngBounds): Boolean 1753 // Returns `true` if the rectangle contains the given one. 1754 1755 // @alternative 1756 // @method contains (latlng: LatLng): Boolean 1757 // Returns `true` if the rectangle contains the given point. 1758 contains: function (obj) { // (LatLngBounds) or (LatLng) -> Boolean 1759 if (typeof obj[0] === 'number' || obj instanceof LatLng || 'lat' in obj) { 1760 obj = toLatLng(obj); 1761 } else { 1762 obj = toLatLngBounds(obj); 1763 } 1764 1765 var sw = this._southWest, 1766 ne = this._northEast, 1767 sw2, ne2; 1768 1769 if (obj instanceof LatLngBounds) { 1770 sw2 = obj.getSouthWest(); 1771 ne2 = obj.getNorthEast(); 1772 } else { 1773 sw2 = ne2 = obj; 1774 } 1775 1776 return (sw2.lat >= sw.lat) && (ne2.lat <= ne.lat) && 1777 (sw2.lng >= sw.lng) && (ne2.lng <= ne.lng); 1778 }, 1779 1780 // @method intersects(otherBounds: LatLngBounds): Boolean 1781 // Returns `true` if the rectangle intersects the given bounds. Two bounds intersect if they have at least one point in common. 1782 intersects: function (bounds) { 1783 bounds = toLatLngBounds(bounds); 1784 1785 var sw = this._southWest, 1786 ne = this._northEast, 1787 sw2 = bounds.getSouthWest(), 1788 ne2 = bounds.getNorthEast(), 1789 1790 latIntersects = (ne2.lat >= sw.lat) && (sw2.lat <= ne.lat), 1791 lngIntersects = (ne2.lng >= sw.lng) && (sw2.lng <= ne.lng); 1792 1793 return latIntersects && lngIntersects; 1794 }, 1795 1796 // @method overlaps(otherBounds: Bounds): Boolean 1797 // Returns `true` if the rectangle overlaps the given bounds. Two bounds overlap if their intersection is an area. 1798 overlaps: function (bounds) { 1799 bounds = toLatLngBounds(bounds); 1800 1801 var sw = this._southWest, 1802 ne = this._northEast, 1803 sw2 = bounds.getSouthWest(), 1804 ne2 = bounds.getNorthEast(), 1805 1806 latOverlaps = (ne2.lat > sw.lat) && (sw2.lat < ne.lat), 1807 lngOverlaps = (ne2.lng > sw.lng) && (sw2.lng < ne.lng); 1808 1809 return latOverlaps && lngOverlaps; 1810 }, 1811 1812 // @method toBBoxString(): String 1813 // 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. 1814 toBBoxString: function () { 1815 return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(','); 1816 }, 1817 1818 // @method equals(otherBounds: LatLngBounds, maxMargin?: Number): Boolean 1819 // 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. 1820 equals: function (bounds, maxMargin) { 1821 if (!bounds) { return false; } 1822 1823 bounds = toLatLngBounds(bounds); 1824 1825 return this._southWest.equals(bounds.getSouthWest(), maxMargin) && 1826 this._northEast.equals(bounds.getNorthEast(), maxMargin); 1827 }, 1828 1829 // @method isValid(): Boolean 1830 // Returns `true` if the bounds are properly initialized. 1831 isValid: function () { 1832 return !!(this._southWest && this._northEast); 1833 } 1834}; 1835 1836// TODO International date line? 1837 1838// @factory L.latLngBounds(corner1: LatLng, corner2: LatLng) 1839// Creates a `LatLngBounds` object by defining two diagonally opposite corners of the rectangle. 1840 1841// @alternative 1842// @factory L.latLngBounds(latlngs: LatLng[]) 1843// 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). 1844function toLatLngBounds(a, b) { 1845 if (a instanceof LatLngBounds) { 1846 return a; 1847 } 1848 return new LatLngBounds(a, b); 1849} 1850 1851/* @class LatLng 1852 * @aka L.LatLng 1853 * 1854 * Represents a geographical point with a certain latitude and longitude. 1855 * 1856 * @example 1857 * 1858 * ``` 1859 * var latlng = L.latLng(50.5, 30.5); 1860 * ``` 1861 * 1862 * 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: 1863 * 1864 * ``` 1865 * map.panTo([50, 30]); 1866 * map.panTo({lon: 30, lat: 50}); 1867 * map.panTo({lat: 50, lng: 30}); 1868 * map.panTo(L.latLng(50, 30)); 1869 * ``` 1870 * 1871 * Note that `LatLng` does not inherit from Leaflet's `Class` object, 1872 * which means new classes can't inherit from it, and new methods 1873 * can't be added to it with the `include` function. 1874 */ 1875 1876function LatLng(lat, lng, alt) { 1877 if (isNaN(lat) || isNaN(lng)) { 1878 throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')'); 1879 } 1880 1881 // @property lat: Number 1882 // Latitude in degrees 1883 this.lat = +lat; 1884 1885 // @property lng: Number 1886 // Longitude in degrees 1887 this.lng = +lng; 1888 1889 // @property alt: Number 1890 // Altitude in meters (optional) 1891 if (alt !== undefined) { 1892 this.alt = +alt; 1893 } 1894} 1895 1896LatLng.prototype = { 1897 // @method equals(otherLatLng: LatLng, maxMargin?: Number): Boolean 1898 // 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. 1899 equals: function (obj, maxMargin) { 1900 if (!obj) { return false; } 1901 1902 obj = toLatLng(obj); 1903 1904 var margin = Math.max( 1905 Math.abs(this.lat - obj.lat), 1906 Math.abs(this.lng - obj.lng)); 1907 1908 return margin <= (maxMargin === undefined ? 1.0E-9 : maxMargin); 1909 }, 1910 1911 // @method toString(): String 1912 // Returns a string representation of the point (for debugging purposes). 1913 toString: function (precision) { 1914 return 'LatLng(' + 1915 formatNum(this.lat, precision) + ', ' + 1916 formatNum(this.lng, precision) + ')'; 1917 }, 1918 1919 // @method distanceTo(otherLatLng: LatLng): Number 1920 // 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). 1921 distanceTo: function (other) { 1922 return Earth.distance(this, toLatLng(other)); 1923 }, 1924 1925 // @method wrap(): LatLng 1926 // Returns a new `LatLng` object with the longitude wrapped so it's always between -180 and +180 degrees. 1927 wrap: function () { 1928 return Earth.wrapLatLng(this); 1929 }, 1930 1931 // @method toBounds(sizeInMeters: Number): LatLngBounds 1932 // Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`. 1933 toBounds: function (sizeInMeters) { 1934 var latAccuracy = 180 * sizeInMeters / 40075017, 1935 lngAccuracy = latAccuracy / Math.cos((Math.PI / 180) * this.lat); 1936 1937 return toLatLngBounds( 1938 [this.lat - latAccuracy, this.lng - lngAccuracy], 1939 [this.lat + latAccuracy, this.lng + lngAccuracy]); 1940 }, 1941 1942 clone: function () { 1943 return new LatLng(this.lat, this.lng, this.alt); 1944 } 1945}; 1946 1947 1948 1949// @factory L.latLng(latitude: Number, longitude: Number, altitude?: Number): LatLng 1950// Creates an object representing a geographical point with the given latitude and longitude (and optionally altitude). 1951 1952// @alternative 1953// @factory L.latLng(coords: Array): LatLng 1954// Expects an array of the form `[Number, Number]` or `[Number, Number, Number]` instead. 1955 1956// @alternative 1957// @factory L.latLng(coords: Object): LatLng 1958// Expects an plain object of the form `{lat: Number, lng: Number}` or `{lat: Number, lng: Number, alt: Number}` instead. 1959 1960function toLatLng(a, b, c) { 1961 if (a instanceof LatLng) { 1962 return a; 1963 } 1964 if (isArray(a) && typeof a[0] !== 'object') { 1965 if (a.length === 3) { 1966 return new LatLng(a[0], a[1], a[2]); 1967 } 1968 if (a.length === 2) { 1969 return new LatLng(a[0], a[1]); 1970 } 1971 return null; 1972 } 1973 if (a === undefined || a === null) { 1974 return a; 1975 } 1976 if (typeof a === 'object' && 'lat' in a) { 1977 return new LatLng(a.lat, 'lng' in a ? a.lng : a.lon, a.alt); 1978 } 1979 if (b === undefined) { 1980 return null; 1981 } 1982 return new LatLng(a, b, c); 1983} 1984 1985/* 1986 * @namespace CRS 1987 * @crs L.CRS.Base 1988 * Object that defines coordinate reference systems for projecting 1989 * geographical points into pixel (screen) coordinates and back (and to 1990 * coordinates in other units for [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services). See 1991 * [spatial reference system](http://en.wikipedia.org/wiki/Coordinate_reference_system). 1992 * 1993 * Leaflet defines the most usual CRSs by default. If you want to use a 1994 * CRS not defined by default, take a look at the 1995 * [Proj4Leaflet](https://github.com/kartena/Proj4Leaflet) plugin. 1996 * 1997 * Note that the CRS instances do not inherit from Leafet's `Class` object, 1998 * and can't be instantiated. Also, new classes can't inherit from them, 1999 * and methods can't be added to them with the `include` function. 2000 */ 2001 2002var CRS = { 2003 // @method latLngToPoint(latlng: LatLng, zoom: Number): Point 2004 // Projects geographical coordinates into pixel coordinates for a given zoom. 2005 latLngToPoint: function (latlng, zoom) { 2006 var projectedPoint = this.projection.project(latlng), 2007 scale = this.scale(zoom); 2008 2009 return this.transformation._transform(projectedPoint, scale); 2010 }, 2011 2012 // @method pointToLatLng(point: Point, zoom: Number): LatLng 2013 // The inverse of `latLngToPoint`. Projects pixel coordinates on a given 2014 // zoom into geographical coordinates. 2015 pointToLatLng: function (point, zoom) { 2016 var scale = this.scale(zoom), 2017 untransformedPoint = this.transformation.untransform(point, scale); 2018 2019 return this.projection.unproject(untransformedPoint); 2020 }, 2021 2022 // @method project(latlng: LatLng): Point 2023 // Projects geographical coordinates into coordinates in units accepted for 2024 // this CRS (e.g. meters for EPSG:3857, for passing it to WMS services). 2025 project: function (latlng) { 2026 return this.projection.project(latlng); 2027 }, 2028 2029 // @method unproject(point: Point): LatLng 2030 // Given a projected coordinate returns the corresponding LatLng. 2031 // The inverse of `project`. 2032 unproject: function (point) { 2033 return this.projection.unproject(point); 2034 }, 2035 2036 // @method scale(zoom: Number): Number 2037 // Returns the scale used when transforming projected coordinates into 2038 // pixel coordinates for a particular zoom. For example, it returns 2039 // `256 * 2^zoom` for Mercator-based CRS. 2040 scale: function (zoom) { 2041 return 256 * Math.pow(2, zoom); 2042 }, 2043 2044 // @method zoom(scale: Number): Number 2045 // Inverse of `scale()`, returns the zoom level corresponding to a scale 2046 // factor of `scale`. 2047 zoom: function (scale) { 2048 return Math.log(scale / 256) / Math.LN2; 2049 }, 2050 2051 // @method getProjectedBounds(zoom: Number): Bounds 2052 // Returns the projection's bounds scaled and transformed for the provided `zoom`. 2053 getProjectedBounds: function (zoom) { 2054 if (this.infinite) { return null; } 2055 2056 var b = this.projection.bounds, 2057 s = this.scale(zoom), 2058 min = this.transformation.transform(b.min, s), 2059 max = this.transformation.transform(b.max, s); 2060 2061 return new Bounds(min, max); 2062 }, 2063 2064 // @method distance(latlng1: LatLng, latlng2: LatLng): Number 2065 // Returns the distance between two geographical coordinates. 2066 2067 // @property code: String 2068 // Standard code name of the CRS passed into WMS services (e.g. `'EPSG:3857'`) 2069 // 2070 // @property wrapLng: Number[] 2071 // An array of two numbers defining whether the longitude (horizontal) coordinate 2072 // axis wraps around a given range and how. Defaults to `[-180, 180]` in most 2073 // geographical CRSs. If `undefined`, the longitude axis does not wrap around. 2074 // 2075 // @property wrapLat: Number[] 2076 // Like `wrapLng`, but for the latitude (vertical) axis. 2077 2078 // wrapLng: [min, max], 2079 // wrapLat: [min, max], 2080 2081 // @property infinite: Boolean 2082 // If true, the coordinate space will be unbounded (infinite in both axes) 2083 infinite: false, 2084 2085 // @method wrapLatLng(latlng: LatLng): LatLng 2086 // Returns a `LatLng` where lat and lng has been wrapped according to the 2087 // CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds. 2088 wrapLatLng: function (latlng) { 2089 var lng = this.wrapLng ? wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng, 2090 lat = this.wrapLat ? wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat, 2091 alt = latlng.alt; 2092 2093 return new LatLng(lat, lng, alt); 2094 }, 2095 2096 // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds 2097 // Returns a `LatLngBounds` with the same size as the given one, ensuring 2098 // that its center is within the CRS's bounds. 2099 // Only accepts actual `L.LatLngBounds` instances, not arrays. 2100 wrapLatLngBounds: function (bounds) { 2101 var center = bounds.getCenter(), 2102 newCenter = this.wrapLatLng(center), 2103 latShift = center.lat - newCenter.lat, 2104 lngShift = center.lng - newCenter.lng; 2105 2106 if (latShift === 0 && lngShift === 0) { 2107 return bounds; 2108 } 2109 2110 var sw = bounds.getSouthWest(), 2111 ne = bounds.getNorthEast(), 2112 newSw = new LatLng(sw.lat - latShift, sw.lng - lngShift), 2113 newNe = new LatLng(ne.lat - latShift, ne.lng - lngShift); 2114 2115 return new LatLngBounds(newSw, newNe); 2116 } 2117}; 2118 2119/* 2120 * @namespace CRS 2121 * @crs L.CRS.Earth 2122 * 2123 * Serves as the base for CRS that are global such that they cover the earth. 2124 * Can only be used as the base for other CRS and cannot be used directly, 2125 * since it does not have a `code`, `projection` or `transformation`. `distance()` returns 2126 * meters. 2127 */ 2128 2129var Earth = extend({}, CRS, { 2130 wrapLng: [-180, 180], 2131 2132 // Mean Earth Radius, as recommended for use by 2133 // the International Union of Geodesy and Geophysics, 2134 // see http://rosettacode.org/wiki/Haversine_formula 2135 R: 6371000, 2136 2137 // distance between two geographical points using spherical law of cosines approximation 2138 distance: function (latlng1, latlng2) { 2139 var rad = Math.PI / 180, 2140 lat1 = latlng1.lat * rad, 2141 lat2 = latlng2.lat * rad, 2142 sinDLat = Math.sin((latlng2.lat - latlng1.lat) * rad / 2), 2143 sinDLon = Math.sin((latlng2.lng - latlng1.lng) * rad / 2), 2144 a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon, 2145 c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 2146 return this.R * c; 2147 } 2148}); 2149 2150/* 2151 * @namespace Projection 2152 * @projection L.Projection.SphericalMercator 2153 * 2154 * Spherical Mercator projection — the most common projection for online maps, 2155 * used by almost all free and commercial tile providers. Assumes that Earth is 2156 * a sphere. Used by the `EPSG:3857` CRS. 2157 */ 2158 2159var earthRadius = 6378137; 2160 2161var SphericalMercator = { 2162 2163 R: earthRadius, 2164 MAX_LATITUDE: 85.0511287798, 2165 2166 project: function (latlng) { 2167 var d = Math.PI / 180, 2168 max = this.MAX_LATITUDE, 2169 lat = Math.max(Math.min(max, latlng.lat), -max), 2170 sin = Math.sin(lat * d); 2171 2172 return new Point( 2173 this.R * latlng.lng * d, 2174 this.R * Math.log((1 + sin) / (1 - sin)) / 2); 2175 }, 2176 2177 unproject: function (point) { 2178 var d = 180 / Math.PI; 2179 2180 return new LatLng( 2181 (2 * Math.atan(Math.exp(point.y / this.R)) - (Math.PI / 2)) * d, 2182 point.x * d / this.R); 2183 }, 2184 2185 bounds: (function () { 2186 var d = earthRadius * Math.PI; 2187 return new Bounds([-d, -d], [d, d]); 2188 })() 2189}; 2190 2191/* 2192 * @class Transformation 2193 * @aka L.Transformation 2194 * 2195 * Represents an affine transformation: a set of coefficients `a`, `b`, `c`, `d` 2196 * for transforming a point of a form `(x, y)` into `(a*x + b, c*y + d)` and doing 2197 * the reverse. Used by Leaflet in its projections code. 2198 * 2199 * @example 2200 * 2201 * ```js 2202 * var transformation = L.transformation(2, 5, -1, 10), 2203 * p = L.point(1, 2), 2204 * p2 = transformation.transform(p), // L.point(7, 8) 2205 * p3 = transformation.untransform(p2); // L.point(1, 2) 2206 * ``` 2207 */ 2208 2209 2210// factory new L.Transformation(a: Number, b: Number, c: Number, d: Number) 2211// Creates a `Transformation` object with the given coefficients. 2212function Transformation(a, b, c, d) { 2213 if (isArray(a)) { 2214 // use array properties 2215 this._a = a[0]; 2216 this._b = a[1]; 2217 this._c = a[2]; 2218 this._d = a[3]; 2219 return; 2220 } 2221 this._a = a; 2222 this._b = b; 2223 this._c = c; 2224 this._d = d; 2225} 2226 2227Transformation.prototype = { 2228 // @method transform(point: Point, scale?: Number): Point 2229 // Returns a transformed point, optionally multiplied by the given scale. 2230 // Only accepts actual `L.Point` instances, not arrays. 2231 transform: function (point, scale) { // (Point, Number) -> Point 2232 return this._transform(point.clone(), scale); 2233 }, 2234 2235 // destructive transform (faster) 2236 _transform: function (point, scale) { 2237 scale = scale || 1; 2238 point.x = scale * (this._a * point.x + this._b); 2239 point.y = scale * (this._c * point.y + this._d); 2240 return point; 2241 }, 2242 2243 // @method untransform(point: Point, scale?: Number): Point 2244 // Returns the reverse transformation of the given point, optionally divided 2245 // by the given scale. Only accepts actual `L.Point` instances, not arrays. 2246 untransform: function (point, scale) { 2247 scale = scale || 1; 2248 return new Point( 2249 (point.x / scale - this._b) / this._a, 2250 (point.y / scale - this._d) / this._c); 2251 } 2252}; 2253 2254// factory L.transformation(a: Number, b: Number, c: Number, d: Number) 2255 2256// @factory L.transformation(a: Number, b: Number, c: Number, d: Number) 2257// Instantiates a Transformation object with the given coefficients. 2258 2259// @alternative 2260// @factory L.transformation(coefficients: Array): Transformation 2261// Expects an coefficients array of the form 2262// `[a: Number, b: Number, c: Number, d: Number]`. 2263 2264function toTransformation(a, b, c, d) { 2265 return new Transformation(a, b, c, d); 2266} 2267 2268/* 2269 * @namespace CRS 2270 * @crs L.CRS.EPSG3857 2271 * 2272 * The most common CRS for online maps, used by almost all free and commercial 2273 * tile providers. Uses Spherical Mercator projection. Set in by default in 2274 * Map's `crs` option. 2275 */ 2276 2277var EPSG3857 = extend({}, Earth, { 2278 code: 'EPSG:3857', 2279 projection: SphericalMercator, 2280 2281 transformation: (function () { 2282 var scale = 0.5 / (Math.PI * SphericalMercator.R); 2283 return toTransformation(scale, 0.5, -scale, 0.5); 2284 }()) 2285}); 2286 2287var EPSG900913 = extend({}, EPSG3857, { 2288 code: 'EPSG:900913' 2289}); 2290 2291// @namespace SVG; @section 2292// There are several static functions which can be called without instantiating L.SVG: 2293 2294// @function create(name: String): SVGElement 2295// Returns a instance of [SVGElement](https://developer.mozilla.org/docs/Web/API/SVGElement), 2296// corresponding to the class name passed. For example, using 'line' will return 2297// an instance of [SVGLineElement](https://developer.mozilla.org/docs/Web/API/SVGLineElement). 2298function svgCreate(name) { 2299 return document.createElementNS('http://www.w3.org/2000/svg', name); 2300} 2301 2302// @function pointsToPath(rings: Point[], closed: Boolean): String 2303// Generates a SVG path string for multiple rings, with each ring turning 2304// into "M..L..L.." instructions 2305function pointsToPath(rings, closed) { 2306 var str = '', 2307 i, j, len, len2, points, p; 2308 2309 for (i = 0, len = rings.length; i < len; i++) { 2310 points = rings[i]; 2311 2312 for (j = 0, len2 = points.length; j < len2; j++) { 2313 p = points[j]; 2314 str += (j ? 'L' : 'M') + p.x + ' ' + p.y; 2315 } 2316 2317 // closes the ring for polygons; "x" is VML syntax 2318 str += closed ? (svg ? 'z' : 'x') : ''; 2319 } 2320 2321 // SVG complains about empty path strings 2322 return str || 'M0 0'; 2323} 2324 2325/* 2326 * @namespace Browser 2327 * @aka L.Browser 2328 * 2329 * A namespace with static properties for browser/feature detection used by Leaflet internally. 2330 * 2331 * @example 2332 * 2333 * ```js 2334 * if (L.Browser.ielt9) { 2335 * alert('Upgrade your browser, dude!'); 2336 * } 2337 * ``` 2338 */ 2339 2340var style$1 = document.documentElement.style; 2341 2342// @property ie: Boolean; `true` for all Internet Explorer versions (not Edge). 2343var ie = 'ActiveXObject' in window; 2344 2345// @property ielt9: Boolean; `true` for Internet Explorer versions less than 9. 2346var ielt9 = ie && !document.addEventListener; 2347 2348// @property edge: Boolean; `true` for the Edge web browser. 2349var edge = 'msLaunchUri' in navigator && !('documentMode' in document); 2350 2351// @property webkit: Boolean; 2352// `true` for webkit-based browsers like Chrome and Safari (including mobile versions). 2353var webkit = userAgentContains('webkit'); 2354 2355// @property android: Boolean 2356// `true` for any browser running on an Android platform. 2357var android = userAgentContains('android'); 2358 2359// @property android23: Boolean; `true` for browsers running on Android 2 or Android 3. 2360var android23 = userAgentContains('android 2') || userAgentContains('android 3'); 2361 2362/* See https://stackoverflow.com/a/17961266 for details on detecting stock Android */ 2363var webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); // also matches AppleWebKit 2364// @property androidStock: Boolean; `true` for the Android stock browser (i.e. not Chrome) 2365var androidStock = android && userAgentContains('Google') && webkitVer < 537 && !('AudioNode' in window); 2366 2367// @property opera: Boolean; `true` for the Opera browser 2368var opera = !!window.opera; 2369 2370// @property chrome: Boolean; `true` for the Chrome browser. 2371var chrome = userAgentContains('chrome'); 2372 2373// @property gecko: Boolean; `true` for gecko-based browsers like Firefox. 2374var gecko = userAgentContains('gecko') && !webkit && !opera && !ie; 2375 2376// @property safari: Boolean; `true` for the Safari browser. 2377var safari = !chrome && userAgentContains('safari'); 2378 2379var phantom = userAgentContains('phantom'); 2380 2381// @property opera12: Boolean 2382// `true` for the Opera browser supporting CSS transforms (version 12 or later). 2383var opera12 = 'OTransition' in style$1; 2384 2385// @property win: Boolean; `true` when the browser is running in a Windows platform 2386var win = navigator.platform.indexOf('Win') === 0; 2387 2388// @property ie3d: Boolean; `true` for all Internet Explorer versions supporting CSS transforms. 2389var ie3d = ie && ('transition' in style$1); 2390 2391// @property webkit3d: Boolean; `true` for webkit-based browsers supporting CSS transforms. 2392var webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23; 2393 2394// @property gecko3d: Boolean; `true` for gecko-based browsers supporting CSS transforms. 2395var gecko3d = 'MozPerspective' in style$1; 2396 2397// @property any3d: Boolean 2398// `true` for all browsers supporting CSS transforms. 2399var any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d) && !opera12 && !phantom; 2400 2401// @property mobile: Boolean; `true` for all browsers running in a mobile device. 2402var mobile = typeof orientation !== 'undefined' || userAgentContains('mobile'); 2403 2404// @property mobileWebkit: Boolean; `true` for all webkit-based browsers in a mobile device. 2405var mobileWebkit = mobile && webkit; 2406 2407// @property mobileWebkit3d: Boolean 2408// `true` for all webkit-based browsers in a mobile device supporting CSS transforms. 2409var mobileWebkit3d = mobile && webkit3d; 2410 2411// @property msPointer: Boolean 2412// `true` for browsers implementing the Microsoft touch events model (notably IE10). 2413var msPointer = !window.PointerEvent && window.MSPointerEvent; 2414 2415// @property pointer: Boolean 2416// `true` for all browsers supporting [pointer events](https://msdn.microsoft.com/en-us/library/dn433244%28v=vs.85%29.aspx). 2417var pointer = !!(window.PointerEvent || msPointer); 2418 2419// @property touch: Boolean 2420// `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events). 2421// This does not necessarily mean that the browser is running in a computer with 2422// a touchscreen, it only means that the browser is capable of understanding 2423// touch events. 2424var touch = !window.L_NO_TOUCH && (pointer || 'ontouchstart' in window || 2425 (window.DocumentTouch && document instanceof window.DocumentTouch)); 2426 2427// @property mobileOpera: Boolean; `true` for the Opera browser in a mobile device. 2428var mobileOpera = mobile && opera; 2429 2430// @property mobileGecko: Boolean 2431// `true` for gecko-based browsers running in a mobile device. 2432var mobileGecko = mobile && gecko; 2433 2434// @property retina: Boolean 2435// `true` for browsers on a high-resolution "retina" screen or on any screen when browser's display zoom is more than 100%. 2436var retina = (window.devicePixelRatio || (window.screen.deviceXDPI / window.screen.logicalXDPI)) > 1; 2437 2438 2439// @property canvas: Boolean 2440// `true` when the browser supports [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API). 2441var canvas = (function () { 2442 return !!document.createElement('canvas').getContext; 2443}()); 2444 2445// @property svg: Boolean 2446// `true` when the browser supports [SVG](https://developer.mozilla.org/docs/Web/SVG). 2447var svg = !!(document.createElementNS && svgCreate('svg').createSVGRect); 2448 2449// @property vml: Boolean 2450// `true` if the browser supports [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language). 2451var vml = !svg && (function () { 2452 try { 2453 var div = document.createElement('div'); 2454 div.innerHTML = '<v:shape adj="1"/>'; 2455 2456 var shape = div.firstChild; 2457 shape.style.behavior = 'url(#default#VML)'; 2458 2459 return shape && (typeof shape.adj === 'object'); 2460 2461 } catch (e) { 2462 return false; 2463 } 2464}()); 2465 2466 2467function userAgentContains(str) { 2468 return navigator.userAgent.toLowerCase().indexOf(str) >= 0; 2469} 2470 2471 2472var Browser = (Object.freeze || Object)({ 2473 ie: ie, 2474 ielt9: ielt9, 2475 edge: edge, 2476 webkit: webkit, 2477 android: android, 2478 android23: android23, 2479 androidStock: androidStock, 2480 opera: opera, 2481 chrome: chrome, 2482 gecko: gecko, 2483 safari: safari, 2484 phantom: phantom, 2485 opera12: opera12, 2486 win: win, 2487 ie3d: ie3d, 2488 webkit3d: webkit3d, 2489 gecko3d: gecko3d, 2490 any3d: any3d, 2491 mobile: mobile, 2492 mobileWebkit: mobileWebkit, 2493 mobileWebkit3d: mobileWebkit3d, 2494 msPointer: msPointer, 2495 pointer: pointer, 2496 touch: touch, 2497 mobileOpera: mobileOpera, 2498 mobileGecko: mobileGecko, 2499 retina: retina, 2500 canvas: canvas, 2501 svg: svg, 2502 vml: vml 2503}); 2504 2505/* 2506 * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices. 2507 */ 2508 2509 2510var POINTER_DOWN = msPointer ? 'MSPointerDown' : 'pointerdown'; 2511var POINTER_MOVE = msPointer ? 'MSPointerMove' : 'pointermove'; 2512var POINTER_UP = msPointer ? 'MSPointerUp' : 'pointerup'; 2513var POINTER_CANCEL = msPointer ? 'MSPointerCancel' : 'pointercancel'; 2514var TAG_WHITE_LIST = ['INPUT', 'SELECT', 'OPTION']; 2515 2516var _pointers = {}; 2517var _pointerDocListener = false; 2518 2519// DomEvent.DoubleTap needs to know about this 2520var _pointersCount = 0; 2521 2522// Provides a touch events wrapper for (ms)pointer events. 2523// ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890 2524 2525function addPointerListener(obj, type, handler, id) { 2526 if (type === 'touchstart') { 2527 _addPointerStart(obj, handler, id); 2528 2529 } else if (type === 'touchmove') { 2530 _addPointerMove(obj, handler, id); 2531 2532 } else if (type === 'touchend') { 2533 _addPointerEnd(obj, handler, id); 2534 } 2535 2536 return this; 2537} 2538 2539function removePointerListener(obj, type, id) { 2540 var handler = obj['_leaflet_' + type + id]; 2541 2542 if (type === 'touchstart') { 2543 obj.removeEventListener(POINTER_DOWN, handler, false); 2544 2545 } else if (type === 'touchmove') { 2546 obj.removeEventListener(POINTER_MOVE, handler, false); 2547 2548 } else if (type === 'touchend') { 2549 obj.removeEventListener(POINTER_UP, handler, false); 2550 obj.removeEventListener(POINTER_CANCEL, handler, false); 2551 } 2552 2553 return this; 2554} 2555 2556function _addPointerStart(obj, handler, id) { 2557 var onDown = bind(function (e) { 2558 if (e.pointerType !== 'mouse' && e.MSPOINTER_TYPE_MOUSE && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) { 2559 // In IE11, some touch events needs to fire for form controls, or 2560 // the controls will stop working. We keep a whitelist of tag names that 2561 // need these events. For other target tags, we prevent default on the event. 2562 if (TAG_WHITE_LIST.indexOf(e.target.tagName) < 0) { 2563 preventDefault(e); 2564 } else { 2565 return; 2566 } 2567 } 2568 2569 _handlePointer(e, handler); 2570 }); 2571 2572 obj['_leaflet_touchstart' + id] = onDown; 2573 obj.addEventListener(POINTER_DOWN, onDown, false); 2574 2575 // need to keep track of what pointers and how many are active to provide e.touches emulation 2576 if (!_pointerDocListener) { 2577 // we listen documentElement as any drags that end by moving the touch off the screen get fired there 2578 document.documentElement.addEventListener(POINTER_DOWN, _globalPointerDown, true); 2579 document.documentElement.addEventListener(POINTER_MOVE, _globalPointerMove, true); 2580 document.documentElement.addEventListener(POINTER_UP, _globalPointerUp, true); 2581 document.documentElement.addEventListener(POINTER_CANCEL, _globalPointerUp, true); 2582 2583 _pointerDocListener = true; 2584 } 2585} 2586 2587function _globalPointerDown(e) { 2588 _pointers[e.pointerId] = e; 2589 _pointersCount++; 2590} 2591 2592function _globalPointerMove(e) { 2593 if (_pointers[e.pointerId]) { 2594 _pointers[e.pointerId] = e; 2595 } 2596} 2597 2598function _globalPointerUp(e) { 2599 delete _pointers[e.pointerId]; 2600 _pointersCount--; 2601} 2602 2603function _handlePointer(e, handler) { 2604 e.touches = []; 2605 for (var i in _pointers) { 2606 e.touches.push(_pointers[i]); 2607 } 2608 e.changedTouches = [e]; 2609 2610 handler(e); 2611} 2612 2613function _addPointerMove(obj, handler, id) { 2614 var onMove = function (e) { 2615 // don't fire touch moves when mouse isn't down 2616 if ((e.pointerType === e.MSPOINTER_TYPE_MOUSE || e.pointerType === 'mouse') && e.buttons === 0) { return; } 2617 2618 _handlePointer(e, handler); 2619 }; 2620 2621 obj['_leaflet_touchmove' + id] = onMove; 2622 obj.addEventListener(POINTER_MOVE, onMove, false); 2623} 2624 2625function _addPointerEnd(obj, handler, id) { 2626 var onUp = function (e) { 2627 _handlePointer(e, handler); 2628 }; 2629 2630 obj['_leaflet_touchend' + id] = onUp; 2631 obj.addEventListener(POINTER_UP, onUp, false); 2632 obj.addEventListener(POINTER_CANCEL, onUp, false); 2633} 2634 2635/* 2636 * Extends the event handling code with double tap support for mobile browsers. 2637 */ 2638 2639var _touchstart = msPointer ? 'MSPointerDown' : pointer ? 'pointerdown' : 'touchstart'; 2640var _touchend = msPointer ? 'MSPointerUp' : pointer ? 'pointerup' : 'touchend'; 2641var _pre = '_leaflet_'; 2642 2643// inspired by Zepto touch code by Thomas Fuchs 2644function addDoubleTapListener(obj, handler, id) { 2645 var last, touch$$1, 2646 doubleTap = false, 2647 delay = 250; 2648 2649 function onTouchStart(e) { 2650 var count; 2651 2652 if (pointer) { 2653 if ((!edge) || e.pointerType === 'mouse') { return; } 2654 count = _pointersCount; 2655 } else { 2656 count = e.touches.length; 2657 } 2658 2659 if (count > 1) { return; } 2660 2661 var now = Date.now(), 2662 delta = now - (last || now); 2663 2664 touch$$1 = e.touches ? e.touches[0] : e; 2665 doubleTap = (delta > 0 && delta <= delay); 2666 last = now; 2667 } 2668 2669 function onTouchEnd(e) { 2670 if (doubleTap && !touch$$1.cancelBubble) { 2671 if (pointer) { 2672 if ((!edge) || e.pointerType === 'mouse') { return; } 2673 // work around .type being readonly with MSPointer* events 2674 var newTouch = {}, 2675 prop, i; 2676 2677 for (i in touch$$1) { 2678 prop = touch$$1[i]; 2679 newTouch[i] = prop && prop.bind ? prop.bind(touch$$1) : prop; 2680 } 2681 touch$$1 = newTouch; 2682 } 2683 touch$$1.type = 'dblclick'; 2684 touch$$1.button = 0; 2685 handler(touch$$1); 2686 last = null; 2687 } 2688 } 2689 2690 obj[_pre + _touchstart + id] = onTouchStart; 2691 obj[_pre + _touchend + id] = onTouchEnd; 2692 obj[_pre + 'dblclick' + id] = handler; 2693 2694 obj.addEventListener(_touchstart, onTouchStart, false); 2695 obj.addEventListener(_touchend, onTouchEnd, false); 2696 2697 // On some platforms (notably, chrome<55 on win10 + touchscreen + mouse), 2698 // the browser doesn't fire touchend/pointerup events but does fire 2699 // native dblclicks. See #4127. 2700 // Edge 14 also fires native dblclicks, but only for pointerType mouse, see #5180. 2701 obj.addEventListener('dblclick', handler, false); 2702 2703 return this; 2704} 2705 2706function removeDoubleTapListener(obj, id) { 2707 var touchstart = obj[_pre + _touchstart + id], 2708 touchend = obj[_pre + _touchend + id], 2709 dblclick = obj[_pre + 'dblclick' + id]; 2710 2711 obj.removeEventListener(_touchstart, touchstart, false); 2712 obj.removeEventListener(_touchend, touchend, false); 2713 if (!edge) { 2714 obj.removeEventListener('dblclick', dblclick, false); 2715 } 2716 2717 return this; 2718} 2719 2720/* 2721 * @namespace DomUtil 2722 * 2723 * Utility functions to work with the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) 2724 * tree, used by Leaflet internally. 2725 * 2726 * Most functions expecting or returning a `HTMLElement` also work for 2727 * SVG elements. The only difference is that classes refer to CSS classes 2728 * in HTML and SVG classes in SVG. 2729 */ 2730 2731 2732// @property TRANSFORM: String 2733// Vendor-prefixed transform style name (e.g. `'webkitTransform'` for WebKit). 2734var TRANSFORM = testProp( 2735 ['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform']); 2736 2737// webkitTransition comes first because some browser versions that drop vendor prefix don't do 2738// the same for the transitionend event, in particular the Android 4.1 stock browser 2739 2740// @property TRANSITION: String 2741// Vendor-prefixed transition style name. 2742var TRANSITION = testProp( 2743 ['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']); 2744 2745// @property TRANSITION_END: String 2746// Vendor-prefixed transitionend event name. 2747var TRANSITION_END = 2748 TRANSITION === 'webkitTransition' || TRANSITION === 'OTransition' ? TRANSITION + 'End' : 'transitionend'; 2749 2750 2751// @function get(id: String|HTMLElement): HTMLElement 2752// Returns an element given its DOM id, or returns the element itself 2753// if it was passed directly. 2754function get(id) { 2755 return typeof id === 'string' ? document.getElementById(id) : id; 2756} 2757 2758// @function getStyle(el: HTMLElement, styleAttrib: String): String 2759// Returns the value for a certain style attribute on an element, 2760// including computed values or values set through CSS. 2761function getStyle(el, style) { 2762 var value = el.style[style] || (el.currentStyle && el.currentStyle[style]); 2763 2764 if ((!value || value === 'auto') && document.defaultView) { 2765 var css = document.defaultView.getComputedStyle(el, null); 2766 value = css ? css[style] : null; 2767 } 2768 return value === 'auto' ? null : value; 2769} 2770 2771// @function create(tagName: String, className?: String, container?: HTMLElement): HTMLElement 2772// Creates an HTML element with `tagName`, sets its class to `className`, and optionally appends it to `container` element. 2773function create$1(tagName, className, container) { 2774 var el = document.createElement(tagName); 2775 el.className = className || ''; 2776 2777 if (container) { 2778 container.appendChild(el); 2779 } 2780 return el; 2781} 2782 2783// @function remove(el: HTMLElement) 2784// Removes `el` from its parent element 2785function remove(el) { 2786 var parent = el.parentNode; 2787 if (parent) { 2788 parent.removeChild(el); 2789 } 2790} 2791 2792// @function empty(el: HTMLElement) 2793// Removes all of `el`'s children elements from `el` 2794function empty(el) { 2795 while (el.firstChild) { 2796 el.removeChild(el.firstChild); 2797 } 2798} 2799 2800// @function toFront(el: HTMLElement) 2801// Makes `el` the last child of its parent, so it renders in front of the other children. 2802function toFront(el) { 2803 var parent = el.parentNode; 2804 if (parent && parent.lastChild !== el) { 2805 parent.appendChild(el); 2806 } 2807} 2808 2809// @function toBack(el: HTMLElement) 2810// Makes `el` the first child of its parent, so it renders behind the other children. 2811function toBack(el) { 2812 var parent = el.parentNode; 2813 if (parent && parent.firstChild !== el) { 2814 parent.insertBefore(el, parent.firstChild); 2815 } 2816} 2817 2818// @function hasClass(el: HTMLElement, name: String): Boolean 2819// Returns `true` if the element's class attribute contains `name`. 2820function hasClass(el, name) { 2821 if (el.classList !== undefined) { 2822 return el.classList.contains(name); 2823 } 2824 var className = getClass(el); 2825 return className.length > 0 && new RegExp('(^|\\s)' + name + '(\\s|$)').test(className); 2826} 2827 2828// @function addClass(el: HTMLElement, name: String) 2829// Adds `name` to the element's class attribute. 2830function addClass(el, name) { 2831 if (el.classList !== undefined) { 2832 var classes = splitWords(name); 2833 for (var i = 0, len = classes.length; i < len; i++) { 2834 el.classList.add(classes[i]); 2835 } 2836 } else if (!hasClass(el, name)) { 2837 var className = getClass(el); 2838 setClass(el, (className ? className + ' ' : '') + name); 2839 } 2840} 2841 2842// @function removeClass(el: HTMLElement, name: String) 2843// Removes `name` from the element's class attribute. 2844function removeClass(el, name) { 2845 if (el.classList !== undefined) { 2846 el.classList.remove(name); 2847 } else { 2848 setClass(el, trim((' ' + getClass(el) + ' ').replace(' ' + name + ' ', ' '))); 2849 } 2850} 2851 2852// @function setClass(el: HTMLElement, name: String) 2853// Sets the element's class. 2854function setClass(el, name) { 2855 if (el.className.baseVal === undefined) { 2856 el.className = name; 2857 } else { 2858 // in case of SVG element 2859 el.className.baseVal = name; 2860 } 2861} 2862 2863// @function getClass(el: HTMLElement): String 2864// Returns the element's class. 2865function getClass(el) { 2866 // Check if the element is an SVGElementInstance and use the correspondingElement instead 2867 // (Required for linked SVG elements in IE11.) 2868 if (el.correspondingElement) { 2869 el = el.correspondingElement; 2870 } 2871 return el.className.baseVal === undefined ? el.className : el.className.baseVal; 2872} 2873 2874// @function setOpacity(el: HTMLElement, opacity: Number) 2875// Set the opacity of an element (including old IE support). 2876// `opacity` must be a number from `0` to `1`. 2877function setOpacity(el, value) { 2878 if ('opacity' in el.style) { 2879 el.style.opacity = value; 2880 } else if ('filter' in el.style) { 2881 _setOpacityIE(el, value); 2882 } 2883} 2884 2885function _setOpacityIE(el, value) { 2886 var filter = false, 2887 filterName = 'DXImageTransform.Microsoft.Alpha'; 2888 2889 // filters collection throws an error if we try to retrieve a filter that doesn't exist 2890 try { 2891 filter = el.filters.item(filterName); 2892 } catch (e) { 2893 // don't set opacity to 1 if we haven't already set an opacity, 2894 // it isn't needed and breaks transparent pngs. 2895 if (value === 1) { return; } 2896 } 2897 2898 value = Math.round(value * 100); 2899 2900 if (filter) { 2901 filter.Enabled = (value !== 100); 2902 filter.Opacity = value; 2903 } else { 2904 el.style.filter += ' progid:' + filterName + '(opacity=' + value + ')'; 2905 } 2906} 2907 2908// @function testProp(props: String[]): String|false 2909// Goes through the array of style names and returns the first name 2910// that is a valid style name for an element. If no such name is found, 2911// it returns false. Useful for vendor-prefixed styles like `transform`. 2912function testProp(props) { 2913 var style = document.documentElement.style; 2914 2915 for (var i = 0; i < props.length; i++) { 2916 if (props[i] in style) { 2917 return props[i]; 2918 } 2919 } 2920 return false; 2921} 2922 2923// @function setTransform(el: HTMLElement, offset: Point, scale?: Number) 2924// Resets the 3D CSS transform of `el` so it is translated by `offset` pixels 2925// and optionally scaled by `scale`. Does not have an effect if the 2926// browser doesn't support 3D CSS transforms. 2927function setTransform(el, offset, scale) { 2928 var pos = offset || new Point(0, 0); 2929 2930 el.style[TRANSFORM] = 2931 (ie3d ? 2932 'translate(' + pos.x + 'px,' + pos.y + 'px)' : 2933 'translate3d(' + pos.x + 'px,' + pos.y + 'px,0)') + 2934 (scale ? ' scale(' + scale + ')' : ''); 2935} 2936 2937// @function setPosition(el: HTMLElement, position: Point) 2938// Sets the position of `el` to coordinates specified by `position`, 2939// using CSS translate or top/left positioning depending on the browser 2940// (used by Leaflet internally to position its layers). 2941function setPosition(el, point) { 2942 2943 /*eslint-disable */ 2944 el._leaflet_pos = point; 2945 /* eslint-enable */ 2946 2947 if (any3d) { 2948 setTransform(el, point); 2949 } else { 2950 el.style.left = point.x + 'px'; 2951 el.style.top = point.y + 'px'; 2952 } 2953} 2954 2955// @function getPosition(el: HTMLElement): Point 2956// Returns the coordinates of an element previously positioned with setPosition. 2957function getPosition(el) { 2958 // this method is only used for elements previously positioned using setPosition, 2959 // so it's safe to cache the position for performance 2960 2961 return el._leaflet_pos || new Point(0, 0); 2962} 2963 2964// @function disableTextSelection() 2965// Prevents the user from generating `selectstart` DOM events, usually generated 2966// when the user drags the mouse through a page with text. Used internally 2967// by Leaflet to override the behaviour of any click-and-drag interaction on 2968// the map. Affects drag interactions on the whole document. 2969 2970// @function enableTextSelection() 2971// Cancels the effects of a previous [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection). 2972var disableTextSelection; 2973var enableTextSelection; 2974var _userSelect; 2975if ('onselectstart' in document) { 2976 disableTextSelection = function () { 2977 on(window, 'selectstart', preventDefault); 2978 }; 2979 enableTextSelection = function () { 2980 off(window, 'selectstart', preventDefault); 2981 }; 2982} else { 2983 var userSelectProperty = testProp( 2984 ['userSelect', 'WebkitUserSelect', 'OUserSelect', 'MozUserSelect', 'msUserSelect']); 2985 2986 disableTextSelection = function () { 2987 if (userSelectProperty) { 2988 var style = document.documentElement.style; 2989 _userSelect = style[userSelectProperty]; 2990 style[userSelectProperty] = 'none'; 2991 } 2992 }; 2993 enableTextSelection = function () { 2994 if (userSelectProperty) { 2995 document.documentElement.style[userSelectProperty] = _userSelect; 2996 _userSelect = undefined; 2997 } 2998 }; 2999} 3000 3001// @function disableImageDrag() 3002// As [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection), but 3003// for `dragstart` DOM events, usually generated when the user drags an image. 3004function disableImageDrag() { 3005 on(window, 'dragstart', preventDefault); 3006} 3007 3008// @function enableImageDrag() 3009// Cancels the effects of a previous [`L.DomUtil.disableImageDrag`](#domutil-disabletextselection). 3010function enableImageDrag() { 3011 off(window, 'dragstart', preventDefault); 3012} 3013 3014var _outlineElement; 3015var _outlineStyle; 3016// @function preventOutline(el: HTMLElement) 3017// Makes the [outline](https://developer.mozilla.org/docs/Web/CSS/outline) 3018// of the element `el` invisible. Used internally by Leaflet to prevent 3019// focusable elements from displaying an outline when the user performs a 3020// drag interaction on them. 3021function preventOutline(element) { 3022 while (element.tabIndex === -1) { 3023 element = element.parentNode; 3024 } 3025 if (!element.style) { return; } 3026 restoreOutline(); 3027 _outlineElement = element; 3028 _outlineStyle = element.style.outline; 3029 element.style.outline = 'none'; 3030 on(window, 'keydown', restoreOutline); 3031} 3032 3033// @function restoreOutline() 3034// Cancels the effects of a previous [`L.DomUtil.preventOutline`](). 3035function restoreOutline() { 3036 if (!_outlineElement) { return; } 3037 _outlineElement.style.outline = _outlineStyle; 3038 _outlineElement = undefined; 3039 _outlineStyle = undefined; 3040 off(window, 'keydown', restoreOutline); 3041} 3042 3043// @function getSizedParentNode(el: HTMLElement): HTMLElement 3044// Finds the closest parent node which size (width and height) is not null. 3045function getSizedParentNode(element) { 3046 do { 3047 element = element.parentNode; 3048 } while ((!element.offsetWidth || !element.offsetHeight) && element !== document.body); 3049 return element; 3050} 3051 3052// @function getScale(el: HTMLElement): Object 3053// Computes the CSS scale currently applied on the element. 3054// Returns an object with `x` and `y` members as horizontal and vertical scales respectively, 3055// and `boundingClientRect` as the result of [`getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect). 3056function getScale(element) { 3057 var rect = element.getBoundingClientRect(); // Read-only in old browsers. 3058 3059 return { 3060 x: rect.width / element.offsetWidth || 1, 3061 y: rect.height / element.offsetHeight || 1, 3062 boundingClientRect: rect 3063 }; 3064} 3065 3066 3067var DomUtil = (Object.freeze || Object)({ 3068 TRANSFORM: TRANSFORM, 3069 TRANSITION: TRANSITION, 3070 TRANSITION_END: TRANSITION_END, 3071 get: get, 3072 getStyle: getStyle, 3073 create: create$1, 3074 remove: remove, 3075 empty: empty, 3076 toFront: toFront, 3077 toBack: toBack, 3078 hasClass: hasClass, 3079 addClass: addClass, 3080 removeClass: removeClass, 3081 setClass: setClass, 3082 getClass: getClass, 3083 setOpacity: setOpacity, 3084 testProp: testProp, 3085 setTransform: setTransform, 3086 setPosition: setPosition, 3087 getPosition: getPosition, 3088 disableTextSelection: disableTextSelection, 3089 enableTextSelection: enableTextSelection, 3090 disableImageDrag: disableImageDrag, 3091 enableImageDrag: enableImageDrag, 3092 preventOutline: preventOutline, 3093 restoreOutline: restoreOutline, 3094 getSizedParentNode: getSizedParentNode, 3095 getScale: getScale 3096}); 3097 3098/* 3099 * @namespace DomEvent 3100 * Utility functions to work with the [DOM events](https://developer.mozilla.org/docs/Web/API/Event), used by Leaflet internally. 3101 */ 3102 3103// Inspired by John Resig, Dean Edwards and YUI addEvent implementations. 3104 3105// @function on(el: HTMLElement, types: String, fn: Function, context?: Object): this 3106// Adds a listener function (`fn`) to a particular DOM event type of the 3107// element `el`. You can optionally specify the context of the listener 3108// (object the `this` keyword will point to). You can also pass several 3109// space-separated types (e.g. `'click dblclick'`). 3110 3111// @alternative 3112// @function on(el: HTMLElement, eventMap: Object, context?: Object): this 3113// Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}` 3114function on(obj, types, fn, context) { 3115 3116 if (typeof types === 'object') { 3117 for (var type in types) { 3118 addOne(obj, type, types[type], fn); 3119 } 3120 } else { 3121 types = splitWords(types); 3122 3123 for (var i = 0, len = types.length; i < len; i++) { 3124 addOne(obj, types[i], fn, context); 3125 } 3126 } 3127 3128 return this; 3129} 3130 3131var eventsKey = '_leaflet_events'; 3132 3133// @function off(el: HTMLElement, types: String, fn: Function, context?: Object): this 3134// Removes a previously added listener function. 3135// Note that if you passed a custom context to on, you must pass the same 3136// context to `off` in order to remove the listener. 3137 3138// @alternative 3139// @function off(el: HTMLElement, eventMap: Object, context?: Object): this 3140// Removes a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}` 3141function off(obj, types, fn, context) { 3142 3143 if (typeof types === 'object') { 3144 for (var type in types) { 3145 removeOne(obj, type, types[type], fn); 3146 } 3147 } else if (types) { 3148 types = splitWords(types); 3149 3150 for (var i = 0, len = types.length; i < len; i++) { 3151 removeOne(obj, types[i], fn, context); 3152 } 3153 } else { 3154 for (var j in obj[eventsKey]) { 3155 removeOne(obj, j, obj[eventsKey][j]); 3156 } 3157 delete obj[eventsKey]; 3158 } 3159 3160 return this; 3161} 3162 3163function addOne(obj, type, fn, context) { 3164 var id = type + stamp(fn) + (context ? '_' + stamp(context) : ''); 3165 3166 if (obj[eventsKey] && obj[eventsKey][id]) { return this; } 3167 3168 var handler = function (e) { 3169 return fn.call(context || obj, e || window.event); 3170 }; 3171 3172 var originalHandler = handler; 3173 3174 if (pointer && type.indexOf('touch') === 0) { 3175 // Needs DomEvent.Pointer.js 3176 addPointerListener(obj, type, handler, id); 3177 3178 } else if (touch && (type === 'dblclick') && addDoubleTapListener && 3179 !(pointer && chrome)) { 3180 // Chrome >55 does not need the synthetic dblclicks from addDoubleTapListener 3181 // See #5180 3182 addDoubleTapListener(obj, handler, id); 3183 3184 } else if ('addEventListener' in obj) { 3185 3186 if (type === 'mousewheel') { 3187 obj.addEventListener('onwheel' in obj ? 'wheel' : 'mousewheel', handler, false); 3188 3189 } else if ((type === 'mouseenter') || (type === 'mouseleave')) { 3190 handler = function (e) { 3191 e = e || window.event; 3192 if (isExternalTarget(obj, e)) { 3193 originalHandler(e); 3194 } 3195 }; 3196 obj.addEventListener(type === 'mouseenter' ? 'mouseover' : 'mouseout', handler, false); 3197 3198 } else { 3199 if (type === 'click' && android) { 3200 handler = function (e) { 3201 filterClick(e, originalHandler); 3202 }; 3203 } 3204 obj.addEventListener(type, handler, false); 3205 } 3206 3207 } else if ('attachEvent' in obj) { 3208 obj.attachEvent('on' + type, handler); 3209 } 3210 3211 obj[eventsKey] = obj[eventsKey] || {}; 3212 obj[eventsKey][id] = handler; 3213} 3214 3215function removeOne(obj, type, fn, context) { 3216 3217 var id = type + stamp(fn) + (context ? '_' + stamp(context) : ''), 3218 handler = obj[eventsKey] && obj[eventsKey][id]; 3219 3220 if (!handler) { return this; } 3221 3222 if (pointer && type.indexOf('touch') === 0) { 3223 removePointerListener(obj, type, id); 3224 3225 } else if (touch && (type === 'dblclick') && removeDoubleTapListener && 3226 !(pointer && chrome)) { 3227 removeDoubleTapListener(obj, id); 3228 3229 } else if ('removeEventListener' in obj) { 3230 3231 if (type === 'mousewheel') { 3232 obj.removeEventListener('onwheel' in obj ? 'wheel' : 'mousewheel', handler, false); 3233 3234 } else { 3235 obj.removeEventListener( 3236 type === 'mouseenter' ? 'mouseover' : 3237 type === 'mouseleave' ? 'mouseout' : type, handler, false); 3238 } 3239 3240 } else if ('detachEvent' in obj) { 3241 obj.detachEvent('on' + type, handler); 3242 } 3243 3244 obj[eventsKey][id] = null; 3245} 3246 3247// @function stopPropagation(ev: DOMEvent): this 3248// Stop the given event from propagation to parent elements. Used inside the listener functions: 3249// ```js 3250// L.DomEvent.on(div, 'click', function (ev) { 3251// L.DomEvent.stopPropagation(ev); 3252// }); 3253// ``` 3254function stopPropagation(e) { 3255 3256 if (e.stopPropagation) { 3257 e.stopPropagation(); 3258 } else if (e.originalEvent) { // In case of Leaflet event. 3259 e.originalEvent._stopped = true; 3260 } else { 3261 e.cancelBubble = true; 3262 } 3263 skipped(e); 3264 3265 return this; 3266} 3267 3268// @function disableScrollPropagation(el: HTMLElement): this 3269// Adds `stopPropagation` to the element's `'mousewheel'` events (plus browser variants). 3270function disableScrollPropagation(el) { 3271 addOne(el, 'mousewheel', stopPropagation); 3272 return this; 3273} 3274 3275// @function disableClickPropagation(el: HTMLElement): this 3276// Adds `stopPropagation` to the element's `'click'`, `'doubleclick'`, 3277// `'mousedown'` and `'touchstart'` events (plus browser variants). 3278function disableClickPropagation(el) { 3279 on(el, 'mousedown touchstart dblclick', stopPropagation); 3280 addOne(el, 'click', fakeStop); 3281 return this; 3282} 3283 3284// @function preventDefault(ev: DOMEvent): this 3285// Prevents the default action of the DOM Event `ev` from happening (such as 3286// following a link in the href of the a element, or doing a POST request 3287// with page reload when a `<form>` is submitted). 3288// Use it inside listener functions. 3289function preventDefault(e) { 3290 if (e.preventDefault) { 3291 e.preventDefault(); 3292 } else { 3293 e.returnValue = false; 3294 } 3295 return this; 3296} 3297 3298// @function stop(ev: DOMEvent): this 3299// Does `stopPropagation` and `preventDefault` at the same time. 3300function stop(e) { 3301 preventDefault(e); 3302 stopPropagation(e); 3303 return this; 3304} 3305 3306// @function getMousePosition(ev: DOMEvent, container?: HTMLElement): Point 3307// Gets normalized mouse position from a DOM event relative to the 3308// `container` (border excluded) or to the whole page if not specified. 3309function getMousePosition(e, container) { 3310 if (!container) { 3311 return new Point(e.clientX, e.clientY); 3312 } 3313 3314 var scale = getScale(container), 3315 offset = scale.boundingClientRect; // left and top values are in page scale (like the event clientX/Y) 3316 3317 return new Point( 3318 // offset.left/top values are in page scale (like clientX/Y), 3319 // whereas clientLeft/Top (border width) values are the original values (before CSS scale applies). 3320 (e.clientX - offset.left) / scale.x - container.clientLeft, 3321 (e.clientY - offset.top) / scale.y - container.clientTop 3322 ); 3323} 3324 3325// Chrome on Win scrolls double the pixels as in other platforms (see #4538), 3326// and Firefox scrolls device pixels, not CSS pixels 3327var wheelPxFactor = 3328 (win && chrome) ? 2 * window.devicePixelRatio : 3329 gecko ? window.devicePixelRatio : 1; 3330 3331// @function getWheelDelta(ev: DOMEvent): Number 3332// Gets normalized wheel delta from a mousewheel DOM event, in vertical 3333// pixels scrolled (negative if scrolling down). 3334// Events from pointing devices without precise scrolling are mapped to 3335// a best guess of 60 pixels. 3336function getWheelDelta(e) { 3337 return (edge) ? e.wheelDeltaY / 2 : // Don't trust window-geometry-based delta 3338 (e.deltaY && e.deltaMode === 0) ? -e.deltaY / wheelPxFactor : // Pixels 3339 (e.deltaY && e.deltaMode === 1) ? -e.deltaY * 20 : // Lines 3340 (e.deltaY && e.deltaMode === 2) ? -e.deltaY * 60 : // Pages 3341 (e.deltaX || e.deltaZ) ? 0 : // Skip horizontal/depth wheel events 3342 e.wheelDelta ? (e.wheelDeltaY || e.wheelDelta) / 2 : // Legacy IE pixels 3343 (e.detail && Math.abs(e.detail) < 32765) ? -e.detail * 20 : // Legacy Moz lines 3344 e.detail ? e.detail / -32765 * 60 : // Legacy Moz pages 3345 0; 3346} 3347 3348var skipEvents = {}; 3349 3350function fakeStop(e) { 3351 // fakes stopPropagation by setting a special event flag, checked/reset with skipped(e) 3352 skipEvents[e.type] = true; 3353} 3354 3355function skipped(e) { 3356 var events = skipEvents[e.type]; 3357 // reset when checking, as it's only used in map container and propagates outside of the map 3358 skipEvents[e.type] = false; 3359 return events; 3360} 3361 3362// check if element really left/entered the event target (for mouseenter/mouseleave) 3363function isExternalTarget(el, e) { 3364 3365 var related = e.relatedTarget; 3366 3367 if (!related) { return true; } 3368 3369 try { 3370 while (related && (related !== el)) { 3371 related = related.parentNode; 3372 } 3373 } catch (err) { 3374 return false; 3375 } 3376 return (related !== el); 3377} 3378 3379var lastClick; 3380 3381// this is a horrible workaround for a bug in Android where a single touch triggers two click events 3382function filterClick(e, handler) { 3383 var timeStamp = (e.timeStamp || (e.originalEvent && e.originalEvent.timeStamp)), 3384 elapsed = lastClick && (timeStamp - lastClick); 3385 3386 // are they closer together than 500ms yet more than 100ms? 3387 // Android typically triggers them ~300ms apart while multiple listeners 3388 // on the same event should be triggered far faster; 3389 // or check if click is simulated on the element, and if it is, reject any non-simulated events 3390 3391 if ((elapsed && elapsed > 100 && elapsed < 500) || (e.target._simulatedClick && !e._simulated)) { 3392 stop(e); 3393 return; 3394 } 3395 lastClick = timeStamp; 3396 3397 handler(e); 3398} 3399 3400 3401 3402 3403var DomEvent = (Object.freeze || Object)({ 3404 on: on, 3405 off: off, 3406 stopPropagation: stopPropagation, 3407 disableScrollPropagation: disableScrollPropagation, 3408 disableClickPropagation: disableClickPropagation, 3409 preventDefault: preventDefault, 3410 stop: stop, 3411 getMousePosition: getMousePosition, 3412 getWheelDelta: getWheelDelta, 3413 fakeStop: fakeStop, 3414 skipped: skipped, 3415 isExternalTarget: isExternalTarget, 3416 addListener: on, 3417 removeListener: off 3418}); 3419 3420/* 3421 * @class PosAnimation 3422 * @aka L.PosAnimation 3423 * @inherits Evented 3424 * Used internally for panning animations, utilizing CSS3 Transitions for modern browsers and a timer fallback for IE6-9. 3425 * 3426 * @example 3427 * ```js 3428 * var fx = new L.PosAnimation(); 3429 * fx.run(el, [300, 500], 0.5); 3430 * ``` 3431 * 3432 * @constructor L.PosAnimation() 3433 * Creates a `PosAnimation` object. 3434 * 3435 */ 3436 3437var PosAnimation = Evented.extend({ 3438 3439 // @method run(el: HTMLElement, newPos: Point, duration?: Number, easeLinearity?: Number) 3440 // Run an animation of a given element to a new position, optionally setting 3441 // duration in seconds (`0.25` by default) and easing linearity factor (3rd 3442 // argument of the [cubic bezier curve](http://cubic-bezier.com/#0,0,.5,1), 3443 // `0.5` by default). 3444 run: function (el, newPos, duration, easeLinearity) { 3445 this.stop(); 3446 3447 this._el = el; 3448 this._inProgress = true; 3449 this._duration = duration || 0.25; 3450 this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2); 3451 3452 this._startPos = getPosition(el); 3453 this._offset = newPos.subtract(this._startPos); 3454 this._startTime = +new Date(); 3455 3456 // @event start: Event 3457 // Fired when the animation starts 3458 this.fire('start'); 3459 3460 this._animate(); 3461 }, 3462 3463 // @method stop() 3464 // Stops the animation (if currently running). 3465 stop: function () { 3466 if (!this._inProgress) { return; } 3467 3468 this._step(true); 3469 this._complete(); 3470 }, 3471 3472 _animate: function () { 3473 // animation loop 3474 this._animId = requestAnimFrame(this._animate, this); 3475 this._step(); 3476 }, 3477 3478 _step: function (round) { 3479 var elapsed = (+new Date()) - this._startTime, 3480 duration = this._duration * 1000; 3481 3482 if (elapsed < duration) { 3483 this._runFrame(this._easeOut(elapsed / duration), round); 3484 } else { 3485 this._runFrame(1); 3486 this._complete(); 3487 } 3488 }, 3489 3490 _runFrame: function (progress, round) { 3491 var pos = this._startPos.add(this._offset.multiplyBy(progress)); 3492 if (round) { 3493 pos._round(); 3494 } 3495 setPosition(this._el, pos); 3496 3497 // @event step: Event 3498 // Fired continuously during the animation. 3499 this.fire('step'); 3500 }, 3501 3502 _complete: function () { 3503 cancelAnimFrame(this._animId); 3504 3505 this._inProgress = false; 3506 // @event end: Event 3507 // Fired when the animation ends. 3508 this.fire('end'); 3509 }, 3510 3511 _easeOut: function (t) { 3512 return 1 - Math.pow(1 - t, this._easeOutPower); 3513 } 3514}); 3515 3516/* 3517 * @class Map 3518 * @aka L.Map 3519 * @inherits Evented 3520 * 3521 * The central class of the API — it is used to create a map on a page and manipulate it. 3522 * 3523 * @example 3524 * 3525 * ```js 3526 * // initialize the map on the "map" div with a given center and zoom 3527 * var map = L.map('map', { 3528 * center: [51.505, -0.09], 3529 * zoom: 13 3530 * }); 3531 * ``` 3532 * 3533 */ 3534 3535var Map = Evented.extend({ 3536 3537 options: { 3538 // @section Map State Options 3539 // @option crs: CRS = L.CRS.EPSG3857 3540 // The [Coordinate Reference System](#crs) to use. Don't change this if you're not 3541 // sure what it means. 3542 crs: EPSG3857, 3543 3544 // @option center: LatLng = undefined 3545 // Initial geographic center of the map 3546 center: undefined, 3547 3548 // @option zoom: Number = undefined 3549 // Initial map zoom level 3550 zoom: undefined, 3551 3552 // @option minZoom: Number = * 3553 // Minimum zoom level of the map. 3554 // If not specified and at least one `GridLayer` or `TileLayer` is in the map, 3555 // the lowest of their `minZoom` options will be used instead. 3556 minZoom: undefined, 3557 3558 // @option maxZoom: Number = * 3559 // Maximum zoom level of the map. 3560 // If not specified and at least one `GridLayer` or `TileLayer` is in the map, 3561 // the highest of their `maxZoom` options will be used instead. 3562 maxZoom: undefined, 3563 3564 // @option layers: Layer[] = [] 3565 // Array of layers that will be added to the map initially 3566 layers: [], 3567 3568 // @option maxBounds: LatLngBounds = null 3569 // When this option is set, the map restricts the view to the given 3570 // geographical bounds, bouncing the user back if the user tries to pan 3571 // outside the view. To set the restriction dynamically, use 3572 // [`setMaxBounds`](#map-setmaxbounds) method. 3573 maxBounds: undefined, 3574 3575 // @option renderer: Renderer = * 3576 // The default method for drawing vector layers on the map. `L.SVG` 3577 // or `L.Canvas` by default depending on browser support. 3578 renderer: undefined, 3579 3580 3581 // @section Animation Options 3582 // @option zoomAnimation: Boolean = true 3583 // Whether the map zoom animation is enabled. By default it's enabled 3584 // in all browsers that support CSS3 Transitions except Android. 3585 zoomAnimation: true, 3586 3587 // @option zoomAnimationThreshold: Number = 4 3588 // Won't animate zoom if the zoom difference exceeds this value. 3589 zoomAnimationThreshold: 4, 3590 3591 // @option fadeAnimation: Boolean = true 3592 // Whether the tile fade animation is enabled. By default it's enabled 3593 // in all browsers that support CSS3 Transitions except Android. 3594 fadeAnimation: true, 3595 3596 // @option markerZoomAnimation: Boolean = true 3597 // Whether markers animate their zoom with the zoom animation, if disabled 3598 // they will disappear for the length of the animation. By default it's 3599 // enabled in all browsers that support CSS3 Transitions except Android. 3600 markerZoomAnimation: true, 3601 3602 // @option transform3DLimit: Number = 2^23 3603 // Defines the maximum size of a CSS translation transform. The default 3604 // value should not be changed unless a web browser positions layers in 3605 // the wrong place after doing a large `panBy`. 3606 transform3DLimit: 8388608, // Precision limit of a 32-bit float 3607 3608 // @section Interaction Options 3609 // @option zoomSnap: Number = 1 3610 // Forces the map's zoom level to always be a multiple of this, particularly 3611 // right after a [`fitBounds()`](#map-fitbounds) or a pinch-zoom. 3612 // By default, the zoom level snaps to the nearest integer; lower values 3613 // (e.g. `0.5` or `0.1`) allow for greater granularity. A value of `0` 3614 // means the zoom level will not be snapped after `fitBounds` or a pinch-zoom. 3615 zoomSnap: 1, 3616 3617 // @option zoomDelta: Number = 1 3618 // Controls how much the map's zoom level will change after a 3619 // [`zoomIn()`](#map-zoomin), [`zoomOut()`](#map-zoomout), pressing `+` 3620 // or `-` on the keyboard, or using the [zoom controls](#control-zoom). 3621 // Values smaller than `1` (e.g. `0.5`) allow for greater granularity. 3622 zoomDelta: 1, 3623 3624 // @option trackResize: Boolean = true 3625 // Whether the map automatically handles browser window resize to update itself. 3626 trackResize: true 3627 }, 3628 3629 initialize: function (id, options) { // (HTMLElement or String, Object) 3630 options = setOptions(this, options); 3631 3632 // Make sure to assign internal flags at the beginning, 3633 // to avoid inconsistent state in some edge cases. 3634 this._handlers = []; 3635 this._layers = {}; 3636 this._zoomBoundLayers = {}; 3637 this._sizeChanged = true; 3638 3639 this._initContainer(id); 3640 this._initLayout(); 3641 3642 // hack for https://github.com/Leaflet/Leaflet/issues/1980 3643 this._onResize = bind(this._onResize, this); 3644 3645 this._initEvents(); 3646 3647 if (options.maxBounds) { 3648 this.setMaxBounds(options.maxBounds); 3649 } 3650 3651 if (options.zoom !== undefined) { 3652 this._zoom = this._limitZoom(options.zoom); 3653 } 3654 3655 if (options.center && options.zoom !== undefined) { 3656 this.setView(toLatLng(options.center), options.zoom, {reset: true}); 3657 } 3658 3659 this.callInitHooks(); 3660 3661 // don't animate on browsers without hardware-accelerated transitions or old Android/Opera 3662 this._zoomAnimated = TRANSITION && any3d && !mobileOpera && 3663 this.options.zoomAnimation; 3664 3665 // zoom transitions run with the same duration for all layers, so if one of transitionend events 3666 // happens after starting zoom animation (propagating to the map pane), we know that it ended globally 3667 if (this._zoomAnimated) { 3668 this._createAnimProxy(); 3669 on(this._proxy, TRANSITION_END, this._catchTransitionEnd, this); 3670 } 3671 3672 this._addLayers(this.options.layers); 3673 }, 3674 3675 3676 // @section Methods for modifying map state 3677 3678 // @method setView(center: LatLng, zoom: Number, options?: Zoom/pan options): this 3679 // Sets the view of the map (geographical center and zoom) with the given 3680 // animation options. 3681 setView: function (center, zoom, options) { 3682 3683 zoom = zoom === undefined ? this._zoom : this._limitZoom(zoom); 3684 center = this._limitCenter(toLatLng(center), zoom, this.options.maxBounds); 3685 options = options || {}; 3686 3687 this._stop(); 3688 3689 if (this._loaded && !options.reset && options !== true) { 3690 3691 if (options.animate !== undefined) { 3692 options.zoom = extend({animate: options.animate}, options.zoom); 3693 options.pan = extend({animate: options.animate, duration: options.duration}, options.pan); 3694 } 3695 3696 // try animating pan or zoom 3697 var moved = (this._zoom !== zoom) ? 3698 this._tryAnimatedZoom && this._tryAnimatedZoom(center, zoom, options.zoom) : 3699 this._tryAnimatedPan(center, options.pan); 3700 3701 if (moved) { 3702 // prevent resize handler call, the view will refresh after animation anyway 3703 clearTimeout(this._sizeTimer); 3704 return this; 3705 } 3706 } 3707 3708 // animation didn't start, just reset the map view 3709 this._resetView(center, zoom); 3710 3711 return this; 3712 }, 3713 3714 // @method setZoom(zoom: Number, options?: Zoom/pan options): this 3715 // Sets the zoom of the map. 3716 setZoom: function (zoom, options) { 3717 if (!this._loaded) { 3718 this._zoom = zoom; 3719 return this; 3720 } 3721 return this.setView(this.getCenter(), zoom, {zoom: options}); 3722 }, 3723 3724 // @method zoomIn(delta?: Number, options?: Zoom options): this 3725 // Increases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default). 3726 zoomIn: function (delta, options) { 3727 delta = delta || (any3d ? this.options.zoomDelta : 1); 3728 return this.setZoom(this._zoom + delta, options); 3729 }, 3730 3731 // @method zoomOut(delta?: Number, options?: Zoom options): this 3732 // Decreases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default). 3733 zoomOut: function (delta, options) { 3734 delta = delta || (any3d ? this.options.zoomDelta : 1); 3735 return this.setZoom(this._zoom - delta, options); 3736 }, 3737 3738 // @method setZoomAround(latlng: LatLng, zoom: Number, options: Zoom options): this 3739 // Zooms the map while keeping a specified geographical point on the map 3740 // stationary (e.g. used internally for scroll zoom and double-click zoom). 3741 // @alternative 3742 // @method setZoomAround(offset: Point, zoom: Number, options: Zoom options): this 3743 // Zooms the map while keeping a specified pixel on the map (relative to the top-left corner) stationary. 3744 setZoomAround: function (latlng, zoom, options) { 3745 var scale = this.getZoomScale(zoom), 3746 viewHalf = this.getSize().divideBy(2), 3747 containerPoint = latlng instanceof Point ? latlng : this.latLngToContainerPoint(latlng), 3748 3749 centerOffset = containerPoint.subtract(viewHalf).multiplyBy(1 - 1 / scale), 3750 newCenter = this.containerPointToLatLng(viewHalf.add(centerOffset)); 3751 3752 return this.setView(newCenter, zoom, {zoom: options}); 3753 }, 3754 3755 _getBoundsCenterZoom: function (bounds, options) { 3756 3757 options = options || {}; 3758 bounds = bounds.getBounds ? bounds.getBounds() : toLatLngBounds(bounds); 3759 3760 var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]), 3761 paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]), 3762 3763 zoom = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR)); 3764 3765 zoom = (typeof options.maxZoom === 'number') ? Math.min(options.maxZoom, zoom) : zoom; 3766 3767 if (zoom === Infinity) { 3768 return { 3769 center: bounds.getCenter(), 3770 zoom: zoom 3771 }; 3772 } 3773 3774 var paddingOffset = paddingBR.subtract(paddingTL).divideBy(2), 3775 3776 swPoint = this.project(bounds.getSouthWest(), zoom), 3777 nePoint = this.project(bounds.getNorthEast(), zoom), 3778 center = this.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom); 3779 3780 return { 3781 center: center, 3782 zoom: zoom 3783 }; 3784 }, 3785 3786 // @method fitBounds(bounds: LatLngBounds, options?: fitBounds options): this 3787 // Sets a map view that contains the given geographical bounds with the 3788 // maximum zoom level possible. 3789 fitBounds: function (bounds, options) { 3790 3791 bounds = toLatLngBounds(bounds); 3792 3793 if (!bounds.isValid()) { 3794 throw new Error('Bounds are not valid.'); 3795 } 3796 3797 var target = this._getBoundsCenterZoom(bounds, options); 3798 return this.setView(target.center, target.zoom, options); 3799 }, 3800 3801 // @method fitWorld(options?: fitBounds options): this 3802 // Sets a map view that mostly contains the whole world with the maximum 3803 // zoom level possible. 3804 fitWorld: function (options) { 3805 return this.fitBounds([[-90, -180], [90, 180]], options); 3806 }, 3807 3808 // @method panTo(latlng: LatLng, options?: Pan options): this 3809 // Pans the map to a given center. 3810 panTo: function (center, options) { // (LatLng) 3811 return this.setView(center, this._zoom, {pan: options}); 3812 }, 3813 3814 // @method panBy(offset: Point, options?: Pan options): this 3815 // Pans the map by a given number of pixels (animated). 3816 panBy: function (offset, options) { 3817 offset = toPoint(offset).round(); 3818 options = options || {}; 3819 3820 if (!offset.x && !offset.y) { 3821 return this.fire('moveend'); 3822 } 3823 // If we pan too far, Chrome gets issues with tiles 3824 // and makes them disappear or appear in the wrong place (slightly offset) #2602 3825 if (options.animate !== true && !this.getSize().contains(offset)) { 3826 this._resetView(this.unproject(this.project(this.getCenter()).add(offset)), this.getZoom()); 3827 return this; 3828 } 3829 3830 if (!this._panAnim) { 3831 this._panAnim = new PosAnimation(); 3832 3833 this._panAnim.on({ 3834 'step': this._onPanTransitionStep, 3835 'end': this._onPanTransitionEnd 3836 }, this); 3837 } 3838 3839 // don't fire movestart if animating inertia 3840 if (!options.noMoveStart) { 3841 this.fire('movestart'); 3842 } 3843 3844 // animate pan unless animate: false specified 3845 if (options.animate !== false) { 3846 addClass(this._mapPane, 'leaflet-pan-anim'); 3847 3848 var newPos = this._getMapPanePos().subtract(offset).round(); 3849 this._panAnim.run(this._mapPane, newPos, options.duration || 0.25, options.easeLinearity); 3850 } else { 3851 this._rawPanBy(offset); 3852 this.fire('move').fire('moveend'); 3853 } 3854 3855 return this; 3856 }, 3857 3858 // @method flyTo(latlng: LatLng, zoom?: Number, options?: Zoom/pan options): this 3859 // Sets the view of the map (geographical center and zoom) performing a smooth 3860 // pan-zoom animation. 3861 flyTo: function (targetCenter, targetZoom, options) { 3862 3863 options = options || {}; 3864 if (options.animate === false || !any3d) { 3865 return this.setView(targetCenter, targetZoom, options); 3866 } 3867 3868 this._stop(); 3869 3870 var from = this.project(this.getCenter()), 3871 to = this.project(targetCenter), 3872 size = this.getSize(), 3873 startZoom = this._zoom; 3874 3875 targetCenter = toLatLng(targetCenter); 3876 targetZoom = targetZoom === undefined ? startZoom : targetZoom; 3877 3878 var w0 = Math.max(size.x, size.y), 3879 w1 = w0 * this.getZoomScale(startZoom, targetZoom), 3880 u1 = (to.distanceTo(from)) || 1, 3881 rho = 1.42, 3882 rho2 = rho * rho; 3883 3884 function r(i) { 3885 var s1 = i ? -1 : 1, 3886 s2 = i ? w1 : w0, 3887 t1 = w1 * w1 - w0 * w0 + s1 * rho2 * rho2 * u1 * u1, 3888 b1 = 2 * s2 * rho2 * u1, 3889 b = t1 / b1, 3890 sq = Math.sqrt(b * b + 1) - b; 3891 3892 // workaround for floating point precision bug when sq = 0, log = -Infinite, 3893 // thus triggering an infinite loop in flyTo 3894 var log = sq < 0.000000001 ? -18 : Math.log(sq); 3895 3896 return log; 3897 } 3898 3899 function sinh(n) { return (Math.exp(n) - Math.exp(-n)) / 2; } 3900 function cosh(n) { return (Math.exp(n) + Math.exp(-n)) / 2; } 3901 function tanh(n) { return sinh(n) / cosh(n); } 3902 3903 var r0 = r(0); 3904 3905 function w(s) { return w0 * (cosh(r0) / cosh(r0 + rho * s)); } 3906 function u(s) { return w0 * (cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2; } 3907 3908 function easeOut(t) { return 1 - Math.pow(1 - t, 1.5); } 3909 3910 var start = Date.now(), 3911 S = (r(1) - r0) / rho, 3912 duration = options.duration ? 1000 * options.duration : 1000 * S * 0.8; 3913 3914 function frame() { 3915 var t = (Date.now() - start) / duration, 3916 s = easeOut(t) * S; 3917 3918 if (t <= 1) { 3919 this._flyToFrame = requestAnimFrame(frame, this); 3920 3921 this._move( 3922 this.unproject(from.add(to.subtract(from).multiplyBy(u(s) / u1)), startZoom), 3923 this.getScaleZoom(w0 / w(s), startZoom), 3924 {flyTo: true}); 3925 3926 } else { 3927 this 3928 ._move(targetCenter, targetZoom) 3929 ._moveEnd(true); 3930 } 3931 } 3932 3933 this._moveStart(true, options.noMoveStart); 3934 3935 frame.call(this); 3936 return this; 3937 }, 3938 3939 // @method flyToBounds(bounds: LatLngBounds, options?: fitBounds options): this 3940 // Sets the view of the map with a smooth animation like [`flyTo`](#map-flyto), 3941 // but takes a bounds parameter like [`fitBounds`](#map-fitbounds). 3942 flyToBounds: function (bounds, options) { 3943 var target = this._getBoundsCenterZoom(bounds, options); 3944 return this.flyTo(target.center, target.zoom, options); 3945 }, 3946 3947 // @method setMaxBounds(bounds: Bounds): this 3948 // Restricts the map view to the given bounds (see the [maxBounds](#map-maxbounds) option). 3949 setMaxBounds: function (bounds) { 3950 bounds = toLatLngBounds(bounds); 3951 3952 if (!bounds.isValid()) { 3953 this.options.maxBounds = null; 3954 return this.off('moveend', this._panInsideMaxBounds); 3955 } else if (this.options.maxBounds) { 3956 this.off('moveend', this._panInsideMaxBounds); 3957 } 3958 3959 this.options.maxBounds = bounds; 3960 3961 if (this._loaded) { 3962 this._panInsideMaxBounds(); 3963 } 3964 3965 return this.on('moveend', this._panInsideMaxBounds); 3966 }, 3967 3968 // @method setMinZoom(zoom: Number): this 3969 // Sets the lower limit for the available zoom levels (see the [minZoom](#map-minzoom) option). 3970 setMinZoom: function (zoom) { 3971 var oldZoom = this.options.minZoom; 3972 this.options.minZoom = zoom; 3973 3974 if (this._loaded && oldZoom !== zoom) { 3975 this.fire('zoomlevelschange'); 3976 3977 if (this.getZoom() < this.options.minZoom) { 3978 return this.setZoom(zoom); 3979 } 3980 } 3981 3982 return this; 3983 }, 3984 3985 // @method setMaxZoom(zoom: Number): this 3986 // Sets the upper limit for the available zoom levels (see the [maxZoom](#map-maxzoom) option). 3987 setMaxZoom: function (zoom) { 3988 var oldZoom = this.options.maxZoom; 3989 this.options.maxZoom = zoom; 3990 3991 if (this._loaded && oldZoom !== zoom) { 3992 this.fire('zoomlevelschange'); 3993 3994 if (this.getZoom() > this.options.maxZoom) { 3995 return this.setZoom(zoom); 3996 } 3997 } 3998 3999 return this; 4000 }, 4001 4002 // @method panInsideBounds(bounds: LatLngBounds, options?: Pan options): this 4003 // 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. 4004 panInsideBounds: function (bounds, options) { 4005 this._enforcingBounds = true; 4006 var center = this.getCenter(), 4007 newCenter = this._limitCenter(center, this._zoom, toLatLngBounds(bounds)); 4008 4009 if (!center.equals(newCenter)) { 4010 this.panTo(newCenter, options); 4011 } 4012 4013 this._enforcingBounds = false; 4014 return this; 4015 }, 4016 4017 // @method panInside(latlng: LatLng, options?: options): this 4018 // Pans the map the minimum amount to make the `latlng` visible. Use 4019 // `padding`, `paddingTopLeft` and `paddingTopRight` options to fit 4020 // the display to more restricted bounds, like [`fitBounds`](#map-fitbounds). 4021 // If `latlng` is already within the (optionally padded) display bounds, 4022 // the map will not be panned. 4023 panInside: function (latlng, options) { 4024 options = options || {}; 4025 4026 var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]), 4027 paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]), 4028 center = this.getCenter(), 4029 pixelCenter = this.project(center), 4030 pixelPoint = this.project(latlng), 4031 pixelBounds = this.getPixelBounds(), 4032 halfPixelBounds = pixelBounds.getSize().divideBy(2), 4033 paddedBounds = toBounds([pixelBounds.min.add(paddingTL), pixelBounds.max.subtract(paddingBR)]); 4034 4035 if (!paddedBounds.contains(pixelPoint)) { 4036 this._enforcingBounds = true; 4037 var diff = pixelCenter.subtract(pixelPoint), 4038 newCenter = toPoint(pixelPoint.x + diff.x, pixelPoint.y + diff.y); 4039 4040 if (pixelPoint.x < paddedBounds.min.x || pixelPoint.x > paddedBounds.max.x) { 4041 newCenter.x = pixelCenter.x - diff.x; 4042 if (diff.x > 0) { 4043 newCenter.x += halfPixelBounds.x - paddingTL.x; 4044 } else { 4045 newCenter.x -= halfPixelBounds.x - paddingBR.x; 4046 } 4047 } 4048 if (pixelPoint.y < paddedBounds.min.y || pixelPoint.y > paddedBounds.max.y) { 4049 newCenter.y = pixelCenter.y - diff.y; 4050 if (diff.y > 0) { 4051 newCenter.y += halfPixelBounds.y - paddingTL.y; 4052 } else { 4053 newCenter.y -= halfPixelBounds.y - paddingBR.y; 4054 } 4055 } 4056 this.panTo(this.unproject(newCenter), options); 4057 this._enforcingBounds = false; 4058 } 4059 return this; 4060 }, 4061 4062 // @method invalidateSize(options: Zoom/pan options): this 4063 // Checks if the map container size changed and updates the map if so — 4064 // call it after you've changed the map size dynamically, also animating 4065 // pan by default. If `options.pan` is `false`, panning will not occur. 4066 // If `options.debounceMoveend` is `true`, it will delay `moveend` event so 4067 // that it doesn't happen often even if the method is called many 4068 // times in a row. 4069 4070 // @alternative 4071 // @method invalidateSize(animate: Boolean): this 4072 // Checks if the map container size changed and updates the map if so — 4073 // call it after you've changed the map size dynamically, also animating 4074 // pan by default. 4075 invalidateSize: function (options) { 4076 if (!this._loaded) { return this; } 4077 4078 options = extend({ 4079 animate: false, 4080 pan: true 4081 }, options === true ? {animate: true} : options); 4082 4083 var oldSize = this.getSize(); 4084 this._sizeChanged = true; 4085 this._lastCenter = null; 4086 4087 var newSize = this.getSize(), 4088 oldCenter = oldSize.divideBy(2).round(), 4089 newCenter = newSize.divideBy(2).round(), 4090 offset = oldCenter.subtract(newCenter); 4091 4092 if (!offset.x && !offset.y) { return this; } 4093 4094 if (options.animate && options.pan) { 4095 this.panBy(offset); 4096 4097 } else { 4098 if (options.pan) { 4099 this._rawPanBy(offset); 4100 } 4101 4102 this.fire('move'); 4103 4104 if (options.debounceMoveend) { 4105 clearTimeout(this._sizeTimer); 4106 this._sizeTimer = setTimeout(bind(this.fire, this, 'moveend'), 200); 4107 } else { 4108 this.fire('moveend'); 4109 } 4110 } 4111 4112 // @section Map state change events 4113 // @event resize: ResizeEvent 4114 // Fired when the map is resized. 4115 return this.fire('resize', { 4116 oldSize: oldSize, 4117 newSize: newSize 4118 }); 4119 }, 4120 4121 // @section Methods for modifying map state 4122 // @method stop(): this 4123 // Stops the currently running `panTo` or `flyTo` animation, if any. 4124 stop: function () { 4125 this.setZoom(this._limitZoom(this._zoom)); 4126 if (!this.options.zoomSnap) { 4127 this.fire('viewreset'); 4128 } 4129 return this._stop(); 4130 }, 4131 4132 // @section Geolocation methods 4133 // @method locate(options?: Locate options): this 4134 // Tries to locate the user using the Geolocation API, firing a [`locationfound`](#map-locationfound) 4135 // event with location data on success or a [`locationerror`](#map-locationerror) event on failure, 4136 // and optionally sets the map view to the user's location with respect to 4137 // detection accuracy (or to the world view if geolocation failed). 4138 // Note that, if your page doesn't use HTTPS, this method will fail in 4139 // modern browsers ([Chrome 50 and newer](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins)) 4140 // See `Locate options` for more details. 4141 locate: function (options) { 4142 4143 options = this._locateOptions = extend({ 4144 timeout: 10000, 4145 watch: false 4146 // setView: false 4147 // maxZoom: <Number> 4148 // maximumAge: 0 4149 // enableHighAccuracy: false 4150 }, options); 4151 4152 if (!('geolocation' in navigator)) { 4153 this._handleGeolocationError({ 4154 code: 0, 4155 message: 'Geolocation not supported.' 4156 }); 4157 return this; 4158 } 4159 4160 var onResponse = bind(this._handleGeolocationResponse, this), 4161 onError = bind(this._handleGeolocationError, this); 4162 4163 if (options.watch) { 4164 this._locationWatchId = 4165 navigator.geolocation.watchPosition(onResponse, onError, options); 4166 } else { 4167 navigator.geolocation.getCurrentPosition(onResponse, onError, options); 4168 } 4169 return this; 4170 }, 4171 4172 // @method stopLocate(): this 4173 // Stops watching location previously initiated by `map.locate({watch: true})` 4174 // and aborts resetting the map view if map.locate was called with 4175 // `{setView: true}`. 4176 stopLocate: function () { 4177 if (navigator.geolocation && navigator.geolocation.clearWatch) { 4178 navigator.geolocation.clearWatch(this._locationWatchId); 4179 } 4180 if (this._locateOptions) { 4181 this._locateOptions.setView = false; 4182 } 4183 return this; 4184 }, 4185 4186 _handleGeolocationError: function (error) { 4187 var c = error.code, 4188 message = error.message || 4189 (c === 1 ? 'permission denied' : 4190 (c === 2 ? 'position unavailable' : 'timeout')); 4191 4192 if (this._locateOptions.setView && !this._loaded) { 4193 this.fitWorld(); 4194 } 4195 4196 // @section Location events 4197 // @event locationerror: ErrorEvent 4198 // Fired when geolocation (using the [`locate`](#map-locate) method) failed. 4199 this.fire('locationerror', { 4200 code: c, 4201 message: 'Geolocation error: ' + message + '.' 4202 }); 4203 }, 4204 4205 _handleGeolocationResponse: function (pos) { 4206 var lat = pos.coords.latitude, 4207 lng = pos.coords.longitude, 4208 latlng = new LatLng(lat, lng), 4209 bounds = latlng.toBounds(pos.coords.accuracy * 2), 4210 options = this._locateOptions; 4211 4212 if (options.setView) { 4213 var zoom = this.getBoundsZoom(bounds); 4214 this.setView(latlng, options.maxZoom ? Math.min(zoom, options.maxZoom) : zoom); 4215 } 4216 4217 var data = { 4218 latlng: latlng, 4219 bounds: bounds, 4220 timestamp: pos.timestamp 4221 }; 4222 4223 for (var i in pos.coords) { 4224 if (typeof pos.coords[i] === 'number') { 4225 data[i] = pos.coords[i]; 4226 } 4227 } 4228 4229 // @event locationfound: LocationEvent 4230 // Fired when geolocation (using the [`locate`](#map-locate) method) 4231 // went successfully. 4232 this.fire('locationfound', data); 4233 }, 4234 4235 // TODO Appropriate docs section? 4236 // @section Other Methods 4237 // @method addHandler(name: String, HandlerClass: Function): this 4238 // Adds a new `Handler` to the map, given its name and constructor function. 4239 addHandler: function (name, HandlerClass) { 4240 if (!HandlerClass) { return this; } 4241 4242 var handler = this[name] = new HandlerClass(this); 4243 4244 this._handlers.push(handler); 4245 4246 if (this.options[name]) { 4247 handler.enable(); 4248 } 4249 4250 return this; 4251 }, 4252 4253 // @method remove(): this 4254 // Destroys the map and clears all related event listeners. 4255 remove: function () { 4256 4257 this._initEvents(true); 4258 4259 if (this._containerId !== this._container._leaflet_id) { 4260 throw new Error('Map container is being reused by another instance'); 4261 } 4262 4263 try { 4264 // throws error in IE6-8 4265 delete this._container._leaflet_id; 4266 delete this._containerId; 4267 } catch (e) { 4268 /*eslint-disable */ 4269 this._container._leaflet_id = undefined; 4270 /* eslint-enable */ 4271 this._containerId = undefined; 4272 } 4273 4274 if (this._locationWatchId !== undefined) { 4275 this.stopLocate(); 4276 } 4277 4278 this._stop(); 4279 4280 remove(this._mapPane); 4281 4282 if (this._clearControlPos) { 4283 this._clearControlPos(); 4284 } 4285 if (this._resizeRequest) { 4286 cancelAnimFrame(this._resizeRequest); 4287 this._resizeRequest = null; 4288 } 4289 4290 this._clearHandlers(); 4291 4292 if (this._loaded) { 4293 // @section Map state change events 4294 // @event unload: Event 4295 // Fired when the map is destroyed with [remove](#map-remove) method. 4296 this.fire('unload'); 4297 } 4298 4299 var i; 4300 for (i in this._layers) { 4301 this._layers[i].remove(); 4302 } 4303 for (i in this._panes) { 4304 remove(this._panes[i]); 4305 } 4306 4307 this._layers = []; 4308 this._panes = []; 4309 delete this._mapPane; 4310 delete this._renderer; 4311 4312 return this; 4313 }, 4314 4315 // @section Other Methods 4316 // @method createPane(name: String, container?: HTMLElement): HTMLElement 4317 // Creates a new [map pane](#map-pane) with the given name if it doesn't exist already, 4318 // then returns it. The pane is created as a child of `container`, or 4319 // as a child of the main map pane if not set. 4320 createPane: function (name, container) { 4321 var className = 'leaflet-pane' + (name ? ' leaflet-' + name.replace('Pane', '') + '-pane' : ''), 4322 pane = create$1('div', className, container || this._mapPane); 4323 4324 if (name) { 4325 this._panes[name] = pane; 4326 } 4327 return pane; 4328 }, 4329 4330 // @section Methods for Getting Map State 4331 4332 // @method getCenter(): LatLng 4333 // Returns the geographical center of the map view 4334 getCenter: function () { 4335 this._checkIfLoaded(); 4336 4337 if (this._lastCenter && !this._moved()) { 4338 return this._lastCenter; 4339 } 4340 return this.layerPointToLatLng(this._getCenterLayerPoint()); 4341 }, 4342 4343 // @method getZoom(): Number 4344 // Returns the current zoom level of the map view 4345 getZoom: function () { 4346 return this._zoom; 4347 }, 4348 4349 // @method getBounds(): LatLngBounds 4350 // Returns the geographical bounds visible in the current map view 4351 getBounds: function () { 4352 var bounds = this.getPixelBounds(), 4353 sw = this.unproject(bounds.getBottomLeft()), 4354 ne = this.unproject(bounds.getTopRight()); 4355 4356 return new LatLngBounds(sw, ne); 4357 }, 4358 4359 // @method getMinZoom(): Number 4360 // 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. 4361 getMinZoom: function () { 4362 return this.options.minZoom === undefined ? this._layersMinZoom || 0 : this.options.minZoom; 4363 }, 4364 4365 // @method getMaxZoom(): Number 4366 // Returns the maximum zoom level of the map (if set in the `maxZoom` option of the map or of any layers). 4367 getMaxZoom: function () { 4368 return this.options.maxZoom === undefined ? 4369 (this._layersMaxZoom === undefined ? Infinity : this._layersMaxZoom) : 4370 this.options.maxZoom; 4371 }, 4372 4373 // @method getBoundsZoom(bounds: LatLngBounds, inside?: Boolean, padding?: Point): Number 4374 // Returns the maximum zoom level on which the given bounds fit to the map 4375 // view in its entirety. If `inside` (optional) is set to `true`, the method 4376 // instead returns the minimum zoom level on which the map view fits into 4377 // the given bounds in its entirety. 4378 getBoundsZoom: function (bounds, inside, padding) { // (LatLngBounds[, Boolean, Point]) -> Number 4379 bounds = toLatLngBounds(bounds); 4380 padding = toPoint(padding || [0, 0]); 4381 4382 var zoom = this.getZoom() || 0, 4383 min = this.getMinZoom(), 4384 max = this.getMaxZoom(), 4385 nw = bounds.getNorthWest(), 4386 se = bounds.getSouthEast(), 4387 size = this.getSize().subtract(padding), 4388 boundsSize = toBounds(this.project(se, zoom), this.project(nw, zoom)).getSize(), 4389 snap = any3d ? this.options.zoomSnap : 1, 4390 scalex = size.x / boundsSize.x, 4391 scaley = size.y / boundsSize.y, 4392 scale = inside ? Math.max(scalex, scaley) : Math.min(scalex, scaley); 4393 4394 zoom = this.getScaleZoom(scale, zoom); 4395 4396 if (snap) { 4397 zoom = Math.round(zoom / (snap / 100)) * (snap / 100); // don't jump if within 1% of a snap level 4398 zoom = inside ? Math.ceil(zoom / snap) * snap : Math.floor(zoom / snap) * snap; 4399 } 4400 4401 return Math.max(min, Math.min(max, zoom)); 4402 }, 4403 4404 // @method getSize(): Point 4405 // Returns the current size of the map container (in pixels). 4406 getSize: function () { 4407 if (!this._size || this._sizeChanged) { 4408 this._size = new Point( 4409 this._container.clientWidth || 0, 4410 this._container.clientHeight || 0); 4411 4412 this._sizeChanged = false; 4413 } 4414 return this._size.clone(); 4415 }, 4416 4417 // @method getPixelBounds(): Bounds 4418 // Returns the bounds of the current map view in projected pixel 4419 // coordinates (sometimes useful in layer and overlay implementations). 4420 getPixelBounds: function (center, zoom) { 4421 var topLeftPoint = this._getTopLeftPoint(center, zoom); 4422 return new Bounds(topLeftPoint, topLeftPoint.add(this.getSize())); 4423 }, 4424 4425 // TODO: Check semantics - isn't the pixel origin the 0,0 coord relative to 4426 // the map pane? "left point of the map layer" can be confusing, specially 4427 // since there can be negative offsets. 4428 // @method getPixelOrigin(): Point 4429 // Returns the projected pixel coordinates of the top left point of 4430 // the map layer (useful in custom layer and overlay implementations). 4431 getPixelOrigin: function () { 4432 this._checkIfLoaded(); 4433 return this._pixelOrigin; 4434 }, 4435 4436 // @method getPixelWorldBounds(zoom?: Number): Bounds 4437 // Returns the world's bounds in pixel coordinates for zoom level `zoom`. 4438 // If `zoom` is omitted, the map's current zoom level is used. 4439 getPixelWorldBounds: function (zoom) { 4440 return this.options.crs.getProjectedBounds(zoom === undefined ? this.getZoom() : zoom); 4441 }, 4442 4443 // @section Other Methods 4444 4445 // @method getPane(pane: String|HTMLElement): HTMLElement 4446 // Returns a [map pane](#map-pane), given its name or its HTML element (its identity). 4447 getPane: function (pane) { 4448 return typeof pane === 'string' ? this._panes[pane] : pane; 4449 }, 4450 4451 // @method getPanes(): Object 4452 // Returns a plain object containing the names of all [panes](#map-pane) as keys and 4453 // the panes as values. 4454 getPanes: function () { 4455 return this._panes; 4456 }, 4457 4458 // @method getContainer: HTMLElement 4459 // Returns the HTML element that contains the map. 4460 getContainer: function () { 4461 return this._container; 4462 }, 4463 4464 4465 // @section Conversion Methods 4466 4467 // @method getZoomScale(toZoom: Number, fromZoom: Number): Number 4468 // Returns the scale factor to be applied to a map transition from zoom level 4469 // `fromZoom` to `toZoom`. Used internally to help with zoom animations. 4470 getZoomScale: function (toZoom, fromZoom) { 4471 // TODO replace with universal implementation after refactoring projections 4472 var crs = this.options.crs; 4473 fromZoom = fromZoom === undefined ? this._zoom : fromZoom; 4474 return crs.scale(toZoom) / crs.scale(fromZoom); 4475 }, 4476 4477 // @method getScaleZoom(scale: Number, fromZoom: Number): Number 4478 // Returns the zoom level that the map would end up at, if it is at `fromZoom` 4479 // level and everything is scaled by a factor of `scale`. Inverse of 4480 // [`getZoomScale`](#map-getZoomScale). 4481 getScaleZoom: function (scale, fromZoom) { 4482 var crs = this.options.crs; 4483 fromZoom = fromZoom === undefined ? this._zoom : fromZoom; 4484 var zoom = crs.zoom(scale * crs.scale(fromZoom)); 4485 return isNaN(zoom) ? Infinity : zoom; 4486 }, 4487 4488 // @method project(latlng: LatLng, zoom: Number): Point 4489 // Projects a geographical coordinate `LatLng` according to the projection 4490 // of the map's CRS, then scales it according to `zoom` and the CRS's 4491 // `Transformation`. The result is pixel coordinate relative to 4492 // the CRS origin. 4493 project: function (latlng, zoom) { 4494 zoom = zoom === undefined ? this._zoom : zoom; 4495 return this.options.crs.latLngToPoint(toLatLng(latlng), zoom); 4496 }, 4497 4498 // @method unproject(point: Point, zoom: Number): LatLng 4499 // Inverse of [`project`](#map-project). 4500 unproject: function (point, zoom) { 4501 zoom = zoom === undefined ? this._zoom : zoom; 4502 return this.options.crs.pointToLatLng(toPoint(point), zoom); 4503 }, 4504 4505 // @method layerPointToLatLng(point: Point): LatLng 4506 // Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin), 4507 // returns the corresponding geographical coordinate (for the current zoom level). 4508 layerPointToLatLng: function (point) { 4509 var projectedPoint = toPoint(point).add(this.getPixelOrigin()); 4510 return this.unproject(projectedPoint); 4511 }, 4512 4513 // @method latLngToLayerPoint(latlng: LatLng): Point 4514 // Given a geographical coordinate, returns the corresponding pixel coordinate 4515 // relative to the [origin pixel](#map-getpixelorigin). 4516 latLngToLayerPoint: function (latlng) { 4517 var projectedPoint = this.project(toLatLng(latlng))._round(); 4518 return projectedPoint._subtract(this.getPixelOrigin()); 4519 }, 4520 4521 // @method wrapLatLng(latlng: LatLng): LatLng 4522 // Returns a `LatLng` where `lat` and `lng` has been wrapped according to the 4523 // map's CRS's `wrapLat` and `wrapLng` properties, if they are outside the 4524 // CRS's bounds. 4525 // By default this means longitude is wrapped around the dateline so its 4526 // value is between -180 and +180 degrees. 4527 wrapLatLng: function (latlng) { 4528 return this.options.crs.wrapLatLng(toLatLng(latlng)); 4529 }, 4530 4531 // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds 4532 // Returns a `LatLngBounds` with the same size as the given one, ensuring that 4533 // its center is within the CRS's bounds. 4534 // By default this means the center longitude is wrapped around the dateline so its 4535 // value is between -180 and +180 degrees, and the majority of the bounds 4536 // overlaps the CRS's bounds. 4537 wrapLatLngBounds: function (latlng) { 4538 return this.options.crs.wrapLatLngBounds(toLatLngBounds(latlng)); 4539 }, 4540 4541 // @method distance(latlng1: LatLng, latlng2: LatLng): Number 4542 // Returns the distance between two geographical coordinates according to 4543 // the map's CRS. By default this measures distance in meters. 4544 distance: function (latlng1, latlng2) { 4545 return this.options.crs.distance(toLatLng(latlng1), toLatLng(latlng2)); 4546 }, 4547 4548 // @method containerPointToLayerPoint(point: Point): Point 4549 // Given a pixel coordinate relative to the map container, returns the corresponding 4550 // pixel coordinate relative to the [origin pixel](#map-getpixelorigin). 4551 containerPointToLayerPoint: function (point) { // (Point) 4552 return toPoint(point).subtract(this._getMapPanePos()); 4553 }, 4554 4555 // @method layerPointToContainerPoint(point: Point): Point 4556 // Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin), 4557 // returns the corresponding pixel coordinate relative to the map container. 4558 layerPointToContainerPoint: function (point) { // (Point) 4559 return toPoint(point).add(this._getMapPanePos()); 4560 }, 4561 4562 // @method containerPointToLatLng(point: Point): LatLng 4563 // Given a pixel coordinate relative to the map container, returns 4564 // the corresponding geographical coordinate (for the current zoom level). 4565 containerPointToLatLng: function (point) { 4566 var layerPoint = this.containerPointToLayerPoint(toPoint(point)); 4567 return this.layerPointToLatLng(layerPoint); 4568 }, 4569 4570 // @method latLngToContainerPoint(latlng: LatLng): Point 4571 // Given a geographical coordinate, returns the corresponding pixel coordinate 4572 // relative to the map container. 4573 latLngToContainerPoint: function (latlng) { 4574 return this.layerPointToContainerPoint(this.latLngToLayerPoint(toLatLng(latlng))); 4575 }, 4576 4577 // @method mouseEventToContainerPoint(ev: MouseEvent): Point 4578 // Given a MouseEvent object, returns the pixel coordinate relative to the 4579 // map container where the event took place. 4580 mouseEventToContainerPoint: function (e) { 4581 return getMousePosition(e, this._container); 4582 }, 4583 4584 // @method mouseEventToLayerPoint(ev: MouseEvent): Point 4585 // Given a MouseEvent object, returns the pixel coordinate relative to 4586 // the [origin pixel](#map-getpixelorigin) where the event took place. 4587 mouseEventToLayerPoint: function (e) { 4588 return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(e)); 4589 }, 4590 4591 // @method mouseEventToLatLng(ev: MouseEvent): LatLng 4592 // Given a MouseEvent object, returns geographical coordinate where the 4593 // event took place. 4594 mouseEventToLatLng: function (e) { // (MouseEvent) 4595 return this.layerPointToLatLng(this.mouseEventToLayerPoint(e)); 4596 }, 4597 4598 4599 // map initialization methods 4600 4601 _initContainer: function (id) { 4602 var container = this._container = get(id); 4603 4604 if (!container) { 4605 throw new Error('Map container not found.'); 4606 } else if (container._leaflet_id) { 4607 throw new Error('Map container is already initialized.'); 4608 } 4609 4610 on(container, 'scroll', this._onScroll, this); 4611 this._containerId = stamp(container); 4612 }, 4613 4614 _initLayout: function () { 4615 var container = this._container; 4616 4617 this._fadeAnimated = this.options.fadeAnimation && any3d; 4618 4619 addClass(container, 'leaflet-container' + 4620 (touch ? ' leaflet-touch' : '') + 4621 (retina ? ' leaflet-retina' : '') + 4622 (ielt9 ? ' leaflet-oldie' : '') + 4623 (safari ? ' leaflet-safari' : '') + 4624 (this._fadeAnimated ? ' leaflet-fade-anim' : '')); 4625 4626 var position = getStyle(container, 'position'); 4627 4628 if (position !== 'absolute' && position !== 'relative' && position !== 'fixed') { 4629 container.style.position = 'relative'; 4630 } 4631 4632 this._initPanes(); 4633 4634 if (this._initControlPos) { 4635 this._initControlPos(); 4636 } 4637 }, 4638 4639 _initPanes: function () { 4640 var panes = this._panes = {}; 4641 this._paneRenderers = {}; 4642 4643 // @section 4644 // 4645 // Panes are DOM elements used to control the ordering of layers on the map. You 4646 // can access panes with [`map.getPane`](#map-getpane) or 4647 // [`map.getPanes`](#map-getpanes) methods. New panes can be created with the 4648 // [`map.createPane`](#map-createpane) method. 4649 // 4650 // Every map has the following default panes that differ only in zIndex. 4651 // 4652 // @pane mapPane: HTMLElement = 'auto' 4653 // Pane that contains all other map panes 4654 4655 this._mapPane = this.createPane('mapPane', this._container); 4656 setPosition(this._mapPane, new Point(0, 0)); 4657 4658 // @pane tilePane: HTMLElement = 200 4659 // Pane for `GridLayer`s and `TileLayer`s 4660 this.createPane('tilePane'); 4661 // @pane overlayPane: HTMLElement = 400 4662 // Pane for vectors (`Path`s, like `Polyline`s and `Polygon`s), `ImageOverlay`s and `VideoOverlay`s 4663 this.createPane('shadowPane'); 4664 // @pane shadowPane: HTMLElement = 500 4665 // Pane for overlay shadows (e.g. `Marker` shadows) 4666 this.createPane('overlayPane'); 4667 // @pane markerPane: HTMLElement = 600 4668 // Pane for `Icon`s of `Marker`s 4669 this.createPane('markerPane'); 4670 // @pane tooltipPane: HTMLElement = 650 4671 // Pane for `Tooltip`s. 4672 this.createPane('tooltipPane'); 4673 // @pane popupPane: HTMLElement = 700 4674 // Pane for `Popup`s. 4675 this.createPane('popupPane'); 4676 4677 if (!this.options.markerZoomAnimation) { 4678 addClass(panes.markerPane, 'leaflet-zoom-hide'); 4679 addClass(panes.shadowPane, 'leaflet-zoom-hide'); 4680 } 4681 }, 4682 4683 4684 // private methods that modify map state 4685 4686 // @section Map state change events 4687 _resetView: function (center, zoom) { 4688 setPosition(this._mapPane, new Point(0, 0)); 4689 4690 var loading = !this._loaded; 4691 this._loaded = true; 4692 zoom = this._limitZoom(zoom); 4693 4694 this.fire('viewprereset'); 4695 4696 var zoomChanged = this._zoom !== zoom; 4697 this 4698 ._moveStart(zoomChanged, false) 4699 ._move(center, zoom) 4700 ._moveEnd(zoomChanged); 4701 4702 // @event viewreset: Event 4703 // Fired when the map needs to redraw its content (this usually happens 4704 // on map zoom or load). Very useful for creating custom overlays. 4705 this.fire('viewreset'); 4706 4707 // @event load: Event 4708 // Fired when the map is initialized (when its center and zoom are set 4709 // for the first time). 4710 if (loading) { 4711 this.fire('load'); 4712 } 4713 }, 4714 4715 _moveStart: function (zoomChanged, noMoveStart) { 4716 // @event zoomstart: Event 4717 // Fired when the map zoom is about to change (e.g. before zoom animation). 4718 // @event movestart: Event 4719 // Fired when the view of the map starts changing (e.g. user starts dragging the map). 4720 if (zoomChanged) { 4721 this.fire('zoomstart'); 4722 } 4723 if (!noMoveStart) { 4724 this.fire('movestart'); 4725 } 4726 return this; 4727 }, 4728 4729 _move: function (center, zoom, data) { 4730 if (zoom === undefined) { 4731 zoom = this._zoom; 4732 } 4733 var zoomChanged = this._zoom !== zoom; 4734 4735 this._zoom = zoom; 4736 this._lastCenter = center; 4737 this._pixelOrigin = this._getNewPixelOrigin(center); 4738 4739 // @event zoom: Event 4740 // Fired repeatedly during any change in zoom level, including zoom 4741 // and fly animations. 4742 if (zoomChanged || (data && data.pinch)) { // Always fire 'zoom' if pinching because #3530 4743 this.fire('zoom', data); 4744 } 4745 4746 // @event move: Event 4747 // Fired repeatedly during any movement of the map, including pan and 4748 // fly animations. 4749 return this.fire('move', data); 4750 }, 4751 4752 _moveEnd: function (zoomChanged) { 4753 // @event zoomend: Event 4754 // Fired when the map has changed, after any animations. 4755 if (zoomChanged) { 4756 this.fire('zoomend'); 4757 } 4758 4759 // @event moveend: Event 4760 // Fired when the center of the map stops changing (e.g. user stopped 4761 // dragging the map). 4762 return this.fire('moveend'); 4763 }, 4764 4765 _stop: function () { 4766 cancelAnimFrame(this._flyToFrame); 4767 if (this._panAnim) { 4768 this._panAnim.stop(); 4769 } 4770 return this; 4771 }, 4772 4773 _rawPanBy: function (offset) { 4774 setPosition(this._mapPane, this._getMapPanePos().subtract(offset)); 4775 }, 4776 4777 _getZoomSpan: function () { 4778 return this.getMaxZoom() - this.getMinZoom(); 4779 }, 4780 4781 _panInsideMaxBounds: function () { 4782 if (!this._enforcingBounds) { 4783 this.panInsideBounds(this.options.maxBounds); 4784 } 4785 }, 4786 4787 _checkIfLoaded: function () { 4788 if (!this._loaded) { 4789 throw new Error('Set map center and zoom first.'); 4790 } 4791 }, 4792 4793 // DOM event handling 4794 4795 // @section Interaction events 4796 _initEvents: function (remove$$1) { 4797 this._targets = {}; 4798 this._targets[stamp(this._container)] = this; 4799 4800 var onOff = remove$$1 ? off : on; 4801 4802 // @event click: MouseEvent 4803 // Fired when the user clicks (or taps) the map. 4804 // @event dblclick: MouseEvent 4805 // Fired when the user double-clicks (or double-taps) the map. 4806 // @event mousedown: MouseEvent 4807 // Fired when the user pushes the mouse button on the map. 4808 // @event mouseup: MouseEvent 4809 // Fired when the user releases the mouse button on the map. 4810 // @event mouseover: MouseEvent 4811 // Fired when the mouse enters the map. 4812 // @event mouseout: MouseEvent 4813 // Fired when the mouse leaves the map. 4814 // @event mousemove: MouseEvent 4815 // Fired while the mouse moves over the map. 4816 // @event contextmenu: MouseEvent 4817 // Fired when the user pushes the right mouse button on the map, prevents 4818 // default browser context menu from showing if there are listeners on 4819 // this event. Also fired on mobile when the user holds a single touch 4820 // for a second (also called long press). 4821 // @event keypress: KeyboardEvent 4822 // Fired when the user presses a key from the keyboard that produces a character value while the map is focused. 4823 // @event keydown: KeyboardEvent 4824 // Fired when the user presses a key from the keyboard while the map is focused. Unlike the `keypress` event, 4825 // the `keydown` event is fired for keys that produce a character value and for keys 4826 // that do not produce a character value. 4827 // @event keyup: KeyboardEvent 4828 // Fired when the user releases a key from the keyboard while the map is focused. 4829 onOff(this._container, 'click dblclick mousedown mouseup ' + 4830 'mouseover mouseout mousemove contextmenu keypress keydown keyup', this._handleDOMEvent, this); 4831 4832 if (this.options.trackResize) { 4833 onOff(window, 'resize', this._onResize, this); 4834 } 4835 4836 if (any3d && this.options.transform3DLimit) { 4837 (remove$$1 ? this.off : this.on).call(this, 'moveend', this._onMoveEnd); 4838 } 4839 }, 4840 4841 _onResize: function () { 4842 cancelAnimFrame(this._resizeRequest); 4843 this._resizeRequest = requestAnimFrame( 4844 function () { this.invalidateSize({debounceMoveend: true}); }, this); 4845 }, 4846 4847 _onScroll: function () { 4848 this._container.scrollTop = 0; 4849 this._container.scrollLeft = 0; 4850 }, 4851 4852 _onMoveEnd: function () { 4853 var pos = this._getMapPanePos(); 4854 if (Math.max(Math.abs(pos.x), Math.abs(pos.y)) >= this.options.transform3DLimit) { 4855 // https://bugzilla.mozilla.org/show_bug.cgi?id=1203873 but Webkit also have 4856 // a pixel offset on very high values, see: http://jsfiddle.net/dg6r5hhb/ 4857 this._resetView(this.getCenter(), this.getZoom()); 4858 } 4859 }, 4860 4861 _findEventTargets: function (e, type) { 4862 var targets = [], 4863 target, 4864 isHover = type === 'mouseout' || type === 'mouseover', 4865 src = e.target || e.srcElement, 4866 dragging = false; 4867 4868 while (src) { 4869 target = this._targets[stamp(src)]; 4870 if (target && (type === 'click' || type === 'preclick') && !e._simulated && this._draggableMoved(target)) { 4871 // Prevent firing click after you just dragged an object. 4872 dragging = true; 4873 break; 4874 } 4875 if (target && target.listens(type, true)) { 4876 if (isHover && !isExternalTarget(src, e)) { break; } 4877 targets.push(target); 4878 if (isHover) { break; } 4879 } 4880 if (src === this._container) { break; } 4881 src = src.parentNode; 4882 } 4883 if (!targets.length && !dragging && !isHover && isExternalTarget(src, e)) { 4884 targets = [this]; 4885 } 4886 return targets; 4887 }, 4888 4889 _handleDOMEvent: function (e) { 4890 if (!this._loaded || skipped(e)) { return; } 4891 4892 var type = e.type; 4893 4894 if (type === 'mousedown' || type === 'keypress' || type === 'keyup' || type === 'keydown') { 4895 // prevents outline when clicking on keyboard-focusable element 4896 preventOutline(e.target || e.srcElement); 4897 } 4898 4899 this._fireDOMEvent(e, type); 4900 }, 4901 4902 _mouseEvents: ['click', 'dblclick', 'mouseover', 'mouseout', 'contextmenu'], 4903 4904 _fireDOMEvent: function (e, type, targets) { 4905 4906 if (e.type === 'click') { 4907 // Fire a synthetic 'preclick' event which propagates up (mainly for closing popups). 4908 // @event preclick: MouseEvent 4909 // Fired before mouse click on the map (sometimes useful when you 4910 // want something to happen on click before any existing click 4911 // handlers start running). 4912 var synth = extend({}, e); 4913 synth.type = 'preclick'; 4914 this._fireDOMEvent(synth, synth.type, targets); 4915 } 4916 4917 if (e._stopped) { return; } 4918 4919 // Find the layer the event is propagating from and its parents. 4920 targets = (targets || []).concat(this._findEventTargets(e, type)); 4921 4922 if (!targets.length) { return; } 4923 4924 var target = targets[0]; 4925 if (type === 'contextmenu' && target.listens(type, true)) { 4926 preventDefault(e); 4927 } 4928 4929 var data = { 4930 originalEvent: e 4931 }; 4932 4933 if (e.type !== 'keypress' && e.type !== 'keydown' && e.type !== 'keyup') { 4934 var isMarker = target.getLatLng && (!target._radius || target._radius <= 10); 4935 data.containerPoint = isMarker ? 4936 this.latLngToContainerPoint(target.getLatLng()) : this.mouseEventToContainerPoint(e); 4937 data.layerPoint = this.containerPointToLayerPoint(data.containerPoint); 4938 data.latlng = isMarker ? target.getLatLng() : this.layerPointToLatLng(data.layerPoint); 4939 } 4940 4941 for (var i = 0; i < targets.length; i++) { 4942 targets[i].fire(type, data, true); 4943 if (data.originalEvent._stopped || 4944 (targets[i].options.bubblingMouseEvents === false && indexOf(this._mouseEvents, type) !== -1)) { return; } 4945 } 4946 }, 4947 4948 _draggableMoved: function (obj) { 4949 obj = obj.dragging && obj.dragging.enabled() ? obj : this; 4950 return (obj.dragging && obj.dragging.moved()) || (this.boxZoom && this.boxZoom.moved()); 4951 }, 4952 4953 _clearHandlers: function () { 4954 for (var i = 0, len = this._handlers.length; i < len; i++) { 4955 this._handlers[i].disable(); 4956 } 4957 }, 4958 4959 // @section Other Methods 4960 4961 // @method whenReady(fn: Function, context?: Object): this 4962 // Runs the given function `fn` when the map gets initialized with 4963 // a view (center and zoom) and at least one layer, or immediately 4964 // if it's already initialized, optionally passing a function context. 4965 whenReady: function (callback, context) { 4966 if (this._loaded) { 4967 callback.call(context || this, {target: this}); 4968 } else { 4969 this.on('load', callback, context); 4970 } 4971 return this; 4972 }, 4973 4974 4975 // private methods for getting map state 4976 4977 _getMapPanePos: function () { 4978 return getPosition(this._mapPane) || new Point(0, 0); 4979 }, 4980 4981 _moved: function () { 4982 var pos = this._getMapPanePos(); 4983 return pos && !pos.equals([0, 0]); 4984 }, 4985 4986 _getTopLeftPoint: function (center, zoom) { 4987 var pixelOrigin = center && zoom !== undefined ? 4988 this._getNewPixelOrigin(center, zoom) : 4989 this.getPixelOrigin(); 4990 return pixelOrigin.subtract(this._getMapPanePos()); 4991 }, 4992 4993 _getNewPixelOrigin: function (center, zoom) { 4994 var viewHalf = this.getSize()._divideBy(2); 4995 return this.project(center, zoom)._subtract(viewHalf)._add(this._getMapPanePos())._round(); 4996 }, 4997 4998 _latLngToNewLayerPoint: function (latlng, zoom, center) { 4999 var topLeft = this._getNewPixelOrigin(center, zoom); 5000 return this.project(latlng, zoom)._subtract(topLeft); 5001 }, 5002 5003 _latLngBoundsToNewLayerBounds: function (latLngBounds, zoom, center) { 5004 var topLeft = this._getNewPixelOrigin(center, zoom); 5005 return toBounds([ 5006 this.project(latLngBounds.getSouthWest(), zoom)._subtract(topLeft), 5007 this.project(latLngBounds.getNorthWest(), zoom)._subtract(topLeft), 5008 this.project(latLngBounds.getSouthEast(), zoom)._subtract(topLeft), 5009 this.project(latLngBounds.getNorthEast(), zoom)._subtract(topLeft) 5010 ]); 5011 }, 5012 5013 // layer point of the current center 5014 _getCenterLayerPoint: function () { 5015 return this.containerPointToLayerPoint(this.getSize()._divideBy(2)); 5016 }, 5017 5018 // offset of the specified place to the current center in pixels 5019 _getCenterOffset: function (latlng) { 5020 return this.latLngToLayerPoint(latlng).subtract(this._getCenterLayerPoint()); 5021 }, 5022 5023 // adjust center for view to get inside bounds 5024 _limitCenter: function (center, zoom, bounds) { 5025 5026 if (!bounds) { return center; } 5027 5028 var centerPoint = this.project(center, zoom), 5029 viewHalf = this.getSize().divideBy(2), 5030 viewBounds = new Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)), 5031 offset = this._getBoundsOffset(viewBounds, bounds, zoom); 5032 5033 // If offset is less than a pixel, ignore. 5034 // This prevents unstable projections from getting into 5035 // an infinite loop of tiny offsets. 5036 if (offset.round().equals([0, 0])) { 5037 return center; 5038 } 5039 5040 return this.unproject(centerPoint.add(offset), zoom); 5041 }, 5042 5043 // adjust offset for view to get inside bounds 5044 _limitOffset: function (offset, bounds) { 5045 if (!bounds) { return offset; } 5046 5047 var viewBounds = this.getPixelBounds(), 5048 newBounds = new Bounds(viewBounds.min.add(offset), viewBounds.max.add(offset)); 5049 5050 return offset.add(this._getBoundsOffset(newBounds, bounds)); 5051 }, 5052 5053 // returns offset needed for pxBounds to get inside maxBounds at a specified zoom 5054 _getBoundsOffset: function (pxBounds, maxBounds, zoom) { 5055 var projectedMaxBounds = toBounds( 5056 this.project(maxBounds.getNorthEast(), zoom), 5057 this.project(maxBounds.getSouthWest(), zoom) 5058 ), 5059 minOffset = projectedMaxBounds.min.subtract(pxBounds.min), 5060 maxOffset = projectedMaxBounds.max.subtract(pxBounds.max), 5061 5062 dx = this._rebound(minOffset.x, -maxOffset.x), 5063 dy = this._rebound(minOffset.y, -maxOffset.y); 5064 5065 return new Point(dx, dy); 5066 }, 5067 5068 _rebound: function (left, right) { 5069 return left + right > 0 ? 5070 Math.round(left - right) / 2 : 5071 Math.max(0, Math.ceil(left)) - Math.max(0, Math.floor(right)); 5072 }, 5073 5074 _limitZoom: function (zoom) { 5075 var min = this.getMinZoom(), 5076 max = this.getMaxZoom(), 5077 snap = any3d ? this.options.zoomSnap : 1; 5078 if (snap) { 5079 zoom = Math.round(zoom / snap) * snap; 5080 } 5081 return Math.max(min, Math.min(max, zoom)); 5082 }, 5083 5084 _onPanTransitionStep: function () { 5085 this.fire('move'); 5086 }, 5087 5088 _onPanTransitionEnd: function () { 5089 removeClass(this._mapPane, 'leaflet-pan-anim'); 5090 this.fire('moveend'); 5091 }, 5092 5093 _tryAnimatedPan: function (center, options) { 5094 // difference between the new and current centers in pixels 5095 var offset = this._getCenterOffset(center)._trunc(); 5096 5097 // don't animate too far unless animate: true specified in options 5098 if ((options && options.animate) !== true && !this.getSize().contains(offset)) { return false; } 5099 5100 this.panBy(offset, options); 5101 5102 return true; 5103 }, 5104 5105 _createAnimProxy: function () { 5106 5107 var proxy = this._proxy = create$1('div', 'leaflet-proxy leaflet-zoom-animated'); 5108 this._panes.mapPane.appendChild(proxy); 5109 5110 this.on('zoomanim', function (e) { 5111 var prop = TRANSFORM, 5112 transform = this._proxy.style[prop]; 5113 5114 setTransform(this._proxy, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1)); 5115 5116 // workaround for case when transform is the same and so transitionend event is not fired 5117 if (transform === this._proxy.style[prop] && this._animatingZoom) { 5118 this._onZoomTransitionEnd(); 5119 } 5120 }, this); 5121 5122 this.on('load moveend', function () { 5123 var c = this.getCenter(), 5124 z = this.getZoom(); 5125 setTransform(this._proxy, this.project(c, z), this.getZoomScale(z, 1)); 5126 }, this); 5127 5128 this._on('unload', this._destroyAnimProxy, this); 5129 }, 5130 5131 _destroyAnimProxy: function () { 5132 remove(this._proxy); 5133 delete this._proxy; 5134 }, 5135 5136 _catchTransitionEnd: function (e) { 5137 if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) { 5138 this._onZoomTransitionEnd(); 5139 } 5140 }, 5141 5142 _nothingToAnimate: function () { 5143 return !this._container.getElementsByClassName('leaflet-zoom-animated').length; 5144 }, 5145 5146 _tryAnimatedZoom: function (center, zoom, options) { 5147 5148 if (this._animatingZoom) { return true; } 5149 5150 options = options || {}; 5151 5152 // don't animate if disabled, not supported or zoom difference is too large 5153 if (!this._zoomAnimated || options.animate === false || this._nothingToAnimate() || 5154 Math.abs(zoom - this._zoom) > this.options.zoomAnimationThreshold) { return false; } 5155 5156 // offset is the pixel coords of the zoom origin relative to the current center 5157 var scale = this.getZoomScale(zoom), 5158 offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale); 5159 5160 // don't animate if the zoom origin isn't within one screen from the current center, unless forced 5161 if (options.animate !== true && !this.getSize().contains(offset)) { return false; } 5162 5163 requestAnimFrame(function () { 5164 this 5165 ._moveStart(true, false) 5166 ._animateZoom(center, zoom, true); 5167 }, this); 5168 5169 return true; 5170 }, 5171 5172 _animateZoom: function (center, zoom, startAnim, noUpdate) { 5173 if (!this._mapPane) { return; } 5174 5175 if (startAnim) { 5176 this._animatingZoom = true; 5177 5178 // remember what center/zoom to set after animation 5179 this._animateToCenter = center; 5180 this._animateToZoom = zoom; 5181 5182 addClass(this._mapPane, 'leaflet-zoom-anim'); 5183 } 5184 5185 // @event zoomanim: ZoomAnimEvent 5186 // Fired at least once per zoom animation. For continuous zoom, like pinch zooming, fired once per frame during zoom. 5187 this.fire('zoomanim', { 5188 center: center, 5189 zoom: zoom, 5190 noUpdate: noUpdate 5191 }); 5192 5193 // Work around webkit not firing 'transitionend', see https://github.com/Leaflet/Leaflet/issues/3689, 2693 5194 setTimeout(bind(this._onZoomTransitionEnd, this), 250); 5195 }, 5196 5197 _onZoomTransitionEnd: function () { 5198 if (!this._animatingZoom) { return; } 5199 5200 if (this._mapPane) { 5201 removeClass(this._mapPane, 'leaflet-zoom-anim'); 5202 } 5203 5204 this._animatingZoom = false; 5205 5206 this._move(this._animateToCenter, this._animateToZoom); 5207 5208 // This anim frame should prevent an obscure iOS webkit tile loading race condition. 5209 requestAnimFrame(function () { 5210 this._moveEnd(true); 5211 }, this); 5212 } 5213}); 5214 5215// @section 5216 5217// @factory L.map(id: String, options?: Map options) 5218// Instantiates a map object given the DOM ID of a `<div>` element 5219// and optionally an object literal with `Map options`. 5220// 5221// @alternative 5222// @factory L.map(el: HTMLElement, options?: Map options) 5223// Instantiates a map object given an instance of a `<div>` HTML element 5224// and optionally an object literal with `Map options`. 5225function createMap(id, options) { 5226 return new Map(id, options); 5227} 5228 5229/* 5230 * @class Control 5231 * @aka L.Control 5232 * @inherits Class 5233 * 5234 * L.Control is a base class for implementing map controls. Handles positioning. 5235 * All other controls extend from this class. 5236 */ 5237 5238var Control = Class.extend({ 5239 // @section 5240 // @aka Control options 5241 options: { 5242 // @option position: String = 'topright' 5243 // The position of the control (one of the map corners). Possible values are `'topleft'`, 5244 // `'topright'`, `'bottomleft'` or `'bottomright'` 5245 position: 'topright' 5246 }, 5247 5248 initialize: function (options) { 5249 setOptions(this, options); 5250 }, 5251 5252 /* @section 5253 * Classes extending L.Control will inherit the following methods: 5254 * 5255 * @method getPosition: string 5256 * Returns the position of the control. 5257 */ 5258 getPosition: function () { 5259 return this.options.position; 5260 }, 5261 5262 // @method setPosition(position: string): this 5263 // Sets the position of the control. 5264 setPosition: function (position) { 5265 var map = this._map; 5266 5267 if (map) { 5268 map.removeControl(this); 5269 } 5270 5271 this.options.position = position; 5272 5273 if (map) { 5274 map.addControl(this); 5275 } 5276 5277 return this; 5278 }, 5279 5280 // @method getContainer: HTMLElement 5281 // Returns the HTMLElement that contains the control. 5282 getContainer: function () { 5283 return this._container; 5284 }, 5285 5286 // @method addTo(map: Map): this 5287 // Adds the control to the given map. 5288 addTo: function (map) { 5289 this.remove(); 5290 this._map = map; 5291 5292 var container = this._container = this.onAdd(map), 5293 pos = this.getPosition(), 5294 corner = map._controlCorners[pos]; 5295 5296 addClass(container, 'leaflet-control'); 5297 5298 if (pos.indexOf('bottom') !== -1) { 5299 corner.insertBefore(container, corner.firstChild); 5300 } else { 5301 corner.appendChild(container); 5302 } 5303 5304 this._map.on('unload', this.remove, this); 5305 5306 return this; 5307 }, 5308 5309 // @method remove: this 5310 // Removes the control from the map it is currently active on. 5311 remove: function () { 5312 if (!this._map) { 5313 return this; 5314 } 5315 5316 remove(this._container); 5317 5318 if (this.onRemove) { 5319 this.onRemove(this._map); 5320 } 5321 5322 this._map.off('unload', this.remove, this); 5323 this._map = null; 5324 5325 return this; 5326 }, 5327 5328 _refocusOnMap: function (e) { 5329 // if map exists and event is not a keyboard event 5330 if (this._map && e && e.screenX > 0 && e.screenY > 0) { 5331 this._map.getContainer().focus(); 5332 } 5333 } 5334}); 5335 5336var control = function (options) { 5337 return new Control(options); 5338}; 5339 5340/* @section Extension methods 5341 * @uninheritable 5342 * 5343 * Every control should extend from `L.Control` and (re-)implement the following methods. 5344 * 5345 * @method onAdd(map: Map): HTMLElement 5346 * Should return the container DOM element for the control and add listeners on relevant map events. Called on [`control.addTo(map)`](#control-addTo). 5347 * 5348 * @method onRemove(map: Map) 5349 * Optional method. Should contain all clean up code that removes the listeners previously added in [`onAdd`](#control-onadd). Called on [`control.remove()`](#control-remove). 5350 */ 5351 5352/* @namespace Map 5353 * @section Methods for Layers and Controls 5354 */ 5355Map.include({ 5356 // @method addControl(control: Control): this 5357 // Adds the given control to the map 5358 addControl: function (control) { 5359 control.addTo(this); 5360 return this; 5361 }, 5362 5363 // @method removeControl(control: Control): this 5364 // Removes the given control from the map 5365 removeControl: function (control) { 5366 control.remove(); 5367 return this; 5368 }, 5369 5370 _initControlPos: function () { 5371 var corners = this._controlCorners = {}, 5372 l = 'leaflet-', 5373 container = this._controlContainer = 5374 create$1('div', l + 'control-container', this._container); 5375 5376 function createCorner(vSide, hSide) { 5377 var className = l + vSide + ' ' + l + hSide; 5378 5379 corners[vSide + hSide] = create$1('div', className, container); 5380 } 5381 5382 createCorner('top', 'left'); 5383 createCorner('top', 'right'); 5384 createCorner('bottom', 'left'); 5385 createCorner('bottom', 'right'); 5386 }, 5387 5388 _clearControlPos: function () { 5389 for (var i in this._controlCorners) { 5390 remove(this._controlCorners[i]); 5391 } 5392 remove(this._controlContainer); 5393 delete this._controlCorners; 5394 delete this._controlContainer; 5395 } 5396}); 5397 5398/* 5399 * @class Control.Layers 5400 * @aka L.Control.Layers 5401 * @inherits Control 5402 * 5403 * 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`. 5404 * 5405 * @example 5406 * 5407 * ```js 5408 * var baseLayers = { 5409 * "Mapbox": mapbox, 5410 * "OpenStreetMap": osm 5411 * }; 5412 * 5413 * var overlays = { 5414 * "Marker": marker, 5415 * "Roads": roadsLayer 5416 * }; 5417 * 5418 * L.control.layers(baseLayers, overlays).addTo(map); 5419 * ``` 5420 * 5421 * The `baseLayers` and `overlays` parameters are object literals with layer names as keys and `Layer` objects as values: 5422 * 5423 * ```js 5424 * { 5425 * "<someName1>": layer1, 5426 * "<someName2>": layer2 5427 * } 5428 * ``` 5429 * 5430 * The layer names can contain HTML, which allows you to add additional styling to the items: 5431 * 5432 * ```js 5433 * {"<img src='my-layer-icon' /> <span class='my-layer-item'>My Layer</span>": myLayer} 5434 * ``` 5435 */ 5436 5437var Layers = Control.extend({ 5438 // @section 5439 // @aka Control.Layers options 5440 options: { 5441 // @option collapsed: Boolean = true 5442 // If `true`, the control will be collapsed into an icon and expanded on mouse hover or touch. 5443 collapsed: true, 5444 position: 'topright', 5445 5446 // @option autoZIndex: Boolean = true 5447 // 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. 5448 autoZIndex: true, 5449 5450 // @option hideSingleBase: Boolean = false 5451 // If `true`, the base layers in the control will be hidden when there is only one. 5452 hideSingleBase: false, 5453 5454 // @option sortLayers: Boolean = false 5455 // Whether to sort the layers. When `false`, layers will keep the order 5456 // in which they were added to the control. 5457 sortLayers: false, 5458 5459 // @option sortFunction: Function = * 5460 // A [compare function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 5461 // that will be used for sorting the layers, when `sortLayers` is `true`. 5462 // The function receives both the `L.Layer` instances and their names, as in 5463 // `sortFunction(layerA, layerB, nameA, nameB)`. 5464 // By default, it sorts layers alphabetically by their name. 5465 sortFunction: function (layerA, layerB, nameA, nameB) { 5466 return nameA < nameB ? -1 : (nameB < nameA ? 1 : 0); 5467 } 5468 }, 5469 5470 initialize: function (baseLayers, overlays, options) { 5471 setOptions(this, options); 5472 5473 this._layerControlInputs = []; 5474 this._layers = []; 5475 this._lastZIndex = 0; 5476 this._handlingClick = false; 5477 5478 for (var i in baseLayers) { 5479 this._addLayer(baseLayers[i], i); 5480 } 5481 5482 for (i in overlays) { 5483 this._addLayer(overlays[i], i, true); 5484 } 5485 }, 5486 5487 onAdd: function (map) { 5488 this._initLayout(); 5489 this._update(); 5490 5491 this._map = map; 5492 map.on('zoomend', this._checkDisabledLayers, this); 5493 5494 for (var i = 0; i < this._layers.length; i++) { 5495 this._layers[i].layer.on('add remove', this._onLayerChange, this); 5496 } 5497 5498 return this._container; 5499 }, 5500 5501 addTo: function (map) { 5502 Control.prototype.addTo.call(this, map); 5503 // Trigger expand after Layers Control has been inserted into DOM so that is now has an actual height. 5504 return this._expandIfNotCollapsed(); 5505 }, 5506 5507 onRemove: function () { 5508 this._map.off('zoomend', this._checkDisabledLayers, this); 5509 5510 for (var i = 0; i < this._layers.length; i++) { 5511 this._layers[i].layer.off('add remove', this._onLayerChange, this); 5512 } 5513 }, 5514 5515 // @method addBaseLayer(layer: Layer, name: String): this 5516 // Adds a base layer (radio button entry) with the given name to the control. 5517 addBaseLayer: function (layer, name) { 5518 this._addLayer(layer, name); 5519 return (this._map) ? this._update() : this; 5520 }, 5521 5522 // @method addOverlay(layer: Layer, name: String): this 5523 // Adds an overlay (checkbox entry) with the given name to the control. 5524 addOverlay: function (layer, name) { 5525 this._addLayer(layer, name, true); 5526 return (this._map) ? this._update() : this; 5527 }, 5528 5529 // @method removeLayer(layer: Layer): this 5530 // Remove the given layer from the control. 5531 removeLayer: function (layer) { 5532 layer.off('add remove', this._onLayerChange, this); 5533 5534 var obj = this._getLayer(stamp(layer)); 5535 if (obj) { 5536 this._layers.splice(this._layers.indexOf(obj), 1); 5537 } 5538 return (this._map) ? this._update() : this; 5539 }, 5540 5541 // @method expand(): this 5542 // Expand the control container if collapsed. 5543 expand: function () { 5544 addClass(this._container, 'leaflet-control-layers-expanded'); 5545 this._section.style.height = null; 5546 var acceptableHeight = this._map.getSize().y - (this._container.offsetTop + 50); 5547 if (acceptableHeight < this._section.clientHeight) { 5548 addClass(this._section, 'leaflet-control-layers-scrollbar'); 5549 this._section.style.height = acceptableHeight + 'px'; 5550 } else { 5551 removeClass(this._section, 'leaflet-control-layers-scrollbar'); 5552 } 5553 this._checkDisabledLayers(); 5554 return this; 5555 }, 5556 5557 // @method collapse(): this 5558 // Collapse the control container if expanded. 5559 collapse: function () { 5560 removeClass(this._container, 'leaflet-control-layers-expanded'); 5561 return this; 5562 }, 5563 5564 _initLayout: function () { 5565 var className = 'leaflet-control-layers', 5566 container = this._container = create$1('div', className), 5567 collapsed = this.options.collapsed; 5568 5569 // makes this work on IE touch devices by stopping it from firing a mouseout event when the touch is released 5570 container.setAttribute('aria-haspopup', true); 5571 5572 disableClickPropagation(container); 5573 disableScrollPropagation(container); 5574 5575 var section = this._section = create$1('section', className + '-list'); 5576 5577 if (collapsed) { 5578 this._map.on('click', this.collapse, this); 5579 5580 if (!android) { 5581 on(container, { 5582 mouseenter: this.expand, 5583 mouseleave: this.collapse 5584 }, this); 5585 } 5586 } 5587 5588 var link = this._layersLink = create$1('a', className + '-toggle', container); 5589 link.href = '#'; 5590 link.title = 'Layers'; 5591 5592 if (touch) { 5593 on(link, 'click', stop); 5594 on(link, 'click', this.expand, this); 5595 } else { 5596 on(link, 'focus', this.expand, this); 5597 } 5598 5599 if (!collapsed) { 5600 this.expand(); 5601 } 5602 5603 this._baseLayersList = create$1('div', className + '-base', section); 5604 this._separator = create$1('div', className + '-separator', section); 5605 this._overlaysList = create$1('div', className + '-overlays', section); 5606 5607 container.appendChild(section); 5608 }, 5609 5610 _getLayer: function (id) { 5611 for (var i = 0; i < this._layers.length; i++) { 5612 5613 if (this._layers[i] && stamp(this._layers[i].layer) === id) { 5614 return this._layers[i]; 5615 } 5616 } 5617 }, 5618 5619 _addLayer: function (layer, name, overlay) { 5620 if (this._map) { 5621 layer.on('add remove', this._onLayerChange, this); 5622 } 5623 5624 this._layers.push({ 5625 layer: layer, 5626 name: name, 5627 overlay: overlay 5628 }); 5629 5630 if (this.options.sortLayers) { 5631 this._layers.sort(bind(function (a, b) { 5632 return this.options.sortFunction(a.layer, b.layer, a.name, b.name); 5633 }, this)); 5634 } 5635 5636 if (this.options.autoZIndex && layer.setZIndex) { 5637 this._lastZIndex++; 5638 layer.setZIndex(this._lastZIndex); 5639 } 5640 5641 this._expandIfNotCollapsed(); 5642 }, 5643 5644 _update: function () { 5645 if (!this._container) { return this; } 5646 5647 empty(this._baseLayersList); 5648 empty(this._overlaysList); 5649 5650 this._layerControlInputs = []; 5651 var baseLayersPresent, overlaysPresent, i, obj, baseLayersCount = 0; 5652 5653 for (i = 0; i < this._layers.length; i++) { 5654 obj = this._layers[i]; 5655 this._addItem(obj); 5656 overlaysPresent = overlaysPresent || obj.overlay; 5657 baseLayersPresent = baseLayersPresent || !obj.overlay; 5658 baseLayersCount += !obj.overlay ? 1 : 0; 5659 } 5660 5661 // Hide base layers section if there's only one layer. 5662 if (this.options.hideSingleBase) { 5663 baseLayersPresent = baseLayersPresent && baseLayersCount > 1; 5664 this._baseLayersList.style.display = baseLayersPresent ? '' : 'none'; 5665 } 5666 5667 this._separator.style.display = overlaysPresent && baseLayersPresent ? '' : 'none'; 5668 5669 return this; 5670 }, 5671 5672 _onLayerChange: function (e) { 5673 if (!this._handlingClick) { 5674 this._update(); 5675 } 5676 5677 var obj = this._getLayer(stamp(e.target)); 5678 5679 // @namespace Map 5680 // @section Layer events 5681 // @event baselayerchange: LayersControlEvent 5682 // Fired when the base layer is changed through the [layer control](#control-layers). 5683 // @event overlayadd: LayersControlEvent 5684 // Fired when an overlay is selected through the [layer control](#control-layers). 5685 // @event overlayremove: LayersControlEvent 5686 // Fired when an overlay is deselected through the [layer control](#control-layers). 5687 // @namespace Control.Layers 5688 var type = obj.overlay ? 5689 (e.type === 'add' ? 'overlayadd' : 'overlayremove') : 5690 (e.type === 'add' ? 'baselayerchange' : null); 5691 5692 if (type) { 5693 this._map.fire(type, obj); 5694 } 5695 }, 5696 5697 // IE7 bugs out if you create a radio dynamically, so you have to do it this hacky way (see http://bit.ly/PqYLBe) 5698 _createRadioElement: function (name, checked) { 5699 5700 var radioHtml = '<input type="radio" class="leaflet-control-layers-selector" name="' + 5701 name + '"' + (checked ? ' checked="checked"' : '') + '/>'; 5702 5703 var radioFragment = document.createElement('div'); 5704 radioFragment.innerHTML = radioHtml; 5705 5706 return radioFragment.firstChild; 5707 }, 5708 5709 _addItem: function (obj) { 5710 var label = document.createElement('label'), 5711 checked = this._map.hasLayer(obj.layer), 5712 input; 5713 5714 if (obj.overlay) { 5715 input = document.createElement('input'); 5716 input.type = 'checkbox'; 5717 input.className = 'leaflet-control-layers-selector'; 5718 input.defaultChecked = checked; 5719 } else { 5720 input = this._createRadioElement('leaflet-base-layers_' + stamp(this), checked); 5721 } 5722 5723 this._layerControlInputs.push(input); 5724 input.layerId = stamp(obj.layer); 5725 5726 on(input, 'click', this._onInputClick, this); 5727 5728 var name = document.createElement('span'); 5729 name.innerHTML = ' ' + obj.name; 5730 5731 // Helps from preventing layer control flicker when checkboxes are disabled 5732 // https://github.com/Leaflet/Leaflet/issues/2771 5733 var holder = document.createElement('div'); 5734 5735 label.appendChild(holder); 5736 holder.appendChild(input); 5737 holder.appendChild(name); 5738 5739 var container = obj.overlay ? this._overlaysList : this._baseLayersList; 5740 container.appendChild(label); 5741 5742 this._checkDisabledLayers(); 5743 return label; 5744 }, 5745 5746 _onInputClick: function () { 5747 var inputs = this._layerControlInputs, 5748 input, layer; 5749 var addedLayers = [], 5750 removedLayers = []; 5751 5752 this._handlingClick = true; 5753 5754 for (var i = inputs.length - 1; i >= 0; i--) { 5755 input = inputs[i]; 5756 layer = this._getLayer(input.layerId).layer; 5757 5758 if (input.checked) { 5759 addedLayers.push(layer); 5760 } else if (!input.checked) { 5761 removedLayers.push(layer); 5762 } 5763 } 5764 5765 // Bugfix issue 2318: Should remove all old layers before readding new ones 5766 for (i = 0; i < removedLayers.length; i++) { 5767 if (this._map.hasLayer(removedLayers[i])) { 5768 this._map.removeLayer(removedLayers[i]); 5769 } 5770 } 5771 for (i = 0; i < addedLayers.length; i++) { 5772 if (!this._map.hasLayer(addedLayers[i])) { 5773 this._map.addLayer(addedLayers[i]); 5774 } 5775 } 5776 5777 this._handlingClick = false; 5778 5779 this._refocusOnMap(); 5780 }, 5781 5782 _checkDisabledLayers: function () { 5783 var inputs = this._layerControlInputs, 5784 input, 5785 layer, 5786 zoom = this._map.getZoom(); 5787 5788 for (var i = inputs.length - 1; i >= 0; i--) { 5789 input = inputs[i]; 5790 layer = this._getLayer(input.layerId).layer; 5791 input.disabled = (layer.options.minZoom !== undefined && zoom < layer.options.minZoom) || 5792 (layer.options.maxZoom !== undefined && zoom > layer.options.maxZoom); 5793 5794 } 5795 }, 5796 5797 _expandIfNotCollapsed: function () { 5798 if (this._map && !this.options.collapsed) { 5799 this.expand(); 5800 } 5801 return this; 5802 }, 5803 5804 _expand: function () { 5805 // Backward compatibility, remove me in 1.1. 5806 return this.expand(); 5807 }, 5808 5809 _collapse: function () { 5810 // Backward compatibility, remove me in 1.1. 5811 return this.collapse(); 5812 } 5813 5814}); 5815 5816 5817// @factory L.control.layers(baselayers?: Object, overlays?: Object, options?: Control.Layers options) 5818// 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. 5819var layers = function (baseLayers, overlays, options) { 5820 return new Layers(baseLayers, overlays, options); 5821}; 5822 5823/* 5824 * @class Control.Zoom 5825 * @aka L.Control.Zoom 5826 * @inherits Control 5827 * 5828 * 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`. 5829 */ 5830 5831var Zoom = Control.extend({ 5832 // @section 5833 // @aka Control.Zoom options 5834 options: { 5835 position: 'topleft', 5836 5837 // @option zoomInText: String = '+' 5838 // The text set on the 'zoom in' button. 5839 zoomInText: '+', 5840 5841 // @option zoomInTitle: String = 'Zoom in' 5842 // The title set on the 'zoom in' button. 5843 zoomInTitle: 'Zoom in', 5844 5845 // @option zoomOutText: String = '−' 5846 // The text set on the 'zoom out' button. 5847 zoomOutText: '−', 5848 5849 // @option zoomOutTitle: String = 'Zoom out' 5850 // The title set on the 'zoom out' button. 5851 zoomOutTitle: 'Zoom out' 5852 }, 5853 5854 onAdd: function (map) { 5855 var zoomName = 'leaflet-control-zoom', 5856 container = create$1('div', zoomName + ' leaflet-bar'), 5857 options = this.options; 5858 5859 this._zoomInButton = this._createButton(options.zoomInText, options.zoomInTitle, 5860 zoomName + '-in', container, this._zoomIn); 5861 this._zoomOutButton = this._createButton(options.zoomOutText, options.zoomOutTitle, 5862 zoomName + '-out', container, this._zoomOut); 5863 5864 this._updateDisabled(); 5865 map.on('zoomend zoomlevelschange', this._updateDisabled, this); 5866 5867 return container; 5868 }, 5869 5870 onRemove: function (map) { 5871 map.off('zoomend zoomlevelschange', this._updateDisabled, this); 5872 }, 5873 5874 disable: function () { 5875 this._disabled = true; 5876 this._updateDisabled(); 5877 return this; 5878 }, 5879 5880 enable: function () { 5881 this._disabled = false; 5882 this._updateDisabled(); 5883 return this; 5884 }, 5885 5886 _zoomIn: function (e) { 5887 if (!this._disabled && this._map._zoom < this._map.getMaxZoom()) { 5888 this._map.zoomIn(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1)); 5889 } 5890 }, 5891 5892 _zoomOut: function (e) { 5893 if (!this._disabled && this._map._zoom > this._map.getMinZoom()) { 5894 this._map.zoomOut(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1)); 5895 } 5896 }, 5897 5898 _createButton: function (html, title, className, container, fn) { 5899 var link = create$1('a', className, container); 5900 link.innerHTML = html; 5901 link.href = '#'; 5902 link.title = title; 5903 5904 /* 5905 * Will force screen readers like VoiceOver to read this as "Zoom in - button" 5906 */ 5907 link.setAttribute('role', 'button'); 5908 link.setAttribute('aria-label', title); 5909 5910 disableClickPropagation(link); 5911 on(link, 'click', stop); 5912 on(link, 'click', fn, this); 5913 on(link, 'click', this._refocusOnMap, this); 5914 5915 return link; 5916 }, 5917 5918 _updateDisabled: function () { 5919 var map = this._map, 5920 className = 'leaflet-disabled'; 5921 5922 removeClass(this._zoomInButton, className); 5923 removeClass(this._zoomOutButton, className); 5924 5925 if (this._disabled || map._zoom === map.getMinZoom()) { 5926 addClass(this._zoomOutButton, className); 5927 } 5928 if (this._disabled || map._zoom === map.getMaxZoom()) { 5929 addClass(this._zoomInButton, className); 5930 } 5931 } 5932}); 5933 5934// @namespace Map 5935// @section Control options 5936// @option zoomControl: Boolean = true 5937// Whether a [zoom control](#control-zoom) is added to the map by default. 5938Map.mergeOptions({ 5939 zoomControl: true 5940}); 5941 5942Map.addInitHook(function () { 5943 if (this.options.zoomControl) { 5944 // @section Controls 5945 // @property zoomControl: Control.Zoom 5946 // The default zoom control (only available if the 5947 // [`zoomControl` option](#map-zoomcontrol) was `true` when creating the map). 5948 this.zoomControl = new Zoom(); 5949 this.addControl(this.zoomControl); 5950 } 5951}); 5952 5953// @namespace Control.Zoom 5954// @factory L.control.zoom(options: Control.Zoom options) 5955// Creates a zoom control 5956var zoom = function (options) { 5957 return new Zoom(options); 5958}; 5959 5960/* 5961 * @class Control.Scale 5962 * @aka L.Control.Scale 5963 * @inherits Control 5964 * 5965 * 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`. 5966 * 5967 * @example 5968 * 5969 * ```js 5970 * L.control.scale().addTo(map); 5971 * ``` 5972 */ 5973 5974var Scale = Control.extend({ 5975 // @section 5976 // @aka Control.Scale options 5977 options: { 5978 position: 'bottomleft', 5979 5980 // @option maxWidth: Number = 100 5981 // Maximum width of the control in pixels. The width is set dynamically to show round values (e.g. 100, 200, 500). 5982 maxWidth: 100, 5983 5984 // @option metric: Boolean = True 5985 // Whether to show the metric scale line (m/km). 5986 metric: true, 5987 5988 // @option imperial: Boolean = True 5989 // Whether to show the imperial scale line (mi/ft). 5990 imperial: true 5991 5992 // @option updateWhenIdle: Boolean = false 5993 // If `true`, the control is updated on [`moveend`](#map-moveend), otherwise it's always up-to-date (updated on [`move`](#map-move)). 5994 }, 5995 5996 onAdd: function (map) { 5997 var className = 'leaflet-control-scale', 5998 container = create$1('div', className), 5999 options = this.options; 6000 6001 this._addScales(options, className + '-line', container); 6002 6003 map.on(options.updateWhenIdle ? 'moveend' : 'move', this._update, this); 6004 map.whenReady(this._update, this); 6005 6006 return container; 6007 }, 6008 6009 onRemove: function (map) { 6010 map.off(this.options.updateWhenIdle ? 'moveend' : 'move', this._update, this); 6011 }, 6012 6013 _addScales: function (options, className, container) { 6014 if (options.metric) { 6015 this._mScale = create$1('div', className, container); 6016 } 6017 if (options.imperial) { 6018 this._iScale = create$1('div', className, container); 6019 } 6020 }, 6021 6022 _update: function () { 6023 var map = this._map, 6024 y = map.getSize().y / 2; 6025 6026 var maxMeters = map.distance( 6027 map.containerPointToLatLng([0, y]), 6028 map.containerPointToLatLng([this.options.maxWidth, y])); 6029 6030 this._updateScales(maxMeters); 6031 }, 6032 6033 _updateScales: function (maxMeters) { 6034 if (this.options.metric && maxMeters) { 6035 this._updateMetric(maxMeters); 6036 } 6037 if (this.options.imperial && maxMeters) { 6038 this._updateImperial(maxMeters); 6039 } 6040 }, 6041 6042 _updateMetric: function (maxMeters) { 6043 var meters = this._getRoundNum(maxMeters), 6044 label = meters < 1000 ? meters + ' m' : (meters / 1000) + ' km'; 6045 6046 this._updateScale(this._mScale, label, meters / maxMeters); 6047 }, 6048 6049 _updateImperial: function (maxMeters) { 6050 var maxFeet = maxMeters * 3.2808399, 6051 maxMiles, miles, feet; 6052 6053 if (maxFeet > 5280) { 6054 maxMiles = maxFeet / 5280; 6055 miles = this._getRoundNum(maxMiles); 6056 this._updateScale(this._iScale, miles + ' mi', miles / maxMiles); 6057 6058 } else { 6059 feet = this._getRoundNum(maxFeet); 6060 this._updateScale(this._iScale, feet + ' ft', feet / maxFeet); 6061 } 6062 }, 6063 6064 _updateScale: function (scale, text, ratio) { 6065 scale.style.width = Math.round(this.options.maxWidth * ratio) + 'px'; 6066 scale.innerHTML = text; 6067 }, 6068 6069 _getRoundNum: function (num) { 6070 var pow10 = Math.pow(10, (Math.floor(num) + '').length - 1), 6071 d = num / pow10; 6072 6073 d = d >= 10 ? 10 : 6074 d >= 5 ? 5 : 6075 d >= 3 ? 3 : 6076 d >= 2 ? 2 : 1; 6077 6078 return pow10 * d; 6079 } 6080}); 6081 6082 6083// @factory L.control.scale(options?: Control.Scale options) 6084// Creates an scale control with the given options. 6085var scale = function (options) { 6086 return new Scale(options); 6087}; 6088 6089/* 6090 * @class Control.Attribution 6091 * @aka L.Control.Attribution 6092 * @inherits Control 6093 * 6094 * 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. 6095 */ 6096 6097var Attribution = Control.extend({ 6098 // @section 6099 // @aka Control.Attribution options 6100 options: { 6101 position: 'bottomright', 6102 6103 // @option prefix: String = 'Leaflet' 6104 // The HTML text shown before the attributions. Pass `false` to disable. 6105 prefix: '<a href="https://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>' 6106 }, 6107 6108 initialize: function (options) { 6109 setOptions(this, options); 6110 6111 this._attributions = {}; 6112 }, 6113 6114 onAdd: function (map) { 6115 map.attributionControl = this; 6116 this._container = create$1('div', 'leaflet-control-attribution'); 6117 disableClickPropagation(this._container); 6118 6119 // TODO ugly, refactor 6120 for (var i in map._layers) { 6121 if (map._layers[i].getAttribution) { 6122 this.addAttribution(map._layers[i].getAttribution()); 6123 } 6124 } 6125 6126 this._update(); 6127 6128 return this._container; 6129 }, 6130 6131 // @method setPrefix(prefix: String): this 6132 // Sets the text before the attributions. 6133 setPrefix: function (prefix) { 6134 this.options.prefix = prefix; 6135 this._update(); 6136 return this; 6137 }, 6138 6139 // @method addAttribution(text: String): this 6140 // Adds an attribution text (e.g. `'Vector data © Mapbox'`). 6141 addAttribution: function (text) { 6142 if (!text) { return this; } 6143 6144 if (!this._attributions[text]) { 6145 this._attributions[text] = 0; 6146 } 6147 this._attributions[text]++; 6148 6149 this._update(); 6150 6151 return this; 6152 }, 6153 6154 // @method removeAttribution(text: String): this 6155 // Removes an attribution text. 6156 removeAttribution: function (text) { 6157 if (!text) { return this; } 6158 6159 if (this._attributions[text]) { 6160 this._attributions[text]--; 6161 this._update(); 6162 } 6163 6164 return this; 6165 }, 6166 6167 _update: function () { 6168 if (!this._map) { return; } 6169 6170 var attribs = []; 6171 6172 for (var i in this._attributions) { 6173 if (this._attributions[i]) { 6174 attribs.push(i); 6175 } 6176 } 6177 6178 var prefixAndAttribs = []; 6179 6180 if (this.options.prefix) { 6181 prefixAndAttribs.push(this.options.prefix); 6182 } 6183 if (attribs.length) { 6184 prefixAndAttribs.push(attribs.join(', ')); 6185 } 6186 6187 this._container.innerHTML = prefixAndAttribs.join(' | '); 6188 } 6189}); 6190 6191// @namespace Map 6192// @section Control options 6193// @option attributionControl: Boolean = true 6194// Whether a [attribution control](#control-attribution) is added to the map by default. 6195Map.mergeOptions({ 6196 attributionControl: true 6197}); 6198 6199Map.addInitHook(function () { 6200 if (this.options.attributionControl) { 6201 new Attribution().addTo(this); 6202 } 6203}); 6204 6205// @namespace Control.Attribution 6206// @factory L.control.attribution(options: Control.Attribution options) 6207// Creates an attribution control. 6208var attribution = function (options) { 6209 return new Attribution(options); 6210}; 6211 6212Control.Layers = Layers; 6213Control.Zoom = Zoom; 6214Control.Scale = Scale; 6215Control.Attribution = Attribution; 6216 6217control.layers = layers; 6218control.zoom = zoom; 6219control.scale = scale; 6220control.attribution = attribution; 6221 6222/* 6223 L.Handler is a base class for handler classes that are used internally to inject 6224 interaction features like dragging to classes like Map and Marker. 6225*/ 6226 6227// @class Handler 6228// @aka L.Handler 6229// Abstract class for map interaction handlers 6230 6231var Handler = Class.extend({ 6232 initialize: function (map) { 6233 this._map = map; 6234 }, 6235 6236 // @method enable(): this 6237 // Enables the handler 6238 enable: function () { 6239 if (this._enabled) { return this; } 6240 6241 this._enabled = true; 6242 this.addHooks(); 6243 return this; 6244 }, 6245 6246 // @method disable(): this 6247 // Disables the handler 6248 disable: function () { 6249 if (!this._enabled) { return this; } 6250 6251 this._enabled = false; 6252 this.removeHooks(); 6253 return this; 6254 }, 6255 6256 // @method enabled(): Boolean 6257 // Returns `true` if the handler is enabled 6258 enabled: function () { 6259 return !!this._enabled; 6260 } 6261 6262 // @section Extension methods 6263 // Classes inheriting from `Handler` must implement the two following methods: 6264 // @method addHooks() 6265 // Called when the handler is enabled, should add event hooks. 6266 // @method removeHooks() 6267 // Called when the handler is disabled, should remove the event hooks added previously. 6268}); 6269 6270// @section There is static function which can be called without instantiating L.Handler: 6271// @function addTo(map: Map, name: String): this 6272// Adds a new Handler to the given map with the given name. 6273Handler.addTo = function (map, name) { 6274 map.addHandler(name, this); 6275 return this; 6276}; 6277 6278var Mixin = {Events: Events}; 6279 6280/* 6281 * @class Draggable 6282 * @aka L.Draggable 6283 * @inherits Evented 6284 * 6285 * A class for making DOM elements draggable (including touch support). 6286 * Used internally for map and marker dragging. Only works for elements 6287 * that were positioned with [`L.DomUtil.setPosition`](#domutil-setposition). 6288 * 6289 * @example 6290 * ```js 6291 * var draggable = new L.Draggable(elementToDrag); 6292 * draggable.enable(); 6293 * ``` 6294 */ 6295 6296var START = touch ? 'touchstart mousedown' : 'mousedown'; 6297var END = { 6298 mousedown: 'mouseup', 6299 touchstart: 'touchend', 6300 pointerdown: 'touchend', 6301 MSPointerDown: 'touchend' 6302}; 6303var MOVE = { 6304 mousedown: 'mousemove', 6305 touchstart: 'touchmove', 6306 pointerdown: 'touchmove', 6307 MSPointerDown: 'touchmove' 6308}; 6309 6310 6311var Draggable = Evented.extend({ 6312 6313 options: { 6314 // @section 6315 // @aka Draggable options 6316 // @option clickTolerance: Number = 3 6317 // The max number of pixels a user can shift the mouse pointer during a click 6318 // for it to be considered a valid click (as opposed to a mouse drag). 6319 clickTolerance: 3 6320 }, 6321 6322 // @constructor L.Draggable(el: HTMLElement, dragHandle?: HTMLElement, preventOutline?: Boolean, options?: Draggable options) 6323 // Creates a `Draggable` object for moving `el` when you start dragging the `dragHandle` element (equals `el` itself by default). 6324 initialize: function (element, dragStartTarget, preventOutline$$1, options) { 6325 setOptions(this, options); 6326 6327 this._element = element; 6328 this._dragStartTarget = dragStartTarget || element; 6329 this._preventOutline = preventOutline$$1; 6330 }, 6331 6332 // @method enable() 6333 // Enables the dragging ability 6334 enable: function () { 6335 if (this._enabled) { return; } 6336 6337 on(this._dragStartTarget, START, this._onDown, this); 6338 6339 this._enabled = true; 6340 }, 6341 6342 // @method disable() 6343 // Disables the dragging ability 6344 disable: function () { 6345 if (!this._enabled) { return; } 6346 6347 // If we're currently dragging this draggable, 6348 // disabling it counts as first ending the drag. 6349 if (Draggable._dragging === this) { 6350 this.finishDrag(); 6351 } 6352 6353 off(this._dragStartTarget, START, this._onDown, this); 6354 6355 this._enabled = false; 6356 this._moved = false; 6357 }, 6358 6359 _onDown: function (e) { 6360 // Ignore simulated events, since we handle both touch and 6361 // mouse explicitly; otherwise we risk getting duplicates of 6362 // touch events, see #4315. 6363 // Also ignore the event if disabled; this happens in IE11 6364 // under some circumstances, see #3666. 6365 if (e._simulated || !this._enabled) { return; } 6366 6367 this._moved = false; 6368 6369 if (hasClass(this._element, 'leaflet-zoom-anim')) { return; } 6370 6371 if (Draggable._dragging || e.shiftKey || ((e.which !== 1) && (e.button !== 1) && !e.touches)) { return; } 6372 Draggable._dragging = this; // Prevent dragging multiple objects at once. 6373 6374 if (this._preventOutline) { 6375 preventOutline(this._element); 6376 } 6377 6378 disableImageDrag(); 6379 disableTextSelection(); 6380 6381 if (this._moving) { return; } 6382 6383 // @event down: Event 6384 // Fired when a drag is about to start. 6385 this.fire('down'); 6386 6387 var first = e.touches ? e.touches[0] : e, 6388 sizedParent = getSizedParentNode(this._element); 6389 6390 this._startPoint = new Point(first.clientX, first.clientY); 6391 6392 // Cache the scale, so that we can continuously compensate for it during drag (_onMove). 6393 this._parentScale = getScale(sizedParent); 6394 6395 on(document, MOVE[e.type], this._onMove, this); 6396 on(document, END[e.type], this._onUp, this); 6397 }, 6398 6399 _onMove: function (e) { 6400 // Ignore simulated events, since we handle both touch and 6401 // mouse explicitly; otherwise we risk getting duplicates of 6402 // touch events, see #4315. 6403 // Also ignore the event if disabled; this happens in IE11 6404 // under some circumstances, see #3666. 6405 if (e._simulated || !this._enabled) { return; } 6406 6407 if (e.touches && e.touches.length > 1) { 6408 this._moved = true; 6409 return; 6410 } 6411 6412 var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e), 6413 offset = new Point(first.clientX, first.clientY)._subtract(this._startPoint); 6414 6415 if (!offset.x && !offset.y) { return; } 6416 if (Math.abs(offset.x) + Math.abs(offset.y) < this.options.clickTolerance) { return; } 6417 6418 // We assume that the parent container's position, border and scale do not change for the duration of the drag. 6419 // Therefore there is no need to account for the position and border (they are eliminated by the subtraction) 6420 // and we can use the cached value for the scale. 6421 offset.x /= this._parentScale.x; 6422 offset.y /= this._parentScale.y; 6423 6424 preventDefault(e); 6425 6426 if (!this._moved) { 6427 // @event dragstart: Event 6428 // Fired when a drag starts 6429 this.fire('dragstart'); 6430 6431 this._moved = true; 6432 this._startPos = getPosition(this._element).subtract(offset); 6433 6434 addClass(document.body, 'leaflet-dragging'); 6435 6436 this._lastTarget = e.target || e.srcElement; 6437 // IE and Edge do not give the <use> element, so fetch it 6438 // if necessary 6439 if ((window.SVGElementInstance) && (this._lastTarget instanceof SVGElementInstance)) { 6440 this._lastTarget = this._lastTarget.correspondingUseElement; 6441 } 6442 addClass(this._lastTarget, 'leaflet-drag-target'); 6443 } 6444 6445 this._newPos = this._startPos.add(offset); 6446 this._moving = true; 6447 6448 cancelAnimFrame(this._animRequest); 6449 this._lastEvent = e; 6450 this._animRequest = requestAnimFrame(this._updatePosition, this, true); 6451 }, 6452 6453 _updatePosition: function () { 6454 var e = {originalEvent: this._lastEvent}; 6455 6456 // @event predrag: Event 6457 // Fired continuously during dragging *before* each corresponding 6458 // update of the element's position. 6459 this.fire('predrag', e); 6460 setPosition(this._element, this._newPos); 6461 6462 // @event drag: Event 6463 // Fired continuously during dragging. 6464 this.fire('drag', e); 6465 }, 6466 6467 _onUp: function (e) { 6468 // Ignore simulated events, since we handle both touch and 6469 // mouse explicitly; otherwise we risk getting duplicates of 6470 // touch events, see #4315. 6471 // Also ignore the event if disabled; this happens in IE11 6472 // under some circumstances, see #3666. 6473 if (e._simulated || !this._enabled) { return; } 6474 this.finishDrag(); 6475 }, 6476 6477 finishDrag: function () { 6478 removeClass(document.body, 'leaflet-dragging'); 6479 6480 if (this._lastTarget) { 6481 removeClass(this._lastTarget, 'leaflet-drag-target'); 6482 this._lastTarget = null; 6483 } 6484 6485 for (var i in MOVE) { 6486 off(document, MOVE[i], this._onMove, this); 6487 off(document, END[i], this._onUp, this); 6488 } 6489 6490 enableImageDrag(); 6491 enableTextSelection(); 6492 6493 if (this._moved && this._moving) { 6494 // ensure drag is not fired after dragend 6495 cancelAnimFrame(this._animRequest); 6496 6497 // @event dragend: DragEndEvent 6498 // Fired when the drag ends. 6499 this.fire('dragend', { 6500 distance: this._newPos.distanceTo(this._startPos) 6501 }); 6502 } 6503 6504 this._moving = false; 6505 Draggable._dragging = false; 6506 } 6507 6508}); 6509 6510/* 6511 * @namespace LineUtil 6512 * 6513 * Various utility functions for polyline points processing, used by Leaflet internally to make polylines lightning-fast. 6514 */ 6515 6516// Simplify polyline with vertex reduction and Douglas-Peucker simplification. 6517// Improves rendering performance dramatically by lessening the number of points to draw. 6518 6519// @function simplify(points: Point[], tolerance: Number): Point[] 6520// Dramatically reduces the number of points in a polyline while retaining 6521// its shape and returns a new array of simplified points, using the 6522// [Douglas-Peucker algorithm](http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm). 6523// Used for a huge performance boost when processing/displaying Leaflet polylines for 6524// each zoom level and also reducing visual noise. tolerance affects the amount of 6525// simplification (lesser value means higher quality but slower and with more points). 6526// Also released as a separated micro-library [Simplify.js](http://mourner.github.com/simplify-js/). 6527function simplify(points, tolerance) { 6528 if (!tolerance || !points.length) { 6529 return points.slice(); 6530 } 6531 6532 var sqTolerance = tolerance * tolerance; 6533 6534 // stage 1: vertex reduction 6535 points = _reducePoints(points, sqTolerance); 6536 6537 // stage 2: Douglas-Peucker simplification 6538 points = _simplifyDP(points, sqTolerance); 6539 6540 return points; 6541} 6542 6543// @function pointToSegmentDistance(p: Point, p1: Point, p2: Point): Number 6544// Returns the distance between point `p` and segment `p1` to `p2`. 6545function pointToSegmentDistance(p, p1, p2) { 6546 return Math.sqrt(_sqClosestPointOnSegment(p, p1, p2, true)); 6547} 6548 6549// @function closestPointOnSegment(p: Point, p1: Point, p2: Point): Number 6550// Returns the closest point from a point `p` on a segment `p1` to `p2`. 6551function closestPointOnSegment(p, p1, p2) { 6552 return _sqClosestPointOnSegment(p, p1, p2); 6553} 6554 6555// Douglas-Peucker simplification, see http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm 6556function _simplifyDP(points, sqTolerance) { 6557 6558 var len = points.length, 6559 ArrayConstructor = typeof Uint8Array !== undefined + '' ? Uint8Array : Array, 6560 markers = new ArrayConstructor(len); 6561 6562 markers[0] = markers[len - 1] = 1; 6563 6564 _simplifyDPStep(points, markers, sqTolerance, 0, len - 1); 6565 6566 var i, 6567 newPoints = []; 6568 6569 for (i = 0; i < len; i++) { 6570 if (markers[i]) { 6571 newPoints.push(points[i]); 6572 } 6573 } 6574 6575 return newPoints; 6576} 6577 6578function _simplifyDPStep(points, markers, sqTolerance, first, last) { 6579 6580 var maxSqDist = 0, 6581 index, i, sqDist; 6582 6583 for (i = first + 1; i <= last - 1; i++) { 6584 sqDist = _sqClosestPointOnSegment(points[i], points[first], points[last], true); 6585 6586 if (sqDist > maxSqDist) { 6587 index = i; 6588 maxSqDist = sqDist; 6589 } 6590 } 6591 6592 if (maxSqDist > sqTolerance) { 6593 markers[index] = 1; 6594 6595 _simplifyDPStep(points, markers, sqTolerance, first, index); 6596 _simplifyDPStep(points, markers, sqTolerance, index, last); 6597 } 6598} 6599 6600// reduce points that are too close to each other to a single point 6601function _reducePoints(points, sqTolerance) { 6602 var reducedPoints = [points[0]]; 6603 6604 for (var i = 1, prev = 0, len = points.length; i < len; i++) { 6605 if (_sqDist(points[i], points[prev]) > sqTolerance) { 6606 reducedPoints.push(points[i]); 6607 prev = i; 6608 } 6609 } 6610 if (prev < len - 1) { 6611 reducedPoints.push(points[len - 1]); 6612 } 6613 return reducedPoints; 6614} 6615 6616var _lastCode; 6617 6618// @function clipSegment(a: Point, b: Point, bounds: Bounds, useLastCode?: Boolean, round?: Boolean): Point[]|Boolean 6619// Clips the segment a to b by rectangular bounds with the 6620// [Cohen-Sutherland algorithm](https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm) 6621// (modifying the segment points directly!). Used by Leaflet to only show polyline 6622// points that are on the screen or near, increasing performance. 6623function clipSegment(a, b, bounds, useLastCode, round) { 6624 var codeA = useLastCode ? _lastCode : _getBitCode(a, bounds), 6625 codeB = _getBitCode(b, bounds), 6626 6627 codeOut, p, newCode; 6628 6629 // save 2nd code to avoid calculating it on the next segment 6630 _lastCode = codeB; 6631 6632 while (true) { 6633 // if a,b is inside the clip window (trivial accept) 6634 if (!(codeA | codeB)) { 6635 return [a, b]; 6636 } 6637 6638 // if a,b is outside the clip window (trivial reject) 6639 if (codeA & codeB) { 6640 return false; 6641 } 6642 6643 // other cases 6644 codeOut = codeA || codeB; 6645 p = _getEdgeIntersection(a, b, codeOut, bounds, round); 6646 newCode = _getBitCode(p, bounds); 6647 6648 if (codeOut === codeA) { 6649 a = p; 6650 codeA = newCode; 6651 } else { 6652 b = p; 6653 codeB = newCode; 6654 } 6655 } 6656} 6657 6658function _getEdgeIntersection(a, b, code, bounds, round) { 6659 var dx = b.x - a.x, 6660 dy = b.y - a.y, 6661 min = bounds.min, 6662 max = bounds.max, 6663 x, y; 6664 6665 if (code & 8) { // top 6666 x = a.x + dx * (max.y - a.y) / dy; 6667 y = max.y; 6668 6669 } else if (code & 4) { // bottom 6670 x = a.x + dx * (min.y - a.y) / dy; 6671 y = min.y; 6672 6673 } else if (code & 2) { // right 6674 x = max.x; 6675 y = a.y + dy * (max.x - a.x) / dx; 6676 6677 } else if (code & 1) { // left 6678 x = min.x; 6679 y = a.y + dy * (min.x - a.x) / dx; 6680 } 6681 6682 return new Point(x, y, round); 6683} 6684 6685function _getBitCode(p, bounds) { 6686 var code = 0; 6687 6688 if (p.x < bounds.min.x) { // left 6689 code |= 1; 6690 } else if (p.x > bounds.max.x) { // right 6691 code |= 2; 6692 } 6693 6694 if (p.y < bounds.min.y) { // bottom 6695 code |= 4; 6696 } else if (p.y > bounds.max.y) { // top 6697 code |= 8; 6698 } 6699 6700 return code; 6701} 6702 6703// square distance (to avoid unnecessary Math.sqrt calls) 6704function _sqDist(p1, p2) { 6705 var dx = p2.x - p1.x, 6706 dy = p2.y - p1.y; 6707 return dx * dx + dy * dy; 6708} 6709 6710// return closest point on segment or distance to that point 6711function _sqClosestPointOnSegment(p, p1, p2, sqDist) { 6712 var x = p1.x, 6713 y = p1.y, 6714 dx = p2.x - x, 6715 dy = p2.y - y, 6716 dot = dx * dx + dy * dy, 6717 t; 6718 6719 if (dot > 0) { 6720 t = ((p.x - x) * dx + (p.y - y) * dy) / dot; 6721 6722 if (t > 1) { 6723 x = p2.x; 6724 y = p2.y; 6725 } else if (t > 0) { 6726 x += dx * t; 6727 y += dy * t; 6728 } 6729 } 6730 6731 dx = p.x - x; 6732 dy = p.y - y; 6733 6734 return sqDist ? dx * dx + dy * dy : new Point(x, y); 6735} 6736 6737 6738// @function isFlat(latlngs: LatLng[]): Boolean 6739// Returns true if `latlngs` is a flat array, false is nested. 6740function isFlat(latlngs) { 6741 return !isArray(latlngs[0]) || (typeof latlngs[0][0] !== 'object' && typeof latlngs[0][0] !== 'undefined'); 6742} 6743 6744function _flat(latlngs) { 6745 console.warn('Deprecated use of _flat, please use L.LineUtil.isFlat instead.'); 6746 return isFlat(latlngs); 6747} 6748 6749 6750var LineUtil = (Object.freeze || Object)({ 6751 simplify: simplify, 6752 pointToSegmentDistance: pointToSegmentDistance, 6753 closestPointOnSegment: closestPointOnSegment, 6754 clipSegment: clipSegment, 6755 _getEdgeIntersection: _getEdgeIntersection, 6756 _getBitCode: _getBitCode, 6757 _sqClosestPointOnSegment: _sqClosestPointOnSegment, 6758 isFlat: isFlat, 6759 _flat: _flat 6760}); 6761 6762/* 6763 * @namespace PolyUtil 6764 * Various utility functions for polygon geometries. 6765 */ 6766 6767/* @function clipPolygon(points: Point[], bounds: Bounds, round?: Boolean): Point[] 6768 * 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)). 6769 * Used by Leaflet to only show polygon points that are on the screen or near, increasing 6770 * performance. Note that polygon points needs different algorithm for clipping 6771 * than polyline, so there's a separate method for it. 6772 */ 6773function clipPolygon(points, bounds, round) { 6774 var clippedPoints, 6775 edges = [1, 4, 2, 8], 6776 i, j, k, 6777 a, b, 6778 len, edge, p; 6779 6780 for (i = 0, len = points.length; i < len; i++) { 6781 points[i]._code = _getBitCode(points[i], bounds); 6782 } 6783 6784 // for each edge (left, bottom, right, top) 6785 for (k = 0; k < 4; k++) { 6786 edge = edges[k]; 6787 clippedPoints = []; 6788 6789 for (i = 0, len = points.length, j = len - 1; i < len; j = i++) { 6790 a = points[i]; 6791 b = points[j]; 6792 6793 // if a is inside the clip window 6794 if (!(a._code & edge)) { 6795 // if b is outside the clip window (a->b goes out of screen) 6796 if (b._code & edge) { 6797 p = _getEdgeIntersection(b, a, edge, bounds, round); 6798 p._code = _getBitCode(p, bounds); 6799 clippedPoints.push(p); 6800 } 6801 clippedPoints.push(a); 6802 6803 // else if b is inside the clip window (a->b enters the screen) 6804 } else if (!(b._code & edge)) { 6805 p = _getEdgeIntersection(b, a, edge, bounds, round); 6806 p._code = _getBitCode(p, bounds); 6807 clippedPoints.push(p); 6808 } 6809 } 6810 points = clippedPoints; 6811 } 6812 6813 return points; 6814} 6815 6816 6817var PolyUtil = (Object.freeze || Object)({ 6818 clipPolygon: clipPolygon 6819}); 6820 6821/* 6822 * @namespace Projection 6823 * @section 6824 * Leaflet comes with a set of already defined Projections out of the box: 6825 * 6826 * @projection L.Projection.LonLat 6827 * 6828 * Equirectangular, or Plate Carree projection — the most simple projection, 6829 * mostly used by GIS enthusiasts. Directly maps `x` as longitude, and `y` as 6830 * latitude. Also suitable for flat worlds, e.g. game maps. Used by the 6831 * `EPSG:4326` and `Simple` CRS. 6832 */ 6833 6834var LonLat = { 6835 project: function (latlng) { 6836 return new Point(latlng.lng, latlng.lat); 6837 }, 6838 6839 unproject: function (point) { 6840 return new LatLng(point.y, point.x); 6841 }, 6842 6843 bounds: new Bounds([-180, -90], [180, 90]) 6844}; 6845 6846/* 6847 * @namespace Projection 6848 * @projection L.Projection.Mercator 6849 * 6850 * Elliptical Mercator projection — more complex than Spherical Mercator. Assumes that Earth is an ellipsoid. Used by the EPSG:3395 CRS. 6851 */ 6852 6853var Mercator = { 6854 R: 6378137, 6855 R_MINOR: 6356752.314245179, 6856 6857 bounds: new Bounds([-20037508.34279, -15496570.73972], [20037508.34279, 18764656.23138]), 6858 6859 project: function (latlng) { 6860 var d = Math.PI / 180, 6861 r = this.R, 6862 y = latlng.lat * d, 6863 tmp = this.R_MINOR / r, 6864 e = Math.sqrt(1 - tmp * tmp), 6865 con = e * Math.sin(y); 6866 6867 var ts = Math.tan(Math.PI / 4 - y / 2) / Math.pow((1 - con) / (1 + con), e / 2); 6868 y = -r * Math.log(Math.max(ts, 1E-10)); 6869 6870 return new Point(latlng.lng * d * r, y); 6871 }, 6872 6873 unproject: function (point) { 6874 var d = 180 / Math.PI, 6875 r = this.R, 6876 tmp = this.R_MINOR / r, 6877 e = Math.sqrt(1 - tmp * tmp), 6878 ts = Math.exp(-point.y / r), 6879 phi = Math.PI / 2 - 2 * Math.atan(ts); 6880 6881 for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) { 6882 con = e * Math.sin(phi); 6883 con = Math.pow((1 - con) / (1 + con), e / 2); 6884 dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi; 6885 phi += dphi; 6886 } 6887 6888 return new LatLng(phi * d, point.x * d / r); 6889 } 6890}; 6891 6892/* 6893 * @class Projection 6894 6895 * An object with methods for projecting geographical coordinates of the world onto 6896 * a flat surface (and back). See [Map projection](http://en.wikipedia.org/wiki/Map_projection). 6897 6898 * @property bounds: Bounds 6899 * The bounds (specified in CRS units) where the projection is valid 6900 6901 * @method project(latlng: LatLng): Point 6902 * Projects geographical coordinates into a 2D point. 6903 * Only accepts actual `L.LatLng` instances, not arrays. 6904 6905 * @method unproject(point: Point): LatLng 6906 * The inverse of `project`. Projects a 2D point into a geographical location. 6907 * Only accepts actual `L.Point` instances, not arrays. 6908 6909 * Note that the projection instances do not inherit from Leafet's `Class` object, 6910 * and can't be instantiated. Also, new classes can't inherit from them, 6911 * and methods can't be added to them with the `include` function. 6912 6913 */ 6914 6915 6916 6917 6918var index = (Object.freeze || Object)({ 6919 LonLat: LonLat, 6920 Mercator: Mercator, 6921 SphericalMercator: SphericalMercator 6922}); 6923 6924/* 6925 * @namespace CRS 6926 * @crs L.CRS.EPSG3395 6927 * 6928 * Rarely used by some commercial tile providers. Uses Elliptical Mercator projection. 6929 */ 6930var EPSG3395 = extend({}, Earth, { 6931 code: 'EPSG:3395', 6932 projection: Mercator, 6933 6934 transformation: (function () { 6935 var scale = 0.5 / (Math.PI * Mercator.R); 6936 return toTransformation(scale, 0.5, -scale, 0.5); 6937 }()) 6938}); 6939 6940/* 6941 * @namespace CRS 6942 * @crs L.CRS.EPSG4326 6943 * 6944 * A common CRS among GIS enthusiasts. Uses simple Equirectangular projection. 6945 * 6946 * Leaflet 1.0.x complies with the [TMS coordinate scheme for EPSG:4326](https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification#global-geodetic), 6947 * which is a breaking change from 0.7.x behaviour. If you are using a `TileLayer` 6948 * with this CRS, ensure that there are two 256x256 pixel tiles covering the 6949 * whole earth at zoom level zero, and that the tile coordinate origin is (-180,+90), 6950 * or (-180,-90) for `TileLayer`s with [the `tms` option](#tilelayer-tms) set. 6951 */ 6952 6953var EPSG4326 = extend({}, Earth, { 6954 code: 'EPSG:4326', 6955 projection: LonLat, 6956 transformation: toTransformation(1 / 180, 1, -1 / 180, 0.5) 6957}); 6958 6959/* 6960 * @namespace CRS 6961 * @crs L.CRS.Simple 6962 * 6963 * A simple CRS that maps longitude and latitude into `x` and `y` directly. 6964 * May be used for maps of flat surfaces (e.g. game maps). Note that the `y` 6965 * axis should still be inverted (going from bottom to top). `distance()` returns 6966 * simple euclidean distance. 6967 */ 6968 6969var Simple = extend({}, CRS, { 6970 projection: LonLat, 6971 transformation: toTransformation(1, 0, -1, 0), 6972 6973 scale: function (zoom) { 6974 return Math.pow(2, zoom); 6975 }, 6976 6977 zoom: function (scale) { 6978 return Math.log(scale) / Math.LN2; 6979 }, 6980 6981 distance: function (latlng1, latlng2) { 6982 var dx = latlng2.lng - latlng1.lng, 6983 dy = latlng2.lat - latlng1.lat; 6984 6985 return Math.sqrt(dx * dx + dy * dy); 6986 }, 6987 6988 infinite: true 6989}); 6990 6991CRS.Earth = Earth; 6992CRS.EPSG3395 = EPSG3395; 6993CRS.EPSG3857 = EPSG3857; 6994CRS.EPSG900913 = EPSG900913; 6995CRS.EPSG4326 = EPSG4326; 6996CRS.Simple = Simple; 6997 6998/* 6999 * @class Layer 7000 * @inherits Evented 7001 * @aka L.Layer 7002 * @aka ILayer 7003 * 7004 * A set of methods from the Layer base class that all Leaflet layers use. 7005 * Inherits all methods, options and events from `L.Evented`. 7006 * 7007 * @example 7008 * 7009 * ```js 7010 * var layer = L.marker(latlng).addTo(map); 7011 * layer.addTo(map); 7012 * layer.remove(); 7013 * ``` 7014 * 7015 * @event add: Event 7016 * Fired after the layer is added to a map 7017 * 7018 * @event remove: Event 7019 * Fired after the layer is removed from a map 7020 */ 7021 7022 7023var Layer = Evented.extend({ 7024 7025 // Classes extending `L.Layer` will inherit the following options: 7026 options: { 7027 // @option pane: String = 'overlayPane' 7028 // 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. 7029 pane: 'overlayPane', 7030 7031 // @option attribution: String = null 7032 // 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. 7033 attribution: null, 7034 7035 bubblingMouseEvents: true 7036 }, 7037 7038 /* @section 7039 * Classes extending `L.Layer` will inherit the following methods: 7040 * 7041 * @method addTo(map: Map|LayerGroup): this 7042 * Adds the layer to the given map or layer group. 7043 */ 7044 addTo: function (map) { 7045 map.addLayer(this); 7046 return this; 7047 }, 7048 7049 // @method remove: this 7050 // Removes the layer from the map it is currently active on. 7051 remove: function () { 7052 return this.removeFrom(this._map || this._mapToAdd); 7053 }, 7054 7055 // @method removeFrom(map: Map): this 7056 // Removes the layer from the given map 7057 removeFrom: function (obj) { 7058 if (obj) { 7059 obj.removeLayer(this); 7060 } 7061 return this; 7062 }, 7063 7064 // @method getPane(name? : String): HTMLElement 7065 // Returns the `HTMLElement` representing the named pane on the map. If `name` is omitted, returns the pane for this layer. 7066 getPane: function (name) { 7067 return this._map.getPane(name ? (this.options[name] || name) : this.options.pane); 7068 }, 7069 7070 addInteractiveTarget: function (targetEl) { 7071 this._map._targets[stamp(targetEl)] = this; 7072 return this; 7073 }, 7074 7075 removeInteractiveTarget: function (targetEl) { 7076 delete this._map._targets[stamp(targetEl)]; 7077 return this; 7078 }, 7079 7080 // @method getAttribution: String 7081 // Used by the `attribution control`, returns the [attribution option](#gridlayer-attribution). 7082 getAttribution: function () { 7083 return this.options.attribution; 7084 }, 7085 7086 _layerAdd: function (e) { 7087 var map = e.target; 7088 7089 // check in case layer gets added and then removed before the map is ready 7090 if (!map.hasLayer(this)) { return; } 7091 7092 this._map = map; 7093 this._zoomAnimated = map._zoomAnimated; 7094 7095 if (this.getEvents) { 7096 var events = this.getEvents(); 7097 map.on(events, this); 7098 this.once('remove', function () { 7099 map.off(events, this); 7100 }, this); 7101 } 7102 7103 this.onAdd(map); 7104 7105 if (this.getAttribution && map.attributionControl) { 7106 map.attributionControl.addAttribution(this.getAttribution()); 7107 } 7108 7109 this.fire('add'); 7110 map.fire('layeradd', {layer: this}); 7111 } 7112}); 7113 7114/* @section Extension methods 7115 * @uninheritable 7116 * 7117 * Every layer should extend from `L.Layer` and (re-)implement the following methods. 7118 * 7119 * @method onAdd(map: Map): this 7120 * 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). 7121 * 7122 * @method onRemove(map: Map): this 7123 * 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). 7124 * 7125 * @method getEvents(): Object 7126 * 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. 7127 * 7128 * @method getAttribution(): String 7129 * This optional method should return a string containing HTML to be shown on the `Attribution control` whenever the layer is visible. 7130 * 7131 * @method beforeAdd(map: Map): this 7132 * 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. 7133 */ 7134 7135 7136/* @namespace Map 7137 * @section Layer events 7138 * 7139 * @event layeradd: LayerEvent 7140 * Fired when a new layer is added to the map. 7141 * 7142 * @event layerremove: LayerEvent 7143 * Fired when some layer is removed from the map 7144 * 7145 * @section Methods for Layers and Controls 7146 */ 7147Map.include({ 7148 // @method addLayer(layer: Layer): this 7149 // Adds the given layer to the map 7150 addLayer: function (layer) { 7151 if (!layer._layerAdd) { 7152 throw new Error('The provided object is not a Layer.'); 7153 } 7154 7155 var id = stamp(layer); 7156 if (this._layers[id]) { return this; } 7157 this._layers[id] = layer; 7158 7159 layer._mapToAdd = this; 7160 7161 if (layer.beforeAdd) { 7162 layer.beforeAdd(this); 7163 } 7164 7165 this.whenReady(layer._layerAdd, layer); 7166 7167 return this; 7168 }, 7169 7170 // @method removeLayer(layer: Layer): this 7171 // Removes the given layer from the map. 7172 removeLayer: function (layer) { 7173 var id = stamp(layer); 7174 7175 if (!this._layers[id]) { return this; } 7176 7177 if (this._loaded) { 7178 layer.onRemove(this); 7179 } 7180 7181 if (layer.getAttribution && this.attributionControl) { 7182 this.attributionControl.removeAttribution(layer.getAttribution()); 7183 } 7184 7185 delete this._layers[id]; 7186 7187 if (this._loaded) { 7188 this.fire('layerremove', {layer: layer}); 7189 layer.fire('remove'); 7190 } 7191 7192 layer._map = layer._mapToAdd = null; 7193 7194 return this; 7195 }, 7196 7197 // @method hasLayer(layer: Layer): Boolean 7198 // Returns `true` if the given layer is currently added to the map 7199 hasLayer: function (layer) { 7200 return !!layer && (stamp(layer) in this._layers); 7201 }, 7202 7203 /* @method eachLayer(fn: Function, context?: Object): this 7204 * Iterates over the layers of the map, optionally specifying context of the iterator function. 7205 * ``` 7206 * map.eachLayer(function(layer){ 7207 * layer.bindPopup('Hello'); 7208 * }); 7209 * ``` 7210 */ 7211 eachLayer: function (method, context) { 7212 for (var i in this._layers) { 7213 method.call(context, this._layers[i]); 7214 } 7215 return this; 7216 }, 7217 7218 _addLayers: function (layers) { 7219 layers = layers ? (isArray(layers) ? layers : [layers]) : []; 7220 7221 for (var i = 0, len = layers.length; i < len; i++) { 7222 this.addLayer(layers[i]); 7223 } 7224 }, 7225 7226 _addZoomLimit: function (layer) { 7227 if (isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom)) { 7228 this._zoomBoundLayers[stamp(layer)] = layer; 7229 this._updateZoomLevels(); 7230 } 7231 }, 7232 7233 _removeZoomLimit: function (layer) { 7234 var id = stamp(layer); 7235 7236 if (this._zoomBoundLayers[id]) { 7237 delete this._zoomBoundLayers[id]; 7238 this._updateZoomLevels(); 7239 } 7240 }, 7241 7242 _updateZoomLevels: function () { 7243 var minZoom = Infinity, 7244 maxZoom = -Infinity, 7245 oldZoomSpan = this._getZoomSpan(); 7246 7247 for (var i in this._zoomBoundLayers) { 7248 var options = this._zoomBoundLayers[i].options; 7249 7250 minZoom = options.minZoom === undefined ? minZoom : Math.min(minZoom, options.minZoom); 7251 maxZoom = options.maxZoom === undefined ? maxZoom : Math.max(maxZoom, options.maxZoom); 7252 } 7253 7254 this._layersMaxZoom = maxZoom === -Infinity ? undefined : maxZoom; 7255 this._layersMinZoom = minZoom === Infinity ? undefined : minZoom; 7256 7257 // @section Map state change events 7258 // @event zoomlevelschange: Event 7259 // Fired when the number of zoomlevels on the map is changed due 7260 // to adding or removing a layer. 7261 if (oldZoomSpan !== this._getZoomSpan()) { 7262 this.fire('zoomlevelschange'); 7263 } 7264 7265 if (this.options.maxZoom === undefined && this._layersMaxZoom && this.getZoom() > this._layersMaxZoom) { 7266 this.setZoom(this._layersMaxZoom); 7267 } 7268 if (this.options.minZoom === undefined && this._layersMinZoom && this.getZoom() < this._layersMinZoom) { 7269 this.setZoom(this._layersMinZoom); 7270 } 7271 } 7272}); 7273 7274/* 7275 * @class LayerGroup 7276 * @aka L.LayerGroup 7277 * @inherits Layer 7278 * 7279 * Used to group several layers and handle them as one. If you add it to the map, 7280 * any layers added or removed from the group will be added/removed on the map as 7281 * well. Extends `Layer`. 7282 * 7283 * @example 7284 * 7285 * ```js 7286 * L.layerGroup([marker1, marker2]) 7287 * .addLayer(polyline) 7288 * .addTo(map); 7289 * ``` 7290 */ 7291 7292var LayerGroup = Layer.extend({ 7293 7294 initialize: function (layers, options) { 7295 setOptions(this, options); 7296 7297 this._layers = {}; 7298 7299 var i, len; 7300 7301 if (layers) { 7302 for (i = 0, len = layers.length; i < len; i++) { 7303 this.addLayer(layers[i]); 7304 } 7305 } 7306 }, 7307 7308 // @method addLayer(layer: Layer): this 7309 // Adds the given layer to the group. 7310 addLayer: function (layer) { 7311 var id = this.getLayerId(layer); 7312 7313 this._layers[id] = layer; 7314 7315 if (this._map) { 7316 this._map.addLayer(layer); 7317 } 7318 7319 return this; 7320 }, 7321 7322 // @method removeLayer(layer: Layer): this 7323 // Removes the given layer from the group. 7324 // @alternative 7325 // @method removeLayer(id: Number): this 7326 // Removes the layer with the given internal ID from the group. 7327 removeLayer: function (layer) { 7328 var id = layer in this._layers ? layer : this.getLayerId(layer); 7329 7330 if (this._map && this._layers[id]) { 7331 this._map.removeLayer(this._layers[id]); 7332 } 7333 7334 delete this._layers[id]; 7335 7336 return this; 7337 }, 7338 7339 // @method hasLayer(layer: Layer): Boolean 7340 // Returns `true` if the given layer is currently added to the group. 7341 // @alternative 7342 // @method hasLayer(id: Number): Boolean 7343 // Returns `true` if the given internal ID is currently added to the group. 7344 hasLayer: function (layer) { 7345 return !!layer && (layer in this._layers || this.getLayerId(layer) in this._layers); 7346 }, 7347 7348 // @method clearLayers(): this 7349 // Removes all the layers from the group. 7350 clearLayers: function () { 7351 return this.eachLayer(this.removeLayer, this); 7352 }, 7353 7354 // @method invoke(methodName: String, …): this 7355 // Calls `methodName` on every layer contained in this group, passing any 7356 // additional parameters. Has no effect if the layers contained do not 7357 // implement `methodName`. 7358 invoke: function (methodName) { 7359 var args = Array.prototype.slice.call(arguments, 1), 7360 i, layer; 7361 7362 for (i in this._layers) { 7363 layer = this._layers[i]; 7364 7365 if (layer[methodName]) { 7366 layer[methodName].apply(layer, args); 7367 } 7368 } 7369 7370 return this; 7371 }, 7372 7373 onAdd: function (map) { 7374 this.eachLayer(map.addLayer, map); 7375 }, 7376 7377 onRemove: function (map) { 7378 this.eachLayer(map.removeLayer, map); 7379 }, 7380 7381 // @method eachLayer(fn: Function, context?: Object): this 7382 // Iterates over the layers of the group, optionally specifying context of the iterator function. 7383 // ```js 7384 // group.eachLayer(function (layer) { 7385 // layer.bindPopup('Hello'); 7386 // }); 7387 // ``` 7388 eachLayer: function (method, context) { 7389 for (var i in this._layers) { 7390 method.call(context, this._layers[i]); 7391 } 7392 return this; 7393 }, 7394 7395 // @method getLayer(id: Number): Layer 7396 // Returns the layer with the given internal ID. 7397 getLayer: function (id) { 7398 return this._layers[id]; 7399 }, 7400 7401 // @method getLayers(): Layer[] 7402 // Returns an array of all the layers added to the group. 7403 getLayers: function () { 7404 var layers = []; 7405 this.eachLayer(layers.push, layers); 7406 return layers; 7407 }, 7408 7409 // @method setZIndex(zIndex: Number): this 7410 // Calls `setZIndex` on every layer contained in this group, passing the z-index. 7411 setZIndex: function (zIndex) { 7412 return this.invoke('setZIndex', zIndex); 7413 }, 7414 7415 // @method getLayerId(layer: Layer): Number 7416 // Returns the internal ID for a layer 7417 getLayerId: function (layer) { 7418 return stamp(layer); 7419 } 7420}); 7421 7422 7423// @factory L.layerGroup(layers?: Layer[], options?: Object) 7424// Create a layer group, optionally given an initial set of layers and an `options` object. 7425var layerGroup = function (layers, options) { 7426 return new LayerGroup(layers, options); 7427}; 7428 7429/* 7430 * @class FeatureGroup 7431 * @aka L.FeatureGroup 7432 * @inherits LayerGroup 7433 * 7434 * Extended `LayerGroup` that makes it easier to do the same thing to all its member layers: 7435 * * [`bindPopup`](#layer-bindpopup) binds a popup to all of the layers at once (likewise with [`bindTooltip`](#layer-bindtooltip)) 7436 * * Events are propagated to the `FeatureGroup`, so if the group has an event 7437 * handler, it will handle events from any of the layers. This includes mouse events 7438 * and custom events. 7439 * * Has `layeradd` and `layerremove` events 7440 * 7441 * @example 7442 * 7443 * ```js 7444 * L.featureGroup([marker1, marker2, polyline]) 7445 * .bindPopup('Hello world!') 7446 * .on('click', function() { alert('Clicked on a member of the group!'); }) 7447 * .addTo(map); 7448 * ``` 7449 */ 7450 7451var FeatureGroup = LayerGroup.extend({ 7452 7453 addLayer: function (layer) { 7454 if (this.hasLayer(layer)) { 7455 return this; 7456 } 7457 7458 layer.addEventParent(this); 7459 7460 LayerGroup.prototype.addLayer.call(this, layer); 7461 7462 // @event layeradd: LayerEvent 7463 // Fired when a layer is added to this `FeatureGroup` 7464 return this.fire('layeradd', {layer: layer}); 7465 }, 7466 7467 removeLayer: function (layer) { 7468 if (!this.hasLayer(layer)) { 7469 return this; 7470 } 7471 if (layer in this._layers) { 7472 layer = this._layers[layer]; 7473 } 7474 7475 layer.removeEventParent(this); 7476 7477 LayerGroup.prototype.removeLayer.call(this, layer); 7478 7479 // @event layerremove: LayerEvent 7480 // Fired when a layer is removed from this `FeatureGroup` 7481 return this.fire('layerremove', {layer: layer}); 7482 }, 7483 7484 // @method setStyle(style: Path options): this 7485 // Sets the given path options to each layer of the group that has a `setStyle` method. 7486 setStyle: function (style) { 7487 return this.invoke('setStyle', style); 7488 }, 7489 7490 // @method bringToFront(): this 7491 // Brings the layer group to the top of all other layers 7492 bringToFront: function () { 7493 return this.invoke('bringToFront'); 7494 }, 7495 7496 // @method bringToBack(): this 7497 // Brings the layer group to the back of all other layers 7498 bringToBack: function () { 7499 return this.invoke('bringToBack'); 7500 }, 7501 7502 // @method getBounds(): LatLngBounds 7503 // Returns the LatLngBounds of the Feature Group (created from bounds and coordinates of its children). 7504 getBounds: function () { 7505 var bounds = new LatLngBounds(); 7506 7507 for (var id in this._layers) { 7508 var layer = this._layers[id]; 7509 bounds.extend(layer.getBounds ? layer.getBounds() : layer.getLatLng()); 7510 } 7511 return bounds; 7512 } 7513}); 7514 7515// @factory L.featureGroup(layers: Layer[]) 7516// Create a feature group, optionally given an initial set of layers. 7517var featureGroup = function (layers) { 7518 return new FeatureGroup(layers); 7519}; 7520 7521/* 7522 * @class Icon 7523 * @aka L.Icon 7524 * 7525 * Represents an icon to provide when creating a marker. 7526 * 7527 * @example 7528 * 7529 * ```js 7530 * var myIcon = L.icon({ 7531 * iconUrl: 'my-icon.png', 7532 * iconRetinaUrl: '[email protected]', 7533 * iconSize: [38, 95], 7534 * iconAnchor: [22, 94], 7535 * popupAnchor: [-3, -76], 7536 * shadowUrl: 'my-icon-shadow.png', 7537 * shadowRetinaUrl: '[email protected]', 7538 * shadowSize: [68, 95], 7539 * shadowAnchor: [22, 94] 7540 * }); 7541 * 7542 * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map); 7543 * ``` 7544 * 7545 * `L.Icon.Default` extends `L.Icon` and is the blue icon Leaflet uses for markers by default. 7546 * 7547 */ 7548 7549var Icon = Class.extend({ 7550 7551 /* @section 7552 * @aka Icon options 7553 * 7554 * @option iconUrl: String = null 7555 * **(required)** The URL to the icon image (absolute or relative to your script path). 7556 * 7557 * @option iconRetinaUrl: String = null 7558 * The URL to a retina sized version of the icon image (absolute or relative to your 7559 * script path). Used for Retina screen devices. 7560 * 7561 * @option iconSize: Point = null 7562 * Size of the icon image in pixels. 7563 * 7564 * @option iconAnchor: Point = null 7565 * The coordinates of the "tip" of the icon (relative to its top left corner). The icon 7566 * will be aligned so that this point is at the marker's geographical location. Centered 7567 * by default if size is specified, also can be set in CSS with negative margins. 7568 * 7569 * @option popupAnchor: Point = [0, 0] 7570 * The coordinates of the point from which popups will "open", relative to the icon anchor. 7571 * 7572 * @option tooltipAnchor: Point = [0, 0] 7573 * The coordinates of the point from which tooltips will "open", relative to the icon anchor. 7574 * 7575 * @option shadowUrl: String = null 7576 * The URL to the icon shadow image. If not specified, no shadow image will be created. 7577 * 7578 * @option shadowRetinaUrl: String = null 7579 * 7580 * @option shadowSize: Point = null 7581 * Size of the shadow image in pixels. 7582 * 7583 * @option shadowAnchor: Point = null 7584 * The coordinates of the "tip" of the shadow (relative to its top left corner) (the same 7585 * as iconAnchor if not specified). 7586 * 7587 * @option className: String = '' 7588 * A custom class name to assign to both icon and shadow images. Empty by default. 7589 */ 7590 7591 options: { 7592 popupAnchor: [0, 0], 7593 tooltipAnchor: [0, 0] 7594 }, 7595 7596 initialize: function (options) { 7597 setOptions(this, options); 7598 }, 7599 7600 // @method createIcon(oldIcon?: HTMLElement): HTMLElement 7601 // Called internally when the icon has to be shown, returns a `<img>` HTML element 7602 // styled according to the options. 7603 createIcon: function (oldIcon) { 7604 return this._createIcon('icon', oldIcon); 7605 }, 7606 7607 // @method createShadow(oldIcon?: HTMLElement): HTMLElement 7608 // As `createIcon`, but for the shadow beneath it. 7609 createShadow: function (oldIcon) { 7610 return this._createIcon('shadow', oldIcon); 7611 }, 7612 7613 _createIcon: function (name, oldIcon) { 7614 var src = this._getIconUrl(name); 7615 7616 if (!src) { 7617 if (name === 'icon') { 7618 throw new Error('iconUrl not set in Icon options (see the docs).'); 7619 } 7620 return null; 7621 } 7622 7623 var img = this._createImg(src, oldIcon && oldIcon.tagName === 'IMG' ? oldIcon : null); 7624 this._setIconStyles(img, name); 7625 7626 return img; 7627 }, 7628 7629 _setIconStyles: function (img, name) { 7630 var options = this.options; 7631 var sizeOption = options[name + 'Size']; 7632 7633 if (typeof sizeOption === 'number') { 7634 sizeOption = [sizeOption, sizeOption]; 7635 } 7636 7637 var size = toPoint(sizeOption), 7638 anchor = toPoint(name === 'shadow' && options.shadowAnchor || options.iconAnchor || 7639 size && size.divideBy(2, true)); 7640 7641 img.className = 'leaflet-marker-' + name + ' ' + (options.className || ''); 7642 7643 if (anchor) { 7644 img.style.marginLeft = (-anchor.x) + 'px'; 7645 img.style.marginTop = (-anchor.y) + 'px'; 7646 } 7647 7648 if (size) { 7649 img.style.width = size.x + 'px'; 7650 img.style.height = size.y + 'px'; 7651 } 7652 }, 7653 7654 _createImg: function (src, el) { 7655 el = el || document.createElement('img'); 7656 el.src = src; 7657 return el; 7658 }, 7659 7660 _getIconUrl: function (name) { 7661 return retina && this.options[name + 'RetinaUrl'] || this.options[name + 'Url']; 7662 } 7663}); 7664 7665 7666// @factory L.icon(options: Icon options) 7667// Creates an icon instance with the given options. 7668function icon(options) { 7669 return new Icon(options); 7670} 7671 7672/* 7673 * @miniclass Icon.Default (Icon) 7674 * @aka L.Icon.Default 7675 * @section 7676 * 7677 * A trivial subclass of `Icon`, represents the icon to use in `Marker`s when 7678 * no icon is specified. Points to the blue marker image distributed with Leaflet 7679 * releases. 7680 * 7681 * In order to customize the default icon, just change the properties of `L.Icon.Default.prototype.options` 7682 * (which is a set of `Icon options`). 7683 * 7684 * If you want to _completely_ replace the default icon, override the 7685 * `L.Marker.prototype.options.icon` with your own icon instead. 7686 */ 7687 7688var IconDefault = Icon.extend({ 7689 7690 options: { 7691 iconUrl: 'marker-icon.png', 7692 iconRetinaUrl: 'marker-icon-2x.png', 7693 shadowUrl: 'marker-shadow.png', 7694 iconSize: [25, 41], 7695 iconAnchor: [12, 41], 7696 popupAnchor: [1, -34], 7697 tooltipAnchor: [16, -28], 7698 shadowSize: [41, 41] 7699 }, 7700 7701 _getIconUrl: function (name) { 7702 if (!IconDefault.imagePath) { // Deprecated, backwards-compatibility only 7703 IconDefault.imagePath = this._detectIconPath(); 7704 } 7705 7706 // @option imagePath: String 7707 // `Icon.Default` will try to auto-detect the location of the 7708 // blue icon images. If you are placing these images in a non-standard 7709 // way, set this option to point to the right path. 7710 return (this.options.imagePath || IconDefault.imagePath) + Icon.prototype._getIconUrl.call(this, name); 7711 }, 7712 7713 _detectIconPath: function () { 7714 var el = create$1('div', 'leaflet-default-icon-path', document.body); 7715 var path = getStyle(el, 'background-image') || 7716 getStyle(el, 'backgroundImage'); // IE8 7717 7718 document.body.removeChild(el); 7719 7720 if (path === null || path.indexOf('url') !== 0) { 7721 path = ''; 7722 } else { 7723 path = path.replace(/^url\(["']?/, '').replace(/marker-icon\.png["']?\)$/, ''); 7724 } 7725 7726 return path; 7727 } 7728}); 7729 7730/* 7731 * L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable. 7732 */ 7733 7734 7735/* @namespace Marker 7736 * @section Interaction handlers 7737 * 7738 * 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: 7739 * 7740 * ```js 7741 * marker.dragging.disable(); 7742 * ``` 7743 * 7744 * @property dragging: Handler 7745 * Marker dragging handler (by both mouse and touch). Only valid when the marker is on the map (Otherwise set [`marker.options.draggable`](#marker-draggable)). 7746 */ 7747 7748var MarkerDrag = Handler.extend({ 7749 initialize: function (marker) { 7750 this._marker = marker; 7751 }, 7752 7753 addHooks: function () { 7754 var icon = this._marker._icon; 7755 7756 if (!this._draggable) { 7757 this._draggable = new Draggable(icon, icon, true); 7758 } 7759 7760 this._draggable.on({ 7761 dragstart: this._onDragStart, 7762 predrag: this._onPreDrag, 7763 drag: this._onDrag, 7764 dragend: this._onDragEnd 7765 }, this).enable(); 7766 7767 addClass(icon, 'leaflet-marker-draggable'); 7768 }, 7769 7770 removeHooks: function () { 7771 this._draggable.off({ 7772 dragstart: this._onDragStart, 7773 predrag: this._onPreDrag, 7774 drag: this._onDrag, 7775 dragend: this._onDragEnd 7776 }, this).disable(); 7777 7778 if (this._marker._icon) { 7779 removeClass(this._marker._icon, 'leaflet-marker-draggable'); 7780 } 7781 }, 7782 7783 moved: function () { 7784 return this._draggable && this._draggable._moved; 7785 }, 7786 7787 _adjustPan: function (e) { 7788 var marker = this._marker, 7789 map = marker._map, 7790 speed = this._marker.options.autoPanSpeed, 7791 padding = this._marker.options.autoPanPadding, 7792 iconPos = getPosition(marker._icon), 7793 bounds = map.getPixelBounds(), 7794 origin = map.getPixelOrigin(); 7795 7796 var panBounds = toBounds( 7797 bounds.min._subtract(origin).add(padding), 7798 bounds.max._subtract(origin).subtract(padding) 7799 ); 7800 7801 if (!panBounds.contains(iconPos)) { 7802 // Compute incremental movement 7803 var movement = toPoint( 7804 (Math.max(panBounds.max.x, iconPos.x) - panBounds.max.x) / (bounds.max.x - panBounds.max.x) - 7805 (Math.min(panBounds.min.x, iconPos.x) - panBounds.min.x) / (bounds.min.x - panBounds.min.x), 7806 7807 (Math.max(panBounds.max.y, iconPos.y) - panBounds.max.y) / (bounds.max.y - panBounds.max.y) - 7808 (Math.min(panBounds.min.y, iconPos.y) - panBounds.min.y) / (bounds.min.y - panBounds.min.y) 7809 ).multiplyBy(speed); 7810 7811 map.panBy(movement, {animate: false}); 7812 7813 this._draggable._newPos._add(movement); 7814 this._draggable._startPos._add(movement); 7815 7816 setPosition(marker._icon, this._draggable._newPos); 7817 this._onDrag(e); 7818 7819 this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e)); 7820 } 7821 }, 7822 7823 _onDragStart: function () { 7824 // @section Dragging events 7825 // @event dragstart: Event 7826 // Fired when the user starts dragging the marker. 7827 7828 // @event movestart: Event 7829 // Fired when the marker starts moving (because of dragging). 7830 7831 this._oldLatLng = this._marker.getLatLng(); 7832 this._marker 7833 .closePopup() 7834 .fire('movestart') 7835 .fire('dragstart'); 7836 }, 7837 7838 _onPreDrag: function (e) { 7839 if (this._marker.options.autoPan) { 7840 cancelAnimFrame(this._panRequest); 7841 this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e)); 7842 } 7843 }, 7844 7845 _onDrag: function (e) { 7846 var marker = this._marker, 7847 shadow = marker._shadow, 7848 iconPos = getPosition(marker._icon), 7849 latlng = marker._map.layerPointToLatLng(iconPos); 7850 7851 // update shadow position 7852 if (shadow) { 7853 setPosition(shadow, iconPos); 7854 } 7855 7856 marker._latlng = latlng; 7857 e.latlng = latlng; 7858 e.oldLatLng = this._oldLatLng; 7859 7860 // @event drag: Event 7861 // Fired repeatedly while the user drags the marker. 7862 marker 7863 .fire('move', e) 7864 .fire('drag', e); 7865 }, 7866 7867 _onDragEnd: function (e) { 7868 // @event dragend: DragEndEvent 7869 // Fired when the user stops dragging the marker. 7870 7871 cancelAnimFrame(this._panRequest); 7872 7873 // @event moveend: Event 7874 // Fired when the marker stops moving (because of dragging). 7875 delete this._oldLatLng; 7876 this._marker 7877 .fire('moveend') 7878 .fire('dragend', e); 7879 } 7880}); 7881 7882/* 7883 * @class Marker 7884 * @inherits Interactive layer 7885 * @aka L.Marker 7886 * L.Marker is used to display clickable/draggable icons on the map. Extends `Layer`. 7887 * 7888 * @example 7889 * 7890 * ```js 7891 * L.marker([50.5, 30.5]).addTo(map); 7892 * ``` 7893 */ 7894 7895var Marker = Layer.extend({ 7896 7897 // @section 7898 // @aka Marker options 7899 options: { 7900 // @option icon: Icon = * 7901 // Icon instance to use for rendering the marker. 7902 // See [Icon documentation](#L.Icon) for details on how to customize the marker icon. 7903 // If not specified, a common instance of `L.Icon.Default` is used. 7904 icon: new IconDefault(), 7905 7906 // Option inherited from "Interactive layer" abstract class 7907 interactive: true, 7908 7909 // @option keyboard: Boolean = true 7910 // Whether the marker can be tabbed to with a keyboard and clicked by pressing enter. 7911 keyboard: true, 7912 7913 // @option title: String = '' 7914 // Text for the browser tooltip that appear on marker hover (no tooltip by default). 7915 title: '', 7916 7917 // @option alt: String = '' 7918 // Text for the `alt` attribute of the icon image (useful for accessibility). 7919 alt: '', 7920 7921 // @option zIndexOffset: Number = 0 7922 // 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). 7923 zIndexOffset: 0, 7924 7925 // @option opacity: Number = 1.0 7926 // The opacity of the marker. 7927 opacity: 1, 7928 7929 // @option riseOnHover: Boolean = false 7930 // If `true`, the marker will get on top of others when you hover the mouse over it. 7931 riseOnHover: false, 7932 7933 // @option riseOffset: Number = 250 7934 // The z-index offset used for the `riseOnHover` feature. 7935 riseOffset: 250, 7936 7937 // @option pane: String = 'markerPane' 7938 // `Map pane` where the markers icon will be added. 7939 pane: 'markerPane', 7940 7941 // @option pane: String = 'shadowPane' 7942 // `Map pane` where the markers shadow will be added. 7943 shadowPane: 'shadowPane', 7944 7945 // @option bubblingMouseEvents: Boolean = false 7946 // When `true`, a mouse event on this marker will trigger the same event on the map 7947 // (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used). 7948 bubblingMouseEvents: false, 7949 7950 // @section Draggable marker options 7951 // @option draggable: Boolean = false 7952 // Whether the marker is draggable with mouse/touch or not. 7953 draggable: false, 7954 7955 // @option autoPan: Boolean = false 7956 // Whether to pan the map when dragging this marker near its edge or not. 7957 autoPan: false, 7958 7959 // @option autoPanPadding: Point = Point(50, 50) 7960 // Distance (in pixels to the left/right and to the top/bottom) of the 7961 // map edge to start panning the map. 7962 autoPanPadding: [50, 50], 7963 7964 // @option autoPanSpeed: Number = 10 7965 // Number of pixels the map should pan by. 7966 autoPanSpeed: 10 7967 }, 7968 7969 /* @section 7970 * 7971 * In addition to [shared layer methods](#Layer) like `addTo()` and `remove()` and [popup methods](#Popup) like bindPopup() you can also use the following methods: 7972 */ 7973 7974 initialize: function (latlng, options) { 7975 setOptions(this, options); 7976 this._latlng = toLatLng(latlng); 7977 }, 7978 7979 onAdd: function (map) { 7980 this._zoomAnimated = this._zoomAnimated && map.options.markerZoomAnimation; 7981 7982 if (this._zoomAnimated) { 7983 map.on('zoomanim', this._animateZoom, this); 7984 } 7985 7986 this._initIcon(); 7987 this.update(); 7988 }, 7989 7990 onRemove: function (map) { 7991 if (this.dragging && this.dragging.enabled()) { 7992 this.options.draggable = true; 7993 this.dragging.removeHooks(); 7994 } 7995 delete this.dragging; 7996 7997 if (this._zoomAnimated) { 7998 map.off('zoomanim', this._animateZoom, this); 7999 } 8000 8001 this._removeIcon(); 8002 this._removeShadow(); 8003 }, 8004 8005 getEvents: function () { 8006 return { 8007 zoom: this.update, 8008 viewreset: this.update 8009 }; 8010 }, 8011 8012 // @method getLatLng: LatLng 8013 // Returns the current geographical position of the marker. 8014 getLatLng: function () { 8015 return this._latlng; 8016 }, 8017 8018 // @method setLatLng(latlng: LatLng): this 8019 // Changes the marker position to the given point. 8020 setLatLng: function (latlng) { 8021 var oldLatLng = this._latlng; 8022 this._latlng = toLatLng(latlng); 8023 this.update(); 8024 8025 // @event move: Event 8026 // 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`. 8027 return this.fire('move', {oldLatLng: oldLatLng, latlng: this._latlng}); 8028 }, 8029 8030 // @method setZIndexOffset(offset: Number): this 8031 // Changes the [zIndex offset](#marker-zindexoffset) of the marker. 8032 setZIndexOffset: function (offset) { 8033 this.options.zIndexOffset = offset; 8034 return this.update(); 8035 }, 8036 8037 // @method getIcon: Icon 8038 // Returns the current icon used by the marker 8039 getIcon: function () { 8040 return this.options.icon; 8041 }, 8042 8043 // @method setIcon(icon: Icon): this 8044 // Changes the marker icon. 8045 setIcon: function (icon) { 8046 8047 this.options.icon = icon; 8048 8049 if (this._map) { 8050 this._initIcon(); 8051 this.update(); 8052 } 8053 8054 if (this._popup) { 8055 this.bindPopup(this._popup, this._popup.options); 8056 } 8057 8058 return this; 8059 }, 8060 8061 getElement: function () { 8062 return this._icon; 8063 }, 8064 8065 update: function () { 8066 8067 if (this._icon && this._map) { 8068 var pos = this._map.latLngToLayerPoint(this._latlng).round(); 8069 this._setPos(pos); 8070 } 8071 8072 return this; 8073 }, 8074 8075 _initIcon: function () { 8076 var options = this.options, 8077 classToAdd = 'leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide'); 8078 8079 var icon = options.icon.createIcon(this._icon), 8080 addIcon = false; 8081 8082 // if we're not reusing the icon, remove the old one and init new one 8083 if (icon !== this._icon) { 8084 if (this._icon) { 8085 this._removeIcon(); 8086 } 8087 addIcon = true; 8088 8089 if (options.title) { 8090 icon.title = options.title; 8091 } 8092 8093 if (icon.tagName === 'IMG') { 8094 icon.alt = options.alt || ''; 8095 } 8096 } 8097 8098 addClass(icon, classToAdd); 8099 8100 if (options.keyboard) { 8101 icon.tabIndex = '0'; 8102 } 8103 8104 this._icon = icon; 8105 8106 if (options.riseOnHover) { 8107 this.on({ 8108 mouseover: this._bringToFront, 8109 mouseout: this._resetZIndex 8110 }); 8111 } 8112 8113 var newShadow = options.icon.createShadow(this._shadow), 8114 addShadow = false; 8115 8116 if (newShadow !== this._shadow) { 8117 this._removeShadow(); 8118 addShadow = true; 8119 } 8120 8121 if (newShadow) { 8122 addClass(newShadow, classToAdd); 8123 newShadow.alt = ''; 8124 } 8125 this._shadow = newShadow; 8126 8127 8128 if (options.opacity < 1) { 8129 this._updateOpacity(); 8130 } 8131 8132 8133 if (addIcon) { 8134 this.getPane().appendChild(this._icon); 8135 } 8136 this._initInteraction(); 8137 if (newShadow && addShadow) { 8138 this.getPane(options.shadowPane).appendChild(this._shadow); 8139 } 8140 }, 8141 8142 _removeIcon: function () { 8143 if (this.options.riseOnHover) { 8144 this.off({ 8145 mouseover: this._bringToFront, 8146 mouseout: this._resetZIndex 8147 }); 8148 } 8149 8150 remove(this._icon); 8151 this.removeInteractiveTarget(this._icon); 8152 8153 this._icon = null; 8154 }, 8155 8156 _removeShadow: function () { 8157 if (this._shadow) { 8158 remove(this._shadow); 8159 } 8160 this._shadow = null; 8161 }, 8162 8163 _setPos: function (pos) { 8164 setPosition(this._icon, pos); 8165 8166 if (this._shadow) { 8167 setPosition(this._shadow, pos); 8168 } 8169 8170 this._zIndex = pos.y + this.options.zIndexOffset; 8171 8172 this._resetZIndex(); 8173 }, 8174 8175 _updateZIndex: function (offset) { 8176 this._icon.style.zIndex = this._zIndex + offset; 8177 }, 8178 8179 _animateZoom: function (opt) { 8180 var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round(); 8181 8182 this._setPos(pos); 8183 }, 8184 8185 _initInteraction: function () { 8186 8187 if (!this.options.interactive) { return; } 8188 8189 addClass(this._icon, 'leaflet-interactive'); 8190 8191 this.addInteractiveTarget(this._icon); 8192 8193 if (MarkerDrag) { 8194 var draggable = this.options.draggable; 8195 if (this.dragging) { 8196 draggable = this.dragging.enabled(); 8197 this.dragging.disable(); 8198 } 8199 8200 this.dragging = new MarkerDrag(this); 8201 8202 if (draggable) { 8203 this.dragging.enable(); 8204 } 8205 } 8206 }, 8207 8208 // @method setOpacity(opacity: Number): this 8209 // Changes the opacity of the marker. 8210 setOpacity: function (opacity) { 8211 this.options.opacity = opacity; 8212 if (this._map) { 8213 this._updateOpacity(); 8214 } 8215 8216 return this; 8217 }, 8218 8219 _updateOpacity: function () { 8220 var opacity = this.options.opacity; 8221 8222 if (this._icon) { 8223 setOpacity(this._icon, opacity); 8224 } 8225 8226 if (this._shadow) { 8227 setOpacity(this._shadow, opacity); 8228 } 8229 }, 8230 8231 _bringToFront: function () { 8232 this._updateZIndex(this.options.riseOffset); 8233 }, 8234 8235 _resetZIndex: function () { 8236 this._updateZIndex(0); 8237 }, 8238 8239 _getPopupAnchor: function () { 8240 return this.options.icon.options.popupAnchor; 8241 }, 8242 8243 _getTooltipAnchor: function () { 8244 return this.options.icon.options.tooltipAnchor; 8245 } 8246}); 8247 8248 8249// factory L.marker(latlng: LatLng, options? : Marker options) 8250 8251// @factory L.marker(latlng: LatLng, options? : Marker options) 8252// Instantiates a Marker object given a geographical point and optionally an options object. 8253function marker(latlng, options) { 8254 return new Marker(latlng, options); 8255} 8256 8257/* 8258 * @class Path 8259 * @aka L.Path 8260 * @inherits Interactive layer 8261 * 8262 * An abstract class that contains options and constants shared between vector 8263 * overlays (Polygon, Polyline, Circle). Do not use it directly. Extends `Layer`. 8264 */ 8265 8266var Path = Layer.extend({ 8267 8268 // @section 8269 // @aka Path options 8270 options: { 8271 // @option stroke: Boolean = true 8272 // Whether to draw stroke along the path. Set it to `false` to disable borders on polygons or circles. 8273 stroke: true, 8274 8275 // @option color: String = '#3388ff' 8276 // Stroke color 8277 color: '#3388ff', 8278 8279 // @option weight: Number = 3 8280 // Stroke width in pixels 8281 weight: 3, 8282 8283 // @option opacity: Number = 1.0 8284 // Stroke opacity 8285 opacity: 1, 8286 8287 // @option lineCap: String= 'round' 8288 // A string that defines [shape to be used at the end](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linecap) of the stroke. 8289 lineCap: 'round', 8290 8291 // @option lineJoin: String = 'round' 8292 // A string that defines [shape to be used at the corners](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linejoin) of the stroke. 8293 lineJoin: 'round', 8294 8295 // @option dashArray: String = null 8296 // 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). 8297 dashArray: null, 8298 8299 // @option dashOffset: String = null 8300 // 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). 8301 dashOffset: null, 8302 8303 // @option fill: Boolean = depends 8304 // Whether to fill the path with color. Set it to `false` to disable filling on polygons or circles. 8305 fill: false, 8306 8307 // @option fillColor: String = * 8308 // Fill color. Defaults to the value of the [`color`](#path-color) option 8309 fillColor: null, 8310 8311 // @option fillOpacity: Number = 0.2 8312 // Fill opacity. 8313 fillOpacity: 0.2, 8314 8315 // @option fillRule: String = 'evenodd' 8316 // A string that defines [how the inside of a shape](https://developer.mozilla.org/docs/Web/SVG/Attribute/fill-rule) is determined. 8317 fillRule: 'evenodd', 8318 8319 // className: '', 8320 8321 // Option inherited from "Interactive layer" abstract class 8322 interactive: true, 8323 8324 // @option bubblingMouseEvents: Boolean = true 8325 // When `true`, a mouse event on this path will trigger the same event on the map 8326 // (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used). 8327 bubblingMouseEvents: true 8328 }, 8329 8330 beforeAdd: function (map) { 8331 // Renderer is set here because we need to call renderer.getEvents 8332 // before this.getEvents. 8333 this._renderer = map.getRenderer(this); 8334 }, 8335 8336 onAdd: function () { 8337 this._renderer._initPath(this); 8338 this._reset(); 8339 this._renderer._addPath(this); 8340 }, 8341 8342 onRemove: function () { 8343 this._renderer._removePath(this); 8344 }, 8345 8346 // @method redraw(): this 8347 // Redraws the layer. Sometimes useful after you changed the coordinates that the path uses. 8348 redraw: function () { 8349 if (this._map) { 8350 this._renderer._updatePath(this); 8351 } 8352 return this; 8353 }, 8354 8355 // @method setStyle(style: Path options): this 8356 // Changes the appearance of a Path based on the options in the `Path options` object. 8357 setStyle: function (style) { 8358 setOptions(this, style); 8359 if (this._renderer) { 8360 this._renderer._updateStyle(this); 8361 if (this.options.stroke && style.hasOwnProperty('weight')) { 8362 this._updateBounds(); 8363 } 8364 } 8365 return this; 8366 }, 8367 8368 // @method bringToFront(): this 8369 // Brings the layer to the top of all path layers. 8370 bringToFront: function () { 8371 if (this._renderer) { 8372 this._renderer._bringToFront(this); 8373 } 8374 return this; 8375 }, 8376 8377 // @method bringToBack(): this 8378 // Brings the layer to the bottom of all path layers. 8379 bringToBack: function () { 8380 if (this._renderer) { 8381 this._renderer._bringToBack(this); 8382 } 8383 return this; 8384 }, 8385 8386 getElement: function () { 8387 return this._path; 8388 }, 8389 8390 _reset: function () { 8391 // defined in child classes 8392 this._project(); 8393 this._update(); 8394 }, 8395 8396 _clickTolerance: function () { 8397 // used when doing hit detection for Canvas layers 8398 return (this.options.stroke ? this.options.weight / 2 : 0) + this._renderer.options.tolerance; 8399 } 8400}); 8401 8402/* 8403 * @class CircleMarker 8404 * @aka L.CircleMarker 8405 * @inherits Path 8406 * 8407 * A circle of a fixed size with radius specified in pixels. Extends `Path`. 8408 */ 8409 8410var CircleMarker = Path.extend({ 8411 8412 // @section 8413 // @aka CircleMarker options 8414 options: { 8415 fill: true, 8416 8417 // @option radius: Number = 10 8418 // Radius of the circle marker, in pixels 8419 radius: 10 8420 }, 8421 8422 initialize: function (latlng, options) { 8423 setOptions(this, options); 8424 this._latlng = toLatLng(latlng); 8425 this._radius = this.options.radius; 8426 }, 8427 8428 // @method setLatLng(latLng: LatLng): this 8429 // Sets the position of a circle marker to a new location. 8430 setLatLng: function (latlng) { 8431 this._latlng = toLatLng(latlng); 8432 this.redraw(); 8433 return this.fire('move', {latlng: this._latlng}); 8434 }, 8435 8436 // @method getLatLng(): LatLng 8437 // Returns the current geographical position of the circle marker 8438 getLatLng: function () { 8439 return this._latlng; 8440 }, 8441 8442 // @method setRadius(radius: Number): this 8443 // Sets the radius of a circle marker. Units are in pixels. 8444 setRadius: function (radius) { 8445 this.options.radius = this._radius = radius; 8446 return this.redraw(); 8447 }, 8448 8449 // @method getRadius(): Number 8450 // Returns the current radius of the circle 8451 getRadius: function () { 8452 return this._radius; 8453 }, 8454 8455 setStyle : function (options) { 8456 var radius = options && options.radius || this._radius; 8457 Path.prototype.setStyle.call(this, options); 8458 this.setRadius(radius); 8459 return this; 8460 }, 8461 8462 _project: function () { 8463 this._point = this._map.latLngToLayerPoint(this._latlng); 8464 this._updateBounds(); 8465 }, 8466 8467 _updateBounds: function () { 8468 var r = this._radius, 8469 r2 = this._radiusY || r, 8470 w = this._clickTolerance(), 8471 p = [r + w, r2 + w]; 8472 this._pxBounds = new Bounds(this._point.subtract(p), this._point.add(p)); 8473 }, 8474 8475 _update: function () { 8476 if (this._map) { 8477 this._updatePath(); 8478 } 8479 }, 8480 8481 _updatePath: function () { 8482 this._renderer._updateCircle(this); 8483 }, 8484 8485 _empty: function () { 8486 return this._radius && !this._renderer._bounds.intersects(this._pxBounds); 8487 }, 8488 8489 // Needed by the `Canvas` renderer for interactivity 8490 _containsPoint: function (p) { 8491 return p.distanceTo(this._point) <= this._radius + this._clickTolerance(); 8492 } 8493}); 8494 8495 8496// @factory L.circleMarker(latlng: LatLng, options?: CircleMarker options) 8497// Instantiates a circle marker object given a geographical point, and an optional options object. 8498function circleMarker(latlng, options) { 8499 return new CircleMarker(latlng, options); 8500} 8501 8502/* 8503 * @class Circle 8504 * @aka L.Circle 8505 * @inherits CircleMarker 8506 * 8507 * A class for drawing circle overlays on a map. Extends `CircleMarker`. 8508 * 8509 * It's an approximation and starts to diverge from a real circle closer to poles (due to projection distortion). 8510 * 8511 * @example 8512 * 8513 * ```js 8514 * L.circle([50.5, 30.5], {radius: 200}).addTo(map); 8515 * ``` 8516 */ 8517 8518var Circle = CircleMarker.extend({ 8519 8520 initialize: function (latlng, options, legacyOptions) { 8521 if (typeof options === 'number') { 8522 // Backwards compatibility with 0.7.x factory (latlng, radius, options?) 8523 options = extend({}, legacyOptions, {radius: options}); 8524 } 8525 setOptions(this, options); 8526 this._latlng = toLatLng(latlng); 8527 8528 if (isNaN(this.options.radius)) { throw new Error('Circle radius cannot be NaN'); } 8529 8530 // @section 8531 // @aka Circle options 8532 // @option radius: Number; Radius of the circle, in meters. 8533 this._mRadius = this.options.radius; 8534 }, 8535 8536 // @method setRadius(radius: Number): this 8537 // Sets the radius of a circle. Units are in meters. 8538 setRadius: function (radius) { 8539 this._mRadius = radius; 8540 return this.redraw(); 8541 }, 8542 8543 // @method getRadius(): Number 8544 // Returns the current radius of a circle. Units are in meters. 8545 getRadius: function () { 8546 return this._mRadius; 8547 }, 8548 8549 // @method getBounds(): LatLngBounds 8550 // Returns the `LatLngBounds` of the path. 8551 getBounds: function () { 8552 var half = [this._radius, this._radiusY || this._radius]; 8553 8554 return new LatLngBounds( 8555 this._map.layerPointToLatLng(this._point.subtract(half)), 8556 this._map.layerPointToLatLng(this._point.add(half))); 8557 }, 8558 8559 setStyle: Path.prototype.setStyle, 8560 8561 _project: function () { 8562 8563 var lng = this._latlng.lng, 8564 lat = this._latlng.lat, 8565 map = this._map, 8566 crs = map.options.crs; 8567 8568 if (crs.distance === Earth.distance) { 8569 var d = Math.PI / 180, 8570 latR = (this._mRadius / Earth.R) / d, 8571 top = map.project([lat + latR, lng]), 8572 bottom = map.project([lat - latR, lng]), 8573 p = top.add(bottom).divideBy(2), 8574 lat2 = map.unproject(p).lat, 8575 lngR = Math.acos((Math.cos(latR * d) - Math.sin(lat * d) * Math.sin(lat2 * d)) / 8576 (Math.cos(lat * d) * Math.cos(lat2 * d))) / d; 8577 8578 if (isNaN(lngR) || lngR === 0) { 8579 lngR = latR / Math.cos(Math.PI / 180 * lat); // Fallback for edge case, #2425 8580 } 8581 8582 this._point = p.subtract(map.getPixelOrigin()); 8583 this._radius = isNaN(lngR) ? 0 : p.x - map.project([lat2, lng - lngR]).x; 8584 this._radiusY = p.y - top.y; 8585 8586 } else { 8587 var latlng2 = crs.unproject(crs.project(this._latlng).subtract([this._mRadius, 0])); 8588 8589 this._point = map.latLngToLayerPoint(this._latlng); 8590 this._radius = this._point.x - map.latLngToLayerPoint(latlng2).x; 8591 } 8592 8593 this._updateBounds(); 8594 } 8595}); 8596 8597// @factory L.circle(latlng: LatLng, options?: Circle options) 8598// Instantiates a circle object given a geographical point, and an options object 8599// which contains the circle radius. 8600// @alternative 8601// @factory L.circle(latlng: LatLng, radius: Number, options?: Circle options) 8602// Obsolete way of instantiating a circle, for compatibility with 0.7.x code. 8603// Do not use in new applications or plugins. 8604function circle(latlng, options, legacyOptions) { 8605 return new Circle(latlng, options, legacyOptions); 8606} 8607 8608/* 8609 * @class Polyline 8610 * @aka L.Polyline 8611 * @inherits Path 8612 * 8613 * A class for drawing polyline overlays on a map. Extends `Path`. 8614 * 8615 * @example 8616 * 8617 * ```js 8618 * // create a red polyline from an array of LatLng points 8619 * var latlngs = [ 8620 * [45.51, -122.68], 8621 * [37.77, -122.43], 8622 * [34.04, -118.2] 8623 * ]; 8624 * 8625 * var polyline = L.polyline(latlngs, {color: 'red'}).addTo(map); 8626 * 8627 * // zoom the map to the polyline 8628 * map.fitBounds(polyline.getBounds()); 8629 * ``` 8630 * 8631 * You can also pass a multi-dimensional array to represent a `MultiPolyline` shape: 8632 * 8633 * ```js 8634 * // create a red polyline from an array of arrays of LatLng points 8635 * var latlngs = [ 8636 * [[45.51, -122.68], 8637 * [37.77, -122.43], 8638 * [34.04, -118.2]], 8639 * [[40.78, -73.91], 8640 * [41.83, -87.62], 8641 * [32.76, -96.72]] 8642 * ]; 8643 * ``` 8644 */ 8645 8646 8647var Polyline = Path.extend({ 8648 8649 // @section 8650 // @aka Polyline options 8651 options: { 8652 // @option smoothFactor: Number = 1.0 8653 // How much to simplify the polyline on each zoom level. More means 8654 // better performance and smoother look, and less means more accurate representation. 8655 smoothFactor: 1.0, 8656 8657 // @option noClip: Boolean = false 8658 // Disable polyline clipping. 8659 noClip: false 8660 }, 8661 8662 initialize: function (latlngs, options) { 8663 setOptions(this, options); 8664 this._setLatLngs(latlngs); 8665 }, 8666 8667 // @method getLatLngs(): LatLng[] 8668 // Returns an array of the points in the path, or nested arrays of points in case of multi-polyline. 8669 getLatLngs: function () { 8670 return this._latlngs; 8671 }, 8672 8673 // @method setLatLngs(latlngs: LatLng[]): this 8674 // Replaces all the points in the polyline with the given array of geographical points. 8675 setLatLngs: function (latlngs) { 8676 this._setLatLngs(latlngs); 8677 return this.redraw(); 8678 }, 8679 8680 // @method isEmpty(): Boolean 8681 // Returns `true` if the Polyline has no LatLngs. 8682 isEmpty: function () { 8683 return !this._latlngs.length; 8684 }, 8685 8686 // @method closestLayerPoint(p: Point): Point 8687 // Returns the point closest to `p` on the Polyline. 8688 closestLayerPoint: function (p) { 8689 var minDistance = Infinity, 8690 minPoint = null, 8691 closest = _sqClosestPointOnSegment, 8692 p1, p2; 8693 8694 for (var j = 0, jLen = this._parts.length; j < jLen; j++) { 8695 var points = this._parts[j]; 8696 8697 for (var i = 1, len = points.length; i < len; i++) { 8698 p1 = points[i - 1]; 8699 p2 = points[i]; 8700 8701 var sqDist = closest(p, p1, p2, true); 8702 8703 if (sqDist < minDistance) { 8704 minDistance = sqDist; 8705 minPoint = closest(p, p1, p2); 8706 } 8707 } 8708 } 8709 if (minPoint) { 8710 minPoint.distance = Math.sqrt(minDistance); 8711 } 8712 return minPoint; 8713 }, 8714 8715 // @method getCenter(): LatLng 8716 // Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the polyline. 8717 getCenter: function () { 8718 // throws error when not yet added to map as this center calculation requires projected coordinates 8719 if (!this._map) { 8720 throw new Error('Must add layer to map before using getCenter()'); 8721 } 8722 8723 var i, halfDist, segDist, dist, p1, p2, ratio, 8724 points = this._rings[0], 8725 len = points.length; 8726 8727 if (!len) { return null; } 8728 8729 // polyline centroid algorithm; only uses the first ring if there are multiple 8730 8731 for (i = 0, halfDist = 0; i < len - 1; i++) { 8732 halfDist += points[i].distanceTo(points[i + 1]) / 2; 8733 } 8734 8735 // The line is so small in the current view that all points are on the same pixel. 8736 if (halfDist === 0) { 8737 return this._map.layerPointToLatLng(points[0]); 8738 } 8739 8740 for (i = 0, dist = 0; i < len - 1; i++) { 8741 p1 = points[i]; 8742 p2 = points[i + 1]; 8743 segDist = p1.distanceTo(p2); 8744 dist += segDist; 8745 8746 if (dist > halfDist) { 8747 ratio = (dist - halfDist) / segDist; 8748 return this._map.layerPointToLatLng([ 8749 p2.x - ratio * (p2.x - p1.x), 8750 p2.y - ratio * (p2.y - p1.y) 8751 ]); 8752 } 8753 } 8754 }, 8755 8756 // @method getBounds(): LatLngBounds 8757 // Returns the `LatLngBounds` of the path. 8758 getBounds: function () { 8759 return this._bounds; 8760 }, 8761 8762 // @method addLatLng(latlng: LatLng, latlngs? LatLng[]): this 8763 // Adds a given point to the polyline. By default, adds to the first ring of 8764 // the polyline in case of a multi-polyline, but can be overridden by passing 8765 // a specific ring as a LatLng array (that you can earlier access with [`getLatLngs`](#polyline-getlatlngs)). 8766 addLatLng: function (latlng, latlngs) { 8767 latlngs = latlngs || this._defaultShape(); 8768 latlng = toLatLng(latlng); 8769 latlngs.push(latlng); 8770 this._bounds.extend(latlng); 8771 return this.redraw(); 8772 }, 8773 8774 _setLatLngs: function (latlngs) { 8775 this._bounds = new LatLngBounds(); 8776 this._latlngs = this._convertLatLngs(latlngs); 8777 }, 8778 8779 _defaultShape: function () { 8780 return isFlat(this._latlngs) ? this._latlngs : this._latlngs[0]; 8781 }, 8782 8783 // recursively convert latlngs input into actual LatLng instances; calculate bounds along the way 8784 _convertLatLngs: function (latlngs) { 8785 var result = [], 8786 flat = isFlat(latlngs); 8787 8788 for (var i = 0, len = latlngs.length; i < len; i++) { 8789 if (flat) { 8790 result[i] = toLatLng(latlngs[i]); 8791 this._bounds.extend(result[i]); 8792 } else { 8793 result[i] = this._convertLatLngs(latlngs[i]); 8794 } 8795 } 8796 8797 return result; 8798 }, 8799 8800 _project: function () { 8801 var pxBounds = new Bounds(); 8802 this._rings = []; 8803 this._projectLatlngs(this._latlngs, this._rings, pxBounds); 8804 8805 if (this._bounds.isValid() && pxBounds.isValid()) { 8806 this._rawPxBounds = pxBounds; 8807 this._updateBounds(); 8808 } 8809 }, 8810 8811 _updateBounds: function () { 8812 var w = this._clickTolerance(), 8813 p = new Point(w, w); 8814 this._pxBounds = new Bounds([ 8815 this._rawPxBounds.min.subtract(p), 8816 this._rawPxBounds.max.add(p) 8817 ]); 8818 }, 8819 8820 // recursively turns latlngs into a set of rings with projected coordinates 8821 _projectLatlngs: function (latlngs, result, projectedBounds) { 8822 var flat = latlngs[0] instanceof LatLng, 8823 len = latlngs.length, 8824 i, ring; 8825 8826 if (flat) { 8827 ring = []; 8828 for (i = 0; i < len; i++) { 8829 ring[i] = this._map.latLngToLayerPoint(latlngs[i]); 8830 projectedBounds.extend(ring[i]); 8831 } 8832 result.push(ring); 8833 } else { 8834 for (i = 0; i < len; i++) { 8835 this._projectLatlngs(latlngs[i], result, projectedBounds); 8836 } 8837 } 8838 }, 8839 8840 // clip polyline by renderer bounds so that we have less to render for performance 8841 _clipPoints: function () { 8842 var bounds = this._renderer._bounds; 8843 8844 this._parts = []; 8845 if (!this._pxBounds || !this._pxBounds.intersects(bounds)) { 8846 return; 8847 } 8848 8849 if (this.options.noClip) { 8850 this._parts = this._rings; 8851 return; 8852 } 8853 8854 var parts = this._parts, 8855 i, j, k, len, len2, segment, points; 8856 8857 for (i = 0, k = 0, len = this._rings.length; i < len; i++) { 8858 points = this._rings[i]; 8859 8860 for (j = 0, len2 = points.length; j < len2 - 1; j++) { 8861 segment = clipSegment(points[j], points[j + 1], bounds, j, true); 8862 8863 if (!segment) { continue; } 8864 8865 parts[k] = parts[k] || []; 8866 parts[k].push(segment[0]); 8867 8868 // if segment goes out of screen, or it's the last one, it's the end of the line part 8869 if ((segment[1] !== points[j + 1]) || (j === len2 - 2)) { 8870 parts[k].push(segment[1]); 8871 k++; 8872 } 8873 } 8874 } 8875 }, 8876 8877 // simplify each clipped part of the polyline for performance 8878 _simplifyPoints: function () { 8879 var parts = this._parts, 8880 tolerance = this.options.smoothFactor; 8881 8882 for (var i = 0, len = parts.length; i < len; i++) { 8883 parts[i] = simplify(parts[i], tolerance); 8884 } 8885 }, 8886 8887 _update: function () { 8888 if (!this._map) { return; } 8889 8890 this._clipPoints(); 8891 this._simplifyPoints(); 8892 this._updatePath(); 8893 }, 8894 8895 _updatePath: function () { 8896 this._renderer._updatePoly(this); 8897 }, 8898 8899 // Needed by the `Canvas` renderer for interactivity 8900 _containsPoint: function (p, closed) { 8901 var i, j, k, len, len2, part, 8902 w = this._clickTolerance(); 8903 8904 if (!this._pxBounds || !this._pxBounds.contains(p)) { return false; } 8905 8906 // hit detection for polylines 8907 for (i = 0, len = this._parts.length; i < len; i++) { 8908 part = this._parts[i]; 8909 8910 for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) { 8911 if (!closed && (j === 0)) { continue; } 8912 8913 if (pointToSegmentDistance(p, part[k], part[j]) <= w) { 8914 return true; 8915 } 8916 } 8917 } 8918 return false; 8919 } 8920}); 8921 8922// @factory L.polyline(latlngs: LatLng[], options?: Polyline options) 8923// Instantiates a polyline object given an array of geographical points and 8924// optionally an options object. You can create a `Polyline` object with 8925// multiple separate lines (`MultiPolyline`) by passing an array of arrays 8926// of geographic points. 8927function polyline(latlngs, options) { 8928 return new Polyline(latlngs, options); 8929} 8930 8931// Retrocompat. Allow plugins to support Leaflet versions before and after 1.1. 8932Polyline._flat = _flat; 8933 8934/* 8935 * @class Polygon 8936 * @aka L.Polygon 8937 * @inherits Polyline 8938 * 8939 * A class for drawing polygon overlays on a map. Extends `Polyline`. 8940 * 8941 * 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. 8942 * 8943 * 8944 * @example 8945 * 8946 * ```js 8947 * // create a red polygon from an array of LatLng points 8948 * var latlngs = [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]]; 8949 * 8950 * var polygon = L.polygon(latlngs, {color: 'red'}).addTo(map); 8951 * 8952 * // zoom the map to the polygon 8953 * map.fitBounds(polygon.getBounds()); 8954 * ``` 8955 * 8956 * 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: 8957 * 8958 * ```js 8959 * var latlngs = [ 8960 * [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring 8961 * [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole 8962 * ]; 8963 * ``` 8964 * 8965 * Additionally, you can pass a multi-dimensional array to represent a MultiPolygon shape. 8966 * 8967 * ```js 8968 * var latlngs = [ 8969 * [ // first polygon 8970 * [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring 8971 * [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole 8972 * ], 8973 * [ // second polygon 8974 * [[41, -111.03],[45, -111.04],[45, -104.05],[41, -104.05]] 8975 * ] 8976 * ]; 8977 * ``` 8978 */ 8979 8980var Polygon = Polyline.extend({ 8981 8982 options: { 8983 fill: true 8984 }, 8985 8986 isEmpty: function () { 8987 return !this._latlngs.length || !this._latlngs[0].length; 8988 }, 8989 8990 getCenter: function () { 8991 // throws error when not yet added to map as this center calculation requires projected coordinates 8992 if (!this._map) { 8993 throw new Error('Must add layer to map before using getCenter()'); 8994 } 8995 8996 var i, j, p1, p2, f, area, x, y, center, 8997 points = this._rings[0], 8998 len = points.length; 8999 9000 if (!len) { return null; } 9001 9002 // polygon centroid algorithm; only uses the first ring if there are multiple 9003 9004 area = x = y = 0; 9005 9006 for (i = 0, j = len - 1; i < len; j = i++) { 9007 p1 = points[i]; 9008 p2 = points[j]; 9009 9010 f = p1.y * p2.x - p2.y * p1.x; 9011 x += (p1.x + p2.x) * f; 9012 y += (p1.y + p2.y) * f; 9013 area += f * 3; 9014 } 9015 9016 if (area === 0) { 9017 // Polygon is so small that all points are on same pixel. 9018 center = points[0]; 9019 } else { 9020 center = [x / area, y / area]; 9021 } 9022 return this._map.layerPointToLatLng(center); 9023 }, 9024 9025 _convertLatLngs: function (latlngs) { 9026 var result = Polyline.prototype._convertLatLngs.call(this, latlngs), 9027 len = result.length; 9028 9029 // remove last point if it equals first one 9030 if (len >= 2 && result[0] instanceof LatLng && result[0].equals(result[len - 1])) { 9031 result.pop(); 9032 } 9033 return result; 9034 }, 9035 9036 _setLatLngs: function (latlngs) { 9037 Polyline.prototype._setLatLngs.call(this, latlngs); 9038 if (isFlat(this._latlngs)) { 9039 this._latlngs = [this._latlngs]; 9040 } 9041 }, 9042 9043 _defaultShape: function () { 9044 return isFlat(this._latlngs[0]) ? this._latlngs[0] : this._latlngs[0][0]; 9045 }, 9046 9047 _clipPoints: function () { 9048 // polygons need a different clipping algorithm so we redefine that 9049 9050 var bounds = this._renderer._bounds, 9051 w = this.options.weight, 9052 p = new Point(w, w); 9053 9054 // increase clip padding by stroke width to avoid stroke on clip edges 9055 bounds = new Bounds(bounds.min.subtract(p), bounds.max.add(p)); 9056 9057 this._parts = []; 9058 if (!this._pxBounds || !this._pxBounds.intersects(bounds)) { 9059 return; 9060 } 9061 9062 if (this.options.noClip) { 9063 this._parts = this._rings; 9064 return; 9065 } 9066 9067 for (var i = 0, len = this._rings.length, clipped; i < len; i++) { 9068 clipped = clipPolygon(this._rings[i], bounds, true); 9069 if (clipped.length) { 9070 this._parts.push(clipped); 9071 } 9072 } 9073 }, 9074 9075 _updatePath: function () { 9076 this._renderer._updatePoly(this, true); 9077 }, 9078 9079 // Needed by the `Canvas` renderer for interactivity 9080 _containsPoint: function (p) { 9081 var inside = false, 9082 part, p1, p2, i, j, k, len, len2; 9083 9084 if (!this._pxBounds || !this._pxBounds.contains(p)) { return false; } 9085 9086 // ray casting algorithm for detecting if point is in polygon 9087 for (i = 0, len = this._parts.length; i < len; i++) { 9088 part = this._parts[i]; 9089 9090 for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) { 9091 p1 = part[j]; 9092 p2 = part[k]; 9093 9094 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)) { 9095 inside = !inside; 9096 } 9097 } 9098 } 9099 9100 // also check if it's on polygon stroke 9101 return inside || Polyline.prototype._containsPoint.call(this, p, true); 9102 } 9103 9104}); 9105 9106 9107// @factory L.polygon(latlngs: LatLng[], options?: Polyline options) 9108function polygon(latlngs, options) { 9109 return new Polygon(latlngs, options); 9110} 9111 9112/* 9113 * @class GeoJSON 9114 * @aka L.GeoJSON 9115 * @inherits FeatureGroup 9116 * 9117 * Represents a GeoJSON object or an array of GeoJSON objects. Allows you to parse 9118 * GeoJSON data and display it on the map. Extends `FeatureGroup`. 9119 * 9120 * @example 9121 * 9122 * ```js 9123 * L.geoJSON(data, { 9124 * style: function (feature) { 9125 * return {color: feature.properties.color}; 9126 * } 9127 * }).bindPopup(function (layer) { 9128 * return layer.feature.properties.description; 9129 * }).addTo(map); 9130 * ``` 9131 */ 9132 9133var GeoJSON = FeatureGroup.extend({ 9134 9135 /* @section 9136 * @aka GeoJSON options 9137 * 9138 * @option pointToLayer: Function = * 9139 * A `Function` defining how GeoJSON points spawn Leaflet layers. It is internally 9140 * called when data is added, passing the GeoJSON point feature and its `LatLng`. 9141 * The default is to spawn a default `Marker`: 9142 * ```js 9143 * function(geoJsonPoint, latlng) { 9144 * return L.marker(latlng); 9145 * } 9146 * ``` 9147 * 9148 * @option style: Function = * 9149 * A `Function` defining the `Path options` for styling GeoJSON lines and polygons, 9150 * called internally when data is added. 9151 * The default value is to not override any defaults: 9152 * ```js 9153 * function (geoJsonFeature) { 9154 * return {} 9155 * } 9156 * ``` 9157 * 9158 * @option onEachFeature: Function = * 9159 * A `Function` that will be called once for each created `Feature`, after it has 9160 * been created and styled. Useful for attaching events and popups to features. 9161 * The default is to do nothing with the newly created layers: 9162 * ```js 9163 * function (feature, layer) {} 9164 * ``` 9165 * 9166 * @option filter: Function = * 9167 * A `Function` that will be used to decide whether to include a feature or not. 9168 * The default is to include all features: 9169 * ```js 9170 * function (geoJsonFeature) { 9171 * return true; 9172 * } 9173 * ``` 9174 * Note: dynamically changing the `filter` option will have effect only on newly 9175 * added data. It will _not_ re-evaluate already included features. 9176 * 9177 * @option coordsToLatLng: Function = * 9178 * A `Function` that will be used for converting GeoJSON coordinates to `LatLng`s. 9179 * The default is the `coordsToLatLng` static method. 9180 */ 9181 9182 initialize: function (geojson, options) { 9183 setOptions(this, options); 9184 9185 this._layers = {}; 9186 9187 if (geojson) { 9188 this.addData(geojson); 9189 } 9190 }, 9191 9192 // @method addData( <GeoJSON> data ): this 9193 // Adds a GeoJSON object to the layer. 9194 addData: function (geojson) { 9195 var features = isArray(geojson) ? geojson : geojson.features, 9196 i, len, feature; 9197 9198 if (features) { 9199 for (i = 0, len = features.length; i < len; i++) { 9200 // only add this if geometry or geometries are set and not null 9201 feature = features[i]; 9202 if (feature.geometries || feature.geometry || feature.features || feature.coordinates) { 9203 this.addData(feature); 9204 } 9205 } 9206 return this; 9207 } 9208 9209 var options = this.options; 9210 9211 if (options.filter && !options.filter(geojson)) { return this; } 9212 9213 var layer = geometryToLayer(geojson, options); 9214 if (!layer) { 9215 return this; 9216 } 9217 layer.feature = asFeature(geojson); 9218 9219 layer.defaultOptions = layer.options; 9220 this.resetStyle(layer); 9221 9222 if (options.onEachFeature) { 9223 options.onEachFeature(geojson, layer); 9224 } 9225 9226 return this.addLayer(layer); 9227 }, 9228 9229 // @method resetStyle( <Path> layer ): this 9230 // Resets the given vector layer's style to the original GeoJSON style, useful for resetting style after hover events. 9231 resetStyle: function (layer) { 9232 // reset any custom styles 9233 layer.options = extend({}, layer.defaultOptions); 9234 this._setLayerStyle(layer, this.options.style); 9235 return this; 9236 }, 9237 9238 // @method setStyle( <Function> style ): this 9239 // Changes styles of GeoJSON vector layers with the given style function. 9240 setStyle: function (style) { 9241 return this.eachLayer(function (layer) { 9242 this._setLayerStyle(layer, style); 9243 }, this); 9244 }, 9245 9246 _setLayerStyle: function (layer, style) { 9247 if (layer.setStyle) { 9248 if (typeof style === 'function') { 9249 style = style(layer.feature); 9250 } 9251 layer.setStyle(style); 9252 } 9253 } 9254}); 9255 9256// @section 9257// There are several static functions which can be called without instantiating L.GeoJSON: 9258 9259// @function geometryToLayer(featureData: Object, options?: GeoJSON options): Layer 9260// Creates a `Layer` from a given GeoJSON feature. Can use a custom 9261// [`pointToLayer`](#geojson-pointtolayer) and/or [`coordsToLatLng`](#geojson-coordstolatlng) 9262// functions if provided as options. 9263function geometryToLayer(geojson, options) { 9264 9265 var geometry = geojson.type === 'Feature' ? geojson.geometry : geojson, 9266 coords = geometry ? geometry.coordinates : null, 9267 layers = [], 9268 pointToLayer = options && options.pointToLayer, 9269 _coordsToLatLng = options && options.coordsToLatLng || coordsToLatLng, 9270 latlng, latlngs, i, len; 9271 9272 if (!coords && !geometry) { 9273 return null; 9274 } 9275 9276 switch (geometry.type) { 9277 case 'Point': 9278 latlng = _coordsToLatLng(coords); 9279 return pointToLayer ? pointToLayer(geojson, latlng) : new Marker(latlng); 9280 9281 case 'MultiPoint': 9282 for (i = 0, len = coords.length; i < len; i++) { 9283 latlng = _coordsToLatLng(coords[i]); 9284 layers.push(pointToLayer ? pointToLayer(geojson, latlng) : new Marker(latlng)); 9285 } 9286 return new FeatureGroup(layers); 9287 9288 case 'LineString': 9289 case 'MultiLineString': 9290 latlngs = coordsToLatLngs(coords, geometry.type === 'LineString' ? 0 : 1, _coordsToLatLng); 9291 return new Polyline(latlngs, options); 9292 9293 case 'Polygon': 9294 case 'MultiPolygon': 9295 latlngs = coordsToLatLngs(coords, geometry.type === 'Polygon' ? 1 : 2, _coordsToLatLng); 9296 return new Polygon(latlngs, options); 9297 9298 case 'GeometryCollection': 9299 for (i = 0, len = geometry.geometries.length; i < len; i++) { 9300 var layer = geometryToLayer({ 9301 geometry: geometry.geometries[i], 9302 type: 'Feature', 9303 properties: geojson.properties 9304 }, options); 9305 9306 if (layer) { 9307 layers.push(layer); 9308 } 9309 } 9310 return new FeatureGroup(layers); 9311 9312 default: 9313 throw new Error('Invalid GeoJSON object.'); 9314 } 9315} 9316 9317// @function coordsToLatLng(coords: Array): LatLng 9318// Creates a `LatLng` object from an array of 2 numbers (longitude, latitude) 9319// or 3 numbers (longitude, latitude, altitude) used in GeoJSON for points. 9320function coordsToLatLng(coords) { 9321 return new LatLng(coords[1], coords[0], coords[2]); 9322} 9323 9324// @function coordsToLatLngs(coords: Array, levelsDeep?: Number, coordsToLatLng?: Function): Array 9325// Creates a multidimensional array of `LatLng`s from a GeoJSON coordinates array. 9326// `levelsDeep` specifies the nesting level (0 is for an array of points, 1 for an array of arrays of points, etc., 0 by default). 9327// Can use a custom [`coordsToLatLng`](#geojson-coordstolatlng) function. 9328function coordsToLatLngs(coords, levelsDeep, _coordsToLatLng) { 9329 var latlngs = []; 9330 9331 for (var i = 0, len = coords.length, latlng; i < len; i++) { 9332 latlng = levelsDeep ? 9333 coordsToLatLngs(coords[i], levelsDeep - 1, _coordsToLatLng) : 9334 (_coordsToLatLng || coordsToLatLng)(coords[i]); 9335 9336 latlngs.push(latlng); 9337 } 9338 9339 return latlngs; 9340} 9341 9342// @function latLngToCoords(latlng: LatLng, precision?: Number): Array 9343// Reverse of [`coordsToLatLng`](#geojson-coordstolatlng) 9344function latLngToCoords(latlng, precision) { 9345 precision = typeof precision === 'number' ? precision : 6; 9346 return latlng.alt !== undefined ? 9347 [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision), formatNum(latlng.alt, precision)] : 9348 [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision)]; 9349} 9350 9351// @function latLngsToCoords(latlngs: Array, levelsDeep?: Number, closed?: Boolean): Array 9352// Reverse of [`coordsToLatLngs`](#geojson-coordstolatlngs) 9353// `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. 9354function latLngsToCoords(latlngs, levelsDeep, closed, precision) { 9355 var coords = []; 9356 9357 for (var i = 0, len = latlngs.length; i < len; i++) { 9358 coords.push(levelsDeep ? 9359 latLngsToCoords(latlngs[i], levelsDeep - 1, closed, precision) : 9360 latLngToCoords(latlngs[i], precision)); 9361 } 9362 9363 if (!levelsDeep && closed) { 9364 coords.push(coords[0]); 9365 } 9366 9367 return coords; 9368} 9369 9370function getFeature(layer, newGeometry) { 9371 return layer.feature ? 9372 extend({}, layer.feature, {geometry: newGeometry}) : 9373 asFeature(newGeometry); 9374} 9375 9376// @function asFeature(geojson: Object): Object 9377// Normalize GeoJSON geometries/features into GeoJSON features. 9378function asFeature(geojson) { 9379 if (geojson.type === 'Feature' || geojson.type === 'FeatureCollection') { 9380 return geojson; 9381 } 9382 9383 return { 9384 type: 'Feature', 9385 properties: {}, 9386 geometry: geojson 9387 }; 9388} 9389 9390var PointToGeoJSON = { 9391 toGeoJSON: function (precision) { 9392 return getFeature(this, { 9393 type: 'Point', 9394 coordinates: latLngToCoords(this.getLatLng(), precision) 9395 }); 9396 } 9397}; 9398 9399// @namespace Marker 9400// @method toGeoJSON(precision?: Number): Object 9401// `precision` is the number of decimal places for coordinates. 9402// The default value is 6 places. 9403// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the marker (as a GeoJSON `Point` Feature). 9404Marker.include(PointToGeoJSON); 9405 9406// @namespace CircleMarker 9407// @method toGeoJSON(precision?: Number): Object 9408// `precision` is the number of decimal places for coordinates. 9409// The default value is 6 places. 9410// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the circle marker (as a GeoJSON `Point` Feature). 9411Circle.include(PointToGeoJSON); 9412CircleMarker.include(PointToGeoJSON); 9413 9414 9415// @namespace Polyline 9416// @method toGeoJSON(precision?: Number): Object 9417// `precision` is the number of decimal places for coordinates. 9418// The default value is 6 places. 9419// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the polyline (as a GeoJSON `LineString` or `MultiLineString` Feature). 9420Polyline.include({ 9421 toGeoJSON: function (precision) { 9422 var multi = !isFlat(this._latlngs); 9423 9424 var coords = latLngsToCoords(this._latlngs, multi ? 1 : 0, false, precision); 9425 9426 return getFeature(this, { 9427 type: (multi ? 'Multi' : '') + 'LineString', 9428 coordinates: coords 9429 }); 9430 } 9431}); 9432 9433// @namespace Polygon 9434// @method toGeoJSON(precision?: Number): Object 9435// `precision` is the number of decimal places for coordinates. 9436// The default value is 6 places. 9437// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the polygon (as a GeoJSON `Polygon` or `MultiPolygon` Feature). 9438Polygon.include({ 9439 toGeoJSON: function (precision) { 9440 var holes = !isFlat(this._latlngs), 9441 multi = holes && !isFlat(this._latlngs[0]); 9442 9443 var coords = latLngsToCoords(this._latlngs, multi ? 2 : holes ? 1 : 0, true, precision); 9444 9445 if (!holes) { 9446 coords = [coords]; 9447 } 9448 9449 return getFeature(this, { 9450 type: (multi ? 'Multi' : '') + 'Polygon', 9451 coordinates: coords 9452 }); 9453 } 9454}); 9455 9456 9457// @namespace LayerGroup 9458LayerGroup.include({ 9459 toMultiPoint: function (precision) { 9460 var coords = []; 9461 9462 this.eachLayer(function (layer) { 9463 coords.push(layer.toGeoJSON(precision).geometry.coordinates); 9464 }); 9465 9466 return getFeature(this, { 9467 type: 'MultiPoint', 9468 coordinates: coords 9469 }); 9470 }, 9471 9472 // @method toGeoJSON(precision?: Number): Object 9473 // `precision` is the number of decimal places for coordinates. 9474 // The default value is 6 places. 9475 // Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the layer group (as a GeoJSON `FeatureCollection`, `GeometryCollection`, or `MultiPoint`). 9476 toGeoJSON: function (precision) { 9477 9478 var type = this.feature && this.feature.geometry && this.feature.geometry.type; 9479 9480 if (type === 'MultiPoint') { 9481 return this.toMultiPoint(precision); 9482 } 9483 9484 var isGeometryCollection = type === 'GeometryCollection', 9485 jsons = []; 9486 9487 this.eachLayer(function (layer) { 9488 if (layer.toGeoJSON) { 9489 var json = layer.toGeoJSON(precision); 9490 if (isGeometryCollection) { 9491 jsons.push(json.geometry); 9492 } else { 9493 var feature = asFeature(json); 9494 // Squash nested feature collections 9495 if (feature.type === 'FeatureCollection') { 9496 jsons.push.apply(jsons, feature.features); 9497 } else { 9498 jsons.push(feature); 9499 } 9500 } 9501 } 9502 }); 9503 9504 if (isGeometryCollection) { 9505 return getFeature(this, { 9506 geometries: jsons, 9507 type: 'GeometryCollection' 9508 }); 9509 } 9510 9511 return { 9512 type: 'FeatureCollection', 9513 features: jsons 9514 }; 9515 } 9516}); 9517 9518// @namespace GeoJSON 9519// @factory L.geoJSON(geojson?: Object, options?: GeoJSON options) 9520// Creates a GeoJSON layer. Optionally accepts an object in 9521// [GeoJSON format](https://tools.ietf.org/html/rfc7946) to display on the map 9522// (you can alternatively add it later with `addData` method) and an `options` object. 9523function geoJSON(geojson, options) { 9524 return new GeoJSON(geojson, options); 9525} 9526 9527// Backward compatibility. 9528var geoJson = geoJSON; 9529 9530/* 9531 * @class ImageOverlay 9532 * @aka L.ImageOverlay 9533 * @inherits Interactive layer 9534 * 9535 * Used to load and display a single image over specific bounds of the map. Extends `Layer`. 9536 * 9537 * @example 9538 * 9539 * ```js 9540 * var imageUrl = 'http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg', 9541 * imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]]; 9542 * L.imageOverlay(imageUrl, imageBounds).addTo(map); 9543 * ``` 9544 */ 9545 9546var ImageOverlay = Layer.extend({ 9547 9548 // @section 9549 // @aka ImageOverlay options 9550 options: { 9551 // @option opacity: Number = 1.0 9552 // The opacity of the image overlay. 9553 opacity: 1, 9554 9555 // @option alt: String = '' 9556 // Text for the `alt` attribute of the image (useful for accessibility). 9557 alt: '', 9558 9559 // @option interactive: Boolean = false 9560 // If `true`, the image overlay will emit [mouse events](#interactive-layer) when clicked or hovered. 9561 interactive: false, 9562 9563 // @option crossOrigin: Boolean|String = false 9564 // Whether the crossOrigin attribute will be added to the image. 9565 // 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. 9566 // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values. 9567 crossOrigin: false, 9568 9569 // @option errorOverlayUrl: String = '' 9570 // URL to the overlay image to show in place of the overlay that failed to load. 9571 errorOverlayUrl: '', 9572 9573 // @option zIndex: Number = 1 9574 // The explicit [zIndex](https://developer.mozilla.org/docs/Web/CSS/CSS_Positioning/Understanding_z_index) of the overlay layer. 9575 zIndex: 1, 9576 9577 // @option className: String = '' 9578 // A custom class name to assign to the image. Empty by default. 9579 className: '' 9580 }, 9581 9582 initialize: function (url, bounds, options) { // (String, LatLngBounds, Object) 9583 this._url = url; 9584 this._bounds = toLatLngBounds(bounds); 9585 9586 setOptions(this, options); 9587 }, 9588 9589 onAdd: function () { 9590 if (!this._image) { 9591 this._initImage(); 9592 9593 if (this.options.opacity < 1) { 9594 this._updateOpacity(); 9595 } 9596 } 9597 9598 if (this.options.interactive) { 9599 addClass(this._image, 'leaflet-interactive'); 9600 this.addInteractiveTarget(this._image); 9601 } 9602 9603 this.getPane().appendChild(this._image); 9604 this._reset(); 9605 }, 9606 9607 onRemove: function () { 9608 remove(this._image); 9609 if (this.options.interactive) { 9610 this.removeInteractiveTarget(this._image); 9611 } 9612 }, 9613 9614 // @method setOpacity(opacity: Number): this 9615 // Sets the opacity of the overlay. 9616 setOpacity: function (opacity) { 9617 this.options.opacity = opacity; 9618 9619 if (this._image) { 9620 this._updateOpacity(); 9621 } 9622 return this; 9623 }, 9624 9625 setStyle: function (styleOpts) { 9626 if (styleOpts.opacity) { 9627 this.setOpacity(styleOpts.opacity); 9628 } 9629 return this; 9630 }, 9631 9632 // @method bringToFront(): this 9633 // Brings the layer to the top of all overlays. 9634 bringToFront: function () { 9635 if (this._map) { 9636 toFront(this._image); 9637 } 9638 return this; 9639 }, 9640 9641 // @method bringToBack(): this 9642 // Brings the layer to the bottom of all overlays. 9643 bringToBack: function () { 9644 if (this._map) { 9645 toBack(this._image); 9646 } 9647 return this; 9648 }, 9649 9650 // @method setUrl(url: String): this 9651 // Changes the URL of the image. 9652 setUrl: function (url) { 9653 this._url = url; 9654 9655 if (this._image) { 9656 this._image.src = url; 9657 } 9658 return this; 9659 }, 9660 9661 // @method setBounds(bounds: LatLngBounds): this 9662 // Update the bounds that this ImageOverlay covers 9663 setBounds: function (bounds) { 9664 this._bounds = toLatLngBounds(bounds); 9665 9666 if (this._map) { 9667 this._reset(); 9668 } 9669 return this; 9670 }, 9671 9672 getEvents: function () { 9673 var events = { 9674 zoom: this._reset, 9675 viewreset: this._reset 9676 }; 9677 9678 if (this._zoomAnimated) { 9679 events.zoomanim = this._animateZoom; 9680 } 9681 9682 return events; 9683 }, 9684 9685 // @method setZIndex(value: Number): this 9686 // Changes the [zIndex](#imageoverlay-zindex) of the image overlay. 9687 setZIndex: function (value) { 9688 this.options.zIndex = value; 9689 this._updateZIndex(); 9690 return this; 9691 }, 9692 9693 // @method getBounds(): LatLngBounds 9694 // Get the bounds that this ImageOverlay covers 9695 getBounds: function () { 9696 return this._bounds; 9697 }, 9698 9699 // @method getElement(): HTMLElement 9700 // Returns the instance of [`HTMLImageElement`](https://developer.mozilla.org/docs/Web/API/HTMLImageElement) 9701 // used by this overlay. 9702 getElement: function () { 9703 return this._image; 9704 }, 9705 9706 _initImage: function () { 9707 var wasElementSupplied = this._url.tagName === 'IMG'; 9708 var img = this._image = wasElementSupplied ? this._url : create$1('img'); 9709 9710 addClass(img, 'leaflet-image-layer'); 9711 if (this._zoomAnimated) { addClass(img, 'leaflet-zoom-animated'); } 9712 if (this.options.className) { addClass(img, this.options.className); } 9713 9714 img.onselectstart = falseFn; 9715 img.onmousemove = falseFn; 9716 9717 // @event load: Event 9718 // Fired when the ImageOverlay layer has loaded its image 9719 img.onload = bind(this.fire, this, 'load'); 9720 img.onerror = bind(this._overlayOnError, this, 'error'); 9721 9722 if (this.options.crossOrigin || this.options.crossOrigin === '') { 9723 img.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin; 9724 } 9725 9726 if (this.options.zIndex) { 9727 this._updateZIndex(); 9728 } 9729 9730 if (wasElementSupplied) { 9731 this._url = img.src; 9732 return; 9733 } 9734 9735 img.src = this._url; 9736 img.alt = this.options.alt; 9737 }, 9738 9739 _animateZoom: function (e) { 9740 var scale = this._map.getZoomScale(e.zoom), 9741 offset = this._map._latLngBoundsToNewLayerBounds(this._bounds, e.zoom, e.center).min; 9742 9743 setTransform(this._image, offset, scale); 9744 }, 9745 9746 _reset: function () { 9747 var image = this._image, 9748 bounds = new Bounds( 9749 this._map.latLngToLayerPoint(this._bounds.getNorthWest()), 9750 this._map.latLngToLayerPoint(this._bounds.getSouthEast())), 9751 size = bounds.getSize(); 9752 9753 setPosition(image, bounds.min); 9754 9755 image.style.width = size.x + 'px'; 9756 image.style.height = size.y + 'px'; 9757 }, 9758 9759 _updateOpacity: function () { 9760 setOpacity(this._image, this.options.opacity); 9761 }, 9762 9763 _updateZIndex: function () { 9764 if (this._image && this.options.zIndex !== undefined && this.options.zIndex !== null) { 9765 this._image.style.zIndex = this.options.zIndex; 9766 } 9767 }, 9768 9769 _overlayOnError: function () { 9770 // @event error: Event 9771 // Fired when the ImageOverlay layer fails to load its image 9772 this.fire('error'); 9773 9774 var errorUrl = this.options.errorOverlayUrl; 9775 if (errorUrl && this._url !== errorUrl) { 9776 this._url = errorUrl; 9777 this._image.src = errorUrl; 9778 } 9779 } 9780}); 9781 9782// @factory L.imageOverlay(imageUrl: String, bounds: LatLngBounds, options?: ImageOverlay options) 9783// Instantiates an image overlay object given the URL of the image and the 9784// geographical bounds it is tied to. 9785var imageOverlay = function (url, bounds, options) { 9786 return new ImageOverlay(url, bounds, options); 9787}; 9788 9789/* 9790 * @class VideoOverlay 9791 * @aka L.VideoOverlay 9792 * @inherits ImageOverlay 9793 * 9794 * Used to load and display a video player over specific bounds of the map. Extends `ImageOverlay`. 9795 * 9796 * A video overlay uses the [`<video>`](https://developer.mozilla.org/docs/Web/HTML/Element/video) 9797 * HTML5 element. 9798 * 9799 * @example 9800 * 9801 * ```js 9802 * var videoUrl = 'https://www.mapbox.com/bites/00188/patricia_nasa.webm', 9803 * videoBounds = [[ 32, -130], [ 13, -100]]; 9804 * L.videoOverlay(videoUrl, videoBounds ).addTo(map); 9805 * ``` 9806 */ 9807 9808var VideoOverlay = ImageOverlay.extend({ 9809 9810 // @section 9811 // @aka VideoOverlay options 9812 options: { 9813 // @option autoplay: Boolean = true 9814 // Whether the video starts playing automatically when loaded. 9815 autoplay: true, 9816 9817 // @option loop: Boolean = true 9818 // Whether the video will loop back to the beginning when played. 9819 loop: true, 9820 9821 // @option keepAspectRatio: Boolean = true 9822 // Whether the video will save aspect ratio after the projection. 9823 // Relevant for supported browsers. Browser compatibility- https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit 9824 keepAspectRatio: true 9825 }, 9826 9827 _initImage: function () { 9828 var wasElementSupplied = this._url.tagName === 'VIDEO'; 9829 var vid = this._image = wasElementSupplied ? this._url : create$1('video'); 9830 9831 addClass(vid, 'leaflet-image-layer'); 9832 if (this._zoomAnimated) { addClass(vid, 'leaflet-zoom-animated'); } 9833 9834 vid.onselectstart = falseFn; 9835 vid.onmousemove = falseFn; 9836 9837 // @event load: Event 9838 // Fired when the video has finished loading the first frame 9839 vid.onloadeddata = bind(this.fire, this, 'load'); 9840 9841 if (wasElementSupplied) { 9842 var sourceElements = vid.getElementsByTagName('source'); 9843 var sources = []; 9844 for (var j = 0; j < sourceElements.length; j++) { 9845 sources.push(sourceElements[j].src); 9846 } 9847 9848 this._url = (sourceElements.length > 0) ? sources : [vid.src]; 9849 return; 9850 } 9851 9852 if (!isArray(this._url)) { this._url = [this._url]; } 9853 9854 if (!this.options.keepAspectRatio && vid.style.hasOwnProperty('objectFit')) { vid.style['objectFit'] = 'fill'; } 9855 vid.autoplay = !!this.options.autoplay; 9856 vid.loop = !!this.options.loop; 9857 for (var i = 0; i < this._url.length; i++) { 9858 var source = create$1('source'); 9859 source.src = this._url[i]; 9860 vid.appendChild(source); 9861 } 9862 } 9863 9864 // @method getElement(): HTMLVideoElement 9865 // Returns the instance of [`HTMLVideoElement`](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement) 9866 // used by this overlay. 9867}); 9868 9869 9870// @factory L.videoOverlay(video: String|Array|HTMLVideoElement, bounds: LatLngBounds, options?: VideoOverlay options) 9871// Instantiates an image overlay object given the URL of the video (or array of URLs, or even a video element) and the 9872// geographical bounds it is tied to. 9873 9874function videoOverlay(video, bounds, options) { 9875 return new VideoOverlay(video, bounds, options); 9876} 9877 9878/* 9879 * @class SVGOverlay 9880 * @aka L.SVGOverlay 9881 * @inherits ImageOverlay 9882 * 9883 * Used to load, display and provide DOM access to an SVG file over specific bounds of the map. Extends `ImageOverlay`. 9884 * 9885 * An SVG overlay uses the [`<svg>`](https://developer.mozilla.org/docs/Web/SVG/Element/svg) element. 9886 * 9887 * @example 9888 * 9889 * ```js 9890 * 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>', 9891 * elementBounds = [ [ 32, -130 ], [ 13, -100 ] ]; 9892 * L.svgOverlay(element, elementBounds).addTo(map); 9893 * ``` 9894 */ 9895 9896var SVGOverlay = ImageOverlay.extend({ 9897 _initImage: function () { 9898 var el = this._image = this._url; 9899 9900 addClass(el, 'leaflet-image-layer'); 9901 if (this._zoomAnimated) { addClass(el, 'leaflet-zoom-animated'); } 9902 9903 el.onselectstart = falseFn; 9904 el.onmousemove = falseFn; 9905 } 9906 9907 // @method getElement(): SVGElement 9908 // Returns the instance of [`SVGElement`](https://developer.mozilla.org/docs/Web/API/SVGElement) 9909 // used by this overlay. 9910}); 9911 9912 9913// @factory L.svgOverlay(svg: String|SVGElement, bounds: LatLngBounds, options?: SVGOverlay options) 9914// Instantiates an image overlay object given an SVG element and the geographical bounds it is tied to. 9915// A viewBox attribute is required on the SVG element to zoom in and out properly. 9916 9917function svgOverlay(el, bounds, options) { 9918 return new SVGOverlay(el, bounds, options); 9919} 9920 9921/* 9922 * @class DivOverlay 9923 * @inherits Layer 9924 * @aka L.DivOverlay 9925 * Base model for L.Popup and L.Tooltip. Inherit from it for custom popup like plugins. 9926 */ 9927 9928// @namespace DivOverlay 9929var DivOverlay = Layer.extend({ 9930 9931 // @section 9932 // @aka DivOverlay options 9933 options: { 9934 // @option offset: Point = Point(0, 7) 9935 // The offset of the popup position. Useful to control the anchor 9936 // of the popup when opening it on some overlays. 9937 offset: [0, 7], 9938 9939 // @option className: String = '' 9940 // A custom CSS class name to assign to the popup. 9941 className: '', 9942 9943 // @option pane: String = 'popupPane' 9944 // `Map pane` where the popup will be added. 9945 pane: 'popupPane' 9946 }, 9947 9948 initialize: function (options, source) { 9949 setOptions(this, options); 9950 9951 this._source = source; 9952 }, 9953 9954 onAdd: function (map) { 9955 this._zoomAnimated = map._zoomAnimated; 9956 9957 if (!this._container) { 9958 this._initLayout(); 9959 } 9960 9961 if (map._fadeAnimated) { 9962 setOpacity(this._container, 0); 9963 } 9964 9965 clearTimeout(this._removeTimeout); 9966 this.getPane().appendChild(this._container); 9967 this.update(); 9968 9969 if (map._fadeAnimated) { 9970 setOpacity(this._container, 1); 9971 } 9972 9973 this.bringToFront(); 9974 }, 9975 9976 onRemove: function (map) { 9977 if (map._fadeAnimated) { 9978 setOpacity(this._container, 0); 9979 this._removeTimeout = setTimeout(bind(remove, undefined, this._container), 200); 9980 } else { 9981 remove(this._container); 9982 } 9983 }, 9984 9985 // @namespace Popup 9986 // @method getLatLng: LatLng 9987 // Returns the geographical point of popup. 9988 getLatLng: function () { 9989 return this._latlng; 9990 }, 9991 9992 // @method setLatLng(latlng: LatLng): this 9993 // Sets the geographical point where the popup will open. 9994 setLatLng: function (latlng) { 9995 this._latlng = toLatLng(latlng); 9996 if (this._map) { 9997 this._updatePosition(); 9998 this._adjustPan(); 9999 } 10000 return this; 10001 }, 10002 10003 // @method getContent: String|HTMLElement 10004 // Returns the content of the popup. 10005 getContent: function () { 10006 return this._content; 10007 }, 10008 10009 // @method setContent(htmlContent: String|HTMLElement|Function): this 10010 // 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. 10011 setContent: function (content) { 10012 this._content = content; 10013 this.update(); 10014 return this; 10015 }, 10016 10017 // @method getElement: String|HTMLElement 10018 // Alias for [getContent()](#popup-getcontent) 10019 getElement: function () { 10020 return this._container; 10021 }, 10022 10023 // @method update: null 10024 // Updates the popup content, layout and position. Useful for updating the popup after something inside changed, e.g. image loaded. 10025 update: function () { 10026 if (!this._map) { return; } 10027 10028 this._container.style.visibility = 'hidden'; 10029 10030 this._updateContent(); 10031 this._updateLayout(); 10032 this._updatePosition(); 10033 10034 this._container.style.visibility = ''; 10035 10036 this._adjustPan(); 10037 }, 10038 10039 getEvents: function () { 10040 var events = { 10041 zoom: this._updatePosition, 10042 viewreset: this._updatePosition 10043 }; 10044 10045 if (this._zoomAnimated) { 10046 events.zoomanim = this._animateZoom; 10047 } 10048 return events; 10049 }, 10050 10051 // @method isOpen: Boolean 10052 // Returns `true` when the popup is visible on the map. 10053 isOpen: function () { 10054 return !!this._map && this._map.hasLayer(this); 10055 }, 10056 10057 // @method bringToFront: this 10058 // Brings this popup in front of other popups (in the same map pane). 10059 bringToFront: function () { 10060 if (this._map) { 10061 toFront(this._container); 10062 } 10063 return this; 10064 }, 10065 10066 // @method bringToBack: this 10067 // Brings this popup to the back of other popups (in the same map pane). 10068 bringToBack: function () { 10069 if (this._map) { 10070 toBack(this._container); 10071 } 10072 return this; 10073 }, 10074 10075 _prepareOpen: function (parent, layer, latlng) { 10076 if (!(layer instanceof Layer)) { 10077 latlng = layer; 10078 layer = parent; 10079 } 10080 10081 if (layer instanceof FeatureGroup) { 10082 for (var id in parent._layers) { 10083 layer = parent._layers[id]; 10084 break; 10085 } 10086 } 10087 10088 if (!latlng) { 10089 if (layer.getCenter) { 10090 latlng = layer.getCenter(); 10091 } else if (layer.getLatLng) { 10092 latlng = layer.getLatLng(); 10093 } else { 10094 throw new Error('Unable to get source layer LatLng.'); 10095 } 10096 } 10097 10098 // set overlay source to this layer 10099 this._source = layer; 10100 10101 // update the overlay (content, layout, ect...) 10102 this.update(); 10103 10104 return latlng; 10105 }, 10106 10107 _updateContent: function () { 10108 if (!this._content) { return; } 10109 10110 var node = this._contentNode; 10111 var content = (typeof this._content === 'function') ? this._content(this._source || this) : this._content; 10112 10113 if (typeof content === 'string') { 10114 node.innerHTML = content; 10115 } else { 10116 while (node.hasChildNodes()) { 10117 node.removeChild(node.firstChild); 10118 } 10119 node.appendChild(content); 10120 } 10121 this.fire('contentupdate'); 10122 }, 10123 10124 _updatePosition: function () { 10125 if (!this._map) { return; } 10126 10127 var pos = this._map.latLngToLayerPoint(this._latlng), 10128 offset = toPoint(this.options.offset), 10129 anchor = this._getAnchor(); 10130 10131 if (this._zoomAnimated) { 10132 setPosition(this._container, pos.add(anchor)); 10133 } else { 10134 offset = offset.add(pos).add(anchor); 10135 } 10136 10137 var bottom = this._containerBottom = -offset.y, 10138 left = this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x; 10139 10140 // bottom position the popup in case the height of the popup changes (images loading etc) 10141 this._container.style.bottom = bottom + 'px'; 10142 this._container.style.left = left + 'px'; 10143 }, 10144 10145 _getAnchor: function () { 10146 return [0, 0]; 10147 } 10148 10149}); 10150 10151/* 10152 * @class Popup 10153 * @inherits DivOverlay 10154 * @aka L.Popup 10155 * Used to open popups in certain places of the map. Use [Map.openPopup](#map-openpopup) to 10156 * open popups while making sure that only one popup is open at one time 10157 * (recommended for usability), or use [Map.addLayer](#map-addlayer) to open as many as you want. 10158 * 10159 * @example 10160 * 10161 * If you want to just bind a popup to marker click and then open it, it's really easy: 10162 * 10163 * ```js 10164 * marker.bindPopup(popupContent).openPopup(); 10165 * ``` 10166 * Path overlays like polylines also have a `bindPopup` method. 10167 * Here's a more complicated way to open a popup on a map: 10168 * 10169 * ```js 10170 * var popup = L.popup() 10171 * .setLatLng(latlng) 10172 * .setContent('<p>Hello world!<br />This is a nice popup.</p>') 10173 * .openOn(map); 10174 * ``` 10175 */ 10176 10177 10178// @namespace Popup 10179var Popup = DivOverlay.extend({ 10180 10181 // @section 10182 // @aka Popup options 10183 options: { 10184 // @option maxWidth: Number = 300 10185 // Max width of the popup, in pixels. 10186 maxWidth: 300, 10187 10188 // @option minWidth: Number = 50 10189 // Min width of the popup, in pixels. 10190 minWidth: 50, 10191 10192 // @option maxHeight: Number = null 10193 // If set, creates a scrollable container of the given height 10194 // inside a popup if its content exceeds it. 10195 maxHeight: null, 10196 10197 // @option autoPan: Boolean = true 10198 // Set it to `false` if you don't want the map to do panning animation 10199 // to fit the opened popup. 10200 autoPan: true, 10201 10202 // @option autoPanPaddingTopLeft: Point = null 10203 // The margin between the popup and the top left corner of the map 10204 // view after autopanning was performed. 10205 autoPanPaddingTopLeft: null, 10206 10207 // @option autoPanPaddingBottomRight: Point = null 10208 // The margin between the popup and the bottom right corner of the map 10209 // view after autopanning was performed. 10210 autoPanPaddingBottomRight: null, 10211 10212 // @option autoPanPadding: Point = Point(5, 5) 10213 // Equivalent of setting both top left and bottom right autopan padding to the same value. 10214 autoPanPadding: [5, 5], 10215 10216 // @option keepInView: Boolean = false 10217 // Set it to `true` if you want to prevent users from panning the popup 10218 // off of the screen while it is open. 10219 keepInView: false, 10220 10221 // @option closeButton: Boolean = true 10222 // Controls the presence of a close button in the popup. 10223 closeButton: true, 10224 10225 // @option autoClose: Boolean = true 10226 // Set it to `false` if you want to override the default behavior of 10227 // the popup closing when another popup is opened. 10228 autoClose: true, 10229 10230 // @option closeOnEscapeKey: Boolean = true 10231 // Set it to `false` if you want to override the default behavior of 10232 // the ESC key for closing of the popup. 10233 closeOnEscapeKey: true, 10234 10235 // @option closeOnClick: Boolean = * 10236 // Set it if you want to override the default behavior of the popup closing when user clicks 10237 // on the map. Defaults to the map's [`closePopupOnClick`](#map-closepopuponclick) option. 10238 10239 // @option className: String = '' 10240 // A custom CSS class name to assign to the popup. 10241 className: '' 10242 }, 10243 10244 // @namespace Popup 10245 // @method openOn(map: Map): this 10246 // Adds the popup to the map and closes the previous one. The same as `map.openPopup(popup)`. 10247 openOn: function (map) { 10248 map.openPopup(this); 10249 return this; 10250 }, 10251 10252 onAdd: function (map) { 10253 DivOverlay.prototype.onAdd.call(this, map); 10254 10255 // @namespace Map 10256 // @section Popup events 10257 // @event popupopen: PopupEvent 10258 // Fired when a popup is opened in the map 10259 map.fire('popupopen', {popup: this}); 10260 10261 if (this._source) { 10262 // @namespace Layer 10263 // @section Popup events 10264 // @event popupopen: PopupEvent 10265 // Fired when a popup bound to this layer is opened 10266 this._source.fire('popupopen', {popup: this}, true); 10267 // For non-path layers, we toggle the popup when clicking 10268 // again the layer, so prevent the map to reopen it. 10269 if (!(this._source instanceof Path)) { 10270 this._source.on('preclick', stopPropagation); 10271 } 10272 } 10273 }, 10274 10275 onRemove: function (map) { 10276 DivOverlay.prototype.onRemove.call(this, map); 10277 10278 // @namespace Map 10279 // @section Popup events 10280 // @event popupclose: PopupEvent 10281 // Fired when a popup in the map is closed 10282 map.fire('popupclose', {popup: this}); 10283 10284 if (this._source) { 10285 // @namespace Layer 10286 // @section Popup events 10287 // @event popupclose: PopupEvent 10288 // Fired when a popup bound to this layer is closed 10289 this._source.fire('popupclose', {popup: this}, true); 10290 if (!(this._source instanceof Path)) { 10291 this._source.off('preclick', stopPropagation); 10292 } 10293 } 10294 }, 10295 10296 getEvents: function () { 10297 var events = DivOverlay.prototype.getEvents.call(this); 10298 10299 if (this.options.closeOnClick !== undefined ? this.options.closeOnClick : this._map.options.closePopupOnClick) { 10300 events.preclick = this._close; 10301 } 10302 10303 if (this.options.keepInView) { 10304 events.moveend = this._adjustPan; 10305 } 10306 10307 return events; 10308 }, 10309 10310 _close: function () { 10311 if (this._map) { 10312 this._map.closePopup(this); 10313 } 10314 }, 10315 10316 _initLayout: function () { 10317 var prefix = 'leaflet-popup', 10318 container = this._container = create$1('div', 10319 prefix + ' ' + (this.options.className || '') + 10320 ' leaflet-zoom-animated'); 10321 10322 var wrapper = this._wrapper = create$1('div', prefix + '-content-wrapper', container); 10323 this._contentNode = create$1('div', prefix + '-content', wrapper); 10324 10325 disableClickPropagation(wrapper); 10326 disableScrollPropagation(this._contentNode); 10327 on(wrapper, 'contextmenu', stopPropagation); 10328 10329 this._tipContainer = create$1('div', prefix + '-tip-container', container); 10330 this._tip = create$1('div', prefix + '-tip', this._tipContainer); 10331 10332 if (this.options.closeButton) { 10333 var closeButton = this._closeButton = create$1('a', prefix + '-close-button', container); 10334 closeButton.href = '#close'; 10335 closeButton.innerHTML = '×'; 10336 10337 on(closeButton, 'click', this._onCloseButtonClick, this); 10338 } 10339 }, 10340 10341 _updateLayout: function () { 10342 var container = this._contentNode, 10343 style = container.style; 10344 10345 style.width = ''; 10346 style.whiteSpace = 'nowrap'; 10347 10348 var width = container.offsetWidth; 10349 width = Math.min(width, this.options.maxWidth); 10350 width = Math.max(width, this.options.minWidth); 10351 10352 style.width = (width + 1) + 'px'; 10353 style.whiteSpace = ''; 10354 10355 style.height = ''; 10356 10357 var height = container.offsetHeight, 10358 maxHeight = this.options.maxHeight, 10359 scrolledClass = 'leaflet-popup-scrolled'; 10360 10361 if (maxHeight && height > maxHeight) { 10362 style.height = maxHeight + 'px'; 10363 addClass(container, scrolledClass); 10364 } else { 10365 removeClass(container, scrolledClass); 10366 } 10367 10368 this._containerWidth = this._container.offsetWidth; 10369 }, 10370 10371 _animateZoom: function (e) { 10372 var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center), 10373 anchor = this._getAnchor(); 10374 setPosition(this._container, pos.add(anchor)); 10375 }, 10376 10377 _adjustPan: function () { 10378 if (!this.options.autoPan) { return; } 10379 if (this._map._panAnim) { this._map._panAnim.stop(); } 10380 10381 var map = this._map, 10382 marginBottom = parseInt(getStyle(this._container, 'marginBottom'), 10) || 0, 10383 containerHeight = this._container.offsetHeight + marginBottom, 10384 containerWidth = this._containerWidth, 10385 layerPos = new Point(this._containerLeft, -containerHeight - this._containerBottom); 10386 10387 layerPos._add(getPosition(this._container)); 10388 10389 var containerPos = map.layerPointToContainerPoint(layerPos), 10390 padding = toPoint(this.options.autoPanPadding), 10391 paddingTL = toPoint(this.options.autoPanPaddingTopLeft || padding), 10392 paddingBR = toPoint(this.options.autoPanPaddingBottomRight || padding), 10393 size = map.getSize(), 10394 dx = 0, 10395 dy = 0; 10396 10397 if (containerPos.x + containerWidth + paddingBR.x > size.x) { // right 10398 dx = containerPos.x + containerWidth - size.x + paddingBR.x; 10399 } 10400 if (containerPos.x - dx - paddingTL.x < 0) { // left 10401 dx = containerPos.x - paddingTL.x; 10402 } 10403 if (containerPos.y + containerHeight + paddingBR.y > size.y) { // bottom 10404 dy = containerPos.y + containerHeight - size.y + paddingBR.y; 10405 } 10406 if (containerPos.y - dy - paddingTL.y < 0) { // top 10407 dy = containerPos.y - paddingTL.y; 10408 } 10409 10410 // @namespace Map 10411 // @section Popup events 10412 // @event autopanstart: Event 10413 // Fired when the map starts autopanning when opening a popup. 10414 if (dx || dy) { 10415 map 10416 .fire('autopanstart') 10417 .panBy([dx, dy]); 10418 } 10419 }, 10420 10421 _onCloseButtonClick: function (e) { 10422 this._close(); 10423 stop(e); 10424 }, 10425 10426 _getAnchor: function () { 10427 // Where should we anchor the popup on the source layer? 10428 return toPoint(this._source && this._source._getPopupAnchor ? this._source._getPopupAnchor() : [0, 0]); 10429 } 10430 10431}); 10432 10433// @namespace Popup 10434// @factory L.popup(options?: Popup options, source?: Layer) 10435// 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. 10436var popup = function (options, source) { 10437 return new Popup(options, source); 10438}; 10439 10440 10441/* @namespace Map 10442 * @section Interaction Options 10443 * @option closePopupOnClick: Boolean = true 10444 * Set it to `false` if you don't want popups to close when user clicks the map. 10445 */ 10446Map.mergeOptions({ 10447 closePopupOnClick: true 10448}); 10449 10450 10451// @namespace Map 10452// @section Methods for Layers and Controls 10453Map.include({ 10454 // @method openPopup(popup: Popup): this 10455 // Opens the specified popup while closing the previously opened (to make sure only one is opened at one time for usability). 10456 // @alternative 10457 // @method openPopup(content: String|HTMLElement, latlng: LatLng, options?: Popup options): this 10458 // Creates a popup with the specified content and options and opens it in the given point on a map. 10459 openPopup: function (popup, latlng, options) { 10460 if (!(popup instanceof Popup)) { 10461 popup = new Popup(options).setContent(popup); 10462 } 10463 10464 if (latlng) { 10465 popup.setLatLng(latlng); 10466 } 10467 10468 if (this.hasLayer(popup)) { 10469 return this; 10470 } 10471 10472 if (this._popup && this._popup.options.autoClose) { 10473 this.closePopup(); 10474 } 10475 10476 this._popup = popup; 10477 return this.addLayer(popup); 10478 }, 10479 10480 // @method closePopup(popup?: Popup): this 10481 // Closes the popup previously opened with [openPopup](#map-openpopup) (or the given one). 10482 closePopup: function (popup) { 10483 if (!popup || popup === this._popup) { 10484 popup = this._popup; 10485 this._popup = null; 10486 } 10487 if (popup) { 10488 this.removeLayer(popup); 10489 } 10490 return this; 10491 } 10492}); 10493 10494/* 10495 * @namespace Layer 10496 * @section Popup methods example 10497 * 10498 * All layers share a set of methods convenient for binding popups to it. 10499 * 10500 * ```js 10501 * var layer = L.Polygon(latlngs).bindPopup('Hi There!').addTo(map); 10502 * layer.openPopup(); 10503 * layer.closePopup(); 10504 * ``` 10505 * 10506 * 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. 10507 */ 10508 10509// @section Popup methods 10510Layer.include({ 10511 10512 // @method bindPopup(content: String|HTMLElement|Function|Popup, options?: Popup options): this 10513 // Binds a popup to the layer with the passed `content` and sets up the 10514 // necessary event listeners. If a `Function` is passed it will receive 10515 // the layer as the first argument and should return a `String` or `HTMLElement`. 10516 bindPopup: function (content, options) { 10517 10518 if (content instanceof Popup) { 10519 setOptions(content, options); 10520 this._popup = content; 10521 content._source = this; 10522 } else { 10523 if (!this._popup || options) { 10524 this._popup = new Popup(options, this); 10525 } 10526 this._popup.setContent(content); 10527 } 10528 10529 if (!this._popupHandlersAdded) { 10530 this.on({ 10531 click: this._openPopup, 10532 keypress: this._onKeyPress, 10533 remove: this.closePopup, 10534 move: this._movePopup 10535 }); 10536 this._popupHandlersAdded = true; 10537 } 10538 10539 return this; 10540 }, 10541 10542 // @method unbindPopup(): this 10543 // Removes the popup previously bound with `bindPopup`. 10544 unbindPopup: function () { 10545 if (this._popup) { 10546 this.off({ 10547 click: this._openPopup, 10548 keypress: this._onKeyPress, 10549 remove: this.closePopup, 10550 move: this._movePopup 10551 }); 10552 this._popupHandlersAdded = false; 10553 this._popup = null; 10554 } 10555 return this; 10556 }, 10557 10558 // @method openPopup(latlng?: LatLng): this 10559 // Opens the bound popup at the specified `latlng` or at the default popup anchor if no `latlng` is passed. 10560 openPopup: function (layer, latlng) { 10561 if (this._popup && this._map) { 10562 latlng = this._popup._prepareOpen(this, layer, latlng); 10563 10564 // open the popup on the map 10565 this._map.openPopup(this._popup, latlng); 10566 } 10567 10568 return this; 10569 }, 10570 10571 // @method closePopup(): this 10572 // Closes the popup bound to this layer if it is open. 10573 closePopup: function () { 10574 if (this._popup) { 10575 this._popup._close(); 10576 } 10577 return this; 10578 }, 10579 10580 // @method togglePopup(): this 10581 // Opens or closes the popup bound to this layer depending on its current state. 10582 togglePopup: function (target) { 10583 if (this._popup) { 10584 if (this._popup._map) { 10585 this.closePopup(); 10586 } else { 10587 this.openPopup(target); 10588 } 10589 } 10590 return this; 10591 }, 10592 10593 // @method isPopupOpen(): boolean 10594 // Returns `true` if the popup bound to this layer is currently open. 10595 isPopupOpen: function () { 10596 return (this._popup ? this._popup.isOpen() : false); 10597 }, 10598 10599 // @method setPopupContent(content: String|HTMLElement|Popup): this 10600 // Sets the content of the popup bound to this layer. 10601 setPopupContent: function (content) { 10602 if (this._popup) { 10603 this._popup.setContent(content); 10604 } 10605 return this; 10606 }, 10607 10608 // @method getPopup(): Popup 10609 // Returns the popup bound to this layer. 10610 getPopup: function () { 10611 return this._popup; 10612 }, 10613 10614 _openPopup: function (e) { 10615 var layer = e.layer || e.target; 10616 10617 if (!this._popup) { 10618 return; 10619 } 10620 10621 if (!this._map) { 10622 return; 10623 } 10624 10625 // prevent map click 10626 stop(e); 10627 10628 // if this inherits from Path its a vector and we can just 10629 // open the popup at the new location 10630 if (layer instanceof Path) { 10631 this.openPopup(e.layer || e.target, e.latlng); 10632 return; 10633 } 10634 10635 // otherwise treat it like a marker and figure out 10636 // if we should toggle it open/closed 10637 if (this._map.hasLayer(this._popup) && this._popup._source === layer) { 10638 this.closePopup(); 10639 } else { 10640 this.openPopup(layer, e.latlng); 10641 } 10642 }, 10643 10644 _movePopup: function (e) { 10645 this._popup.setLatLng(e.latlng); 10646 }, 10647 10648 _onKeyPress: function (e) { 10649 if (e.originalEvent.keyCode === 13) { 10650 this._openPopup(e); 10651 } 10652 } 10653}); 10654 10655/* 10656 * @class Tooltip 10657 * @inherits DivOverlay 10658 * @aka L.Tooltip 10659 * Used to display small texts on top of map layers. 10660 * 10661 * @example 10662 * 10663 * ```js 10664 * marker.bindTooltip("my tooltip text").openTooltip(); 10665 * ``` 10666 * Note about tooltip offset. Leaflet takes two options in consideration 10667 * for computing tooltip offsetting: 10668 * - the `offset` Tooltip option: it defaults to [0, 0], and it's specific to one tooltip. 10669 * Add a positive x offset to move the tooltip to the right, and a positive y offset to 10670 * move it to the bottom. Negatives will move to the left and top. 10671 * - the `tooltipAnchor` Icon option: this will only be considered for Marker. You 10672 * should adapt this value if you use a custom icon. 10673 */ 10674 10675 10676// @namespace Tooltip 10677var Tooltip = DivOverlay.extend({ 10678 10679 // @section 10680 // @aka Tooltip options 10681 options: { 10682 // @option pane: String = 'tooltipPane' 10683 // `Map pane` where the tooltip will be added. 10684 pane: 'tooltipPane', 10685 10686 // @option offset: Point = Point(0, 0) 10687 // Optional offset of the tooltip position. 10688 offset: [0, 0], 10689 10690 // @option direction: String = 'auto' 10691 // Direction where to open the tooltip. Possible values are: `right`, `left`, 10692 // `top`, `bottom`, `center`, `auto`. 10693 // `auto` will dynamically switch between `right` and `left` according to the tooltip 10694 // position on the map. 10695 direction: 'auto', 10696 10697 // @option permanent: Boolean = false 10698 // Whether to open the tooltip permanently or only on mouseover. 10699 permanent: false, 10700 10701 // @option sticky: Boolean = false 10702 // If true, the tooltip will follow the mouse instead of being fixed at the feature center. 10703 sticky: false, 10704 10705 // @option interactive: Boolean = false 10706 // If true, the tooltip will listen to the feature events. 10707 interactive: false, 10708 10709 // @option opacity: Number = 0.9 10710 // Tooltip container opacity. 10711 opacity: 0.9 10712 }, 10713 10714 onAdd: function (map) { 10715 DivOverlay.prototype.onAdd.call(this, map); 10716 this.setOpacity(this.options.opacity); 10717 10718 // @namespace Map 10719 // @section Tooltip events 10720 // @event tooltipopen: TooltipEvent 10721 // Fired when a tooltip is opened in the map. 10722 map.fire('tooltipopen', {tooltip: this}); 10723 10724 if (this._source) { 10725 // @namespace Layer 10726 // @section Tooltip events 10727 // @event tooltipopen: TooltipEvent 10728 // Fired when a tooltip bound to this layer is opened. 10729 this._source.fire('tooltipopen', {tooltip: this}, true); 10730 } 10731 }, 10732 10733 onRemove: function (map) { 10734 DivOverlay.prototype.onRemove.call(this, map); 10735 10736 // @namespace Map 10737 // @section Tooltip events 10738 // @event tooltipclose: TooltipEvent 10739 // Fired when a tooltip in the map is closed. 10740 map.fire('tooltipclose', {tooltip: this}); 10741 10742 if (this._source) { 10743 // @namespace Layer 10744 // @section Tooltip events 10745 // @event tooltipclose: TooltipEvent 10746 // Fired when a tooltip bound to this layer is closed. 10747 this._source.fire('tooltipclose', {tooltip: this}, true); 10748 } 10749 }, 10750 10751 getEvents: function () { 10752 var events = DivOverlay.prototype.getEvents.call(this); 10753 10754 if (touch && !this.options.permanent) { 10755 events.preclick = this._close; 10756 } 10757 10758 return events; 10759 }, 10760 10761 _close: function () { 10762 if (this._map) { 10763 this._map.closeTooltip(this); 10764 } 10765 }, 10766 10767 _initLayout: function () { 10768 var prefix = 'leaflet-tooltip', 10769 className = prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide'); 10770 10771 this._contentNode = this._container = create$1('div', className); 10772 }, 10773 10774 _updateLayout: function () {}, 10775 10776 _adjustPan: function () {}, 10777 10778 _setPosition: function (pos) { 10779 var map = this._map, 10780 container = this._container, 10781 centerPoint = map.latLngToContainerPoint(map.getCenter()), 10782 tooltipPoint = map.layerPointToContainerPoint(pos), 10783 direction = this.options.direction, 10784 tooltipWidth = container.offsetWidth, 10785 tooltipHeight = container.offsetHeight, 10786 offset = toPoint(this.options.offset), 10787 anchor = this._getAnchor(); 10788 10789 if (direction === 'top') { 10790 pos = pos.add(toPoint(-tooltipWidth / 2 + offset.x, -tooltipHeight + offset.y + anchor.y, true)); 10791 } else if (direction === 'bottom') { 10792 pos = pos.subtract(toPoint(tooltipWidth / 2 - offset.x, -offset.y, true)); 10793 } else if (direction === 'center') { 10794 pos = pos.subtract(toPoint(tooltipWidth / 2 + offset.x, tooltipHeight / 2 - anchor.y + offset.y, true)); 10795 } else if (direction === 'right' || direction === 'auto' && tooltipPoint.x < centerPoint.x) { 10796 direction = 'right'; 10797 pos = pos.add(toPoint(offset.x + anchor.x, anchor.y - tooltipHeight / 2 + offset.y, true)); 10798 } else { 10799 direction = 'left'; 10800 pos = pos.subtract(toPoint(tooltipWidth + anchor.x - offset.x, tooltipHeight / 2 - anchor.y - offset.y, true)); 10801 } 10802 10803 removeClass(container, 'leaflet-tooltip-right'); 10804 removeClass(container, 'leaflet-tooltip-left'); 10805 removeClass(container, 'leaflet-tooltip-top'); 10806 removeClass(container, 'leaflet-tooltip-bottom'); 10807 addClass(container, 'leaflet-tooltip-' + direction); 10808 setPosition(container, pos); 10809 }, 10810 10811 _updatePosition: function () { 10812 var pos = this._map.latLngToLayerPoint(this._latlng); 10813 this._setPosition(pos); 10814 }, 10815 10816 setOpacity: function (opacity) { 10817 this.options.opacity = opacity; 10818 10819 if (this._container) { 10820 setOpacity(this._container, opacity); 10821 } 10822 }, 10823 10824 _animateZoom: function (e) { 10825 var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center); 10826 this._setPosition(pos); 10827 }, 10828 10829 _getAnchor: function () { 10830 // Where should we anchor the tooltip on the source layer? 10831 return toPoint(this._source && this._source._getTooltipAnchor && !this.options.sticky ? this._source._getTooltipAnchor() : [0, 0]); 10832 } 10833 10834}); 10835 10836// @namespace Tooltip 10837// @factory L.tooltip(options?: Tooltip options, source?: Layer) 10838// 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. 10839var tooltip = function (options, source) { 10840 return new Tooltip(options, source); 10841}; 10842 10843// @namespace Map 10844// @section Methods for Layers and Controls 10845Map.include({ 10846 10847 // @method openTooltip(tooltip: Tooltip): this 10848 // Opens the specified tooltip. 10849 // @alternative 10850 // @method openTooltip(content: String|HTMLElement, latlng: LatLng, options?: Tooltip options): this 10851 // Creates a tooltip with the specified content and options and open it. 10852 openTooltip: function (tooltip, latlng, options) { 10853 if (!(tooltip instanceof Tooltip)) { 10854 tooltip = new Tooltip(options).setContent(tooltip); 10855 } 10856 10857 if (latlng) { 10858 tooltip.setLatLng(latlng); 10859 } 10860 10861 if (this.hasLayer(tooltip)) { 10862 return this; 10863 } 10864 10865 return this.addLayer(tooltip); 10866 }, 10867 10868 // @method closeTooltip(tooltip?: Tooltip): this 10869 // Closes the tooltip given as parameter. 10870 closeTooltip: function (tooltip) { 10871 if (tooltip) { 10872 this.removeLayer(tooltip); 10873 } 10874 return this; 10875 } 10876 10877}); 10878 10879/* 10880 * @namespace Layer 10881 * @section Tooltip methods example 10882 * 10883 * All layers share a set of methods convenient for binding tooltips to it. 10884 * 10885 * ```js 10886 * var layer = L.Polygon(latlngs).bindTooltip('Hi There!').addTo(map); 10887 * layer.openTooltip(); 10888 * layer.closeTooltip(); 10889 * ``` 10890 */ 10891 10892// @section Tooltip methods 10893Layer.include({ 10894 10895 // @method bindTooltip(content: String|HTMLElement|Function|Tooltip, options?: Tooltip options): this 10896 // Binds a tooltip to the layer with the passed `content` and sets up the 10897 // necessary event listeners. If a `Function` is passed it will receive 10898 // the layer as the first argument and should return a `String` or `HTMLElement`. 10899 bindTooltip: function (content, options) { 10900 10901 if (content instanceof Tooltip) { 10902 setOptions(content, options); 10903 this._tooltip = content; 10904 content._source = this; 10905 } else { 10906 if (!this._tooltip || options) { 10907 this._tooltip = new Tooltip(options, this); 10908 } 10909 this._tooltip.setContent(content); 10910 10911 } 10912 10913 this._initTooltipInteractions(); 10914 10915 if (this._tooltip.options.permanent && this._map && this._map.hasLayer(this)) { 10916 this.openTooltip(); 10917 } 10918 10919 return this; 10920 }, 10921 10922 // @method unbindTooltip(): this 10923 // Removes the tooltip previously bound with `bindTooltip`. 10924 unbindTooltip: function () { 10925 if (this._tooltip) { 10926 this._initTooltipInteractions(true); 10927 this.closeTooltip(); 10928 this._tooltip = null; 10929 } 10930 return this; 10931 }, 10932 10933 _initTooltipInteractions: function (remove$$1) { 10934 if (!remove$$1 && this._tooltipHandlersAdded) { return; } 10935 var onOff = remove$$1 ? 'off' : 'on', 10936 events = { 10937 remove: this.closeTooltip, 10938 move: this._moveTooltip 10939 }; 10940 if (!this._tooltip.options.permanent) { 10941 events.mouseover = this._openTooltip; 10942 events.mouseout = this.closeTooltip; 10943 if (this._tooltip.options.sticky) { 10944 events.mousemove = this._moveTooltip; 10945 } 10946 if (touch) { 10947 events.click = this._openTooltip; 10948 } 10949 } else { 10950 events.add = this._openTooltip; 10951 } 10952 this[onOff](events); 10953 this._tooltipHandlersAdded = !remove$$1; 10954 }, 10955 10956 // @method openTooltip(latlng?: LatLng): this 10957 // Opens the bound tooltip at the specified `latlng` or at the default tooltip anchor if no `latlng` is passed. 10958 openTooltip: function (layer, latlng) { 10959 if (this._tooltip && this._map) { 10960 latlng = this._tooltip._prepareOpen(this, layer, latlng); 10961 10962 // open the tooltip on the map 10963 this._map.openTooltip(this._tooltip, latlng); 10964 10965 // Tooltip container may not be defined if not permanent and never 10966 // opened. 10967 if (this._tooltip.options.interactive && this._tooltip._container) { 10968 addClass(this._tooltip._container, 'leaflet-clickable'); 10969 this.addInteractiveTarget(this._tooltip._container); 10970 } 10971 } 10972 10973 return this; 10974 }, 10975 10976 // @method closeTooltip(): this 10977 // Closes the tooltip bound to this layer if it is open. 10978 closeTooltip: function () { 10979 if (this._tooltip) { 10980 this._tooltip._close(); 10981 if (this._tooltip.options.interactive && this._tooltip._container) { 10982 removeClass(this._tooltip._container, 'leaflet-clickable'); 10983 this.removeInteractiveTarget(this._tooltip._container); 10984 } 10985 } 10986 return this; 10987 }, 10988 10989 // @method toggleTooltip(): this 10990 // Opens or closes the tooltip bound to this layer depending on its current state. 10991 toggleTooltip: function (target) { 10992 if (this._tooltip) { 10993 if (this._tooltip._map) { 10994 this.closeTooltip(); 10995 } else { 10996 this.openTooltip(target); 10997 } 10998 } 10999 return this; 11000 }, 11001 11002 // @method isTooltipOpen(): boolean 11003 // Returns `true` if the tooltip bound to this layer is currently open. 11004 isTooltipOpen: function () { 11005 return this._tooltip.isOpen(); 11006 }, 11007 11008 // @method setTooltipContent(content: String|HTMLElement|Tooltip): this 11009 // Sets the content of the tooltip bound to this layer. 11010 setTooltipContent: function (content) { 11011 if (this._tooltip) { 11012 this._tooltip.setContent(content); 11013 } 11014 return this; 11015 }, 11016 11017 // @method getTooltip(): Tooltip 11018 // Returns the tooltip bound to this layer. 11019 getTooltip: function () { 11020 return this._tooltip; 11021 }, 11022 11023 _openTooltip: function (e) { 11024 var layer = e.layer || e.target; 11025 11026 if (!this._tooltip || !this._map) { 11027 return; 11028 } 11029 this.openTooltip(layer, this._tooltip.options.sticky ? e.latlng : undefined); 11030 }, 11031 11032 _moveTooltip: function (e) { 11033 var latlng = e.latlng, containerPoint, layerPoint; 11034 if (this._tooltip.options.sticky && e.originalEvent) { 11035 containerPoint = this._map.mouseEventToContainerPoint(e.originalEvent); 11036 layerPoint = this._map.containerPointToLayerPoint(containerPoint); 11037 latlng = this._map.layerPointToLatLng(layerPoint); 11038 } 11039 this._tooltip.setLatLng(latlng); 11040 } 11041}); 11042 11043/* 11044 * @class DivIcon 11045 * @aka L.DivIcon 11046 * @inherits Icon 11047 * 11048 * Represents a lightweight icon for markers that uses a simple `<div>` 11049 * element instead of an image. Inherits from `Icon` but ignores the `iconUrl` and shadow options. 11050 * 11051 * @example 11052 * ```js 11053 * var myIcon = L.divIcon({className: 'my-div-icon'}); 11054 * // you can set .my-div-icon styles in CSS 11055 * 11056 * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map); 11057 * ``` 11058 * 11059 * By default, it has a 'leaflet-div-icon' CSS class and is styled as a little white square with a shadow. 11060 */ 11061 11062var DivIcon = Icon.extend({ 11063 options: { 11064 // @section 11065 // @aka DivIcon options 11066 iconSize: [12, 12], // also can be set through CSS 11067 11068 // iconAnchor: (Point), 11069 // popupAnchor: (Point), 11070 11071 // @option html: String|HTMLElement = '' 11072 // Custom HTML code to put inside the div element, empty by default. Alternatively, 11073 // an instance of `HTMLElement`. 11074 html: false, 11075 11076 // @option bgPos: Point = [0, 0] 11077 // Optional relative position of the background, in pixels 11078 bgPos: null, 11079 11080 className: 'leaflet-div-icon' 11081 }, 11082 11083 createIcon: function (oldIcon) { 11084 var div = (oldIcon && oldIcon.tagName === 'DIV') ? oldIcon : document.createElement('div'), 11085 options = this.options; 11086 11087 if (options.html instanceof Element) { 11088 empty(div); 11089 div.appendChild(options.html); 11090 } else { 11091 div.innerHTML = options.html !== false ? options.html : ''; 11092 } 11093 11094 if (options.bgPos) { 11095 var bgPos = toPoint(options.bgPos); 11096 div.style.backgroundPosition = (-bgPos.x) + 'px ' + (-bgPos.y) + 'px'; 11097 } 11098 this._setIconStyles(div, 'icon'); 11099 11100 return div; 11101 }, 11102 11103 createShadow: function () { 11104 return null; 11105 } 11106}); 11107 11108// @factory L.divIcon(options: DivIcon options) 11109// Creates a `DivIcon` instance with the given options. 11110function divIcon(options) { 11111 return new DivIcon(options); 11112} 11113 11114Icon.Default = IconDefault; 11115 11116/* 11117 * @class GridLayer 11118 * @inherits Layer 11119 * @aka L.GridLayer 11120 * 11121 * Generic class for handling a tiled grid of HTML elements. This is the base class for all tile layers and replaces `TileLayer.Canvas`. 11122 * 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. 11123 * 11124 * 11125 * @section Synchronous usage 11126 * @example 11127 * 11128 * 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. 11129 * 11130 * ```js 11131 * var CanvasLayer = L.GridLayer.extend({ 11132 * createTile: function(coords){ 11133 * // create a <canvas> element for drawing 11134 * var tile = L.DomUtil.create('canvas', 'leaflet-tile'); 11135 * 11136 * // setup tile width and height according to the options 11137 * var size = this.getTileSize(); 11138 * tile.width = size.x; 11139 * tile.height = size.y; 11140 * 11141 * // get a canvas context and draw something on it using coords.x, coords.y and coords.z 11142 * var ctx = tile.getContext('2d'); 11143 * 11144 * // return the tile so it can be rendered on screen 11145 * return tile; 11146 * } 11147 * }); 11148 * ``` 11149 * 11150 * @section Asynchronous usage 11151 * @example 11152 * 11153 * 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. 11154 * 11155 * ```js 11156 * var CanvasLayer = L.GridLayer.extend({ 11157 * createTile: function(coords, done){ 11158 * var error; 11159 * 11160 * // create a <canvas> element for drawing 11161 * var tile = L.DomUtil.create('canvas', 'leaflet-tile'); 11162 * 11163 * // setup tile width and height according to the options 11164 * var size = this.getTileSize(); 11165 * tile.width = size.x; 11166 * tile.height = size.y; 11167 * 11168 * // draw something asynchronously and pass the tile to the done() callback 11169 * setTimeout(function() { 11170 * done(error, tile); 11171 * }, 1000); 11172 * 11173 * return tile; 11174 * } 11175 * }); 11176 * ``` 11177 * 11178 * @section 11179 */ 11180 11181 11182var GridLayer = Layer.extend({ 11183 11184 // @section 11185 // @aka GridLayer options 11186 options: { 11187 // @option tileSize: Number|Point = 256 11188 // Width and height of tiles in the grid. Use a number if width and height are equal, or `L.point(width, height)` otherwise. 11189 tileSize: 256, 11190 11191 // @option opacity: Number = 1.0 11192 // Opacity of the tiles. Can be used in the `createTile()` function. 11193 opacity: 1, 11194 11195 // @option updateWhenIdle: Boolean = (depends) 11196 // Load new tiles only when panning ends. 11197 // `true` by default on mobile browsers, in order to avoid too many requests and keep smooth navigation. 11198 // `false` otherwise in order to display new tiles _during_ panning, since it is easy to pan outside the 11199 // [`keepBuffer`](#gridlayer-keepbuffer) option in desktop browsers. 11200 updateWhenIdle: mobile, 11201 11202 // @option updateWhenZooming: Boolean = true 11203 // 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. 11204 updateWhenZooming: true, 11205 11206 // @option updateInterval: Number = 200 11207 // Tiles will not update more than once every `updateInterval` milliseconds when panning. 11208 updateInterval: 200, 11209 11210 // @option zIndex: Number = 1 11211 // The explicit zIndex of the tile layer. 11212 zIndex: 1, 11213 11214 // @option bounds: LatLngBounds = undefined 11215 // If set, tiles will only be loaded inside the set `LatLngBounds`. 11216 bounds: null, 11217 11218 // @option minZoom: Number = 0 11219 // The minimum zoom level down to which this layer will be displayed (inclusive). 11220 minZoom: 0, 11221 11222 // @option maxZoom: Number = undefined 11223 // The maximum zoom level up to which this layer will be displayed (inclusive). 11224 maxZoom: undefined, 11225 11226 // @option maxNativeZoom: Number = undefined 11227 // Maximum zoom number the tile source has available. If it is specified, 11228 // the tiles on all zoom levels higher than `maxNativeZoom` will be loaded 11229 // from `maxNativeZoom` level and auto-scaled. 11230 maxNativeZoom: undefined, 11231 11232 // @option minNativeZoom: Number = undefined 11233 // Minimum zoom number the tile source has available. If it is specified, 11234 // the tiles on all zoom levels lower than `minNativeZoom` will be loaded 11235 // from `minNativeZoom` level and auto-scaled. 11236 minNativeZoom: undefined, 11237 11238 // @option noWrap: Boolean = false 11239 // Whether the layer is wrapped around the antimeridian. If `true`, the 11240 // GridLayer will only be displayed once at low zoom levels. Has no 11241 // effect when the [map CRS](#map-crs) doesn't wrap around. Can be used 11242 // in combination with [`bounds`](#gridlayer-bounds) to prevent requesting 11243 // tiles outside the CRS limits. 11244 noWrap: false, 11245 11246 // @option pane: String = 'tilePane' 11247 // `Map pane` where the grid layer will be added. 11248 pane: 'tilePane', 11249 11250 // @option className: String = '' 11251 // A custom class name to assign to the tile layer. Empty by default. 11252 className: '', 11253 11254 // @option keepBuffer: Number = 2 11255 // When panning the map, keep this many rows and columns of tiles before unloading them. 11256 keepBuffer: 2 11257 }, 11258 11259 initialize: function (options) { 11260 setOptions(this, options); 11261 }, 11262 11263 onAdd: function () { 11264 this._initContainer(); 11265 11266 this._levels = {}; 11267 this._tiles = {}; 11268 11269 this._resetView(); 11270 this._update(); 11271 }, 11272 11273 beforeAdd: function (map) { 11274 map._addZoomLimit(this); 11275 }, 11276 11277 onRemove: function (map) { 11278 this._removeAllTiles(); 11279 remove(this._container); 11280 map._removeZoomLimit(this); 11281 this._container = null; 11282 this._tileZoom = undefined; 11283 }, 11284 11285 // @method bringToFront: this 11286 // Brings the tile layer to the top of all tile layers. 11287 bringToFront: function () { 11288 if (this._map) { 11289 toFront(this._container); 11290 this._setAutoZIndex(Math.max); 11291 } 11292 return this; 11293 }, 11294 11295 // @method bringToBack: this 11296 // Brings the tile layer to the bottom of all tile layers. 11297 bringToBack: function () { 11298 if (this._map) { 11299 toBack(this._container); 11300 this._setAutoZIndex(Math.min); 11301 } 11302 return this; 11303 }, 11304 11305 // @method getContainer: HTMLElement 11306 // Returns the HTML element that contains the tiles for this layer. 11307 getContainer: function () { 11308 return this._container; 11309 }, 11310 11311 // @method setOpacity(opacity: Number): this 11312 // Changes the [opacity](#gridlayer-opacity) of the grid layer. 11313 setOpacity: function (opacity) { 11314 this.options.opacity = opacity; 11315 this._updateOpacity(); 11316 return this; 11317 }, 11318 11319 // @method setZIndex(zIndex: Number): this 11320 // Changes the [zIndex](#gridlayer-zindex) of the grid layer. 11321 setZIndex: function (zIndex) { 11322 this.options.zIndex = zIndex; 11323 this._updateZIndex(); 11324 11325 return this; 11326 }, 11327 11328 // @method isLoading: Boolean 11329 // Returns `true` if any tile in the grid layer has not finished loading. 11330 isLoading: function () { 11331 return this._loading; 11332 }, 11333 11334 // @method redraw: this 11335 // Causes the layer to clear all the tiles and request them again. 11336 redraw: function () { 11337 if (this._map) { 11338 this._removeAllTiles(); 11339 this._update(); 11340 } 11341 return this; 11342 }, 11343 11344 getEvents: function () { 11345 var events = { 11346 viewprereset: this._invalidateAll, 11347 viewreset: this._resetView, 11348 zoom: this._resetView, 11349 moveend: this._onMoveEnd 11350 }; 11351 11352 if (!this.options.updateWhenIdle) { 11353 // update tiles on move, but not more often than once per given interval 11354 if (!this._onMove) { 11355 this._onMove = throttle(this._onMoveEnd, this.options.updateInterval, this); 11356 } 11357 11358 events.move = this._onMove; 11359 } 11360 11361 if (this._zoomAnimated) { 11362 events.zoomanim = this._animateZoom; 11363 } 11364 11365 return events; 11366 }, 11367 11368 // @section Extension methods 11369 // Layers extending `GridLayer` shall reimplement the following method. 11370 // @method createTile(coords: Object, done?: Function): HTMLElement 11371 // Called only internally, must be overridden by classes extending `GridLayer`. 11372 // Returns the `HTMLElement` corresponding to the given `coords`. If the `done` callback 11373 // is specified, it must be called when the tile has finished loading and drawing. 11374 createTile: function () { 11375 return document.createElement('div'); 11376 }, 11377 11378 // @section 11379 // @method getTileSize: Point 11380 // Normalizes the [tileSize option](#gridlayer-tilesize) into a point. Used by the `createTile()` method. 11381 getTileSize: function () { 11382 var s = this.options.tileSize; 11383 return s instanceof Point ? s : new Point(s, s); 11384 }, 11385 11386 _updateZIndex: function () { 11387 if (this._container && this.options.zIndex !== undefined && this.options.zIndex !== null) { 11388 this._container.style.zIndex = this.options.zIndex; 11389 } 11390 }, 11391 11392 _setAutoZIndex: function (compare) { 11393 // go through all other layers of the same pane, set zIndex to max + 1 (front) or min - 1 (back) 11394 11395 var layers = this.getPane().children, 11396 edgeZIndex = -compare(-Infinity, Infinity); // -Infinity for max, Infinity for min 11397 11398 for (var i = 0, len = layers.length, zIndex; i < len; i++) { 11399 11400 zIndex = layers[i].style.zIndex; 11401 11402 if (layers[i] !== this._container && zIndex) { 11403 edgeZIndex = compare(edgeZIndex, +zIndex); 11404 } 11405 } 11406 11407 if (isFinite(edgeZIndex)) { 11408 this.options.zIndex = edgeZIndex + compare(-1, 1); 11409 this._updateZIndex(); 11410 } 11411 }, 11412 11413 _updateOpacity: function () { 11414 if (!this._map) { return; } 11415 11416 // IE doesn't inherit filter opacity properly, so we're forced to set it on tiles 11417 if (ielt9) { return; } 11418 11419 setOpacity(this._container, this.options.opacity); 11420 11421 var now = +new Date(), 11422 nextFrame = false, 11423 willPrune = false; 11424 11425 for (var key in this._tiles) { 11426 var tile = this._tiles[key]; 11427 if (!tile.current || !tile.loaded) { continue; } 11428 11429 var fade = Math.min(1, (now - tile.loaded) / 200); 11430 11431 setOpacity(tile.el, fade); 11432 if (fade < 1) { 11433 nextFrame = true; 11434 } else { 11435 if (tile.active) { 11436 willPrune = true; 11437 } else { 11438 this._onOpaqueTile(tile); 11439 } 11440 tile.active = true; 11441 } 11442 } 11443 11444 if (willPrune && !this._noPrune) { this._pruneTiles(); } 11445 11446 if (nextFrame) { 11447 cancelAnimFrame(this._fadeFrame); 11448 this._fadeFrame = requestAnimFrame(this._updateOpacity, this); 11449 } 11450 }, 11451 11452 _onOpaqueTile: falseFn, 11453 11454 _initContainer: function () { 11455 if (this._container) { return; } 11456 11457 this._container = create$1('div', 'leaflet-layer ' + (this.options.className || '')); 11458 this._updateZIndex(); 11459 11460 if (this.options.opacity < 1) { 11461 this._updateOpacity(); 11462 } 11463 11464 this.getPane().appendChild(this._container); 11465 }, 11466 11467 _updateLevels: function () { 11468 11469 var zoom = this._tileZoom, 11470 maxZoom = this.options.maxZoom; 11471 11472 if (zoom === undefined) { return undefined; } 11473 11474 for (var z in this._levels) { 11475 if (this._levels[z].el.children.length || z === zoom) { 11476 this._levels[z].el.style.zIndex = maxZoom - Math.abs(zoom - z); 11477 this._onUpdateLevel(z); 11478 } else { 11479 remove(this._levels[z].el); 11480 this._removeTilesAtZoom(z); 11481 this._onRemoveLevel(z); 11482 delete this._levels[z]; 11483 } 11484 } 11485 11486 var level = this._levels[zoom], 11487 map = this._map; 11488 11489 if (!level) { 11490 level = this._levels[zoom] = {}; 11491 11492 level.el = create$1('div', 'leaflet-tile-container leaflet-zoom-animated', this._container); 11493 level.el.style.zIndex = maxZoom; 11494 11495 level.origin = map.project(map.unproject(map.getPixelOrigin()), zoom).round(); 11496 level.zoom = zoom; 11497 11498 this._setZoomTransform(level, map.getCenter(), map.getZoom()); 11499 11500 // force the browser to consider the newly added element for transition 11501 falseFn(level.el.offsetWidth); 11502 11503 this._onCreateLevel(level); 11504 } 11505 11506 this._level = level; 11507 11508 return level; 11509 }, 11510 11511 _onUpdateLevel: falseFn, 11512 11513 _onRemoveLevel: falseFn, 11514 11515 _onCreateLevel: falseFn, 11516 11517 _pruneTiles: function () { 11518 if (!this._map) { 11519 return; 11520 } 11521 11522 var key, tile; 11523 11524 var zoom = this._map.getZoom(); 11525 if (zoom > this.options.maxZoom || 11526 zoom < this.options.minZoom) { 11527 this._removeAllTiles(); 11528 return; 11529 } 11530 11531 for (key in this._tiles) { 11532 tile = this._tiles[key]; 11533 tile.retain = tile.current; 11534 } 11535 11536 for (key in this._tiles) { 11537 tile = this._tiles[key]; 11538 if (tile.current && !tile.active) { 11539 var coords = tile.coords; 11540 if (!this._retainParent(coords.x, coords.y, coords.z, coords.z - 5)) { 11541 this._retainChildren(coords.x, coords.y, coords.z, coords.z + 2); 11542 } 11543 } 11544 } 11545 11546 for (key in this._tiles) { 11547 if (!this._tiles[key].retain) { 11548 this._removeTile(key); 11549 } 11550 } 11551 }, 11552 11553 _removeTilesAtZoom: function (zoom) { 11554 for (var key in this._tiles) { 11555 if (this._tiles[key].coords.z !== zoom) { 11556 continue; 11557 } 11558 this._removeTile(key); 11559 } 11560 }, 11561 11562 _removeAllTiles: function () { 11563 for (var key in this._tiles) { 11564 this._removeTile(key); 11565 } 11566 }, 11567 11568 _invalidateAll: function () { 11569 for (var z in this._levels) { 11570 remove(this._levels[z].el); 11571 this._onRemoveLevel(z); 11572 delete this._levels[z]; 11573 } 11574 this._removeAllTiles(); 11575 11576 this._tileZoom = undefined; 11577 }, 11578 11579 _retainParent: function (x, y, z, minZoom) { 11580 var x2 = Math.floor(x / 2), 11581 y2 = Math.floor(y / 2), 11582 z2 = z - 1, 11583 coords2 = new Point(+x2, +y2); 11584 coords2.z = +z2; 11585 11586 var key = this._tileCoordsToKey(coords2), 11587 tile = this._tiles[key]; 11588 11589 if (tile && tile.active) { 11590 tile.retain = true; 11591 return true; 11592 11593 } else if (tile && tile.loaded) { 11594 tile.retain = true; 11595 } 11596 11597 if (z2 > minZoom) { 11598 return this._retainParent(x2, y2, z2, minZoom); 11599 } 11600 11601 return false; 11602 }, 11603 11604 _retainChildren: function (x, y, z, maxZoom) { 11605 11606 for (var i = 2 * x; i < 2 * x + 2; i++) { 11607 for (var j = 2 * y; j < 2 * y + 2; j++) { 11608 11609 var coords = new Point(i, j); 11610 coords.z = z + 1; 11611 11612 var key = this._tileCoordsToKey(coords), 11613 tile = this._tiles[key]; 11614 11615 if (tile && tile.active) { 11616 tile.retain = true; 11617 continue; 11618 11619 } else if (tile && tile.loaded) { 11620 tile.retain = true; 11621 } 11622 11623 if (z + 1 < maxZoom) { 11624 this._retainChildren(i, j, z + 1, maxZoom); 11625 } 11626 } 11627 } 11628 }, 11629 11630 _resetView: function (e) { 11631 var animating = e && (e.pinch || e.flyTo); 11632 this._setView(this._map.getCenter(), this._map.getZoom(), animating, animating); 11633 }, 11634 11635 _animateZoom: function (e) { 11636 this._setView(e.center, e.zoom, true, e.noUpdate); 11637 }, 11638 11639 _clampZoom: function (zoom) { 11640 var options = this.options; 11641 11642 if (undefined !== options.minNativeZoom && zoom < options.minNativeZoom) { 11643 return options.minNativeZoom; 11644 } 11645 11646 if (undefined !== options.maxNativeZoom && options.maxNativeZoom < zoom) { 11647 return options.maxNativeZoom; 11648 } 11649 11650 return zoom; 11651 }, 11652 11653 _setView: function (center, zoom, noPrune, noUpdate) { 11654 var tileZoom = this._clampZoom(Math.round(zoom)); 11655 if ((this.options.maxZoom !== undefined && tileZoom > this.options.maxZoom) || 11656 (this.options.minZoom !== undefined && tileZoom < this.options.minZoom)) { 11657 tileZoom = undefined; 11658 } 11659 11660 var tileZoomChanged = this.options.updateWhenZooming && (tileZoom !== this._tileZoom); 11661 11662 if (!noUpdate || tileZoomChanged) { 11663 11664 this._tileZoom = tileZoom; 11665 11666 if (this._abortLoading) { 11667 this._abortLoading(); 11668 } 11669 11670 this._updateLevels(); 11671 this._resetGrid(); 11672 11673 if (tileZoom !== undefined) { 11674 this._update(center); 11675 } 11676 11677 if (!noPrune) { 11678 this._pruneTiles(); 11679 } 11680 11681 // Flag to prevent _updateOpacity from pruning tiles during 11682 // a zoom anim or a pinch gesture 11683 this._noPrune = !!noPrune; 11684 } 11685 11686 this._setZoomTransforms(center, zoom); 11687 }, 11688 11689 _setZoomTransforms: function (center, zoom) { 11690 for (var i in this._levels) { 11691 this._setZoomTransform(this._levels[i], center, zoom); 11692 } 11693 }, 11694 11695 _setZoomTransform: function (level, center, zoom) { 11696 var scale = this._map.getZoomScale(zoom, level.zoom), 11697 translate = level.origin.multiplyBy(scale) 11698 .subtract(this._map._getNewPixelOrigin(center, zoom)).round(); 11699 11700 if (any3d) { 11701 setTransform(level.el, translate, scale); 11702 } else { 11703 setPosition(level.el, translate); 11704 } 11705 }, 11706 11707 _resetGrid: function () { 11708 var map = this._map, 11709 crs = map.options.crs, 11710 tileSize = this._tileSize = this.getTileSize(), 11711 tileZoom = this._tileZoom; 11712 11713 var bounds = this._map.getPixelWorldBounds(this._tileZoom); 11714 if (bounds) { 11715 this._globalTileRange = this._pxBoundsToTileRange(bounds); 11716 } 11717 11718 this._wrapX = crs.wrapLng && !this.options.noWrap && [ 11719 Math.floor(map.project([0, crs.wrapLng[0]], tileZoom).x / tileSize.x), 11720 Math.ceil(map.project([0, crs.wrapLng[1]], tileZoom).x / tileSize.y) 11721 ]; 11722 this._wrapY = crs.wrapLat && !this.options.noWrap && [ 11723 Math.floor(map.project([crs.wrapLat[0], 0], tileZoom).y / tileSize.x), 11724 Math.ceil(map.project([crs.wrapLat[1], 0], tileZoom).y / tileSize.y) 11725 ]; 11726 }, 11727 11728 _onMoveEnd: function () { 11729 if (!this._map || this._map._animatingZoom) { return; } 11730 11731 this._update(); 11732 }, 11733 11734 _getTiledPixelBounds: function (center) { 11735 var map = this._map, 11736 mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(), 11737 scale = map.getZoomScale(mapZoom, this._tileZoom), 11738 pixelCenter = map.project(center, this._tileZoom).floor(), 11739 halfSize = map.getSize().divideBy(scale * 2); 11740 11741 return new Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize)); 11742 }, 11743 11744 // Private method to load tiles in the grid's active zoom level according to map bounds 11745 _update: function (center) { 11746 var map = this._map; 11747 if (!map) { return; } 11748 var zoom = this._clampZoom(map.getZoom()); 11749 11750 if (center === undefined) { center = map.getCenter(); } 11751 if (this._tileZoom === undefined) { return; } // if out of minzoom/maxzoom 11752 11753 var pixelBounds = this._getTiledPixelBounds(center), 11754 tileRange = this._pxBoundsToTileRange(pixelBounds), 11755 tileCenter = tileRange.getCenter(), 11756 queue = [], 11757 margin = this.options.keepBuffer, 11758 noPruneRange = new Bounds(tileRange.getBottomLeft().subtract([margin, -margin]), 11759 tileRange.getTopRight().add([margin, -margin])); 11760 11761 // Sanity check: panic if the tile range contains Infinity somewhere. 11762 if (!(isFinite(tileRange.min.x) && 11763 isFinite(tileRange.min.y) && 11764 isFinite(tileRange.max.x) && 11765 isFinite(tileRange.max.y))) { throw new Error('Attempted to load an infinite number of tiles'); } 11766 11767 for (var key in this._tiles) { 11768 var c = this._tiles[key].coords; 11769 if (c.z !== this._tileZoom || !noPruneRange.contains(new Point(c.x, c.y))) { 11770 this._tiles[key].current = false; 11771 } 11772 } 11773 11774 // _update just loads more tiles. If the tile zoom level differs too much 11775 // from the map's, let _setView reset levels and prune old tiles. 11776 if (Math.abs(zoom - this._tileZoom) > 1) { this._setView(center, zoom); return; } 11777 11778 // create a queue of coordinates to load tiles from 11779 for (var j = tileRange.min.y; j <= tileRange.max.y; j++) { 11780 for (var i = tileRange.min.x; i <= tileRange.max.x; i++) { 11781 var coords = new Point(i, j); 11782 coords.z = this._tileZoom; 11783 11784 if (!this._isValidTile(coords)) { continue; } 11785 11786 var tile = this._tiles[this._tileCoordsToKey(coords)]; 11787 if (tile) { 11788 tile.current = true; 11789 } else { 11790 queue.push(coords); 11791 } 11792 } 11793 } 11794 11795 // sort tile queue to load tiles in order of their distance to center 11796 queue.sort(function (a, b) { 11797 return a.distanceTo(tileCenter) - b.distanceTo(tileCenter); 11798 }); 11799 11800 if (queue.length !== 0) { 11801 // if it's the first batch of tiles to load 11802 if (!this._loading) { 11803 this._loading = true; 11804 // @event loading: Event 11805 // Fired when the grid layer starts loading tiles. 11806 this.fire('loading'); 11807 } 11808 11809 // create DOM fragment to append tiles in one batch 11810 var fragment = document.createDocumentFragment(); 11811 11812 for (i = 0; i < queue.length; i++) { 11813 this._addTile(queue[i], fragment); 11814 } 11815 11816 this._level.el.appendChild(fragment); 11817 } 11818 }, 11819 11820 _isValidTile: function (coords) { 11821 var crs = this._map.options.crs; 11822 11823 if (!crs.infinite) { 11824 // don't load tile if it's out of bounds and not wrapped 11825 var bounds = this._globalTileRange; 11826 if ((!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x)) || 11827 (!crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y))) { return false; } 11828 } 11829 11830 if (!this.options.bounds) { return true; } 11831 11832 // don't load tile if it doesn't intersect the bounds in options 11833 var tileBounds = this._tileCoordsToBounds(coords); 11834 return toLatLngBounds(this.options.bounds).overlaps(tileBounds); 11835 }, 11836 11837 _keyToBounds: function (key) { 11838 return this._tileCoordsToBounds(this._keyToTileCoords(key)); 11839 }, 11840 11841 _tileCoordsToNwSe: function (coords) { 11842 var map = this._map, 11843 tileSize = this.getTileSize(), 11844 nwPoint = coords.scaleBy(tileSize), 11845 sePoint = nwPoint.add(tileSize), 11846 nw = map.unproject(nwPoint, coords.z), 11847 se = map.unproject(sePoint, coords.z); 11848 return [nw, se]; 11849 }, 11850 11851 // converts tile coordinates to its geographical bounds 11852 _tileCoordsToBounds: function (coords) { 11853 var bp = this._tileCoordsToNwSe(coords), 11854 bounds = new LatLngBounds(bp[0], bp[1]); 11855 11856 if (!this.options.noWrap) { 11857 bounds = this._map.wrapLatLngBounds(bounds); 11858 } 11859 return bounds; 11860 }, 11861 // converts tile coordinates to key for the tile cache 11862 _tileCoordsToKey: function (coords) { 11863 return coords.x + ':' + coords.y + ':' + coords.z; 11864 }, 11865 11866 // converts tile cache key to coordinates 11867 _keyToTileCoords: function (key) { 11868 var k = key.split(':'), 11869 coords = new Point(+k[0], +k[1]); 11870 coords.z = +k[2]; 11871 return coords; 11872 }, 11873 11874 _removeTile: function (key) { 11875 var tile = this._tiles[key]; 11876 if (!tile) { return; } 11877 11878 remove(tile.el); 11879 11880 delete this._tiles[key]; 11881 11882 // @event tileunload: TileEvent 11883 // Fired when a tile is removed (e.g. when a tile goes off the screen). 11884 this.fire('tileunload', { 11885 tile: tile.el, 11886 coords: this._keyToTileCoords(key) 11887 }); 11888 }, 11889 11890 _initTile: function (tile) { 11891 addClass(tile, 'leaflet-tile'); 11892 11893 var tileSize = this.getTileSize(); 11894 tile.style.width = tileSize.x + 'px'; 11895 tile.style.height = tileSize.y + 'px'; 11896 11897 tile.onselectstart = falseFn; 11898 tile.onmousemove = falseFn; 11899 11900 // update opacity on tiles in IE7-8 because of filter inheritance problems 11901 if (ielt9 && this.options.opacity < 1) { 11902 setOpacity(tile, this.options.opacity); 11903 } 11904 11905 // without this hack, tiles disappear after zoom on Chrome for Android 11906 // https://github.com/Leaflet/Leaflet/issues/2078 11907 if (android && !android23) { 11908 tile.style.WebkitBackfaceVisibility = 'hidden'; 11909 } 11910 }, 11911 11912 _addTile: function (coords, container) { 11913 var tilePos = this._getTilePos(coords), 11914 key = this._tileCoordsToKey(coords); 11915 11916 var tile = this.createTile(this._wrapCoords(coords), bind(this._tileReady, this, coords)); 11917 11918 this._initTile(tile); 11919 11920 // if createTile is defined with a second argument ("done" callback), 11921 // we know that tile is async and will be ready later; otherwise 11922 if (this.createTile.length < 2) { 11923 // mark tile as ready, but delay one frame for opacity animation to happen 11924 requestAnimFrame(bind(this._tileReady, this, coords, null, tile)); 11925 } 11926 11927 setPosition(tile, tilePos); 11928 11929 // save tile in cache 11930 this._tiles[key] = { 11931 el: tile, 11932 coords: coords, 11933 current: true 11934 }; 11935 11936 container.appendChild(tile); 11937 // @event tileloadstart: TileEvent 11938 // Fired when a tile is requested and starts loading. 11939 this.fire('tileloadstart', { 11940 tile: tile, 11941 coords: coords 11942 }); 11943 }, 11944 11945 _tileReady: function (coords, err, tile) { 11946 if (err) { 11947 // @event tileerror: TileErrorEvent 11948 // Fired when there is an error loading a tile. 11949 this.fire('tileerror', { 11950 error: err, 11951 tile: tile, 11952 coords: coords 11953 }); 11954 } 11955 11956 var key = this._tileCoordsToKey(coords); 11957 11958 tile = this._tiles[key]; 11959 if (!tile) { return; } 11960 11961 tile.loaded = +new Date(); 11962 if (this._map._fadeAnimated) { 11963 setOpacity(tile.el, 0); 11964 cancelAnimFrame(this._fadeFrame); 11965 this._fadeFrame = requestAnimFrame(this._updateOpacity, this); 11966 } else { 11967 tile.active = true; 11968 this._pruneTiles(); 11969 } 11970 11971 if (!err) { 11972 addClass(tile.el, 'leaflet-tile-loaded'); 11973 11974 // @event tileload: TileEvent 11975 // Fired when a tile loads. 11976 this.fire('tileload', { 11977 tile: tile.el, 11978 coords: coords 11979 }); 11980 } 11981 11982 if (this._noTilesToLoad()) { 11983 this._loading = false; 11984 // @event load: Event 11985 // Fired when the grid layer loaded all visible tiles. 11986 this.fire('load'); 11987 11988 if (ielt9 || !this._map._fadeAnimated) { 11989 requestAnimFrame(this._pruneTiles, this); 11990 } else { 11991 // Wait a bit more than 0.2 secs (the duration of the tile fade-in) 11992 // to trigger a pruning. 11993 setTimeout(bind(this._pruneTiles, this), 250); 11994 } 11995 } 11996 }, 11997 11998 _getTilePos: function (coords) { 11999 return coords.scaleBy(this.getTileSize()).subtract(this._level.origin); 12000 }, 12001 12002 _wrapCoords: function (coords) { 12003 var newCoords = new Point( 12004 this._wrapX ? wrapNum(coords.x, this._wrapX) : coords.x, 12005 this._wrapY ? wrapNum(coords.y, this._wrapY) : coords.y); 12006 newCoords.z = coords.z; 12007 return newCoords; 12008 }, 12009 12010 _pxBoundsToTileRange: function (bounds) { 12011 var tileSize = this.getTileSize(); 12012 return new Bounds( 12013 bounds.min.unscaleBy(tileSize).floor(), 12014 bounds.max.unscaleBy(tileSize).ceil().subtract([1, 1])); 12015 }, 12016 12017 _noTilesToLoad: function () { 12018 for (var key in this._tiles) { 12019 if (!this._tiles[key].loaded) { return false; } 12020 } 12021 return true; 12022 } 12023}); 12024 12025// @factory L.gridLayer(options?: GridLayer options) 12026// Creates a new instance of GridLayer with the supplied options. 12027function gridLayer(options) { 12028 return new GridLayer(options); 12029} 12030 12031/* 12032 * @class TileLayer 12033 * @inherits GridLayer 12034 * @aka L.TileLayer 12035 * 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`. 12036 * 12037 * @example 12038 * 12039 * ```js 12040 * 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); 12041 * ``` 12042 * 12043 * @section URL template 12044 * @example 12045 * 12046 * A string of the following form: 12047 * 12048 * ``` 12049 * 'http://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png' 12050 * ``` 12051 * 12052 * `{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. 12053 * 12054 * You can use custom keys in the template, which will be [evaluated](#util-template) from TileLayer options, like this: 12055 * 12056 * ``` 12057 * L.tileLayer('http://{s}.somedomain.com/{foo}/{z}/{x}/{y}.png', {foo: 'bar'}); 12058 * ``` 12059 */ 12060 12061 12062var TileLayer = GridLayer.extend({ 12063 12064 // @section 12065 // @aka TileLayer options 12066 options: { 12067 // @option minZoom: Number = 0 12068 // The minimum zoom level down to which this layer will be displayed (inclusive). 12069 minZoom: 0, 12070 12071 // @option maxZoom: Number = 18 12072 // The maximum zoom level up to which this layer will be displayed (inclusive). 12073 maxZoom: 18, 12074 12075 // @option subdomains: String|String[] = 'abc' 12076 // 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. 12077 subdomains: 'abc', 12078 12079 // @option errorTileUrl: String = '' 12080 // URL to the tile image to show in place of the tile that failed to load. 12081 errorTileUrl: '', 12082 12083 // @option zoomOffset: Number = 0 12084 // The zoom number used in tile URLs will be offset with this value. 12085 zoomOffset: 0, 12086 12087 // @option tms: Boolean = false 12088 // If `true`, inverses Y axis numbering for tiles (turn this on for [TMS](https://en.wikipedia.org/wiki/Tile_Map_Service) services). 12089 tms: false, 12090 12091 // @option zoomReverse: Boolean = false 12092 // If set to true, the zoom number used in tile URLs will be reversed (`maxZoom - zoom` instead of `zoom`) 12093 zoomReverse: false, 12094 12095 // @option detectRetina: Boolean = false 12096 // 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. 12097 detectRetina: false, 12098 12099 // @option crossOrigin: Boolean|String = false 12100 // Whether the crossOrigin attribute will be added to the tiles. 12101 // 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. 12102 // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values. 12103 crossOrigin: false 12104 }, 12105 12106 initialize: function (url, options) { 12107 12108 this._url = url; 12109 12110 options = setOptions(this, options); 12111 12112 // detecting retina displays, adjusting tileSize and zoom levels 12113 if (options.detectRetina && retina && options.maxZoom > 0) { 12114 12115 options.tileSize = Math.floor(options.tileSize / 2); 12116 12117 if (!options.zoomReverse) { 12118 options.zoomOffset++; 12119 options.maxZoom--; 12120 } else { 12121 options.zoomOffset--; 12122 options.minZoom++; 12123 } 12124 12125 options.minZoom = Math.max(0, options.minZoom); 12126 } 12127 12128 if (typeof options.subdomains === 'string') { 12129 options.subdomains = options.subdomains.split(''); 12130 } 12131 12132 // for https://github.com/Leaflet/Leaflet/issues/137 12133 if (!android) { 12134 this.on('tileunload', this._onTileRemove); 12135 } 12136 }, 12137 12138 // @method setUrl(url: String, noRedraw?: Boolean): this 12139 // Updates the layer's URL template and redraws it (unless `noRedraw` is set to `true`). 12140 // If the URL does not change, the layer will not be redrawn unless 12141 // the noRedraw parameter is set to false. 12142 setUrl: function (url, noRedraw) { 12143 if (this._url === url && noRedraw === undefined) { 12144 noRedraw = true; 12145 } 12146 12147 this._url = url; 12148 12149 if (!noRedraw) { 12150 this.redraw(); 12151 } 12152 return this; 12153 }, 12154 12155 // @method createTile(coords: Object, done?: Function): HTMLElement 12156 // Called only internally, overrides GridLayer's [`createTile()`](#gridlayer-createtile) 12157 // to return an `<img>` HTML element with the appropriate image URL given `coords`. The `done` 12158 // callback is called when the tile has been loaded. 12159 createTile: function (coords, done) { 12160 var tile = document.createElement('img'); 12161 12162 on(tile, 'load', bind(this._tileOnLoad, this, done, tile)); 12163 on(tile, 'error', bind(this._tileOnError, this, done, tile)); 12164 12165 if (this.options.crossOrigin || this.options.crossOrigin === '') { 12166 tile.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin; 12167 } 12168 12169 /* 12170 Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons 12171 http://www.w3.org/TR/WCAG20-TECHS/H67 12172 */ 12173 tile.alt = ''; 12174 12175 /* 12176 Set role="presentation" to force screen readers to ignore this 12177 https://www.w3.org/TR/wai-aria/roles#textalternativecomputation 12178 */ 12179 tile.setAttribute('role', 'presentation'); 12180 12181 tile.src = this.getTileUrl(coords); 12182 12183 return tile; 12184 }, 12185 12186 // @section Extension methods 12187 // @uninheritable 12188 // Layers extending `TileLayer` might reimplement the following method. 12189 // @method getTileUrl(coords: Object): String 12190 // Called only internally, returns the URL for a tile given its coordinates. 12191 // Classes extending `TileLayer` can override this function to provide custom tile URL naming schemes. 12192 getTileUrl: function (coords) { 12193 var data = { 12194 r: retina ? '@2x' : '', 12195 s: this._getSubdomain(coords), 12196 x: coords.x, 12197 y: coords.y, 12198 z: this._getZoomForUrl() 12199 }; 12200 if (this._map && !this._map.options.crs.infinite) { 12201 var invertedY = this._globalTileRange.max.y - coords.y; 12202 if (this.options.tms) { 12203 data['y'] = invertedY; 12204 } 12205 data['-y'] = invertedY; 12206 } 12207 12208 return template(this._url, extend(data, this.options)); 12209 }, 12210 12211 _tileOnLoad: function (done, tile) { 12212 // For https://github.com/Leaflet/Leaflet/issues/3332 12213 if (ielt9) { 12214 setTimeout(bind(done, this, null, tile), 0); 12215 } else { 12216 done(null, tile); 12217 } 12218 }, 12219 12220 _tileOnError: function (done, tile, e) { 12221 var errorUrl = this.options.errorTileUrl; 12222 if (errorUrl && tile.getAttribute('src') !== errorUrl) { 12223 tile.src = errorUrl; 12224 } 12225 done(e, tile); 12226 }, 12227 12228 _onTileRemove: function (e) { 12229 e.tile.onload = null; 12230 }, 12231 12232 _getZoomForUrl: function () { 12233 var zoom = this._tileZoom, 12234 maxZoom = this.options.maxZoom, 12235 zoomReverse = this.options.zoomReverse, 12236 zoomOffset = this.options.zoomOffset; 12237 12238 if (zoomReverse) { 12239 zoom = maxZoom - zoom; 12240 } 12241 12242 return zoom + zoomOffset; 12243 }, 12244 12245 _getSubdomain: function (tilePoint) { 12246 var index = Math.abs(tilePoint.x + tilePoint.y) % this.options.subdomains.length; 12247 return this.options.subdomains[index]; 12248 }, 12249 12250 // stops loading all tiles in the background layer 12251 _abortLoading: function () { 12252 var i, tile; 12253 for (i in this._tiles) { 12254 if (this._tiles[i].coords.z !== this._tileZoom) { 12255 tile = this._tiles[i].el; 12256 12257 tile.onload = falseFn; 12258 tile.onerror = falseFn; 12259 12260 if (!tile.complete) { 12261 tile.src = emptyImageUrl; 12262 remove(tile); 12263 delete this._tiles[i]; 12264 } 12265 } 12266 } 12267 }, 12268 12269 _removeTile: function (key) { 12270 var tile = this._tiles[key]; 12271 if (!tile) { return; } 12272 12273 // Cancels any pending http requests associated with the tile 12274 // unless we're on Android's stock browser, 12275 // see https://github.com/Leaflet/Leaflet/issues/137 12276 if (!androidStock) { 12277 tile.el.setAttribute('src', emptyImageUrl); 12278 } 12279 12280 return GridLayer.prototype._removeTile.call(this, key); 12281 }, 12282 12283 _tileReady: function (coords, err, tile) { 12284 if (!this._map || (tile && tile.getAttribute('src') === emptyImageUrl)) { 12285 return; 12286 } 12287 12288 return GridLayer.prototype._tileReady.call(this, coords, err, tile); 12289 } 12290}); 12291 12292 12293// @factory L.tilelayer(urlTemplate: String, options?: TileLayer options) 12294// Instantiates a tile layer object given a `URL template` and optionally an options object. 12295 12296function tileLayer(url, options) { 12297 return new TileLayer(url, options); 12298} 12299 12300/* 12301 * @class TileLayer.WMS 12302 * @inherits TileLayer 12303 * @aka L.TileLayer.WMS 12304 * Used to display [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services as tile layers on the map. Extends `TileLayer`. 12305 * 12306 * @example 12307 * 12308 * ```js 12309 * var nexrad = L.tileLayer.wms("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", { 12310 * layers: 'nexrad-n0r-900913', 12311 * format: 'image/png', 12312 * transparent: true, 12313 * attribution: "Weather data © 2012 IEM Nexrad" 12314 * }); 12315 * ``` 12316 */ 12317 12318var TileLayerWMS = TileLayer.extend({ 12319 12320 // @section 12321 // @aka TileLayer.WMS options 12322 // If any custom options not documented here are used, they will be sent to the 12323 // WMS server as extra parameters in each request URL. This can be useful for 12324 // [non-standard vendor WMS parameters](http://docs.geoserver.org/stable/en/user/services/wms/vendor.html). 12325 defaultWmsParams: { 12326 service: 'WMS', 12327 request: 'GetMap', 12328 12329 // @option layers: String = '' 12330 // **(required)** Comma-separated list of WMS layers to show. 12331 layers: '', 12332 12333 // @option styles: String = '' 12334 // Comma-separated list of WMS styles. 12335 styles: '', 12336 12337 // @option format: String = 'image/jpeg' 12338 // WMS image format (use `'image/png'` for layers with transparency). 12339 format: 'image/jpeg', 12340 12341 // @option transparent: Boolean = false 12342 // If `true`, the WMS service will return images with transparency. 12343 transparent: false, 12344 12345 // @option version: String = '1.1.1' 12346 // Version of the WMS service to use 12347 version: '1.1.1' 12348 }, 12349 12350 options: { 12351 // @option crs: CRS = null 12352 // Coordinate Reference System to use for the WMS requests, defaults to 12353 // map CRS. Don't change this if you're not sure what it means. 12354 crs: null, 12355 12356 // @option uppercase: Boolean = false 12357 // If `true`, WMS request parameter keys will be uppercase. 12358 uppercase: false 12359 }, 12360 12361 initialize: function (url, options) { 12362 12363 this._url = url; 12364 12365 var wmsParams = extend({}, this.defaultWmsParams); 12366 12367 // all keys that are not TileLayer options go to WMS params 12368 for (var i in options) { 12369 if (!(i in this.options)) { 12370 wmsParams[i] = options[i]; 12371 } 12372 } 12373 12374 options = setOptions(this, options); 12375 12376 var realRetina = options.detectRetina && retina ? 2 : 1; 12377 var tileSize = this.getTileSize(); 12378 wmsParams.width = tileSize.x * realRetina; 12379 wmsParams.height = tileSize.y * realRetina; 12380 12381 this.wmsParams = wmsParams; 12382 }, 12383 12384 onAdd: function (map) { 12385 12386 this._crs = this.options.crs || map.options.crs; 12387 this._wmsVersion = parseFloat(this.wmsParams.version); 12388 12389 var projectionKey = this._wmsVersion >= 1.3 ? 'crs' : 'srs'; 12390 this.wmsParams[projectionKey] = this._crs.code; 12391 12392 TileLayer.prototype.onAdd.call(this, map); 12393 }, 12394 12395 getTileUrl: function (coords) { 12396 12397 var tileBounds = this._tileCoordsToNwSe(coords), 12398 crs = this._crs, 12399 bounds = toBounds(crs.project(tileBounds[0]), crs.project(tileBounds[1])), 12400 min = bounds.min, 12401 max = bounds.max, 12402 bbox = (this._wmsVersion >= 1.3 && this._crs === EPSG4326 ? 12403 [min.y, min.x, max.y, max.x] : 12404 [min.x, min.y, max.x, max.y]).join(','), 12405 url = TileLayer.prototype.getTileUrl.call(this, coords); 12406 return url + 12407 getParamString(this.wmsParams, url, this.options.uppercase) + 12408 (this.options.uppercase ? '&BBOX=' : '&bbox=') + bbox; 12409 }, 12410 12411 // @method setParams(params: Object, noRedraw?: Boolean): this 12412 // Merges an object with the new parameters and re-requests tiles on the current screen (unless `noRedraw` was set to true). 12413 setParams: function (params, noRedraw) { 12414 12415 extend(this.wmsParams, params); 12416 12417 if (!noRedraw) { 12418 this.redraw(); 12419 } 12420 12421 return this; 12422 } 12423}); 12424 12425 12426// @factory L.tileLayer.wms(baseUrl: String, options: TileLayer.WMS options) 12427// Instantiates a WMS tile layer object given a base URL of the WMS service and a WMS parameters/options object. 12428function tileLayerWMS(url, options) { 12429 return new TileLayerWMS(url, options); 12430} 12431 12432TileLayer.WMS = TileLayerWMS; 12433tileLayer.wms = tileLayerWMS; 12434 12435/* 12436 * @class Renderer 12437 * @inherits Layer 12438 * @aka L.Renderer 12439 * 12440 * Base class for vector renderer implementations (`SVG`, `Canvas`). Handles the 12441 * DOM container of the renderer, its bounds, and its zoom animation. 12442 * 12443 * A `Renderer` works as an implicit layer group for all `Path`s - the renderer 12444 * itself can be added or removed to the map. All paths use a renderer, which can 12445 * be implicit (the map will decide the type of renderer and use it automatically) 12446 * or explicit (using the [`renderer`](#path-renderer) option of the path). 12447 * 12448 * Do not use this class directly, use `SVG` and `Canvas` instead. 12449 * 12450 * @event update: Event 12451 * Fired when the renderer updates its bounds, center and zoom, for example when 12452 * its map has moved 12453 */ 12454 12455var Renderer = Layer.extend({ 12456 12457 // @section 12458 // @aka Renderer options 12459 options: { 12460 // @option padding: Number = 0.1 12461 // How much to extend the clip area around the map view (relative to its size) 12462 // e.g. 0.1 would be 10% of map view in each direction 12463 padding: 0.1, 12464 12465 // @option tolerance: Number = 0 12466 // How much to extend click tolerance round a path/object on the map 12467 tolerance : 0 12468 }, 12469 12470 initialize: function (options) { 12471 setOptions(this, options); 12472 stamp(this); 12473 this._layers = this._layers || {}; 12474 }, 12475 12476 onAdd: function () { 12477 if (!this._container) { 12478 this._initContainer(); // defined by renderer implementations 12479 12480 if (this._zoomAnimated) { 12481 addClass(this._container, 'leaflet-zoom-animated'); 12482 } 12483 } 12484 12485 this.getPane().appendChild(this._container); 12486 this._update(); 12487 this.on('update', this._updatePaths, this); 12488 }, 12489 12490 onRemove: function () { 12491 this.off('update', this._updatePaths, this); 12492 this._destroyContainer(); 12493 }, 12494 12495 getEvents: function () { 12496 var events = { 12497 viewreset: this._reset, 12498 zoom: this._onZoom, 12499 moveend: this._update, 12500 zoomend: this._onZoomEnd 12501 }; 12502 if (this._zoomAnimated) { 12503 events.zoomanim = this._onAnimZoom; 12504 } 12505 return events; 12506 }, 12507 12508 _onAnimZoom: function (ev) { 12509 this._updateTransform(ev.center, ev.zoom); 12510 }, 12511 12512 _onZoom: function () { 12513 this._updateTransform(this._map.getCenter(), this._map.getZoom()); 12514 }, 12515 12516 _updateTransform: function (center, zoom) { 12517 var scale = this._map.getZoomScale(zoom, this._zoom), 12518 position = getPosition(this._container), 12519 viewHalf = this._map.getSize().multiplyBy(0.5 + this.options.padding), 12520 currentCenterPoint = this._map.project(this._center, zoom), 12521 destCenterPoint = this._map.project(center, zoom), 12522 centerOffset = destCenterPoint.subtract(currentCenterPoint), 12523 12524 topLeftOffset = viewHalf.multiplyBy(-scale).add(position).add(viewHalf).subtract(centerOffset); 12525 12526 if (any3d) { 12527 setTransform(this._container, topLeftOffset, scale); 12528 } else { 12529 setPosition(this._container, topLeftOffset); 12530 } 12531 }, 12532 12533 _reset: function () { 12534 this._update(); 12535 this._updateTransform(this._center, this._zoom); 12536 12537 for (var id in this._layers) { 12538 this._layers[id]._reset(); 12539 } 12540 }, 12541 12542 _onZoomEnd: function () { 12543 for (var id in this._layers) { 12544 this._layers[id]._project(); 12545 } 12546 }, 12547 12548 _updatePaths: function () { 12549 for (var id in this._layers) { 12550 this._layers[id]._update(); 12551 } 12552 }, 12553 12554 _update: function () { 12555 // Update pixel bounds of renderer container (for positioning/sizing/clipping later) 12556 // Subclasses are responsible of firing the 'update' event. 12557 var p = this.options.padding, 12558 size = this._map.getSize(), 12559 min = this._map.containerPointToLayerPoint(size.multiplyBy(-p)).round(); 12560 12561 this._bounds = new Bounds(min, min.add(size.multiplyBy(1 + p * 2)).round()); 12562 12563 this._center = this._map.getCenter(); 12564 this._zoom = this._map.getZoom(); 12565 } 12566}); 12567 12568/* 12569 * @class Canvas 12570 * @inherits Renderer 12571 * @aka L.Canvas 12572 * 12573 * Allows vector layers to be displayed with [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API). 12574 * Inherits `Renderer`. 12575 * 12576 * Due to [technical limitations](http://caniuse.com/#search=canvas), Canvas is not 12577 * available in all web browsers, notably IE8, and overlapping geometries might 12578 * not display properly in some edge cases. 12579 * 12580 * @example 12581 * 12582 * Use Canvas by default for all paths in the map: 12583 * 12584 * ```js 12585 * var map = L.map('map', { 12586 * renderer: L.canvas() 12587 * }); 12588 * ``` 12589 * 12590 * Use a Canvas renderer with extra padding for specific vector geometries: 12591 * 12592 * ```js 12593 * var map = L.map('map'); 12594 * var myRenderer = L.canvas({ padding: 0.5 }); 12595 * var line = L.polyline( coordinates, { renderer: myRenderer } ); 12596 * var circle = L.circle( center, { renderer: myRenderer } ); 12597 * ``` 12598 */ 12599 12600var Canvas = Renderer.extend({ 12601 getEvents: function () { 12602 var events = Renderer.prototype.getEvents.call(this); 12603 events.viewprereset = this._onViewPreReset; 12604 return events; 12605 }, 12606 12607 _onViewPreReset: function () { 12608 // Set a flag so that a viewprereset+moveend+viewreset only updates&redraws once 12609 this._postponeUpdatePaths = true; 12610 }, 12611 12612 onAdd: function () { 12613 Renderer.prototype.onAdd.call(this); 12614 12615 // Redraw vectors since canvas is cleared upon removal, 12616 // in case of removing the renderer itself from the map. 12617 this._draw(); 12618 }, 12619 12620 _initContainer: function () { 12621 var container = this._container = document.createElement('canvas'); 12622 12623 on(container, 'mousemove', throttle(this._onMouseMove, 32, this), this); 12624 on(container, 'click dblclick mousedown mouseup contextmenu', this._onClick, this); 12625 on(container, 'mouseout', this._handleMouseOut, this); 12626 12627 this._ctx = container.getContext('2d'); 12628 }, 12629 12630 _destroyContainer: function () { 12631 cancelAnimFrame(this._redrawRequest); 12632 delete this._ctx; 12633 remove(this._container); 12634 off(this._container); 12635 delete this._container; 12636 }, 12637 12638 _updatePaths: function () { 12639 if (this._postponeUpdatePaths) { return; } 12640 12641 var layer; 12642 this._redrawBounds = null; 12643 for (var id in this._layers) { 12644 layer = this._layers[id]; 12645 layer._update(); 12646 } 12647 this._redraw(); 12648 }, 12649 12650 _update: function () { 12651 if (this._map._animatingZoom && this._bounds) { return; } 12652 12653 Renderer.prototype._update.call(this); 12654 12655 var b = this._bounds, 12656 container = this._container, 12657 size = b.getSize(), 12658 m = retina ? 2 : 1; 12659 12660 setPosition(container, b.min); 12661 12662 // set canvas size (also clearing it); use double size on retina 12663 container.width = m * size.x; 12664 container.height = m * size.y; 12665 container.style.width = size.x + 'px'; 12666 container.style.height = size.y + 'px'; 12667 12668 if (retina) { 12669 this._ctx.scale(2, 2); 12670 } 12671 12672 // translate so we use the same path coordinates after canvas element moves 12673 this._ctx.translate(-b.min.x, -b.min.y); 12674 12675 // Tell paths to redraw themselves 12676 this.fire('update'); 12677 }, 12678 12679 _reset: function () { 12680 Renderer.prototype._reset.call(this); 12681 12682 if (this._postponeUpdatePaths) { 12683 this._postponeUpdatePaths = false; 12684 this._updatePaths(); 12685 } 12686 }, 12687 12688 _initPath: function (layer) { 12689 this._updateDashArray(layer); 12690 this._layers[stamp(layer)] = layer; 12691 12692 var order = layer._order = { 12693 layer: layer, 12694 prev: this._drawLast, 12695 next: null 12696 }; 12697 if (this._drawLast) { this._drawLast.next = order; } 12698 this._drawLast = order; 12699 this._drawFirst = this._drawFirst || this._drawLast; 12700 }, 12701 12702 _addPath: function (layer) { 12703 this._requestRedraw(layer); 12704 }, 12705 12706 _removePath: function (layer) { 12707 var order = layer._order; 12708 var next = order.next; 12709 var prev = order.prev; 12710 12711 if (next) { 12712 next.prev = prev; 12713 } else { 12714 this._drawLast = prev; 12715 } 12716 if (prev) { 12717 prev.next = next; 12718 } else { 12719 this._drawFirst = next; 12720 } 12721 12722 delete layer._order; 12723 12724 delete this._layers[stamp(layer)]; 12725 12726 this._requestRedraw(layer); 12727 }, 12728 12729 _updatePath: function (layer) { 12730 // Redraw the union of the layer's old pixel 12731 // bounds and the new pixel bounds. 12732 this._extendRedrawBounds(layer); 12733 layer._project(); 12734 layer._update(); 12735 // The redraw will extend the redraw bounds 12736 // with the new pixel bounds. 12737 this._requestRedraw(layer); 12738 }, 12739 12740 _updateStyle: function (layer) { 12741 this._updateDashArray(layer); 12742 this._requestRedraw(layer); 12743 }, 12744 12745 _updateDashArray: function (layer) { 12746 if (typeof layer.options.dashArray === 'string') { 12747 var parts = layer.options.dashArray.split(/[, ]+/), 12748 dashArray = [], 12749 dashValue, 12750 i; 12751 for (i = 0; i < parts.length; i++) { 12752 dashValue = Number(parts[i]); 12753 // Ignore dash array containing invalid lengths 12754 if (isNaN(dashValue)) { return; } 12755 dashArray.push(dashValue); 12756 } 12757 layer.options._dashArray = dashArray; 12758 } else { 12759 layer.options._dashArray = layer.options.dashArray; 12760 } 12761 }, 12762 12763 _requestRedraw: function (layer) { 12764 if (!this._map) { return; } 12765 12766 this._extendRedrawBounds(layer); 12767 this._redrawRequest = this._redrawRequest || requestAnimFrame(this._redraw, this); 12768 }, 12769 12770 _extendRedrawBounds: function (layer) { 12771 if (layer._pxBounds) { 12772 var padding = (layer.options.weight || 0) + 1; 12773 this._redrawBounds = this._redrawBounds || new Bounds(); 12774 this._redrawBounds.extend(layer._pxBounds.min.subtract([padding, padding])); 12775 this._redrawBounds.extend(layer._pxBounds.max.add([padding, padding])); 12776 } 12777 }, 12778 12779 _redraw: function () { 12780 this._redrawRequest = null; 12781 12782 if (this._redrawBounds) { 12783 this._redrawBounds.min._floor(); 12784 this._redrawBounds.max._ceil(); 12785 } 12786 12787 this._clear(); // clear layers in redraw bounds 12788 this._draw(); // draw layers 12789 12790 this._redrawBounds = null; 12791 }, 12792 12793 _clear: function () { 12794 var bounds = this._redrawBounds; 12795 if (bounds) { 12796 var size = bounds.getSize(); 12797 this._ctx.clearRect(bounds.min.x, bounds.min.y, size.x, size.y); 12798 } else { 12799 this._ctx.clearRect(0, 0, this._container.width, this._container.height); 12800 } 12801 }, 12802 12803 _draw: function () { 12804 var layer, bounds = this._redrawBounds; 12805 this._ctx.save(); 12806 if (bounds) { 12807 var size = bounds.getSize(); 12808 this._ctx.beginPath(); 12809 this._ctx.rect(bounds.min.x, bounds.min.y, size.x, size.y); 12810 this._ctx.clip(); 12811 } 12812 12813 this._drawing = true; 12814 12815 for (var order = this._drawFirst; order; order = order.next) { 12816 layer = order.layer; 12817 if (!bounds || (layer._pxBounds && layer._pxBounds.intersects(bounds))) { 12818 layer._updatePath(); 12819 } 12820 } 12821 12822 this._drawing = false; 12823 12824 this._ctx.restore(); // Restore state before clipping. 12825 }, 12826 12827 _updatePoly: function (layer, closed) { 12828 if (!this._drawing) { return; } 12829 12830 var i, j, len2, p, 12831 parts = layer._parts, 12832 len = parts.length, 12833 ctx = this._ctx; 12834 12835 if (!len) { return; } 12836 12837 ctx.beginPath(); 12838 12839 for (i = 0; i < len; i++) { 12840 for (j = 0, len2 = parts[i].length; j < len2; j++) { 12841 p = parts[i][j]; 12842 ctx[j ? 'lineTo' : 'moveTo'](p.x, p.y); 12843 } 12844 if (closed) { 12845 ctx.closePath(); 12846 } 12847 } 12848 12849 this._fillStroke(ctx, layer); 12850 12851 // TODO optimization: 1 fill/stroke for all features with equal style instead of 1 for each feature 12852 }, 12853 12854 _updateCircle: function (layer) { 12855 12856 if (!this._drawing || layer._empty()) { return; } 12857 12858 var p = layer._point, 12859 ctx = this._ctx, 12860 r = Math.max(Math.round(layer._radius), 1), 12861 s = (Math.max(Math.round(layer._radiusY), 1) || r) / r; 12862 12863 if (s !== 1) { 12864 ctx.save(); 12865 ctx.scale(1, s); 12866 } 12867 12868 ctx.beginPath(); 12869 ctx.arc(p.x, p.y / s, r, 0, Math.PI * 2, false); 12870 12871 if (s !== 1) { 12872 ctx.restore(); 12873 } 12874 12875 this._fillStroke(ctx, layer); 12876 }, 12877 12878 _fillStroke: function (ctx, layer) { 12879 var options = layer.options; 12880 12881 if (options.fill) { 12882 ctx.globalAlpha = options.fillOpacity; 12883 ctx.fillStyle = options.fillColor || options.color; 12884 ctx.fill(options.fillRule || 'evenodd'); 12885 } 12886 12887 if (options.stroke && options.weight !== 0) { 12888 if (ctx.setLineDash) { 12889 ctx.setLineDash(layer.options && layer.options._dashArray || []); 12890 } 12891 ctx.globalAlpha = options.opacity; 12892 ctx.lineWidth = options.weight; 12893 ctx.strokeStyle = options.color; 12894 ctx.lineCap = options.lineCap; 12895 ctx.lineJoin = options.lineJoin; 12896 ctx.stroke(); 12897 } 12898 }, 12899 12900 // Canvas obviously doesn't have mouse events for individual drawn objects, 12901 // so we emulate that by calculating what's under the mouse on mousemove/click manually 12902 12903 _onClick: function (e) { 12904 var point = this._map.mouseEventToLayerPoint(e), layer, clickedLayer; 12905 12906 for (var order = this._drawFirst; order; order = order.next) { 12907 layer = order.layer; 12908 if (layer.options.interactive && layer._containsPoint(point) && !this._map._draggableMoved(layer)) { 12909 clickedLayer = layer; 12910 } 12911 } 12912 if (clickedLayer) { 12913 fakeStop(e); 12914 this._fireEvent([clickedLayer], e); 12915 } 12916 }, 12917 12918 _onMouseMove: function (e) { 12919 if (!this._map || this._map.dragging.moving() || this._map._animatingZoom) { return; } 12920 12921 var point = this._map.mouseEventToLayerPoint(e); 12922 this._handleMouseHover(e, point); 12923 }, 12924 12925 12926 _handleMouseOut: function (e) { 12927 var layer = this._hoveredLayer; 12928 if (layer) { 12929 // if we're leaving the layer, fire mouseout 12930 removeClass(this._container, 'leaflet-interactive'); 12931 this._fireEvent([layer], e, 'mouseout'); 12932 this._hoveredLayer = null; 12933 } 12934 }, 12935 12936 _handleMouseHover: function (e, point) { 12937 var layer, candidateHoveredLayer; 12938 12939 for (var order = this._drawFirst; order; order = order.next) { 12940 layer = order.layer; 12941 if (layer.options.interactive && layer._containsPoint(point)) { 12942 candidateHoveredLayer = layer; 12943 } 12944 } 12945 12946 if (candidateHoveredLayer !== this._hoveredLayer) { 12947 this._handleMouseOut(e); 12948 12949 if (candidateHoveredLayer) { 12950 addClass(this._container, 'leaflet-interactive'); // change cursor 12951 this._fireEvent([candidateHoveredLayer], e, 'mouseover'); 12952 this._hoveredLayer = candidateHoveredLayer; 12953 } 12954 } 12955 12956 if (this._hoveredLayer) { 12957 this._fireEvent([this._hoveredLayer], e); 12958 } 12959 }, 12960 12961 _fireEvent: function (layers, e, type) { 12962 this._map._fireDOMEvent(e, type || e.type, layers); 12963 }, 12964 12965 _bringToFront: function (layer) { 12966 var order = layer._order; 12967 12968 if (!order) { return; } 12969 12970 var next = order.next; 12971 var prev = order.prev; 12972 12973 if (next) { 12974 next.prev = prev; 12975 } else { 12976 // Already last 12977 return; 12978 } 12979 if (prev) { 12980 prev.next = next; 12981 } else if (next) { 12982 // Update first entry unless this is the 12983 // single entry 12984 this._drawFirst = next; 12985 } 12986 12987 order.prev = this._drawLast; 12988 this._drawLast.next = order; 12989 12990 order.next = null; 12991 this._drawLast = order; 12992 12993 this._requestRedraw(layer); 12994 }, 12995 12996 _bringToBack: function (layer) { 12997 var order = layer._order; 12998 12999 if (!order) { return; } 13000 13001 var next = order.next; 13002 var prev = order.prev; 13003 13004 if (prev) { 13005 prev.next = next; 13006 } else { 13007 // Already first 13008 return; 13009 } 13010 if (next) { 13011 next.prev = prev; 13012 } else if (prev) { 13013 // Update last entry unless this is the 13014 // single entry 13015 this._drawLast = prev; 13016 } 13017 13018 order.prev = null; 13019 13020 order.next = this._drawFirst; 13021 this._drawFirst.prev = order; 13022 this._drawFirst = order; 13023 13024 this._requestRedraw(layer); 13025 } 13026}); 13027 13028// @factory L.canvas(options?: Renderer options) 13029// Creates a Canvas renderer with the given options. 13030function canvas$1(options) { 13031 return canvas ? new Canvas(options) : null; 13032} 13033 13034/* 13035 * Thanks to Dmitry Baranovsky and his Raphael library for inspiration! 13036 */ 13037 13038 13039var vmlCreate = (function () { 13040 try { 13041 document.namespaces.add('lvml', 'urn:schemas-microsoft-com:vml'); 13042 return function (name) { 13043 return document.createElement('<lvml:' + name + ' class="lvml">'); 13044 }; 13045 } catch (e) { 13046 return function (name) { 13047 return document.createElement('<' + name + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">'); 13048 }; 13049 } 13050})(); 13051 13052 13053/* 13054 * @class SVG 13055 * 13056 * 13057 * VML was deprecated in 2012, which means VML functionality exists only for backwards compatibility 13058 * with old versions of Internet Explorer. 13059 */ 13060 13061// mixin to redefine some SVG methods to handle VML syntax which is similar but with some differences 13062var vmlMixin = { 13063 13064 _initContainer: function () { 13065 this._container = create$1('div', 'leaflet-vml-container'); 13066 }, 13067 13068 _update: function () { 13069 if (this._map._animatingZoom) { return; } 13070 Renderer.prototype._update.call(this); 13071 this.fire('update'); 13072 }, 13073 13074 _initPath: function (layer) { 13075 var container = layer._container = vmlCreate('shape'); 13076 13077 addClass(container, 'leaflet-vml-shape ' + (this.options.className || '')); 13078 13079 container.coordsize = '1 1'; 13080 13081 layer._path = vmlCreate('path'); 13082 container.appendChild(layer._path); 13083 13084 this._updateStyle(layer); 13085 this._layers[stamp(layer)] = layer; 13086 }, 13087 13088 _addPath: function (layer) { 13089 var container = layer._container; 13090 this._container.appendChild(container); 13091 13092 if (layer.options.interactive) { 13093 layer.addInteractiveTarget(container); 13094 } 13095 }, 13096 13097 _removePath: function (layer) { 13098 var container = layer._container; 13099 remove(container); 13100 layer.removeInteractiveTarget(container); 13101 delete this._layers[stamp(layer)]; 13102 }, 13103 13104 _updateStyle: function (layer) { 13105 var stroke = layer._stroke, 13106 fill = layer._fill, 13107 options = layer.options, 13108 container = layer._container; 13109 13110 container.stroked = !!options.stroke; 13111 container.filled = !!options.fill; 13112 13113 if (options.stroke) { 13114 if (!stroke) { 13115 stroke = layer._stroke = vmlCreate('stroke'); 13116 } 13117 container.appendChild(stroke); 13118 stroke.weight = options.weight + 'px'; 13119 stroke.color = options.color; 13120 stroke.opacity = options.opacity; 13121 13122 if (options.dashArray) { 13123 stroke.dashStyle = isArray(options.dashArray) ? 13124 options.dashArray.join(' ') : 13125 options.dashArray.replace(/( *, *)/g, ' '); 13126 } else { 13127 stroke.dashStyle = ''; 13128 } 13129 stroke.endcap = options.lineCap.replace('butt', 'flat'); 13130 stroke.joinstyle = options.lineJoin; 13131 13132 } else if (stroke) { 13133 container.removeChild(stroke); 13134 layer._stroke = null; 13135 } 13136 13137 if (options.fill) { 13138 if (!fill) { 13139 fill = layer._fill = vmlCreate('fill'); 13140 } 13141 container.appendChild(fill); 13142 fill.color = options.fillColor || options.color; 13143 fill.opacity = options.fillOpacity; 13144 13145 } else if (fill) { 13146 container.removeChild(fill); 13147 layer._fill = null; 13148 } 13149 }, 13150 13151 _updateCircle: function (layer) { 13152 var p = layer._point.round(), 13153 r = Math.round(layer._radius), 13154 r2 = Math.round(layer._radiusY || r); 13155 13156 this._setPath(layer, layer._empty() ? 'M0 0' : 13157 'AL ' + p.x + ',' + p.y + ' ' + r + ',' + r2 + ' 0,' + (65535 * 360)); 13158 }, 13159 13160 _setPath: function (layer, path) { 13161 layer._path.v = path; 13162 }, 13163 13164 _bringToFront: function (layer) { 13165 toFront(layer._container); 13166 }, 13167 13168 _bringToBack: function (layer) { 13169 toBack(layer._container); 13170 } 13171}; 13172 13173var create$2 = vml ? vmlCreate : svgCreate; 13174 13175/* 13176 * @class SVG 13177 * @inherits Renderer 13178 * @aka L.SVG 13179 * 13180 * Allows vector layers to be displayed with [SVG](https://developer.mozilla.org/docs/Web/SVG). 13181 * Inherits `Renderer`. 13182 * 13183 * Due to [technical limitations](http://caniuse.com/#search=svg), SVG is not 13184 * available in all web browsers, notably Android 2.x and 3.x. 13185 * 13186 * Although SVG is not available on IE7 and IE8, these browsers support 13187 * [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language) 13188 * (a now deprecated technology), and the SVG renderer will fall back to VML in 13189 * this case. 13190 * 13191 * @example 13192 * 13193 * Use SVG by default for all paths in the map: 13194 * 13195 * ```js 13196 * var map = L.map('map', { 13197 * renderer: L.svg() 13198 * }); 13199 * ``` 13200 * 13201 * Use a SVG renderer with extra padding for specific vector geometries: 13202 * 13203 * ```js 13204 * var map = L.map('map'); 13205 * var myRenderer = L.svg({ padding: 0.5 }); 13206 * var line = L.polyline( coordinates, { renderer: myRenderer } ); 13207 * var circle = L.circle( center, { renderer: myRenderer } ); 13208 * ``` 13209 */ 13210 13211var SVG = Renderer.extend({ 13212 13213 getEvents: function () { 13214 var events = Renderer.prototype.getEvents.call(this); 13215 events.zoomstart = this._onZoomStart; 13216 return events; 13217 }, 13218 13219 _initContainer: function () { 13220 this._container = create$2('svg'); 13221 13222 // makes it possible to click through svg root; we'll reset it back in individual paths 13223 this._container.setAttribute('pointer-events', 'none'); 13224 13225 this._rootGroup = create$2('g'); 13226 this._container.appendChild(this._rootGroup); 13227 }, 13228 13229 _destroyContainer: function () { 13230 remove(this._container); 13231 off(this._container); 13232 delete this._container; 13233 delete this._rootGroup; 13234 delete this._svgSize; 13235 }, 13236 13237 _onZoomStart: function () { 13238 // Drag-then-pinch interactions might mess up the center and zoom. 13239 // In this case, the easiest way to prevent this is re-do the renderer 13240 // bounds and padding when the zooming starts. 13241 this._update(); 13242 }, 13243 13244 _update: function () { 13245 if (this._map._animatingZoom && this._bounds) { return; } 13246 13247 Renderer.prototype._update.call(this); 13248 13249 var b = this._bounds, 13250 size = b.getSize(), 13251 container = this._container; 13252 13253 // set size of svg-container if changed 13254 if (!this._svgSize || !this._svgSize.equals(size)) { 13255 this._svgSize = size; 13256 container.setAttribute('width', size.x); 13257 container.setAttribute('height', size.y); 13258 } 13259 13260 // movement: update container viewBox so that we don't have to change coordinates of individual layers 13261 setPosition(container, b.min); 13262 container.setAttribute('viewBox', [b.min.x, b.min.y, size.x, size.y].join(' ')); 13263 13264 this.fire('update'); 13265 }, 13266 13267 // methods below are called by vector layers implementations 13268 13269 _initPath: function (layer) { 13270 var path = layer._path = create$2('path'); 13271 13272 // @namespace Path 13273 // @option className: String = null 13274 // Custom class name set on an element. Only for SVG renderer. 13275 if (layer.options.className) { 13276 addClass(path, layer.options.className); 13277 } 13278 13279 if (layer.options.interactive) { 13280 addClass(path, 'leaflet-interactive'); 13281 } 13282 13283 this._updateStyle(layer); 13284 this._layers[stamp(layer)] = layer; 13285 }, 13286 13287 _addPath: function (layer) { 13288 if (!this._rootGroup) { this._initContainer(); } 13289 this._rootGroup.appendChild(layer._path); 13290 layer.addInteractiveTarget(layer._path); 13291 }, 13292 13293 _removePath: function (layer) { 13294 remove(layer._path); 13295 layer.removeInteractiveTarget(layer._path); 13296 delete this._layers[stamp(layer)]; 13297 }, 13298 13299 _updatePath: function (layer) { 13300 layer._project(); 13301 layer._update(); 13302 }, 13303 13304 _updateStyle: function (layer) { 13305 var path = layer._path, 13306 options = layer.options; 13307 13308 if (!path) { return; } 13309 13310 if (options.stroke) { 13311 path.setAttribute('stroke', options.color); 13312 path.setAttribute('stroke-opacity', options.opacity); 13313 path.setAttribute('stroke-width', options.weight); 13314 path.setAttribute('stroke-linecap', options.lineCap); 13315 path.setAttribute('stroke-linejoin', options.lineJoin); 13316 13317 if (options.dashArray) { 13318 path.setAttribute('stroke-dasharray', options.dashArray); 13319 } else { 13320 path.removeAttribute('stroke-dasharray'); 13321 } 13322 13323 if (options.dashOffset) { 13324 path.setAttribute('stroke-dashoffset', options.dashOffset); 13325 } else { 13326 path.removeAttribute('stroke-dashoffset'); 13327 } 13328 } else { 13329 path.setAttribute('stroke', 'none'); 13330 } 13331 13332 if (options.fill) { 13333 path.setAttribute('fill', options.fillColor || options.color); 13334 path.setAttribute('fill-opacity', options.fillOpacity); 13335 path.setAttribute('fill-rule', options.fillRule || 'evenodd'); 13336 } else { 13337 path.setAttribute('fill', 'none'); 13338 } 13339 }, 13340 13341 _updatePoly: function (layer, closed) { 13342 this._setPath(layer, pointsToPath(layer._parts, closed)); 13343 }, 13344 13345 _updateCircle: function (layer) { 13346 var p = layer._point, 13347 r = Math.max(Math.round(layer._radius), 1), 13348 r2 = Math.max(Math.round(layer._radiusY), 1) || r, 13349 arc = 'a' + r + ',' + r2 + ' 0 1,0 '; 13350 13351 // drawing a circle with two half-arcs 13352 var d = layer._empty() ? 'M0 0' : 13353 'M' + (p.x - r) + ',' + p.y + 13354 arc + (r * 2) + ',0 ' + 13355 arc + (-r * 2) + ',0 '; 13356 13357 this._setPath(layer, d); 13358 }, 13359 13360 _setPath: function (layer, path) { 13361 layer._path.setAttribute('d', path); 13362 }, 13363 13364 // SVG does not have the concept of zIndex so we resort to changing the DOM order of elements 13365 _bringToFront: function (layer) { 13366 toFront(layer._path); 13367 }, 13368 13369 _bringToBack: function (layer) { 13370 toBack(layer._path); 13371 } 13372}); 13373 13374if (vml) { 13375 SVG.include(vmlMixin); 13376} 13377 13378// @namespace SVG 13379// @factory L.svg(options?: Renderer options) 13380// Creates a SVG renderer with the given options. 13381function svg$1(options) { 13382 return svg || vml ? new SVG(options) : null; 13383} 13384 13385Map.include({ 13386 // @namespace Map; @method getRenderer(layer: Path): Renderer 13387 // Returns the instance of `Renderer` that should be used to render the given 13388 // `Path`. It will ensure that the `renderer` options of the map and paths 13389 // are respected, and that the renderers do exist on the map. 13390 getRenderer: function (layer) { 13391 // @namespace Path; @option renderer: Renderer 13392 // Use this specific instance of `Renderer` for this path. Takes 13393 // precedence over the map's [default renderer](#map-renderer). 13394 var renderer = layer.options.renderer || this._getPaneRenderer(layer.options.pane) || this.options.renderer || this._renderer; 13395 13396 if (!renderer) { 13397 renderer = this._renderer = this._createRenderer(); 13398 } 13399 13400 if (!this.hasLayer(renderer)) { 13401 this.addLayer(renderer); 13402 } 13403 return renderer; 13404 }, 13405 13406 _getPaneRenderer: function (name) { 13407 if (name === 'overlayPane' || name === undefined) { 13408 return false; 13409 } 13410 13411 var renderer = this._paneRenderers[name]; 13412 if (renderer === undefined) { 13413 renderer = this._createRenderer({pane: name}); 13414 this._paneRenderers[name] = renderer; 13415 } 13416 return renderer; 13417 }, 13418 13419 _createRenderer: function (options) { 13420 // @namespace Map; @option preferCanvas: Boolean = false 13421 // Whether `Path`s should be rendered on a `Canvas` renderer. 13422 // By default, all `Path`s are rendered in a `SVG` renderer. 13423 return (this.options.preferCanvas && canvas$1(options)) || svg$1(options); 13424 } 13425}); 13426 13427/* 13428 * L.Rectangle extends Polygon and creates a rectangle when passed a LatLngBounds object. 13429 */ 13430 13431/* 13432 * @class Rectangle 13433 * @aka L.Rectangle 13434 * @inherits Polygon 13435 * 13436 * A class for drawing rectangle overlays on a map. Extends `Polygon`. 13437 * 13438 * @example 13439 * 13440 * ```js 13441 * // define rectangle geographical bounds 13442 * var bounds = [[54.559322, -5.767822], [56.1210604, -3.021240]]; 13443 * 13444 * // create an orange rectangle 13445 * L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(map); 13446 * 13447 * // zoom the map to the rectangle bounds 13448 * map.fitBounds(bounds); 13449 * ``` 13450 * 13451 */ 13452 13453 13454var Rectangle = Polygon.extend({ 13455 initialize: function (latLngBounds, options) { 13456 Polygon.prototype.initialize.call(this, this._boundsToLatLngs(latLngBounds), options); 13457 }, 13458 13459 // @method setBounds(latLngBounds: LatLngBounds): this 13460 // Redraws the rectangle with the passed bounds. 13461 setBounds: function (latLngBounds) { 13462 return this.setLatLngs(this._boundsToLatLngs(latLngBounds)); 13463 }, 13464 13465 _boundsToLatLngs: function (latLngBounds) { 13466 latLngBounds = toLatLngBounds(latLngBounds); 13467 return [ 13468 latLngBounds.getSouthWest(), 13469 latLngBounds.getNorthWest(), 13470 latLngBounds.getNorthEast(), 13471 latLngBounds.getSouthEast() 13472 ]; 13473 } 13474}); 13475 13476 13477// @factory L.rectangle(latLngBounds: LatLngBounds, options?: Polyline options) 13478function rectangle(latLngBounds, options) { 13479 return new Rectangle(latLngBounds, options); 13480} 13481 13482SVG.create = create$2; 13483SVG.pointsToPath = pointsToPath; 13484 13485GeoJSON.geometryToLayer = geometryToLayer; 13486GeoJSON.coordsToLatLng = coordsToLatLng; 13487GeoJSON.coordsToLatLngs = coordsToLatLngs; 13488GeoJSON.latLngToCoords = latLngToCoords; 13489GeoJSON.latLngsToCoords = latLngsToCoords; 13490GeoJSON.getFeature = getFeature; 13491GeoJSON.asFeature = asFeature; 13492 13493/* 13494 * L.Handler.BoxZoom is used to add shift-drag zoom interaction to the map 13495 * (zoom to a selected bounding box), enabled by default. 13496 */ 13497 13498// @namespace Map 13499// @section Interaction Options 13500Map.mergeOptions({ 13501 // @option boxZoom: Boolean = true 13502 // Whether the map can be zoomed to a rectangular area specified by 13503 // dragging the mouse while pressing the shift key. 13504 boxZoom: true 13505}); 13506 13507var BoxZoom = Handler.extend({ 13508 initialize: function (map) { 13509 this._map = map; 13510 this._container = map._container; 13511 this._pane = map._panes.overlayPane; 13512 this._resetStateTimeout = 0; 13513 map.on('unload', this._destroy, this); 13514 }, 13515 13516 addHooks: function () { 13517 on(this._container, 'mousedown', this._onMouseDown, this); 13518 }, 13519 13520 removeHooks: function () { 13521 off(this._container, 'mousedown', this._onMouseDown, this); 13522 }, 13523 13524 moved: function () { 13525 return this._moved; 13526 }, 13527 13528 _destroy: function () { 13529 remove(this._pane); 13530 delete this._pane; 13531 }, 13532 13533 _resetState: function () { 13534 this._resetStateTimeout = 0; 13535 this._moved = false; 13536 }, 13537 13538 _clearDeferredResetState: function () { 13539 if (this._resetStateTimeout !== 0) { 13540 clearTimeout(this._resetStateTimeout); 13541 this._resetStateTimeout = 0; 13542 } 13543 }, 13544 13545 _onMouseDown: function (e) { 13546 if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; } 13547 13548 // Clear the deferred resetState if it hasn't executed yet, otherwise it 13549 // will interrupt the interaction and orphan a box element in the container. 13550 this._clearDeferredResetState(); 13551 this._resetState(); 13552 13553 disableTextSelection(); 13554 disableImageDrag(); 13555 13556 this._startPoint = this._map.mouseEventToContainerPoint(e); 13557 13558 on(document, { 13559 contextmenu: stop, 13560 mousemove: this._onMouseMove, 13561 mouseup: this._onMouseUp, 13562 keydown: this._onKeyDown 13563 }, this); 13564 }, 13565 13566 _onMouseMove: function (e) { 13567 if (!this._moved) { 13568 this._moved = true; 13569 13570 this._box = create$1('div', 'leaflet-zoom-box', this._container); 13571 addClass(this._container, 'leaflet-crosshair'); 13572 13573 this._map.fire('boxzoomstart'); 13574 } 13575 13576 this._point = this._map.mouseEventToContainerPoint(e); 13577 13578 var bounds = new Bounds(this._point, this._startPoint), 13579 size = bounds.getSize(); 13580 13581 setPosition(this._box, bounds.min); 13582 13583 this._box.style.width = size.x + 'px'; 13584 this._box.style.height = size.y + 'px'; 13585 }, 13586 13587 _finish: function () { 13588 if (this._moved) { 13589 remove(this._box); 13590 removeClass(this._container, 'leaflet-crosshair'); 13591 } 13592 13593 enableTextSelection(); 13594 enableImageDrag(); 13595 13596 off(document, { 13597 contextmenu: stop, 13598 mousemove: this._onMouseMove, 13599 mouseup: this._onMouseUp, 13600 keydown: this._onKeyDown 13601 }, this); 13602 }, 13603 13604 _onMouseUp: function (e) { 13605 if ((e.which !== 1) && (e.button !== 1)) { return; } 13606 13607 this._finish(); 13608 13609 if (!this._moved) { return; } 13610 // Postpone to next JS tick so internal click event handling 13611 // still see it as "moved". 13612 this._clearDeferredResetState(); 13613 this._resetStateTimeout = setTimeout(bind(this._resetState, this), 0); 13614 13615 var bounds = new LatLngBounds( 13616 this._map.containerPointToLatLng(this._startPoint), 13617 this._map.containerPointToLatLng(this._point)); 13618 13619 this._map 13620 .fitBounds(bounds) 13621 .fire('boxzoomend', {boxZoomBounds: bounds}); 13622 }, 13623 13624 _onKeyDown: function (e) { 13625 if (e.keyCode === 27) { 13626 this._finish(); 13627 } 13628 } 13629}); 13630 13631// @section Handlers 13632// @property boxZoom: Handler 13633// Box (shift-drag with mouse) zoom handler. 13634Map.addInitHook('addHandler', 'boxZoom', BoxZoom); 13635 13636/* 13637 * L.Handler.DoubleClickZoom is used to handle double-click zoom on the map, enabled by default. 13638 */ 13639 13640// @namespace Map 13641// @section Interaction Options 13642 13643Map.mergeOptions({ 13644 // @option doubleClickZoom: Boolean|String = true 13645 // Whether the map can be zoomed in by double clicking on it and 13646 // zoomed out by double clicking while holding shift. If passed 13647 // `'center'`, double-click zoom will zoom to the center of the 13648 // view regardless of where the mouse was. 13649 doubleClickZoom: true 13650}); 13651 13652var DoubleClickZoom = Handler.extend({ 13653 addHooks: function () { 13654 this._map.on('dblclick', this._onDoubleClick, this); 13655 }, 13656 13657 removeHooks: function () { 13658 this._map.off('dblclick', this._onDoubleClick, this); 13659 }, 13660 13661 _onDoubleClick: function (e) { 13662 var map = this._map, 13663 oldZoom = map.getZoom(), 13664 delta = map.options.zoomDelta, 13665 zoom = e.originalEvent.shiftKey ? oldZoom - delta : oldZoom + delta; 13666 13667 if (map.options.doubleClickZoom === 'center') { 13668 map.setZoom(zoom); 13669 } else { 13670 map.setZoomAround(e.containerPoint, zoom); 13671 } 13672 } 13673}); 13674 13675// @section Handlers 13676// 13677// Map properties include interaction handlers that allow you to control 13678// interaction behavior in runtime, enabling or disabling certain features such 13679// as dragging or touch zoom (see `Handler` methods). For example: 13680// 13681// ```js 13682// map.doubleClickZoom.disable(); 13683// ``` 13684// 13685// @property doubleClickZoom: Handler 13686// Double click zoom handler. 13687Map.addInitHook('addHandler', 'doubleClickZoom', DoubleClickZoom); 13688 13689/* 13690 * L.Handler.MapDrag is used to make the map draggable (with panning inertia), enabled by default. 13691 */ 13692 13693// @namespace Map 13694// @section Interaction Options 13695Map.mergeOptions({ 13696 // @option dragging: Boolean = true 13697 // Whether the map be draggable with mouse/touch or not. 13698 dragging: true, 13699 13700 // @section Panning Inertia Options 13701 // @option inertia: Boolean = * 13702 // If enabled, panning of the map will have an inertia effect where 13703 // the map builds momentum while dragging and continues moving in 13704 // the same direction for some time. Feels especially nice on touch 13705 // devices. Enabled by default unless running on old Android devices. 13706 inertia: !android23, 13707 13708 // @option inertiaDeceleration: Number = 3000 13709 // The rate with which the inertial movement slows down, in pixels/second². 13710 inertiaDeceleration: 3400, // px/s^2 13711 13712 // @option inertiaMaxSpeed: Number = Infinity 13713 // Max speed of the inertial movement, in pixels/second. 13714 inertiaMaxSpeed: Infinity, // px/s 13715 13716 // @option easeLinearity: Number = 0.2 13717 easeLinearity: 0.2, 13718 13719 // TODO refactor, move to CRS 13720 // @option worldCopyJump: Boolean = false 13721 // With this option enabled, the map tracks when you pan to another "copy" 13722 // of the world and seamlessly jumps to the original one so that all overlays 13723 // like markers and vector layers are still visible. 13724 worldCopyJump: false, 13725 13726 // @option maxBoundsViscosity: Number = 0.0 13727 // If `maxBounds` is set, this option will control how solid the bounds 13728 // are when dragging the map around. The default value of `0.0` allows the 13729 // user to drag outside the bounds at normal speed, higher values will 13730 // slow down map dragging outside bounds, and `1.0` makes the bounds fully 13731 // solid, preventing the user from dragging outside the bounds. 13732 maxBoundsViscosity: 0.0 13733}); 13734 13735var Drag = Handler.extend({ 13736 addHooks: function () { 13737 if (!this._draggable) { 13738 var map = this._map; 13739 13740 this._draggable = new Draggable(map._mapPane, map._container); 13741 13742 this._draggable.on({ 13743 dragstart: this._onDragStart, 13744 drag: this._onDrag, 13745 dragend: this._onDragEnd 13746 }, this); 13747 13748 this._draggable.on('predrag', this._onPreDragLimit, this); 13749 if (map.options.worldCopyJump) { 13750 this._draggable.on('predrag', this._onPreDragWrap, this); 13751 map.on('zoomend', this._onZoomEnd, this); 13752 13753 map.whenReady(this._onZoomEnd, this); 13754 } 13755 } 13756 addClass(this._map._container, 'leaflet-grab leaflet-touch-drag'); 13757 this._draggable.enable(); 13758 this._positions = []; 13759 this._times = []; 13760 }, 13761 13762 removeHooks: function () { 13763 removeClass(this._map._container, 'leaflet-grab'); 13764 removeClass(this._map._container, 'leaflet-touch-drag'); 13765 this._draggable.disable(); 13766 }, 13767 13768 moved: function () { 13769 return this._draggable && this._draggable._moved; 13770 }, 13771 13772 moving: function () { 13773 return this._draggable && this._draggable._moving; 13774 }, 13775 13776 _onDragStart: function () { 13777 var map = this._map; 13778 13779 map._stop(); 13780 if (this._map.options.maxBounds && this._map.options.maxBoundsViscosity) { 13781 var bounds = toLatLngBounds(this._map.options.maxBounds); 13782 13783 this._offsetLimit = toBounds( 13784 this._map.latLngToContainerPoint(bounds.getNorthWest()).multiplyBy(-1), 13785 this._map.latLngToContainerPoint(bounds.getSouthEast()).multiplyBy(-1) 13786 .add(this._map.getSize())); 13787 13788 this._viscosity = Math.min(1.0, Math.max(0.0, this._map.options.maxBoundsViscosity)); 13789 } else { 13790 this._offsetLimit = null; 13791 } 13792 13793 map 13794 .fire('movestart') 13795 .fire('dragstart'); 13796 13797 if (map.options.inertia) { 13798 this._positions = []; 13799 this._times = []; 13800 } 13801 }, 13802 13803 _onDrag: function (e) { 13804 if (this._map.options.inertia) { 13805 var time = this._lastTime = +new Date(), 13806 pos = this._lastPos = this._draggable._absPos || this._draggable._newPos; 13807 13808 this._positions.push(pos); 13809 this._times.push(time); 13810 13811 this._prunePositions(time); 13812 } 13813 13814 this._map 13815 .fire('move', e) 13816 .fire('drag', e); 13817 }, 13818 13819 _prunePositions: function (time) { 13820 while (this._positions.length > 1 && time - this._times[0] > 50) { 13821 this._positions.shift(); 13822 this._times.shift(); 13823 } 13824 }, 13825 13826 _onZoomEnd: function () { 13827 var pxCenter = this._map.getSize().divideBy(2), 13828 pxWorldCenter = this._map.latLngToLayerPoint([0, 0]); 13829 13830 this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x; 13831 this._worldWidth = this._map.getPixelWorldBounds().getSize().x; 13832 }, 13833 13834 _viscousLimit: function (value, threshold) { 13835 return value - (value - threshold) * this._viscosity; 13836 }, 13837 13838 _onPreDragLimit: function () { 13839 if (!this._viscosity || !this._offsetLimit) { return; } 13840 13841 var offset = this._draggable._newPos.subtract(this._draggable._startPos); 13842 13843 var limit = this._offsetLimit; 13844 if (offset.x < limit.min.x) { offset.x = this._viscousLimit(offset.x, limit.min.x); } 13845 if (offset.y < limit.min.y) { offset.y = this._viscousLimit(offset.y, limit.min.y); } 13846 if (offset.x > limit.max.x) { offset.x = this._viscousLimit(offset.x, limit.max.x); } 13847 if (offset.y > limit.max.y) { offset.y = this._viscousLimit(offset.y, limit.max.y); } 13848 13849 this._draggable._newPos = this._draggable._startPos.add(offset); 13850 }, 13851 13852 _onPreDragWrap: function () { 13853 // TODO refactor to be able to adjust map pane position after zoom 13854 var worldWidth = this._worldWidth, 13855 halfWidth = Math.round(worldWidth / 2), 13856 dx = this._initialWorldOffset, 13857 x = this._draggable._newPos.x, 13858 newX1 = (x - halfWidth + dx) % worldWidth + halfWidth - dx, 13859 newX2 = (x + halfWidth + dx) % worldWidth - halfWidth - dx, 13860 newX = Math.abs(newX1 + dx) < Math.abs(newX2 + dx) ? newX1 : newX2; 13861 13862 this._draggable._absPos = this._draggable._newPos.clone(); 13863 this._draggable._newPos.x = newX; 13864 }, 13865 13866 _onDragEnd: function (e) { 13867 var map = this._map, 13868 options = map.options, 13869 13870 noInertia = !options.inertia || this._times.length < 2; 13871 13872 map.fire('dragend', e); 13873 13874 if (noInertia) { 13875 map.fire('moveend'); 13876 13877 } else { 13878 this._prunePositions(+new Date()); 13879 13880 var direction = this._lastPos.subtract(this._positions[0]), 13881 duration = (this._lastTime - this._times[0]) / 1000, 13882 ease = options.easeLinearity, 13883 13884 speedVector = direction.multiplyBy(ease / duration), 13885 speed = speedVector.distanceTo([0, 0]), 13886 13887 limitedSpeed = Math.min(options.inertiaMaxSpeed, speed), 13888 limitedSpeedVector = speedVector.multiplyBy(limitedSpeed / speed), 13889 13890 decelerationDuration = limitedSpeed / (options.inertiaDeceleration * ease), 13891 offset = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round(); 13892 13893 if (!offset.x && !offset.y) { 13894 map.fire('moveend'); 13895 13896 } else { 13897 offset = map._limitOffset(offset, map.options.maxBounds); 13898 13899 requestAnimFrame(function () { 13900 map.panBy(offset, { 13901 duration: decelerationDuration, 13902 easeLinearity: ease, 13903 noMoveStart: true, 13904 animate: true 13905 }); 13906 }); 13907 } 13908 } 13909 } 13910}); 13911 13912// @section Handlers 13913// @property dragging: Handler 13914// Map dragging handler (by both mouse and touch). 13915Map.addInitHook('addHandler', 'dragging', Drag); 13916 13917/* 13918 * L.Map.Keyboard is handling keyboard interaction with the map, enabled by default. 13919 */ 13920 13921// @namespace Map 13922// @section Keyboard Navigation Options 13923Map.mergeOptions({ 13924 // @option keyboard: Boolean = true 13925 // Makes the map focusable and allows users to navigate the map with keyboard 13926 // arrows and `+`/`-` keys. 13927 keyboard: true, 13928 13929 // @option keyboardPanDelta: Number = 80 13930 // Amount of pixels to pan when pressing an arrow key. 13931 keyboardPanDelta: 80 13932}); 13933 13934var Keyboard = Handler.extend({ 13935 13936 keyCodes: { 13937 left: [37], 13938 right: [39], 13939 down: [40], 13940 up: [38], 13941 zoomIn: [187, 107, 61, 171], 13942 zoomOut: [189, 109, 54, 173] 13943 }, 13944 13945 initialize: function (map) { 13946 this._map = map; 13947 13948 this._setPanDelta(map.options.keyboardPanDelta); 13949 this._setZoomDelta(map.options.zoomDelta); 13950 }, 13951 13952 addHooks: function () { 13953 var container = this._map._container; 13954 13955 // make the container focusable by tabbing 13956 if (container.tabIndex <= 0) { 13957 container.tabIndex = '0'; 13958 } 13959 13960 on(container, { 13961 focus: this._onFocus, 13962 blur: this._onBlur, 13963 mousedown: this._onMouseDown 13964 }, this); 13965 13966 this._map.on({ 13967 focus: this._addHooks, 13968 blur: this._removeHooks 13969 }, this); 13970 }, 13971 13972 removeHooks: function () { 13973 this._removeHooks(); 13974 13975 off(this._map._container, { 13976 focus: this._onFocus, 13977 blur: this._onBlur, 13978 mousedown: this._onMouseDown 13979 }, this); 13980 13981 this._map.off({ 13982 focus: this._addHooks, 13983 blur: this._removeHooks 13984 }, this); 13985 }, 13986 13987 _onMouseDown: function () { 13988 if (this._focused) { return; } 13989 13990 var body = document.body, 13991 docEl = document.documentElement, 13992 top = body.scrollTop || docEl.scrollTop, 13993 left = body.scrollLeft || docEl.scrollLeft; 13994 13995 this._map._container.focus(); 13996 13997 window.scrollTo(left, top); 13998 }, 13999 14000 _onFocus: function () { 14001 this._focused = true; 14002 this._map.fire('focus'); 14003 }, 14004 14005 _onBlur: function () { 14006 this._focused = false; 14007 this._map.fire('blur'); 14008 }, 14009 14010 _setPanDelta: function (panDelta) { 14011 var keys = this._panKeys = {}, 14012 codes = this.keyCodes, 14013 i, len; 14014 14015 for (i = 0, len = codes.left.length; i < len; i++) { 14016 keys[codes.left[i]] = [-1 * panDelta, 0]; 14017 } 14018 for (i = 0, len = codes.right.length; i < len; i++) { 14019 keys[codes.right[i]] = [panDelta, 0]; 14020 } 14021 for (i = 0, len = codes.down.length; i < len; i++) { 14022 keys[codes.down[i]] = [0, panDelta]; 14023 } 14024 for (i = 0, len = codes.up.length; i < len; i++) { 14025 keys[codes.up[i]] = [0, -1 * panDelta]; 14026 } 14027 }, 14028 14029 _setZoomDelta: function (zoomDelta) { 14030 var keys = this._zoomKeys = {}, 14031 codes = this.keyCodes, 14032 i, len; 14033 14034 for (i = 0, len = codes.zoomIn.length; i < len; i++) { 14035 keys[codes.zoomIn[i]] = zoomDelta; 14036 } 14037 for (i = 0, len = codes.zoomOut.length; i < len; i++) { 14038 keys[codes.zoomOut[i]] = -zoomDelta; 14039 } 14040 }, 14041 14042 _addHooks: function () { 14043 on(document, 'keydown', this._onKeyDown, this); 14044 }, 14045 14046 _removeHooks: function () { 14047 off(document, 'keydown', this._onKeyDown, this); 14048 }, 14049 14050 _onKeyDown: function (e) { 14051 if (e.altKey || e.ctrlKey || e.metaKey) { return; } 14052 14053 var key = e.keyCode, 14054 map = this._map, 14055 offset; 14056 14057 if (key in this._panKeys) { 14058 if (!map._panAnim || !map._panAnim._inProgress) { 14059 offset = this._panKeys[key]; 14060 if (e.shiftKey) { 14061 offset = toPoint(offset).multiplyBy(3); 14062 } 14063 14064 map.panBy(offset); 14065 14066 if (map.options.maxBounds) { 14067 map.panInsideBounds(map.options.maxBounds); 14068 } 14069 } 14070 } else if (key in this._zoomKeys) { 14071 map.setZoom(map.getZoom() + (e.shiftKey ? 3 : 1) * this._zoomKeys[key]); 14072 14073 } else if (key === 27 && map._popup && map._popup.options.closeOnEscapeKey) { 14074 map.closePopup(); 14075 14076 } else { 14077 return; 14078 } 14079 14080 stop(e); 14081 } 14082}); 14083 14084// @section Handlers 14085// @section Handlers 14086// @property keyboard: Handler 14087// Keyboard navigation handler. 14088Map.addInitHook('addHandler', 'keyboard', Keyboard); 14089 14090/* 14091 * L.Handler.ScrollWheelZoom is used by L.Map to enable mouse scroll wheel zoom on the map. 14092 */ 14093 14094// @namespace Map 14095// @section Interaction Options 14096Map.mergeOptions({ 14097 // @section Mousewheel options 14098 // @option scrollWheelZoom: Boolean|String = true 14099 // Whether the map can be zoomed by using the mouse wheel. If passed `'center'`, 14100 // it will zoom to the center of the view regardless of where the mouse was. 14101 scrollWheelZoom: true, 14102 14103 // @option wheelDebounceTime: Number = 40 14104 // Limits the rate at which a wheel can fire (in milliseconds). By default 14105 // user can't zoom via wheel more often than once per 40 ms. 14106 wheelDebounceTime: 40, 14107 14108 // @option wheelPxPerZoomLevel: Number = 60 14109 // How many scroll pixels (as reported by [L.DomEvent.getWheelDelta](#domevent-getwheeldelta)) 14110 // mean a change of one full zoom level. Smaller values will make wheel-zooming 14111 // faster (and vice versa). 14112 wheelPxPerZoomLevel: 60 14113}); 14114 14115var ScrollWheelZoom = Handler.extend({ 14116 addHooks: function () { 14117 on(this._map._container, 'mousewheel', this._onWheelScroll, this); 14118 14119 this._delta = 0; 14120 }, 14121 14122 removeHooks: function () { 14123 off(this._map._container, 'mousewheel', this._onWheelScroll, this); 14124 }, 14125 14126 _onWheelScroll: function (e) { 14127 var delta = getWheelDelta(e); 14128 14129 var debounce = this._map.options.wheelDebounceTime; 14130 14131 this._delta += delta; 14132 this._lastMousePos = this._map.mouseEventToContainerPoint(e); 14133 14134 if (!this._startTime) { 14135 this._startTime = +new Date(); 14136 } 14137 14138 var left = Math.max(debounce - (+new Date() - this._startTime), 0); 14139 14140 clearTimeout(this._timer); 14141 this._timer = setTimeout(bind(this._performZoom, this), left); 14142 14143 stop(e); 14144 }, 14145 14146 _performZoom: function () { 14147 var map = this._map, 14148 zoom = map.getZoom(), 14149 snap = this._map.options.zoomSnap || 0; 14150 14151 map._stop(); // stop panning and fly animations if any 14152 14153 // map the delta with a sigmoid function to -4..4 range leaning on -1..1 14154 var d2 = this._delta / (this._map.options.wheelPxPerZoomLevel * 4), 14155 d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2, 14156 d4 = snap ? Math.ceil(d3 / snap) * snap : d3, 14157 delta = map._limitZoom(zoom + (this._delta > 0 ? d4 : -d4)) - zoom; 14158 14159 this._delta = 0; 14160 this._startTime = null; 14161 14162 if (!delta) { return; } 14163 14164 if (map.options.scrollWheelZoom === 'center') { 14165 map.setZoom(zoom + delta); 14166 } else { 14167 map.setZoomAround(this._lastMousePos, zoom + delta); 14168 } 14169 } 14170}); 14171 14172// @section Handlers 14173// @property scrollWheelZoom: Handler 14174// Scroll wheel zoom handler. 14175Map.addInitHook('addHandler', 'scrollWheelZoom', ScrollWheelZoom); 14176 14177/* 14178 * L.Map.Tap is used to enable mobile hacks like quick taps and long hold. 14179 */ 14180 14181// @namespace Map 14182// @section Interaction Options 14183Map.mergeOptions({ 14184 // @section Touch interaction options 14185 // @option tap: Boolean = true 14186 // Enables mobile hacks for supporting instant taps (fixing 200ms click 14187 // delay on iOS/Android) and touch holds (fired as `contextmenu` events). 14188 tap: true, 14189 14190 // @option tapTolerance: Number = 15 14191 // The max number of pixels a user can shift his finger during touch 14192 // for it to be considered a valid tap. 14193 tapTolerance: 15 14194}); 14195 14196var Tap = Handler.extend({ 14197 addHooks: function () { 14198 on(this._map._container, 'touchstart', this._onDown, this); 14199 }, 14200 14201 removeHooks: function () { 14202 off(this._map._container, 'touchstart', this._onDown, this); 14203 }, 14204 14205 _onDown: function (e) { 14206 if (!e.touches) { return; } 14207 14208 preventDefault(e); 14209 14210 this._fireClick = true; 14211 14212 // don't simulate click or track longpress if more than 1 touch 14213 if (e.touches.length > 1) { 14214 this._fireClick = false; 14215 clearTimeout(this._holdTimeout); 14216 return; 14217 } 14218 14219 var first = e.touches[0], 14220 el = first.target; 14221 14222 this._startPos = this._newPos = new Point(first.clientX, first.clientY); 14223 14224 // if touching a link, highlight it 14225 if (el.tagName && el.tagName.toLowerCase() === 'a') { 14226 addClass(el, 'leaflet-active'); 14227 } 14228 14229 // simulate long hold but setting a timeout 14230 this._holdTimeout = setTimeout(bind(function () { 14231 if (this._isTapValid()) { 14232 this._fireClick = false; 14233 this._onUp(); 14234 this._simulateEvent('contextmenu', first); 14235 } 14236 }, this), 1000); 14237 14238 this._simulateEvent('mousedown', first); 14239 14240 on(document, { 14241 touchmove: this._onMove, 14242 touchend: this._onUp 14243 }, this); 14244 }, 14245 14246 _onUp: function (e) { 14247 clearTimeout(this._holdTimeout); 14248 14249 off(document, { 14250 touchmove: this._onMove, 14251 touchend: this._onUp 14252 }, this); 14253 14254 if (this._fireClick && e && e.changedTouches) { 14255 14256 var first = e.changedTouches[0], 14257 el = first.target; 14258 14259 if (el && el.tagName && el.tagName.toLowerCase() === 'a') { 14260 removeClass(el, 'leaflet-active'); 14261 } 14262 14263 this._simulateEvent('mouseup', first); 14264 14265 // simulate click if the touch didn't move too much 14266 if (this._isTapValid()) { 14267 this._simulateEvent('click', first); 14268 } 14269 } 14270 }, 14271 14272 _isTapValid: function () { 14273 return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance; 14274 }, 14275 14276 _onMove: function (e) { 14277 var first = e.touches[0]; 14278 this._newPos = new Point(first.clientX, first.clientY); 14279 this._simulateEvent('mousemove', first); 14280 }, 14281 14282 _simulateEvent: function (type, e) { 14283 var simulatedEvent = document.createEvent('MouseEvents'); 14284 14285 simulatedEvent._simulated = true; 14286 e.target._simulatedClick = true; 14287 14288 simulatedEvent.initMouseEvent( 14289 type, true, true, window, 1, 14290 e.screenX, e.screenY, 14291 e.clientX, e.clientY, 14292 false, false, false, false, 0, null); 14293 14294 e.target.dispatchEvent(simulatedEvent); 14295 } 14296}); 14297 14298// @section Handlers 14299// @property tap: Handler 14300// Mobile touch hacks (quick tap and touch hold) handler. 14301if (touch && !pointer) { 14302 Map.addInitHook('addHandler', 'tap', Tap); 14303} 14304 14305/* 14306 * L.Handler.TouchZoom is used by L.Map to add pinch zoom on supported mobile browsers. 14307 */ 14308 14309// @namespace Map 14310// @section Interaction Options 14311Map.mergeOptions({ 14312 // @section Touch interaction options 14313 // @option touchZoom: Boolean|String = * 14314 // Whether the map can be zoomed by touch-dragging with two fingers. If 14315 // passed `'center'`, it will zoom to the center of the view regardless of 14316 // where the touch events (fingers) were. Enabled for touch-capable web 14317 // browsers except for old Androids. 14318 touchZoom: touch && !android23, 14319 14320 // @option bounceAtZoomLimits: Boolean = true 14321 // Set it to false if you don't want the map to zoom beyond min/max zoom 14322 // and then bounce back when pinch-zooming. 14323 bounceAtZoomLimits: true 14324}); 14325 14326var TouchZoom = Handler.extend({ 14327 addHooks: function () { 14328 addClass(this._map._container, 'leaflet-touch-zoom'); 14329 on(this._map._container, 'touchstart', this._onTouchStart, this); 14330 }, 14331 14332 removeHooks: function () { 14333 removeClass(this._map._container, 'leaflet-touch-zoom'); 14334 off(this._map._container, 'touchstart', this._onTouchStart, this); 14335 }, 14336 14337 _onTouchStart: function (e) { 14338 var map = this._map; 14339 if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming) { return; } 14340 14341 var p1 = map.mouseEventToContainerPoint(e.touches[0]), 14342 p2 = map.mouseEventToContainerPoint(e.touches[1]); 14343 14344 this._centerPoint = map.getSize()._divideBy(2); 14345 this._startLatLng = map.containerPointToLatLng(this._centerPoint); 14346 if (map.options.touchZoom !== 'center') { 14347 this._pinchStartLatLng = map.containerPointToLatLng(p1.add(p2)._divideBy(2)); 14348 } 14349 14350 this._startDist = p1.distanceTo(p2); 14351 this._startZoom = map.getZoom(); 14352 14353 this._moved = false; 14354 this._zooming = true; 14355 14356 map._stop(); 14357 14358 on(document, 'touchmove', this._onTouchMove, this); 14359 on(document, 'touchend', this._onTouchEnd, this); 14360 14361 preventDefault(e); 14362 }, 14363 14364 _onTouchMove: function (e) { 14365 if (!e.touches || e.touches.length !== 2 || !this._zooming) { return; } 14366 14367 var map = this._map, 14368 p1 = map.mouseEventToContainerPoint(e.touches[0]), 14369 p2 = map.mouseEventToContainerPoint(e.touches[1]), 14370 scale = p1.distanceTo(p2) / this._startDist; 14371 14372 this._zoom = map.getScaleZoom(scale, this._startZoom); 14373 14374 if (!map.options.bounceAtZoomLimits && ( 14375 (this._zoom < map.getMinZoom() && scale < 1) || 14376 (this._zoom > map.getMaxZoom() && scale > 1))) { 14377 this._zoom = map._limitZoom(this._zoom); 14378 } 14379 14380 if (map.options.touchZoom === 'center') { 14381 this._center = this._startLatLng; 14382 if (scale === 1) { return; } 14383 } else { 14384 // Get delta from pinch to center, so centerLatLng is delta applied to initial pinchLatLng 14385 var delta = p1._add(p2)._divideBy(2)._subtract(this._centerPoint); 14386 if (scale === 1 && delta.x === 0 && delta.y === 0) { return; } 14387 this._center = map.unproject(map.project(this._pinchStartLatLng, this._zoom).subtract(delta), this._zoom); 14388 } 14389 14390 if (!this._moved) { 14391 map._moveStart(true, false); 14392 this._moved = true; 14393 } 14394 14395 cancelAnimFrame(this._animRequest); 14396 14397 var moveFn = bind(map._move, map, this._center, this._zoom, {pinch: true, round: false}); 14398 this._animRequest = requestAnimFrame(moveFn, this, true); 14399 14400 preventDefault(e); 14401 }, 14402 14403 _onTouchEnd: function () { 14404 if (!this._moved || !this._zooming) { 14405 this._zooming = false; 14406 return; 14407 } 14408 14409 this._zooming = false; 14410 cancelAnimFrame(this._animRequest); 14411 14412 off(document, 'touchmove', this._onTouchMove); 14413 off(document, 'touchend', this._onTouchEnd); 14414 14415 // Pinch updates GridLayers' levels only when zoomSnap is off, so zoomSnap becomes noUpdate. 14416 if (this._map.options.zoomAnimation) { 14417 this._map._animateZoom(this._center, this._map._limitZoom(this._zoom), true, this._map.options.zoomSnap); 14418 } else { 14419 this._map._resetView(this._center, this._map._limitZoom(this._zoom)); 14420 } 14421 } 14422}); 14423 14424// @section Handlers 14425// @property touchZoom: Handler 14426// Touch zoom handler. 14427Map.addInitHook('addHandler', 'touchZoom', TouchZoom); 14428 14429Map.BoxZoom = BoxZoom; 14430Map.DoubleClickZoom = DoubleClickZoom; 14431Map.Drag = Drag; 14432Map.Keyboard = Keyboard; 14433Map.ScrollWheelZoom = ScrollWheelZoom; 14434Map.Tap = Tap; 14435Map.TouchZoom = TouchZoom; 14436 14437Object.freeze = freeze; 14438 14439exports.version = version; 14440exports.Control = Control; 14441exports.control = control; 14442exports.Browser = Browser; 14443exports.Evented = Evented; 14444exports.Mixin = Mixin; 14445exports.Util = Util; 14446exports.Class = Class; 14447exports.Handler = Handler; 14448exports.extend = extend; 14449exports.bind = bind; 14450exports.stamp = stamp; 14451exports.setOptions = setOptions; 14452exports.DomEvent = DomEvent; 14453exports.DomUtil = DomUtil; 14454exports.PosAnimation = PosAnimation; 14455exports.Draggable = Draggable; 14456exports.LineUtil = LineUtil; 14457exports.PolyUtil = PolyUtil; 14458exports.Point = Point; 14459exports.point = toPoint; 14460exports.Bounds = Bounds; 14461exports.bounds = toBounds; 14462exports.Transformation = Transformation; 14463exports.transformation = toTransformation; 14464exports.Projection = index; 14465exports.LatLng = LatLng; 14466exports.latLng = toLatLng; 14467exports.LatLngBounds = LatLngBounds; 14468exports.latLngBounds = toLatLngBounds; 14469exports.CRS = CRS; 14470exports.GeoJSON = GeoJSON; 14471exports.geoJSON = geoJSON; 14472exports.geoJson = geoJson; 14473exports.Layer = Layer; 14474exports.LayerGroup = LayerGroup; 14475exports.layerGroup = layerGroup; 14476exports.FeatureGroup = FeatureGroup; 14477exports.featureGroup = featureGroup; 14478exports.ImageOverlay = ImageOverlay; 14479exports.imageOverlay = imageOverlay; 14480exports.VideoOverlay = VideoOverlay; 14481exports.videoOverlay = videoOverlay; 14482exports.SVGOverlay = SVGOverlay; 14483exports.svgOverlay = svgOverlay; 14484exports.DivOverlay = DivOverlay; 14485exports.Popup = Popup; 14486exports.popup = popup; 14487exports.Tooltip = Tooltip; 14488exports.tooltip = tooltip; 14489exports.Icon = Icon; 14490exports.icon = icon; 14491exports.DivIcon = DivIcon; 14492exports.divIcon = divIcon; 14493exports.Marker = Marker; 14494exports.marker = marker; 14495exports.TileLayer = TileLayer; 14496exports.tileLayer = tileLayer; 14497exports.GridLayer = GridLayer; 14498exports.gridLayer = gridLayer; 14499exports.SVG = SVG; 14500exports.svg = svg$1; 14501exports.Renderer = Renderer; 14502exports.Canvas = Canvas; 14503exports.canvas = canvas$1; 14504exports.Path = Path; 14505exports.CircleMarker = CircleMarker; 14506exports.circleMarker = circleMarker; 14507exports.Circle = Circle; 14508exports.circle = circle; 14509exports.Polyline = Polyline; 14510exports.polyline = polyline; 14511exports.Polygon = Polygon; 14512exports.polygon = polygon; 14513exports.Rectangle = Rectangle; 14514exports.rectangle = rectangle; 14515exports.Map = Map; 14516exports.map = createMap; 14517 14518var oldL = window.L; 14519exports.noConflict = function() { 14520 window.L = oldL; 14521 return this; 14522} 14523 14524// Always export us to window global (see #2364) 14525window.L = exports; 14526 14527}))); 14528//# sourceMappingURL=leaflet-src.js.map 14529 14530 14531/***/ }), 14532
vendor: 9,887 bytes, lines 14533-14769
14533/***/ "./node_modules/paroller.js/dist/jquery.paroller.js": 14534/*!**********************************************************!*\ 14535 !*** ./node_modules/paroller.js/dist/jquery.paroller.js ***! 14536 \**********************************************************/ 14537/*! no static exports found */ 14538/***/ (function(module, exports, __webpack_require__) { 14539 14540var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 14541 * jQuery plugin paroller.js v1.4.6 14542 * https://github.com/tgomilar/paroller.js 14543 * preview: https://tgomilar.github.io/paroller/ 14544 **/ 14545(function (factory) { 14546 'use strict'; 14547 if (true) { 14548 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ "jquery")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 14549 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 14550 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 14551 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 14552 } else {} 14553})(function ($) { 14554 'use strict'; 14555 14556 var working = false; 14557 var scrollAction = function() { 14558 working = false; 14559 }; 14560 14561 var setDirection = { 14562 bgVertical: function (elem, bgOffset) { 14563 return elem.css({'background-position': 'center ' + -bgOffset + 'px'}); 14564 }, 14565 bgHorizontal: function (elem, bgOffset) { 14566 return elem.css({'background-position': -bgOffset + 'px' + ' center'}); 14567 }, 14568 vertical: function (elem, elemOffset, transition, oldTransform) { 14569 (oldTransform === 'none' ? oldTransform = '' : true); 14570 return elem.css({ 14571 '-webkit-transform': 'translateY(' + elemOffset + 'px)' + oldTransform, 14572 '-moz-transform': 'translateY(' + elemOffset + 'px)' + oldTransform, 14573 'transform': 'translate(0,' + elemOffset + 'px)' + oldTransform, 14574 'transition': transition, 14575 'will-change': 'transform' 14576 }); 14577 }, 14578 horizontal: function (elem, elemOffset, transition, oldTransform) { 14579 (oldTransform === 'none' ? oldTransform = '' : true); 14580 return elem.css({ 14581 '-webkit-transform': 'translateX(' + elemOffset + 'px)' + oldTransform, 14582 '-moz-transform': 'translateX(' + elemOffset + 'px)' + oldTransform, 14583 'transform': 'translate(' + elemOffset + 'px, 0)' + oldTransform, 14584 'transition': transition, 14585 'will-change': 'transform' 14586 }); 14587 } 14588 }; 14589 14590 var setMovement = { 14591 factor: function (elem, width, options) { 14592 var dataFactor = elem.data('paroller-factor'); 14593 var factor = (dataFactor) ? dataFactor : options.factor; 14594 if (width < 576) { 14595 var dataFactorXs = elem.data('paroller-factor-xs'); 14596 var factorXs = (dataFactorXs) ? dataFactorXs : options.factorXs; 14597 return (factorXs) ? factorXs : factor; 14598 } 14599 else if (width <= 768) { 14600 var dataFactorSm = elem.data('paroller-factor-sm'); 14601 var factorSm = (dataFactorSm) ? dataFactorSm : options.factorSm; 14602 return (factorSm) ? factorSm : factor; 14603 } 14604 else if (width <= 1024) { 14605 var dataFactorMd = elem.data('paroller-factor-md'); 14606 var factorMd = (dataFactorMd) ? dataFactorMd : options.factorMd; 14607 return (factorMd) ? factorMd : factor; 14608 } 14609 else if (width <= 1200) { 14610 var dataFactorLg = elem.data('paroller-factor-lg'); 14611 var factorLg = (dataFactorLg) ? dataFactorLg : options.factorLg; 14612 return (factorLg) ? factorLg : factor; 14613 } else if (width <= 1920) { 14614 var dataFactorXl = elem.data('paroller-factor-xl'); 14615 var factorXl = (dataFactorXl) ? dataFactorXl : options.factorXl; 14616 return (factorXl) ? factorXl : factor; 14617 } else { 14618 return factor; 14619 } 14620 }, 14621 bgOffset: function (offset, factor) { 14622 return Math.round(offset * factor); 14623 }, 14624 transform: function (offset, factor, windowHeight, height) { 14625 return Math.round((offset - (windowHeight / 2) + height) * factor); 14626 } 14627 }; 14628 14629 var clearPositions = { 14630 background: function (elem) { 14631 return elem.css({'background-position': 'unset'}); 14632 }, 14633 foreground: function (elem) { 14634 return elem.css({ 14635 'transform' : 'unset', 14636 'transition' : 'unset' 14637 }); 14638 } 14639 }; 14640 14641 $.fn.paroller = function (options) { 14642 var windowHeight = $(window).height(); 14643 var documentHeight = $(document).height(); 14644 14645 // default options 14646 var options = $.extend({ 14647 factor: 0, // - to + 14648 factorXs: 0, // - to + 14649 factorSm: 0, // - to + 14650 factorMd: 0, // - to + 14651 factorLg: 0, // - to + 14652 factorXl: 0, // - to + 14653 transition: 'transform .1s ease', // CSS transition 14654 type: 'background', // foreground 14655 direction: 'vertical' // horizontal 14656 }, options); 14657 14658 return this.each(function () { 14659 var $this = $(this); 14660 var width = $(window).width(); 14661 var offset = $this.offset().top; 14662 var height = $this.outerHeight(); 14663 14664 var dataType = $this.data('paroller-type'); 14665 var dataDirection = $this.data('paroller-direction'); 14666 var dataTransition = $this.data('paroller-transition'); 14667 var oldTransform = $this.css('transform'); 14668 14669 var transition = (dataTransition) ? dataTransition : options.transition; 14670 var type = (dataType) ? dataType : options.type; 14671 var direction = (dataDirection) ? dataDirection : options.direction; 14672 var factor = 0; 14673 var bgOffset = setMovement.bgOffset(offset, factor); 14674 var transform = setMovement.transform(offset, factor, windowHeight, height); 14675 14676 if (type === 'background') { 14677 if (direction === 'vertical') { 14678 setDirection.bgVertical($this, bgOffset); 14679 } 14680 else if (direction === 'horizontal') { 14681 setDirection.bgHorizontal($this, bgOffset); 14682 } 14683 } 14684 else if (type === 'foreground') { 14685 if (direction === 'vertical') { 14686 setDirection.vertical($this, transform, transition, oldTransform); 14687 } 14688 else if (direction === 'horizontal') { 14689 setDirection.horizontal($this, transform, transition, oldTransform); 14690 } 14691 } 14692 14693 $(window).on('resize', function () { 14694 var scrolling = $(this).scrollTop(); 14695 width = $(window).width(); 14696 offset = $this.offset().top; 14697 height = $this.outerHeight(); 14698 factor = setMovement.factor($this, width, options); 14699 14700 bgOffset = Math.round(offset * factor); 14701 transform = Math.round((offset - (windowHeight / 2) + height) * factor); 14702 14703 if (! working) { 14704 window.requestAnimationFrame(scrollAction); 14705 working = true; 14706 } 14707 14708 if (type === 'background') { 14709 clearPositions.background($this); 14710 if (direction === 'vertical') { 14711 setDirection.bgVertical($this, bgOffset); 14712 } 14713 else if (direction === 'horizontal') { 14714 setDirection.bgHorizontal($this, bgOffset); 14715 } 14716 } 14717 else if ((type === 'foreground') && (scrolling <= documentHeight)) { 14718 clearPositions.foreground($this); 14719 if (direction === 'vertical') { 14720 setDirection.vertical($this, transform, transition); 14721 } 14722 else if (direction === 'horizontal') { 14723 setDirection.horizontal($this, transform, transition); 14724 } 14725 } 14726 }); 14727 14728 $(window).on('scroll', function () { 14729 var scrolling = $(this).scrollTop(); 14730 var scrollTop = $(document).scrollTop(); 14731 14732 if (scrollTop === 0) { 14733 factor = 0; 14734 } else { 14735 factor = setMovement.factor($this, width, options); 14736 } 14737 14738 bgOffset = Math.round((offset - scrolling) * factor); 14739 transform = Math.round(((offset - (windowHeight / 2) + height) - scrolling) * factor); 14740 14741 if (! working) { 14742 window.requestAnimationFrame(scrollAction); 14743 working = true; 14744 } 14745 14746 if (type === 'background') { 14747 if (direction === 'vertical') { 14748 setDirection.bgVertical($this, bgOffset); 14749 } 14750 else if (direction === 'horizontal') { 14751 setDirection.bgHorizontal($this, bgOffset); 14752 } 14753 } 14754 else if ((type === 'foreground') && (scrolling <= documentHeight)) { 14755 if (direction === 'vertical') { 14756 setDirection.vertical($this, transform, transition, oldTransform); 14757 } 14758 else if (direction === 'horizontal') { 14759 setDirection.horizontal($this, transform, transition, oldTransform); 14760 } 14761 } 14762 }); 14763 }); 14764 }; 14765}); 14766 14767 14768/***/ }), 14769
vendor: 43,614 bytes, lines 14770-14784
14770/***/ "./node_modules/slick-carousel/slick/slick.min.js": 14771/*!********************************************************!*\ 14772 !*** ./node_modules/slick-carousel/slick/slick.min.js ***! 14773 \********************************************************/ 14774/*! no static exports found */ 14775/***/ (function(module, exports, __webpack_require__) { 14776 14777var __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), 14778 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 14779 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 14780 __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}}); 14781 14782 14783/***/ }), 14784
vendor: 5,990 bytes, lines 14785-14801
14785/***/ "./node_modules/vanilla-lazyload/dist/lazyload.min.js": 14786/*!************************************************************!*\ 14787 !*** ./node_modules/vanilla-lazyload/dist/lazyload.min.js ***! 14788 \************************************************************/ 14789/*! no static exports found */ 14790/***/ (function(module, exports, __webpack_require__) { 14791 14792var __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), 14793 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 14794 (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : 14795 __WEBPACK_AMD_DEFINE_FACTORY__), 14796 __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}); 14797//# sourceMappingURL=lazyload.min.js.map 14798 14799 14800/***/ }), 14801
vendor: 724 bytes, lines 14802-14832
14802/***/ "./node_modules/webpack/buildin/global.js": 14803/*!***********************************!*\ 14804 !*** (webpack)/buildin/global.js ***! 14805 \***********************************/ 14806/*! no static exports found */ 14807/***/ (function(module, exports) { 14808 14809var g; 14810 14811// This works in non-strict mode 14812g = (function() { 14813 return this; 14814})(); 14815 14816try { 14817 // This works if eval is allowed (see CSP) 14818 g = g || new Function("return this")(); 14819} catch (e) { 14820 // This works if the window reference is available 14821 if (typeof window === "object") g = window; 14822} 14823 14824// g can still be undefined, but nothing to do about it... 14825// We return undefined, instead of nothing here, so it's 14826// easier to handle this case. if(!global) { ...} 14827 14828module.exports = g; 14829 14830 14831/***/ }), 14832
14833/***/ "./wp-content/themes/camiers/assets/src/js/app.js": 14834/*!********************************************************!*\ 14835 !*** ./wp-content/themes/camiers/assets/src/js/app.js ***! 14836 \********************************************************/ 14837/*! no exports provided */ 14838/***/ (function(module, __webpack_exports__, __webpack_require__) { 14839 14840"use strict"; 14841__webpack_require__.r(__webpack_exports__); 14842/* harmony import */ var _camiers_scss_site_scss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @camiers/scss/site.scss */ "./wp-content/themes/camiers/assets/src/scss/site.scss"); 14843/* harmony import */ var _camiers_scss_site_scss__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_camiers_scss_site_scss__WEBPACK_IMPORTED_MODULE_0__); 14844/* harmony import */ var _camiers_scss_site_editor_scss__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @camiers/scss/site-editor.scss */ "./wp-content/themes/camiers/assets/src/scss/site-editor.scss"); 14845/* harmony import */ var _camiers_scss_site_editor_scss__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_camiers_scss_site_editor_scss__WEBPACK_IMPORTED_MODULE_1__); 14846/* harmony import */ var _camiers_js_bootstrap_bundle__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @camiers/js/bootstrap.bundle */ "./wp-content/themes/camiers/assets/src/js/bootstrap.bundle.js"); 14847/* harmony import */ var _camiers_js_bootstrap_bundle__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_camiers_js_bootstrap_bundle__WEBPACK_IMPORTED_MODULE_2__); 14848/* harmony import */ var _camiers_js_components_ux_cpnt__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @camiers/js/components/ux_cpnt */ "./wp-content/themes/camiers/assets/src/js/components/ux_cpnt.js"); 14849/* harmony import */ var _camiers_js_components_form_cpnt__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @camiers/js/components/form_cpnt */ "./wp-content/themes/camiers/assets/src/js/components/form_cpnt.js"); 14850/* harmony import */ var _camiers_js_components_brochure_cpnt__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @camiers/js/components/brochure_cpnt */ "./wp-content/themes/camiers/assets/src/js/components/brochure_cpnt.js"); 14851/* harmony import */ var _camiers_js_components_map_cpnt__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @camiers/js/components/map_cpnt */ "./wp-content/themes/camiers/assets/src/js/components/map_cpnt.js"); 14852/* harmony import */ var _camiers_js_components_weather_cpnt__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @camiers/js/components/weather_cpnt */ "./wp-content/themes/camiers/assets/src/js/components/weather_cpnt.js"); 14853/* harmony import */ var _camiers_js_components_tide_cpnt__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @camiers/js/components/tide_cpnt */ "./wp-content/themes/camiers/assets/src/js/components/tide_cpnt.js"); 14854/* harmony import */ var _camiers_js_components_slider_cpnt__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @camiers/js/components/slider_cpnt */ "./wp-content/themes/camiers/assets/src/js/components/slider_cpnt.js"); 14855/* harmony import */ var _camiers_js_components_engine_home_cpnt__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @camiers/js/components/engine_home_cpnt */ "./wp-content/themes/camiers/assets/src/js/components/engine_home_cpnt.js"); 14856 14857 14858 14859 14860 14861 14862 14863 14864 14865 14866 14867document.addEventListener("DOMContentLoaded", function () { 14868 var ObjUxCpnt = new _camiers_js_components_ux_cpnt__WEBPACK_IMPORTED_MODULE_3__["UxCpnt"](); 14869 var ObjFormCpnt = new _camiers_js_components_form_cpnt__WEBPACK_IMPORTED_MODULE_4__["FormCpnt"](); 14870 var ObjBrochureCpnt = new _camiers_js_components_brochure_cpnt__WEBPACK_IMPORTED_MODULE_5__["BrochureCpnt"](); 14871 var ObjMapCpnt = new _camiers_js_components_map_cpnt__WEBPACK_IMPORTED_MODULE_6__["MapCpnt"](); 14872 var ObjWeatherCpnt = new _camiers_js_components_weather_cpnt__WEBPACK_IMPORTED_MODULE_7__["WeatherCpnt"](); 14873 var ObjTideCpnt = new _camiers_js_components_tide_cpnt__WEBPACK_IMPORTED_MODULE_8__["TideCpnt"](); 14874 var ObjSliderCpnt = new _camiers_js_components_slider_cpnt__WEBPACK_IMPORTED_MODULE_9__["SliderCpnt"](); 14875 var ObjEngineJomeCpnt = new _camiers_js_components_engine_home_cpnt__WEBPACK_IMPORTED_MODULE_10__["EngineHomeCpnt"](); 14876}); 14877 14878/***/ }), 14879
14880/***/ "./wp-content/themes/camiers/assets/src/js/bootstrap.bundle.js": 14881/*!*********************************************************************!*\ 14882 !*** ./wp-content/themes/camiers/assets/src/js/bootstrap.bundle.js ***! 14883 \*********************************************************************/ 14884/*! no static exports found */ 14885/***/ (function(module, exports, __webpack_require__) { 14886 14887/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;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); } 14888 14889/*! 14890 * Bootstrap v4.1.1 (https://getbootstrap.com/) 14891 * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 14892 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 14893 */ 14894(function (global, factory) { 14895 ( false ? undefined : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? factory(exports, __webpack_require__(/*! jquery */ "jquery")) : true ? !(__WEBPACK_AMD_DEFINE_ARRAY__ = [exports, __webpack_require__(/*! jquery */ "jquery")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 14896 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 14897 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 14898 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)) : undefined; 14899})(this, function (exports, $) { 14900 'use strict'; 14901 14902 $ = $ && $.hasOwnProperty('default') ? $['default'] : $; 14903 14904 function _defineProperties(target, props) { 14905 for (var i = 0; i < props.length; i++) { 14906 var descriptor = props[i]; 14907 descriptor.enumerable = descriptor.enumerable || false; 14908 descriptor.configurable = true; 14909 if ("value" in descriptor) descriptor.writable = true; 14910 Object.defineProperty(target, descriptor.key, descriptor); 14911 } 14912 } 14913 14914 function _createClass(Constructor, protoProps, staticProps) { 14915 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 14916 if (staticProps) _defineProperties(Constructor, staticProps); 14917 return Constructor; 14918 } 14919 14920 function _defineProperty(obj, key, value) { 14921 if (key in obj) { 14922 Object.defineProperty(obj, key, { 14923 value: value, 14924 enumerable: true, 14925 configurable: true, 14926 writable: true 14927 }); 14928 } else { 14929 obj[key] = value; 14930 } 14931 14932 return obj; 14933 } 14934 14935 function _objectSpread(target) { 14936 for (var i = 1; i < arguments.length; i++) { 14937 var source = arguments[i] != null ? arguments[i] : {}; 14938 var ownKeys = Object.keys(source); 14939 14940 if (typeof Object.getOwnPropertySymbols === 'function') { 14941 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { 14942 return Object.getOwnPropertyDescriptor(source, sym).enumerable; 14943 })); 14944 } 14945 14946 ownKeys.forEach(function (key) { 14947 _defineProperty(target, key, source[key]); 14948 }); 14949 } 14950 14951 return target; 14952 } 14953 14954 function _inheritsLoose(subClass, superClass) { 14955 subClass.prototype = Object.create(superClass.prototype); 14956 subClass.prototype.constructor = subClass; 14957 subClass.__proto__ = superClass; 14958 } 14959 /** 14960 * -------------------------------------------------------------------------- 14961 * Bootstrap (v4.1.1): util.js 14962 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 14963 * -------------------------------------------------------------------------- 14964 */ 14965 14966 14967 var Util = function ($$$1) { 14968 /** 14969 * ------------------------------------------------------------------------ 14970 * Private TransitionEnd Helpers 14971 * ------------------------------------------------------------------------ 14972 */ 14973 var TRANSITION_END = 'transitionend'; 14974 var MAX_UID = 1000000; 14975 var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp) 14976 14977 function toType(obj) { 14978 return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase(); 14979 } 14980 14981 function getSpecialTransitionEndEvent() { 14982 return { 14983 bindType: TRANSITION_END, 14984 delegateType: TRANSITION_END, 14985 handle: function handle(event) { 14986 if ($$$1(event.target).is(this)) { 14987 return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params 14988 } 14989 14990 return undefined; // eslint-disable-line no-undefined 14991 } 14992 }; 14993 } 14994 14995 function transitionEndEmulator(duration) { 14996 var _this = this; 14997 14998 var called = false;
14999 $$$1(this).one(Util.TRANSITION_END, function () { 15000 called = true; 15001 }); 15002 setTimeout(function () { 15003 if (!called) { 15004 Util.triggerTransitionEnd(_this); 15005 } 15006 }, duration); 15007 return this; 15008 } 15009 15010 function setTransitionEndSupport() { 15011 $$$1.fn.emulateTransitionEnd = transitionEndEmulator; 15012 $$$1.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent(); 15013 } 15014 /** 15015 * -------------------------------------------------------------------------- 15016 * Public Util Api 15017 * -------------------------------------------------------------------------- 15018 */ 15019 15020 15021 var Util = { 15022 TRANSITION_END: 'bsTransitionEnd', 15023 getUID: function getUID(prefix) { 15024 do { 15025 // eslint-disable-next-line no-bitwise 15026 prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here 15027 } while (document.getElementById(prefix)); 15028 15029 return prefix; 15030 }, 15031 getSelectorFromElement: function getSelectorFromElement(element) { 15032 var selector = element.getAttribute('data-target'); 15033 15034 if (!selector || selector === '#') { 15035 selector = element.getAttribute('href') || ''; 15036 } 15037 15038 try { 15039 var $selector = $$$1(document).find(selector); 15040 return $selector.length > 0 ? selector : null; 15041 } catch (err) { 15042 return null; 15043 } 15044 }, 15045 getTransitionDurationFromElement: function getTransitionDurationFromElement(element) { 15046 if (!element) { 15047 return 0; 15048 } // Get transition-duration of the element 15049 15050 15051 var transitionDuration = $$$1(element).css('transition-duration'); 15052 var floatTransitionDuration = parseFloat(transitionDuration); // Return 0 if element or transition duration is not found 15053 15054 if (!floatTransitionDuration) { 15055 return 0; 15056 } // If multiple durations are defined, take the first 15057 15058 15059 transitionDuration = transitionDuration.split(',')[0]; 15060 return parseFloat(transitionDuration) * MILLISECONDS_MULTIPLIER; 15061 }, 15062 reflow: function reflow(element) { 15063 return element.offsetHeight; 15064 }, 15065 triggerTransitionEnd: function triggerTransitionEnd(element) { 15066 $$$1(element).trigger(TRANSITION_END); 15067 }, 15068 // TODO: Remove in v5 15069 supportsTransitionEnd: function supportsTransitionEnd() { 15070 return Boolean(TRANSITION_END); 15071 }, 15072 isElement: function isElement(obj) { 15073 return (obj[0] || obj).nodeType; 15074 }, 15075 typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) { 15076 for (var property in configTypes) { 15077 if (Object.prototype.hasOwnProperty.call(configTypes, property)) { 15078 var expectedTypes = configTypes[property]; 15079 var value = config[property]; 15080 var valueType = value && Util.isElement(value) ? 'element' : toType(value); 15081 15082 if (!new RegExp(expectedTypes).test(valueType)) { 15083 throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\".")); 15084 } 15085 } 15086 } 15087 } 15088 }; 15089 setTransitionEndSupport(); 15090 return Util; 15091 }($); 15092 /** 15093 * -------------------------------------------------------------------------- 15094 * Bootstrap (v4.1.1): alert.js 15095 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 15096 * -------------------------------------------------------------------------- 15097 */ 15098 15099 15100 var Alert = function ($$$1) { 15101 /** 15102 * ------------------------------------------------------------------------ 15103 * Constants 15104 * ------------------------------------------------------------------------ 15105 */ 15106 var NAME = 'alert'; 15107 var VERSION = '4.1.1'; 15108 var DATA_KEY = 'bs.alert'; 15109 var EVENT_KEY = "." + DATA_KEY; 15110 var DATA_API_KEY = '.data-api'; 15111 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 15112 var Selector = { 15113 DISMISS: '[data-dismiss="alert"]' 15114 }; 15115 var Event = { 15116 CLOSE: "close" + EVENT_KEY, 15117 CLOSED: "closed" + EVENT_KEY, 15118 CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY 15119 }; 15120 var ClassName = { 15121 ALERT: 'alert', 15122 FADE: 'fade', 15123 SHOW: 'show' 15124 /** 15125 * ------------------------------------------------------------------------ 15126 * Class Definition 15127 * ------------------------------------------------------------------------ 15128 */ 15129 15130 }; 15131 15132 var Alert = 15133 /*#__PURE__*/ 15134 function () { 15135 function Alert(element) { 15136 this._element = element; 15137 } // Getters 15138 15139 15140 var _proto = Alert.prototype; // Public 15141 15142 _proto.close = function close(element) { 15143 var rootElement = this._element; 15144 15145 if (element) { 15146 rootElement = this._getRootElement(element); 15147 } 15148 15149 var customEvent = this._triggerCloseEvent(rootElement); 15150 15151 if (customEvent.isDefaultPrevented()) { 15152 return; 15153 } 15154 15155 this._removeElement(rootElement); 15156 }; 15157 15158 _proto.dispose = function dispose() { 15159 $$$1.removeData(this._element, DATA_KEY); 15160 this._element = null; 15161 }; // Private 15162 15163 15164 _proto._getRootElement = function _getRootElement(element) { 15165 var selector = Util.getSelectorFromElement(element); 15166 var parent = false;
15167 15168 if (selector) { 15169 parent = $$$1(selector)[0]; 15170 } 15171 15172 if (!parent) { 15173 parent = $$$1(element).closest("." + ClassName.ALERT)[0]; 15174 } 15175 15176 return parent; 15177 }; 15178 15179 _proto._triggerCloseEvent = function _triggerCloseEvent(element) { 15180 var closeEvent = $$$1.Event(Event.CLOSE); 15181 $$$1(element).trigger(closeEvent); 15182 return closeEvent; 15183 }; 15184 15185 _proto._removeElement = function _removeElement(element) { 15186 var _this = this; 15187 15188 $$$1(element).removeClass(ClassName.SHOW); 15189 15190 if (!$$$1(element).hasClass(ClassName.FADE)) { 15191 this._destroyElement(element); 15192 15193 return; 15194 } 15195 15196 var transitionDuration = Util.getTransitionDurationFromElement(element); 15197 $$$1(element).one(Util.TRANSITION_END, function (event) { 15198 return _this._destroyElement(element, event); 15199 }).emulateTransitionEnd(transitionDuration); 15200 }; 15201 15202 _proto._destroyElement = function _destroyElement(element) { 15203 $$$1(element).detach().trigger(Event.CLOSED).remove(); 15204 }; // Static 15205 15206 15207 Alert._jQueryInterface = function _jQueryInterface(config) { 15208 return this.each(function () { 15209 var $element = $$$1(this); 15210 var data = $element.data(DATA_KEY); 15211 15212 if (!data) { 15213 data = new Alert(this); 15214 $element.data(DATA_KEY, data); 15215 } 15216 15217 if (config === 'close') { 15218 data[config](this); 15219 } 15220 }); 15221 }; 15222 15223 Alert._handleDismiss = function _handleDismiss(alertInstance) { 15224 return function (event) { 15225 if (event) { 15226 event.preventDefault(); 15227 } 15228 15229 alertInstance.close(this); 15230 }; 15231 }; 15232 15233 _createClass(Alert, null, [{ 15234 key: "VERSION", 15235 get: function get() { 15236 return VERSION; 15237 } 15238 }]); 15239 15240 return Alert; 15241 }(); 15242 /** 15243 * ------------------------------------------------------------------------ 15244 * Data Api implementation 15245 * ------------------------------------------------------------------------ 15246 */ 15247 15248 15249 $$$1(document).on(Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert())); 15250 /** 15251 * ------------------------------------------------------------------------ 15252 * jQuery 15253 * ------------------------------------------------------------------------ 15254 */ 15255 15256 $$$1.fn[NAME] = Alert._jQueryInterface; 15257 $$$1.fn[NAME].Constructor = Alert; 15258 15259 $$$1.fn[NAME].noConflict = function () { 15260 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 15261 return Alert._jQueryInterface; 15262 }; 15263 15264 return Alert; 15265 }($); 15266 /** 15267 * -------------------------------------------------------------------------- 15268 * Bootstrap (v4.1.1): button.js 15269 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 15270 * -------------------------------------------------------------------------- 15271 */ 15272 15273 15274 var Button = function ($$$1) { 15275 /** 15276 * ------------------------------------------------------------------------ 15277 * Constants 15278 * ------------------------------------------------------------------------ 15279 */ 15280 var NAME = 'button'; 15281 var VERSION = '4.1.1'; 15282 var DATA_KEY = 'bs.button'; 15283 var EVENT_KEY = "." + DATA_KEY; 15284 var DATA_API_KEY = '.data-api'; 15285 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 15286 var ClassName = { 15287 ACTIVE: 'active', 15288 BUTTON: 'btn', 15289 FOCUS: 'focus' 15290 }; 15291 var Selector = { 15292 DATA_TOGGLE_CARROT: '[data-toggle^="button"]', 15293 DATA_TOGGLE: '[data-toggle="buttons"]', 15294 INPUT: 'input', 15295 ACTIVE: '.active', 15296 BUTTON: '.btn' 15297 }; 15298 var Event = { 15299 CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY, 15300 FOCUS_BLUR_DATA_API: "focus" + EVENT_KEY + DATA_API_KEY + " " + ("blur" + EVENT_KEY + DATA_API_KEY) 15301 /** 15302 * ------------------------------------------------------------------------ 15303 * Class Definition 15304 * ------------------------------------------------------------------------ 15305 */ 15306 15307 }; 15308 15309 var Button = 15310 /*#__PURE__*/ 15311 function () { 15312 function Button(element) { 15313 this._element = element; 15314 } // Getters 15315 15316 15317 var _proto = Button.prototype; // Public 15318
vendor: 5,659 bytes, lines 15319-15500
15319 _proto.toggle = function toggle() { 15320 var triggerChangeEvent = true; 15321 var addAriaPressed = true; 15322 var rootElement = $$$1(this._element).closest(Selector.DATA_TOGGLE)[0]; 15323 15324 if (rootElement) { 15325 var input = $$$1(this._element).find(Selector.INPUT)[0]; 15326 15327 if (input) { 15328 if (input.type === 'radio') { 15329 if (input.checked && $$$1(this._element).hasClass(ClassName.ACTIVE)) { 15330 triggerChangeEvent = false; 15331 } else { 15332 var activeElement = $$$1(rootElement).find(Selector.ACTIVE)[0]; 15333 15334 if (activeElement) { 15335 $$$1(activeElement).removeClass(ClassName.ACTIVE); 15336 } 15337 } 15338 } 15339 15340 if (triggerChangeEvent) { 15341 if (input.hasAttribute('disabled') || rootElement.hasAttribute('disabled') || input.classList.contains('disabled') || rootElement.classList.contains('disabled')) { 15342 return; 15343 } 15344 15345 input.checked = !$$$1(this._element).hasClass(ClassName.ACTIVE); 15346 $$$1(input).trigger('change'); 15347 } 15348 15349 input.focus(); 15350 addAriaPressed = false; 15351 } 15352 } 15353 15354 if (addAriaPressed) { 15355 this._element.setAttribute('aria-pressed', !$$$1(this._element).hasClass(ClassName.ACTIVE)); 15356 } 15357 15358 if (triggerChangeEvent) { 15359 $$$1(this._element).toggleClass(ClassName.ACTIVE); 15360 } 15361 }; 15362 15363 _proto.dispose = function dispose() { 15364 $$$1.removeData(this._element, DATA_KEY); 15365 this._element = null; 15366 }; // Static 15367 15368 15369 Button._jQueryInterface = function _jQueryInterface(config) { 15370 return this.each(function () { 15371 var data = $$$1(this).data(DATA_KEY); 15372 15373 if (!data) { 15374 data = new Button(this); 15375 $$$1(this).data(DATA_KEY, data); 15376 } 15377 15378 if (config === 'toggle') { 15379 data[config](); 15380 } 15381 }); 15382 }; 15383 15384 _createClass(Button, null, [{ 15385 key: "VERSION", 15386 get: function get() { 15387 return VERSION; 15388 } 15389 }]); 15390 15391 return Button; 15392 }(); 15393 /** 15394 * ------------------------------------------------------------------------ 15395 * Data Api implementation 15396 * ------------------------------------------------------------------------ 15397 */ 15398 15399 15400 $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) { 15401 event.preventDefault(); 15402 var button = event.target; 15403 15404 if (!$$$1(button).hasClass(ClassName.BUTTON)) { 15405 button = $$$1(button).closest(Selector.BUTTON); 15406 } 15407 15408 Button._jQueryInterface.call($$$1(button), 'toggle'); 15409 }).on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) { 15410 var button = $$$1(event.target).closest(Selector.BUTTON)[0]; 15411 $$$1(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type)); 15412 }); 15413 /** 15414 * ------------------------------------------------------------------------ 15415 * jQuery 15416 * ------------------------------------------------------------------------ 15417 */ 15418 15419 $$$1.fn[NAME] = Button._jQueryInterface; 15420 $$$1.fn[NAME].Constructor = Button; 15421 15422 $$$1.fn[NAME].noConflict = function () { 15423 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 15424 return Button._jQueryInterface; 15425 }; 15426 15427 return Button; 15428 }($); 15429 /** 15430 * -------------------------------------------------------------------------- 15431 * Bootstrap (v4.1.1): carousel.js 15432 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 15433 * -------------------------------------------------------------------------- 15434 */ 15435 15436 15437 var Carousel = function ($$$1) { 15438 /** 15439 * ------------------------------------------------------------------------ 15440 * Constants 15441 * ------------------------------------------------------------------------ 15442 */ 15443 var NAME = 'carousel'; 15444 var VERSION = '4.1.1'; 15445 var DATA_KEY = 'bs.carousel'; 15446 var EVENT_KEY = "." + DATA_KEY; 15447 var DATA_API_KEY = '.data-api'; 15448 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 15449 var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key 15450 15451 var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key 15452 15453 var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch 15454 15455 var Default = { 15456 interval: 5000, 15457 keyboard: true, 15458 slide: false, 15459 pause: 'hover', 15460 wrap: true 15461 }; 15462 var DefaultType = { 15463 interval: '(number|boolean)', 15464 keyboard: 'boolean', 15465 slide: '(boolean|string)', 15466 pause: '(string|boolean)', 15467 wrap: 'boolean' 15468 }; 15469 var Direction = { 15470 NEXT: 'next', 15471 PREV: 'prev', 15472 LEFT: 'left', 15473 RIGHT: 'right' 15474 }; 15475 var Event = { 15476 SLIDE: "slide" + EVENT_KEY, 15477 SLID: "slid" + EVENT_KEY, 15478 KEYDOWN: "keydown" + EVENT_KEY, 15479 MOUSEENTER: "mouseenter" + EVENT_KEY, 15480 MOUSELEAVE: "mouseleave" + EVENT_KEY, 15481 TOUCHEND: "touchend" + EVENT_KEY, 15482 LOAD_DATA_API: "load" + EVENT_KEY + DATA_API_KEY, 15483 CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY 15484 }; 15485 var ClassName = { 15486 CAROUSEL: 'carousel', 15487 ACTIVE: 'active', 15488 SLIDE: 'slide', 15489 RIGHT: 'carousel-item-right', 15490 LEFT: 'carousel-item-left', 15491 NEXT: 'carousel-item-next', 15492 PREV: 'carousel-item-prev', 15493 ITEM: 'carousel-item' 15494 }; 15495 var Selector = { 15496 ACTIVE: '.active', 15497 ACTIVE_ITEM: '.active.carousel-item', 15498 ITEM: '.carousel-item', 15499 NEXT_PREV: '.carousel-item-next, .carousel-item-prev', 15500 INDICATORS: '.carousel-indicators',
15501 DATA_SLIDE: '[data-slide], [data-slide-to]', 15502 DATA_RIDE: '[data-ride="carousel"]' 15503 /** 15504 * ------------------------------------------------------------------------ 15505 * Class Definition 15506 * ------------------------------------------------------------------------ 15507 */ 15508 15509 }; 15510 15511 var Carousel = 15512 /*#__PURE__*/ 15513 function () { 15514 function Carousel(element, config) { 15515 this._items = null; 15516 this._interval = null; 15517 this._activeElement = null; 15518 this._isPaused = false; 15519 this._isSliding = false; 15520 this.touchTimeout = null; 15521 this._config = this._getConfig(config); 15522 this._element = $$$1(element)[0]; 15523 this._indicatorsElement = $$$1(this._element).find(Selector.INDICATORS)[0]; 15524 15525 this._addEventListeners(); 15526 } // Getters 15527 15528 15529 var _proto = Carousel.prototype; // Public 15530 15531 _proto.next = function next() { 15532 if (!this._isSliding) { 15533 this._slide(Direction.NEXT); 15534 } 15535 }; 15536 15537 _proto.nextWhenVisible = function nextWhenVisible() { 15538 // Don't call next when the page isn't visible 15539 // or the carousel or its parent isn't visible 15540 if (!document.hidden && $$$1(this._element).is(':visible') && $$$1(this._element).css('visibility') !== 'hidden') { 15541 this.next(); 15542 } 15543 }; 15544 15545 _proto.prev = function prev() { 15546 if (!this._isSliding) { 15547 this._slide(Direction.PREV); 15548 } 15549 }; 15550 15551 _proto.pause = function pause(event) { 15552 if (!event) { 15553 this._isPaused = true; 15554 } 15555 15556 if ($$$1(this._element).find(Selector.NEXT_PREV)[0]) { 15557 Util.triggerTransitionEnd(this._element); 15558 this.cycle(true); 15559 } 15560 15561 clearInterval(this._interval); 15562 this._interval = null; 15563 }; 15564 15565 _proto.cycle = function cycle(event) { 15566 if (!event) { 15567 this._isPaused = false; 15568 } 15569 15570 if (this._interval) { 15571 clearInterval(this._interval); 15572 this._interval = null; 15573 } 15574 15575 if (this._config.interval && !this._isPaused) { 15576 this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval); 15577 } 15578 }; 15579 15580 _proto.to = function to(index) { 15581 var _this = this; 15582 15583 this._activeElement = $$$1(this._element).find(Selector.ACTIVE_ITEM)[0]; 15584 15585 var activeIndex = this._getItemIndex(this._activeElement); 15586 15587 if (index > this._items.length - 1 || index < 0) { 15588 return; 15589 } 15590 15591 if (this._isSliding) { 15592 $$$1(this._element).one(Event.SLID, function () { 15593 return _this.to(index); 15594 }); 15595 return; 15596 } 15597 15598 if (activeIndex === index) { 15599 this.pause(); 15600 this.cycle(); 15601 return; 15602 } 15603 15604 var direction = index > activeIndex ? Direction.NEXT : Direction.PREV; 15605 15606 this._slide(direction, this._items[index]); 15607 }; 15608 15609 _proto.dispose = function dispose() { 15610 $$$1(this._element).off(EVENT_KEY); 15611 $$$1.removeData(this._element, DATA_KEY); 15612 this._items = null; 15613 this._config = null; 15614 this._element = null; 15615 this._interval = null; 15616 this._isPaused = null; 15617 this._isSliding = null; 15618 this._activeElement = null; 15619 this._indicatorsElement = null; 15620 }; // Private 15621 15622 15623 _proto._getConfig = function _getConfig(config) { 15624 config = _objectSpread({}, Default, config); 15625 Util.typeCheckConfig(NAME, config, DefaultType); 15626 return config; 15627 }; 15628 15629 _proto._addEventListeners = function _addEventListeners() { 15630 var _this2 = this; 15631 15632 if (this._config.keyboard) { 15633 $$$1(this._element).on(Event.KEYDOWN, function (event) { 15634 return _this2._keydown(event); 15635 }); 15636 } 15637 15638 if (this._config.pause === 'hover') { 15639 $$$1(this._element).on(Event.MOUSEENTER, function (event) { 15640 return _this2.pause(event); 15641 }).on(Event.MOUSELEAVE, function (event) { 15642 return _this2.cycle(event); 15643 }); 15644 15645 if ('ontouchstart' in document.documentElement) {
15646 // If it's a touch-enabled device, mouseenter/leave are fired as 15647 // part of the mouse compatibility events on first tap - the carousel 15648 // would stop cycling until user tapped out of it; 15649 // here, we listen for touchend, explicitly pause the carousel 15650 // (as if it's the second time we tap on it, mouseenter compat event 15651 // is NOT fired) and after a timeout (to allow for mouse compatibility 15652 // events to fire) we explicitly restart cycling 15653 $$$1(this._element).on(Event.TOUCHEND, function () { 15654 _this2.pause(); 15655 15656 if (_this2.touchTimeout) { 15657 clearTimeout(_this2.touchTimeout); 15658 } 15659 15660 _this2.touchTimeout = setTimeout(function (event) { 15661 return _this2.cycle(event); 15662 }, TOUCHEVENT_COMPAT_WAIT + _this2._config.interval); 15663 }); 15664 } 15665 } 15666 }; 15667 15668 _proto._keydown = function _keydown(event) { 15669 if (/input|textarea/i.test(event.target.tagName)) { 15670 return; 15671 } 15672 15673 switch (event.which) { 15674 case ARROW_LEFT_KEYCODE: 15675 event.preventDefault(); 15676 this.prev(); 15677 break; 15678 15679 case ARROW_RIGHT_KEYCODE: 15680 event.preventDefault(); 15681 this.next(); 15682 break; 15683 15684 default: 15685 } 15686 }; 15687 15688 _proto._getItemIndex = function _getItemIndex(element) { 15689 this._items = $$$1.makeArray($$$1(element).parent().find(Selector.ITEM)); 15690 return this._items.indexOf(element); 15691 }; 15692 15693 _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) { 15694 var isNextDirection = direction === Direction.NEXT; 15695 var isPrevDirection = direction === Direction.PREV; 15696 15697 var activeIndex = this._getItemIndex(activeElement); 15698 15699 var lastItemIndex = this._items.length - 1; 15700 var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex; 15701 15702 if (isGoingToWrap && !this._config.wrap) { 15703 return activeElement; 15704 } 15705 15706 var delta = direction === Direction.PREV ? -1 : 1; 15707 var itemIndex = (activeIndex + delta) % this._items.length; 15708 return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex]; 15709 }; 15710 15711 _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) { 15712 var targetIndex = this._getItemIndex(relatedTarget); 15713 15714 var fromIndex = this._getItemIndex($$$1(this._element).find(Selector.ACTIVE_ITEM)[0]); 15715 15716 var slideEvent = $$$1.Event(Event.SLIDE, { 15717 relatedTarget: relatedTarget, 15718 direction: eventDirectionName, 15719 from: fromIndex, 15720 to: targetIndex 15721 }); 15722 $$$1(this._element).trigger(slideEvent); 15723 return slideEvent; 15724 }; 15725 15726 _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) { 15727 if (this._indicatorsElement) { 15728 $$$1(this._indicatorsElement).find(Selector.ACTIVE).removeClass(ClassName.ACTIVE); 15729 15730 var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)]; 15731 15732 if (nextIndicator) { 15733 $$$1(nextIndicator).addClass(ClassName.ACTIVE); 15734 } 15735 } 15736 }; 15737 15738 _proto._slide = function _slide(direction, element) { 15739 var _this3 = this; 15740 15741 var activeElement = $$$1(this._element).find(Selector.ACTIVE_ITEM)[0]; 15742 15743 var activeElementIndex = this._getItemIndex(activeElement); 15744 15745 var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement); 15746 15747 var nextElementIndex = this._getItemIndex(nextElement); 15748 15749 var isCycling = Boolean(this._interval); 15750 var directionalClassName; 15751 var orderClassName; 15752 var eventDirectionName; 15753 15754 if (direction === Direction.NEXT) { 15755 directionalClassName = ClassName.LEFT; 15756 orderClassName = ClassName.NEXT; 15757 eventDirectionName = Direction.LEFT; 15758 } else { 15759 directionalClassName = ClassName.RIGHT; 15760 orderClassName = ClassName.PREV; 15761 eventDirectionName = Direction.RIGHT; 15762 } 15763 15764 if (nextElement && $$$1(nextElement).hasClass(ClassName.ACTIVE)) { 15765 this._isSliding = false;
15766 return; 15767 } 15768 15769 var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName); 15770 15771 if (slideEvent.isDefaultPrevented()) { 15772 return; 15773 } 15774 15775 if (!activeElement || !nextElement) { 15776 // Some weirdness is happening, so we bail 15777 return; 15778 } 15779 15780 this._isSliding = true; 15781 15782 if (isCycling) { 15783 this.pause(); 15784 } 15785 15786 this._setActiveIndicatorElement(nextElement); 15787 15788 var slidEvent = $$$1.Event(Event.SLID, { 15789 relatedTarget: nextElement, 15790 direction: eventDirectionName, 15791 from: activeElementIndex, 15792 to: nextElementIndex 15793 }); 15794 15795 if ($$$1(this._element).hasClass(ClassName.SLIDE)) { 15796 $$$1(nextElement).addClass(orderClassName); 15797 Util.reflow(nextElement); 15798 $$$1(activeElement).addClass(directionalClassName); 15799 $$$1(nextElement).addClass(directionalClassName); 15800 var transitionDuration = Util.getTransitionDurationFromElement(activeElement); 15801 $$$1(activeElement).one(Util.TRANSITION_END, function () { 15802 $$$1(nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(ClassName.ACTIVE); 15803 $$$1(activeElement).removeClass(ClassName.ACTIVE + " " + orderClassName + " " + directionalClassName); 15804 _this3._isSliding = false; 15805 setTimeout(function () { 15806 return $$$1(_this3._element).trigger(slidEvent); 15807 }, 0); 15808 }).emulateTransitionEnd(transitionDuration); 15809 } else { 15810 $$$1(activeElement).removeClass(ClassName.ACTIVE); 15811 $$$1(nextElement).addClass(ClassName.ACTIVE); 15812 this._isSliding = false; 15813 $$$1(this._element).trigger(slidEvent); 15814 } 15815 15816 if (isCycling) { 15817 this.cycle(); 15818 } 15819 }; // Static 15820 15821 15822 Carousel._jQueryInterface = function _jQueryInterface(config) { 15823 return this.each(function () { 15824 var data = $$$1(this).data(DATA_KEY); 15825 15826 var _config = _objectSpread({}, Default, $$$1(this).data()); 15827 15828 if (_typeof(config) === 'object') { 15829 _config = _objectSpread({}, _config, config); 15830 } 15831 15832 var action = typeof config === 'string' ? config : _config.slide; 15833 15834 if (!data) { 15835 data = new Carousel(this, _config); 15836 $$$1(this).data(DATA_KEY, data); 15837 } 15838 15839 if (typeof config === 'number') { 15840 data.to(config); 15841 } else if (typeof action === 'string') { 15842 if (typeof data[action] === 'undefined') { 15843 throw new TypeError("No method named \"" + action + "\""); 15844 } 15845 15846 data[action](); 15847 } else if (_config.interval) { 15848 data.pause(); 15849 data.cycle(); 15850 } 15851 }); 15852 }; 15853 15854 Carousel._dataApiClickHandler = function _dataApiClickHandler(event) { 15855 var selector = Util.getSelectorFromElement(this); 15856 15857 if (!selector) { 15858 return; 15859 } 15860 15861 var target = $$$1(selector)[0]; 15862 15863 if (!target || !$$$1(target).hasClass(ClassName.CAROUSEL)) { 15864 return; 15865 } 15866 15867 var config = _objectSpread({}, $$$1(target).data(), $$$1(this).data()); 15868 15869 var slideIndex = this.getAttribute('data-slide-to'); 15870 15871 if (slideIndex) { 15872 config.interval = false; 15873 } 15874 15875 Carousel._jQueryInterface.call($$$1(target), config); 15876 15877 if (slideIndex) { 15878 $$$1(target).data(DATA_KEY).to(slideIndex); 15879 } 15880 15881 event.preventDefault(); 15882 }; 15883 15884 _createClass(Carousel, null, [{ 15885 key: "VERSION", 15886 get: function get() { 15887 return VERSION; 15888 } 15889 }, { 15890 key: "Default", 15891 get: function get() { 15892 return Default; 15893 } 15894 }]); 15895 15896 return Carousel; 15897 }(); 15898 /** 15899 * ------------------------------------------------------------------------ 15900 * Data Api implementation 15901 * ------------------------------------------------------------------------ 15902 */ 15903 15904 15905 $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler); 15906 $$$1(window).on(Event.LOAD_DATA_API, function () { 15907 $$$1(Selector.DATA_RIDE).each(function () { 15908 var $carousel = $$$1(this); 15909
15910 Carousel._jQueryInterface.call($carousel, $carousel.data()); 15911 }); 15912 }); 15913 /** 15914 * ------------------------------------------------------------------------ 15915 * jQuery 15916 * ------------------------------------------------------------------------ 15917 */ 15918 15919 $$$1.fn[NAME] = Carousel._jQueryInterface; 15920 $$$1.fn[NAME].Constructor = Carousel; 15921 15922 $$$1.fn[NAME].noConflict = function () { 15923 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 15924 return Carousel._jQueryInterface; 15925 }; 15926 15927 return Carousel; 15928 }($); 15929 /** 15930 * -------------------------------------------------------------------------- 15931 * Bootstrap (v4.1.1): collapse.js 15932 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 15933 * -------------------------------------------------------------------------- 15934 */ 15935 15936 15937 var Collapse = function ($$$1) { 15938 /** 15939 * ------------------------------------------------------------------------ 15940 * Constants 15941 * ------------------------------------------------------------------------ 15942 */ 15943 var NAME = 'collapse'; 15944 var VERSION = '4.1.1'; 15945 var DATA_KEY = 'bs.collapse'; 15946 var EVENT_KEY = "." + DATA_KEY; 15947 var DATA_API_KEY = '.data-api'; 15948 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 15949 var Default = { 15950 toggle: true, 15951 parent: '' 15952 }; 15953 var DefaultType = { 15954 toggle: 'boolean', 15955 parent: '(string|element)' 15956 }; 15957 var Event = { 15958 SHOW: "show" + EVENT_KEY, 15959 SHOWN: "shown" + EVENT_KEY, 15960 HIDE: "hide" + EVENT_KEY, 15961 HIDDEN: "hidden" + EVENT_KEY, 15962 CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY 15963 }; 15964 var ClassName = { 15965 SHOW: 'show', 15966 COLLAPSE: 'collapse', 15967 COLLAPSING: 'collapsing', 15968 COLLAPSED: 'collapsed' 15969 }; 15970 var Dimension = { 15971 WIDTH: 'width', 15972 HEIGHT: 'height' 15973 }; 15974 var Selector = { 15975 ACTIVES: '.show, .collapsing', 15976 DATA_TOGGLE: '[data-toggle="collapse"]' 15977 /** 15978 * ------------------------------------------------------------------------ 15979 * Class Definition 15980 * ------------------------------------------------------------------------ 15981 */ 15982 15983 }; 15984 15985 var Collapse = 15986 /*#__PURE__*/ 15987 function () { 15988 function Collapse(element, config) { 15989 this._isTransitioning = false; 15990 this._element = element; 15991 this._config = this._getConfig(config); 15992 this._triggerArray = $$$1.makeArray($$$1("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]"))); 15993 var tabToggles = $$$1(Selector.DATA_TOGGLE); 15994 15995 for (var i = 0; i < tabToggles.length; i++) { 15996 var elem = tabToggles[i]; 15997 var selector = Util.getSelectorFromElement(elem); 15998 15999 if (selector !== null && $$$1(selector).filter(element).length > 0) { 16000 this._selector = selector; 16001 16002 this._triggerArray.push(elem); 16003 } 16004 } 16005 16006 this._parent = this._config.parent ? this._getParent() : null; 16007 16008 if (!this._config.parent) { 16009 this._addAriaAndCollapsedClass(this._element, this._triggerArray); 16010 } 16011 16012 if (this._config.toggle) { 16013 this.toggle(); 16014 } 16015 } // Getters 16016 16017 16018 var _proto = Collapse.prototype; // Public 16019 16020 _proto.toggle = function toggle() { 16021 if ($$$1(this._element).hasClass(ClassName.SHOW)) { 16022 this.hide(); 16023 } else { 16024 this.show(); 16025 } 16026 }; 16027 16028 _proto.show = function show() { 16029 var _this = this; 16030 16031 if (this._isTransitioning || $$$1(this._element).hasClass(ClassName.SHOW)) { 16032 return; 16033 } 16034 16035 var actives; 16036 var activesData; 16037 16038 if (this._parent) { 16039 actives = $$$1.makeArray($$$1(this._parent).find(Selector.ACTIVES).filter("[data-parent=\"" + this._config.parent + "\"]")); 16040 16041 if (actives.length === 0) { 16042 actives = null; 16043 } 16044 } 16045 16046 if (actives) { 16047 activesData = $$$1(actives).not(this._selector).data(DATA_KEY); 16048 16049 if (activesData && activesData._isTransitioning) { 16050 return; 16051 } 16052 } 16053 16054 var startEvent = $$$1.Event(Event.SHOW); 16055 $$$1(this._element).trigger(startEvent); 16056 16057 if (startEvent.isDefaultPrevented()) { 16058 return; 16059 } 16060 16061 if (actives) { 16062 Collapse._jQueryInterface.call($$$1(actives).not(this._selector), 'hide'); 16063 16064 if (!activesData) { 16065 $$$1(actives).data(DATA_KEY, null); 16066 } 16067 } 16068 16069 var dimension = this._getDimension(); 16070 16071 $$$1(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING); 16072 this._element.style[dimension] = 0; 16073 16074 if (this._triggerArray.length > 0) { 16075 $$$1(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true); 16076 } 16077 16078 this.setTransitioning(true); 16079 16080 var complete = function complete() { 16081 $$$1(_this._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.SHOW); 16082 _this._element.style[dimension] = ''; 16083 16084 _this.setTransitioning(false); 16085 16086 $$$1(_this._element).trigger(Event.SHOWN); 16087 }; 16088 16089 var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); 16090 var scrollSize = "scroll" + capitalizedDimension; 16091 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 16092 $$$1(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 16093 this._element.style[dimension] = this._element[scrollSize] + "px"; 16094 }; 16095 16096 _proto.hide = function hide() { 16097 var _this2 = this; 16098 16099 if (this._isTransitioning || !$$$1(this._element).hasClass(ClassName.SHOW)) { 16100 return; 16101 } 16102 16103 var startEvent = $$$1.Event(Event.HIDE); 16104 $$$1(this._element).trigger(startEvent); 16105 16106 if (startEvent.isDefaultPrevented()) { 16107 return; 16108 } 16109 16110 var dimension = this._getDimension(); 16111 16112 this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px"; 16113 Util.reflow(this._element); 16114 $$$1(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW); 16115 16116 if (this._triggerArray.length > 0) { 16117 for (var i = 0; i < this._triggerArray.length; i++) { 16118 var trigger = this._triggerArray[i]; 16119 var selector = Util.getSelectorFromElement(trigger); 16120 16121 if (selector !== null) { 16122 var $elem = $$$1(selector); 16123 16124 if (!$elem.hasClass(ClassName.SHOW)) { 16125 $$$1(trigger).addClass(ClassName.COLLAPSED).attr('aria-expanded', false); 16126 } 16127 } 16128 } 16129 } 16130 16131 this.setTransitioning(true); 16132 16133 var complete = function complete() { 16134 _this2.setTransitioning(false); 16135 16136 $$$1(_this2._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN); 16137 }; 16138 16139 this._element.style[dimension] = ''; 16140 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 16141 $$$1(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 16142 }; 16143 16144 _proto.setTransitioning = function setTransitioning(isTransitioning) { 16145 this._isTransitioning = isTransitioning; 16146 }; 16147 16148 _proto.dispose = function dispose() { 16149 $$$1.removeData(this._element, DATA_KEY); 16150 this._config = null; 16151 this._parent = null; 16152 this._element = null; 16153 this._triggerArray = null; 16154 this._isTransitioning = null; 16155 }; // Private 16156 16157 16158 _proto._getConfig = function _getConfig(config) { 16159 config = _objectSpread({}, Default, config); 16160 config.toggle = Boolean(config.toggle); // Coerce string values 16161 16162 Util.typeCheckConfig(NAME, config, DefaultType); 16163 return config; 16164 }; 16165 16166 _proto._getDimension = function _getDimension() { 16167 var hasWidth = $$$1(this._element).hasClass(Dimension.WIDTH); 16168 return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT; 16169 }; 16170 16171 _proto._getParent = function _getParent() { 16172 var _this3 = this; 16173 16174 var parent = null; 16175 16176 if (Util.isElement(this._config.parent)) { 16177 parent = this._config.parent; // It's a jQuery object 16178 16179 if (typeof this._config.parent.jquery !== 'undefined') { 16180 parent = this._config.parent[0]; 16181 } 16182 } else { 16183 parent = $$$1(this._config.parent)[0]; 16184 } 16185 16186 var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]"; 16187 $$$1(parent).find(selector).each(function (i, element) { 16188 _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]); 16189 }); 16190 return parent; 16191 }; 16192 16193 _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) { 16194 if (element) { 16195 var isOpen = $$$1(element).hasClass(ClassName.SHOW); 16196 16197 if (triggerArray.length > 0) { 16198 $$$1(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen); 16199 } 16200 } 16201 }; // Static 16202 16203 16204 Collapse._getTargetFromElement = function _getTargetFromElement(element) { 16205 var selector = Util.getSelectorFromElement(element); 16206 return selector ? $$$1(selector)[0] : null; 16207 }; 16208 16209 Collapse._jQueryInterface = function _jQueryInterface(config) { 16210 return this.each(function () { 16211 var $this = $$$1(this); 16212 var data = $this.data(DATA_KEY); 16213 16214 var _config = _objectSpread({}, Default, $this.data(), _typeof(config) === 'object' && config ? config : {}); 16215 16216 if (!data && _config.toggle && /show|hide/.test(config)) { 16217 _config.toggle = false;
16218 } 16219 16220 if (!data) { 16221 data = new Collapse(this, _config); 16222 $this.data(DATA_KEY, data); 16223 } 16224 16225 if (typeof config === 'string') { 16226 if (typeof data[config] === 'undefined') { 16227 throw new TypeError("No method named \"" + config + "\""); 16228 } 16229 16230 data[config](); 16231 } 16232 }); 16233 }; 16234 16235 _createClass(Collapse, null, [{ 16236 key: "VERSION", 16237 get: function get() { 16238 return VERSION; 16239 } 16240 }, { 16241 key: "Default", 16242 get: function get() { 16243 return Default; 16244 } 16245 }]); 16246 16247 return Collapse; 16248 }(); 16249 /** 16250 * ------------------------------------------------------------------------ 16251 * Data Api implementation 16252 * ------------------------------------------------------------------------ 16253 */ 16254 16255 16256 $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { 16257 // preventDefault only for <a> elements (which change the URL) not inside the collapsible element 16258 if (event.currentTarget.tagName === 'A') { 16259 event.preventDefault(); 16260 } 16261 16262 var $trigger = $$$1(this); 16263 var selector = Util.getSelectorFromElement(this); 16264 $$$1(selector).each(function () { 16265 var $target = $$$1(this); 16266 var data = $target.data(DATA_KEY); 16267 var config = data ? 'toggle' : $trigger.data(); 16268 16269 Collapse._jQueryInterface.call($target, config); 16270 }); 16271 }); 16272 /** 16273 * ------------------------------------------------------------------------ 16274 * jQuery 16275 * ------------------------------------------------------------------------ 16276 */ 16277 16278 $$$1.fn[NAME] = Collapse._jQueryInterface; 16279 $$$1.fn[NAME].Constructor = Collapse; 16280 16281 $$$1.fn[NAME].noConflict = function () { 16282 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 16283 return Collapse._jQueryInterface; 16284 }; 16285 16286 return Collapse; 16287 }($); 16288 /**! 16289 * @fileOverview Kickass library to create and place poppers near their reference elements. 16290 * @version 1.14.3 16291 * @license 16292 * Copyright (c) 2016 Federico Zivolo and contributors 16293 * 16294 * Permission is hereby granted, free of charge, to any person obtaining a copy 16295 * of this software and associated documentation files (the "Software"), to deal 16296 * in the Software without restriction, including without limitation the rights 16297 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16298 * copies of the Software, and to permit persons to whom the Software is 16299 * furnished to do so, subject to the following conditions: 16300 * 16301 * The above copyright notice and this permission notice shall be included in all 16302 * copies or substantial portions of the Software. 16303 * 16304 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16305 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16306 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16307 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16308 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16309 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 16310 * SOFTWARE. 16311 */ 16312 16313 16314 var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'; 16315 var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; 16316 var timeoutDuration = 0; 16317 16318 for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) { 16319 if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { 16320 timeoutDuration = 1; 16321 break; 16322 } 16323 } 16324 16325 function microtaskDebounce(fn) { 16326 var called = false; 16327 return function () { 16328 if (called) { 16329 return; 16330 } 16331 16332 called = true; 16333 window.Promise.resolve().then(function () { 16334 called = false; 16335 fn(); 16336 }); 16337 }; 16338 } 16339 16340 function taskDebounce(fn) { 16341 var scheduled = false; 16342 return function () { 16343 if (!scheduled) { 16344 scheduled = true; 16345 setTimeout(function () { 16346 scheduled = false; 16347 fn(); 16348 }, timeoutDuration); 16349 } 16350 }; 16351 } 16352 16353 var supportsMicroTasks = isBrowser && window.Promise; 16354 /** 16355 * Create a debounced version of a method, that's asynchronously deferred 16356 * but called in the minimum time possible. 16357 * 16358 * @method 16359 * @memberof Popper.Utils 16360 * @argument {Function} fn 16361 * @returns {Function} 16362 */ 16363 16364 var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce; 16365 /** 16366 * Check if the given variable is a function 16367 * @method 16368 * @memberof Popper.Utils 16369 * @argument {Any} functionToCheck - variable to check 16370 * @returns {Boolean} answer to: is a function? 16371 */ 16372 16373 function isFunction(functionToCheck) { 16374 var getType = {}; 16375 return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; 16376 } 16377 /** 16378 * Get CSS computed property of the given element 16379 * @method 16380 * @memberof Popper.Utils 16381 * @argument {Eement} element 16382 * @argument {String} property 16383 */ 16384 16385 16386 function getStyleComputedProperty(element, property) { 16387 if (element.nodeType !== 1) { 16388 return []; 16389 } // NOTE: 1 DOM access here 16390 16391 16392 var css = getComputedStyle(element, null); 16393 return property ? css[property] : css; 16394 } 16395 /** 16396 * Returns the parentNode or the host of the element 16397 * @method 16398 * @memberof Popper.Utils 16399 * @argument {Element} element 16400 * @returns {Element} parent 16401 */ 16402 16403 16404 function getParentNode(element) { 16405 if (element.nodeName === 'HTML') { 16406 return element; 16407 } 16408 16409 return element.parentNode || element.host; 16410 } 16411 /** 16412 * Returns the scrolling parent of the given element 16413 * @method 16414 * @memberof Popper.Utils 16415 * @argument {Element} element 16416 * @returns {Element} scroll parent 16417 */ 16418 16419 16420 function getScrollParent(element) { 16421 // Return body, `getScroll` will take care to get the correct `scrollTop` from it 16422 if (!element) { 16423 return document.body; 16424 } 16425 16426 switch (element.nodeName) { 16427 case 'HTML': 16428 case 'BODY': 16429 return element.ownerDocument.body; 16430 16431 case '#document': 16432 return element.body; 16433 } // Firefox want us to check `-x` and `-y` variations as well 16434 16435 16436 var _getStyleComputedProp = getStyleComputedProperty(element), 16437 overflow = _getStyleComputedProp.overflow, 16438 overflowX = _getStyleComputedProp.overflowX, 16439 overflowY = _getStyleComputedProp.overflowY; 16440 16441 if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { 16442 return element; 16443 } 16444 16445 return getScrollParent(getParentNode(element)); 16446 } 16447 16448 var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode); 16449 var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent); 16450 /** 16451 * Determines if the browser is Internet Explorer 16452 * @method 16453 * @memberof Popper.Utils 16454 * @param {Number} version to check 16455 * @returns {Boolean} isIE 16456 */ 16457 16458 function isIE(version) { 16459 if (version === 11) { 16460 return isIE11; 16461 } 16462 16463 if (version === 10) { 16464 return isIE10; 16465 } 16466 16467 return isIE11 || isIE10; 16468 } 16469 /** 16470 * Returns the offset parent of the given element 16471 * @method 16472 * @memberof Popper.Utils 16473 * @argument {Element} element 16474 * @returns {Element} offset parent 16475 */ 16476 16477 16478 function getOffsetParent(element) { 16479 if (!element) { 16480 return document.documentElement; 16481 } 16482 16483 var noOffsetParent = isIE(10) ? document.body : null; // NOTE: 1 DOM access here 16484 16485 var offsetParent = element.offsetParent; // Skip hidden elements which don't have an offsetParent 16486 16487 while (offsetParent === noOffsetParent && element.nextElementSibling) { 16488 offsetParent = (element = element.nextElementSibling).offsetParent; 16489 } 16490
vendor: 11,802 bytes, lines 16491-16822
16491 var nodeName = offsetParent && offsetParent.nodeName; 16492 16493 if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { 16494 return element ? element.ownerDocument.documentElement : document.documentElement; 16495 } // .offsetParent will return the closest TD or TABLE in case 16496 // no offsetParent is present, I hate this job... 16497 16498 16499 if (['TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') { 16500 return getOffsetParent(offsetParent); 16501 } 16502 16503 return offsetParent; 16504 } 16505 16506 function isOffsetContainer(element) { 16507 var nodeName = element.nodeName; 16508 16509 if (nodeName === 'BODY') { 16510 return false; 16511 } 16512 16513 return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element; 16514 } 16515 /** 16516 * Finds the root node (document, shadowDOM root) of the given element 16517 * @method 16518 * @memberof Popper.Utils 16519 * @argument {Element} node 16520 * @returns {Element} root node 16521 */ 16522 16523 16524 function getRoot(node) { 16525 if (node.parentNode !== null) { 16526 return getRoot(node.parentNode); 16527 } 16528 16529 return node; 16530 } 16531 /** 16532 * Finds the offset parent common to the two provided nodes 16533 * @method 16534 * @memberof Popper.Utils 16535 * @argument {Element} element1 16536 * @argument {Element} element2 16537 * @returns {Element} common offset parent 16538 */ 16539 16540 16541 function findCommonOffsetParent(element1, element2) { 16542 // This check is needed to avoid errors in case one of the elements isn't defined for any reason 16543 if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { 16544 return document.documentElement; 16545 } // Here we make sure to give as "start" the element that comes first in the DOM 16546 16547 16548 var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; 16549 var start = order ? element1 : element2; 16550 var end = order ? element2 : element1; // Get common ancestor container 16551 16552 var range = document.createRange(); 16553 range.setStart(start, 0); 16554 range.setEnd(end, 0); 16555 var commonAncestorContainer = range.commonAncestorContainer; // Both nodes are inside #document 16556 16557 if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { 16558 if (isOffsetContainer(commonAncestorContainer)) { 16559 return commonAncestorContainer; 16560 } 16561 16562 return getOffsetParent(commonAncestorContainer); 16563 } // one of the nodes is inside shadowDOM, find which one 16564 16565 16566 var element1root = getRoot(element1); 16567 16568 if (element1root.host) { 16569 return findCommonOffsetParent(element1root.host, element2); 16570 } else { 16571 return findCommonOffsetParent(element1, getRoot(element2).host); 16572 } 16573 } 16574 /** 16575 * Gets the scroll value of the given element in the given side (top and left) 16576 * @method 16577 * @memberof Popper.Utils 16578 * @argument {Element} element 16579 * @argument {String} side `top` or `left` 16580 * @returns {number} amount of scrolled pixels 16581 */ 16582 16583 16584 function getScroll(element) { 16585 var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top'; 16586 var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; 16587 var nodeName = element.nodeName; 16588 16589 if (nodeName === 'BODY' || nodeName === 'HTML') { 16590 var html = element.ownerDocument.documentElement; 16591 var scrollingElement = element.ownerDocument.scrollingElement || html; 16592 return scrollingElement[upperSide]; 16593 } 16594 16595 return element[upperSide]; 16596 } 16597 /* 16598 * Sum or subtract the element scroll values (left and top) from a given rect object 16599 * @method 16600 * @memberof Popper.Utils 16601 * @param {Object} rect - Rect object you want to change 16602 * @param {HTMLElement} element - The element from the function reads the scroll values 16603 * @param {Boolean} subtract - set to true if you want to subtract the scroll values 16604 * @return {Object} rect - The modifier rect object 16605 */ 16606 16607 16608 function includeScroll(rect, element) { 16609 var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 16610 var scrollTop = getScroll(element, 'top'); 16611 var scrollLeft = getScroll(element, 'left'); 16612 var modifier = subtract ? -1 : 1; 16613 rect.top += scrollTop * modifier; 16614 rect.bottom += scrollTop * modifier; 16615 rect.left += scrollLeft * modifier; 16616 rect.right += scrollLeft * modifier; 16617 return rect; 16618 } 16619 /* 16620 * Helper to detect borders of a given element 16621 * @method 16622 * @memberof Popper.Utils 16623 * @param {CSSStyleDeclaration} styles 16624 * Result of `getStyleComputedProperty` on the given element 16625 * @param {String} axis - `x` or `y` 16626 * @return {number} borders - The borders size of the given axis 16627 */ 16628 16629 16630 function getBordersSize(styles, axis) { 16631 var sideA = axis === 'x' ? 'Left' : 'Top'; 16632 var sideB = sideA === 'Left' ? 'Right' : 'Bottom'; 16633 return parseFloat(styles['border' + sideA + 'Width'], 10) + parseFloat(styles['border' + sideB + 'Width'], 10); 16634 } 16635 16636 function getSize(axis, body, html, computedStyle) { 16637 return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? html['offset' + axis] + computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')] + computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')] : 0); 16638 } 16639 16640 function getWindowSizes() { 16641 var body = document.body; 16642 var html = document.documentElement; 16643 var computedStyle = isIE(10) && getComputedStyle(html); 16644 return { 16645 height: getSize('Height', body, html, computedStyle), 16646 width: getSize('Width', body, html, computedStyle) 16647 }; 16648 } 16649 16650 var classCallCheck = function classCallCheck(instance, Constructor) { 16651 if (!(instance instanceof Constructor)) { 16652 throw new TypeError("Cannot call a class as a function"); 16653 } 16654 }; 16655 16656 var createClass = function () { 16657 function defineProperties(target, props) { 16658 for (var i = 0; i < props.length; i++) { 16659 var descriptor = props[i]; 16660 descriptor.enumerable = descriptor.enumerable || false; 16661 descriptor.configurable = true; 16662 if ("value" in descriptor) descriptor.writable = true; 16663 Object.defineProperty(target, descriptor.key, descriptor); 16664 } 16665 } 16666 16667 return function (Constructor, protoProps, staticProps) { 16668 if (protoProps) defineProperties(Constructor.prototype, protoProps); 16669 if (staticProps) defineProperties(Constructor, staticProps); 16670 return Constructor; 16671 }; 16672 }(); 16673 16674 var defineProperty = function defineProperty(obj, key, value) { 16675 if (key in obj) { 16676 Object.defineProperty(obj, key, { 16677 value: value, 16678 enumerable: true, 16679 configurable: true, 16680 writable: true 16681 }); 16682 } else { 16683 obj[key] = value; 16684 } 16685 16686 return obj; 16687 }; 16688 16689 var _extends = Object.assign || function (target) { 16690 for (var i = 1; i < arguments.length; i++) { 16691 var source = arguments[i]; 16692 16693 for (var key in source) { 16694 if (Object.prototype.hasOwnProperty.call(source, key)) { 16695 target[key] = source[key]; 16696 } 16697 } 16698 } 16699 16700 return target; 16701 }; 16702 /** 16703 * Given element offsets, generate an output similar to getBoundingClientRect 16704 * @method 16705 * @memberof Popper.Utils 16706 * @argument {Object} offsets 16707 * @returns {Object} ClientRect like output 16708 */ 16709 16710 16711 function getClientRect(offsets) { 16712 return _extends({}, offsets, { 16713 right: offsets.left + offsets.width, 16714 bottom: offsets.top + offsets.height 16715 }); 16716 } 16717 /** 16718 * Get bounding client rect of given element 16719 * @method 16720 * @memberof Popper.Utils 16721 * @param {HTMLElement} element 16722 * @return {Object} client rect 16723 */ 16724 16725 16726 function getBoundingClientRect(element) { 16727 var rect = {}; // IE10 10 FIX: Please, don't ask, the element isn't 16728 // considered in DOM in some circumstances... 16729 // This isn't reproducible in IE10 compatibility mode of IE11 16730 16731 try { 16732 if (isIE(10)) { 16733 rect = element.getBoundingClientRect(); 16734 var scrollTop = getScroll(element, 'top'); 16735 var scrollLeft = getScroll(element, 'left'); 16736 rect.top += scrollTop; 16737 rect.left += scrollLeft; 16738 rect.bottom += scrollTop; 16739 rect.right += scrollLeft; 16740 } else { 16741 rect = element.getBoundingClientRect(); 16742 } 16743 } catch (e) {} 16744 16745 var result = { 16746 left: rect.left, 16747 top: rect.top, 16748 width: rect.right - rect.left, 16749 height: rect.bottom - rect.top 16750 }; // subtract scrollbar size from sizes 16751 16752 var sizes = element.nodeName === 'HTML' ? getWindowSizes() : {}; 16753 var width = sizes.width || element.clientWidth || result.right - result.left; 16754 var height = sizes.height || element.clientHeight || result.bottom - result.top; 16755 var horizScrollbar = element.offsetWidth - width; 16756 var vertScrollbar = element.offsetHeight - height; // if an hypothetical scrollbar is detected, we must be sure it's not a `border` 16757 // we make this check conditional for performance reasons 16758 16759 if (horizScrollbar || vertScrollbar) { 16760 var styles = getStyleComputedProperty(element); 16761 horizScrollbar -= getBordersSize(styles, 'x'); 16762 vertScrollbar -= getBordersSize(styles, 'y'); 16763 result.width -= horizScrollbar; 16764 result.height -= vertScrollbar; 16765 } 16766 16767 return getClientRect(result); 16768 } 16769 16770 function getOffsetRectRelativeToArbitraryNode(children, parent) { 16771 var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 16772 var isIE10 = isIE(10); 16773 var isHTML = parent.nodeName === 'HTML'; 16774 var childrenRect = getBoundingClientRect(children); 16775 var parentRect = getBoundingClientRect(parent); 16776 var scrollParent = getScrollParent(children); 16777 var styles = getStyleComputedProperty(parent); 16778 var borderTopWidth = parseFloat(styles.borderTopWidth, 10); 16779 var borderLeftWidth = parseFloat(styles.borderLeftWidth, 10); // In cases where the parent is fixed, we must ignore negative scroll in offset calc 16780 16781 if (fixedPosition && parent.nodeName === 'HTML') { 16782 parentRect.top = Math.max(parentRect.top, 0); 16783 parentRect.left = Math.max(parentRect.left, 0); 16784 } 16785 16786 var offsets = getClientRect({ 16787 top: childrenRect.top - parentRect.top - borderTopWidth, 16788 left: childrenRect.left - parentRect.left - borderLeftWidth, 16789 width: childrenRect.width, 16790 height: childrenRect.height 16791 }); 16792 offsets.marginTop = 0; 16793 offsets.marginLeft = 0; // Subtract margins of documentElement in case it's being used as parent 16794 // we do this only on HTML because it's the only element that behaves 16795 // differently when margins are applied to it. The margins are included in 16796 // the box of the documentElement, in the other cases not. 16797 16798 if (!isIE10 && isHTML) { 16799 var marginTop = parseFloat(styles.marginTop, 10); 16800 var marginLeft = parseFloat(styles.marginLeft, 10); 16801 offsets.top -= borderTopWidth - marginTop; 16802 offsets.bottom -= borderTopWidth - marginTop; 16803 offsets.left -= borderLeftWidth - marginLeft; 16804 offsets.right -= borderLeftWidth - marginLeft; // Attach marginTop and marginLeft because in some circumstances we may need them 16805 16806 offsets.marginTop = marginTop; 16807 offsets.marginLeft = marginLeft; 16808 } 16809 16810 if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') { 16811 offsets = includeScroll(offsets, parent); 16812 } 16813 16814 return offsets; 16815 } 16816 16817 function getViewportOffsetRectRelativeToArtbitraryNode(element) { 16818 var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 16819 var html = element.ownerDocument.documentElement; 16820 var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); 16821 var width = Math.max(html.clientWidth, window.innerWidth || 0); 16822 var height = Math.max(html.clientHeight, window.innerHeight || 0
vendor: 6,237 bytes, lines 16822-17012
16822); 16823 var scrollTop = !excludeScroll ? getScroll(html) : 0; 16824 var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; 16825 var offset = { 16826 top: scrollTop - relativeOffset.top + relativeOffset.marginTop, 16827 left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, 16828 width: width, 16829 height: height 16830 }; 16831 return getClientRect(offset); 16832 } 16833 /** 16834 * Check if the given element is fixed or is inside a fixed parent 16835 * @method 16836 * @memberof Popper.Utils 16837 * @argument {Element} element 16838 * @argument {Element} customContainer 16839 * @returns {Boolean} answer to "isFixed?" 16840 */ 16841 16842 16843 function isFixed(element) { 16844 var nodeName = element.nodeName; 16845 16846 if (nodeName === 'BODY' || nodeName === 'HTML') { 16847 return false; 16848 } 16849 16850 if (getStyleComputedProperty(element, 'position') === 'fixed') { 16851 return true; 16852 } 16853 16854 return isFixed(getParentNode(element)); 16855 } 16856 /** 16857 * Finds the first parent of an element that has a transformed property defined 16858 * @method 16859 * @memberof Popper.Utils 16860 * @argument {Element} element 16861 * @returns {Element} first transformed parent or documentElement 16862 */ 16863 16864 16865 function getFixedPositionOffsetParent(element) { 16866 // This check is needed to avoid errors in case one of the elements isn't defined for any reason 16867 if (!element || !element.parentElement || isIE()) { 16868 return document.documentElement; 16869 } 16870 16871 var el = element.parentElement; 16872 16873 while (el && getStyleComputedProperty(el, 'transform') === 'none') { 16874 el = el.parentElement; 16875 } 16876 16877 return el || document.documentElement; 16878 } 16879 /** 16880 * Computed the boundaries limits and return them 16881 * @method 16882 * @memberof Popper.Utils 16883 * @param {HTMLElement} popper 16884 * @param {HTMLElement} reference 16885 * @param {number} padding 16886 * @param {HTMLElement} boundariesElement - Element used to define the boundaries 16887 * @param {Boolean} fixedPosition - Is in fixed position mode 16888 * @returns {Object} Coordinates of the boundaries 16889 */ 16890 16891 16892 function getBoundaries(popper, reference, padding, boundariesElement) { 16893 var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; // NOTE: 1 DOM access here 16894 16895 var boundaries = { 16896 top: 0, 16897 left: 0 16898 }; 16899 var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference); // Handle viewport case 16900 16901 if (boundariesElement === 'viewport') { 16902 boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); 16903 } else { 16904 // Handle other cases based on DOM element used as boundaries 16905 var boundariesNode = void 0; 16906 16907 if (boundariesElement === 'scrollParent') { 16908 boundariesNode = getScrollParent(getParentNode(reference)); 16909 16910 if (boundariesNode.nodeName === 'BODY') { 16911 boundariesNode = popper.ownerDocument.documentElement; 16912 } 16913 } else if (boundariesElement === 'window') { 16914 boundariesNode = popper.ownerDocument.documentElement; 16915 } else { 16916 boundariesNode = boundariesElement; 16917 } 16918 16919 var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); // In case of HTML, we need a different computation 16920 16921 if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { 16922 var _getWindowSizes = getWindowSizes(), 16923 height = _getWindowSizes.height, 16924 width = _getWindowSizes.width; 16925 16926 boundaries.top += offsets.top - offsets.marginTop; 16927 boundaries.bottom = height + offsets.top; 16928 boundaries.left += offsets.left - offsets.marginLeft; 16929 boundaries.right = width + offsets.left; 16930 } else { 16931 // for all the other DOM elements, this one is good 16932 boundaries = offsets; 16933 } 16934 } // Add paddings 16935 16936 16937 boundaries.left += padding; 16938 boundaries.top += padding; 16939 boundaries.right -= padding; 16940 boundaries.bottom -= padding; 16941 return boundaries; 16942 } 16943 16944 function getArea(_ref) { 16945 var width = _ref.width, 16946 height = _ref.height; 16947 return width * height; 16948 } 16949 /** 16950 * Utility used to transform the `auto` placement to the placement with more 16951 * available space. 16952 * @method 16953 * @memberof Popper.Utils 16954 * @argument {Object} data - The data object generated by update method 16955 * @argument {Object} options - Modifiers configuration and options 16956 * @returns {Object} The data object, properly modified 16957 */ 16958 16959 16960 function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { 16961 var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; 16962 16963 if (placement.indexOf('auto') === -1) { 16964 return placement; 16965 } 16966 16967 var boundaries = getBoundaries(popper, reference, padding, boundariesElement); 16968 var rects = { 16969 top: { 16970 width: boundaries.width, 16971 height: refRect.top - boundaries.top 16972 }, 16973 right: { 16974 width: boundaries.right - refRect.right, 16975 height: boundaries.height 16976 }, 16977 bottom: { 16978 width: boundaries.width, 16979 height: boundaries.bottom - refRect.bottom 16980 }, 16981 left: { 16982 width: refRect.left - boundaries.left, 16983 height: boundaries.height 16984 } 16985 }; 16986 var sortedAreas = Object.keys(rects).map(function (key) { 16987 return _extends({ 16988 key: key 16989 }, rects[key], { 16990 area: getArea(rects[key]) 16991 }); 16992 }).sort(function (a, b) { 16993 return b.area - a.area; 16994 }); 16995 var filteredAreas = sortedAreas.filter(function (_ref2) { 16996 var width = _ref2.width, 16997 height = _ref2.height; 16998 return width >= popper.clientWidth && height >= popper.clientHeight; 16999 }); 17000 var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; 17001 var variation = placement.split('-')[1]; 17002 return computedPlacement + (variation ? '-' + variation : ''); 17003 } 17004 /** 17005 * Get offsets to the reference element 17006 * @method 17007 * @memberof Popper.Utils 17008 * @param {Object} state 17009 * @param {Element} popper - the popper element 17010 * @param {Element} reference - the reference element (the popper will be relative to this) 17011 * @param {Element} fixedPosition - is in fixed position mode 17012 * @returns {Object}
vendor: 4,573 bytes, lines 17012-17155
17012 An object containing the offsets which will be applied to the popper 17013 */ 17014 17015 17016 function getReferenceOffsets(state, popper, reference) { 17017 var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 17018 var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, reference); 17019 return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); 17020 } 17021 /** 17022 * Get the outer sizes of the given element (offset size + margins) 17023 * @method 17024 * @memberof Popper.Utils 17025 * @argument {Element} element 17026 * @returns {Object} object containing width and height properties 17027 */ 17028 17029 17030 function getOuterSizes(element) { 17031 var styles = getComputedStyle(element); 17032 var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom); 17033 var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight); 17034 var result = { 17035 width: element.offsetWidth + y, 17036 height: element.offsetHeight + x 17037 }; 17038 return result; 17039 } 17040 /** 17041 * Get the opposite placement of the given one 17042 * @method 17043 * @memberof Popper.Utils 17044 * @argument {String} placement 17045 * @returns {String} flipped placement 17046 */ 17047 17048 17049 function getOppositePlacement(placement) { 17050 var hash = { 17051 left: 'right', 17052 right: 'left', 17053 bottom: 'top', 17054 top: 'bottom' 17055 }; 17056 return placement.replace(/left|right|bottom|top/g, function (matched) { 17057 return hash[matched]; 17058 }); 17059 } 17060 /** 17061 * Get offsets to the popper 17062 * @method 17063 * @memberof Popper.Utils 17064 * @param {Object} position - CSS position the Popper will get applied 17065 * @param {HTMLElement} popper - the popper element 17066 * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) 17067 * @param {String} placement - one of the valid placement options 17068 * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper 17069 */ 17070 17071 17072 function getPopperOffsets(popper, referenceOffsets, placement) { 17073 placement = placement.split('-')[0]; // Get popper node sizes 17074 17075 var popperRect = getOuterSizes(popper); // Add position, width and height to our offsets object 17076 17077 var popperOffsets = { 17078 width: popperRect.width, 17079 height: popperRect.height 17080 }; // depending by the popper placement we have to compute its offsets slightly differently 17081 17082 var isHoriz = ['right', 'left'].indexOf(placement) !== -1; 17083 var mainSide = isHoriz ? 'top' : 'left'; 17084 var secondarySide = isHoriz ? 'left' : 'top'; 17085 var measurement = isHoriz ? 'height' : 'width'; 17086 var secondaryMeasurement = !isHoriz ? 'height' : 'width'; 17087 popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; 17088 17089 if (placement === secondarySide) { 17090 popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; 17091 } else { 17092 popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; 17093 } 17094 17095 return popperOffsets; 17096 } 17097 /** 17098 * Mimics the `find` method of Array 17099 * @method 17100 * @memberof Popper.Utils 17101 * @argument {Array} arr 17102 * @argument prop 17103 * @argument value 17104 * @returns index or -1 17105 */ 17106 17107 17108 function find(arr, check) { 17109 // use native find if supported 17110 if (Array.prototype.find) { 17111 return arr.find(check); 17112 } // use `filter` to obtain the same behavior of `find` 17113 17114 17115 return arr.filter(check)[0]; 17116 } 17117 /** 17118 * Return the index of the matching object 17119 * @method 17120 * @memberof Popper.Utils 17121 * @argument {Array} arr 17122 * @argument prop 17123 * @argument value 17124 * @returns index or -1 17125 */ 17126 17127 17128 function findIndex(arr, prop, value) { 17129 // use native findIndex if supported 17130 if (Array.prototype.findIndex) { 17131 return arr.findIndex(function (cur) { 17132 return cur[prop] === value; 17133 }); 17134 } // use `find` + `indexOf` if `findIndex` isn't supported 17135 17136 17137 var match = find(arr, function (obj) { 17138 return obj[prop] === value; 17139 }); 17140 return arr.indexOf(match); 17141 } 17142 /** 17143 * Loop trough the list of modifiers and run them in order, 17144 * each of them will then edit the data object. 17145 * @method 17146 * @memberof Popper.Utils 17147 * @param {dataObject} data 17148 * @param {Array} modifiers 17149 * @param {String} ends - Optional modifier name used as stopper 17150 * @returns {dataObject} 17151 */ 17152 17153 17154 function runModifiers(modifiers, data, ends) { 17155 var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));
vendor: 8,545 bytes, lines 17156-17429
17156 modifiersToRun.forEach(function (modifier) { 17157 if (modifier['function']) { 17158 // eslint-disable-line dot-notation 17159 console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); 17160 } 17161 17162 var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation 17163 17164 if (modifier.enabled && isFunction(fn)) { 17165 // Add properties to offsets to make them a complete clientRect object 17166 // we do this before each modifier to make sure the previous one doesn't 17167 // mess with these values 17168 data.offsets.popper = getClientRect(data.offsets.popper); 17169 data.offsets.reference = getClientRect(data.offsets.reference); 17170 data = fn(data, modifier); 17171 } 17172 }); 17173 return data; 17174 } 17175 /** 17176 * Updates the position of the popper, computing the new offsets and applying 17177 * the new style.<br /> 17178 * Prefer `scheduleUpdate` over `update` because of performance reasons. 17179 * @method 17180 * @memberof Popper 17181 */ 17182 17183 17184 function update() { 17185 // if popper is destroyed, don't perform any further update 17186 if (this.state.isDestroyed) { 17187 return; 17188 } 17189 17190 var data = { 17191 instance: this, 17192 styles: {}, 17193 arrowStyles: {}, 17194 attributes: {}, 17195 flipped: false, 17196 offsets: {} 17197 }; // compute reference element offsets 17198 17199 data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); // compute auto placement, store placement inside the data object, 17200 // modifiers will be able to edit `placement` if needed 17201 // and refer to originalPlacement to know the original value 17202 17203 data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); // store the computed placement inside `originalPlacement` 17204 17205 data.originalPlacement = data.placement; 17206 data.positionFixed = this.options.positionFixed; // compute the popper offsets 17207 17208 data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); 17209 data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; // run the modifiers 17210 17211 data = runModifiers(this.modifiers, data); // the first `update` will call `onCreate` callback 17212 // the other ones will call `onUpdate` callback 17213 17214 if (!this.state.isCreated) { 17215 this.state.isCreated = true; 17216 this.options.onCreate(data); 17217 } else { 17218 this.options.onUpdate(data); 17219 } 17220 } 17221 /** 17222 * Helper used to know if the given modifier is enabled. 17223 * @method 17224 * @memberof Popper.Utils 17225 * @returns {Boolean} 17226 */ 17227 17228 17229 function isModifierEnabled(modifiers, modifierName) { 17230 return modifiers.some(function (_ref) { 17231 var name = _ref.name, 17232 enabled = _ref.enabled; 17233 return enabled && name === modifierName; 17234 }); 17235 } 17236 /** 17237 * Get the prefixed supported property name 17238 * @method 17239 * @memberof Popper.Utils 17240 * @argument {String} property (camelCase) 17241 * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) 17242 */ 17243 17244 17245 function getSupportedPropertyName(property) { 17246 var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; 17247 var upperProp = property.charAt(0).toUpperCase() + property.slice(1); 17248 17249 for (var i = 0; i < prefixes.length; i++) { 17250 var prefix = prefixes[i]; 17251 var toCheck = prefix ? '' + prefix + upperProp : property; 17252 17253 if (typeof document.body.style[toCheck] !== 'undefined') { 17254 return toCheck; 17255 } 17256 } 17257 17258 return null; 17259 } 17260 /** 17261 * Destroy the popper 17262 * @method 17263 * @memberof Popper 17264 */ 17265 17266 17267 function destroy() { 17268 this.state.isDestroyed = true; // touch DOM only if `applyStyle` modifier is enabled 17269 17270 if (isModifierEnabled(this.modifiers, 'applyStyle')) { 17271 this.popper.removeAttribute('x-placement'); 17272 this.popper.style.position = ''; 17273 this.popper.style.top = ''; 17274 this.popper.style.left = ''; 17275 this.popper.style.right = ''; 17276 this.popper.style.bottom = ''; 17277 this.popper.style.willChange = ''; 17278 this.popper.style[getSupportedPropertyName('transform')] = ''; 17279 } 17280 17281 this.disableEventListeners(); // remove the popper if user explicity asked for the deletion on destroy 17282 // do not use `remove` because IE11 doesn't support it 17283 17284 if (this.options.removeOnDestroy) { 17285 this.popper.parentNode.removeChild(this.popper); 17286 } 17287 17288 return this; 17289 } 17290 /** 17291 * Get the window associated with the element 17292 * @argument {Element} element 17293 * @returns {Window} 17294 */ 17295 17296 17297 function getWindow(element) { 17298 var ownerDocument = element.ownerDocument; 17299 return ownerDocument ? ownerDocument.defaultView : window; 17300 } 17301 17302 function attachToScrollParents(scrollParent, event, callback, scrollParents) { 17303 var isBody = scrollParent.nodeName === 'BODY'; 17304 var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; 17305 target.addEventListener(event, callback, { 17306 passive: true 17307 }); 17308 17309 if (!isBody) { 17310 attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); 17311 } 17312 17313 scrollParents.push(target); 17314 } 17315 /** 17316 * Setup needed event listeners used to update the popper position 17317 * @method 17318 * @memberof Popper.Utils 17319 * @private 17320 */ 17321 17322 17323 function setupEventListeners(reference, options, state, updateBound) { 17324 // Resize event listener on window 17325 state.updateBound = updateBound; 17326 getWindow(reference).addEventListener('resize', state.updateBound, { 17327 passive: true 17328 }); // Scroll event listener on scroll parents 17329 17330 var scrollElement = getScrollParent(reference); 17331 attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); 17332 state.scrollElement = scrollElement; 17333 state.eventsEnabled = true; 17334 return state; 17335 } 17336 /** 17337 * It will add resize/scroll events and start recalculating 17338 * position of the popper element when they are triggered. 17339 * @method 17340 * @memberof Popper 17341 */ 17342 17343 17344 function enableEventListeners() { 17345 if (!this.state.eventsEnabled) { 17346 this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); 17347 } 17348 } 17349 /** 17350 * Remove event listeners used to update the popper position 17351 * @method 17352 * @memberof Popper.Utils 17353 * @private 17354 */ 17355 17356 17357 function removeEventListeners(reference, state) { 17358 // Remove resize event listener on window 17359 getWindow(reference).removeEventListener('resize', state.updateBound); // Remove scroll event listener on scroll parents 17360 17361 state.scrollParents.forEach(function (target) { 17362 target.removeEventListener('scroll', state.updateBound); 17363 }); // Reset state 17364 17365 state.updateBound = null; 17366 state.scrollParents = []; 17367 state.scrollElement = null; 17368 state.eventsEnabled = false; 17369 return state; 17370 } 17371 /** 17372 * It will remove resize/scroll events and won't recalculate popper position 17373 * when they are triggered. It also won't trigger onUpdate callback anymore, 17374 * unless you call `update` method manually. 17375 * @method 17376 * @memberof Popper 17377 */ 17378 17379 17380 function disableEventListeners() { 17381 if (this.state.eventsEnabled) { 17382 cancelAnimationFrame(this.scheduleUpdate); 17383 this.state = removeEventListeners(this.reference, this.state); 17384 } 17385 } 17386 /** 17387 * Tells if a given input is a number 17388 * @method 17389 * @memberof Popper.Utils 17390 * @param {*} input to check 17391 * @return {Boolean} 17392 */ 17393 17394 17395 function isNumeric(n) { 17396 return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); 17397 } 17398 /** 17399 * Set the style to the given popper 17400 * @method 17401 * @memberof Popper.Utils 17402 * @argument {Element} element - Element to apply the style to 17403 * @argument {Object} styles 17404 * Object with a list of properties and values which will be applied to the element 17405 */ 17406 17407 17408 function setStyles(element, styles) { 17409 Object.keys(styles).forEach(function (prop) { 17410 var unit = ''; // add unit if the value is numeric and is one of the following 17411 17412 if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) { 17413 unit = 'px'; 17414 } 17415 17416 element.style[prop] = styles[prop] + unit; 17417 }); 17418 } 17419 /** 17420 * Set the attributes to the given popper 17421 * @method 17422 * @memberof Popper.Utils 17423 * @argument {Element} element - Element to apply the attributes to 17424 * @argument {Object} styles 17425 * Object with a list of properties and values which will be applied to the element 17426 */ 17427 17428 17429 function setAttributes(element, attributes) {
17430 Object.keys(attributes).forEach(function (prop) { 17431 var value = attributes[prop]; 17432 17433 if (value !== false) { 17434 element.setAttribute(prop, attributes[prop]); 17435 } else { 17436 element.removeAttribute(prop); 17437 } 17438 }); 17439 } 17440 /** 17441 * @function 17442 * @memberof Modifiers 17443 * @argument {Object} data - The data object generated by `update` method 17444 * @argument {Object} data.styles - List of style properties - values to apply to popper element 17445 * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element 17446 * @argument {Object} options - Modifiers configuration and options 17447 * @returns {Object} The same data object 17448 */ 17449 17450 17451 function applyStyle(data) { 17452 // any property present in `data.styles` will be applied to the popper, 17453 // in this way we can make the 3rd party modifiers add custom styles to it 17454 // Be aware, modifiers could override the properties defined in the previous 17455 // lines of this modifier! 17456 setStyles(data.instance.popper, data.styles); // any property present in `data.attributes` will be applied to the popper, 17457 // they will be set as HTML attributes of the element 17458 17459 setAttributes(data.instance.popper, data.attributes); // if arrowElement is defined and arrowStyles has some properties 17460
vendor: 5,761 bytes, lines 17461-17603
17461 if (data.arrowElement && Object.keys(data.arrowStyles).length) { 17462 setStyles(data.arrowElement, data.arrowStyles); 17463 } 17464 17465 return data; 17466 } 17467 /** 17468 * Set the x-placement attribute before everything else because it could be used 17469 * to add margins to the popper margins needs to be calculated to get the 17470 * correct popper offsets. 17471 * @method 17472 * @memberof Popper.modifiers 17473 * @param {HTMLElement} reference - The reference element used to position the popper 17474 * @param {HTMLElement} popper - The HTML element used as popper 17475 * @param {Object} options - Popper.js options 17476 */ 17477 17478 17479 function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { 17480 // compute reference element offsets 17481 var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); // compute auto placement, store placement inside the data object, 17482 // modifiers will be able to edit `placement` if needed 17483 // and refer to originalPlacement to know the original value 17484 17485 var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); 17486 popper.setAttribute('x-placement', placement); // Apply `position` to popper before anything else because 17487 // without the position applied we can't guarantee correct computations 17488 17489 setStyles(popper, { 17490 position: options.positionFixed ? 'fixed' : 'absolute' 17491 }); 17492 return options; 17493 } 17494 /** 17495 * @function 17496 * @memberof Modifiers 17497 * @argument {Object} data - The data object generated by `update` method 17498 * @argument {Object} options - Modifiers configuration and options 17499 * @returns {Object} The data object, properly modified 17500 */ 17501 17502 17503 function computeStyle(data, options) { 17504 var x = options.x, 17505 y = options.y; 17506 var popper = data.offsets.popper; // Remove this legacy support in Popper.js v2 17507 17508 var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) { 17509 return modifier.name === 'applyStyle'; 17510 }).gpuAcceleration; 17511 17512 if (legacyGpuAccelerationOption !== undefined) { 17513 console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); 17514 } 17515 17516 var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; 17517 var offsetParent = getOffsetParent(data.instance.popper); 17518 var offsetParentRect = getBoundingClientRect(offsetParent); // Styles 17519 17520 var styles = { 17521 position: popper.position 17522 }; // Avoid blurry text by using full pixel integers. 17523 // For pixel-perfect positioning, top/bottom prefers rounded 17524 // values, while left/right prefers floored values. 17525 17526 var offsets = { 17527 left: Math.floor(popper.left), 17528 top: Math.round(popper.top), 17529 bottom: Math.round(popper.bottom), 17530 right: Math.floor(popper.right) 17531 }; 17532 var sideA = x === 'bottom' ? 'top' : 'bottom'; 17533 var sideB = y === 'right' ? 'left' : 'right'; // if gpuAcceleration is set to `true` and transform is supported, 17534 // we use `translate3d` to apply the position to the popper we 17535 // automatically use the supported prefixed version if needed 17536 17537 var prefixedProperty = getSupportedPropertyName('transform'); // now, let's make a step back and look at this code closely (wtf?) 17538 // If the content of the popper grows once it's been positioned, it 17539 // may happen that the popper gets misplaced because of the new content 17540 // overflowing its reference element 17541 // To avoid this problem, we provide two options (x and y), which allow 17542 // the consumer to define the offset origin. 17543 // If we position a popper on top of a reference element, we can set 17544 // `x` to `top` to make the popper grow towards its top instead of 17545 // its bottom. 17546 17547 var left = void 0, 17548 top = void 0; 17549 17550 if (sideA === 'bottom') { 17551 top = -offsetParentRect.height + offsets.bottom; 17552 } else { 17553 top = offsets.top; 17554 } 17555 17556 if (sideB === 'right') { 17557 left = -offsetParentRect.width + offsets.right; 17558 } else { 17559 left = offsets.left; 17560 } 17561 17562 if (gpuAcceleration && prefixedProperty) { 17563 styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; 17564 styles[sideA] = 0; 17565 styles[sideB] = 0; 17566 styles.willChange = 'transform'; 17567 } else { 17568 // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties 17569 var invertTop = sideA === 'bottom' ? -1 : 1; 17570 var invertLeft = sideB === 'right' ? -1 : 1; 17571 styles[sideA] = top * invertTop; 17572 styles[sideB] = left * invertLeft; 17573 styles.willChange = sideA + ', ' + sideB; 17574 } // Attributes 17575 17576 17577 var attributes = { 17578 'x-placement': data.placement 17579 }; // Update `data` attributes, styles and arrowStyles 17580 17581 data.attributes = _extends({}, attributes, data.attributes); 17582 data.styles = _extends({}, styles, data.styles); 17583 data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles); 17584 return data; 17585 } 17586 /** 17587 * Helper used to know if the given modifier depends from another one.<br /> 17588 * It checks if the needed modifier is listed and enabled. 17589 * @method 17590 * @memberof Popper.Utils 17591 * @param {Array} modifiers - list of modifiers 17592 * @param {String} requestingName - name of requesting modifier 17593 * @param {String} requestedName - name of requested modifier 17594 * @returns {Boolean} 17595 */ 17596 17597 17598 function isModifierRequired(modifiers, requestingName, requestedName) { 17599 var requesting = find(modifiers, function (_ref) { 17600 var name = _ref.name; 17601 return name === requestingName; 17602 }); 17603 var isRequired = !!requesting && modifiers.some(function (modifier) {
vendor: 4,293 bytes, lines 17604-17718
17604 return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; 17605 }); 17606 17607 if (!isRequired) { 17608 var _requesting = '`' + requestingName + '`'; 17609 17610 var requested = '`' + requestedName + '`'; 17611 console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); 17612 } 17613 17614 return isRequired; 17615 } 17616 /** 17617 * @function 17618 * @memberof Modifiers 17619 * @argument {Object} data - The data object generated by update method 17620 * @argument {Object} options - Modifiers configuration and options 17621 * @returns {Object} The data object, properly modified 17622 */ 17623 17624 17625 function arrow(data, options) { 17626 var _data$offsets$arrow; // arrow depends on keepTogether in order to work 17627 17628 17629 if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { 17630 return data; 17631 } 17632 17633 var arrowElement = options.element; // if arrowElement is a string, suppose it's a CSS selector 17634 17635 if (typeof arrowElement === 'string') { 17636 arrowElement = data.instance.popper.querySelector(arrowElement); // if arrowElement is not found, don't run the modifier 17637 17638 if (!arrowElement) { 17639 return data; 17640 } 17641 } else { 17642 // if the arrowElement isn't a query selector we must check that the 17643 // provided DOM node is child of its popper node 17644 if (!data.instance.popper.contains(arrowElement)) { 17645 console.warn('WARNING: `arrow.element` must be child of its popper element!'); 17646 return data; 17647 } 17648 } 17649 17650 var placement = data.placement.split('-')[0]; 17651 var _data$offsets = data.offsets, 17652 popper = _data$offsets.popper, 17653 reference = _data$offsets.reference; 17654 var isVertical = ['left', 'right'].indexOf(placement) !== -1; 17655 var len = isVertical ? 'height' : 'width'; 17656 var sideCapitalized = isVertical ? 'Top' : 'Left'; 17657 var side = sideCapitalized.toLowerCase(); 17658 var altSide = isVertical ? 'left' : 'top'; 17659 var opSide = isVertical ? 'bottom' : 'right'; 17660 var arrowElementSize = getOuterSizes(arrowElement)[len]; // 17661 // extends keepTogether behavior making sure the popper and its 17662 // reference have enough pixels in conjuction 17663 // 17664 // top/left side 17665 17666 if (reference[opSide] - arrowElementSize < popper[side]) { 17667 data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); 17668 } // bottom/right side 17669 17670 17671 if (reference[side] + arrowElementSize > popper[opSide]) { 17672 data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; 17673 } 17674 17675 data.offsets.popper = getClientRect(data.offsets.popper); // compute center of the popper 17676 17677 var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; // Compute the sideValue using the updated popper offsets 17678 // take popper margin in account because we don't have this info available 17679 17680 var css = getStyleComputedProperty(data.instance.popper); 17681 var popperMarginSide = parseFloat(css['margin' + sideCapitalized], 10); 17682 var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width'], 10); 17683 var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; // prevent arrowElement from being placed not contiguously to its popper 17684 17685 sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); 17686 data.arrowElement = arrowElement; 17687 data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); 17688 return data; 17689 } 17690 /** 17691 * Get the opposite placement variation of the given one 17692 * @method 17693 * @memberof Popper.Utils 17694 * @argument {String} placement variation 17695 * @returns {String} flipped placement variation 17696 */ 17697 17698 17699 function getOppositeVariation(variation) { 17700 if (variation === 'end') { 17701 return 'start'; 17702 } else if (variation === 'start') { 17703 return 'end'; 17704 } 17705 17706 return variation; 17707 } 17708 /** 17709 * List of accepted placements to use as values of the `placement` option.<br /> 17710 * Valid placements are: 17711 * - `auto` 17712 * - `top` 17713 * - `right` 17714 * - `bottom` 17715 * - `left` 17716 * 17717 * Each placement can have a variation from this list: 17718 * - `-start`
17719 * - `-end` 17720 * 17721 * Variations are interpreted easily if you think of them as the left to right 17722 * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` 17723 * is right.<br /> 17724 * Vertically (`left` and `right`), `start` is top and `end` is bottom. 17725 * 17726 * Some valid examples are: 17727 * - `top-end` (on top of reference, right aligned) 17728 * - `right-start` (on right of reference, top aligned) 17729 * - `bottom` (on bottom, centered) 17730 * - `auto-right` (on the side with more space available, alignment depends by placement) 17731 * 17732 * @static 17733 * @type {Array} 17734 * @enum {String} 17735 * @readonly 17736 * @method placements 17737 * @memberof Popper 17738 */ 17739 17740 17741 var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']; // Get rid of `auto` `auto-start` and `auto-end` 17742 17743 var validPlacements = placements.slice(3); 17744 /** 17745 * Given an initial placement, returns all the subsequent placements 17746 * clockwise (or counter-clockwise). 17747 * 17748 * @method 17749 * @memberof Popper.Utils 17750 * @argument {String} placement - A valid placement (it accepts variations) 17751 * @argument {Boolean} counter - Set to true to walk the placements counterclockwise 17752 * @returns {Array} placements including their variations 17753 */ 17754 17755 function clockwise(placement) { 17756 var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 17757 var index = validPlacements.indexOf(placement); 17758 var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); 17759 return counter ? arr.reverse() : arr; 17760 } 17761 17762 var BEHAVIORS = { 17763 FLIP: 'flip', 17764 CLOCKWISE: 'clockwise', 17765 COUNTERCLOCKWISE: 'counterclockwise' 17766 }; 17767 /** 17768 * @function 17769 * @memberof Modifiers 17770 * @argument {Object} data - The data object generated by update method 17771 * @argument {Object} options - Modifiers configuration and options 17772 * @returns {Object} The data object, properly modified 17773 */ 17774 17775 function flip(data, options) { 17776 // if `inner` modifier is enabled, we can't use the `flip` modifier 17777 if (isModifierEnabled(data.instance.modifiers, 'inner')) { 17778 return data; 17779 } 17780 17781 if (data.flipped && data.placement === data.originalPlacement) { 17782 // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides 17783 return data; 17784 } 17785 17786 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); 17787 var placement = data.placement.split('-')[0]; 17788 var placementOpposite = getOppositePlacement(placement); 17789 var variation = data.placement.split('-')[1] || ''; 17790 var flipOrder = []; 17791 17792 switch (options.behavior) { 17793 case BEHAVIORS.FLIP: 17794 flipOrder = [placement, placementOpposite]; 17795 break; 17796 17797 case BEHAVIORS.CLOCKWISE: 17798 flipOrder = clockwise(placement); 17799 break; 17800 17801 case BEHAVIORS.COUNTERCLOCKWISE: 17802 flipOrder = clockwise(placement, true); 17803 break; 17804 17805 default: 17806 flipOrder = options.behavior; 17807 } 17808 17809 flipOrder.forEach(function (step, index) { 17810 if (placement !== step || flipOrder.length === index + 1) { 17811 return data; 17812 } 17813 17814 placement = data.placement.split('-')[0]; 17815 placementOpposite = getOppositePlacement(placement); 17816 var popperOffsets = data.offsets.popper; 17817 var refOffsets = data.offsets.reference; // using floor because the reference offsets may contain decimals we are not going to consider here 17818 17819 var floor = Math.floor; 17820 var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom); 17821 var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); 17822 var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); 17823 var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); 17824 var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); 17825 var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; // flip the variation if required 17826 17827 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 17828 var flippedVariation = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); 17829 17830 if (overlapsRef || overflowsBoundaries || flippedVariation) { 17831 // this boolean to detect any flip loop 17832 data.flipped = true; 17833 17834 if (overlapsRef || overflowsBoundaries) { 17835 placement = flipOrder[index + 1]; 17836 } 17837 17838 if (flippedVariation) { 17839 variation = getOppositeVariation(variation); 17840 } 17841 17842 data.placement = placement + (variation ? '-' + variation : '');
vendor: 15,576 bytes, lines 17842-18269
17842 // this object contains `position`, we want to preserve it along with 17843 // any additional property we may add in the future 17844 17845 data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); 17846 data = runModifiers(data.instance.modifiers, data, 'flip'); 17847 } 17848 }); 17849 return data; 17850 } 17851 /** 17852 * @function 17853 * @memberof Modifiers 17854 * @argument {Object} data - The data object generated by update method 17855 * @argument {Object} options - Modifiers configuration and options 17856 * @returns {Object} The data object, properly modified 17857 */ 17858 17859 17860 function keepTogether(data) { 17861 var _data$offsets = data.offsets, 17862 popper = _data$offsets.popper, 17863 reference = _data$offsets.reference; 17864 var placement = data.placement.split('-')[0]; 17865 var floor = Math.floor; 17866 var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; 17867 var side = isVertical ? 'right' : 'bottom'; 17868 var opSide = isVertical ? 'left' : 'top'; 17869 var measurement = isVertical ? 'width' : 'height'; 17870 17871 if (popper[side] < floor(reference[opSide])) { 17872 data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; 17873 } 17874 17875 if (popper[opSide] > floor(reference[side])) { 17876 data.offsets.popper[opSide] = floor(reference[side]); 17877 } 17878 17879 return data; 17880 } 17881 /** 17882 * Converts a string containing value + unit into a px value number 17883 * @function 17884 * @memberof {modifiers~offset} 17885 * @private 17886 * @argument {String} str - Value + unit string 17887 * @argument {String} measurement - `height` or `width` 17888 * @argument {Object} popperOffsets 17889 * @argument {Object} referenceOffsets 17890 * @returns {Number|String} 17891 * Value in pixels, or original string if no values were extracted 17892 */ 17893 17894 17895 function toValue(str, measurement, popperOffsets, referenceOffsets) { 17896 // separate value from unit 17897 var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); 17898 var value = +split[1]; 17899 var unit = split[2]; // If it's not a number it's an operator, I guess 17900 17901 if (!value) { 17902 return str; 17903 } 17904 17905 if (unit.indexOf('%') === 0) { 17906 var element = void 0; 17907 17908 switch (unit) { 17909 case '%p': 17910 element = popperOffsets; 17911 break; 17912 17913 case '%': 17914 case '%r': 17915 default: 17916 element = referenceOffsets; 17917 } 17918 17919 var rect = getClientRect(element); 17920 return rect[measurement] / 100 * value; 17921 } else if (unit === 'vh' || unit === 'vw') { 17922 // if is a vh or vw, we calculate the size based on the viewport 17923 var size = void 0; 17924 17925 if (unit === 'vh') { 17926 size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); 17927 } else { 17928 size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); 17929 } 17930 17931 return size / 100 * value; 17932 } else { 17933 // if is an explicit pixel unit, we get rid of the unit and keep the value 17934 // if is an implicit unit, it's px, and we return just the value 17935 return value; 17936 } 17937 } 17938 /** 17939 * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. 17940 * @function 17941 * @memberof {modifiers~offset} 17942 * @private 17943 * @argument {String} offset 17944 * @argument {Object} popperOffsets 17945 * @argument {Object} referenceOffsets 17946 * @argument {String} basePlacement 17947 * @returns {Array} a two cells array with x and y offsets in numbers 17948 */ 17949 17950 17951 function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { 17952 var offsets = [0, 0]; // Use height if placement is left or right and index is 0 otherwise use width 17953 // in this way the first offset will use an axis and the second one 17954 // will use the other one 17955 17956 var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; // Split the offset string to obtain a list of values and operands 17957 // The regex addresses values with the plus or minus sign in front (+10, -20, etc) 17958 17959 var fragments = offset.split(/(\+|\-)/).map(function (frag) { 17960 return frag.trim(); 17961 }); // Detect if the offset string contains a pair of values or a single one 17962 // they could be separated by comma or space 17963 17964 var divider = fragments.indexOf(find(fragments, function (frag) { 17965 return frag.search(/,|\s/) !== -1; 17966 })); 17967 17968 if (fragments[divider] && fragments[divider].indexOf(',') === -1) { 17969 console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); 17970 } // If divider is found, we divide the list of values and operands to divide 17971 // them by ofset X and Y. 17972 17973 17974 var splitRegex = /\s*,\s*|\s+/; 17975 var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments]; // Convert the values with units to absolute pixels to allow our computations 17976 17977 ops = ops.map(function (op, index) { 17978 // Most of the units rely on the orientation of the popper 17979 var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; 17980 var mergeWithPrevious = false; 17981 return op // This aggregates any `+` or `-` sign that aren't considered operators 17982 // e.g.: 10 + +5 => [10, +, +5] 17983 .reduce(function (a, b) { 17984 if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { 17985 a[a.length - 1] = b; 17986 mergeWithPrevious = true; 17987 return a; 17988 } else if (mergeWithPrevious) { 17989 a[a.length - 1] += b; 17990 mergeWithPrevious = false; 17991 return a; 17992 } else { 17993 return a.concat(b); 17994 } 17995 }, []) // Here we convert the string values into number values (in px) 17996 .map(function (str) { 17997 return toValue(str, measurement, popperOffsets, referenceOffsets); 17998 }); 17999 }); // Loop trough the offsets arrays and execute the operations 18000 18001 ops.forEach(function (op, index) { 18002 op.forEach(function (frag, index2) { 18003 if (isNumeric(frag)) { 18004 offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); 18005 } 18006 }); 18007 }); 18008 return offsets; 18009 } 18010 /** 18011 * @function 18012 * @memberof Modifiers 18013 * @argument {Object} data - The data object generated by update method 18014 * @argument {Object} options - Modifiers configuration and options 18015 * @argument {Number|String} options.offset=0 18016 * The offset value as described in the modifier description 18017 * @returns {Object} The data object, properly modified 18018 */ 18019 18020 18021 function offset(data, _ref) { 18022 var offset = _ref.offset; 18023 var placement = data.placement, 18024 _data$offsets = data.offsets, 18025 popper = _data$offsets.popper, 18026 reference = _data$offsets.reference; 18027 var basePlacement = placement.split('-')[0]; 18028 var offsets = void 0; 18029 18030 if (isNumeric(+offset)) { 18031 offsets = [+offset, 0]; 18032 } else { 18033 offsets = parseOffset(offset, popper, reference, basePlacement); 18034 } 18035 18036 if (basePlacement === 'left') { 18037 popper.top += offsets[0]; 18038 popper.left -= offsets[1]; 18039 } else if (basePlacement === 'right') { 18040 popper.top += offsets[0]; 18041 popper.left += offsets[1]; 18042 } else if (basePlacement === 'top') { 18043 popper.left += offsets[0]; 18044 popper.top -= offsets[1]; 18045 } else if (basePlacement === 'bottom') { 18046 popper.left += offsets[0]; 18047 popper.top += offsets[1]; 18048 } 18049 18050 data.popper = popper; 18051 return data; 18052 } 18053 /** 18054 * @function 18055 * @memberof Modifiers 18056 * @argument {Object} data - The data object generated by `update` method 18057 * @argument {Object} options - Modifiers configuration and options 18058 * @returns {Object} The data object, properly modified 18059 */ 18060 18061 18062 function preventOverflow(data, options) { 18063 var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); // If offsetParent is the reference element, we really want to 18064 // go one step up and use the next offsetParent as reference to 18065 // avoid to make this modifier completely useless and look like broken 18066 18067 if (data.instance.reference === boundariesElement) { 18068 boundariesElement = getOffsetParent(boundariesElement); 18069 } // NOTE: DOM access here 18070 // resets the popper's position so that the document size can be calculated excluding 18071 // the size of the popper element itself 18072 18073 18074 var transformProp = getSupportedPropertyName('transform'); 18075 var popperStyles = data.instance.popper.style; // assignment to help minification 18076 18077 var top = popperStyles.top, 18078 left = popperStyles.left, 18079 transform = popperStyles[transformProp]; 18080 popperStyles.top = ''; 18081 popperStyles.left = ''; 18082 popperStyles[transformProp] = ''; 18083 var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); // NOTE: DOM access here 18084 // restores the original style properties after the offsets have been computed 18085 18086 popperStyles.top = top; 18087 popperStyles.left = left; 18088 popperStyles[transformProp] = transform; 18089 options.boundaries = boundaries; 18090 var order = options.priority; 18091 var popper = data.offsets.popper; 18092 var check = { 18093 primary: function primary(placement) { 18094 var value = popper[placement]; 18095 18096 if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { 18097 value = Math.max(popper[placement], boundaries[placement]); 18098 } 18099 18100 return defineProperty({}, placement, value); 18101 }, 18102 secondary: function secondary(placement) { 18103 var mainSide = placement === 'right' ? 'left' : 'top'; 18104 var value = popper[mainSide]; 18105 18106 if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { 18107 value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); 18108 } 18109 18110 return defineProperty({}, mainSide, value); 18111 } 18112 }; 18113 order.forEach(function (placement) { 18114 var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; 18115 popper = _extends({}, popper, check[side](placement)); 18116 }); 18117 data.offsets.popper = popper; 18118 return data; 18119 } 18120 /** 18121 * @function 18122 * @memberof Modifiers 18123 * @argument {Object} data - The data object generated by `update` method 18124 * @argument {Object} options - Modifiers configuration and options 18125 * @returns {Object} The data object, properly modified 18126 */ 18127 18128 18129 function shift(data) { 18130 var placement = data.placement; 18131 var basePlacement = placement.split('-')[0]; 18132 var shiftvariation = placement.split('-')[1]; // if shift shiftvariation is specified, run the modifier 18133 18134 if (shiftvariation) { 18135 var _data$offsets = data.offsets, 18136 reference = _data$offsets.reference, 18137 popper = _data$offsets.popper; 18138 var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; 18139 var side = isVertical ? 'left' : 'top'; 18140 var measurement = isVertical ? 'width' : 'height'; 18141 var shiftOffsets = { 18142 start: defineProperty({}, side, reference[side]), 18143 end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement]) 18144 }; 18145 data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]); 18146 } 18147 18148 return data; 18149 } 18150 /** 18151 * @function 18152 * @memberof Modifiers 18153 * @argument {Object} data - The data object generated by update method 18154 * @argument {Object} options - Modifiers configuration and options 18155 * @returns {Object} The data object, properly modified 18156 */ 18157 18158 18159 function hide(data) { 18160 if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { 18161 return data; 18162 } 18163 18164 var refRect = data.offsets.reference; 18165 var bound = find(data.instance.modifiers, function (modifier) { 18166 return modifier.name === 'preventOverflow'; 18167 }).boundaries; 18168 18169 if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { 18170 // Avoid unnecessary DOM access if visibility hasn't changed 18171 if (data.hide === true) { 18172 return data; 18173 } 18174 18175 data.hide = true; 18176 data.attributes['x-out-of-boundaries'] = ''; 18177 } else { 18178 // Avoid unnecessary DOM access if visibility hasn't changed 18179 if (data.hide === false) { 18180 return data; 18181 } 18182 18183 data.hide = false; 18184 data.attributes['x-out-of-boundaries'] = false; 18185 } 18186 18187 return data; 18188 } 18189 /** 18190 * @function 18191 * @memberof Modifiers 18192 * @argument {Object} data - The data object generated by `update` method 18193 * @argument {Object} options - Modifiers configuration and options 18194 * @returns {Object} The data object, properly modified 18195 */ 18196 18197 18198 function inner(data) { 18199 var placement = data.placement; 18200 var basePlacement = placement.split('-')[0]; 18201 var _data$offsets = data.offsets, 18202 popper = _data$offsets.popper, 18203 reference = _data$offsets.reference; 18204 var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; 18205 var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; 18206 popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); 18207 data.placement = getOppositePlacement(placement); 18208 data.offsets.popper = getClientRect(popper); 18209 return data; 18210 } 18211 /** 18212 * Modifier function, each modifier can have a function of this type assigned 18213 * to its `fn` property.<br /> 18214 * These functions will be called on each update, this means that you must 18215 * make sure they are performant enough to avoid performance bottlenecks. 18216 * 18217 * @function ModifierFn 18218 * @argument {dataObject} data - The data object generated by `update` method 18219 * @argument {Object} options - Modifiers configuration and options 18220 * @returns {dataObject} The data object, properly modified 18221 */ 18222 18223 /** 18224 * Modifiers are plugins used to alter the behavior of your poppers.<br /> 18225 * Popper.js uses a set of 9 modifiers to provide all the basic functionalities 18226 * needed by the library. 18227 * 18228 * Usually you don't want to override the `order`, `fn` and `onLoad` props. 18229 * All the other properties are configurations that could be tweaked. 18230 * @namespace modifiers 18231 */ 18232 18233 18234 var modifiers = { 18235 /** 18236 * Modifier used to shift the popper on the start or end of its reference 18237 * element.<br /> 18238 * It will read the variation of the `placement` property.<br /> 18239 * It can be one either `-end` or `-start`. 18240 * @memberof modifiers 18241 * @inner 18242 */ 18243 shift: { 18244 /** @prop {number} order=100 - Index used to define the order of execution */ 18245 order: 100, 18246 18247 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 18248 enabled: true, 18249 18250 /** @prop {ModifierFn} */ 18251 fn: shift 18252 }, 18253 18254 /** 18255 * The `offset` modifier can shift your popper on both its axis. 18256 * 18257 * It accepts the following units: 18258 * - `px` or unitless, interpreted as pixels 18259 * - `%` or `%r`, percentage relative to the length of the reference element 18260 * - `%p`, percentage relative to the length of the popper element 18261 * - `vw`, CSS viewport width unit 18262 * - `vh`, CSS viewport height unit 18263 * 18264 * For length is intended the main axis relative to the placement of the popper.<br /> 18265 * This means that if the placement is `top` or `bottom`, the length will be the 18266 * `width`. In case of `left` or `right`, it will be the height. 18267 * 18268 * You can provide a single value (as `Number` or `String`), or a pair of values 18269 * as `String` divided by a comma or one (or more) white space
18269s.<br /> 18270 * The latter is a deprecated method because it leads to confusion and will be 18271 * removed in v2.<br /> 18272 * Additionally, it accepts additions and subtractions between different units. 18273 * Note that multiplications and divisions aren't supported. 18274 * 18275 * Valid examples are: 18276 * ``` 18277 * 10 18278 * '10%' 18279 * '10, 10' 18280 * '10%, 10' 18281 * '10 + 10%' 18282 * '10 - 5vh + 3%' 18283 * '-10px + 5vh, 5px - 6%' 18284 * ``` 18285 * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap 18286 * > with their reference element, unfortunately, you will have to disable the `flip` modifier. 18287 * > More on this [reading this issue](https://github.com/FezVrasta/popper.js/issues/373) 18288 * 18289 * @memberof modifiers 18290 * @inner 18291 */ 18292 offset: { 18293 /** @prop {number} order=200 - Index used to define the order of execution */ 18294 order: 200, 18295 18296 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 18297 enabled: true, 18298 18299 /** @prop {ModifierFn} */ 18300 fn: offset, 18301 18302 /** @prop {Number|String} offset=0 18303 * The offset value as described in the modifier description 18304 */ 18305 offset: 0 18306 }, 18307 18308 /** 18309 * Modifier used to prevent the popper from being positioned outside the boundary. 18310 * 18311 * An scenario exists where the reference itself is not within the boundaries.<br /> 18312 * We can say it has "escaped the boundaries" — or just "escaped".<br /> 18313 * In this case we need to decide whether the popper should either: 18314 * 18315 * - detach from the reference and remain "trapped" in the boundaries, or 18316 * - if it should ignore the boundary and "escape with its reference" 18317 * 18318 * When `escapeWithReference` is set to`true` and reference is completely 18319 * outside its boundaries, the popper will overflow (or completely leave) 18320 * the boundaries in order to remain attached to the edge of the reference. 18321 * 18322 * @memberof modifiers 18323 * @inner 18324 */ 18325 preventOverflow: { 18326 /** @prop {number} order=300 - Index used to define the order of execution */ 18327 order: 300, 18328 18329 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 18330 enabled: true, 18331 18332 /** @prop {ModifierFn} */ 18333 fn: preventOverflow, 18334 18335 /** 18336 * @prop {Array} [priority=['left','right','top','bottom']] 18337 * Popper will try to prevent overflow following these priorities by default, 18338 * then, it could overflow on the left and on top of the `boundariesElement` 18339 */ 18340 priority: ['left', 'right', 'top', 'bottom'], 18341 18342 /** 18343 * @prop {number} padding=5 18344 * Amount of pixel used to define a minimum distance between the boundaries 18345 * and the popper this makes sure the popper has always a little padding 18346 * between the edges of its container 18347 */ 18348 padding: 5, 18349 18350 /** 18351 * @prop {String|HTMLElement} boundariesElement='scrollParent' 18352 * Boundaries used by the modifier, can be `scrollParent`, `window`, 18353 * `viewport` or any DOM element. 18354 */ 18355 boundariesElement: 'scrollParent' 18356 }, 18357 18358 /** 18359 * Modifier used to make sure the reference and its popper stay near eachothers 18360 * without leaving any gap between the two. Expecially useful when the arrow is 18361 * enabled and you want to assure it to point to its reference element. 18362 * It cares only about the first axis, you can still have poppers with margin 18363 * between the popper and its reference element. 18364 * @memberof modifiers 18365 * @inner 18366 */ 18367 keepTogether: { 18368 /** @prop {number} order=400 - Index used to define the order of execution */ 18369 order: 400, 18370 18371 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 18372 enabled: true, 18373 18374 /** @prop {ModifierFn} */ 18375 fn: keepTogether 18376 }, 18377 18378 /** 18379 * This modifier is used to move the `arrowElement` of the popper to make 18380 * sure it is positioned between the reference element and its popper element. 18381 * It will read the outer size of the `arrowElement` node to detect how many 18382 * pixels of conjuction are needed. 18383 * 18384 * It has no effect if no `arrowElement` is provided. 18385 * @memberof modifiers 18386 * @inner 18387 */ 18388 arrow: { 18389 /** @prop {number} order=500 - Index used to define the order of execution */ 18390 order: 500, 18391 18392 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 18393 enabled: true, 18394 18395 /** @prop {ModifierFn} */ 18396 fn: arrow, 18397 18398 /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ 18399 element: '[x-arrow]' 18400 }, 18401 18402 /** 18403 * Modifier used to flip the popper's placement when it starts to overlap its 18404 * reference element. 18405 * 18406 * Requires the `preventOverflow` modifier before it in order to work. 18407 * 18408 * **NOTE:** this modifier will interrupt the current update cycle and will 18409 * restart it if it detects the need to flip the placement. 18410 * @memberof modifiers 18411 * @inner 18412 */ 18413 flip: { 18414 /** @prop {number} order=600 - Index used to define the order of execution */ 18415 order: 600, 18416 18417 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 18418 enabled: true, 18419 18420 /** @prop {ModifierFn} */ 18421 fn: flip, 18422 18423 /** 18424 * @prop {String|Array} behavior='flip' 18425 * The behavior used to change the popper's placement. It can be one of 18426 * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid 18427 * placements (with optional variations). 18428 */ 18429 behavior: 'flip', 18430 18431 /** 18432 * @prop {number} padding=5 18433 * The popper will flip if it hits the edges of the `boundariesElement` 18434 */ 18435 padding: 5, 18436 18437 /** 18438 * @prop {String|HTMLElement} boundariesElement='viewport' 18439 * The element which will define the boundaries of the popper position, 18440 * the popper will never be placed outside of the defined boundaries 18441 * (except if keepTogether is enabled) 18442 */ 18443 boundariesElement: 'viewport' 18444 }, 18445 18446 /** 18447 * Modifier used to make the popper flow toward the inner of the reference element. 18448 * By default, when this modifier is disabled, the popper will be placed outside 18449 * the reference element. 18450 * @memberof modifiers 18451 * @inner 18452 */ 18453 inner: { 18454 /** @prop {number} order=700 - Index used to define the order of execution */ 18455 order: 700, 18456 18457 /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ 18458 enabled: false, 18459 18460 /** @prop {ModifierFn} */ 18461 fn: inner 18462 }, 18463 18464 /** 18465 * Modifier used to hide the popper when its reference element is outside of the 18466 * popper boundaries. It will set a `x-out-of-boundaries` attribute which can 18467 * be used to hide with a CSS selector the popper when its reference is 18468 * out of boundaries. 18469 * 18470 * Requires the `preventOverflow` modifier before it in order to work. 18471 * @memberof modifiers 18472 * @inner 18473 */ 18474 hide: { 18475 /** @prop {number} order=800 - Index used to define the order of execution */ 18476 order: 800, 18477 18478 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 18479 enabled: true, 18480 18481 /** @prop {ModifierFn} */ 18482 fn: hide 18483 }, 18484 18485 /** 18486 * Computes the style that will be applied to the popper element to gets 18487 * properly positioned. 18488 * 18489 * Note that this modifier will not touch the DOM, it just prepares the styles 18490 * so that `applyStyle` modifier can apply it. This separation is useful 18491 * in case you need to replace `applyStyle` with a custom implementation. 18492 * 18493 * This modifier has `850` as `order` value to maintain backward compatibility 18494 * with previous versions of Popper.js. Expect the modifiers ordering method 18495 * to change in future major versions of the library. 18496 * 18497 * @memberof modifiers 18498 * @inner 18499 */ 18500 computeStyle: { 18501 /** @prop {number} order=850 - Index used to define the order of execution */ 18502 order: 850, 18503 18504 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 18505 enabled: true, 18506 18507 /** @prop {ModifierFn} */ 18508 fn: computeStyle, 18509 18510 /** 18511 * @prop {Boolean} gpuAcceleration=true 18512 * If true, it uses the CSS 3d transformation to position the popper. 18513 * Otherwise, it will use the `top` and `left` properties. 18514 */ 18515 gpuAcceleration: true, 18516 18517 /** 18518 * @prop {string} [x='bottom'] 18519 * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. 18520 * Change this if your popper should grow in a direction different from `bottom` 18521 */ 18522 x: 'bottom', 18523 18524 /** 18525 * @prop {string} [x='left'] 18526 * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. 18527 * Change this if your popper should grow in a direction different from `right` 18528 */ 18529 y: 'right' 18530 }, 18531 18532 /** 18533 * Applies the computed styles to the popper element. 18534 * 18535 * All the DOM manipulations are limited to this modifier. This is useful in case 18536 * you want to integrate Popper.js inside a framework or view library and you 18537 * want to delegate all the DOM manipulations to it. 18538 * 18539 * Note that if you disable this modifier, you must make sure the popper element 18540 * has its position set to `absolute` before Popper.js can do its work! 18541 * 18542 * Just disable this modifier and define you own to achieve the desired effect. 18543 * 18544 * @memberof modifiers 18545 * @inner 18546 */ 18547 applyStyle: { 18548 /** @prop {number} order=900 - Index used to define the order of execution */ 18549 order: 900, 18550 18551 /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ 18552 enabled: true, 18553 18554 /** @prop {ModifierFn} */
vendor: 5,031 bytes, lines 18555-18692
18555 fn: applyStyle, 18556 18557 /** @prop {Function} */ 18558 onLoad: applyStyleOnLoad, 18559 18560 /** 18561 * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier 18562 * @prop {Boolean} gpuAcceleration=true 18563 * If true, it uses the CSS 3d transformation to position the popper. 18564 * Otherwise, it will use the `top` and `left` properties. 18565 */ 18566 gpuAcceleration: undefined 18567 } 18568 }; 18569 /** 18570 * The `dataObject` is an object containing all the informations used by Popper.js 18571 * this object get passed to modifiers and to the `onCreate` and `onUpdate` callbacks. 18572 * @name dataObject 18573 * @property {Object} data.instance The Popper.js instance 18574 * @property {String} data.placement Placement applied to popper 18575 * @property {String} data.originalPlacement Placement originally defined on init 18576 * @property {Boolean} data.flipped True if popper has been flipped by flip modifier 18577 * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper. 18578 * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier 18579 * @property {Object} data.styles Any CSS property defined here will be applied to the popper, it expects the JavaScript nomenclature (eg. `marginBottom`) 18580 * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow, it expects the JavaScript nomenclature (eg. `marginBottom`) 18581 * @property {Object} data.boundaries Offsets of the popper boundaries 18582 * @property {Object} data.offsets The measurements of popper, reference and arrow elements. 18583 * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values 18584 * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values 18585 * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 18586 */ 18587 18588 /** 18589 * Default options provided to Popper.js constructor.<br /> 18590 * These can be overriden using the `options` argument of Popper.js.<br /> 18591 * To override an option, simply pass as 3rd argument an object with the same 18592 * structure of this object, example: 18593 * ``` 18594 * new Popper(ref, pop, { 18595 * modifiers: { 18596 * preventOverflow: { enabled: false } 18597 * } 18598 * }) 18599 * ``` 18600 * @type {Object} 18601 * @static 18602 * @memberof Popper 18603 */ 18604 18605 var Defaults = { 18606 /** 18607 * Popper's placement 18608 * @prop {Popper.placements} placement='bottom' 18609 */ 18610 placement: 'bottom', 18611 18612 /** 18613 * Set this to true if you want popper to position it self in 'fixed' mode 18614 * @prop {Boolean} positionFixed=false 18615 */ 18616 positionFixed: false, 18617 18618 /** 18619 * Whether events (resize, scroll) are initially enabled 18620 * @prop {Boolean} eventsEnabled=true 18621 */ 18622 eventsEnabled: true, 18623 18624 /** 18625 * Set to true if you want to automatically remove the popper when 18626 * you call the `destroy` method. 18627 * @prop {Boolean} removeOnDestroy=false 18628 */ 18629 removeOnDestroy: false, 18630 18631 /** 18632 * Callback called when the popper is created.<br /> 18633 * By default, is set to no-op.<br /> 18634 * Access Popper.js instance with `data.instance`. 18635 * @prop {onCreate} 18636 */ 18637 onCreate: function onCreate() {}, 18638 18639 /** 18640 * Callback called when the popper is updated, this callback is not called 18641 * on the initialization/creation of the popper, but only on subsequent 18642 * updates.<br /> 18643 * By default, is set to no-op.<br /> 18644 * Access Popper.js instance with `data.instance`. 18645 * @prop {onUpdate} 18646 */ 18647 onUpdate: function onUpdate() {}, 18648 18649 /** 18650 * List of modifiers used to modify the offsets before they are applied to the popper. 18651 * They provide most of the functionalities of Popper.js 18652 * @prop {modifiers} 18653 */ 18654 modifiers: modifiers 18655 }; 18656 /** 18657 * @callback onCreate 18658 * @param {dataObject} data 18659 */ 18660 18661 /** 18662 * @callback onUpdate 18663 * @param {dataObject} data 18664 */ 18665 // Utils 18666 // Methods 18667 18668 var Popper = function () { 18669 /** 18670 * Create a new Popper.js instance 18671 * @class Popper 18672 * @param {HTMLElement|referenceObject} reference - The reference element used to position the popper 18673 * @param {HTMLElement} popper - The HTML element used as popper. 18674 * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) 18675 * @return {Object} instance - The generated Popper.js instance 18676 */ 18677 function Popper(reference, popper) { 18678 var _this = this; 18679 18680 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 18681 classCallCheck(this, Popper); 18682 18683 this.scheduleUpdate = function () { 18684 return requestAnimationFrame(_this.update); 18685 }; // make update() debounced, so that it only runs at most once-per-tick 18686 18687 18688 this.update = debounce(this.update.bind(this)); // with {} we create a new object with the options inside it 18689 18690 this.options = _extends({}, Popper.Defaults, options); // init state 18691 18692 this.state = {
vendor: 7,906 bytes, lines 18693-18912
18693 isDestroyed: false, 18694 isCreated: false, 18695 scrollParents: [] 18696 }; // get reference and popper elements (allow jQuery wrappers) 18697 18698 this.reference = reference && reference.jquery ? reference[0] : reference; 18699 this.popper = popper && popper.jquery ? popper[0] : popper; // Deep merge modifiers options 18700 18701 this.options.modifiers = {}; 18702 Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { 18703 _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); 18704 }); // Refactoring modifiers' list (Object => Array) 18705 18706 this.modifiers = Object.keys(this.options.modifiers).map(function (name) { 18707 return _extends({ 18708 name: name 18709 }, _this.options.modifiers[name]); 18710 }) // sort the modifiers by order 18711 .sort(function (a, b) { 18712 return a.order - b.order; 18713 }); // modifiers have the ability to execute arbitrary code when Popper.js get inited 18714 // such code is executed in the same order of its modifier 18715 // they could add new properties to their options configuration 18716 // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! 18717 18718 this.modifiers.forEach(function (modifierOptions) { 18719 if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { 18720 modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); 18721 } 18722 }); // fire the first update to position the popper in the right place 18723 18724 this.update(); 18725 var eventsEnabled = this.options.eventsEnabled; 18726 18727 if (eventsEnabled) { 18728 // setup event listeners, they will take care of update the position in specific situations 18729 this.enableEventListeners(); 18730 } 18731 18732 this.state.eventsEnabled = eventsEnabled; 18733 } // We can't use class properties because they don't get listed in the 18734 // class prototype and break stuff like Sinon stubs 18735 18736 18737 createClass(Popper, [{ 18738 key: 'update', 18739 value: function update$$1() { 18740 return update.call(this); 18741 } 18742 }, { 18743 key: 'destroy', 18744 value: function destroy$$1() { 18745 return destroy.call(this); 18746 } 18747 }, { 18748 key: 'enableEventListeners', 18749 value: function enableEventListeners$$1() { 18750 return enableEventListeners.call(this); 18751 } 18752 }, { 18753 key: 'disableEventListeners', 18754 value: function disableEventListeners$$1() { 18755 return disableEventListeners.call(this); 18756 } 18757 /** 18758 * Schedule an update, it will run on the next UI update available 18759 * @method scheduleUpdate 18760 * @memberof Popper 18761 */ 18762 18763 /** 18764 * Collection of utilities useful when writing custom modifiers. 18765 * Starting from version 1.7, this method is available only if you 18766 * include `popper-utils.js` before `popper.js`. 18767 * 18768 * **DEPRECATION**: This way to access PopperUtils is deprecated 18769 * and will be removed in v2! Use the PopperUtils module directly instead. 18770 * Due to the high instability of the methods contained in Utils, we can't 18771 * guarantee them to follow semver. Use them at your own risk! 18772 * @static 18773 * @private 18774 * @type {Object} 18775 * @deprecated since version 1.8 18776 * @member Utils 18777 * @memberof Popper 18778 */ 18779 18780 }]); 18781 return Popper; 18782 }(); 18783 /** 18784 * The `referenceObject` is an object that provides an interface compatible with Popper.js 18785 * and lets you use it as replacement of a real DOM node.<br /> 18786 * You can use this method to position a popper relatively to a set of coordinates 18787 * in case you don't have a DOM node to use as reference. 18788 * 18789 * ``` 18790 * new Popper(referenceObject, popperNode); 18791 * ``` 18792 * 18793 * NB: This feature isn't supported in Internet Explorer 10 18794 * @name referenceObject 18795 * @property {Function} data.getBoundingClientRect 18796 * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. 18797 * @property {number} data.clientWidth 18798 * An ES6 getter that will return the width of the virtual reference element. 18799 * @property {number} data.clientHeight 18800 * An ES6 getter that will return the height of the virtual reference element. 18801 */ 18802 18803 18804 Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; 18805 Popper.placements = placements; 18806 Popper.Defaults = Defaults; 18807 /** 18808 * -------------------------------------------------------------------------- 18809 * Bootstrap (v4.1.1): dropdown.js 18810 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 18811 * -------------------------------------------------------------------------- 18812 */ 18813 18814 var Dropdown = function ($$$1) { 18815 /** 18816 * ------------------------------------------------------------------------ 18817 * Constants 18818 * ------------------------------------------------------------------------ 18819 */ 18820 var NAME = 'dropdown'; 18821 var VERSION = '4.1.1'; 18822 var DATA_KEY = 'bs.dropdown'; 18823 var EVENT_KEY = "." + DATA_KEY; 18824 var DATA_API_KEY = '.data-api'; 18825 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 18826 var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key 18827 18828 var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key 18829 18830 var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key 18831 18832 var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key 18833 18834 var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key 18835 18836 var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse) 18837 18838 var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE); 18839 var Event = { 18840 HIDE: "hide" + EVENT_KEY, 18841 HIDDEN: "hidden" + EVENT_KEY, 18842 SHOW: "show" + EVENT_KEY, 18843 SHOWN: "shown" + EVENT_KEY, 18844 CLICK: "click" + EVENT_KEY, 18845 CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY, 18846 KEYDOWN_DATA_API: "keydown" + EVENT_KEY + DATA_API_KEY, 18847 KEYUP_DATA_API: "keyup" + EVENT_KEY + DATA_API_KEY 18848 }; 18849 var ClassName = { 18850 DISABLED: 'disabled', 18851 SHOW: 'show', 18852 DROPUP: 'dropup', 18853 DROPRIGHT: 'dropright', 18854 DROPLEFT: 'dropleft', 18855 MENURIGHT: 'dropdown-menu-right', 18856 MENULEFT: 'dropdown-menu-left', 18857 POSITION_STATIC: 'position-static' 18858 }; 18859 var Selector = { 18860 DATA_TOGGLE: '[data-toggle="dropdown"]', 18861 FORM_CHILD: '.dropdown form', 18862 MENU: '.dropdown-menu', 18863 NAVBAR_NAV: '.navbar-nav', 18864 VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)' 18865 }; 18866 var AttachmentMap = { 18867 TOP: 'top-start', 18868 TOPEND: 'top-end', 18869 BOTTOM: 'bottom-start', 18870 BOTTOMEND: 'bottom-end', 18871 RIGHT: 'right-start', 18872 RIGHTEND: 'right-end', 18873 LEFT: 'left-start', 18874 LEFTEND: 'left-end' 18875 }; 18876 var Default = { 18877 offset: 0, 18878 flip: true, 18879 boundary: 'scrollParent', 18880 reference: 'toggle', 18881 display: 'dynamic' 18882 }; 18883 var DefaultType = { 18884 offset: '(number|string|function)', 18885 flip: 'boolean', 18886 boundary: '(string|element)', 18887 reference: '(string|element)', 18888 display: 'string' 18889 /** 18890 * ------------------------------------------------------------------------ 18891 * Class Definition 18892 * ------------------------------------------------------------------------ 18893 */ 18894 18895 }; 18896 18897 var Dropdown = 18898 /*#__PURE__*/ 18899 function () { 18900 function Dropdown(element, config) { 18901 this._element = element; 18902 this._popper = null; 18903 this._config = this._getConfig(config); 18904 this._menu = this._getMenuElement(); 18905 this._inNavbar = this._detectNavbar(); 18906 18907 this._addEventListeners(); 18908 } // Getters 18909 18910 18911 var _proto = Dropdown.prototype; // Public 18912
18913 _proto.toggle = function toggle() { 18914 if (this._element.disabled || $$$1(this._element).hasClass(ClassName.DISABLED)) { 18915 return; 18916 } 18917 18918 var parent = Dropdown._getParentFromElement(this._element); 18919 18920 var isActive = $$$1(this._menu).hasClass(ClassName.SHOW); 18921 18922 Dropdown._clearMenus(); 18923 18924 if (isActive) { 18925 return; 18926 } 18927 18928 var relatedTarget = { 18929 relatedTarget: this._element 18930 }; 18931 var showEvent = $$$1.Event(Event.SHOW, relatedTarget); 18932 $$$1(parent).trigger(showEvent); 18933 18934 if (showEvent.isDefaultPrevented()) { 18935 return; 18936 } // Disable totally Popper.js for Dropdown in Navbar 18937 18938 18939 if (!this._inNavbar) { 18940 /** 18941 * Check for Popper dependency 18942 * Popper - https://popper.js.org 18943 */ 18944 if (typeof Popper === 'undefined') { 18945 throw new TypeError('Bootstrap dropdown require Popper.js (https://popper.js.org)'); 18946 } 18947 18948 var referenceElement = this._element; 18949 18950 if (this._config.reference === 'parent') { 18951 referenceElement = parent; 18952 } else if (Util.isElement(this._config.reference)) { 18953 referenceElement = this._config.reference; // Check if it's jQuery element 18954 18955 if (typeof this._config.reference.jquery !== 'undefined') { 18956 referenceElement = this._config.reference[0]; 18957 } 18958 } // If boundary is not `scrollParent`, then set position to `static` 18959 // to allow the menu to "escape" the scroll parent's boundaries 18960 // https://github.com/twbs/bootstrap/issues/24251 18961 18962 18963 if (this._config.boundary !== 'scrollParent') { 18964 $$$1(parent).addClass(ClassName.POSITION_STATIC); 18965 } 18966 18967 this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()); 18968 } // If this is a touch-enabled device we add extra 18969 // empty mouseover listeners to the body's immediate children; 18970 // only needed because of broken event delegation on iOS 18971 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 18972 18973 18974 if ('ontouchstart' in document.documentElement && $$$1(parent).closest(Selector.NAVBAR_NAV).length === 0) { 18975 $$$1(document.body).children().on('mouseover', null, $$$1.noop); 18976 } 18977 18978 this._element.focus(); 18979 18980 this._element.setAttribute('aria-expanded', true); 18981 18982 $$$1(this._menu).toggleClass(ClassName.SHOW); 18983 $$$1(parent).toggleClass(ClassName.SHOW).trigger($$$1.Event(Event.SHOWN, relatedTarget)); 18984 }; 18985 18986 _proto.dispose = function dispose() { 18987 $$$1.removeData(this._element, DATA_KEY); 18988 $$$1(this._element).off(EVENT_KEY); 18989 this._element = null; 18990 this._menu = null; 18991 18992 if (this._popper !== null) { 18993 this._popper.destroy(); 18994 18995 this._popper = null; 18996 } 18997 }; 18998 18999 _proto.update = function update() { 19000 this._inNavbar = this._detectNavbar(); 19001 19002 if (this._popper !== null) { 19003 this._popper.scheduleUpdate(); 19004 } 19005 }; // Private 19006 19007 19008 _proto._addEventListeners = function _addEventListeners() { 19009 var _this = this; 19010 19011 $$$1(this._element).on(Event.CLICK, function (event) { 19012 event.preventDefault(); 19013 event.stopPropagation(); 19014 19015 _this.toggle(); 19016 }); 19017 }; 19018 19019 _proto._getConfig = function _getConfig(config) { 19020 config = _objectSpread({}, this.constructor.Default, $$$1(this._element).data(), config); 19021 Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); 19022 return config; 19023 }; 19024 19025 _proto._getMenuElement = function _getMenuElement() { 19026 if (!this._menu) { 19027 var parent = Dropdown._getParentFromElement(this._element); 19028 19029 this._menu = $$$1(parent).find(Selector.MENU)[0]; 19030 } 19031 19032 return this._menu; 19033 }; 19034 19035 _proto._getPlacement = function _getPlacement() { 19036 var $parentDropdown = $$$1(this._element).parent(); 19037 var placement = AttachmentMap.BOTTOM; // Handle dropup 19038 19039 if ($parentDropdown.hasClass(ClassName.DROPUP)) { 19040 placement = AttachmentMap.TOP; 19041 19042 if ($$$1(this._menu).hasClass(ClassName.MENURIGHT)) { 19043 placement = AttachmentMap.TOPEND; 19044 } 19045 } else if ($parentDropdown.hasClass(ClassName.DROPRIGHT)) { 19046 placement = AttachmentMap.RIGHT; 19047 } else if ($parentDropdown.hasClass(ClassName.DROPLEFT)) { 19048 placement = AttachmentMap.LEFT; 19049 } else if ($$$1(this._menu).hasClass(ClassName.MENURIGHT)) { 19050 placement = AttachmentMap.BOTTOMEND; 19051 } 19052 19053 return placement; 19054 }; 19055 19056 _proto._detectNavbar = function _detectNavbar() { 19057 return $$$1(this._element).closest('.navbar').length > 0; 19058 }; 19059 19060 _proto._getPopperConfig = function _getPopperConfig() { 19061 var _this2 = this; 19062 19063 var offsetConf = {}; 19064 19065 if (typeof this._config.offset === 'function') { 19066 offsetConf.fn = function (data) { 19067 data.offsets = _objectSpread({}, data.offsets, _this2._config.offset(data.offsets) || {}); 19068 return data; 19069 }; 19070 } else { 19071 offsetConf.offset = this._config.offset; 19072 } 19073 19074 var popperConfig = { 19075 placement: this._getPlacement(), 19076 modifiers: { 19077 offset: offsetConf, 19078 flip: { 19079 enabled: this._config.flip 19080 }, 19081 preventOverflow: {
vendor: 8,089 bytes, lines 19082-19334
19082 boundariesElement: this._config.boundary 19083 } 19084 } // Disable Popper.js if we have a static display 19085 19086 }; 19087 19088 if (this._config.display === 'static') { 19089 popperConfig.modifiers.applyStyle = { 19090 enabled: false 19091 }; 19092 } 19093 19094 return popperConfig; 19095 }; // Static 19096 19097 19098 Dropdown._jQueryInterface = function _jQueryInterface(config) { 19099 return this.each(function () { 19100 var data = $$$1(this).data(DATA_KEY); 19101 19102 var _config = _typeof(config) === 'object' ? config : null; 19103 19104 if (!data) { 19105 data = new Dropdown(this, _config); 19106 $$$1(this).data(DATA_KEY, data); 19107 } 19108 19109 if (typeof config === 'string') { 19110 if (typeof data[config] === 'undefined') { 19111 throw new TypeError("No method named \"" + config + "\""); 19112 } 19113 19114 data[config](); 19115 } 19116 }); 19117 }; 19118 19119 Dropdown._clearMenus = function _clearMenus(event) { 19120 if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) { 19121 return; 19122 } 19123 19124 var toggles = $$$1.makeArray($$$1(Selector.DATA_TOGGLE)); 19125 19126 for (var i = 0; i < toggles.length; i++) { 19127 var parent = Dropdown._getParentFromElement(toggles[i]); 19128 19129 var context = $$$1(toggles[i]).data(DATA_KEY); 19130 var relatedTarget = { 19131 relatedTarget: toggles[i] 19132 }; 19133 19134 if (!context) { 19135 continue; 19136 } 19137 19138 var dropdownMenu = context._menu; 19139 19140 if (!$$$1(parent).hasClass(ClassName.SHOW)) { 19141 continue; 19142 } 19143 19144 if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $$$1.contains(parent, event.target)) { 19145 continue; 19146 } 19147 19148 var hideEvent = $$$1.Event(Event.HIDE, relatedTarget); 19149 $$$1(parent).trigger(hideEvent); 19150 19151 if (hideEvent.isDefaultPrevented()) { 19152 continue; 19153 } // If this is a touch-enabled device we remove the extra 19154 // empty mouseover listeners we added for iOS support 19155 19156 19157 if ('ontouchstart' in document.documentElement) { 19158 $$$1(document.body).children().off('mouseover', null, $$$1.noop); 19159 } 19160 19161 toggles[i].setAttribute('aria-expanded', 'false'); 19162 $$$1(dropdownMenu).removeClass(ClassName.SHOW); 19163 $$$1(parent).removeClass(ClassName.SHOW).trigger($$$1.Event(Event.HIDDEN, relatedTarget)); 19164 } 19165 }; 19166 19167 Dropdown._getParentFromElement = function _getParentFromElement(element) { 19168 var parent; 19169 var selector = Util.getSelectorFromElement(element); 19170 19171 if (selector) { 19172 parent = $$$1(selector)[0]; 19173 } 19174 19175 return parent || element.parentNode; 19176 }; // eslint-disable-next-line complexity 19177 19178 19179 Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) { 19180 // If not input/textarea: 19181 // - And not a key in REGEXP_KEYDOWN => not a dropdown command 19182 // If input/textarea: 19183 // - If space key => not a dropdown command 19184 // - If key is other than escape 19185 // - If key is not up or down => not a dropdown command 19186 // - If trigger inside the menu => not a dropdown command 19187 if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $$$1(event.target).closest(Selector.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) { 19188 return; 19189 } 19190 19191 event.preventDefault(); 19192 event.stopPropagation(); 19193 19194 if (this.disabled || $$$1(this).hasClass(ClassName.DISABLED)) { 19195 return; 19196 } 19197 19198 var parent = Dropdown._getParentFromElement(this); 19199 19200 var isActive = $$$1(parent).hasClass(ClassName.SHOW); 19201 19202 if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) { 19203 if (event.which === ESCAPE_KEYCODE) { 19204 var toggle = $$$1(parent).find(Selector.DATA_TOGGLE)[0]; 19205 $$$1(toggle).trigger('focus'); 19206 } 19207 19208 $$$1(this).trigger('click'); 19209 return; 19210 } 19211 19212 var items = $$$1(parent).find(Selector.VISIBLE_ITEMS).get(); 19213 19214 if (items.length === 0) { 19215 return; 19216 } 19217 19218 var index = items.indexOf(event.target); 19219 19220 if (event.which === ARROW_UP_KEYCODE && index > 0) { 19221 // Up 19222 index--; 19223 } 19224 19225 if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { 19226 // Down 19227 index++; 19228 } 19229 19230 if (index < 0) { 19231 index = 0; 19232 } 19233 19234 items[index].focus(); 19235 }; 19236 19237 _createClass(Dropdown, null, [{ 19238 key: "VERSION", 19239 get: function get() { 19240 return VERSION; 19241 } 19242 }, { 19243 key: "Default", 19244 get: function get() { 19245 return Default; 19246 } 19247 }, { 19248 key: "DefaultType", 19249 get: function get() { 19250 return DefaultType; 19251 } 19252 }]); 19253 19254 return Dropdown; 19255 }(); 19256 /** 19257 * ------------------------------------------------------------------------ 19258 * Data Api implementation 19259 * ------------------------------------------------------------------------ 19260 */ 19261 19262 19263 $$$1(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + " " + Event.KEYUP_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { 19264 event.preventDefault(); 19265 event.stopPropagation(); 19266 19267 Dropdown._jQueryInterface.call($$$1(this), 'toggle'); 19268 }).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) { 19269 e.stopPropagation(); 19270 }); 19271 /** 19272 * ------------------------------------------------------------------------ 19273 * jQuery 19274 * ------------------------------------------------------------------------ 19275 */ 19276 19277 $$$1.fn[NAME] = Dropdown._jQueryInterface; 19278 $$$1.fn[NAME].Constructor = Dropdown; 19279 19280 $$$1.fn[NAME].noConflict = function () { 19281 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 19282 return Dropdown._jQueryInterface; 19283 }; 19284 19285 return Dropdown; 19286 }($, Popper); 19287 /** 19288 * -------------------------------------------------------------------------- 19289 * Bootstrap (v4.1.1): modal.js 19290 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 19291 * -------------------------------------------------------------------------- 19292 */ 19293 19294 19295 var Modal = function ($$$1) { 19296 /** 19297 * ------------------------------------------------------------------------ 19298 * Constants 19299 * ------------------------------------------------------------------------ 19300 */ 19301 var NAME = 'modal'; 19302 var VERSION = '4.1.1'; 19303 var DATA_KEY = 'bs.modal'; 19304 var EVENT_KEY = "." + DATA_KEY; 19305 var DATA_API_KEY = '.data-api'; 19306 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 19307 var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key 19308 19309 var Default = { 19310 backdrop: true, 19311 keyboard: true, 19312 focus: true, 19313 show: true 19314 }; 19315 var DefaultType = { 19316 backdrop: '(boolean|string)', 19317 keyboard: 'boolean', 19318 focus: 'boolean', 19319 show: 'boolean' 19320 }; 19321 var Event = { 19322 HIDE: "hide" + EVENT_KEY, 19323 HIDDEN: "hidden" + EVENT_KEY, 19324 SHOW: "show" + EVENT_KEY, 19325 SHOWN: "shown" + EVENT_KEY, 19326 FOCUSIN: "focusin" + EVENT_KEY, 19327 RESIZE: "resize" + EVENT_KEY, 19328 CLICK_DISMISS: "click.dismiss" + EVENT_KEY, 19329 KEYDOWN_DISMISS: "keydown.dismiss" + EVENT_KEY, 19330 MOUSEUP_DISMISS: "mouseup.dismiss" + EVENT_KEY, 19331 MOUSEDOWN_DISMISS: "mousedown.dismiss" + EVENT_KEY, 19332 CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY 19333 }; 19334 var ClassName = {
19335 SCROLLBAR_MEASURER: 'modal-scrollbar-measure', 19336 BACKDROP: 'modal-backdrop', 19337 OPEN: 'modal-open', 19338 FADE: 'fade', 19339 SHOW: 'show' 19340 }; 19341 var Selector = { 19342 DIALOG: '.modal-dialog', 19343 DATA_TOGGLE: '[data-toggle="modal"]', 19344 DATA_DISMISS: '[data-dismiss="modal"]', 19345 FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top', 19346 STICKY_CONTENT: '.sticky-top', 19347 NAVBAR_TOGGLER: '.navbar-toggler' 19348 /** 19349 * ------------------------------------------------------------------------ 19350 * Class Definition 19351 * ------------------------------------------------------------------------ 19352 */ 19353 19354 }; 19355 19356 var Modal = 19357 /*#__PURE__*/ 19358 function () { 19359 function Modal(element, config) { 19360 this._config = this._getConfig(config); 19361 this._element = element; 19362 this._dialog = $$$1(element).find(Selector.DIALOG)[0]; 19363 this._backdrop = null; 19364 this._isShown = false; 19365 this._isBodyOverflowing = false; 19366 this._ignoreBackdropClick = false; 19367 this._scrollbarWidth = 0; 19368 } // Getters 19369 19370 19371 var _proto = Modal.prototype; // Public 19372 19373 _proto.toggle = function toggle(relatedTarget) { 19374 return this._isShown ? this.hide() : this.show(relatedTarget); 19375 }; 19376 19377 _proto.show = function show(relatedTarget) { 19378 var _this = this; 19379 19380 if (this._isTransitioning || this._isShown) { 19381 return; 19382 } 19383 19384 if ($$$1(this._element).hasClass(ClassName.FADE)) { 19385 this._isTransitioning = true; 19386 } 19387 19388 var showEvent = $$$1.Event(Event.SHOW, { 19389 relatedTarget: relatedTarget 19390 }); 19391 $$$1(this._element).trigger(showEvent); 19392 19393 if (this._isShown || showEvent.isDefaultPrevented()) { 19394 return; 19395 } 19396 19397 this._isShown = true; 19398 19399 this._checkScrollbar(); 19400 19401 this._setScrollbar(); 19402 19403 this._adjustDialog(); 19404 19405 $$$1(document.body).addClass(ClassName.OPEN); 19406 19407 this._setEscapeEvent(); 19408 19409 this._setResizeEvent(); 19410 19411 $$$1(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, function (event) { 19412 return _this.hide(event); 19413 }); 19414 $$$1(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () { 19415 $$$1(_this._element).one(Event.MOUSEUP_DISMISS, function (event) { 19416 if ($$$1(event.target).is(_this._element)) { 19417 _this._ignoreBackdropClick = true; 19418 } 19419 }); 19420 }); 19421 19422 this._showBackdrop(function () { 19423 return _this._showElement(relatedTarget); 19424 }); 19425 }; 19426 19427 _proto.hide = function hide(event) { 19428 var _this2 = this; 19429 19430 if (event) { 19431 event.preventDefault(); 19432 } 19433 19434 if (this._isTransitioning || !this._isShown) { 19435 return; 19436 } 19437 19438 var hideEvent = $$$1.Event(Event.HIDE); 19439 $$$1(this._element).trigger(hideEvent); 19440 19441 if (!this._isShown || hideEvent.isDefaultPrevented()) { 19442 return; 19443 } 19444 19445 this._isShown = false; 19446 var transition = $$$1(this._element).hasClass(ClassName.FADE); 19447 19448 if (transition) { 19449 this._isTransitioning = true; 19450 } 19451 19452 this._setEscapeEvent(); 19453 19454 this._setResizeEvent(); 19455 19456 $$$1(document).off(Event.FOCUSIN); 19457 $$$1(this._element).removeClass(ClassName.SHOW); 19458 $$$1(this._element).off(Event.CLICK_DISMISS); 19459 $$$1(this._dialog).off(Event.MOUSEDOWN_DISMISS); 19460 19461 if (transition) { 19462 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 19463 $$$1(this._element).one(Util.TRANSITION_END, function (event) { 19464 return _this2._hideModal(event); 19465 }).emulateTransitionEnd(transitionDuration); 19466 } else { 19467 this._hideModal(); 19468 } 19469 }; 19470 19471 _proto.dispose = function dispose() { 19472 $$$1.removeData(this._element, DATA_KEY); 19473 $$$1(window, document, this._element, this._backdrop).off(EVENT_KEY); 19474 this._config = null; 19475 this._element = null; 19476 this._dialog = null; 19477 this._backdrop = null; 19478 this._isShown = null; 19479 this._isBodyOverflowing = null; 19480 this._ignoreBackdropClick = null; 19481 this._scrollbarWidth = null; 19482 }; 19483 19484 _proto.handleUpdate = function handleUpdate() { 19485 this._adjustDialog(); 19486 }; // Private 19487 19488 19489 _proto._getConfig = function _getConfig(config) { 19490 config = _objectSpread({}, Default, config); 19491 Util.typeCheckConfig(NAME, config, DefaultType); 19492 return config; 19493 }; 19494 19495 _proto._showElement = function _showElement(relatedTarget) { 19496 var _this3 = this; 19497 19498 var transition = $$$1(this._element).hasClass(ClassName.FADE); 19499 19500 if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { 19501 // Don't move modal's DOM position 19502 document.body.appendChild(this._element); 19503 } 19504 19505 this._element.style.display = 'block'; 19506 19507 this._element.removeAttribute('aria-hidden'); 19508 19509 this._element.scrollTop = 0; 19510 19511 if (transition) { 19512 Util.reflow(this._element); 19513 } 19514 19515 $$$1(this._element).addClass(ClassName.SHOW); 19516 19517 if (this._config.focus) { 19518 this._enforceFocus(); 19519 } 19520 19521 var shownEvent = $$$1.Event(Event.SHOWN, { 19522 relatedTarget: relatedTarget 19523 }); 19524 19525 var transitionComplete = function transitionComplete() { 19526 if (_this3._config.focus) { 19527 _this3._element.focus(); 19528 } 19529 19530 _this3._isTransitioning = false;
19531 $$$1(_this3._element).trigger(shownEvent); 19532 }; 19533 19534 if (transition) { 19535 var transitionDuration = Util.getTransitionDurationFromElement(this._element); 19536 $$$1(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration); 19537 } else { 19538 transitionComplete(); 19539 } 19540 }; 19541 19542 _proto._enforceFocus = function _enforceFocus() { 19543 var _this4 = this; 19544 19545 $$$1(document).off(Event.FOCUSIN) // Guard against infinite focus loop 19546 .on(Event.FOCUSIN, function (event) { 19547 if (document !== event.target && _this4._element !== event.target && $$$1(_this4._element).has(event.target).length === 0) { 19548 _this4._element.focus(); 19549 } 19550 }); 19551 }; 19552 19553 _proto._setEscapeEvent = function _setEscapeEvent() { 19554 var _this5 = this; 19555 19556 if (this._isShown && this._config.keyboard) { 19557 $$$1(this._element).on(Event.KEYDOWN_DISMISS, function (event) { 19558 if (event.which === ESCAPE_KEYCODE) { 19559 event.preventDefault(); 19560 19561 _this5.hide(); 19562 } 19563 }); 19564 } else if (!this._isShown) { 19565 $$$1(this._element).off(Event.KEYDOWN_DISMISS); 19566 } 19567 }; 19568 19569 _proto._setResizeEvent = function _setResizeEvent() { 19570 var _this6 = this; 19571 19572 if (this._isShown) { 19573 $$$1(window).on(Event.RESIZE, function (event) { 19574 return _this6.handleUpdate(event); 19575 }); 19576 } else { 19577 $$$1(window).off(Event.RESIZE); 19578 } 19579 }; 19580 19581 _proto._hideModal = function _hideModal() { 19582 var _this7 = this; 19583 19584 this._element.style.display = 'none'; 19585 19586 this._element.setAttribute('aria-hidden', true); 19587 19588 this._isTransitioning = false; 19589 19590 this._showBackdrop(function () { 19591 $$$1(document.body).removeClass(ClassName.OPEN); 19592 19593 _this7._resetAdjustments(); 19594 19595 _this7._resetScrollbar(); 19596 19597 $$$1(_this7._element).trigger(Event.HIDDEN); 19598 }); 19599 }; 19600 19601 _proto._removeBackdrop = function _removeBackdrop() { 19602 if (this._backdrop) { 19603 $$$1(this._backdrop).remove(); 19604 this._backdrop = null; 19605 } 19606 }; 19607 19608 _proto._showBackdrop = function _showBackdrop(callback) { 19609 var _this8 = this; 19610 19611 var animate = $$$1(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : ''; 19612 19613 if (this._isShown && this._config.backdrop) { 19614 this._backdrop = document.createElement('div'); 19615 this._backdrop.className = ClassName.BACKDROP; 19616 19617 if (animate) { 19618 $$$1(this._backdrop).addClass(animate); 19619 } 19620 19621 $$$1(this._backdrop).appendTo(document.body); 19622 $$$1(this._element).on(Event.CLICK_DISMISS, function (event) { 19623 if (_this8._ignoreBackdropClick) { 19624 _this8._ignoreBackdropClick = false; 19625 return; 19626 } 19627 19628 if (event.target !== event.currentTarget) { 19629 return; 19630 } 19631 19632 if (_this8._config.backdrop === 'static') { 19633 _this8._element.focus(); 19634 } else { 19635 _this8.hide(); 19636 } 19637 }); 19638 19639 if (animate) { 19640 Util.reflow(this._backdrop); 19641 } 19642 19643 $$$1(this._backdrop).addClass(ClassName.SHOW); 19644 19645 if (!callback) { 19646 return; 19647 } 19648 19649 if (!animate) { 19650 callback(); 19651 return; 19652 } 19653 19654 var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop); 19655 $$$1(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration); 19656 } else if (!this._isShown && this._backdrop) { 19657 $$$1(this._backdrop).removeClass(ClassName.SHOW); 19658 19659 var callbackRemove = function callbackRemove() { 19660 _this8._removeBackdrop(); 19661 19662 if (callback) { 19663 callback(); 19664 } 19665 }; 19666 19667 if ($$$1(this._element).hasClass(ClassName.FADE)) { 19668 var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop); 19669 19670 $$$1(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration); 19671 } else { 19672 callbackRemove(); 19673 } 19674 } else if (callback) { 19675 callback(); 19676 } 19677 }; // ---------------------------------------------------------------------- 19678 // the following methods are used to handle overflowing modals 19679 // todo (fat): these should probably be refactored out of modal.js 19680 // ---------------------------------------------------------------------- 19681 19682
19683 _proto._adjustDialog = function _adjustDialog() { 19684 var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 19685 19686 if (!this._isBodyOverflowing && isModalOverflowing) { 19687 this._element.style.paddingLeft = this._scrollbarWidth + "px"; 19688 } 19689 19690 if (this._isBodyOverflowing && !isModalOverflowing) { 19691 this._element.style.paddingRight = this._scrollbarWidth + "px"; 19692 } 19693 }; 19694 19695 _proto._resetAdjustments = function _resetAdjustments() { 19696 this._element.style.paddingLeft = ''; 19697 this._element.style.paddingRight = ''; 19698 }; 19699 19700 _proto._checkScrollbar = function _checkScrollbar() { 19701 var rect = document.body.getBoundingClientRect(); 19702 this._isBodyOverflowing = rect.left + rect.right < window.innerWidth; 19703 this._scrollbarWidth = this._getScrollbarWidth(); 19704 }; 19705 19706 _proto._setScrollbar = function _setScrollbar() { 19707 var _this9 = this; 19708 19709 if (this._isBodyOverflowing) { 19710 // Note: DOMNode.style.paddingRight returns the actual value or '' if not set 19711 // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set 19712 // Adjust fixed content padding 19713 $$$1(Selector.FIXED_CONTENT).each(function (index, element) { 19714 var actualPadding = $$$1(element)[0].style.paddingRight; 19715 var calculatedPadding = $$$1(element).css('padding-right'); 19716 $$$1(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this9._scrollbarWidth + "px"); 19717 }); // Adjust sticky content margin 19718 19719 $$$1(Selector.STICKY_CONTENT).each(function (index, element) { 19720 var actualMargin = $$$1(element)[0].style.marginRight; 19721 var calculatedMargin = $$$1(element).css('margin-right'); 19722 $$$1(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this9._scrollbarWidth + "px"); 19723 }); // Adjust navbar-toggler margin 19724 19725 $$$1(Selector.NAVBAR_TOGGLER).each(function (index, element) { 19726 var actualMargin = $$$1(element)[0].style.marginRight; 19727 var calculatedMargin = $$$1(element).css('margin-right'); 19728 $$$1(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) + _this9._scrollbarWidth + "px"); 19729 }); // Adjust body padding 19730 19731 var actualPadding = document.body.style.paddingRight; 19732 var calculatedPadding = $$$1(document.body).css('padding-right'); 19733 $$$1(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px"); 19734 } 19735 }; 19736 19737 _proto._resetScrollbar = function _resetScrollbar() { 19738 // Restore fixed content padding 19739 $$$1(Selector.FIXED_CONTENT).each(function (index, element) { 19740 var padding = $$$1(element).data('padding-right'); 19741 19742 if (typeof padding !== 'undefined') { 19743 $$$1(element).css('padding-right', padding).removeData('padding-right'); 19744 } 19745 }); // Restore sticky content and navbar-toggler margin 19746 19747 $$$1(Selector.STICKY_CONTENT + ", " + Selector.NAVBAR_TOGGLER).each(function (index, element) { 19748 var margin = $$$1(element).data('margin-right'); 19749 19750 if (typeof margin !== 'undefined') { 19751 $$$1(element).css('margin-right', margin).removeData('margin-right'); 19752 } 19753 }); // Restore body padding 19754 19755 var padding = $$$1(document.body).data('padding-right'); 19756 19757 if (typeof padding !== 'undefined') { 19758 $$$1(document.body).css('padding-right', padding).removeData('padding-right'); 19759 } 19760 }; 19761 19762 _proto._getScrollbarWidth = function _getScrollbarWidth() { 19763 // thx d.walsh 19764 var scrollDiv = document.createElement('div'); 19765 scrollDiv.className = ClassName.SCROLLBAR_MEASURER; 19766 document.body.appendChild(scrollDiv); 19767 var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth; 19768 document.body.removeChild(scrollDiv); 19769 return scrollbarWidth; 19770 }; // Static 19771 19772 19773 Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) { 19774 return this.each(function () { 19775 var data = $$$1(this).data(DATA_KEY); 19776 19777 var _config = _objectSpread({}, Default, $$$1(this).data(), _typeof(config) === 'object' && config ? config : {}); 19778 19779 if (!data) { 19780 data = new Modal(this, _config); 19781 $$$1(this).data(DATA_KEY, data); 19782 } 19783 19784 if (typeof config === 'string') { 19785 if (typeof data[config] === 'undefined') {
19786 throw new TypeError("No method named \"" + config + "\""); 19787 } 19788 19789 data[config](relatedTarget); 19790 } else if (_config.show) { 19791 data.show(relatedTarget); 19792 } 19793 }); 19794 }; 19795 19796 _createClass(Modal, null, [{ 19797 key: "VERSION", 19798 get: function get() { 19799 return VERSION; 19800 } 19801 }, { 19802 key: "Default", 19803 get: function get() { 19804 return Default; 19805 } 19806 }]); 19807 19808 return Modal; 19809 }(); 19810 /** 19811 * ------------------------------------------------------------------------ 19812 * Data Api implementation 19813 * ------------------------------------------------------------------------ 19814 */ 19815 19816 19817 $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { 19818 var _this10 = this; 19819 19820 var target; 19821 var selector = Util.getSelectorFromElement(this); 19822 19823 if (selector) { 19824 target = $$$1(selector)[0]; 19825 } 19826 19827 var config = $$$1(target).data(DATA_KEY) ? 'toggle' : _objectSpread({}, $$$1(target).data(), $$$1(this).data()); 19828 19829 if (this.tagName === 'A' || this.tagName === 'AREA') { 19830 event.preventDefault(); 19831 } 19832 19833 var $target = $$$1(target).one(Event.SHOW, function (showEvent) { 19834 if (showEvent.isDefaultPrevented()) { 19835 // Only register focus restorer if modal will actually get shown 19836 return; 19837 } 19838 19839 $target.one(Event.HIDDEN, function () { 19840 if ($$$1(_this10).is(':visible')) { 19841 _this10.focus(); 19842 } 19843 }); 19844 }); 19845 19846 Modal._jQueryInterface.call($$$1(target), config, this); 19847 }); 19848 /** 19849 * ------------------------------------------------------------------------ 19850 * jQuery 19851 * ------------------------------------------------------------------------ 19852 */ 19853 19854 $$$1.fn[NAME] = Modal._jQueryInterface; 19855 $$$1.fn[NAME].Constructor = Modal; 19856 19857 $$$1.fn[NAME].noConflict = function () { 19858 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 19859 return Modal._jQueryInterface; 19860 }; 19861 19862 return Modal; 19863 }($); 19864 /** 19865 * -------------------------------------------------------------------------- 19866 * Bootstrap (v4.1.1): tooltip.js 19867 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 19868 * -------------------------------------------------------------------------- 19869 */ 19870 19871 19872 var Tooltip = function ($$$1) { 19873 /** 19874 * ------------------------------------------------------------------------ 19875 * Constants 19876 * ------------------------------------------------------------------------ 19877 */ 19878 var NAME = 'tooltip'; 19879 var VERSION = '4.1.1'; 19880 var DATA_KEY = 'bs.tooltip'; 19881 var EVENT_KEY = "." + DATA_KEY; 19882 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 19883 var CLASS_PREFIX = 'bs-tooltip'; 19884 var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); 19885 var DefaultType = { 19886 animation: 'boolean', 19887 template: 'string', 19888 title: '(string|element|function)', 19889 trigger: 'string', 19890 delay: '(number|object)', 19891 html: 'boolean', 19892 selector: '(string|boolean)', 19893 placement: '(string|function)', 19894 offset: '(number|string)', 19895 container: '(string|element|boolean)', 19896 fallbackPlacement: '(string|array)', 19897 boundary: '(string|element)' 19898 }; 19899 var AttachmentMap = { 19900 AUTO: 'auto', 19901 TOP: 'top', 19902 RIGHT: 'right', 19903 BOTTOM: 'bottom', 19904 LEFT: 'left' 19905 }; 19906 var Default = { 19907 animation: true, 19908 template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>', 19909 trigger: 'hover focus', 19910 title: '', 19911 delay: 0, 19912 html: false, 19913 selector: false, 19914 placement: 'top', 19915 offset: 0, 19916 container: false, 19917 fallbackPlacement: 'flip', 19918 boundary: 'scrollParent' 19919 }; 19920 var HoverState = { 19921 SHOW: 'show', 19922 OUT: 'out' 19923 }; 19924 var Event = { 19925 HIDE: "hide" + EVENT_KEY, 19926 HIDDEN: "hidden" + EVENT_KEY, 19927 SHOW: "show" + EVENT_KEY, 19928 SHOWN: "shown" + EVENT_KEY, 19929 INSERTED: "inserted" + EVENT_KEY, 19930 CLICK: "click" + EVENT_KEY, 19931 FOCUSIN: "focusin" + EVENT_KEY, 19932 FOCUSOUT: "focusout" + EVENT_KEY, 19933 MOUSEENTER: "mouseenter" + EVENT_KEY, 19934 MOUSELEAVE: "mouseleave" + EVENT_KEY 19935 }; 19936 var ClassName = { 19937 FADE: 'fade', 19938 SHOW: 'show' 19939 }; 19940 var Selector = { 19941 TOOLTIP: '.tooltip', 19942 TOOLTIP_INNER: '.tooltip-inner', 19943 ARROW: '.arrow' 19944 }; 19945 var Trigger = {
19946 HOVER: 'hover', 19947 FOCUS: 'focus', 19948 CLICK: 'click', 19949 MANUAL: 'manual' 19950 /** 19951 * ------------------------------------------------------------------------ 19952 * Class Definition 19953 * ------------------------------------------------------------------------ 19954 */ 19955 19956 }; 19957 19958 var Tooltip = 19959 /*#__PURE__*/ 19960 function () { 19961 function Tooltip(element, config) { 19962 /** 19963 * Check for Popper dependency 19964 * Popper - https://popper.js.org 19965 */ 19966 if (typeof Popper === 'undefined') { 19967 throw new TypeError('Bootstrap tooltips require Popper.js (https://popper.js.org)'); 19968 } // private 19969 19970 19971 this._isEnabled = true; 19972 this._timeout = 0; 19973 this._hoverState = ''; 19974 this._activeTrigger = {}; 19975 this._popper = null; // Protected 19976 19977 this.element = element; 19978 this.config = this._getConfig(config); 19979 this.tip = null; 19980 19981 this._setListeners(); 19982 } // Getters 19983 19984 19985 var _proto = Tooltip.prototype; // Public 19986 19987 _proto.enable = function enable() { 19988 this._isEnabled = true; 19989 }; 19990 19991 _proto.disable = function disable() { 19992 this._isEnabled = false; 19993 }; 19994 19995 _proto.toggleEnabled = function toggleEnabled() { 19996 this._isEnabled = !this._isEnabled; 19997 }; 19998 19999 _proto.toggle = function toggle(event) { 20000 if (!this._isEnabled) { 20001 return; 20002 } 20003 20004 if (event) { 20005 var dataKey = this.constructor.DATA_KEY; 20006 var context = $$$1(event.currentTarget).data(dataKey); 20007 20008 if (!context) { 20009 context = new this.constructor(event.currentTarget, this._getDelegateConfig()); 20010 $$$1(event.currentTarget).data(dataKey, context); 20011 } 20012 20013 context._activeTrigger.click = !context._activeTrigger.click; 20014 20015 if (context._isWithActiveTrigger()) { 20016 context._enter(null, context); 20017 } else { 20018 context._leave(null, context); 20019 } 20020 } else { 20021 if ($$$1(this.getTipElement()).hasClass(ClassName.SHOW)) { 20022 this._leave(null, this); 20023 20024 return; 20025 } 20026 20027 this._enter(null, this); 20028 } 20029 }; 20030 20031 _proto.dispose = function dispose() { 20032 clearTimeout(this._timeout); 20033 $$$1.removeData(this.element, this.constructor.DATA_KEY); 20034 $$$1(this.element).off(this.constructor.EVENT_KEY); 20035 $$$1(this.element).closest('.modal').off('hide.bs.modal'); 20036 20037 if (this.tip) { 20038 $$$1(this.tip).remove(); 20039 } 20040 20041 this._isEnabled = null; 20042 this._timeout = null; 20043 this._hoverState = null; 20044 this._activeTrigger = null; 20045 20046 if (this._popper !== null) { 20047 this._popper.destroy(); 20048 } 20049 20050 this._popper = null; 20051 this.element = null; 20052 this.config = null; 20053 this.tip = null; 20054 }; 20055 20056 _proto.show = function show() { 20057 var _this = this; 20058 20059 if ($$$1(this.element).css('display') === 'none') { 20060 throw new Error('Please use show on visible elements'); 20061 } 20062 20063 var showEvent = $$$1.Event(this.constructor.Event.SHOW); 20064 20065 if (this.isWithContent() && this._isEnabled) { 20066 $$$1(this.element).trigger(showEvent); 20067 var isInTheDom = $$$1.contains(this.element.ownerDocument.documentElement, this.element); 20068 20069 if (showEvent.isDefaultPrevented() || !isInTheDom) { 20070 return; 20071 } 20072 20073 var tip = this.getTipElement(); 20074 var tipId = Util.getUID(this.constructor.NAME);
20075 tip.setAttribute('id', tipId); 20076 this.element.setAttribute('aria-describedby', tipId); 20077 this.setContent(); 20078 20079 if (this.config.animation) { 20080 $$$1(tip).addClass(ClassName.FADE); 20081 } 20082 20083 var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; 20084 20085 var attachment = this._getAttachment(placement); 20086 20087 this.addAttachmentClass(attachment); 20088 var container = this.config.container === false ? document.body : $$$1(this.config.container); 20089 $$$1(tip).data(this.constructor.DATA_KEY, this); 20090 20091 if (!$$$1.contains(this.element.ownerDocument.documentElement, this.tip)) { 20092 $$$1(tip).appendTo(container); 20093 } 20094 20095 $$$1(this.element).trigger(this.constructor.Event.INSERTED); 20096 this._popper = new Popper(this.element, tip, { 20097 placement: attachment, 20098 modifiers: { 20099 offset: { 20100 offset: this.config.offset 20101 }, 20102 flip: { 20103 behavior: this.config.fallbackPlacement 20104 }, 20105 arrow: { 20106 element: Selector.ARROW 20107 }, 20108 preventOverflow: { 20109 boundariesElement: this.config.boundary 20110 } 20111 }, 20112 onCreate: function onCreate(data) { 20113 if (data.originalPlacement !== data.placement) { 20114 _this._handlePopperPlacementChange(data); 20115 } 20116 }, 20117 onUpdate: function onUpdate(data) { 20118 _this._handlePopperPlacementChange(data); 20119 } 20120 }); 20121 $$$1(tip).addClass(ClassName.SHOW); // If this is a touch-enabled device we add extra 20122 // empty mouseover listeners to the body's immediate children; 20123 // only needed because of broken event delegation on iOS 20124 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 20125 20126 if ('ontouchstart' in document.documentElement) { 20127 $$$1(document.body).children().on('mouseover', null, $$$1.noop); 20128 } 20129 20130 var complete = function complete() { 20131 if (_this.config.animation) { 20132 _this._fixTransition(); 20133 } 20134 20135 var prevHoverState = _this._hoverState; 20136 _this._hoverState = null; 20137 $$$1(_this.element).trigger(_this.constructor.Event.SHOWN); 20138 20139 if (prevHoverState === HoverState.OUT) { 20140 _this._leave(null, _this); 20141 } 20142 }; 20143 20144 if ($$$1(this.tip).hasClass(ClassName.FADE)) { 20145 var transitionDuration = Util.getTransitionDurationFromElement(this.tip); 20146 $$$1(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 20147 } else { 20148 complete(); 20149 } 20150 } 20151 }; 20152 20153 _proto.hide = function hide(callback) { 20154 var _this2 = this; 20155 20156 var tip = this.getTipElement(); 20157 var hideEvent = $$$1.Event(this.constructor.Event.HIDE); 20158 20159 var complete = function complete() { 20160 if (_this2._hoverState !== HoverState.SHOW && tip.parentNode) { 20161 tip.parentNode.removeChild(tip); 20162 } 20163 20164 _this2._cleanTipClass(); 20165 20166 _this2.element.removeAttribute('aria-describedby'); 20167 20168 $$$1(_this2.element).trigger(_this2.constructor.Event.HIDDEN); 20169 20170 if (_this2._popper !== null) { 20171 _this2._popper.destroy(); 20172 } 20173 20174 if (callback) { 20175 callback(); 20176 } 20177 }; 20178 20179 $$$1(this.element).trigger(hideEvent); 20180 20181 if (hideEvent.isDefaultPrevented()) { 20182 return; 20183 } 20184 20185 $$$1(tip).removeClass(ClassName.SHOW); // If this is a touch-enabled device we remove the extra 20186 // empty mouseover listeners we added for iOS support 20187 20188 if ('ontouchstart' in document.documentElement) { 20189 $$$1(document.body).children().off('mouseover', null, $$$1.noop); 20190 } 20191 20192 this._activeTrigger[Trigger.CLICK] = false;
20193 this._activeTrigger[Trigger.FOCUS] = false; 20194 this._activeTrigger[Trigger.HOVER] = false; 20195 20196 if ($$$1(this.tip).hasClass(ClassName.FADE)) { 20197 var transitionDuration = Util.getTransitionDurationFromElement(tip); 20198 $$$1(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 20199 } else { 20200 complete(); 20201 } 20202 20203 this._hoverState = ''; 20204 }; 20205 20206 _proto.update = function update() { 20207 if (this._popper !== null) { 20208 this._popper.scheduleUpdate(); 20209 } 20210 }; // Protected 20211 20212 20213 _proto.isWithContent = function isWithContent() { 20214 return Boolean(this.getTitle()); 20215 }; 20216 20217 _proto.addAttachmentClass = function addAttachmentClass(attachment) { 20218 $$$1(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); 20219 }; 20220 20221 _proto.getTipElement = function getTipElement() { 20222 this.tip = this.tip || $$$1(this.config.template)[0]; 20223 return this.tip; 20224 }; 20225 20226 _proto.setContent = function setContent() { 20227 var $tip = $$$1(this.getTipElement()); 20228 this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle()); 20229 $tip.removeClass(ClassName.FADE + " " + ClassName.SHOW); 20230 }; 20231 20232 _proto.setElementContent = function setElementContent($element, content) { 20233 var html = this.config.html; 20234 20235 if (_typeof(content) === 'object' && (content.nodeType || content.jquery)) { 20236 // Content is a DOM node or a jQuery 20237 if (html) { 20238 if (!$$$1(content).parent().is($element)) { 20239 $element.empty().append(content); 20240 } 20241 } else { 20242 $element.text($$$1(content).text()); 20243 } 20244 } else { 20245 $element[html ? 'html' : 'text'](content); 20246 } 20247 }; 20248 20249 _proto.getTitle = function getTitle() { 20250 var title = this.element.getAttribute('data-original-title'); 20251 20252 if (!title) { 20253 title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title; 20254 } 20255 20256 return title; 20257 }; // Private 20258 20259 20260 _proto._getAttachment = function _getAttachment(placement) { 20261 return AttachmentMap[placement.toUpperCase()]; 20262 }; 20263 20264 _proto._setListeners = function _setListeners() { 20265 var _this3 = this; 20266 20267 var triggers = this.config.trigger.split(' '); 20268 triggers.forEach(function (trigger) { 20269 if (trigger === 'click') { 20270 $$$1(_this3.element).on(_this3.constructor.Event.CLICK, _this3.config.selector, function (event) { 20271 return _this3.toggle(event); 20272 }); 20273 } else if (trigger !== Trigger.MANUAL) { 20274 var eventIn = trigger === Trigger.HOVER ? _this3.constructor.Event.MOUSEENTER : _this3.constructor.Event.FOCUSIN; 20275 var eventOut = trigger === Trigger.HOVER ? _this3.constructor.Event.MOUSELEAVE : _this3.constructor.Event.FOCUSOUT; 20276 $$$1(_this3.element).on(eventIn, _this3.config.selector, function (event) { 20277 return _this3._enter(event); 20278 }).on(eventOut, _this3.config.selector, function (event) { 20279 return _this3._leave(event); 20280 }); 20281 } 20282 20283 $$$1(_this3.element).closest('.modal').on('hide.bs.modal', function () { 20284 return _this3.hide(); 20285 }); 20286 }); 20287 20288 if (this.config.selector) { 20289 this.config = _objectSpread({}, this.config, { 20290 trigger: 'manual', 20291 selector: '' 20292 }); 20293 } else { 20294 this._fixTitle(); 20295 } 20296 }; 20297 20298 _proto._fixTitle = function _fixTitle() { 20299 var titleType = _typeof(this.element.getAttribute('data-original-title')); 20300 20301 if (this.element.getAttribute('title') || titleType !== 'string') { 20302 this.element.setAttribute('data-original-title', this.element.getAttribute('title') || ''); 20303 this.element.setAttribute('title', ''); 20304 } 20305 }; 20306 20307 _proto._enter = function _enter(event, context) { 20308 var dataKey = this.constructor.DATA_KEY; 20309 context = context || $$$1(event.currentTarget).data(dataKey); 20310 20311 if (!context) { 20312 context = new this.constructor(event.currentTarget, this._getDelegateConfig()); 20313 $$$1(event.currentTarget).data(dataKey, context); 20314 } 20315 20316 if (event) { 20317 context._activeTrigger[event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true; 20318 } 20319 20320 if ($$$1(context.getTipElement()).hasClass(ClassName.SHOW) || context._hoverState === HoverState.SHOW) { 20321 context._hoverState = HoverState.SHOW; 20322 return; 20323 } 20324 20325 clearTimeout(context._timeout); 20326 context._hoverState = HoverState.SHOW; 20327 20328 if (!context.config.delay || !context.config.delay.show) { 20329 context.show(); 20330 return; 20331 } 20332 20333 context._timeout = setTimeout(function () { 20334 if (context._hoverState === HoverState.SHOW) { 20335 context.show(); 20336 } 20337 }, context.config.delay.show); 20338 }; 20339 20340 _proto._leave = function _leave(event, context) { 20341 var dataKey = this.constructor.DATA_KEY; 20342 context = context || $$$1(event.currentTarget).data(dataKey); 20343 20344 if (!context) { 20345 context = new this.constructor(event.currentTarget, this._getDelegateConfig()); 20346 $$$1(event.currentTarget).data(dataKey, context); 20347 } 20348 20349 if (event) { 20350 context._activeTrigger[event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false;
vendor: 5,320 bytes, lines 20351-20548
20351 } 20352 20353 if (context._isWithActiveTrigger()) { 20354 return; 20355 } 20356 20357 clearTimeout(context._timeout); 20358 context._hoverState = HoverState.OUT; 20359 20360 if (!context.config.delay || !context.config.delay.hide) { 20361 context.hide(); 20362 return; 20363 } 20364 20365 context._timeout = setTimeout(function () { 20366 if (context._hoverState === HoverState.OUT) { 20367 context.hide(); 20368 } 20369 }, context.config.delay.hide); 20370 }; 20371 20372 _proto._isWithActiveTrigger = function _isWithActiveTrigger() { 20373 for (var trigger in this._activeTrigger) { 20374 if (this._activeTrigger[trigger]) { 20375 return true; 20376 } 20377 } 20378 20379 return false; 20380 }; 20381 20382 _proto._getConfig = function _getConfig(config) { 20383 config = _objectSpread({}, this.constructor.Default, $$$1(this.element).data(), _typeof(config) === 'object' && config ? config : {}); 20384 20385 if (typeof config.delay === 'number') { 20386 config.delay = { 20387 show: config.delay, 20388 hide: config.delay 20389 }; 20390 } 20391 20392 if (typeof config.title === 'number') { 20393 config.title = config.title.toString(); 20394 } 20395 20396 if (typeof config.content === 'number') { 20397 config.content = config.content.toString(); 20398 } 20399 20400 Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); 20401 return config; 20402 }; 20403 20404 _proto._getDelegateConfig = function _getDelegateConfig() { 20405 var config = {}; 20406 20407 if (this.config) { 20408 for (var key in this.config) { 20409 if (this.constructor.Default[key] !== this.config[key]) { 20410 config[key] = this.config[key]; 20411 } 20412 } 20413 } 20414 20415 return config; 20416 }; 20417 20418 _proto._cleanTipClass = function _cleanTipClass() { 20419 var $tip = $$$1(this.getTipElement()); 20420 var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); 20421 20422 if (tabClass !== null && tabClass.length > 0) { 20423 $tip.removeClass(tabClass.join('')); 20424 } 20425 }; 20426 20427 _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(data) { 20428 this._cleanTipClass(); 20429 20430 this.addAttachmentClass(this._getAttachment(data.placement)); 20431 }; 20432 20433 _proto._fixTransition = function _fixTransition() { 20434 var tip = this.getTipElement(); 20435 var initConfigAnimation = this.config.animation; 20436 20437 if (tip.getAttribute('x-placement') !== null) { 20438 return; 20439 } 20440 20441 $$$1(tip).removeClass(ClassName.FADE); 20442 this.config.animation = false; 20443 this.hide(); 20444 this.show(); 20445 this.config.animation = initConfigAnimation; 20446 }; // Static 20447 20448 20449 Tooltip._jQueryInterface = function _jQueryInterface(config) { 20450 return this.each(function () { 20451 var data = $$$1(this).data(DATA_KEY); 20452 20453 var _config = _typeof(config) === 'object' && config; 20454 20455 if (!data && /dispose|hide/.test(config)) { 20456 return; 20457 } 20458 20459 if (!data) { 20460 data = new Tooltip(this, _config); 20461 $$$1(this).data(DATA_KEY, data); 20462 } 20463 20464 if (typeof config === 'string') { 20465 if (typeof data[config] === 'undefined') { 20466 throw new TypeError("No method named \"" + config + "\""); 20467 } 20468 20469 data[config](); 20470 } 20471 }); 20472 }; 20473 20474 _createClass(Tooltip, null, [{ 20475 key: "VERSION", 20476 get: function get() { 20477 return VERSION; 20478 } 20479 }, { 20480 key: "Default", 20481 get: function get() { 20482 return Default; 20483 } 20484 }, { 20485 key: "NAME", 20486 get: function get() { 20487 return NAME; 20488 } 20489 }, { 20490 key: "DATA_KEY", 20491 get: function get() { 20492 return DATA_KEY; 20493 } 20494 }, { 20495 key: "Event", 20496 get: function get() { 20497 return Event; 20498 } 20499 }, { 20500 key: "EVENT_KEY", 20501 get: function get() { 20502 return EVENT_KEY; 20503 } 20504 }, { 20505 key: "DefaultType", 20506 get: function get() { 20507 return DefaultType; 20508 } 20509 }]); 20510 20511 return Tooltip; 20512 }(); 20513 /** 20514 * ------------------------------------------------------------------------ 20515 * jQuery 20516 * ------------------------------------------------------------------------ 20517 */ 20518 20519 20520 $$$1.fn[NAME] = Tooltip._jQueryInterface; 20521 $$$1.fn[NAME].Constructor = Tooltip; 20522 20523 $$$1.fn[NAME].noConflict = function () { 20524 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 20525 return Tooltip._jQueryInterface; 20526 }; 20527 20528 return Tooltip; 20529 }($, Popper); 20530 /** 20531 * -------------------------------------------------------------------------- 20532 * Bootstrap (v4.1.1): popover.js 20533 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 20534 * -------------------------------------------------------------------------- 20535 */ 20536 20537 20538 var Popover = function ($$$1) { 20539 /** 20540 * ------------------------------------------------------------------------ 20541 * Constants 20542 * ------------------------------------------------------------------------ 20543 */ 20544 var NAME = 'popover'; 20545 var VERSION = '4.1.1'; 20546 var DATA_KEY = 'bs.popover'; 20547 var EVENT_KEY = "." + DATA_KEY; 20548 var JQUERY_NO_CONFLICT = $$$1.fn[NAME];
20549 var CLASS_PREFIX = 'bs-popover'; 20550 var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); 20551 20552 var Default = _objectSpread({}, Tooltip.Default, { 20553 placement: 'right', 20554 trigger: 'click', 20555 content: '', 20556 template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>' 20557 }); 20558 20559 var DefaultType = _objectSpread({}, Tooltip.DefaultType, { 20560 content: '(string|element|function)' 20561 }); 20562 20563 var ClassName = { 20564 FADE: 'fade', 20565 SHOW: 'show' 20566 }; 20567 var Selector = { 20568 TITLE: '.popover-header', 20569 CONTENT: '.popover-body' 20570 }; 20571 var Event = { 20572 HIDE: "hide" + EVENT_KEY, 20573 HIDDEN: "hidden" + EVENT_KEY, 20574 SHOW: "show" + EVENT_KEY, 20575 SHOWN: "shown" + EVENT_KEY, 20576 INSERTED: "inserted" + EVENT_KEY, 20577 CLICK: "click" + EVENT_KEY, 20578 FOCUSIN: "focusin" + EVENT_KEY, 20579 FOCUSOUT: "focusout" + EVENT_KEY, 20580 MOUSEENTER: "mouseenter" + EVENT_KEY, 20581 MOUSELEAVE: "mouseleave" + EVENT_KEY 20582 /** 20583 * ------------------------------------------------------------------------ 20584 * Class Definition 20585 * ------------------------------------------------------------------------ 20586 */ 20587 20588 }; 20589 20590 var Popover = 20591 /*#__PURE__*/ 20592 function (_Tooltip) { 20593 _inheritsLoose(Popover, _Tooltip); 20594 20595 function Popover() { 20596 return _Tooltip.apply(this, arguments) || this; 20597 } 20598 20599 var _proto = Popover.prototype; // Overrides 20600 20601 _proto.isWithContent = function isWithContent() { 20602 return this.getTitle() || this._getContent(); 20603 }; 20604 20605 _proto.addAttachmentClass = function addAttachmentClass(attachment) { 20606 $$$1(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); 20607 }; 20608 20609 _proto.getTipElement = function getTipElement() { 20610 this.tip = this.tip || $$$1(this.config.template)[0]; 20611 return this.tip; 20612 }; 20613 20614 _proto.setContent = function setContent() { 20615 var $tip = $$$1(this.getTipElement()); // We use append for html objects to maintain js events 20616 20617 this.setElementContent($tip.find(Selector.TITLE), this.getTitle()); 20618 20619 var content = this._getContent(); 20620 20621 if (typeof content === 'function') { 20622 content = content.call(this.element); 20623 } 20624 20625 this.setElementContent($tip.find(Selector.CONTENT), content); 20626 $tip.removeClass(ClassName.FADE + " " + ClassName.SHOW); 20627 }; // Private 20628 20629 20630 _proto._getContent = function _getContent() { 20631 return this.element.getAttribute('data-content') || this.config.content; 20632 }; 20633 20634 _proto._cleanTipClass = function _cleanTipClass() { 20635 var $tip = $$$1(this.getTipElement()); 20636 var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); 20637 20638 if (tabClass !== null && tabClass.length > 0) { 20639 $tip.removeClass(tabClass.join('')); 20640 } 20641 }; // Static 20642 20643 20644 Popover._jQueryInterface = function _jQueryInterface(config) { 20645 return this.each(function () { 20646 var data = $$$1(this).data(DATA_KEY); 20647 20648 var _config = _typeof(config) === 'object' ? config : null; 20649 20650 if (!data && /destroy|hide/.test(config)) { 20651 return; 20652 } 20653 20654 if (!data) { 20655 data = new Popover(this, _config); 20656 $$$1(this).data(DATA_KEY, data); 20657 } 20658 20659 if (typeof config === 'string') { 20660 if (typeof data[config] === 'undefined') { 20661 throw new TypeError("No method named \"" + config + "\""); 20662 } 20663 20664 data[config](); 20665 } 20666 }); 20667 }; 20668 20669 _createClass(Popover, null, [{ 20670 key: "VERSION", 20671 // Getters 20672 get: function get() { 20673 return VERSION; 20674 } 20675 }, { 20676 key: "Default", 20677 get: function get() { 20678 return Default; 20679 } 20680 }, { 20681 key: "NAME", 20682 get: function get() { 20683 return NAME; 20684 } 20685 }, { 20686 key: "DATA_KEY", 20687 get: function get() { 20688 return DATA_KEY; 20689 } 20690 }, { 20691 key: "Event", 20692 get: function get() { 20693 return Event; 20694 } 20695 }, { 20696 key: "EVENT_KEY", 20697 get: function get() { 20698 return EVENT_KEY; 20699 } 20700 }, { 20701 key: "DefaultType", 20702 get: function get() { 20703 return DefaultType; 20704 } 20705 }]); 20706 20707 return Popover; 20708 }(Tooltip); 20709 /** 20710 * ------------------------------------------------------------------------ 20711 * jQuery 20712 * ------------------------------------------------------------------------ 20713 */ 20714 20715 20716 $$$1.fn[NAME] = Popover._jQueryInterface; 20717 $$$1.fn[NAME].Constructor = Popover; 20718 20719 $$$1.fn[NAME].noConflict = function () { 20720 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 20721 return Popover._jQueryInterface; 20722 }; 20723 20724 return Popover; 20725 }($); 20726 /** 20727 * -------------------------------------------------------------------------- 20728 * Bootstrap (v4.1.1): scrollspy.js 20729 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 20730 * -------------------------------------------------------------------------- 20731 */ 20732 20733 20734 var ScrollSpy = function ($$$1) { 20735 /** 20736 * ------------------------------------------------------------------------ 20737 * Constants 20738 * ------------------------------------------------------------------------ 20739 */ 20740 var NAME = 'scrollspy'; 20741 var VERSION = '4.1.1'; 20742 var DATA_KEY = 'bs.scrollspy'; 20743 var EVENT_KEY = "." + DATA_KEY; 20744 var DATA_API_KEY = '.data-api'; 20745 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 20746 var Default = { 20747 offset: 10, 20748 method: 'auto', 20749 target: '' 20750 }; 20751 var DefaultType = { 20752 offset: 'number', 20753 method: 'string', 20754 target: '(string|element)' 20755 }; 20756 var Event = { 20757 ACTIVATE: "activate" + EVENT_KEY, 20758 SCROLL: "scroll" + EVENT_KEY, 20759 LOAD_DATA_API: "load" + EVENT_KEY + DATA_API_KEY 20760 }; 20761 var ClassName = {
20762 DROPDOWN_ITEM: 'dropdown-item', 20763 DROPDOWN_MENU: 'dropdown-menu', 20764 ACTIVE: 'active' 20765 }; 20766 var Selector = { 20767 DATA_SPY: '[data-spy="scroll"]', 20768 ACTIVE: '.active', 20769 NAV_LIST_GROUP: '.nav, .list-group', 20770 NAV_LINKS: '.nav-link', 20771 NAV_ITEMS: '.nav-item', 20772 LIST_ITEMS: '.list-group-item', 20773 DROPDOWN: '.dropdown', 20774 DROPDOWN_ITEMS: '.dropdown-item', 20775 DROPDOWN_TOGGLE: '.dropdown-toggle' 20776 }; 20777 var OffsetMethod = { 20778 OFFSET: 'offset', 20779 POSITION: 'position' 20780 /** 20781 * ------------------------------------------------------------------------ 20782 * Class Definition 20783 * ------------------------------------------------------------------------ 20784 */ 20785 20786 }; 20787 20788 var ScrollSpy = 20789 /*#__PURE__*/ 20790 function () { 20791 function ScrollSpy(element, config) { 20792 var _this = this; 20793 20794 this._element = element; 20795 this._scrollElement = element.tagName === 'BODY' ? window : element; 20796 this._config = this._getConfig(config); 20797 this._selector = this._config.target + " " + Selector.NAV_LINKS + "," + (this._config.target + " " + Selector.LIST_ITEMS + ",") + (this._config.target + " " + Selector.DROPDOWN_ITEMS); 20798 this._offsets = []; 20799 this._targets = []; 20800 this._activeTarget = null; 20801 this._scrollHeight = 0; 20802 $$$1(this._scrollElement).on(Event.SCROLL, function (event) { 20803 return _this._process(event); 20804 }); 20805 this.refresh(); 20806 20807 this._process(); 20808 } // Getters 20809 20810 20811 var _proto = ScrollSpy.prototype; // Public 20812 20813 _proto.refresh = function refresh() { 20814 var _this2 = this; 20815 20816 var autoMethod = this._scrollElement === this._scrollElement.window ? OffsetMethod.OFFSET : OffsetMethod.POSITION; 20817 var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method; 20818 var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0; 20819 this._offsets = []; 20820 this._targets = []; 20821 this._scrollHeight = this._getScrollHeight(); 20822 var targets = $$$1.makeArray($$$1(this._selector)); 20823 targets.map(function (element) { 20824 var target; 20825 var targetSelector = Util.getSelectorFromElement(element); 20826 20827 if (targetSelector) { 20828 target = $$$1(targetSelector)[0]; 20829 } 20830 20831 if (target) { 20832 var targetBCR = target.getBoundingClientRect(); 20833 20834 if (targetBCR.width || targetBCR.height) { 20835 // TODO (fat): remove sketch reliance on jQuery position/offset 20836 return [$$$1(target)[offsetMethod]().top + offsetBase, targetSelector]; 20837 } 20838 } 20839 20840 return null; 20841 }).filter(function (item) { 20842 return item; 20843 }).sort(function (a, b) { 20844 return a[0] - b[0]; 20845 }
20845).forEach(function (item) { 20846 _this2._offsets.push(item[0]); 20847 20848 _this2._targets.push(item[1]); 20849 }); 20850 }; 20851 20852 _proto.dispose = function dispose() { 20853 $$$1.removeData(this._element, DATA_KEY); 20854 $$$1(this._scrollElement).off(EVENT_KEY); 20855 this._element = null; 20856 this._scrollElement = null; 20857 this._config = null; 20858 this._selector = null; 20859 this._offsets = null; 20860 this._targets = null; 20861 this._activeTarget = null; 20862 this._scrollHeight = null; 20863 }; // Private 20864 20865 20866 _proto._getConfig = function _getConfig(config) { 20867 config = _objectSpread({}, Default, _typeof(config) === 'object' && config ? config : {}); 20868 20869 if (typeof config.target !== 'string') { 20870 var id = $$$1(config.target).attr('id'); 20871 20872 if (!id) { 20873 id = Util.getUID(NAME); 20874 $$$1(config.target).attr('id', id); 20875 } 20876 20877 config.target = "#" + id; 20878 } 20879 20880 Util.typeCheckConfig(NAME, config, DefaultType); 20881 return config; 20882 }; 20883 20884 _proto._getScrollTop = function _getScrollTop() { 20885 return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop; 20886 }; 20887 20888 _proto._getScrollHeight = function _getScrollHeight() { 20889 return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); 20890 }; 20891 20892 _proto._getOffsetHeight = function _getOffsetHeight() { 20893 return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height; 20894 }; 20895 20896 _proto._process = function _process() { 20897 var scrollTop = this._getScrollTop() + this._config.offset; 20898 20899 var scrollHeight = this._getScrollHeight(); 20900 20901 var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight(); 20902 20903 if (this._scrollHeight !== scrollHeight) { 20904 this.refresh(); 20905 } 20906 20907 if (scrollTop >= maxScroll) { 20908 var target = this._targets[this._targets.length - 1]; 20909 20910 if (this._activeTarget !== target) { 20911 this._activate(target); 20912 } 20913 20914 return; 20915 } 20916 20917 if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) { 20918 this._activeTarget = null; 20919 20920 this._clear(); 20921 20922 return; 20923 } 20924 20925 for (var i = this._offsets.length; i--;) { 20926 var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]); 20927 20928 if (isActiveTarget) { 20929 this._activate(this._targets[i]); 20930 } 20931 } 20932 }; 20933 20934 _proto._activate = function _activate(target) { 20935 this._activeTarget = target; 20936 20937 this._clear(); 20938 20939 var queries = this._selector.split(','); // eslint-disable-next-line arrow-body-style 20940 20941 20942 queries = queries.map(function (selector) { 20943 return selector + "[data-target=\"" + target + "\"]," + (selector + "[href=\"" + target + "\"]"); 20944 }); 20945 var $link = $$$1(queries.join(',')); 20946 20947 if ($link.hasClass(ClassName.DROPDOWN_ITEM)) { 20948 $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE); 20949 $link.addClass(ClassName.ACTIVE); 20950 } else { 20951 // Set triggered link as active 20952 $link.addClass(ClassName.ACTIVE); // Set triggered links parents as active
20953 // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor 20954 20955 $link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_LINKS + ", " + Selector.LIST_ITEMS).addClass(ClassName.ACTIVE); // Handle special case when .nav-link is inside .nav-item 20956 20957 $link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_ITEMS).children(Selector.NAV_LINKS).addClass(ClassName.ACTIVE); 20958 } 20959 20960 $$$1(this._scrollElement).trigger(Event.ACTIVATE, { 20961 relatedTarget: target 20962 }); 20963 }; 20964 20965 _proto._clear = function _clear() { 20966 $$$1(this._selector).filter(Selector.ACTIVE).removeClass(ClassName.ACTIVE); 20967 }; // Static 20968 20969 20970 ScrollSpy._jQueryInterface = function _jQueryInterface(config) { 20971 return this.each(function () { 20972 var data = $$$1(this).data(DATA_KEY); 20973 20974 var _config = _typeof(config) === 'object' && config; 20975 20976 if (!data) { 20977 data = new ScrollSpy(this, _config); 20978 $$$1(this).data(DATA_KEY, data); 20979 } 20980 20981 if (typeof config === 'string') { 20982 if (typeof data[config] === 'undefined') { 20983 throw new TypeError("No method named \"" + config + "\""); 20984 } 20985 20986 data[config](); 20987 } 20988 }); 20989 }; 20990 20991 _createClass(ScrollSpy, null, [{ 20992 key: "VERSION", 20993 get: function get() { 20994 return VERSION; 20995 } 20996 }, { 20997 key: "Default", 20998 get: function get() { 20999 return Default; 21000 } 21001 }]); 21002 21003 return ScrollSpy; 21004 }(); 21005 /** 21006 * ------------------------------------------------------------------------ 21007 * Data Api implementation 21008 * ------------------------------------------------------------------------ 21009 */ 21010 21011 21012 $$$1(window).on(Event.LOAD_DATA_API, function () { 21013 var scrollSpys = $$$1.makeArray($$$1(Selector.DATA_SPY)); 21014 21015 for (var i = scrollSpys.length; i--;) { 21016 var $spy = $$$1(scrollSpys[i]); 21017 21018 ScrollSpy._jQueryInterface.call($spy, $spy.data()); 21019 } 21020 }); 21021 /** 21022 * ------------------------------------------------------------------------ 21023 * jQuery 21024 * ------------------------------------------------------------------------ 21025 */ 21026 21027 $$$1.fn[NAME] = ScrollSpy._jQueryInterface; 21028 $$$1.fn[NAME].Constructor = ScrollSpy; 21029 21030 $$$1.fn[NAME].noConflict = function () { 21031 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 21032 return ScrollSpy._jQueryInterface; 21033 }; 21034 21035 return ScrollSpy; 21036 }($); 21037 /** 21038 * -------------------------------------------------------------------------- 21039 * Bootstrap (v4.1.1): tab.js 21040 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 21041 * -------------------------------------------------------------------------- 21042 */ 21043 21044 21045 var Tab = function ($$$1) { 21046 /** 21047 * ------------------------------------------------------------------------ 21048 * Constants 21049 * ------------------------------------------------------------------------ 21050 */ 21051 var NAME = 'tab'; 21052 var VERSION = '4.1.1'; 21053 var DATA_KEY = 'bs.tab'; 21054 var EVENT_KEY = "." + DATA_KEY; 21055 var DATA_API_KEY = '.data-api'; 21056 var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; 21057 var Event = { 21058 HIDE: "hide" + EVENT_KEY, 21059 HIDDEN: "hidden" + EVENT_KEY, 21060 SHOW: "show" + EVENT_KEY, 21061 SHOWN: "shown" + EVENT_KEY, 21062 CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY 21063 }; 21064 var ClassName = { 21065 DROPDOWN_MENU: 'dropdown-menu', 21066 ACTIVE: 'active', 21067 DISABLED: 'disabled', 21068 FADE: 'fade', 21069 SHOW: 'show' 21070 }; 21071 var Selector = { 21072 DROPDOWN: '.dropdown', 21073 NAV_LIST_GROUP: '.nav, .list-group', 21074 ACTIVE: '.active', 21075 ACTIVE_UL: '> li > .active', 21076 DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]', 21077 DROPDOWN_TOGGLE: '.dropdown-toggle', 21078 DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active' 21079 /** 21080 * ------------------------------------------------------------------------ 21081 * Class Definition 21082 * ------------------------------------------------------------------------ 21083 */ 21084 21085 }; 21086 21087 var Tab = 21088 /*#__PURE__*/ 21089 function () { 21090 function Tab(element) { 21091 this._element = element; 21092 } // Getters 21093 21094 21095 var _proto = Tab.prototype; // Public 21096 21097 _proto.show = function show() { 21098 var _this = this; 21099 21100 if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $$$1(this._element).hasClass(ClassName.ACTIVE) || $$$1(this._element).hasClass(ClassName.DISABLED)) { 21101 return; 21102 } 21103 21104 var target; 21105 var previous; 21106 var listElement = $$$1(this._element).closest(Selector.NAV_LIST_GROUP)[0]; 21107 var selector = Util.getSelectorFromElement(this._element); 21108 21109 if (listElement) { 21110 var itemSelector = listElement.nodeName === 'UL' ? Selector.ACTIVE_UL : Selector.ACTIVE; 21111 previous = $$$1.makeArray($$$1(listElement).find(itemSelector)); 21112 previous = previous[previous.length - 1]; 21113 } 21114 21115 var hideEvent = $$$1.Event(Event.HIDE, { 21116 relatedTarget: this._element 21117 }); 21118 var showEvent = $$$1.Event(Event.SHOW, { 21119 relatedTarget: previous 21120 }); 21121 21122 if (previous) { 21123 $$$1(previous).trigger(hideEvent); 21124 } 21125 21126 $$$1(this._element).trigger(showEvent); 21127 21128 if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) { 21129 return; 21130 } 21131 21132 if (selector) { 21133 target = $$$1(selector)[0]; 21134 } 21135 21136 this._activate(this._element, listElement); 21137 21138 var complete = function complete() { 21139 var hiddenEvent = $$$1.Event(Event.HIDDEN, { 21140 relatedTarget: _this._element 21141 }); 21142 var shownEvent = $$$1.Event(Event.SHOWN, { 21143 relatedTarget: previous 21144 }); 21145 $$$1(previous).trigger(hiddenEvent); 21146 $$$1(_this._element).trigger(shownEvent); 21147 }; 21148 21149 if (target) { 21150 this._activate(target, target.parentNode, complete); 21151 } else { 21152 complete(); 21153 } 21154 }; 21155 21156 _proto.dispose = function dispose() { 21157 $$$1.removeData(this._element, DATA_KEY); 21158 this._element = null; 21159 }; // Private 21160 21161 21162 _proto._activate = function _activate(element, container, callback) { 21163 var _this2 = this; 21164 21165 var activeElements; 21166 21167 if (container.nodeName === 'UL') { 21168 activeElements = $$$1(container).find(Selector.ACTIVE_UL); 21169 } else { 21170 activeElements = $$$1(container).children(Selector.ACTIVE); 21171 } 21172 21173 var active = activeElements[0]; 21174 var isTransitioning = callback && active && $$$1(active).hasClass(ClassName.FADE); 21175 21176 var complete = function complete() { 21177 return _this2._transitionComplete(element, active, callback); 21178 }; 21179 21180 if (active && isTransitioning) { 21181 var transitionDuration = Util.getTransitionDurationFromElement(active); 21182 $$$1(active).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); 21183 } else { 21184 complete(); 21185 } 21186 }; 21187 21188 _proto._transitionComplete = function _transitionComplete(element, active, callback) { 21189 if (active) { 21190 $$$1(active).removeClass(ClassName.SHOW + " " + ClassName.ACTIVE);
21191 var dropdownChild = $$$1(active.parentNode).find(Selector.DROPDOWN_ACTIVE_CHILD)[0]; 21192 21193 if (dropdownChild) { 21194 $$$1(dropdownChild).removeClass(ClassName.ACTIVE); 21195 } 21196 21197 if (active.getAttribute('role') === 'tab') { 21198 active.setAttribute('aria-selected', false); 21199 } 21200 } 21201 21202 $$$1(element).addClass(ClassName.ACTIVE); 21203 21204 if (element.getAttribute('role') === 'tab') { 21205 element.setAttribute('aria-selected', true); 21206 } 21207 21208 Util.reflow(element); 21209 $$$1(element).addClass(ClassName.SHOW); 21210 21211 if (element.parentNode && $$$1(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) { 21212 var dropdownElement = $$$1(element).closest(Selector.DROPDOWN)[0]; 21213 21214 if (dropdownElement) { 21215 $$$1(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE); 21216 } 21217 21218 element.setAttribute('aria-expanded', true); 21219 } 21220 21221 if (callback) { 21222 callback(); 21223 } 21224 }; // Static 21225 21226 21227 Tab._jQueryInterface = function _jQueryInterface(config) { 21228 return this.each(function () { 21229 var $this = $$$1(this); 21230 var data = $this.data(DATA_KEY); 21231 21232 if (!data) { 21233 data = new Tab(this); 21234 $this.data(DATA_KEY, data); 21235 } 21236 21237 if (typeof config === 'string') { 21238 if (typeof data[config] === 'undefined') { 21239 throw new TypeError("No method named \"" + config + "\""); 21240 } 21241 21242 data[config](); 21243 } 21244 }); 21245 }; 21246 21247 _createClass(Tab, null, [{ 21248 key: "VERSION", 21249 get: function get() { 21250 return VERSION; 21251 } 21252 }]); 21253 21254 return Tab; 21255 }(); 21256 /** 21257 * ------------------------------------------------------------------------ 21258 * Data Api implementation 21259 * ------------------------------------------------------------------------ 21260 */ 21261 21262 21263 $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { 21264 event.preventDefault(); 21265 21266 Tab._jQueryInterface.call($$$1(this), 'show'); 21267 }); 21268 /** 21269 * ------------------------------------------------------------------------ 21270 * jQuery 21271 * ------------------------------------------------------------------------ 21272 */ 21273 21274 $$$1.fn[NAME] = Tab._jQueryInterface; 21275 $$$1.fn[NAME].Constructor = Tab; 21276 21277 $$$1.fn[NAME].noConflict = function () { 21278 $$$1.fn[NAME] = JQUERY_NO_CONFLICT; 21279 return Tab._jQueryInterface; 21280 }; 21281 21282 return Tab; 21283 }($); 21284 /** 21285 * -------------------------------------------------------------------------- 21286 * Bootstrap (v4.1.1): index.js 21287 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 21288 * -------------------------------------------------------------------------- 21289 */ 21290 21291 21292 (function ($$$1) { 21293 if (typeof $$$1 === 'undefined') { 21294 throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.'); 21295 } 21296 21297 var version = $$$1.fn.jquery.split(' ')[0].split('.'); 21298 var minMajor = 1; 21299 var ltMajor = 2; 21300 var minMinor = 9; 21301 var minPatch = 1; 21302 var maxMajor = 4; 21303 21304 if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) { 21305 throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0'); 21306 } 21307 })($); 21308 21309 exports.Util = Util; 21310 exports.Alert = Alert; 21311 exports.Button = Button; 21312 exports.Carousel = Carousel; 21313 exports.Collapse = Collapse; 21314 exports.Dropdown = Dropdown; 21315 exports.Modal = Modal; 21316 exports.Popover = Popover; 21317 exports.Scrollspy = ScrollSpy; 21318 exports.Tab = Tab; 21319 exports.Tooltip = Tooltip; 21320 Object.defineProperty(exports, '__esModule', { 21321 value: true 21322 }); 21323}); 21324/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../../../node_modules/webpack/buildin/global.js */ "./node_modules/webpack/buildin/global.js"))) 21325 21326/***/ }), 21327
21328/***/ "./wp-content/themes/camiers/assets/src/js/components/brochure_cpnt.js": 21329/*!*****************************************************************************!*\ 21330 !*** ./wp-content/themes/camiers/assets/src/js/components/brochure_cpnt.js ***! 21331 \*****************************************************************************/ 21332/*! exports provided: BrochureCpnt */ 21333/***/ (function(module, __webpack_exports__, __webpack_require__) { 21334 21335"use strict"; 21336__webpack_require__.r(__webpack_exports__); 21337/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BrochureCpnt", function() { return BrochureCpnt; }); 21338/* 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"); 21339/* 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__); 21340/* harmony import */ var imagesloaded_imagesloaded_pkgd_min__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! imagesloaded/imagesloaded.pkgd.min */ "./node_modules/imagesloaded/imagesloaded.pkgd.min.js"); 21341/* harmony import */ var imagesloaded_imagesloaded_pkgd_min__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(imagesloaded_imagesloaded_pkgd_min__WEBPACK_IMPORTED_MODULE_1__); 21342function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 21343 21344function _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); } } 21345 21346function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 21347 21348 21349 21350var BrochureCpnt = 21351/*#__PURE__*/ 21352function () { 21353 function BrochureCpnt() { 21354 _classCallCheck(this, BrochureCpnt); 21355 21356 this.initializeBrochureIsotope(); 21357 } 21358 21359 _createClass(BrochureCpnt, [{ 21360 key: "initializeBrochureIsotope", 21361 value: function initializeBrochureIsotope() { 21362 var grid = document.querySelector('[isotope-grid]'), 21363 item = '[isotope-item]', 21364 filters = '[isotope-filters]', 21365 $filters = $(filters), 21366 active = 'current', 21367 gutterSize = 40; 21368 21369 if (window.matchMedia("(max-width: 959px)").matches) { 21370 gutterSize = 20; 21371 } 21372 21373 if (document.body.contains(grid)) { 21374 $(window).load(function () { 21375 var iso = new isotope_layout_dist_isotope_pkgd_min__WEBPACK_IMPORTED_MODULE_0___default.a(grid, { 21376 masonry: { 21377 itemSelector: item, 21378 gutter: gutterSize 21379 } 21380 }); 21381 21382 if ($filters.length > 0) { 21383 // Filter items on button click 21384 $filters.on('click', 'a', function () { 21385 var filterValue = $(this).attr('data-filter'); 21386 iso.arrange({ 21387 filter: filterValue 21388 }); 21389 }); // Change class on click 21390 21391 $filters.each(function (i, buttonGroup) { 21392 var $buttonGroup = $(buttonGroup); 21393 $buttonGroup.on('click', 'a', function () { 21394 $buttonGroup.find('.' + active).removeClass(active); 21395 $(this).addClass(active); 21396 }); 21397 }); 21398 } 21399 }); 21400 } 21401 } 21402 }]); 21403 21404 return BrochureCpnt; 21405}(); 21406/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 21407 21408/***/ }), 21409
21410/***/ "./wp-content/themes/camiers/assets/src/js/components/engine_home_cpnt.js": 21411/*!********************************************************************************!*\ 21412 !*** ./wp-content/themes/camiers/assets/src/js/components/engine_home_cpnt.js ***! 21413 \********************************************************************************/ 21414/*! exports provided: EngineHomeCpnt */ 21415/***/ (function(module, __webpack_exports__, __webpack_require__) { 21416 21417"use strict"; 21418__webpack_require__.r(__webpack_exports__); 21419/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EngineHomeCpnt", function() { return EngineHomeCpnt; }); 21420function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 21421 21422function _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); } } 21423 21424function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 21425 21426var EngineHomeCpnt = 21427/*#__PURE__*/ 21428function () { 21429 function EngineHomeCpnt() { 21430 _classCallCheck(this, EngineHomeCpnt); 21431 21432 this.initializeEngineHome(); 21433 } 21434 21435 _createClass(EngineHomeCpnt, [{ 21436 key: "initializeEngineHome", 21437 value: function initializeEngineHome() { 21438 var $engine = $('[data-engine-home]'), 21439 $engineSelect = $('[data-engine-home-select]'), 21440 $form = $('[data-engine-form]'), 21441 $engineTab = $('[data-engine-tab-item]'), 21442 showEngine = '[data-show-engine]', 21443 closeEngine = '[data-close-engine]'; 21444 21445 if ($('.home').length > 0 && $engine.length > 0 & $engineSelect.length > 0) { 21446 $(document).on('click', showEngine, function () { 21447 $('body').addClass('engineModalOpen'); 21448 }); 21449 $(document).on('click', closeEngine, function () { 21450 $('body').removeClass('engineModalOpen'); 21451 }); 21452 $(document).on('click', '[data-engine-tab-item]', function () { 21453 $('.nbPers').hide(); 21454 var type = $(this).attr('id'); 21455 21456 if ($engine.attr('data-current') != type) { 21457 $('[data-engine-tab-item]').removeClass('active'); 21458 $(this).addClass('active'); 21459 $.ajax({ 21460 url: Theme.getSelectEngineHome, 21461 method: "POST", 21462 data: { 21463 'type': type 21464 } 21465 }).done(function (data) { 21466 $engine.attr('data-current', type); 21467 $engineSelect.html(data.result); 21468 var url = $engineSelect.find('option:selected').attr('rel'); 21469 var nbpers = $engineSelect.find('option:selected').attr('data-pers'); 21470 21471 if (nbpers == 1) { 21472 $('.nbPers').show(); 21473 } else { 21474 $('.nbPers').hide(); 21475 } 21476 21477 $form.attr('action', url); 21478 }); 21479 } 21480 }); // Change action form 21481 21482 $engineSelect.on('change', function () { 21483 var url = $(this).find('option:selected').attr('rel'); 21484 var nbpers = $(this).find('option:selected').attr('data-pers'); 21485 21486 if (nbpers == 1) { 21487 $('.nbPers').show(); 21488 } else { 21489 $('.nbPers').hide(); 21490 } 21491 21492 $form.attr('action', url); 21493 }); // code js qui permet de genere les calendriers 21494 21495 var date = new Date(); 21496 var $inputfin = $('#dateend').pickadate({ 21497 min: date, 21498 container: '.wrapper' 21499 }); 21500 var $inputdeb = $('#datestart').pickadate({ 21501 min: date, 21502 container: '.wrapper', 21503 onSet: function onSet(date) { 21504 date = new Date(date.select); 21505 var picker_fin = $inputfin.pickadate('picker'); 21506 picker_fin.set('min', date); 21507 date.setDate(date.getDate() + 7); 21508 picker_fin.set('select', date); 21509 } 21510 }); 21511 $('#dateend').on('click', function () { 21512 if ($('#datestart').val() != '') { 21513 $inputfin.pickadate('picker').set('min', $('#datestart').val()); 21514 } 21515 }); 21516 $engine.find('input[type=submit]').on('click', function (e) { 21517 var pickerdeb = $inputdeb.pickadate('picker'); 21518 var pickerend = $inputfin.pickadate('picker'); 21519 var datedeb = pickerdeb.get('select'); 21520 var datefin = pickerend.get('select'); 21521 21522 if (datedeb !== null && datefin !== null && typeof datedeb.obj != 'undefined' && typeof datefin.obj != 'undefined') { 21523 var timeDiff = Math.abs(datefin.obj.getTime() - datedeb.obj.getTime()); 21524 var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24)); 21525 21526 if (diffDays == 0) { 21527 diffDays = 1; 21528 } 21529 21530 $('.engineBookingForm [name="marketplace_search[duration]"]').val(diffDays); 21531 } 21532 21533 $engine.validationEngine('attach', { 21534 promptPosition: "topLeft", 21535 scroll: false 21536 }); 21537 21538 if ($engine.validationEngine('validate') == true) { 21539 $form.submit(); 21540 } 21541 21542 e.preventDefault(); 21543 return false;
21544 }); 21545 } 21546 } 21547 }]); 21548 21549 return EngineHomeCpnt; 21550}(); 21551/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 21552 21553/***/ }), 21554
21555/***/ "./wp-content/themes/camiers/assets/src/js/components/form_cpnt.js": 21556/*!*************************************************************************!*\ 21557 !*** ./wp-content/themes/camiers/assets/src/js/components/form_cpnt.js ***! 21558 \*************************************************************************/ 21559/*! exports provided: FormCpnt */ 21560/***/ (function(module, __webpack_exports__, __webpack_require__) { 21561 21562"use strict"; 21563__webpack_require__.r(__webpack_exports__); 21564/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FormCpnt", function() { return FormCpnt; }); 21565function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 21566 21567function _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); } } 21568 21569function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 21570 21571var FormCpnt = 21572/*#__PURE__*/ 21573function () { 21574 function FormCpnt() { 21575 _classCallCheck(this, FormCpnt); 21576 21577 this.customizeInput(); 21578 this.customizeSelect(); 21579 } 21580 21581 _createClass(FormCpnt, [{ 21582 key: "customizeInput", 21583 value: function customizeInput() { 21584 var form_items = $('.wpcf7 [type="checkbox"], .wpcf7 [type="radio"]'); 21585 $(form_items).each(function (i, elm) { 21586 var id = $(elm).attr('name') + '-' + i; 21587 var label_text = $(elm).siblings('.wpcf7-list-item-label').text(); 21588 var label = '<label for="' + id + '">' + label_text + '</label>'; 21589 $(elm).siblings('.wpcf7-list-item-label').remove(); 21590 $(elm).parent().append(label); 21591 $(elm).attr('id', id); 21592 }); 21593 } 21594 }, { 21595 key: "customizeSelect", 21596 value: function customizeSelect() { 21597 $('select').parent().not('.formSelect').children('select').wrap('<div class="formSelect"></div>'); 21598 } 21599 }]); 21600 21601 return FormCpnt; 21602}(); 21603/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 21604 21605/***/ }), 21606
21607/***/ "./wp-content/themes/camiers/assets/src/js/components/map_cpnt.js": 21608/*!************************************************************************!*\ 21609 !*** ./wp-content/themes/camiers/assets/src/js/components/map_cpnt.js ***! 21610 \************************************************************************/ 21611/*! exports provided: MapCpnt */ 21612/***/ (function(module, __webpack_exports__, __webpack_require__) { 21613 21614"use strict"; 21615__webpack_require__.r(__webpack_exports__); 21616/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MapCpnt", function() { return MapCpnt; }); 21617/* harmony import */ var leaflet__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! leaflet */ "./node_modules/leaflet/dist/leaflet-src.js"); 21618/* harmony import */ var leaflet__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(leaflet__WEBPACK_IMPORTED_MODULE_0__); 21619function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 21620 21621function _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); } } 21622 21623function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 21624 21625 21626var MapCpnt = 21627/*#__PURE__*/ 21628function () { 21629 function MapCpnt() { 21630 _classCallCheck(this, MapCpnt); 21631 21632 this.initializeMap(); 21633 } 21634 21635 _createClass(MapCpnt, [{ 21636 key: "initializeMap", 21637 value: function initializeMap() { 21638 this.initializeApi('js-map'); 21639 } 21640 }, { 21641 key: "initializeApi", 21642 value: function initializeApi($el) { 21643 if (document.body.contains(document.getElementById($el))) { 21644 var addresses = [{ 21645 latitude: Theme.latitude, 21646 longitude: Theme.longitude, 21647 title: Theme.name, 21648 street: Theme.street, 21649 postalcode: Theme.postalcode, 21650 city: Theme.city 21651 }]; 21652 var map = leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.map($el, { 21653 center: [parseFloat(Theme.latitude), parseFloat(Theme.longitude)], 21654 zoom: 11, 21655 scrollWheelZoom: false 21656 }); 21657 leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { 21658 attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' 21659 }).addTo(map); 21660 var marker_bounds = []; 21661 var self = this; 21662 $.each(addresses, function (index, data) { 21663 var marker_icon = leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.icon({ 21664 iconUrl: Theme.themeURL + '/assets/dist/images/markers/marker.png', 21665 iconSize: [33, 33] 21666 }); 21667 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)], { 21668 icon: marker_icon 21669 })).bindPopup(self.getInfoboxContent(data), { 21670 className: 'light', 21671 autoPanPadding: leaflet__WEBPACK_IMPORTED_MODULE_0___default.a.point(30, 30) 21672 }).addTo(map).openPopup(); 21673 marker_bounds.push([parseFloat(data.latitude), parseFloat(data.longitude)]); 21674 }); 21675 } 21676 } 21677 }, { 21678 key: "getInfoboxContent", 21679 value: function getInfoboxContent(data) { 21680 var html = '<div class="infoBoxContent">' + '<p class="infoBoxContentTitle">' + data.title + '</p>'; 21681 21682 if (data.street || data.postalcode || data.city) { 21683 html += '<p class="infoBoxContentExcerpt">' + data.street + '<br>' + data.postalcode + ' ' + data.city + '<br>' + '</p>'; 21684 } 21685 21686 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>'; 21687 return html; 21688 } 21689 }]); 21690 21691 return MapCpnt; 21692}(); 21693/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 21694 21695/***/ }), 21696
21697/***/ "./wp-content/themes/camiers/assets/src/js/components/slider_cpnt.js": 21698/*!***************************************************************************!*\ 21699 !*** ./wp-content/themes/camiers/assets/src/js/components/slider_cpnt.js ***! 21700 \***************************************************************************/ 21701/*! exports provided: SliderCpnt */ 21702/***/ (function(module, __webpack_exports__, __webpack_require__) { 21703 21704"use strict"; 21705__webpack_require__.r(__webpack_exports__); 21706/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SliderCpnt", function() { return SliderCpnt; }); 21707/* 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"); 21708/* 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__); 21709/* harmony import */ var modernizr__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! modernizr */ "./.modernizrrc.js"); 21710/* harmony import */ var modernizr__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(modernizr__WEBPACK_IMPORTED_MODULE_1__); 21711function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 21712 21713function _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); } } 21714 21715function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 21716 21717 21718 21719var SliderCpnt = 21720/*#__PURE__*/ 21721function () { 21722 function SliderCpnt() { 21723 _classCallCheck(this, SliderCpnt); 21724 21725 this.initializeRelatedPost(); 21726 this.initializeHomeSlider(); 21727 this.initializeHomePages(); 21728 this.initializeHomeInspirations(); 21729 this.initializeHomeHighlight(); 21730 this.initializeHomeDestination(); 21731 } 21732 21733 _createClass(SliderCpnt, [{ 21734 key: "initializeRelatedPost", 21735 value: function initializeRelatedPost() { 21736 var $sliders = $('.relatedpostSlider'); 21737 $sliders.each(function () { 21738 var id_slider = $(this).attr('id'), 21739 $items = $('#' + id_slider + ' .relatedpostItem'), 21740 $slider = $('#' + id_slider); 21741 21742 if ($items.length > 3 || $items.length > 2 && window.matchMedia("(max-width: 739px)").matches) { 21743 var settings = { 21744 slidesToShow: 3, 21745 slidesToScroll: 1, 21746 arrows: true, 21747 dots: false, 21748 infinite: false, 21749 variableWidth: true, 21750 initialSlide: $items.length - 3, 21751 responsive: [{ 21752 breakpoint: 959, 21753 settings: { 21754 slidesToShow: 3, 21755 slidesToScroll: 2, 21756 initialSlide: 0, 21757 arrows: false 21758 } 21759 }, { 21760 breakpoint: 739, 21761 settings: { 21762 slidesToShow: 2, 21763 slidesToScroll: 2, 21764 initialSlide: 0, 21765 arrows: false 21766 } 21767 }] 21768 }; 21769 $slider.slick(settings); 21770 } 21771 }); 21772 } 21773 }, { 21774 key: "initializeHomeSlider", 21775 value: function initializeHomeSlider() { 21776 //Slider home 21777 var $slider = $('.sliderList'), 21778 sliderItem = '.sliderItemPhoto', 21779 $currentSlider = $('.sliderList [data-slide-current]'); 21780 21781 if ($(sliderItem).length > 0) { 21782 $slider.slick({ 21783 slide: sliderItem, 21784 infinite: true, 21785 slidesToShow: 1, 21786 slidesToScroll: 1, 21787 autoplay: true, 21788 autoplaySpeed: 4000, 21789 speed: 1000, 21790 arrows: true, 21791 dots: false, 21792 fade: true, 21793 cssEase: 'linear',
21794 prevArrow: $("[data-slide-arrow ='prev']"), 21795 nextArrow: $("[data-slide-arrow ='next']") 21796 }); 21797 } 21798 21799 $slider.on('beforeChange', function (event, slick, currentSlide, nextSlide) { 21800 $currentSlider.html('0' + (nextSlide + 1)); 21801 }); 21802 } 21803 }, { 21804 key: "initializeHomePages", 21805 value: function initializeHomePages() { 21806 var $slider = $('.pageHighlightList'), 21807 sliderItem = '.pageHighlightItem', 21808 $currentSlider = $('.stratePages [data-slide-pages-current]'); 21809 21810 if ($(sliderItem).length > 1 && window.matchMedia("(min-width: 959px)").matches || $(sliderItem).length > 2 && window.matchMedia("(max-width: 959px)").matches || $(sliderItem).length > 1 && window.matchMedia("(max-width: 739px)").matches) { 21811 $slider.slick({ 21812 slide: sliderItem, 21813 infinite: false, 21814 slidesToShow: 1, 21815 slidesToScroll: 1, 21816 speed: 800, 21817 autoplay: false, 21818 arrows: true, 21819 dots: false, 21820 cssEase: 'linear', 21821 prevArrow: $("[data-slide-pages-arrow ='prev']"), 21822 nextArrow: $("[data-slide-pages-arrow ='next']"), 21823 responsive: [{ 21824 breakpoint: 1279, 21825 settings: { 21826 slidesToShow: 1, 21827 slidesToScroll: 1, 21828 variableWidth: true, 21829 arrows: true 21830 } 21831 }, { 21832 breakpoint: 959, 21833 settings: { 21834 slidesToShow: 1, 21835 slidesToScroll: 1, 21836 initialSlide: 0, 21837 variableWidth: true, 21838 arrows: false 21839 } 21840 }, { 21841 breakpoint: 739, 21842 settings: { 21843 slidesToShow: 1, 21844 slidesToScroll: 1, 21845 initialSlide: 1, 21846 variableWidth: true, 21847 arrows: false, 21848 centerMode: true 21849 } 21850 }] 21851 }); 21852 } 21853 21854 $slider.on('beforeChange', function (event, slick, currentSlide, nextSlide) { 21855 $currentSlider.html('0' + (nextSlide + 1)); 21856 }); 21857 } 21858 }, { 21859 key: "initializeHomeInspirations", 21860 value: function initializeHomeInspirations() { 21861 var $slider = $('.entityList--home'), 21862 sliderItem = '.entityList--home .entityItem'; 21863 21864 if ($(sliderItem).length > 0 && window.matchMedia("(min-width: 959px)").matches || $(sliderItem).length > 3 && window.matchMedia("(max-width: 959px)").matches || $(sliderItem).length > 1 && window.matchMedia("(max-width: 739px)").matches) { 21865 $slider.slick({ 21866 slide: sliderItem, 21867 infinite: false, 21868 slidesToShow: 2, 21869 slidesToScroll: 1, 21870 autoplay: false, 21871 arrows: true, 21872 dots: false, 21873 variableWidth: true, 21874 cssEase: 'linear', 21875 responsive: [{ 21876 breakpoint: 959, 21877 settings: { 21878 slidesToShow: 3, 21879 slidesToScroll: 3, 21880 arrows: false, 21881 variableWidth: true 21882 } 21883 }, { 21884 breakpoint: 739, 21885 settings: { 21886 slidesToShow: 2, 21887 slidesToScroll: 1, 21888 arrows: false, 21889 variableWidth: true 21890 } 21891 }] 21892 }); 21893 } 21894 } 21895 }, { 21896 key: "initializeHomeHighlight", 21897 value: function initializeHomeHighlight() { 21898 var $slider = $('.strateHighlight .posthighlightList'), 21899 sliderItem = '.posthighlightList .posthighlightItem'; 21900 21901 if ($(sliderItem).length > 2 && window.matchMedia("(max-width: 739px)").matches) { 21902 $slider.slick({ 21903 slide: sliderItem, 21904 infinite: false, 21905 slidesToShow: 2, 21906 slidesToScroll: 1, 21907 autoplay: false, 21908 arrows: false, 21909 dots: false, 21910 variableWidth: true, 21911 cssEase: 'linear', 21912 centerMode: true, 21913 initialSlide: 1 21914 }); 21915 } 21916 } 21917 }, { 21918 key: "initializeHomeDestination", 21919 value: function initializeHomeDestination() { 21920 var $slider = $('.strateMap .mapList'), 21921 sliderItem = '.mapList .mapItem'; 21922 21923 if (sliderItem.length > 0 && window.matchMedia("(max-width: 959px)").matches || modernizr__WEBPACK_IMPORTED_MODULE_1___default.a.touchevents) { 21924 $slider.slick({ 21925 slide: sliderItem, 21926 infinite: false, 21927 slidesToShow: 3, 21928 slidesToScroll: 3, 21929 autoplay: false,
21930 arrows: false, 21931 dots: false, 21932 variableWidth: true, 21933 centerMode: true, 21934 cssEase: 'linear', 21935 initialSlide: 1, 21936 responsive: [{ 21937 breakpoint: 959, 21938 settings: { 21939 centerMode: false, 21940 slidesToShow: 2, 21941 slidesToScroll: 1, 21942 variableWidth: true, 21943 initialSlide: 1 21944 } 21945 }, { 21946 breakpoint: 739, 21947 settings: { 21948 centerMode: true, 21949 slidesToShow: 1, 21950 slidesToScroll: 1, 21951 variableWidth: true, 21952 initialSlide: 1 21953 } 21954 }] 21955 }); 21956 } 21957 } 21958 }]); 21959 21960 return SliderCpnt; 21961}(); 21962/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 21963 21964/***/ }), 21965
21966/***/ "./wp-content/themes/camiers/assets/src/js/components/tide_cpnt.js": 21967/*!*************************************************************************!*\ 21968 !*** ./wp-content/themes/camiers/assets/src/js/components/tide_cpnt.js ***! 21969 \*************************************************************************/ 21970/*! exports provided: TideCpnt */ 21971/***/ (function(module, __webpack_exports__, __webpack_require__) { 21972 21973"use strict"; 21974__webpack_require__.r(__webpack_exports__); 21975/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TideCpnt", function() { return TideCpnt; }); 21976function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 21977 21978function _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); } } 21979 21980function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 21981 21982var TideCpnt = 21983/*#__PURE__*/ 21984function () { 21985 function TideCpnt() { 21986 _classCallCheck(this, TideCpnt); 21987 21988 this.initializeTide(); 21989 } 21990 21991 _createClass(TideCpnt, [{ 21992 key: "initializeTide", 21993 value: function initializeTide() { 21994 if ($('.tides-header').length > 0) { 21995 $('.tides-month-item').on('click', function () { 21996 var month = $(this).attr('index'); 21997 $('.tides-month-item').removeClass('active'); 21998 $(this).addClass('active'); 21999 $.each($('.tides-container'), function () { 22000 $(this).addClass('active').removeClass('active'); 22001 22002 if ($(this).attr('data-month') == month) { 22003 $(this).removeClass('active').addClass('active'); 22004 } 22005 }); 22006 }); 22007 $('.tides-body-item').hover(function () { 22008 var row = $(this).attr('rel'); 22009 $('.tides-body-item[rel="' + row + '"]').removeClass('hover').addClass('hover'); 22010 }, function () { 22011 var row = $(this).attr('rel'); 22012 $('.tides-body-item[rel="' + row + '"]').addClass('hover').removeClass('hover'); 22013 }); 22014 var row = $('.tides-container.active .tides-body-item.current').attr('rel'); 22015 $('.tides-container.active .tides-body-item[rel="' + row + '"]').addClass('current'); 22016 } 22017 } 22018 }]); 22019 22020 return TideCpnt; 22021}(); 22022/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 22023 22024/***/ }), 22025
22026/***/ "./wp-content/themes/camiers/assets/src/js/components/ux_cpnt.js": 22027/*!***********************************************************************!*\ 22028 !*** ./wp-content/themes/camiers/assets/src/js/components/ux_cpnt.js ***! 22029 \***********************************************************************/ 22030/*! exports provided: UxCpnt */ 22031/***/ (function(module, __webpack_exports__, __webpack_require__) { 22032 22033"use strict"; 22034__webpack_require__.r(__webpack_exports__); 22035/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UxCpnt", function() { return UxCpnt; }); 22036/* harmony import */ var _fancyapps_fancybox_dist_jquery_fancybox_min__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fancyapps/fancybox/dist/jquery.fancybox.min */ "./node_modules/@fancyapps/fancybox/dist/jquery.fancybox.min.js"); 22037/* harmony import */ var _fancyapps_fancybox_dist_jquery_fancybox_min__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_fancyapps_fancybox_dist_jquery_fancybox_min__WEBPACK_IMPORTED_MODULE_0__); 22038/* harmony import */ var modernizr__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! modernizr */ "./.modernizrrc.js"); 22039/* harmony import */ var modernizr__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(modernizr__WEBPACK_IMPORTED_MODULE_1__); 22040/* harmony import */ var vanilla_lazyload__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vanilla-lazyload */ "./node_modules/vanilla-lazyload/dist/lazyload.min.js"); 22041/* harmony import */ var vanilla_lazyload__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(vanilla_lazyload__WEBPACK_IMPORTED_MODULE_2__); 22042/* harmony import */ var jquery_match_height_dist_jquery_matchHeight_min__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! jquery-match-height/dist/jquery.matchHeight-min */ "./node_modules/jquery-match-height/dist/jquery.matchHeight-min.js"); 22043/* harmony import */ var jquery_match_height_dist_jquery_matchHeight_min__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(jquery_match_height_dist_jquery_matchHeight_min__WEBPACK_IMPORTED_MODULE_3__); 22044/* harmony import */ var paroller_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! paroller.js */ "./node_modules/paroller.js/dist/jquery.paroller.js"); 22045/* harmony import */ var paroller_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(paroller_js__WEBPACK_IMPORTED_MODULE_4__); 22046function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 22047 22048function _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); } } 22049 22050function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 22051 22052 22053 22054 22055 22056 22057var UxCpnt = 22058/*#__PURE__*/ 22059function () { 22060 function UxCpnt() { 22061 _classCallCheck(this, UxCpnt); 22062 22063 this.initializeJsClick(); 22064 this.initializeBootstrpTooltip(); 22065 this.initializeFancybox(); 22066 this.initializeSearchBox(); 22067 this.initializeBackToTop(); 22068 this.initializeSmoothScroll(); 22069 this.initializeLazy(); 22070 this.initializeOnScroll(); 22071 this.initializeVideoGutenberg(); 22072 this.initializeLastBlock(); 22073 this.initializeParoller(); 22074 this.initializeMatchHeight(); 22075 this.initializeHoverPostHighlight(); 22076 this.initializeAgendaLink(); 22077 this.initializeInstagram(); 22078 this.initializeSvgMap(); 22079 this.initializeBurgerMenu(); 22080 this.initializeLang(); 22081 this.initializeCookieOptIn(); 22082 } 22083 22084 _createClass(UxCpnt, [{ 22085 key: "initializeJsClick", 22086 value: function initializeJsClick() { 22087 if (!modernizr__WEBPACK_IMPORTED_MODULE_1___default.a.touchevents) { 22088 var ctrl = 0; 22089 $(window).on('keydown', function (e) { 22090 if (e.which == 17 || e.which == 91) { 22091 ctrl = true; 22092 } 22093 }); 22094 $(window).on('keyup', function () { 22095 ctrl = false;
22096 }); 22097 $(document).on('mouseup', '.js-click', function (e) { 22098 if (e.which == 1 || e.which == 2) { 22099 var blank = false; 22100 var url = $(this).find("a").attr("href"); 22101 22102 if (e.which == 2) { 22103 blank = true; 22104 } // Clic molette 22105 22106 22107 if ($(this).find("a").attr("target") == "_blank") { 22108 blank = true; 22109 } 22110 22111 if (blank || ctrl) { 22112 window.open(url, '_blank'); 22113 } else { 22114 window.location = url; 22115 } 22116 22117 return false; 22118 } 22119 22120 return false; 22121 }); 22122 } else { 22123 $(document).on('click', '.js-click', function (e) { 22124 var blank = false; 22125 var url = $(this).find("a").attr("href"); 22126 22127 if ($(this).find("a").attr("target") == "_blank") { 22128 blank = true; 22129 } 22130 22131 if (blank) { 22132 window.open(url, '_blank'); 22133 } else { 22134 window.location = url; 22135 } 22136 22137 return false; 22138 }); 22139 } 22140 } 22141 }, { 22142 key: "initializeBootstrpTooltip", 22143 value: function initializeBootstrpTooltip() { 22144 if (!modernizr__WEBPACK_IMPORTED_MODULE_1___default.a.touchevents) { 22145 $('[data-toggle="tooltip"], [rel="tooltip"]').tooltip({ 22146 trigger: "hover" 22147 }); 22148 } 22149 } 22150 }, { 22151 key: "initializeFancybox", 22152 value: function initializeFancybox() { 22153 $('.article a:has(>img):not([target="_blank"]):not(".no-fancybox")').attr('data-fancybox', 'fancybox'); 22154 $("[data-fancybox='fancybox']").fancybox({ 22155 buttons: ["zoom", //"share", 22156 "slideShow", //"fullScreen", 22157 //"download", 22158 //"thumbs", 22159 "close"], 22160 lang: "fr", 22161 i18n: { 22162 fr: { 22163 CLOSE: Theme.translate.fancyboxClose, 22164 NEXT: Theme.translate.fancyboxNext, 22165 PREV: Theme.translate.fancyboxPrev, 22166 ERROR: Theme.translate.fancyboxError, 22167 PLAY_START: Theme.translate.fancyboxStart, 22168 PLAY_STOP: Theme.translate.fancyboxStop, 22169 FULL_SCREEN: Theme.translate.fancyboxFullScreen, 22170 THUMBS: Theme.translate.fancyboxThumbs, 22171 DOWNLOAD: Theme.translate.fancyboxDownload, 22172 SHARE: Theme.translate.fancyboxShare, 22173 ZOOM: Theme.translate.fancyboxZoom 22174 } 22175 }, 22176 caption: function caption(instance, item) { 22177 var caption = $(this).closest('figure').find('figcaption').html(); 22178 22179 if (!caption) { 22180 caption = $(this).find('img').attr('title'); 22181 } 22182 22183 if (!caption) { 22184 caption = $(this).find('img').attr('alt'); 22185 } 22186 22187 return caption; 22188 } 22189 }); 22190 } 22191 }, { 22192 key: "initializeCookieOptIn", 22193 value: function initializeCookieOptIn() { 22194 tarteaucitron.init({ 22195 "useExternalCss": false, 22196 "privacyUrl": Theme.privacyPolicyURL, 22197 "hashtag": "", 22198 "cookieName": "tartaucitron", 22199 "orientation": "bottom", 22200 "showAlertSmall": false, 22201 "cookieslist": true, 22202 "adblocker": false, 22203 "AcceptAllCta": true, 22204 "highPrivacy": true, 22205 "handleBrowserDNTRequest": false, 22206 "removeCredit": true, 22207 "moreInfoLink": true, 22208 "showExitButton": true 22209 }); 22210 tarteaucitronForceLanguage = Theme.current_locale; 22211 (tarteaucitron.job = tarteaucitron.job || []).push('wordpress'); 22212 (tarteaucitron.job = tarteaucitron.job || []).push('recaptcha'); 22213 (tarteaucitron.job = tarteaucitron.job || []).push('gtag'); 22214 } 22215 }, { 22216 key: "initializeSearchBox", 22217 value: function initializeSearchBox() { 22218 $('.js-wpSearchLayoutOpen').on('click', function (e) { 22219 e.preventDefault(); 22220 $('.wpSearchLayout').fadeIn(); 22221 setTimeout(function () { 22222 $('.wpSearchFormItem--input').focus(); 22223 }, 100); 22224 }); 22225 $('.js-wpSearchLayoutClose').on('click', function (e) { 22226 e.preventDefault(); 22227 $('.wpSearchLayout').fadeOut(); 22228 }); 22229 } 22230 }, { 22231 key: "initializeBackToTop", 22232 value: function initializeBackToTop() { 22233 $('.js-backToTop').on('click', function (e) { 22234 e.preventDefault(); 22235 22236 if ($(window).scrollTop() != 0) { 22237 $('html, body').animate({ 22238 scrollTop: 0 22239 }, 300); 22240 } 22241 }); 22242 $(window).on('scroll', function (e) { 22243 if ($(this).scrollTop() > 250) { 22244 $('.js-backToTop').addClass('backToTop--show'); 22245 } else { 22246 $('.js-backToTop').removeClass('backToTop--show'); 22247 } 22248 }); 22249 } 22250 }, { 22251 key: "initializeSmoothScroll", 22252 value: function initializeSmoothScroll() { 22253 $('.js-scroll').click(function () {
22254 if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) { 22255 var target = $(this.hash); 22256 target = target.length ? target : $('[name=' + this.hash.slice(1) + ']'); 22257 22258 if (target.length) { 22259 $('html,body').animate({ 22260 scrollTop: target.offset().top 22261 }, 750); 22262 return false; 22263 } 22264 } 22265 }); 22266 } 22267 }, { 22268 key: "initializeLazy", 22269 value: function initializeLazy() { 22270 var lazyLoadInstance = new vanilla_lazyload__WEBPACK_IMPORTED_MODULE_2___default.a({ 22271 elements_selector: "[data-src], [data-bg]" 22272 }); 22273 } 22274 }, { 22275 key: "initializeOnScroll", 22276 value: function initializeOnScroll() { 22277 var last_scroll_top = 0; 22278 $(window).on('load scroll', function () { 22279 var scroll_top = $(this).scrollTop(); 22280 var $header = $('.header'); 22281 22282 if (scroll_top >= last_scroll_top && scroll_top > 100) { 22283 // Down 22284 $('body').addClass('header-is-hidden'); 22285 } else { 22286 // Up 22287 $('body').removeClass('header-is-hidden'); 22288 } 22289 22290 last_scroll_top = scroll_top; // Site header color 22291 22292 if ($('.header-is-transparent').length) { 22293 var height_banner = $('[data-banner]').outerHeight() - $('.header').outerHeight(); 22294 22295 if (scroll_top > 100) { 22296 $header.removeClass('header--transparent'); 22297 } else { 22298 $header.addClass('header--transparent'); 22299 } 22300 } 22301 }); 22302 } 22303 }, { 22304 key: "initializeVideoGutenberg", 22305 value: function initializeVideoGutenberg() { 22306 var block = '.wp-block-video', 22307 $video = $('.wp-block-video video'); 22308 22309 if ($video.length > 0) { 22310 $video.on('click', function (e) { 22311 e.preventDefault(); 22312 var video = this; 22313 22314 if (video.paused) { 22315 video.play(); 22316 } else { 22317 video.pause(); 22318 } 22319 }); 22320 $video.each(function () { 22321 var video = this; 22322 $(video).on('ended', function () { 22323 // video.controls = false; 22324 // video.currentTime = 0; 22325 $(video).parent().removeClass('is-playing'); 22326 }); 22327 $(video).on('playing', function () { 22328 // video.controls = true; 22329 $(video).parent().addClass('is-playing'); 22330 }); 22331 $(video).on('pause', function () { 22332 $(video).parent().removeClass('is-playing'); // video.controls = false; 22333 }); 22334 }); 22335 } 22336 } 22337 }, { 22338 key: "initializeLastBlock", 22339 value: function initializeLastBlock() { 22340 if ($('.page-template-default .article > .relatedpost, .post-template-default .article > .relatedpost').length > 0) { 22341 $('.article > *:last-child').addClass('lastblock'); 22342 } 22343 } 22344 }, { 22345 key: "initializeParoller", 22346 value: function initializeParoller() { 22347 if (window.matchMedia("(min-width: 959px)").matches) { 22348 $('[data-paroller]').paroller(); 22349 } 22350 } 22351 }, { 22352 key: "initializeMatchHeight", 22353 value: function initializeMatchHeight() { 22354 var $item = $('[data-mh]'); 22355 22356 if ($item.length > 0) { 22357 $item.matchHeight({ 22358 property: 'min-height' 22359 }); 22360 } 22361 } 22362 }, { 22363 key: "initializeAgendaLink", 22364 value: function initializeAgendaLink() { 22365 $('[data-link-agenda]').on('click', function (e) { 22366 console.log('test'); 22367 e.preventDefault(); 22368 var rel = $(this).attr('rel'); 22369 $('#datedebutlisting_18').val(rel); 22370 $('#agendaHomeForm').submit(); 22371 }); 22372 } 22373 }, { 22374 key: "initializeHoverPostHighlight", 22375 value: function initializeHoverPostHighlight() { 22376 var $wrapper = $('.posthighlightList'), 22377 $first = $('.posthighlightItem--first'), 22378 $item = $('.posthighlightItem'); 22379 22380 if ($wrapper.length > 0) { 22381 $item.hover(function () { 22382 $item.removeClass("active"); 22383 $(this).addClass("active"); 22384 }, function () { 22385 $item.removeClass("active"); 22386 $('.posthighlightItem--first').addClass("active"); 22387 }); 22388 } 22389 } 22390 }, { 22391 key: "initializeInstagram", 22392 value: function initializeInstagram() { 22393 if ($('.strateInstagram').length > 0) { 22394 self = this; 22395 $.ajax({ 22396 url: Theme.ajaxURL, 22397 data: { 22398 'action': 'social_wall' 22399 }, 22400 type: 'POST', 22401 success: function success(socialData) { 22402 $('.strateInstagram').append(socialData); 22403 self.initializeLazy(); 22404 self.initializeBootstrpTooltip(); 22405 } 22406 }); 22407 } 22408 } 22409 }, { 22410 key: "initializeSvgMap", 22411 value: function initializeSvgMap() { 22412 if ($('.strateMap').length > 0) { 22413 var $item = $('.mapItem'), 22414 $city = $('.svgMapCity'); 22415 $city.hover(function () { 22416 var id = $(this).attr('id'); 22417 $('[data-city]').removeClass('active'); 22418 $('[data-city=' + id + ']').addClass('active'); 22419 }, function () { 22420 $('[data-city]').removeClass('active'); 22421 $('[data-city=montreuil]').addClass('active'); 22422 }); 22423 } 22424 } 22425 }, { 22426 key: "initializeBurgerMenu", 22427 value: function initializeBurgerMenu() { 22428 var more_menu = '[data-more-menu]', 22429 item_menu = '[data-item-menu]', 22430 return_menu = '[data-return-menu]', 22431 nav_menu = '[data-nav-menu]', 22432 burger_menu = '[data-burger-menu]'; 22433 $(document).on('click', more_menu, function (e) { 22434 $(item_menu).removeClass('submenuActive'); 22435 $(this).parents(item_menu).addClass('submenuActive'); 22436 }); 22437 $(document).on('click', return_menu, function (e) { 22438 $(this).parents(item_menu).removeClass('submenuActive'); 22439 }); 22440 $(document).on('click', burger_menu, function (e) { 22441 $('body').toggleClass('menuOpen'); 22442 $(this).toggleClass('open'); 22443 $(item_menu).removeClass('submenuActive'); 22444 }); 22445 } 22446 }, { 22447 key: "initializeLang", 22448 value: function initializeLang() { 22449 function getCookie(cname) { 22450 var name = cname + "="; 22451 var ca = document.cookie.split(';'); 22452 22453 for (var i = 0; i < ca.length; i++) { 22454 var c = ca[i].trim(); 22455 22456 if (c.indexOf(name) == 0) { 22457 return c.substring(name.length, c.length); 22458 } 22459 } 22460 22461 return ""; 22462 } 22463 22464 var current_lang = getCookie('googtrans'); 22465 var lang_item = '[data-lang]'; 22466 $(document).on('click', lang_item, function () { 22467 var value = $(this).html(); 22468 $('.langItem').removeClass('active'); 22469 $(this).parent().addClass('active'); 22470 $('.langCurrent').html(value); 22471 }); 22472 } 22473 }]); 22474 22475 return UxCpnt; 22476}(); 22477/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 22478 22479/***/ }), 22480
22481/***/ "./wp-content/themes/camiers/assets/src/js/components/weather_cpnt.js": 22482/*!****************************************************************************!*\ 22483 !*** ./wp-content/themes/camiers/assets/src/js/components/weather_cpnt.js ***! 22484 \****************************************************************************/ 22485/*! exports provided: WeatherCpnt */ 22486/***/ (function(module, __webpack_exports__, __webpack_require__) { 22487 22488"use strict"; 22489__webpack_require__.r(__webpack_exports__); 22490/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WeatherCpnt", function() { return WeatherCpnt; }); 22491function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 22492 22493function _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); } } 22494 22495function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 22496 22497var WeatherCpnt = 22498/*#__PURE__*/ 22499function () { 22500 function WeatherCpnt() { 22501 _classCallCheck(this, WeatherCpnt); 22502 22503 this.initializeWeather(); 22504 } 22505 22506 _createClass(WeatherCpnt, [{ 22507 key: "initializeWeather", 22508 value: function initializeWeather() { 22509 $(".js-trigger-weather-single").click(function () { 22510 $('.js-data').removeClass('open'); 22511 $(this).toggleClass("open"); 22512 $(this).parents('.weatherItemRow--preview').next().addClass('open'); 22513 $('.js-data.open').slideToggle(500); 22514 return false; 22515 }); 22516 } 22517 }]); 22518 22519 return WeatherCpnt; 22520}(); 22521/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "jquery"))) 22522 22523/***/ }), 22524
22525/***/ "./wp-content/themes/camiers/assets/src/scss/site-editor.scss": 22526/*!********************************************************************!*\ 22527 !*** ./wp-content/themes/camiers/assets/src/scss/site-editor.scss ***! 22528 \********************************************************************/ 22529/*! no static exports found */ 22530/***/ (function(module, exports) { 22531 22532// removed by extract-text-webpack-plugin 22533 22534/***/ }), 22535
22536/***/ "./wp-content/themes/camiers/assets/src/scss/site.scss": 22537/*!*************************************************************!*\ 22538 !*** ./wp-content/themes/camiers/assets/src/scss/site.scss ***! 22539 \*************************************************************/ 22540/*! no static exports found */ 22541/***/ (function(module, exports) { 22542 22543// removed by extract-text-webpack-plugin 22544 22545/***/ })
22545, 22546 22547/***/ "jquery": 22548/*!*************************!*\ 22549 !*** external "jQuery" ***! 22550 \*************************/ 22551/*! no static exports found */ 22552/***/ (function(module, exports) { 22553 22554module.exports = jQuery; 22555 22556/***/ }) 22557 22558/******/ }); 22559//# 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.