1(() => { 2 var __create = Object.create; 3 var __defProp = Object.defineProperty; 4 var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 5 var __getOwnPropNames = Object.getOwnPropertyNames; 6 var __getProtoOf = Object.getPrototypeOf; 7 var __hasOwnProp = Object.prototype.hasOwnProperty; 8 var __commonJS = (cb, mod) => function __require() { 9 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; 10 }; 11 var __export = (target, all) => { 12 for (var name in all) 13 __defProp(target, name, { get: all[name], enumerable: true }); 14 }; 15 var __copyProps = (to, from, except, desc) => { 16 if (from && typeof from === "object" || typeof from === "function") { 17 for (let key of __getOwnPropNames(from)) 18 if (!__hasOwnProp.call(to, key) && key !== except) 19 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); 20 } 21 return to; 22 }; 23 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( 24 // If the importer is in node compatibility mode or this is not an ESM 25 // file that has been converted to a CommonJS file using a Babel- 26 // compatible transform (i.e. "__esModule" has not been set), then set 27 // "default" to the CommonJS "module.exports" for node compatibility. 28 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, 29 mod 30 )); 31 32
vendor: 406,415 bytes, lines 32-9582
32// node_modules/leaflet/dist/leaflet-src.js 33 var require_leaflet_src = __commonJS({ 34 "node_modules/leaflet/dist/leaflet-src.js"(exports, module) { 35 (function(global, factory) { 36 typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.leaflet = {})); 37 })(exports, function(exports2) { 38 "use strict"; 39 var version = "1.9.4"; 40 function extend(dest) { 41 var i, j, len, src; 42 for (j = 1, len = arguments.length; j < len; j++) { 43 src = arguments[j]; 44 for (i in src) { 45 dest[i] = src[i]; 46 } 47 } 48 return dest; 49 } 50 var create$2 = Object.create || /* @__PURE__ */ function() { 51 function F() { 52 } 53 return function(proto) { 54 F.prototype = proto; 55 return new F(); 56 }; 57 }(); 58 function bind(fn2, obj) { 59 var slice = Array.prototype.slice; 60 if (fn2.bind) { 61 return fn2.bind.apply(fn2, slice.call(arguments, 1)); 62 } 63 var args = slice.call(arguments, 2); 64 return function() { 65 return fn2.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments); 66 }; 67 } 68 var lastId = 0; 69 function stamp(obj) { 70 if (!("_leaflet_id" in obj)) { 71 obj["_leaflet_id"] = ++lastId; 72 } 73 return obj._leaflet_id; 74 } 75 function throttle(fn2, time, context) { 76 var lock, args, wrapperFn, later; 77 later = function() { 78 lock = false; 79 if (args) { 80 wrapperFn.apply(context, args); 81 args = false; 82 } 83 }; 84 wrapperFn = function() { 85 if (lock) { 86 args = arguments; 87 } else { 88 fn2.apply(context, arguments); 89 setTimeout(later, time); 90 lock = true; 91 } 92 }; 93 return wrapperFn; 94 } 95 function wrapNum(x, range, includeMax) { 96 var max2 = range[1], min2 = range[0], d = max2 - min2; 97 return x === max2 && includeMax ? x : ((x - min2) % d + d) % d + min2; 98 } 99 function falseFn() { 100 return false; 101 } 102 function formatNum(num, precision) { 103 if (precision === false) { 104 return num; 105 } 106 var pow = Math.pow(10, precision === void 0 ? 6 : precision); 107 return Math.round(num * pow) / pow; 108 } 109 function trim(str) { 110 return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, ""); 111 } 112 function splitWords(str) { 113 return trim(str).split(/\s+/); 114 } 115 function setOptions(obj, options) { 116 if (!Object.prototype.hasOwnProperty.call(obj, "options")) { 117 obj.options = obj.options ? create$2(obj.options) : {}; 118 } 119 for (var i in options) { 120 obj.options[i] = options[i]; 121 } 122 return obj.options; 123 } 124 function getParamString(obj, existingUrl, uppercase) { 125 var params = []; 126 for (var i in obj) { 127 params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + "=" + encodeURIComponent(obj[i])); 128 } 129 return (!existingUrl || existingUrl.indexOf("?") === -1 ? "?" : "&") + params.join("&"); 130 } 131 var templateRe = /\{ *([\w_ -]+) *\}/g; 132 function template(str, data) { 133 return str.replace(templateRe, function(str2, key) { 134 var value = data[key]; 135 if (value === void 0) { 136 throw new Error("No value provided for variable " + str2); 137 } else if (typeof value === "function") { 138 value = value(data); 139 } 140 return value; 141 }); 142 } 143 var isArray = Array.isArray || function(obj) { 144 return Object.prototype.toString.call(obj) === "[object Array]"; 145 }; 146 function indexOf(array, el) { 147 for (var i = 0; i < array.length; i++) { 148 if (array[i] === el) { 149 return i; 150 } 151 } 152 return -1; 153 } 154 var emptyImageUrl = "data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="; 155 function getPrefixed(name) { 156 return window["webkit" + name] || window["moz" + name] || window["ms" + name]; 157 } 158 var lastTime = 0; 159 function timeoutDefer(fn2) { 160 var time = +/* @__PURE__ */ new Date(), timeToCall = Math.max(0, 16 - (time - lastTime)); 161 lastTime = time + timeToCall; 162 return window.setTimeout(fn2, timeToCall); 163 } 164 var requestFn = window.requestAnimationFrame || getPrefixed("RequestAnimationFrame") || timeoutDefer; 165 var cancelFn = window.cancelAnimationFrame || getPrefixed("CancelAnimationFrame") || getPrefixed("CancelRequestAnimationFrame") || function(id) { 166 window.clearTimeout(id); 167 }; 168 function requestAnimFrame(fn2, context, immediate) { 169 if (immediate && requestFn === timeoutDefer) { 170 fn2.call(context); 171 } else { 172 return requestFn.call(window, bind(fn2, context)); 173 } 174 } 175 function cancelAnimFrame(id) { 176 if (id) { 177 cancelFn.call(window, id); 178 } 179 } 180 var Util = { 181 __proto__: null, 182 extend, 183 create: create$2, 184 bind, 185 get lastId() { 186 return lastId; 187 }, 188 stamp, 189 throttle, 190 wrapNum, 191 falseFn, 192 formatNum, 193 trim, 194 splitWords, 195 setOptions, 196 getParamString, 197 template, 198 isArray, 199 indexOf, 200 emptyImageUrl, 201 requestFn, 202 cancelFn, 203 requestAnimFrame, 204 cancelAnimFrame 205 }; 206 function Class() { 207 } 208 Class.extend = function(props) { 209 var NewClass = function() { 210 setOptions(this); 211 if (this.initialize) { 212 this.initialize.apply(this, arguments); 213 } 214 this.callInitHooks(); 215 }; 216 var parentProto = NewClass.__super__ = this.prototype; 217 var proto = create$2(parentProto); 218 proto.constructor = NewClass; 219 NewClass.prototype = proto; 220 for (var i in this) { 221 if (Object.prototype.hasOwnProperty.call(this, i) && i !== "prototype" && i !== "__super__") { 222 NewClass[i] = this[i]; 223 } 224 } 225 if (props.statics) { 226 extend(NewClass, props.statics); 227 } 228 if (props.includes) { 229 checkDeprecatedMixinEvents(props.includes); 230 extend.apply(null, [proto].concat(props.includes)); 231 } 232 extend(proto, props); 233 delete proto.statics; 234 delete proto.includes; 235 if (proto.options) { 236 proto.options = parentProto.options ? create$2(parentProto.options) : {}; 237 extend(proto.options, props.options); 238 } 239 proto._initHooks = []; 240 proto.callInitHooks = function() { 241 if (this._initHooksCalled) { 242 return; 243 } 244 if (parentProto.callInitHooks) { 245 parentProto.callInitHooks.call(this); 246 } 247 this._initHooksCalled = true; 248 for (var i2 = 0, len = proto._initHooks.length; i2 < len; i2++) { 249 proto._initHooks[i2].call(this); 250 } 251 }; 252 return NewClass; 253 }; 254 Class.include = function(props) { 255 var parentOptions = this.prototype.options; 256 extend(this.prototype, props); 257 if (props.options) { 258 this.prototype.options = parentOptions; 259 this.mergeOptions(props.options); 260 } 261 return this; 262 }; 263 Class.mergeOptions = function(options) { 264 extend(this.prototype.options, options); 265 return this; 266 }; 267 Class.addInitHook = function(fn2) { 268 var args = Array.prototype.slice.call(arguments, 1); 269 var init = typeof fn2 === "function" ? fn2 : function() { 270 this[fn2].apply(this, args); 271 }; 272 this.prototype._initHooks = this.prototype._initHooks || []; 273 this.prototype._initHooks.push(init); 274 return this; 275 }; 276 function checkDeprecatedMixinEvents(includes) { 277 if (typeof L === "undefined" || !L || !L.Mixin) { 278 return; 279 } 280 includes = isArray(includes) ? includes : [includes]; 281 for (var i = 0; i < includes.length; i++) { 282 if (includes[i] === L.Mixin.Events) { 283 console.warn("Deprecated include of L.Mixin.Events: this property will be removed in future releases, please inherit from L.Evented instead.", new Error().stack); 284 } 285 } 286 } 287 var Events = { 288 /* @method on(type: String, fn: Function, context?: Object): this 289 * 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'`). 290 * 291 * @alternative 292 * @method on(eventMap: Object): this 293 * Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}` 294 */ 295 on: function(types, fn2, context) { 296 if (typeof types === "object") { 297 for (var type in types) { 298 this._on(type, types[type], fn2); 299 } 300 } else { 301 types = splitWords(types); 302 for (var i = 0, len = types.length; i < len; i++) { 303 this._on(types[i], fn2, context); 304 } 305 } 306 return this; 307 }, 308 /* @method off(type: String, fn?: Function, context?: Object): this 309 * 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. 310 * 311 * @alternative 312 * @method off(eventMap: Object): this 313 * Removes a set of type/listener pairs. 314 * 315 * @alternative 316 * @method off: this 317 * Removes all listeners to all events on the object. This includes implicitly attached events. 318 */ 319 off: function(types, fn2, context) { 320 if (!arguments.length) { 321 delete this._events; 322 } else if (typeof types === "object") { 323 for (var type in types) { 324 this._off(type, types[type], fn2); 325 } 326 } else { 327 types = splitWords(types); 328 var removeAll = arguments.length === 1; 329 for (var i = 0, len = types.length; i < len; i++) { 330 if (removeAll) { 331 this._off(types[i]); 332 } else { 333 this._off(types[i], fn2, context); 334 } 335 } 336 } 337 return this; 338 }, 339 // attach listener (without syntactic sugar now) 340 _on: function(type, fn2, context, _once) { 341 if (typeof fn2 !== "function") { 342 console.warn("wrong listener type: " + typeof fn2); 343 return; 344 } 345 if (this._listens(type, fn2, context) !== false) { 346 return; 347 } 348 if (context === this) { 349 context = void 0; 350 } 351 var newListener = { fn: fn2, ctx: context }; 352 if (_once) { 353 newListener.once = true; 354 } 355 this._events = this._events || {}; 356 this._events[type] = this._events[type] || []; 357 this._events[type].push(newListener); 358 }, 359 _off: function(type, fn2, context) { 360 var listeners, i, len; 361 if (!this._events) { 362 return; 363 } 364 listeners = this._events[type]; 365 if (!listeners) { 366 return; 367 } 368 if (arguments.length === 1) { 369 if (this._firingCount) { 370 for (i = 0, len = listeners.length; i < len; i++) { 371 listeners[i].fn = falseFn; 372 } 373 } 374 delete this._events[type]; 375 return; 376 } 377 if (typeof fn2 !== "function") { 378 console.warn("wrong listener type: " + typeof fn2); 379 return; 380 } 381 var index2 = this._listens(type, fn2, context); 382 if (index2 !== false) { 383 var listener = listeners[index2]; 384 if (this._firingCount) { 385 listener.fn = falseFn; 386 this._events[type] = listeners = listeners.slice(); 387 } 388 listeners.splice(index2, 1); 389 } 390 }, 391 // @method fire(type: String, data?: Object, propagate?: Boolean): this 392 // Fires an event of the specified type. You can optionally provide a data 393 // object â the first argument of the listener function will contain its 394 // properties. The event can optionally be propagated to event parents. 395 fire: function(type, data, propagate) { 396 if (!this.listens(type, propagate)) { 397 return this; 398 } 399 var event = extend({}, data, { 400 type, 401 target: this, 402 sourceTarget: data && data.sourceTarget || this 403 }); 404 if (this._events) { 405 var listeners = this._events[type]; 406 if (listeners) { 407 this._firingCount = this._firingCount + 1 || 1; 408 for (var i = 0, len = listeners.length; i < len; i++) { 409 var l = listeners[i]; 410 var fn2 = l.fn; 411 if (l.once) { 412 this.off(type, fn2, l.ctx); 413 } 414 fn2.call(l.ctx || this, event); 415 } 416 this._firingCount--; 417 } 418 } 419 if (propagate) { 420 this._propagateEvent(event); 421 } 422 return this; 423 }, 424 // @method listens(type: String, propagate?: Boolean): Boolean 425 // @method listens(type: String, fn: Function, context?: Object, propagate?: Boolean): Boolean 426 // Returns `true` if a particular event type has any listeners attached to it. 427 // The verification can optionally be propagated, it will return `true` if parents have the listener attached to it. 428 listens: function(type, fn2, context, propagate) { 429 if (typeof type !== "string") { 430 console.warn('"string" type argument expected'); 431 } 432 var _fn = fn2; 433 if (typeof fn2 !== "function") { 434 propagate = !!fn2; 435 _fn = void 0; 436 context = void 0; 437 } 438 var listeners = this._events && this._events[type]; 439 if (listeners && listeners.length) { 440 if (this._listens(type, _fn, context) !== false) { 441 return true; 442 } 443 } 444 if (propagate) { 445 for (var id in this._eventParents) { 446 if (this._eventParents[id].listens(type, fn2, context, propagate)) { 447 return true; 448 } 449 } 450 } 451 return false; 452 }, 453 // returns the index (number) or false 454 _listens: function(type, fn2, context) { 455 if (!this._events) { 456 return false; 457 } 458 var listeners = this._events[type] || []; 459 if (!fn2) { 460 return !!listeners.length; 461 } 462 if (context === this) { 463 context = void 0; 464 } 465 for (var i = 0, len = listeners.length; i < len; i++) { 466 if (listeners[i].fn === fn2 && listeners[i].ctx === context) { 467 return i; 468 } 469 } 470 return false; 471 }, 472 // @method once(â¦): this 473 // Behaves as [`on(â¦)`](#evented-on), except the listener will only get fired once and then removed. 474 once: function(types, fn2, context) { 475 if (typeof types === "object") { 476 for (var type in types) { 477 this._on(type, types[type], fn2, true); 478 } 479 } else { 480 types = splitWords(types); 481 for (var i = 0, len = types.length; i < len; i++) { 482 this._on(types[i], fn2, context, true); 483 } 484 } 485 return this; 486 }, 487 // @method addEventParent(obj: Evented): this 488 // Adds an event parent - an `Evented` that will receive propagated events 489 addEventParent: function(obj) { 490 this._eventParents = this._eventParents || {}; 491 this._eventParents[stamp(obj)] = obj; 492 return this; 493 }, 494 // @method removeEventParent(obj: Evented): this 495 // Removes an event parent, so it will stop receiving propagated events 496 removeEventParent: function(obj) { 497 if (this._eventParents) { 498 delete this._eventParents[stamp(obj)]; 499 } 500 return this; 501 }, 502 _propagateEvent: function(e) { 503 for (var id in this._eventParents) { 504 this._eventParents[id].fire(e.type, extend({ 505 layer: e.target, 506 propagatedFrom: e.target 507 }, e), true); 508 } 509 } 510 }; 511 Events.addEventListener = Events.on; 512 Events.removeEventListener = Events.clearAllEventListeners = Events.off; 513 Events.addOneTimeEventListener = Events.once; 514 Events.fireEvent = Events.fire; 515 Events.hasEventListeners = Events.listens; 516 var Evented = Class.extend(Events); 517 function Point(x, y, round2) { 518 this.x = round2 ? Math.round(x) : x; 519 this.y = round2 ? Math.round(y) : y; 520 } 521 var trunc = Math.trunc || function(v) { 522 return v > 0 ? Math.floor(v) : Math.ceil(v); 523 }; 524 Point.prototype = { 525 // @method clone(): Point 526 // Returns a copy of the current point. 527 clone: function() { 528 return new Point(this.x, this.y); 529 }, 530 // @method add(otherPoint: Point): Point 531 // Returns the result of addition of the current and the given points. 532 add: function(point) { 533 return this.clone()._add(toPoint(point)); 534 }, 535 _add: function(point) { 536 this.x += point.x; 537 this.y += point.y; 538 return this; 539 }, 540 // @method subtract(otherPoint: Point): Point 541 // Returns the result of subtraction of the given point from the current. 542 subtract: function(point) { 543 return this.clone()._subtract(toPoint(point)); 544 }, 545 _subtract: function(point) { 546 this.x -= point.x; 547 this.y -= point.y; 548 return this; 549 }, 550 // @method divideBy(num: Number): Point 551 // Returns the result of division of the current point by the given number. 552 divideBy: function(num) { 553 return this.clone()._divideBy(num); 554 }, 555 _divideBy: function(num) { 556 this.x /= num; 557 this.y /= num; 558 return this; 559 }, 560 // @method multiplyBy(num: Number): Point 561 // Returns the result of multiplication of the current point by the given number. 562 multiplyBy: function(num) { 563 return this.clone()._multiplyBy(num); 564 }, 565 _multiplyBy: function(num) { 566 this.x *= num; 567 this.y *= num; 568 return this; 569 }, 570 // @method scaleBy(scale: Point): Point 571 // Multiply each coordinate of the current point by each coordinate of 572 // `scale`. In linear algebra terms, multiply the point by the 573 // [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation) 574 // defined by `scale`. 575 scaleBy: function(point) { 576 return new Point(this.x * point.x, this.y * point.y); 577 }, 578 // @method unscaleBy(scale: Point): Point 579 // Inverse of `scaleBy`. Divide each coordinate of the current point by 580 // each coordinate of `scale`. 581 unscaleBy: function(point) { 582 return new Point(this.x / point.x, this.y / point.y); 583 }, 584 // @method round(): Point 585 // Returns a copy of the current point with rounded coordinates. 586 round: function() { 587 return this.clone()._round(); 588 }, 589 _round: function() { 590 this.x = Math.round(this.x); 591 this.y = Math.round(this.y); 592 return this; 593 }, 594 // @method floor(): Point 595 // Returns a copy of the current point with floored coordinates (rounded down). 596 floor: function() { 597 return this.clone()._floor(); 598 }, 599 _floor: function() { 600 this.x = Math.floor(this.x); 601 this.y = Math.floor(this.y); 602 return this; 603 }, 604 // @method ceil(): Point 605 // Returns a copy of the current point with ceiled coordinates (rounded up). 606 ceil: function() { 607 return this.clone()._ceil(); 608 }, 609 _ceil: function() { 610 this.x = Math.ceil(this.x); 611 this.y = Math.ceil(this.y); 612 return this; 613 }, 614 // @method trunc(): Point 615 // Returns a copy of the current point with truncated coordinates (rounded towards zero). 616 trunc: function() { 617 return this.clone()._trunc(); 618 }, 619 _trunc: function() { 620 this.x = trunc(this.x); 621 this.y = trunc(this.y); 622 return this; 623 }, 624 // @method distanceTo(otherPoint: Point): Number 625 // Returns the cartesian distance between the current and the given points. 626 distanceTo: function(point) { 627 point = toPoint(point); 628 var x = point.x - this.x, y = point.y - this.y; 629 return Math.sqrt(x * x + y * y); 630 }, 631 // @method equals(otherPoint: Point): Boolean 632 // Returns `true` if the given point has the same coordinates. 633 equals: function(point) { 634 point = toPoint(point); 635 return point.x === this.x && point.y === this.y; 636 }, 637 // @method contains(otherPoint: Point): Boolean 638 // Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values). 639 contains: function(point) { 640 point = toPoint(point); 641 return Math.abs(point.x) <= Math.abs(this.x) && Math.abs(point.y) <= Math.abs(this.y); 642 }, 643 // @method toString(): String 644 // Returns a string representation of the point for debugging purposes. 645 toString: function() { 646 return "Point(" + formatNum(this.x) + ", " + formatNum(this.y) + ")"; 647 } 648 }; 649 function toPoint(x, y, round2) { 650 if (x instanceof Point) { 651 return x; 652 } 653 if (isArray(x)) { 654 return new Point(x[0], x[1]); 655 } 656 if (x === void 0 || x === null) { 657 return x; 658 } 659 if (typeof x === "object" && "x" in x && "y" in x) { 660 return new Point(x.x, x.y); 661 } 662 return new Point(x, y, round2); 663 } 664 function Bounds(a, b) { 665 if (!a) { 666 return; 667 } 668 var points = b ? [a, b] : a; 669 for (var i = 0, len = points.length; i < len; i++) { 670 this.extend(points[i]); 671 } 672 } 673 Bounds.prototype = { 674 // @method extend(point: Point): this 675 // Extends the bounds to contain the given point. 676 // @alternative 677 // @method extend(otherBounds: Bounds): this 678 // Extend the bounds to contain the given bounds 679 extend: function(obj) { 680 var min2, max2; 681 if (!obj) { 682 return this; 683 } 684 if (obj instanceof Point || typeof obj[0] === "number" || "x" in obj) { 685 min2 = max2 = toPoint(obj); 686 } else { 687 obj = toBounds(obj); 688 min2 = obj.min; 689 max2 = obj.max; 690 if (!min2 || !max2) { 691 return this; 692 } 693 } 694 if (!this.min && !this.max) { 695 this.min = min2.clone(); 696 this.max = max2.clone(); 697 } else { 698 this.min.x = Math.min(min2.x, this.min.x); 699 this.max.x = Math.max(max2.x, this.max.x); 700 this.min.y = Math.min(min2.y, this.min.y); 701 this.max.y = Math.max(max2.y, this.max.y); 702 } 703 return this; 704 }, 705 // @method getCenter(round?: Boolean): Point 706 // Returns the center point of the bounds. 707 getCenter: function(round2) { 708 return toPoint( 709 (this.min.x + this.max.x) / 2, 710 (this.min.y + this.max.y) / 2, 711 round2 712 ); 713 }, 714 // @method getBottomLeft(): Point 715 // Returns the bottom-left point of the bounds. 716 getBottomLeft: function() { 717 return toPoint(this.min.x, this.max.y); 718 }, 719 // @method getTopRight(): Point 720 // Returns the top-right point of the bounds. 721 getTopRight: function() { 722 return toPoint(this.max.x, this.min.y); 723 }, 724 // @method getTopLeft(): Point 725 // Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)). 726 getTopLeft: function() { 727 return this.min; 728 }, 729 // @method getBottomRight(): Point 730 // Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)). 731 getBottomRight: function() { 732 return this.max; 733 }, 734 // @method getSize(): Point 735 // Returns the size of the given bounds 736 getSize: function() { 737 return this.max.subtract(this.min); 738 }, 739 // @method contains(otherBounds: Bounds): Boolean 740 // Returns `true` if the rectangle contains the given one. 741 // @alternative 742 // @method contains(point: Point): Boolean 743 // Returns `true` if the rectangle contains the given point. 744 contains: function(obj) { 745 var min2, max2; 746 if (typeof obj[0] === "number" || obj instanceof Point) { 747 obj = toPoint(obj); 748 } else { 749 obj = toBounds(obj); 750 } 751 if (obj instanceof Bounds) { 752 min2 = obj.min; 753 max2 = obj.max; 754 } else { 755 min2 = max2 = obj; 756 } 757 return min2.x >= this.min.x && max2.x <= this.max.x && min2.y >= this.min.y && max2.y <= this.max.y; 758 }, 759 // @method intersects(otherBounds: Bounds): Boolean 760 // Returns `true` if the rectangle intersects the given bounds. Two bounds 761 // intersect if they have at least one point in common. 762 intersects: function(bounds) { 763 bounds = toBounds(bounds); 764 var min2 = this.min, max2 = this.max, min22 = bounds.min, max22 = bounds.max, xIntersects = max22.x >= min2.x && min22.x <= max2.x, yIntersects = max22.y >= min2.y && min22.y <= max2.y; 765 return xIntersects && yIntersects; 766 }, 767 // @method overlaps(otherBounds: Bounds): Boolean 768 // Returns `true` if the rectangle overlaps the given bounds. Two bounds 769 // overlap if their intersection is an area. 770 overlaps: function(bounds) { 771 bounds = toBounds(bounds); 772 var min2 = this.min, max2 = this.max, min22 = bounds.min, max22 = bounds.max, xOverlaps = max22.x > min2.x && min22.x < max2.x, yOverlaps = max22.y > min2.y && min22.y < max2.y; 773 return xOverlaps && yOverlaps; 774 }, 775 // @method isValid(): Boolean 776 // Returns `true` if the bounds are properly initialized. 777 isValid: function() { 778 return !!(this.min && this.max); 779 }, 780 // @method pad(bufferRatio: Number): Bounds 781 // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction. 782 // For example, a ratio of 0.5 extends the bounds by 50% in each direction. 783 // Negative values will retract the bounds. 784 pad: function(bufferRatio) { 785 var min2 = this.min, max2 = this.max, heightBuffer = Math.abs(min2.x - max2.x) * bufferRatio, widthBuffer = Math.abs(min2.y - max2.y) * bufferRatio; 786 return toBounds( 787 toPoint(min2.x - heightBuffer, min2.y - widthBuffer), 788 toPoint(max2.x + heightBuffer, max2.y + widthBuffer) 789 ); 790 }, 791 // @method equals(otherBounds: Bounds): Boolean 792 // Returns `true` if the rectangle is equivalent to the given bounds. 793 equals: function(bounds) { 794 if (!bounds) { 795 return false; 796 } 797 bounds = toBounds(bounds); 798 return this.min.equals(bounds.getTopLeft()) && this.max.equals(bounds.getBottomRight()); 799 } 800 }; 801 function toBounds(a, b) { 802 if (!a || a instanceof Bounds) { 803 return a; 804 } 805 return new Bounds(a, b); 806 } 807 function LatLngBounds(corner1, corner2) { 808 if (!corner1) { 809 return; 810 } 811 var latlngs = corner2 ? [corner1, corner2] : corner1; 812 for (var i = 0, len = latlngs.length; i < len; i++) { 813 this.extend(latlngs[i]); 814 } 815 } 816 LatLngBounds.prototype = { 817 // @method extend(latlng: LatLng): this 818 // Extend the bounds to contain the given point 819 // @alternative 820 // @method extend(otherBounds: LatLngBounds): this 821 // Extend the bounds to contain the given bounds 822 extend: function(obj) { 823 var sw = this._southWest, ne = this._northEast, sw2, ne2; 824 if (obj instanceof LatLng) { 825 sw2 = obj; 826 ne2 = obj; 827 } else if (obj instanceof LatLngBounds) { 828 sw2 = obj._southWest; 829 ne2 = obj._northEast; 830 if (!sw2 || !ne2) { 831 return this; 832 } 833 } else { 834 return obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this; 835 } 836 if (!sw && !ne) { 837 this._southWest = new LatLng(sw2.lat, sw2.lng); 838 this._northEast = new LatLng(ne2.lat, ne2.lng); 839 } else { 840 sw.lat = Math.min(sw2.lat, sw.lat); 841 sw.lng = Math.min(sw2.lng, sw.lng); 842 ne.lat = Math.max(ne2.lat, ne.lat); 843 ne.lng = Math.max(ne2.lng, ne.lng); 844 } 845 return this; 846 }, 847 // @method pad(bufferRatio: Number): LatLngBounds 848 // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction. 849 // For example, a ratio of 0.5 extends the bounds by 50% in each direction. 850 // Negative values will retract the bounds. 851 pad: function(bufferRatio) { 852 var sw = this._southWest, ne = this._northEast, heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio, widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio; 853 return new LatLngBounds( 854 new LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer), 855 new LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer) 856 ); 857 }, 858 // @method getCenter(): LatLng 859 // Returns the center point of the bounds. 860 getCenter: function() { 861 return new LatLng( 862 (this._southWest.lat + this._northEast.lat) / 2, 863 (this._southWest.lng + this._northEast.lng) / 2 864 ); 865 }, 866 // @method getSouthWest(): LatLng 867 // Returns the south-west point of the bounds. 868 getSouthWest: function() { 869 return this._southWest; 870 }, 871 // @method getNorthEast(): LatLng 872 // Returns the north-east point of the bounds. 873 getNorthEast: function() { 874 return this._northEast; 875 }, 876 // @method getNorthWest(): LatLng 877 // Returns the north-west point of the bounds. 878 getNorthWest: function() { 879 return new LatLng(this.getNorth(), this.getWest()); 880 }, 881 // @method getSouthEast(): LatLng 882 // Returns the south-east point of the bounds. 883 getSouthEast: function() { 884 return new LatLng(this.getSouth(), this.getEast()); 885 }, 886 // @method getWest(): Number 887 // Returns the west longitude of the bounds 888 getWest: function() { 889 return this._southWest.lng; 890 }, 891 // @method getSouth(): Number 892 // Returns the south latitude of the bounds 893 getSouth: function() { 894 return this._southWest.lat; 895 }, 896 // @method getEast(): Number 897 // Returns the east longitude of the bounds 898 getEast: function() { 899 return this._northEast.lng; 900 }, 901 // @method getNorth(): Number 902 // Returns the north latitude of the bounds 903 getNorth: function() { 904 return this._northEast.lat; 905 }, 906 // @method contains(otherBounds: LatLngBounds): Boolean 907 // Returns `true` if the rectangle contains the given one. 908 // @alternative 909 // @method contains (latlng: LatLng): Boolean 910 // Returns `true` if the rectangle contains the given point. 911 contains: function(obj) { 912 if (typeof obj[0] === "number" || obj instanceof LatLng || "lat" in obj) { 913 obj = toLatLng(obj); 914 } else { 915 obj = toLatLngBounds(obj); 916 } 917 var sw = this._southWest, ne = this._northEast, sw2, ne2; 918 if (obj instanceof LatLngBounds) { 919 sw2 = obj.getSouthWest(); 920 ne2 = obj.getNorthEast(); 921 } else { 922 sw2 = ne2 = obj; 923 } 924 return sw2.lat >= sw.lat && ne2.lat <= ne.lat && sw2.lng >= sw.lng && ne2.lng <= ne.lng; 925 }, 926 // @method intersects(otherBounds: LatLngBounds): Boolean 927 // Returns `true` if the rectangle intersects the given bounds. Two bounds intersect if they have at least one point in common. 928 intersects: function(bounds) { 929 bounds = toLatLngBounds(bounds); 930 var sw = this._southWest, ne = this._northEast, sw2 = bounds.getSouthWest(), ne2 = bounds.getNorthEast(), latIntersects = ne2.lat >= sw.lat && sw2.lat <= ne.lat, lngIntersects = ne2.lng >= sw.lng && sw2.lng <= ne.lng; 931 return latIntersects && lngIntersects; 932 }, 933 // @method overlaps(otherBounds: LatLngBounds): Boolean 934 // Returns `true` if the rectangle overlaps the given bounds. Two bounds overlap if their intersection is an area. 935 overlaps: function(bounds) { 936 bounds = toLatLngBounds(bounds); 937 var sw = this._southWest, ne = this._northEast, sw2 = bounds.getSouthWest(), ne2 = bounds.getNorthEast(), latOverlaps = ne2.lat > sw.lat && sw2.lat < ne.lat, lngOverlaps = ne2.lng > sw.lng && sw2.lng < ne.lng; 938 return latOverlaps && lngOverlaps; 939 }, 940 // @method toBBoxString(): String 941 // 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. 942 toBBoxString: function() { 943 return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(","); 944 }, 945 // @method equals(otherBounds: LatLngBounds, maxMargin?: Number): Boolean 946 // 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. 947 equals: function(bounds, maxMargin) { 948 if (!bounds) { 949 return false; 950 } 951 bounds = toLatLngBounds(bounds); 952 return this._southWest.equals(bounds.getSouthWest(), maxMargin) && this._northEast.equals(bounds.getNorthEast(), maxMargin); 953 }, 954 // @method isValid(): Boolean 955 // Returns `true` if the bounds are properly initialized. 956 isValid: function() { 957 return !!(this._southWest && this._northEast); 958 } 959 }; 960 function toLatLngBounds(a, b) { 961 if (a instanceof LatLngBounds) { 962 return a; 963 } 964 return new LatLngBounds(a, b); 965 } 966 function LatLng(lat, lng, alt) { 967 if (isNaN(lat) || isNaN(lng)) { 968 throw new Error("Invalid LatLng object: (" + lat + ", " + lng + ")"); 969 } 970 this.lat = +lat; 971 this.lng = +lng; 972 if (alt !== void 0) { 973 this.alt = +alt; 974 } 975 } 976 LatLng.prototype = { 977 // @method equals(otherLatLng: LatLng, maxMargin?: Number): Boolean 978 // 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. 979 equals: function(obj, maxMargin) { 980 if (!obj) { 981 return false; 982 } 983 obj = toLatLng(obj); 984 var margin = Math.max( 985 Math.abs(this.lat - obj.lat), 986 Math.abs(this.lng - obj.lng) 987 ); 988 return margin <= (maxMargin === void 0 ? 1e-9 : maxMargin); 989 }, 990 // @method toString(): String 991 // Returns a string representation of the point (for debugging purposes). 992 toString: function(precision) { 993 return "LatLng(" + formatNum(this.lat, precision) + ", " + formatNum(this.lng, precision) + ")"; 994 }, 995 // @method distanceTo(otherLatLng: LatLng): Number 996 // 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). 997 distanceTo: function(other) { 998 return Earth.distance(this, toLatLng(other)); 999 }, 1000 // @method wrap(): LatLng 1001 // Returns a new `LatLng` object with the longitude wrapped so it's always between -180 and +180 degrees. 1002 wrap: function() { 1003 return Earth.wrapLatLng(this); 1004 }, 1005 // @method toBounds(sizeInMeters: Number): LatLngBounds 1006 // Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`. 1007 toBounds: function(sizeInMeters) { 1008 var latAccuracy = 180 * sizeInMeters / 40075017, lngAccuracy = latAccuracy / Math.cos(Math.PI / 180 * this.lat); 1009 return toLatLngBounds( 1010 [this.lat - latAccuracy, this.lng - lngAccuracy], 1011 [this.lat + latAccuracy, this.lng + lngAccuracy] 1012 ); 1013 }, 1014 clone: function() { 1015 return new LatLng(this.lat, this.lng, this.alt); 1016 } 1017 }; 1018 function toLatLng(a, b, c) { 1019 if (a instanceof LatLng) { 1020 return a; 1021 } 1022 if (isArray(a) && typeof a[0] !== "object") { 1023 if (a.length === 3) { 1024 return new LatLng(a[0], a[1], a[2]); 1025 } 1026 if (a.length === 2) { 1027 return new LatLng(a[0], a[1]); 1028 } 1029 return null; 1030 } 1031 if (a === void 0 || a === null) { 1032 return a; 1033 } 1034 if (typeof a === "object" && "lat" in a) { 1035 return new LatLng(a.lat, "lng" in a ? a.lng : a.lon, a.alt); 1036 } 1037 if (b === void 0) { 1038 return null; 1039 } 1040 return new LatLng(a, b, c); 1041 } 1042 var CRS = { 1043 // @method latLngToPoint(latlng: LatLng, zoom: Number): Point 1044 // Projects geographical coordinates into pixel coordinates for a given zoom. 1045 latLngToPoint: function(latlng, zoom2) { 1046 var projectedPoint = this.projection.project(latlng), scale2 = this.scale(zoom2); 1047 return this.transformation._transform(projectedPoint, scale2); 1048 }, 1049 // @method pointToLatLng(point: Point, zoom: Number): LatLng 1050 // The inverse of `latLngToPoint`. Projects pixel coordinates on a given 1051 // zoom into geographical coordinates. 1052 pointToLatLng: function(point, zoom2) { 1053 var scale2 = this.scale(zoom2), untransformedPoint = this.transformation.untransform(point, scale2); 1054 return this.projection.unproject(untransformedPoint); 1055 }, 1056 // @method project(latlng: LatLng): Point 1057 // Projects geographical coordinates into coordinates in units accepted for 1058 // this CRS (e.g. meters for EPSG:3857, for passing it to WMS services). 1059 project: function(latlng) { 1060 return this.projection.project(latlng); 1061 }, 1062 // @method unproject(point: Point): LatLng 1063 // Given a projected coordinate returns the corresponding LatLng. 1064 // The inverse of `project`. 1065 unproject: function(point) { 1066 return this.projection.unproject(point); 1067 }, 1068 // @method scale(zoom: Number): Number 1069 // Returns the scale used when transforming projected coordinates into 1070 // pixel coordinates for a particular zoom. For example, it returns 1071 // `256 * 2^zoom` for Mercator-based CRS. 1072 scale: function(zoom2) { 1073 return 256 * Math.pow(2, zoom2); 1074 }, 1075 // @method zoom(scale: Number): Number 1076 // Inverse of `scale()`, returns the zoom level corresponding to a scale 1077 // factor of `scale`. 1078 zoom: function(scale2) { 1079 return Math.log(scale2 / 256) / Math.LN2; 1080 }, 1081 // @method getProjectedBounds(zoom: Number): Bounds 1082 // Returns the projection's bounds scaled and transformed for the provided `zoom`. 1083 getProjectedBounds: function(zoom2) { 1084 if (this.infinite) { 1085 return null; 1086 } 1087 var b = this.projection.bounds, s = this.scale(zoom2), min2 = this.transformation.transform(b.min, s), max2 = this.transformation.transform(b.max, s); 1088 return new Bounds(min2, max2); 1089 }, 1090 // @method distance(latlng1: LatLng, latlng2: LatLng): Number 1091 // Returns the distance between two geographical coordinates. 1092 // @property code: String 1093 // Standard code name of the CRS passed into WMS services (e.g. `'EPSG:3857'`) 1094 // 1095 // @property wrapLng: Number[] 1096 // An array of two numbers defining whether the longitude (horizontal) coordinate 1097 // axis wraps around a given range and how. Defaults to `[-180, 180]` in most 1098 // geographical CRSs. If `undefined`, the longitude axis does not wrap around. 1099 // 1100 // @property wrapLat: Number[] 1101 // Like `wrapLng`, but for the latitude (vertical) axis. 1102 // wrapLng: [min, max], 1103 // wrapLat: [min, max], 1104 // @property infinite: Boolean 1105 // If true, the coordinate space will be unbounded (infinite in both axes) 1106 infinite: false, 1107 // @method wrapLatLng(latlng: LatLng): LatLng 1108 // Returns a `LatLng` where lat and lng has been wrapped according to the 1109 // CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds. 1110 wrapLatLng: function(latlng) { 1111 var lng = this.wrapLng ? wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng, lat = this.wrapLat ? wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat, alt = latlng.alt; 1112 return new LatLng(lat, lng, alt); 1113 }, 1114 // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds 1115 // Returns a `LatLngBounds` with the same size as the given one, ensuring 1116 // that its center is within the CRS's bounds. 1117 // Only accepts actual `L.LatLngBounds` instances, not arrays. 1118 wrapLatLngBounds: function(bounds) { 1119 var center = bounds.getCenter(), newCenter = this.wrapLatLng(center), latShift = center.lat - newCenter.lat, lngShift = center.lng - newCenter.lng; 1120 if (latShift === 0 && lngShift === 0) { 1121 return bounds; 1122 } 1123 var sw = bounds.getSouthWest(), ne = bounds.getNorthEast(), newSw = new LatLng(sw.lat - latShift, sw.lng - lngShift), newNe = new LatLng(ne.lat - latShift, ne.lng - lngShift); 1124 return new LatLngBounds(newSw, newNe); 1125 } 1126 }; 1127 var Earth = extend({}, CRS, { 1128 wrapLng: [-180, 180], 1129 // Mean Earth Radius, as recommended for use by 1130 // the International Union of Geodesy and Geophysics, 1131 // see https://rosettacode.org/wiki/Haversine_formula 1132 R: 6371e3, 1133 // distance between two geographical points using spherical law of cosines approximation 1134 distance: function(latlng1, latlng2) { 1135 var rad = Math.PI / 180, lat1 = latlng1.lat * rad, lat2 = latlng2.lat * rad, sinDLat = Math.sin((latlng2.lat - latlng1.lat) * rad / 2), sinDLon = Math.sin((latlng2.lng - latlng1.lng) * rad / 2), a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon, c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 1136 return this.R * c; 1137 } 1138 }); 1139 var earthRadius = 6378137; 1140 var SphericalMercator = { 1141 R: earthRadius, 1142 MAX_LATITUDE: 85.0511287798, 1143 project: function(latlng) { 1144 var d = Math.PI / 180, max2 = this.MAX_LATITUDE, lat = Math.max(Math.min(max2, latlng.lat), -max2), sin = Math.sin(lat * d); 1145 return new Point( 1146 this.R * latlng.lng * d, 1147 this.R * Math.log((1 + sin) / (1 - sin)) / 2 1148 ); 1149 }, 1150 unproject: function(point) { 1151 var d = 180 / Math.PI; 1152 return new LatLng( 1153 (2 * Math.atan(Math.exp(point.y / this.R)) - Math.PI / 2) * d, 1154 point.x * d / this.R 1155 ); 1156 }, 1157 bounds: function() { 1158 var d = earthRadius * Math.PI; 1159 return new Bounds([-d, -d], [d, d]); 1160 }() 1161 }; 1162 function Transformation(a, b, c, d) { 1163 if (isArray(a)) { 1164 this._a = a[0]; 1165 this._b = a[1]; 1166 this._c = a[2]; 1167 this._d = a[3]; 1168 return; 1169 } 1170 this._a = a; 1171 this._b = b; 1172 this._c = c; 1173 this._d = d; 1174 } 1175 Transformation.prototype = { 1176 // @method transform(point: Point, scale?: Number): Point 1177 // Returns a transformed point, optionally multiplied by the given scale. 1178 // Only accepts actual `L.Point` instances, not arrays. 1179 transform: function(point, scale2) { 1180 return this._transform(point.clone(), scale2); 1181 }, 1182 // destructive transform (faster) 1183 _transform: function(point, scale2) { 1184 scale2 = scale2 || 1; 1185 point.x = scale2 * (this._a * point.x + this._b); 1186 point.y = scale2 * (this._c * point.y + this._d); 1187 return point; 1188 }, 1189 // @method untransform(point: Point, scale?: Number): Point 1190 // Returns the reverse transformation of the given point, optionally divided 1191 // by the given scale. Only accepts actual `L.Point` instances, not arrays. 1192 untransform: function(point, scale2) { 1193 scale2 = scale2 || 1; 1194 return new Point( 1195 (point.x / scale2 - this._b) / this._a, 1196 (point.y / scale2 - this._d) / this._c 1197 ); 1198 } 1199 }; 1200 function toTransformation(a, b, c, d) { 1201 return new Transformation(a, b, c, d); 1202 } 1203 var EPSG3857 = extend({}, Earth, { 1204 code: "EPSG:3857", 1205 projection: SphericalMercator, 1206 transformation: function() { 1207 var scale2 = 0.5 / (Math.PI * SphericalMercator.R); 1208 return toTransformation(scale2, 0.5, -scale2, 0.5); 1209 }() 1210 }); 1211 var EPSG900913 = extend({}, EPSG3857, { 1212 code: "EPSG:900913" 1213 }); 1214 function svgCreate(name) { 1215 return document.createElementNS("http://www.w3.org/2000/svg", name); 1216 } 1217 function pointsToPath(rings, closed) { 1218 var str = "", i, j, len, len2, points, p; 1219 for (i = 0, len = rings.length; i < len; i++) { 1220 points = rings[i]; 1221 for (j = 0, len2 = points.length; j < len2; j++) { 1222 p = points[j]; 1223 str += (j ? "L" : "M") + p.x + " " + p.y; 1224 } 1225 str += closed ? Browser.svg ? "z" : "x" : ""; 1226 } 1227 return str || "M0 0"; 1228 } 1229 var style = document.documentElement.style; 1230 var ie = "ActiveXObject" in window; 1231 var ielt9 = ie && !document.addEventListener; 1232 var edge = "msLaunchUri" in navigator && !("documentMode" in document); 1233 var webkit = userAgentContains("webkit"); 1234 var android = userAgentContains("android"); 1235 var android23 = userAgentContains("android 2") || userAgentContains("android 3"); 1236 var webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); 1237 var androidStock = android && userAgentContains("Google") && webkitVer < 537 && !("AudioNode" in window); 1238 var opera = !!window.opera; 1239 var chrome = !edge && userAgentContains("chrome"); 1240 var gecko = userAgentContains("gecko") && !webkit && !opera && !ie; 1241 var safari = !chrome && userAgentContains("safari"); 1242 var phantom = userAgentContains("phantom"); 1243 var opera12 = "OTransition" in style; 1244 var win = navigator.platform.indexOf("Win") === 0; 1245 var ie3d = ie && "transition" in style; 1246 var webkit3d = "WebKitCSSMatrix" in window && "m11" in new window.WebKitCSSMatrix() && !android23; 1247 var gecko3d = "MozPerspective" in style; 1248 var any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d) && !opera12 && !phantom; 1249 var mobile = typeof orientation !== "undefined" || userAgentContains("mobile"); 1250 var mobileWebkit = mobile && webkit; 1251 var mobileWebkit3d = mobile && webkit3d; 1252 var msPointer = !window.PointerEvent && window.MSPointerEvent; 1253 var pointer = !!(window.PointerEvent || msPointer); 1254 var touchNative = "ontouchstart" in window || !!window.TouchEvent; 1255 var touch = !window.L_NO_TOUCH && (touchNative || pointer); 1256 var mobileOpera = mobile && opera; 1257 var mobileGecko = mobile && gecko; 1258 var retina = (window.devicePixelRatio || window.screen.deviceXDPI / window.screen.logicalXDPI) > 1; 1259 var passiveEvents = function() { 1260 var supportsPassiveOption = false; 1261 try { 1262 var opts = Object.defineProperty({}, "passive", { 1263 get: function() { 1264 supportsPassiveOption = true; 1265 } 1266 }); 1267 window.addEventListener("testPassiveEventSupport", falseFn, opts); 1268 window.removeEventListener("testPassiveEventSupport", falseFn, opts); 1269 } catch (e) { 1270 } 1271 return supportsPassiveOption; 1272 }(); 1273 var canvas$1 = function() { 1274 return !!document.createElement("canvas").getContext; 1275 }(); 1276 var svg$1 = !!(document.createElementNS && svgCreate("svg").createSVGRect); 1277 var inlineSvg = !!svg$1 && function() { 1278 var div = document.createElement("div"); 1279 div.innerHTML = "<svg/>"; 1280 return (div.firstChild && div.firstChild.namespaceURI) === "http://www.w3.org/2000/svg"; 1281 }(); 1282 var vml = !svg$1 && function() { 1283 try { 1284 var div = document.createElement("div"); 1285 div.innerHTML = '<v:shape adj="1"/>'; 1286 var shape = div.firstChild; 1287 shape.style.behavior = "url(#default#VML)"; 1288 return shape && typeof shape.adj === "object"; 1289 } catch (e) { 1290 return false; 1291 } 1292 }(); 1293 var mac = navigator.platform.indexOf("Mac") === 0; 1294 var linux = navigator.platform.indexOf("Linux") === 0; 1295 function userAgentContains(str) { 1296 return navigator.userAgent.toLowerCase().indexOf(str) >= 0; 1297 } 1298 var Browser = { 1299 ie, 1300 ielt9, 1301 edge, 1302 webkit, 1303 android, 1304 android23, 1305 androidStock, 1306 opera, 1307 chrome, 1308 gecko, 1309 safari, 1310 phantom, 1311 opera12, 1312 win, 1313 ie3d, 1314 webkit3d, 1315 gecko3d, 1316 any3d, 1317 mobile, 1318 mobileWebkit, 1319 mobileWebkit3d, 1320 msPointer, 1321 pointer, 1322 touch, 1323 touchNative, 1324 mobileOpera, 1325 mobileGecko, 1326 retina, 1327 passiveEvents, 1328 canvas: canvas$1, 1329 svg: svg$1, 1330 vml, 1331 inlineSvg, 1332 mac, 1333 linux 1334 }; 1335 var POINTER_DOWN = Browser.msPointer ? "MSPointerDown" : "pointerdown"; 1336 var POINTER_MOVE = Browser.msPointer ? "MSPointerMove" : "pointermove"; 1337 var POINTER_UP = Browser.msPointer ? "MSPointerUp" : "pointerup"; 1338 var POINTER_CANCEL = Browser.msPointer ? "MSPointerCancel" : "pointercancel"; 1339 var pEvent = { 1340 touchstart: POINTER_DOWN, 1341 touchmove: POINTER_MOVE, 1342 touchend: POINTER_UP, 1343 touchcancel: POINTER_CANCEL 1344 }; 1345 var handle = { 1346 touchstart: _onPointerStart, 1347 touchmove: _handlePointer, 1348 touchend: _handlePointer, 1349 touchcancel: _handlePointer 1350 }; 1351 var _pointers = {}; 1352 var _pointerDocListener = false; 1353 function addPointerListener(obj, type, handler) { 1354 if (type === "touchstart") { 1355 _addPointerDocListener(); 1356 } 1357 if (!handle[type]) { 1358 console.warn("wrong event specified:", type); 1359 return falseFn; 1360 } 1361 handler = handle[type].bind(this, handler); 1362 obj.addEventListener(pEvent[type], handler, false); 1363 return handler; 1364 } 1365 function removePointerListener(obj, type, handler) { 1366 if (!pEvent[type]) { 1367 console.warn("wrong event specified:", type); 1368 return; 1369 } 1370 obj.removeEventListener(pEvent[type], handler, false); 1371 } 1372 function _globalPointerDown(e) { 1373 _pointers[e.pointerId] = e; 1374 } 1375 function _globalPointerMove(e) { 1376 if (_pointers[e.pointerId]) { 1377 _pointers[e.pointerId] = e; 1378 } 1379 } 1380 function _globalPointerUp(e) { 1381 delete _pointers[e.pointerId]; 1382 } 1383 function _addPointerDocListener() { 1384 if (!_pointerDocListener) { 1385 document.addEventListener(POINTER_DOWN, _globalPointerDown, true); 1386 document.addEventListener(POINTER_MOVE, _globalPointerMove, true); 1387 document.addEventListener(POINTER_UP, _globalPointerUp, true); 1388 document.addEventListener(POINTER_CANCEL, _globalPointerUp, true); 1389 _pointerDocListener = true; 1390 } 1391 } 1392 function _handlePointer(handler, e) { 1393 if (e.pointerType === (e.MSPOINTER_TYPE_MOUSE || "mouse")) { 1394 return; 1395 } 1396 e.touches = []; 1397 for (var i in _pointers) { 1398 e.touches.push(_pointers[i]); 1399 } 1400 e.changedTouches = [e]; 1401 handler(e); 1402 } 1403 function _onPointerStart(handler, e) { 1404 if (e.MSPOINTER_TYPE_TOUCH && e.pointerType === e.MSPOINTER_TYPE_TOUCH) { 1405 preventDefault(e); 1406 } 1407 _handlePointer(handler, e); 1408 } 1409 function makeDblclick(event) { 1410 var newEvent = {}, prop, i; 1411 for (i in event) { 1412 prop = event[i]; 1413 newEvent[i] = prop && prop.bind ? prop.bind(event) : prop; 1414 } 1415 event = newEvent; 1416 newEvent.type = "dblclick"; 1417 newEvent.detail = 2; 1418 newEvent.isTrusted = false; 1419 newEvent._simulated = true; 1420 return newEvent; 1421 } 1422 var delay = 200; 1423 function addDoubleTapListener(obj, handler) { 1424 obj.addEventListener("dblclick", handler); 1425 var last = 0, detail; 1426 function simDblclick(e) { 1427 if (e.detail !== 1) { 1428 detail = e.detail; 1429 return; 1430 } 1431 if (e.pointerType === "mouse" || e.sourceCapabilities && !e.sourceCapabilities.firesTouchEvents) { 1432 return; 1433 } 1434 var path = getPropagationPath(e); 1435 if (path.some(function(el) { 1436 return el instanceof HTMLLabelElement && el.attributes.for; 1437 }) && !path.some(function(el) { 1438 return el instanceof HTMLInputElement || el instanceof HTMLSelectElement; 1439 })) { 1440 return; 1441 } 1442 var now = Date.now(); 1443 if (now - last <= delay) { 1444 detail++; 1445 if (detail === 2) { 1446 handler(makeDblclick(e)); 1447 } 1448 } else { 1449 detail = 1; 1450 } 1451 last = now; 1452 } 1453 obj.addEventListener("click", simDblclick); 1454 return { 1455 dblclick: handler, 1456 simDblclick 1457 }; 1458 } 1459 function removeDoubleTapListener(obj, handlers) { 1460 obj.removeEventListener("dblclick", handlers.dblclick); 1461 obj.removeEventListener("click", handlers.simDblclick); 1462 } 1463 var TRANSFORM = testProp( 1464 ["transform", "webkitTransform", "OTransform", "MozTransform", "msTransform"] 1465 ); 1466 var TRANSITION = testProp( 1467 ["webkitTransition", "transition", "OTransition", "MozTransition", "msTransition"] 1468 ); 1469 var TRANSITION_END2 = TRANSITION === "webkitTransition" || TRANSITION === "OTransition" ? TRANSITION + "End" : "transitionend"; 1470 function get(id) { 1471 return typeof id === "string" ? document.getElementById(id) : id; 1472 } 1473 function getStyle(el, style2) { 1474 var value = el.style[style2] || el.currentStyle && el.currentStyle[style2]; 1475 if ((!value || value === "auto") && document.defaultView) { 1476 var css = document.defaultView.getComputedStyle(el, null); 1477 value = css ? css[style2] : null; 1478 } 1479 return value === "auto" ? null : value; 1480 } 1481 function create$1(tagName, className, container) { 1482 var el = document.createElement(tagName); 1483 el.className = className || ""; 1484 if (container) { 1485 container.appendChild(el); 1486 } 1487 return el; 1488 } 1489 function remove(el) { 1490 var parent = el.parentNode; 1491 if (parent) { 1492 parent.removeChild(el); 1493 } 1494 } 1495 function empty(el) { 1496 while (el.firstChild) { 1497 el.removeChild(el.firstChild); 1498 } 1499 } 1500 function toFront(el) { 1501 var parent = el.parentNode; 1502 if (parent && parent.lastChild !== el) { 1503 parent.appendChild(el); 1504 } 1505 } 1506 function toBack(el) { 1507 var parent = el.parentNode; 1508 if (parent && parent.firstChild !== el) { 1509 parent.insertBefore(el, parent.firstChild); 1510 } 1511 } 1512 function hasClass(el, name) { 1513 if (el.classList !== void 0) { 1514 return el.classList.contains(name); 1515 } 1516 var className = getClass(el); 1517 return className.length > 0 && new RegExp("(^|\\s)" + name + "(\\s|$)").test(className); 1518 } 1519 function addClass(el, name) { 1520 if (el.classList !== void 0) { 1521 var classes = splitWords(name); 1522 for (var i = 0, len = classes.length; i < len; i++) { 1523 el.classList.add(classes[i]); 1524 } 1525 } else if (!hasClass(el, name)) { 1526 var className = getClass(el); 1527 setClass(el, (className ? className + " " : "") + name); 1528 } 1529 } 1530 function removeClass(el, name) { 1531 if (el.classList !== void 0) { 1532 el.classList.remove(name); 1533 } else { 1534 setClass(el, trim((" " + getClass(el) + " ").replace(" " + name + " ", " "))); 1535 } 1536 } 1537 function setClass(el, name) { 1538 if (el.className.baseVal === void 0) { 1539 el.className = name; 1540 } else { 1541 el.className.baseVal = name; 1542 } 1543 } 1544 function getClass(el) { 1545 if (el.correspondingElement) { 1546 el = el.correspondingElement; 1547 } 1548 return el.className.baseVal === void 0 ? el.className : el.className.baseVal; 1549 } 1550 function setOpacity(el, value) { 1551 if ("opacity" in el.style) { 1552 el.style.opacity = value; 1553 } else if ("filter" in el.style) { 1554 _setOpacityIE(el, value); 1555 } 1556 } 1557 function _setOpacityIE(el, value) { 1558 var filter = false, filterName = "DXImageTransform.Microsoft.Alpha"; 1559 try { 1560 filter = el.filters.item(filterName); 1561 } catch (e) { 1562 if (value === 1) { 1563 return; 1564 } 1565 } 1566 value = Math.round(value * 100); 1567 if (filter) { 1568 filter.Enabled = value !== 100; 1569 filter.Opacity = value; 1570 } else { 1571 el.style.filter += " progid:" + filterName + "(opacity=" + value + ")"; 1572 } 1573 } 1574 function testProp(props) { 1575 var style2 = document.documentElement.style; 1576 for (var i = 0; i < props.length; i++) { 1577 if (props[i] in style2) { 1578 return props[i]; 1579 } 1580 } 1581 return false; 1582 } 1583 function setTransform(el, offset2, scale2) { 1584 var pos = offset2 || new Point(0, 0); 1585 el.style[TRANSFORM] = (Browser.ie3d ? "translate(" + pos.x + "px," + pos.y + "px)" : "translate3d(" + pos.x + "px," + pos.y + "px,0)") + (scale2 ? " scale(" + scale2 + ")" : ""); 1586 } 1587 function setPosition(el, point) { 1588 el._leaflet_pos = point; 1589 if (Browser.any3d) { 1590 setTransform(el, point); 1591 } else { 1592 el.style.left = point.x + "px"; 1593 el.style.top = point.y + "px"; 1594 } 1595 } 1596 function getPosition(el) { 1597 return el._leaflet_pos || new Point(0, 0); 1598 } 1599 var disableTextSelection; 1600 var enableTextSelection; 1601 var _userSelect; 1602 if ("onselectstart" in document) { 1603 disableTextSelection = function() { 1604 on(window, "selectstart", preventDefault); 1605 }; 1606 enableTextSelection = function() { 1607 off(window, "selectstart", preventDefault); 1608 }; 1609 } else { 1610 var userSelectProperty = testProp( 1611 ["userSelect", "WebkitUserSelect", "OUserSelect", "MozUserSelect", "msUserSelect"] 1612 ); 1613 disableTextSelection = function() { 1614 if (userSelectProperty) { 1615 var style2 = document.documentElement.style; 1616 _userSelect = style2[userSelectProperty]; 1617 style2[userSelectProperty] = "none"; 1618 } 1619 }; 1620 enableTextSelection = function() { 1621 if (userSelectProperty) { 1622 document.documentElement.style[userSelectProperty] = _userSelect; 1623 _userSelect = void 0; 1624 } 1625 }; 1626 } 1627 function disableImageDrag() { 1628 on(window, "dragstart", preventDefault); 1629 } 1630 function enableImageDrag() { 1631 off(window, "dragstart", preventDefault); 1632 } 1633 var _outlineElement, _outlineStyle; 1634 function preventOutline(element) { 1635 while (element.tabIndex === -1) { 1636 element = element.parentNode; 1637 } 1638 if (!element.style) { 1639 return; 1640 } 1641 restoreOutline(); 1642 _outlineElement = element; 1643 _outlineStyle = element.style.outlineStyle; 1644 element.style.outlineStyle = "none"; 1645 on(window, "keydown", restoreOutline); 1646 } 1647 function restoreOutline() { 1648 if (!_outlineElement) { 1649 return; 1650 } 1651 _outlineElement.style.outlineStyle = _outlineStyle; 1652 _outlineElement = void 0; 1653 _outlineStyle = void 0; 1654 off(window, "keydown", restoreOutline); 1655 } 1656 function getSizedParentNode(element) { 1657 do { 1658 element = element.parentNode; 1659 } while ((!element.offsetWidth || !element.offsetHeight) && element !== document.body); 1660 return element; 1661 } 1662 function getScale(element) { 1663 var rect = element.getBoundingClientRect(); 1664 return { 1665 x: rect.width / element.offsetWidth || 1, 1666 y: rect.height / element.offsetHeight || 1, 1667 boundingClientRect: rect 1668 }; 1669 } 1670 var DomUtil = { 1671 __proto__: null, 1672 TRANSFORM, 1673 TRANSITION, 1674 TRANSITION_END: TRANSITION_END2, 1675 get, 1676 getStyle, 1677 create: create$1, 1678 remove, 1679 empty, 1680 toFront, 1681 toBack, 1682 hasClass, 1683 addClass, 1684 removeClass, 1685 setClass, 1686 getClass, 1687 setOpacity, 1688 testProp, 1689 setTransform, 1690 setPosition, 1691 getPosition, 1692 get disableTextSelection() { 1693 return disableTextSelection; 1694 }, 1695 get enableTextSelection() { 1696 return enableTextSelection; 1697 }, 1698 disableImageDrag, 1699 enableImageDrag, 1700 preventOutline, 1701 restoreOutline, 1702 getSizedParentNode, 1703 getScale 1704 }; 1705 function on(obj, types, fn2, context) { 1706 if (types && typeof types === "object") { 1707 for (var type in types) { 1708 addOne(obj, type, types[type], fn2); 1709 } 1710 } else { 1711 types = splitWords(types); 1712 for (var i = 0, len = types.length; i < len; i++) { 1713 addOne(obj, types[i], fn2, context); 1714 } 1715 } 1716 return this; 1717 } 1718 var eventsKey = "_leaflet_events"; 1719 function off(obj, types, fn2, context) { 1720 if (arguments.length === 1) { 1721 batchRemove(obj); 1722 delete obj[eventsKey]; 1723 } else if (types && typeof types === "object") { 1724 for (var type in types) { 1725 removeOne(obj, type, types[type], fn2); 1726 } 1727 } else { 1728 types = splitWords(types); 1729 if (arguments.length === 2) { 1730 batchRemove(obj, function(type2) { 1731 return indexOf(types, type2) !== -1; 1732 }); 1733 } else { 1734 for (var i = 0, len = types.length; i < len; i++) { 1735 removeOne(obj, types[i], fn2, context); 1736 } 1737 } 1738 } 1739 return this; 1740 } 1741 function batchRemove(obj, filterFn) { 1742 for (var id in obj[eventsKey]) { 1743 var type = id.split(/\d/)[0]; 1744 if (!filterFn || filterFn(type)) { 1745 removeOne(obj, type, null, null, id); 1746 } 1747 } 1748 } 1749 var mouseSubst = { 1750 mouseenter: "mouseover", 1751 mouseleave: "mouseout", 1752 wheel: !("onwheel" in window) && "mousewheel" 1753 }; 1754 function addOne(obj, type, fn2, context) { 1755 var id = type + stamp(fn2) + (context ? "_" + stamp(context) : ""); 1756 if (obj[eventsKey] && obj[eventsKey][id]) { 1757 return this; 1758 } 1759 var handler = function(e) { 1760 return fn2.call(context || obj, e || window.event); 1761 }; 1762 var originalHandler = handler; 1763 if (!Browser.touchNative && Browser.pointer && type.indexOf("touch") === 0) { 1764 handler = addPointerListener(obj, type, handler); 1765 } else if (Browser.touch && type === "dblclick") { 1766 handler = addDoubleTapListener(obj, handler); 1767 } else if ("addEventListener" in obj) { 1768 if (type === "touchstart" || type === "touchmove" || type === "wheel" || type === "mousewheel") { 1769 obj.addEventListener(mouseSubst[type] || type, handler, Browser.passiveEvents ? { passive: false } : false); 1770 } else if (type === "mouseenter" || type === "mouseleave") { 1771 handler = function(e) { 1772 e = e || window.event; 1773 if (isExternalTarget(obj, e)) { 1774 originalHandler(e); 1775 } 1776 }; 1777 obj.addEventListener(mouseSubst[type], handler, false); 1778 } else { 1779 obj.addEventListener(type, originalHandler, false); 1780 } 1781 } else { 1782 obj.attachEvent("on" + type, handler); 1783 } 1784 obj[eventsKey] = obj[eventsKey] || {}; 1785 obj[eventsKey][id] = handler; 1786 } 1787 function removeOne(obj, type, fn2, context, id) { 1788 id = id || type + stamp(fn2) + (context ? "_" + stamp(context) : ""); 1789 var handler = obj[eventsKey] && obj[eventsKey][id]; 1790 if (!handler) { 1791 return this; 1792 } 1793 if (!Browser.touchNative && Browser.pointer && type.indexOf("touch") === 0) { 1794 removePointerListener(obj, type, handler); 1795 } else if (Browser.touch && type === "dblclick") { 1796 removeDoubleTapListener(obj, handler); 1797 } else if ("removeEventListener" in obj) { 1798 obj.removeEventListener(mouseSubst[type] || type, handler, false); 1799 } else { 1800 obj.detachEvent("on" + type, handler); 1801 } 1802 obj[eventsKey][id] = null; 1803 } 1804 function stopPropagation(e) { 1805 if (e.stopPropagation) { 1806 e.stopPropagation(); 1807 } else if (e.originalEvent) { 1808 e.originalEvent._stopped = true; 1809 } else { 1810 e.cancelBubble = true; 1811 } 1812 return this; 1813 } 1814 function disableScrollPropagation(el) { 1815 addOne(el, "wheel", stopPropagation); 1816 return this; 1817 } 1818 function disableClickPropagation(el) { 1819 on(el, "mousedown touchstart dblclick contextmenu", stopPropagation); 1820 el["_leaflet_disable_click"] = true; 1821 return this; 1822 } 1823 function preventDefault(e) { 1824 if (e.preventDefault) { 1825 e.preventDefault(); 1826 } else { 1827 e.returnValue = false; 1828 } 1829 return this; 1830 } 1831 function stop(e) { 1832 preventDefault(e); 1833 stopPropagation(e); 1834 return this; 1835 } 1836 function getPropagationPath(ev) { 1837 if (ev.composedPath) { 1838 return ev.composedPath(); 1839 } 1840 var path = []; 1841 var el = ev.target; 1842 while (el) { 1843 path.push(el); 1844 el = el.parentNode; 1845 } 1846 return path; 1847 } 1848 function getMousePosition(e, container) { 1849 if (!container) { 1850 return new Point(e.clientX, e.clientY); 1851 } 1852 var scale2 = getScale(container), offset2 = scale2.boundingClientRect; 1853 return new Point( 1854 // offset.left/top values are in page scale (like clientX/Y), 1855 // whereas clientLeft/Top (border width) values are the original values (before CSS scale applies). 1856 (e.clientX - offset2.left) / scale2.x - container.clientLeft, 1857 (e.clientY - offset2.top) / scale2.y - container.clientTop 1858 ); 1859 } 1860 var wheelPxFactor = Browser.linux && Browser.chrome ? window.devicePixelRatio : Browser.mac ? window.devicePixelRatio * 3 : window.devicePixelRatio > 0 ? 2 * window.devicePixelRatio : 1; 1861 function getWheelDelta(e) { 1862 return Browser.edge ? e.wheelDeltaY / 2 : ( 1863 // Don't trust window-geometry-based delta 1864 e.deltaY && e.deltaMode === 0 ? -e.deltaY / wheelPxFactor : ( 1865 // Pixels 1866 e.deltaY && e.deltaMode === 1 ? -e.deltaY * 20 : ( 1867 // Lines 1868 e.deltaY && e.deltaMode === 2 ? -e.deltaY * 60 : ( 1869 // Pages 1870 e.deltaX || e.deltaZ ? 0 : ( 1871 // Skip horizontal/depth wheel events 1872 e.wheelDelta ? (e.wheelDeltaY || e.wheelDelta) / 2 : ( 1873 // Legacy IE pixels 1874 e.detail && Math.abs(e.detail) < 32765 ? -e.detail * 20 : ( 1875 // Legacy Moz lines 1876 e.detail ? e.detail / -32765 * 60 : ( 1877 // Legacy Moz pages 1878 0 1879 ) 1880 ) 1881 ) 1882 ) 1883 ) 1884 ) 1885 ) 1886 ); 1887 } 1888 function isExternalTarget(el, e) { 1889 var related = e.relatedTarget; 1890 if (!related) { 1891 return true; 1892 } 1893 try { 1894 while (related && related !== el) { 1895 related = related.parentNode; 1896 } 1897 } catch (err) { 1898 return false; 1899 } 1900 return related !== el; 1901 } 1902 var DomEvent = { 1903 __proto__: null, 1904 on, 1905 off, 1906 stopPropagation, 1907 disableScrollPropagation, 1908 disableClickPropagation, 1909 preventDefault, 1910 stop, 1911 getPropagationPath, 1912 getMousePosition, 1913 getWheelDelta, 1914 isExternalTarget, 1915 addListener: on, 1916 removeListener: off 1917 }; 1918 var PosAnimation = Evented.extend({ 1919 // @method run(el: HTMLElement, newPos: Point, duration?: Number, easeLinearity?: Number) 1920 // Run an animation of a given element to a new position, optionally setting 1921 // duration in seconds (`0.25` by default) and easing linearity factor (3rd 1922 // argument of the [cubic bezier curve](https://cubic-bezier.com/#0,0,.5,1), 1923 // `0.5` by default). 1924 run: function(el, newPos, duration, easeLinearity) { 1925 this.stop(); 1926 this._el = el; 1927 this._inProgress = true; 1928 this._duration = duration || 0.25; 1929 this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2); 1930 this._startPos = getPosition(el); 1931 this._offset = newPos.subtract(this._startPos); 1932 this._startTime = +/* @__PURE__ */ new Date(); 1933 this.fire("start"); 1934 this._animate(); 1935 }, 1936 // @method stop() 1937 // Stops the animation (if currently running). 1938 stop: function() { 1939 if (!this._inProgress) { 1940 return; 1941 } 1942 this._step(true); 1943 this._complete(); 1944 }, 1945 _animate: function() { 1946 this._animId = requestAnimFrame(this._animate, this); 1947 this._step(); 1948 }, 1949 _step: function(round2) { 1950 var elapsed = +/* @__PURE__ */ new Date() - this._startTime, duration = this._duration * 1e3; 1951 if (elapsed < duration) { 1952 this._runFrame(this._easeOut(elapsed / duration), round2); 1953 } else { 1954 this._runFrame(1); 1955 this._complete(); 1956 } 1957 }, 1958 _runFrame: function(progress, round2) { 1959 var pos = this._startPos.add(this._offset.multiplyBy(progress)); 1960 if (round2) { 1961 pos._round(); 1962 } 1963 setPosition(this._el, pos); 1964 this.fire("step"); 1965 }, 1966 _complete: function() { 1967 cancelAnimFrame(this._animId); 1968 this._inProgress = false; 1969 this.fire("end"); 1970 }, 1971 _easeOut: function(t) { 1972 return 1 - Math.pow(1 - t, this._easeOutPower); 1973 } 1974 }); 1975 var Map2 = Evented.extend({ 1976 options: { 1977 // @section Map State Options 1978 // @option crs: CRS = L.CRS.EPSG3857 1979 // The [Coordinate Reference System](#crs) to use. Don't change this if you're not 1980 // sure what it means. 1981 crs: EPSG3857, 1982 // @option center: LatLng = undefined 1983 // Initial geographic center of the map 1984 center: void 0, 1985 // @option zoom: Number = undefined 1986 // Initial map zoom level 1987 zoom: void 0, 1988 // @option minZoom: Number = * 1989 // Minimum zoom level of the map. 1990 // If not specified and at least one `GridLayer` or `TileLayer` is in the map, 1991 // the lowest of their `minZoom` options will be used instead. 1992 minZoom: void 0, 1993 // @option maxZoom: Number = * 1994 // Maximum zoom level of the map. 1995 // If not specified and at least one `GridLayer` or `TileLayer` is in the map, 1996 // the highest of their `maxZoom` options will be used instead. 1997 maxZoom: void 0, 1998 // @option layers: Layer[] = [] 1999 // Array of layers that will be added to the map initially 2000 layers: [], 2001 // @option maxBounds: LatLngBounds = null 2002 // When this option is set, the map restricts the view to the given 2003 // geographical bounds, bouncing the user back if the user tries to pan 2004 // outside the view. To set the restriction dynamically, use 2005 // [`setMaxBounds`](#map-setmaxbounds) method. 2006 maxBounds: void 0, 2007 // @option renderer: Renderer = * 2008 // The default method for drawing vector layers on the map. `L.SVG` 2009 // or `L.Canvas` by default depending on browser support. 2010 renderer: void 0, 2011 // @section Animation Options 2012 // @option zoomAnimation: Boolean = true 2013 // Whether the map zoom animation is enabled. By default it's enabled 2014 // in all browsers that support CSS3 Transitions except Android. 2015 zoomAnimation: true, 2016 // @option zoomAnimationThreshold: Number = 4 2017 // Won't animate zoom if the zoom difference exceeds this value. 2018 zoomAnimationThreshold: 4, 2019 // @option fadeAnimation: Boolean = true 2020 // Whether the tile fade animation is enabled. By default it's enabled 2021 // in all browsers that support CSS3 Transitions except Android. 2022 fadeAnimation: true, 2023 // @option markerZoomAnimation: Boolean = true 2024 // Whether markers animate their zoom with the zoom animation, if disabled 2025 // they will disappear for the length of the animation. By default it's 2026 // enabled in all browsers that support CSS3 Transitions except Android. 2027 markerZoomAnimation: true, 2028 // @option transform3DLimit: Number = 2^23 2029 // Defines the maximum size of a CSS translation transform. The default 2030 // value should not be changed unless a web browser positions layers in 2031 // the wrong place after doing a large `panBy`. 2032 transform3DLimit: 8388608, 2033 // Precision limit of a 32-bit float 2034 // @section Interaction Options 2035 // @option zoomSnap: Number = 1 2036 // Forces the map's zoom level to always be a multiple of this, particularly 2037 // right after a [`fitBounds()`](#map-fitbounds) or a pinch-zoom. 2038 // By default, the zoom level snaps to the nearest integer; lower values 2039 // (e.g. `0.5` or `0.1`) allow for greater granularity. A value of `0` 2040 // means the zoom level will not be snapped after `fitBounds` or a pinch-zoom. 2041 zoomSnap: 1, 2042 // @option zoomDelta: Number = 1 2043 // Controls how much the map's zoom level will change after a 2044 // [`zoomIn()`](#map-zoomin), [`zoomOut()`](#map-zoomout), pressing `+` 2045 // or `-` on the keyboard, or using the [zoom controls](#control-zoom). 2046 // Values smaller than `1` (e.g. `0.5`) allow for greater granularity. 2047 zoomDelta: 1, 2048 // @option trackResize: Boolean = true 2049 // Whether the map automatically handles browser window resize to update itself. 2050 trackResize: true 2051 }, 2052 initialize: function(id, options) { 2053 options = setOptions(this, options); 2054 this._handlers = []; 2055 this._layers = {}; 2056 this._zoomBoundLayers = {}; 2057 this._sizeChanged = true; 2058 this._initContainer(id); 2059 this._initLayout(); 2060 this._onResize = bind(this._onResize, this); 2061 this._initEvents(); 2062 if (options.maxBounds) { 2063 this.setMaxBounds(options.maxBounds); 2064 } 2065 if (options.zoom !== void 0) { 2066 this._zoom = this._limitZoom(options.zoom); 2067 } 2068 if (options.center && options.zoom !== void 0) { 2069 this.setView(toLatLng(options.center), options.zoom, { reset: true }); 2070 } 2071 this.callInitHooks(); 2072 this._zoomAnimated = TRANSITION && Browser.any3d && !Browser.mobileOpera && this.options.zoomAnimation; 2073 if (this._zoomAnimated) { 2074 this._createAnimProxy(); 2075 on(this._proxy, TRANSITION_END2, this._catchTransitionEnd, this); 2076 } 2077 this._addLayers(this.options.layers); 2078 }, 2079 // @section Methods for modifying map state 2080 // @method setView(center: LatLng, zoom: Number, options?: Zoom/pan options): this 2081 // Sets the view of the map (geographical center and zoom) with the given 2082 // animation options. 2083 setView: function(center, zoom2, options) { 2084 zoom2 = zoom2 === void 0 ? this._zoom : this._limitZoom(zoom2); 2085 center = this._limitCenter(toLatLng(center), zoom2, this.options.maxBounds); 2086 options = options || {}; 2087 this._stop(); 2088 if (this._loaded && !options.reset && options !== true) { 2089 if (options.animate !== void 0) { 2090 options.zoom = extend({ animate: options.animate }, options.zoom); 2091 options.pan = extend({ animate: options.animate, duration: options.duration }, options.pan); 2092 } 2093 var moved = this._zoom !== zoom2 ? this._tryAnimatedZoom && this._tryAnimatedZoom(center, zoom2, options.zoom) : this._tryAnimatedPan(center, options.pan); 2094 if (moved) { 2095 clearTimeout(this._sizeTimer); 2096 return this; 2097 } 2098 } 2099 this._resetView(center, zoom2, options.pan && options.pan.noMoveStart); 2100 return this; 2101 }, 2102 // @method setZoom(zoom: Number, options?: Zoom/pan options): this 2103 // Sets the zoom of the map. 2104 setZoom: function(zoom2, options) { 2105 if (!this._loaded) { 2106 this._zoom = zoom2; 2107 return this; 2108 } 2109 return this.setView(this.getCenter(), zoom2, { zoom: options }); 2110 }, 2111 // @method zoomIn(delta?: Number, options?: Zoom options): this 2112 // Increases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default). 2113 zoomIn: function(delta, options) { 2114 delta = delta || (Browser.any3d ? this.options.zoomDelta : 1); 2115 return this.setZoom(this._zoom + delta, options); 2116 }, 2117 // @method zoomOut(delta?: Number, options?: Zoom options): this 2118 // Decreases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default). 2119 zoomOut: function(delta, options) { 2120 delta = delta || (Browser.any3d ? this.options.zoomDelta : 1); 2121 return this.setZoom(this._zoom - delta, options); 2122 }, 2123 // @method setZoomAround(latlng: LatLng, zoom: Number, options: Zoom options): this 2124 // Zooms the map while keeping a specified geographical point on the map 2125 // stationary (e.g. used internally for scroll zoom and double-click zoom). 2126 // @alternative 2127 // @method setZoomAround(offset: Point, zoom: Number, options: Zoom options): this 2128 // Zooms the map while keeping a specified pixel on the map (relative to the top-left corner) stationary. 2129 setZoomAround: function(latlng, zoom2, options) { 2130 var scale2 = this.getZoomScale(zoom2), viewHalf = this.getSize().divideBy(2), containerPoint = latlng instanceof Point ? latlng : this.latLngToContainerPoint(latlng), centerOffset = containerPoint.subtract(viewHalf).multiplyBy(1 - 1 / scale2), newCenter = this.containerPointToLatLng(viewHalf.add(centerOffset)); 2131 return this.setView(newCenter, zoom2, { zoom: options }); 2132 }, 2133 _getBoundsCenterZoom: function(bounds, options) { 2134 options = options || {}; 2135 bounds = bounds.getBounds ? bounds.getBounds() : toLatLngBounds(bounds); 2136 var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]), paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]), zoom2 = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR)); 2137 zoom2 = typeof options.maxZoom === "number" ? Math.min(options.maxZoom, zoom2) : zoom2; 2138 if (zoom2 === Infinity) { 2139 return { 2140 center: bounds.getCenter(), 2141 zoom: zoom2 2142 }; 2143 } 2144 var paddingOffset = paddingBR.subtract(paddingTL).divideBy(2), swPoint = this.project(bounds.getSouthWest(), zoom2), nePoint = this.project(bounds.getNorthEast(), zoom2), center = this.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom2); 2145 return { 2146 center, 2147 zoom: zoom2 2148 }; 2149 }, 2150 // @method fitBounds(bounds: LatLngBounds, options?: fitBounds options): this 2151 // Sets a map view that contains the given geographical bounds with the 2152 // maximum zoom level possible. 2153 fitBounds: function(bounds, options) { 2154 bounds = toLatLngBounds(bounds); 2155 if (!bounds.isValid()) { 2156 throw new Error("Bounds are not valid."); 2157 } 2158 var target = this._getBoundsCenterZoom(bounds, options); 2159 return this.setView(target.center, target.zoom, options); 2160 }, 2161 // @method fitWorld(options?: fitBounds options): this 2162 // Sets a map view that mostly contains the whole world with the maximum 2163 // zoom level possible. 2164 fitWorld: function(options) { 2165 return this.fitBounds([[-90, -180], [90, 180]], options); 2166 }, 2167 // @method panTo(latlng: LatLng, options?: Pan options): this 2168 // Pans the map to a given center. 2169 panTo: function(center, options) { 2170 return this.setView(center, this._zoom, { pan: options }); 2171 }, 2172 // @method panBy(offset: Point, options?: Pan options): this 2173 // Pans the map by a given number of pixels (animated). 2174 panBy: function(offset2, options) { 2175 offset2 = toPoint(offset2).round(); 2176 options = options || {}; 2177 if (!offset2.x && !offset2.y) { 2178 return this.fire("moveend"); 2179 } 2180 if (options.animate !== true && !this.getSize().contains(offset2)) { 2181 this._resetView(this.unproject(this.project(this.getCenter()).add(offset2)), this.getZoom()); 2182 return this; 2183 } 2184 if (!this._panAnim) { 2185 this._panAnim = new PosAnimation(); 2186 this._panAnim.on({ 2187 "step": this._onPanTransitionStep, 2188 "end": this._onPanTransitionEnd 2189 }, this); 2190 } 2191 if (!options.noMoveStart) { 2192 this.fire("movestart"); 2193 } 2194 if (options.animate !== false) { 2195 addClass(this._mapPane, "leaflet-pan-anim"); 2196 var newPos = this._getMapPanePos().subtract(offset2).round(); 2197 this._panAnim.run(this._mapPane, newPos, options.duration || 0.25, options.easeLinearity); 2198 } else { 2199 this._rawPanBy(offset2); 2200 this.fire("move").fire("moveend"); 2201 } 2202 return this; 2203 }, 2204 // @method flyTo(latlng: LatLng, zoom?: Number, options?: Zoom/pan options): this 2205 // Sets the view of the map (geographical center and zoom) performing a smooth 2206 // pan-zoom animation. 2207 flyTo: function(targetCenter, targetZoom, options) { 2208 options = options || {}; 2209 if (options.animate === false || !Browser.any3d) { 2210 return this.setView(targetCenter, targetZoom, options); 2211 } 2212 this._stop(); 2213 var from = this.project(this.getCenter()), to = this.project(targetCenter), size = this.getSize(), startZoom = this._zoom; 2214 targetCenter = toLatLng(targetCenter); 2215 targetZoom = targetZoom === void 0 ? startZoom : targetZoom; 2216 var w0 = Math.max(size.x, size.y), w1 = w0 * this.getZoomScale(startZoom, targetZoom), u1 = to.distanceTo(from) || 1, rho = 1.42, rho2 = rho * rho; 2217 function r(i) { 2218 var s1 = i ? -1 : 1, s2 = i ? w1 : w0, t1 = w1 * w1 - w0 * w0 + s1 * rho2 * rho2 * u1 * u1, b1 = 2 * s2 * rho2 * u1, b = t1 / b1, sq = Math.sqrt(b * b + 1) - b; 2219 var log = sq < 1e-9 ? -18 : Math.log(sq); 2220 return log; 2221 } 2222 function sinh(n) { 2223 return (Math.exp(n) - Math.exp(-n)) / 2; 2224 } 2225 function cosh(n) { 2226 return (Math.exp(n) + Math.exp(-n)) / 2; 2227 } 2228 function tanh(n) { 2229 return sinh(n) / cosh(n); 2230 } 2231 var r0 = r(0); 2232 function w(s) { 2233 return w0 * (cosh(r0) / cosh(r0 + rho * s)); 2234 } 2235 function u(s) { 2236 return w0 * (cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2; 2237 } 2238 function easeOut(t) { 2239 return 1 - Math.pow(1 - t, 1.5); 2240 } 2241 var start2 = Date.now(), S = (r(1) - r0) / rho, duration = options.duration ? 1e3 * options.duration : 1e3 * S * 0.8; 2242 function frame() { 2243 var t = (Date.now() - start2) / duration, s = easeOut(t) * S; 2244 if (t <= 1) { 2245 this._flyToFrame = requestAnimFrame(frame, this); 2246 this._move( 2247 this.unproject(from.add(to.subtract(from).multiplyBy(u(s) / u1)), startZoom), 2248 this.getScaleZoom(w0 / w(s), startZoom), 2249 { flyTo: true } 2250 ); 2251 } else { 2252 this._move(targetCenter, targetZoom)._moveEnd(true); 2253 } 2254 } 2255 this._moveStart(true, options.noMoveStart); 2256 frame.call(this); 2257 return this; 2258 }, 2259 // @method flyToBounds(bounds: LatLngBounds, options?: fitBounds options): this 2260 // Sets the view of the map with a smooth animation like [`flyTo`](#map-flyto), 2261 // but takes a bounds parameter like [`fitBounds`](#map-fitbounds). 2262 flyToBounds: function(bounds, options) { 2263 var target = this._getBoundsCenterZoom(bounds, options); 2264 return this.flyTo(target.center, target.zoom, options); 2265 }, 2266 // @method setMaxBounds(bounds: LatLngBounds): this 2267 // Restricts the map view to the given bounds (see the [maxBounds](#map-maxbounds) option). 2268 setMaxBounds: function(bounds) { 2269 bounds = toLatLngBounds(bounds); 2270 if (this.listens("moveend", this._panInsideMaxBounds)) { 2271 this.off("moveend", this._panInsideMaxBounds); 2272 } 2273 if (!bounds.isValid()) { 2274 this.options.maxBounds = null; 2275 return this; 2276 } 2277 this.options.maxBounds = bounds; 2278 if (this._loaded) { 2279 this._panInsideMaxBounds(); 2280 } 2281 return this.on("moveend", this._panInsideMaxBounds); 2282 }, 2283 // @method setMinZoom(zoom: Number): this 2284 // Sets the lower limit for the available zoom levels (see the [minZoom](#map-minzoom) option). 2285 setMinZoom: function(zoom2) { 2286 var oldZoom = this.options.minZoom; 2287 this.options.minZoom = zoom2; 2288 if (this._loaded && oldZoom !== zoom2) { 2289 this.fire("zoomlevelschange"); 2290 if (this.getZoom() < this.options.minZoom) { 2291 return this.setZoom(zoom2); 2292 } 2293 } 2294 return this; 2295 }, 2296 // @method setMaxZoom(zoom: Number): this 2297 // Sets the upper limit for the available zoom levels (see the [maxZoom](#map-maxzoom) option). 2298 setMaxZoom: function(zoom2) { 2299 var oldZoom = this.options.maxZoom; 2300 this.options.maxZoom = zoom2; 2301 if (this._loaded && oldZoom !== zoom2) { 2302 this.fire("zoomlevelschange"); 2303 if (this.getZoom() > this.options.maxZoom) { 2304 return this.setZoom(zoom2); 2305 } 2306 } 2307 return this; 2308 }, 2309 // @method panInsideBounds(bounds: LatLngBounds, options?: Pan options): this 2310 // 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. 2311 panInsideBounds: function(bounds, options) { 2312 this._enforcingBounds = true; 2313 var center = this.getCenter(), newCenter = this._limitCenter(center, this._zoom, toLatLngBounds(bounds)); 2314 if (!center.equals(newCenter)) { 2315 this.panTo(newCenter, options); 2316 } 2317 this._enforcingBounds = false; 2318 return this; 2319 }, 2320 // @method panInside(latlng: LatLng, options?: padding options): this 2321 // Pans the map the minimum amount to make the `latlng` visible. Use 2322 // padding options to fit the display to more restricted bounds. 2323 // If `latlng` is already within the (optionally padded) display bounds, 2324 // the map will not be panned. 2325 panInside: function(latlng, options) { 2326 options = options || {}; 2327 var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]), paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]), pixelCenter = this.project(this.getCenter()), pixelPoint = this.project(latlng), pixelBounds = this.getPixelBounds(), paddedBounds = toBounds([pixelBounds.min.add(paddingTL), pixelBounds.max.subtract(paddingBR)]), paddedSize = paddedBounds.getSize(); 2328 if (!paddedBounds.contains(pixelPoint)) { 2329 this._enforcingBounds = true; 2330 var centerOffset = pixelPoint.subtract(paddedBounds.getCenter()); 2331 var offset2 = paddedBounds.extend(pixelPoint).getSize().subtract(paddedSize); 2332 pixelCenter.x += centerOffset.x < 0 ? -offset2.x : offset2.x; 2333 pixelCenter.y += centerOffset.y < 0 ? -offset2.y : offset2.y; 2334 this.panTo(this.unproject(pixelCenter), options); 2335 this._enforcingBounds = false; 2336 } 2337 return this; 2338 }, 2339 // @method invalidateSize(options: Zoom/pan options): this 2340 // Checks if the map container size changed and updates the map if so â 2341 // call it after you've changed the map size dynamically, also animating 2342 // pan by default. If `options.pan` is `false`, panning will not occur. 2343 // If `options.debounceMoveend` is `true`, it will delay `moveend` event so 2344 // that it doesn't happen often even if the method is called many 2345 // times in a row. 2346 // @alternative 2347 // @method invalidateSize(animate: Boolean): this 2348 // Checks if the map container size changed and updates the map if so â 2349 // call it after you've changed the map size dynamically, also animating 2350 // pan by default. 2351 invalidateSize: function(options) { 2352 if (!this._loaded) { 2353 return this; 2354 } 2355 options = extend({ 2356 animate: false, 2357 pan: true 2358 }, options === true ? { animate: true } : options); 2359 var oldSize = this.getSize(); 2360 this._sizeChanged = true; 2361 this._lastCenter = null; 2362 var newSize = this.getSize(), oldCenter = oldSize.divideBy(2).round(), newCenter = newSize.divideBy(2).round(), offset2 = oldCenter.subtract(newCenter); 2363 if (!offset2.x && !offset2.y) { 2364 return this; 2365 } 2366 if (options.animate && options.pan) { 2367 this.panBy(offset2); 2368 } else { 2369 if (options.pan) { 2370 this._rawPanBy(offset2); 2371 } 2372 this.fire("move"); 2373 if (options.debounceMoveend) { 2374 clearTimeout(this._sizeTimer); 2375 this._sizeTimer = setTimeout(bind(this.fire, this, "moveend"), 200); 2376 } else { 2377 this.fire("moveend"); 2378 } 2379 } 2380 return this.fire("resize", { 2381 oldSize, 2382 newSize 2383 }); 2384 }, 2385 // @section Methods for modifying map state 2386 // @method stop(): this 2387 // Stops the currently running `panTo` or `flyTo` animation, if any. 2388 stop: function() { 2389 this.setZoom(this._limitZoom(this._zoom)); 2390 if (!this.options.zoomSnap) { 2391 this.fire("viewreset"); 2392 } 2393 return this._stop(); 2394 }, 2395 // @section Geolocation methods 2396 // @method locate(options?: Locate options): this 2397 // Tries to locate the user using the Geolocation API, firing a [`locationfound`](#map-locationfound) 2398 // event with location data on success or a [`locationerror`](#map-locationerror) event on failure, 2399 // and optionally sets the map view to the user's location with respect to 2400 // detection accuracy (or to the world view if geolocation failed). 2401 // Note that, if your page doesn't use HTTPS, this method will fail in 2402 // modern browsers ([Chrome 50 and newer](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins)) 2403 // See `Locate options` for more details. 2404 locate: function(options) { 2405 options = this._locateOptions = extend({ 2406 timeout: 1e4, 2407 watch: false 2408 // setView: false 2409 // maxZoom: <Number> 2410 // maximumAge: 0 2411 // enableHighAccuracy: false 2412 }, options); 2413 if (!("geolocation" in navigator)) { 2414 this._handleGeolocationError({ 2415 code: 0, 2416 message: "Geolocation not supported." 2417 }); 2418 return this; 2419 } 2420 var onResponse = bind(this._handleGeolocationResponse, this), onError = bind(this._handleGeolocationError, this); 2421 if (options.watch) { 2422 this._locationWatchId = navigator.geolocation.watchPosition(onResponse, onError, options); 2423 } else { 2424 navigator.geolocation.getCurrentPosition(onResponse, onError, options); 2425 } 2426 return this; 2427 }, 2428 // @method stopLocate(): this 2429 // Stops watching location previously initiated by `map.locate({watch: true})` 2430 // and aborts resetting the map view if map.locate was called with 2431 // `{setView: true}`. 2432 stopLocate: function() { 2433 if (navigator.geolocation && navigator.geolocation.clearWatch) { 2434 navigator.geolocation.clearWatch(this._locationWatchId); 2435 } 2436 if (this._locateOptions) { 2437 this._locateOptions.setView = false; 2438 } 2439 return this; 2440 }, 2441 _handleGeolocationError: function(error) { 2442 if (!this._container._leaflet_id) { 2443 return; 2444 } 2445 var c = error.code, message = error.message || (c === 1 ? "permission denied" : c === 2 ? "position unavailable" : "timeout"); 2446 if (this._locateOptions.setView && !this._loaded) { 2447 this.fitWorld(); 2448 } 2449 this.fire("locationerror", { 2450 code: c, 2451 message: "Geolocation error: " + message + "." 2452 }); 2453 }, 2454 _handleGeolocationResponse: function(pos) { 2455 if (!this._container._leaflet_id) { 2456 return; 2457 } 2458 var lat = pos.coords.latitude, lng = pos.coords.longitude, latlng = new LatLng(lat, lng), bounds = latlng.toBounds(pos.coords.accuracy * 2), options = this._locateOptions; 2459 if (options.setView) { 2460 var zoom2 = this.getBoundsZoom(bounds); 2461 this.setView(latlng, options.maxZoom ? Math.min(zoom2, options.maxZoom) : zoom2); 2462 } 2463 var data = { 2464 latlng, 2465 bounds, 2466 timestamp: pos.timestamp 2467 }; 2468 for (var i in pos.coords) { 2469 if (typeof pos.coords[i] === "number") { 2470 data[i] = pos.coords[i]; 2471 } 2472 } 2473 this.fire("locationfound", data); 2474 }, 2475 // TODO Appropriate docs section? 2476 // @section Other Methods 2477 // @method addHandler(name: String, HandlerClass: Function): this 2478 // Adds a new `Handler` to the map, given its name and constructor function. 2479 addHandler: function(name, HandlerClass) { 2480 if (!HandlerClass) { 2481 return this; 2482 } 2483 var handler = this[name] = new HandlerClass(this); 2484 this._handlers.push(handler); 2485 if (this.options[name]) { 2486 handler.enable(); 2487 } 2488 return this; 2489 }, 2490 // @method remove(): this 2491 // Destroys the map and clears all related event listeners. 2492 remove: function() { 2493 this._initEvents(true); 2494 if (this.options.maxBounds) { 2495 this.off("moveend", this._panInsideMaxBounds); 2496 } 2497 if (this._containerId !== this._container._leaflet_id) { 2498 throw new Error("Map container is being reused by another instance"); 2499 } 2500 try { 2501 delete this._container._leaflet_id; 2502 delete this._containerId; 2503 } catch (e) { 2504 this._container._leaflet_id = void 0; 2505 this._containerId = void 0; 2506 } 2507 if (this._locationWatchId !== void 0) { 2508 this.stopLocate(); 2509 } 2510 this._stop(); 2511 remove(this._mapPane); 2512 if (this._clearControlPos) { 2513 this._clearControlPos(); 2514 } 2515 if (this._resizeRequest) { 2516 cancelAnimFrame(this._resizeRequest); 2517 this._resizeRequest = null; 2518 } 2519 this._clearHandlers(); 2520 if (this._loaded) { 2521 this.fire("unload"); 2522 } 2523 var i; 2524 for (i in this._layers) { 2525 this._layers[i].remove(); 2526 } 2527 for (i in this._panes) { 2528 remove(this._panes[i]); 2529 } 2530 this._layers = []; 2531 this._panes = []; 2532 delete this._mapPane; 2533 delete this._renderer; 2534 return this; 2535 }, 2536 // @section Other Methods 2537 // @method createPane(name: String, container?: HTMLElement): HTMLElement 2538 // Creates a new [map pane](#map-pane) with the given name if it doesn't exist already, 2539 // then returns it. The pane is created as a child of `container`, or 2540 // as a child of the main map pane if not set. 2541 createPane: function(name, container) { 2542 var className = "leaflet-pane" + (name ? " leaflet-" + name.replace("Pane", "") + "-pane" : ""), pane = create$1("div", className, container || this._mapPane); 2543 if (name) { 2544 this._panes[name] = pane; 2545 } 2546 return pane; 2547 }, 2548 // @section Methods for Getting Map State 2549 // @method getCenter(): LatLng 2550 // Returns the geographical center of the map view 2551 getCenter: function() { 2552 this._checkIfLoaded(); 2553 if (this._lastCenter && !this._moved()) { 2554 return this._lastCenter.clone(); 2555 } 2556 return this.layerPointToLatLng(this._getCenterLayerPoint()); 2557 }, 2558 // @method getZoom(): Number 2559 // Returns the current zoom level of the map view 2560 getZoom: function() { 2561 return this._zoom; 2562 }, 2563 // @method getBounds(): LatLngBounds 2564 // Returns the geographical bounds visible in the current map view 2565 getBounds: function() { 2566 var bounds = this.getPixelBounds(), sw = this.unproject(bounds.getBottomLeft()), ne = this.unproject(bounds.getTopRight()); 2567 return new LatLngBounds(sw, ne); 2568 }, 2569 // @method getMinZoom(): Number 2570 // 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. 2571 getMinZoom: function() { 2572 return this.options.minZoom === void 0 ? this._layersMinZoom || 0 : this.options.minZoom; 2573 }, 2574 // @method getMaxZoom(): Number 2575 // Returns the maximum zoom level of the map (if set in the `maxZoom` option of the map or of any layers). 2576 getMaxZoom: function() { 2577 return this.options.maxZoom === void 0 ? this._layersMaxZoom === void 0 ? Infinity : this._layersMaxZoom : this.options.maxZoom; 2578 }, 2579 // @method getBoundsZoom(bounds: LatLngBounds, inside?: Boolean, padding?: Point): Number 2580 // Returns the maximum zoom level on which the given bounds fit to the map 2581 // view in its entirety. If `inside` (optional) is set to `true`, the method 2582 // instead returns the minimum zoom level on which the map view fits into 2583 // the given bounds in its entirety. 2584 getBoundsZoom: function(bounds, inside, padding) { 2585 bounds = toLatLngBounds(bounds); 2586 padding = toPoint(padding || [0, 0]); 2587 var zoom2 = this.getZoom() || 0, min2 = this.getMinZoom(), max2 = this.getMaxZoom(), nw = bounds.getNorthWest(), se = bounds.getSouthEast(), size = this.getSize().subtract(padding), boundsSize = toBounds(this.project(se, zoom2), this.project(nw, zoom2)).getSize(), snap = Browser.any3d ? this.options.zoomSnap : 1, scalex = size.x / boundsSize.x, scaley = size.y / boundsSize.y, scale2 = inside ? Math.max(scalex, scaley) : Math.min(scalex, scaley); 2588 zoom2 = this.getScaleZoom(scale2, zoom2); 2589 if (snap) { 2590 zoom2 = Math.round(zoom2 / (snap / 100)) * (snap / 100); 2591 zoom2 = inside ? Math.ceil(zoom2 / snap) * snap : Math.floor(zoom2 / snap) * snap; 2592 } 2593 return Math.max(min2, Math.min(max2, zoom2)); 2594 }, 2595 // @method getSize(): Point 2596 // Returns the current size of the map container (in pixels). 2597 getSize: function() { 2598 if (!this._size || this._sizeChanged) { 2599 this._size = new Point( 2600 this._container.clientWidth || 0, 2601 this._container.clientHeight || 0 2602 ); 2603 this._sizeChanged = false; 2604 } 2605 return this._size.clone(); 2606 }, 2607 // @method getPixelBounds(): Bounds 2608 // Returns the bounds of the current map view in projected pixel 2609 // coordinates (sometimes useful in layer and overlay implementations). 2610 getPixelBounds: function(center, zoom2) { 2611 var topLeftPoint = this._getTopLeftPoint(center, zoom2); 2612 return new Bounds(topLeftPoint, topLeftPoint.add(this.getSize())); 2613 }, 2614 // TODO: Check semantics - isn't the pixel origin the 0,0 coord relative to 2615 // the map pane? "left point of the map layer" can be confusing, specially 2616 // since there can be negative offsets. 2617 // @method getPixelOrigin(): Point 2618 // Returns the projected pixel coordinates of the top left point of 2619 // the map layer (useful in custom layer and overlay implementations). 2620 getPixelOrigin: function() { 2621 this._checkIfLoaded(); 2622 return this._pixelOrigin; 2623 }, 2624 // @method getPixelWorldBounds(zoom?: Number): Bounds 2625 // Returns the world's bounds in pixel coordinates for zoom level `zoom`. 2626 // If `zoom` is omitted, the map's current zoom level is used. 2627 getPixelWorldBounds: function(zoom2) { 2628 return this.options.crs.getProjectedBounds(zoom2 === void 0 ? this.getZoom() : zoom2); 2629 }, 2630 // @section Other Methods 2631 // @method getPane(pane: String|HTMLElement): HTMLElement 2632 // Returns a [map pane](#map-pane), given its name or its HTML element (its identity). 2633 getPane: function(pane) { 2634 return typeof pane === "string" ? this._panes[pane] : pane; 2635 }, 2636 // @method getPanes(): Object 2637 // Returns a plain object containing the names of all [panes](#map-pane) as keys and 2638 // the panes as values. 2639 getPanes: function() { 2640 return this._panes; 2641 }, 2642 // @method getContainer: HTMLElement 2643 // Returns the HTML element that contains the map. 2644 getContainer: function() { 2645 return this._container; 2646 }, 2647 // @section Conversion Methods 2648 // @method getZoomScale(toZoom: Number, fromZoom: Number): Number 2649 // Returns the scale factor to be applied to a map transition from zoom level 2650 // `fromZoom` to `toZoom`. Used internally to help with zoom animations. 2651 getZoomScale: function(toZoom, fromZoom) { 2652 var crs = this.options.crs; 2653 fromZoom = fromZoom === void 0 ? this._zoom : fromZoom; 2654 return crs.scale(toZoom) / crs.scale(fromZoom); 2655 }, 2656 // @method getScaleZoom(scale: Number, fromZoom: Number): Number 2657 // Returns the zoom level that the map would end up at, if it is at `fromZoom` 2658 // level and everything is scaled by a factor of `scale`. Inverse of 2659 // [`getZoomScale`](#map-getZoomScale). 2660 getScaleZoom: function(scale2, fromZoom) { 2661 var crs = this.options.crs; 2662 fromZoom = fromZoom === void 0 ? this._zoom : fromZoom; 2663 var zoom2 = crs.zoom(scale2 * crs.scale(fromZoom)); 2664 return isNaN(zoom2) ? Infinity : zoom2; 2665 }, 2666 // @method project(latlng: LatLng, zoom: Number): Point 2667 // Projects a geographical coordinate `LatLng` according to the projection 2668 // of the map's CRS, then scales it according to `zoom` and the CRS's 2669 // `Transformation`. The result is pixel coordinate relative to 2670 // the CRS origin. 2671 project: function(latlng, zoom2) { 2672 zoom2 = zoom2 === void 0 ? this._zoom : zoom2; 2673 return this.options.crs.latLngToPoint(toLatLng(latlng), zoom2); 2674 }, 2675 // @method unproject(point: Point, zoom: Number): LatLng 2676 // Inverse of [`project`](#map-project). 2677 unproject: function(point, zoom2) { 2678 zoom2 = zoom2 === void 0 ? this._zoom : zoom2; 2679 return this.options.crs.pointToLatLng(toPoint(point), zoom2); 2680 }, 2681 // @method layerPointToLatLng(point: Point): LatLng 2682 // Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin), 2683 // returns the corresponding geographical coordinate (for the current zoom level). 2684 layerPointToLatLng: function(point) { 2685 var projectedPoint = toPoint(point).add(this.getPixelOrigin()); 2686 return this.unproject(projectedPoint); 2687 }, 2688 // @method latLngToLayerPoint(latlng: LatLng): Point 2689 // Given a geographical coordinate, returns the corresponding pixel coordinate 2690 // relative to the [origin pixel](#map-getpixelorigin). 2691 latLngToLayerPoint: function(latlng) { 2692 var projectedPoint = this.project(toLatLng(latlng))._round(); 2693 return projectedPoint._subtract(this.getPixelOrigin()); 2694 }, 2695 // @method wrapLatLng(latlng: LatLng): LatLng 2696 // Returns a `LatLng` where `lat` and `lng` has been wrapped according to the 2697 // map's CRS's `wrapLat` and `wrapLng` properties, if they are outside the 2698 // CRS's bounds. 2699 // By default this means longitude is wrapped around the dateline so its 2700 // value is between -180 and +180 degrees. 2701 wrapLatLng: function(latlng) { 2702 return this.options.crs.wrapLatLng(toLatLng(latlng)); 2703 }, 2704 // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds 2705 // Returns a `LatLngBounds` with the same size as the given one, ensuring that 2706 // its center is within the CRS's bounds. 2707 // By default this means the center longitude is wrapped around the dateline so its 2708 // value is between -180 and +180 degrees, and the majority of the bounds 2709 // overlaps the CRS's bounds. 2710 wrapLatLngBounds: function(latlng) { 2711 return this.options.crs.wrapLatLngBounds(toLatLngBounds(latlng)); 2712 }, 2713 // @method distance(latlng1: LatLng, latlng2: LatLng): Number 2714 // Returns the distance between two geographical coordinates according to 2715 // the map's CRS. By default this measures distance in meters. 2716 distance: function(latlng1, latlng2) { 2717 return this.options.crs.distance(toLatLng(latlng1), toLatLng(latlng2)); 2718 }, 2719 // @method containerPointToLayerPoint(point: Point): Point 2720 // Given a pixel coordinate relative to the map container, returns the corresponding 2721 // pixel coordinate relative to the [origin pixel](#map-getpixelorigin). 2722 containerPointToLayerPoint: function(point) { 2723 return toPoint(point).subtract(this._getMapPanePos()); 2724 }, 2725 // @method layerPointToContainerPoint(point: Point): Point 2726 // Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin), 2727 // returns the corresponding pixel coordinate relative to the map container. 2728 layerPointToContainerPoint: function(point) { 2729 return toPoint(point).add(this._getMapPanePos()); 2730 }, 2731 // @method containerPointToLatLng(point: Point): LatLng 2732 // Given a pixel coordinate relative to the map container, returns 2733 // the corresponding geographical coordinate (for the current zoom level). 2734 containerPointToLatLng: function(point) { 2735 var layerPoint = this.containerPointToLayerPoint(toPoint(point)); 2736 return this.layerPointToLatLng(layerPoint); 2737 }, 2738 // @method latLngToContainerPoint(latlng: LatLng): Point 2739 // Given a geographical coordinate, returns the corresponding pixel coordinate 2740 // relative to the map container. 2741 latLngToContainerPoint: function(latlng) { 2742 return this.layerPointToContainerPoint(this.latLngToLayerPoint(toLatLng(latlng))); 2743 }, 2744 // @method mouseEventToContainerPoint(ev: MouseEvent): Point 2745 // Given a MouseEvent object, returns the pixel coordinate relative to the 2746 // map container where the event took place. 2747 mouseEventToContainerPoint: function(e) { 2748 return getMousePosition(e, this._container); 2749 }, 2750 // @method mouseEventToLayerPoint(ev: MouseEvent): Point 2751 // Given a MouseEvent object, returns the pixel coordinate relative to 2752 // the [origin pixel](#map-getpixelorigin) where the event took place. 2753 mouseEventToLayerPoint: function(e) { 2754 return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(e)); 2755 }, 2756 // @method mouseEventToLatLng(ev: MouseEvent): LatLng 2757 // Given a MouseEvent object, returns geographical coordinate where the 2758 // event took place. 2759 mouseEventToLatLng: function(e) { 2760 return this.layerPointToLatLng(this.mouseEventToLayerPoint(e)); 2761 }, 2762 // map initialization methods 2763 _initContainer: function(id) { 2764 var container = this._container = get(id); 2765 if (!container) { 2766 throw new Error("Map container not found."); 2767 } else if (container._leaflet_id) { 2768 throw new Error("Map container is already initialized."); 2769 } 2770 on(container, "scroll", this._onScroll, this); 2771 this._containerId = stamp(container); 2772 }, 2773 _initLayout: function() { 2774 var container = this._container; 2775 this._fadeAnimated = this.options.fadeAnimation && Browser.any3d; 2776 addClass(container, "leaflet-container" + (Browser.touch ? " leaflet-touch" : "") + (Browser.retina ? " leaflet-retina" : "") + (Browser.ielt9 ? " leaflet-oldie" : "") + (Browser.safari ? " leaflet-safari" : "") + (this._fadeAnimated ? " leaflet-fade-anim" : "")); 2777 var position = getStyle(container, "position"); 2778 if (position !== "absolute" && position !== "relative" && position !== "fixed" && position !== "sticky") { 2779 container.style.position = "relative"; 2780 } 2781 this._initPanes(); 2782 if (this._initControlPos) { 2783 this._initControlPos(); 2784 } 2785 }, 2786 _initPanes: function() { 2787 var panes = this._panes = {}; 2788 this._paneRenderers = {}; 2789 this._mapPane = this.createPane("mapPane", this._container); 2790 setPosition(this._mapPane, new Point(0, 0)); 2791 this.createPane("tilePane"); 2792 this.createPane("overlayPane"); 2793 this.createPane("shadowPane"); 2794 this.createPane("markerPane"); 2795 this.createPane("tooltipPane"); 2796 this.createPane("popupPane"); 2797 if (!this.options.markerZoomAnimation) { 2798 addClass(panes.markerPane, "leaflet-zoom-hide"); 2799 addClass(panes.shadowPane, "leaflet-zoom-hide"); 2800 } 2801 }, 2802 // private methods that modify map state 2803 // @section Map state change events 2804 _resetView: function(center, zoom2, noMoveStart) { 2805 setPosition(this._mapPane, new Point(0, 0)); 2806 var loading = !this._loaded; 2807 this._loaded = true; 2808 zoom2 = this._limitZoom(zoom2); 2809 this.fire("viewprereset"); 2810 var zoomChanged = this._zoom !== zoom2; 2811 this._moveStart(zoomChanged, noMoveStart)._move(center, zoom2)._moveEnd(zoomChanged); 2812 this.fire("viewreset"); 2813 if (loading) { 2814 this.fire("load"); 2815 } 2816 }, 2817 _moveStart: function(zoomChanged, noMoveStart) { 2818 if (zoomChanged) { 2819 this.fire("zoomstart"); 2820 } 2821 if (!noMoveStart) { 2822 this.fire("movestart"); 2823 } 2824 return this; 2825 }, 2826 _move: function(center, zoom2, data, supressEvent) { 2827 if (zoom2 === void 0) { 2828 zoom2 = this._zoom; 2829 } 2830 var zoomChanged = this._zoom !== zoom2; 2831 this._zoom = zoom2; 2832 this._lastCenter = center; 2833 this._pixelOrigin = this._getNewPixelOrigin(center); 2834 if (!supressEvent) { 2835 if (zoomChanged || data && data.pinch) { 2836 this.fire("zoom", data); 2837 } 2838 this.fire("move", data); 2839 } else if (data && data.pinch) { 2840 this.fire("zoom", data); 2841 } 2842 return this; 2843 }, 2844 _moveEnd: function(zoomChanged) { 2845 if (zoomChanged) { 2846 this.fire("zoomend"); 2847 } 2848 return this.fire("moveend"); 2849 }, 2850 _stop: function() { 2851 cancelAnimFrame(this._flyToFrame); 2852 if (this._panAnim) { 2853 this._panAnim.stop(); 2854 } 2855 return this; 2856 }, 2857 _rawPanBy: function(offset2) { 2858 setPosition(this._mapPane, this._getMapPanePos().subtract(offset2)); 2859 }, 2860 _getZoomSpan: function() { 2861 return this.getMaxZoom() - this.getMinZoom(); 2862 }, 2863 _panInsideMaxBounds: function() { 2864 if (!this._enforcingBounds) { 2865 this.panInsideBounds(this.options.maxBounds); 2866 } 2867 }, 2868 _checkIfLoaded: function() { 2869 if (!this._loaded) { 2870 throw new Error("Set map center and zoom first."); 2871 } 2872 }, 2873 // DOM event handling 2874 // @section Interaction events 2875 _initEvents: function(remove2) { 2876 this._targets = {}; 2877 this._targets[stamp(this._container)] = this; 2878 var onOff = remove2 ? off : on; 2879 onOff(this._container, "click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress keydown keyup", this._handleDOMEvent, this); 2880 if (this.options.trackResize) { 2881 onOff(window, "resize", this._onResize, this); 2882 } 2883 if (Browser.any3d && this.options.transform3DLimit) { 2884 (remove2 ? this.off : this.on).call(this, "moveend", this._onMoveEnd); 2885 } 2886 }, 2887 _onResize: function() { 2888 cancelAnimFrame(this._resizeRequest); 2889 this._resizeRequest = requestAnimFrame( 2890 function() { 2891 this.invalidateSize({ debounceMoveend: true }); 2892 }, 2893 this 2894 ); 2895 }, 2896 _onScroll: function() { 2897 this._container.scrollTop = 0; 2898 this._container.scrollLeft = 0; 2899 }, 2900 _onMoveEnd: function() { 2901 var pos = this._getMapPanePos(); 2902 if (Math.max(Math.abs(pos.x), Math.abs(pos.y)) >= this.options.transform3DLimit) { 2903 this._resetView(this.getCenter(), this.getZoom()); 2904 } 2905 }, 2906 _findEventTargets: function(e, type) { 2907 var targets = [], target, isHover = type === "mouseout" || type === "mouseover", src = e.target || e.srcElement, dragging = false; 2908 while (src) { 2909 target = this._targets[stamp(src)]; 2910 if (target && (type === "click" || type === "preclick") && this._draggableMoved(target)) { 2911 dragging = true; 2912 break; 2913 } 2914 if (target && target.listens(type, true)) { 2915 if (isHover && !isExternalTarget(src, e)) { 2916 break; 2917 } 2918 targets.push(target); 2919 if (isHover) { 2920 break; 2921 } 2922 } 2923 if (src === this._container) { 2924 break; 2925 } 2926 src = src.parentNode; 2927 } 2928 if (!targets.length && !dragging && !isHover && this.listens(type, true)) { 2929 targets = [this]; 2930 } 2931 return targets; 2932 }, 2933 _isClickDisabled: function(el) { 2934 while (el && el !== this._container) { 2935 if (el["_leaflet_disable_click"]) { 2936 return true; 2937 } 2938 el = el.parentNode; 2939 } 2940 }, 2941 _handleDOMEvent: function(e) { 2942 var el = e.target || e.srcElement; 2943 if (!this._loaded || el["_leaflet_disable_events"] || e.type === "click" && this._isClickDisabled(el)) { 2944 return; 2945 } 2946 var type = e.type; 2947 if (type === "mousedown") { 2948 preventOutline(el); 2949 } 2950 this._fireDOMEvent(e, type); 2951 }, 2952 _mouseEvents: ["click", "dblclick", "mouseover", "mouseout", "contextmenu"], 2953 _fireDOMEvent: function(e, type, canvasTargets) { 2954 if (e.type === "click") { 2955 var synth = extend({}, e); 2956 synth.type = "preclick"; 2957 this._fireDOMEvent(synth, synth.type, canvasTargets); 2958 } 2959 var targets = this._findEventTargets(e, type); 2960 if (canvasTargets) { 2961 var filtered = []; 2962 for (var i = 0; i < canvasTargets.length; i++) { 2963 if (canvasTargets[i].listens(type, true)) { 2964 filtered.push(canvasTargets[i]); 2965 } 2966 } 2967 targets = filtered.concat(targets); 2968 } 2969 if (!targets.length) { 2970 return; 2971 } 2972 if (type === "contextmenu") { 2973 preventDefault(e); 2974 } 2975 var target = targets[0]; 2976 var data = { 2977 originalEvent: e 2978 }; 2979 if (e.type !== "keypress" && e.type !== "keydown" && e.type !== "keyup") { 2980 var isMarker = target.getLatLng && (!target._radius || target._radius <= 10); 2981 data.containerPoint = isMarker ? this.latLngToContainerPoint(target.getLatLng()) : this.mouseEventToContainerPoint(e); 2982 data.layerPoint = this.containerPointToLayerPoint(data.containerPoint); 2983 data.latlng = isMarker ? target.getLatLng() : this.layerPointToLatLng(data.layerPoint); 2984 } 2985 for (i = 0; i < targets.length; i++) { 2986 targets[i].fire(type, data, true); 2987 if (data.originalEvent._stopped || targets[i].options.bubblingMouseEvents === false && indexOf(this._mouseEvents, type) !== -1) { 2988 return; 2989 } 2990 } 2991 }, 2992 _draggableMoved: function(obj) { 2993 obj = obj.dragging && obj.dragging.enabled() ? obj : this; 2994 return obj.dragging && obj.dragging.moved() || this.boxZoom && this.boxZoom.moved(); 2995 }, 2996 _clearHandlers: function() { 2997 for (var i = 0, len = this._handlers.length; i < len; i++) { 2998 this._handlers[i].disable(); 2999 } 3000 }, 3001 // @section Other Methods 3002 // @method whenReady(fn: Function, context?: Object): this 3003 // Runs the given function `fn` when the map gets initialized with 3004 // a view (center and zoom) and at least one layer, or immediately 3005 // if it's already initialized, optionally passing a function context. 3006 whenReady: function(callback, context) { 3007 if (this._loaded) { 3008 callback.call(context || this, { target: this }); 3009 } else { 3010 this.on("load", callback, context); 3011 } 3012 return this; 3013 }, 3014 // private methods for getting map state 3015 _getMapPanePos: function() { 3016 return getPosition(this._mapPane) || new Point(0, 0); 3017 }, 3018 _moved: function() { 3019 var pos = this._getMapPanePos(); 3020 return pos && !pos.equals([0, 0]); 3021 }, 3022 _getTopLeftPoint: function(center, zoom2) { 3023 var pixelOrigin = center && zoom2 !== void 0 ? this._getNewPixelOrigin(center, zoom2) : this.getPixelOrigin(); 3024 return pixelOrigin.subtract(this._getMapPanePos()); 3025 }, 3026 _getNewPixelOrigin: function(center, zoom2) { 3027 var viewHalf = this.getSize()._divideBy(2); 3028 return this.project(center, zoom2)._subtract(viewHalf)._add(this._getMapPanePos())._round(); 3029 }, 3030 _latLngToNewLayerPoint: function(latlng, zoom2, center) { 3031 var topLeft = this._getNewPixelOrigin(center, zoom2); 3032 return this.project(latlng, zoom2)._subtract(topLeft); 3033 }, 3034 _latLngBoundsToNewLayerBounds: function(latLngBounds, zoom2, center) { 3035 var topLeft = this._getNewPixelOrigin(center, zoom2); 3036 return toBounds([ 3037 this.project(latLngBounds.getSouthWest(), zoom2)._subtract(topLeft), 3038 this.project(latLngBounds.getNorthWest(), zoom2)._subtract(topLeft), 3039 this.project(latLngBounds.getSouthEast(), zoom2)._subtract(topLeft), 3040 this.project(latLngBounds.getNorthEast(), zoom2)._subtract(topLeft) 3041 ]); 3042 }, 3043 // layer point of the current center 3044 _getCenterLayerPoint: function() { 3045 return this.containerPointToLayerPoint(this.getSize()._divideBy(2)); 3046 }, 3047 // offset of the specified place to the current center in pixels 3048 _getCenterOffset: function(latlng) { 3049 return this.latLngToLayerPoint(latlng).subtract(this._getCenterLayerPoint()); 3050 }, 3051 // adjust center for view to get inside bounds 3052 _limitCenter: function(center, zoom2, bounds) { 3053 if (!bounds) { 3054 return center; 3055 } 3056 var centerPoint = this.project(center, zoom2), viewHalf = this.getSize().divideBy(2), viewBounds = new Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)), offset2 = this._getBoundsOffset(viewBounds, bounds, zoom2); 3057 if (Math.abs(offset2.x) <= 1 && Math.abs(offset2.y) <= 1) { 3058 return center; 3059 } 3060 return this.unproject(centerPoint.add(offset2), zoom2); 3061 }, 3062 // adjust offset for view to get inside bounds 3063 _limitOffset: function(offset2, bounds) { 3064 if (!bounds) { 3065 return offset2; 3066 } 3067 var viewBounds = this.getPixelBounds(), newBounds = new Bounds(viewBounds.min.add(offset2), viewBounds.max.add(offset2)); 3068 return offset2.add(this._getBoundsOffset(newBounds, bounds)); 3069 }, 3070 // returns offset needed for pxBounds to get inside maxBounds at a specified zoom 3071 _getBoundsOffset: function(pxBounds, maxBounds, zoom2) { 3072 var projectedMaxBounds = toBounds( 3073 this.project(maxBounds.getNorthEast(), zoom2), 3074 this.project(maxBounds.getSouthWest(), zoom2) 3075 ), minOffset = projectedMaxBounds.min.subtract(pxBounds.min), maxOffset = projectedMaxBounds.max.subtract(pxBounds.max), dx = this._rebound(minOffset.x, -maxOffset.x), dy = this._rebound(minOffset.y, -maxOffset.y); 3076 return new Point(dx, dy); 3077 }, 3078 _rebound: function(left2, right2) { 3079 return left2 + right2 > 0 ? Math.round(left2 - right2) / 2 : Math.max(0, Math.ceil(left2)) - Math.max(0, Math.floor(right2)); 3080 }, 3081 _limitZoom: function(zoom2) { 3082 var min2 = this.getMinZoom(), max2 = this.getMaxZoom(), snap = Browser.any3d ? this.options.zoomSnap : 1; 3083 if (snap) { 3084 zoom2 = Math.round(zoom2 / snap) * snap; 3085 } 3086 return Math.max(min2, Math.min(max2, zoom2)); 3087 }, 3088 _onPanTransitionStep: function() { 3089 this.fire("move"); 3090 }, 3091 _onPanTransitionEnd: function() { 3092 removeClass(this._mapPane, "leaflet-pan-anim"); 3093 this.fire("moveend"); 3094 }, 3095 _tryAnimatedPan: function(center, options) { 3096 var offset2 = this._getCenterOffset(center)._trunc(); 3097 if ((options && options.animate) !== true && !this.getSize().contains(offset2)) { 3098 return false; 3099 } 3100 this.panBy(offset2, options); 3101 return true; 3102 }, 3103 _createAnimProxy: function() { 3104 var proxy = this._proxy = create$1("div", "leaflet-proxy leaflet-zoom-animated"); 3105 this._panes.mapPane.appendChild(proxy); 3106 this.on("zoomanim", function(e) { 3107 var prop = TRANSFORM, transform = this._proxy.style[prop]; 3108 setTransform(this._proxy, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1)); 3109 if (transform === this._proxy.style[prop] && this._animatingZoom) { 3110 this._onZoomTransitionEnd(); 3111 } 3112 }, this); 3113 this.on("load moveend", this._animMoveEnd, this); 3114 this._on("unload", this._destroyAnimProxy, this); 3115 }, 3116 _destroyAnimProxy: function() { 3117 remove(this._proxy); 3118 this.off("load moveend", this._animMoveEnd, this); 3119 delete this._proxy; 3120 }, 3121 _animMoveEnd: function() { 3122 var c = this.getCenter(), z = this.getZoom(); 3123 setTransform(this._proxy, this.project(c, z), this.getZoomScale(z, 1)); 3124 }, 3125 _catchTransitionEnd: function(e) { 3126 if (this._animatingZoom && e.propertyName.indexOf("transform") >= 0) { 3127 this._onZoomTransitionEnd(); 3128 } 3129 }, 3130 _nothingToAnimate: function() { 3131 return !this._container.getElementsByClassName("leaflet-zoom-animated").length; 3132 }, 3133 _tryAnimatedZoom: function(center, zoom2, options) { 3134 if (this._animatingZoom) { 3135 return true; 3136 } 3137 options = options || {}; 3138 if (!this._zoomAnimated || options.animate === false || this._nothingToAnimate() || Math.abs(zoom2 - this._zoom) > this.options.zoomAnimationThreshold) { 3139 return false; 3140 } 3141 var scale2 = this.getZoomScale(zoom2), offset2 = this._getCenterOffset(center)._divideBy(1 - 1 / scale2); 3142 if (options.animate !== true && !this.getSize().contains(offset2)) { 3143 return false; 3144 } 3145 requestAnimFrame(function() { 3146 this._moveStart(true, options.noMoveStart || false)._animateZoom(center, zoom2, true); 3147 }, this); 3148 return true; 3149 }, 3150 _animateZoom: function(center, zoom2, startAnim, noUpdate) { 3151 if (!this._mapPane) { 3152 return; 3153 } 3154 if (startAnim) { 3155 this._animatingZoom = true; 3156 this._animateToCenter = center; 3157 this._animateToZoom = zoom2; 3158 addClass(this._mapPane, "leaflet-zoom-anim"); 3159 } 3160 this.fire("zoomanim", { 3161 center, 3162 zoom: zoom2, 3163 noUpdate 3164 }); 3165 if (!this._tempFireZoomEvent) { 3166 this._tempFireZoomEvent = this._zoom !== this._animateToZoom; 3167 } 3168 this._move(this._animateToCenter, this._animateToZoom, void 0, true); 3169 setTimeout(bind(this._onZoomTransitionEnd, this), 250); 3170 }, 3171 _onZoomTransitionEnd: function() { 3172 if (!this._animatingZoom) { 3173 return; 3174 } 3175 if (this._mapPane) { 3176 removeClass(this._mapPane, "leaflet-zoom-anim"); 3177 } 3178 this._animatingZoom = false; 3179 this._move(this._animateToCenter, this._animateToZoom, void 0, true); 3180 if (this._tempFireZoomEvent) { 3181 this.fire("zoom"); 3182 } 3183 delete this._tempFireZoomEvent; 3184 this.fire("move"); 3185 this._moveEnd(true); 3186 } 3187 }); 3188 function createMap(id, options) { 3189 return new Map2(id, options); 3190 } 3191 var Control = Class.extend({ 3192 // @section 3193 // @aka Control Options 3194 options: { 3195 // @option position: String = 'topright' 3196 // The position of the control (one of the map corners). Possible values are `'topleft'`, 3197 // `'topright'`, `'bottomleft'` or `'bottomright'` 3198 position: "topright" 3199 }, 3200 initialize: function(options) { 3201 setOptions(this, options); 3202 }, 3203 /* @section 3204 * Classes extending L.Control will inherit the following methods: 3205 * 3206 * @method getPosition: string 3207 * Returns the position of the control. 3208 */ 3209 getPosition: function() { 3210 return this.options.position; 3211 }, 3212 // @method setPosition(position: string): this 3213 // Sets the position of the control. 3214 setPosition: function(position) { 3215 var map = this._map; 3216 if (map) { 3217 map.removeControl(this); 3218 } 3219 this.options.position = position; 3220 if (map) { 3221 map.addControl(this); 3222 } 3223 return this; 3224 }, 3225 // @method getContainer: HTMLElement 3226 // Returns the HTMLElement that contains the control. 3227 getContainer: function() { 3228 return this._container; 3229 }, 3230 // @method addTo(map: Map): this 3231 // Adds the control to the given map. 3232 addTo: function(map) { 3233 this.remove(); 3234 this._map = map; 3235 var container = this._container = this.onAdd(map), pos = this.getPosition(), corner = map._controlCorners[pos]; 3236 addClass(container, "leaflet-control"); 3237 if (pos.indexOf("bottom") !== -1) { 3238 corner.insertBefore(container, corner.firstChild); 3239 } else { 3240 corner.appendChild(container); 3241 } 3242 this._map.on("unload", this.remove, this); 3243 return this; 3244 }, 3245 // @method remove: this 3246 // Removes the control from the map it is currently active on. 3247 remove: function() { 3248 if (!this._map) { 3249 return this; 3250 } 3251 remove(this._container); 3252 if (this.onRemove) { 3253 this.onRemove(this._map); 3254 } 3255 this._map.off("unload", this.remove, this); 3256 this._map = null; 3257 return this; 3258 }, 3259 _refocusOnMap: function(e) { 3260 if (this._map && e && e.screenX > 0 && e.screenY > 0) { 3261 this._map.getContainer().focus(); 3262 } 3263 } 3264 }); 3265 var control = function(options) { 3266 return new Control(options); 3267 }; 3268 Map2.include({ 3269 // @method addControl(control: Control): this 3270 // Adds the given control to the map 3271 addControl: function(control2) { 3272 control2.addTo(this); 3273 return this; 3274 }, 3275 // @method removeControl(control: Control): this 3276 // Removes the given control from the map 3277 removeControl: function(control2) { 3278 control2.remove(); 3279 return this; 3280 }, 3281 _initControlPos: function() { 3282 var corners = this._controlCorners = {}, l = "leaflet-", container = this._controlContainer = create$1("div", l + "control-container", this._container); 3283 function createCorner(vSide, hSide) { 3284 var className = l + vSide + " " + l + hSide; 3285 corners[vSide + hSide] = create$1("div", className, container); 3286 } 3287 createCorner("top", "left"); 3288 createCorner("top", "right"); 3289 createCorner("bottom", "left"); 3290 createCorner("bottom", "right"); 3291 }, 3292 _clearControlPos: function() { 3293 for (var i in this._controlCorners) { 3294 remove(this._controlCorners[i]); 3295 } 3296 remove(this._controlContainer); 3297 delete this._controlCorners; 3298 delete this._controlContainer; 3299 } 3300 }); 3301 var Layers = Control.extend({ 3302 // @section 3303 // @aka Control.Layers options 3304 options: { 3305 // @option collapsed: Boolean = true 3306 // If `true`, the control will be collapsed into an icon and expanded on mouse hover, touch, or keyboard activation. 3307 collapsed: true, 3308 position: "topright", 3309 // @option autoZIndex: Boolean = true 3310 // 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. 3311 autoZIndex: true, 3312 // @option hideSingleBase: Boolean = false 3313 // If `true`, the base layers in the control will be hidden when there is only one. 3314 hideSingleBase: false, 3315 // @option sortLayers: Boolean = false 3316 // Whether to sort the layers. When `false`, layers will keep the order 3317 // in which they were added to the control. 3318 sortLayers: false, 3319 // @option sortFunction: Function = * 3320 // A [compare function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 3321 // that will be used for sorting the layers, when `sortLayers` is `true`. 3322 // The function receives both the `L.Layer` instances and their names, as in 3323 // `sortFunction(layerA, layerB, nameA, nameB)`. 3324 // By default, it sorts layers alphabetically by their name. 3325 sortFunction: function(layerA, layerB, nameA, nameB) { 3326 return nameA < nameB ? -1 : nameB < nameA ? 1 : 0; 3327 } 3328 }, 3329 initialize: function(baseLayers, overlays, options) { 3330 setOptions(this, options); 3331 this._layerControlInputs = []; 3332 this._layers = []; 3333 this._lastZIndex = 0; 3334 this._handlingClick = false; 3335 this._preventClick = false; 3336 for (var i in baseLayers) { 3337 this._addLayer(baseLayers[i], i); 3338 } 3339 for (i in overlays) { 3340 this._addLayer(overlays[i], i, true); 3341 } 3342 }, 3343 onAdd: function(map) { 3344 this._initLayout(); 3345 this._update(); 3346 this._map = map; 3347 map.on("zoomend", this._checkDisabledLayers, this); 3348 for (var i = 0; i < this._layers.length; i++) { 3349 this._layers[i].layer.on("add remove", this._onLayerChange, this); 3350 } 3351 return this._container; 3352 }, 3353 addTo: function(map) { 3354 Control.prototype.addTo.call(this, map); 3355 return this._expandIfNotCollapsed(); 3356 }, 3357 onRemove: function() { 3358 this._map.off("zoomend", this._checkDisabledLayers, this); 3359 for (var i = 0; i < this._layers.length; i++) { 3360 this._layers[i].layer.off("add remove", this._onLayerChange, this); 3361 } 3362 }, 3363 // @method addBaseLayer(layer: Layer, name: String): this 3364 // Adds a base layer (radio button entry) with the given name to the control. 3365 addBaseLayer: function(layer, name) { 3366 this._addLayer(layer, name); 3367 return this._map ? this._update() : this; 3368 }, 3369 // @method addOverlay(layer: Layer, name: String): this 3370 // Adds an overlay (checkbox entry) with the given name to the control. 3371 addOverlay: function(layer, name) { 3372 this._addLayer(layer, name, true); 3373 return this._map ? this._update() : this; 3374 }, 3375 // @method removeLayer(layer: Layer): this 3376 // Remove the given layer from the control. 3377 removeLayer: function(layer) { 3378 layer.off("add remove", this._onLayerChange, this); 3379 var obj = this._getLayer(stamp(layer)); 3380 if (obj) { 3381 this._layers.splice(this._layers.indexOf(obj), 1); 3382 } 3383 return this._map ? this._update() : this; 3384 }, 3385 // @method expand(): this 3386 // Expand the control container if collapsed. 3387 expand: function() { 3388 addClass(this._container, "leaflet-control-layers-expanded"); 3389 this._section.style.height = null; 3390 var acceptableHeight = this._map.getSize().y - (this._container.offsetTop + 50); 3391 if (acceptableHeight < this._section.clientHeight) { 3392 addClass(this._section, "leaflet-control-layers-scrollbar"); 3393 this._section.style.height = acceptableHeight + "px"; 3394 } else { 3395 removeClass(this._section, "leaflet-control-layers-scrollbar"); 3396 } 3397 this._checkDisabledLayers(); 3398 return this; 3399 }, 3400 // @method collapse(): this 3401 // Collapse the control container if expanded. 3402 collapse: function() { 3403 removeClass(this._container, "leaflet-control-layers-expanded"); 3404 return this; 3405 }, 3406 _initLayout: function() { 3407 var className = "leaflet-control-layers", container = this._container = create$1("div", className), collapsed = this.options.collapsed; 3408 container.setAttribute("aria-haspopup", true); 3409 disableClickPropagation(container); 3410 disableScrollPropagation(container); 3411 var section = this._section = create$1("section", className + "-list"); 3412 if (collapsed) { 3413 this._map.on("click", this.collapse, this); 3414 on(container, { 3415 mouseenter: this._expandSafely, 3416 mouseleave: this.collapse 3417 }, this); 3418 } 3419 var link = this._layersLink = create$1("a", className + "-toggle", container); 3420 link.href = "#"; 3421 link.title = "Layers"; 3422 link.setAttribute("role", "button"); 3423 on(link, { 3424 keydown: function(e) { 3425 if (e.keyCode === 13) { 3426 this._expandSafely(); 3427 } 3428 }, 3429 // Certain screen readers intercept the key event and instead send a click event 3430 click: function(e) { 3431 preventDefault(e); 3432 this._expandSafely(); 3433 } 3434 }, this); 3435 if (!collapsed) { 3436 this.expand(); 3437 } 3438 this._baseLayersList = create$1("div", className + "-base", section); 3439 this._separator = create$1("div", className + "-separator", section); 3440 this._overlaysList = create$1("div", className + "-overlays", section); 3441 container.appendChild(section); 3442 }, 3443 _getLayer: function(id) { 3444 for (var i = 0; i < this._layers.length; i++) { 3445 if (this._layers[i] && stamp(this._layers[i].layer) === id) { 3446 return this._layers[i]; 3447 } 3448 } 3449 }, 3450 _addLayer: function(layer, name, overlay) { 3451 if (this._map) { 3452 layer.on("add remove", this._onLayerChange, this); 3453 } 3454 this._layers.push({ 3455 layer, 3456 name, 3457 overlay 3458 }); 3459 if (this.options.sortLayers) { 3460 this._layers.sort(bind(function(a, b) { 3461 return this.options.sortFunction(a.layer, b.layer, a.name, b.name); 3462 }, this)); 3463 } 3464 if (this.options.autoZIndex && layer.setZIndex) { 3465 this._lastZIndex++; 3466 layer.setZIndex(this._lastZIndex); 3467 } 3468 this._expandIfNotCollapsed(); 3469 }, 3470 _update: function() { 3471 if (!this._container) { 3472 return this; 3473 } 3474 empty(this._baseLayersList); 3475 empty(this._overlaysList); 3476 this._layerControlInputs = []; 3477 var baseLayersPresent, overlaysPresent, i, obj, baseLayersCount = 0; 3478 for (i = 0; i < this._layers.length; i++) { 3479 obj = this._layers[i]; 3480 this._addItem(obj); 3481 overlaysPresent = overlaysPresent || obj.overlay; 3482 baseLayersPresent = baseLayersPresent || !obj.overlay; 3483 baseLayersCount += !obj.overlay ? 1 : 0; 3484 } 3485 if (this.options.hideSingleBase) { 3486 baseLayersPresent = baseLayersPresent && baseLayersCount > 1; 3487 this._baseLayersList.style.display = baseLayersPresent ? "" : "none"; 3488 } 3489 this._separator.style.display = overlaysPresent && baseLayersPresent ? "" : "none"; 3490 return this; 3491 }, 3492 _onLayerChange: function(e) { 3493 if (!this._handlingClick) { 3494 this._update(); 3495 } 3496 var obj = this._getLayer(stamp(e.target)); 3497 var type = obj.overlay ? e.type === "add" ? "overlayadd" : "overlayremove" : e.type === "add" ? "baselayerchange" : null; 3498 if (type) { 3499 this._map.fire(type, obj); 3500 } 3501 }, 3502 // IE7 bugs out if you create a radio dynamically, so you have to do it this hacky way (see https://stackoverflow.com/a/119079) 3503 _createRadioElement: function(name, checked) { 3504 var radioHtml = '<input type="radio" class="leaflet-control-layers-selector" name="' + name + '"' + (checked ? ' checked="checked"' : "") + "/>"; 3505 var radioFragment = document.createElement("div"); 3506 radioFragment.innerHTML = radioHtml; 3507 return radioFragment.firstChild; 3508 }, 3509 _addItem: function(obj) { 3510 var label = document.createElement("label"), checked = this._map.hasLayer(obj.layer), input; 3511 if (obj.overlay) { 3512 input = document.createElement("input"); 3513 input.type = "checkbox"; 3514 input.className = "leaflet-control-layers-selector"; 3515 input.defaultChecked = checked; 3516 } else { 3517 input = this._createRadioElement("leaflet-base-layers_" + stamp(this), checked); 3518 } 3519 this._layerControlInputs.push(input); 3520 input.layerId = stamp(obj.layer); 3521 on(input, "click", this._onInputClick, this); 3522 var name = document.createElement("span"); 3523 name.innerHTML = " " + obj.name; 3524 var holder = document.createElement("span"); 3525 label.appendChild(holder); 3526 holder.appendChild(input); 3527 holder.appendChild(name); 3528 var container = obj.overlay ? this._overlaysList : this._baseLayersList; 3529 container.appendChild(label); 3530 this._checkDisabledLayers(); 3531 return label; 3532 }, 3533 _onInputClick: function() { 3534 if (this._preventClick) { 3535 return; 3536 } 3537 var inputs = this._layerControlInputs, input, layer; 3538 var addedLayers = [], removedLayers = []; 3539 this._handlingClick = true; 3540 for (var i = inputs.length - 1; i >= 0; i--) { 3541 input = inputs[i]; 3542 layer = this._getLayer(input.layerId).layer; 3543 if (input.checked) { 3544 addedLayers.push(layer); 3545 } else if (!input.checked) { 3546 removedLayers.push(layer); 3547 } 3548 } 3549 for (i = 0; i < removedLayers.length; i++) { 3550 if (this._map.hasLayer(removedLayers[i])) { 3551 this._map.removeLayer(removedLayers[i]); 3552 } 3553 } 3554 for (i = 0; i < addedLayers.length; i++) { 3555 if (!this._map.hasLayer(addedLayers[i])) { 3556 this._map.addLayer(addedLayers[i]); 3557 } 3558 } 3559 this._handlingClick = false; 3560 this._refocusOnMap(); 3561 }, 3562 _checkDisabledLayers: function() { 3563 var inputs = this._layerControlInputs, input, layer, zoom2 = this._map.getZoom(); 3564 for (var i = inputs.length - 1; i >= 0; i--) { 3565 input = inputs[i]; 3566 layer = this._getLayer(input.layerId).layer; 3567 input.disabled = layer.options.minZoom !== void 0 && zoom2 < layer.options.minZoom || layer.options.maxZoom !== void 0 && zoom2 > layer.options.maxZoom; 3568 } 3569 }, 3570 _expandIfNotCollapsed: function() { 3571 if (this._map && !this.options.collapsed) { 3572 this.expand(); 3573 } 3574 return this; 3575 }, 3576 _expandSafely: function() { 3577 var section = this._section; 3578 this._preventClick = true; 3579 on(section, "click", preventDefault); 3580 this.expand(); 3581 var that = this; 3582 setTimeout(function() { 3583 off(section, "click", preventDefault); 3584 that._preventClick = false; 3585 }); 3586 } 3587 }); 3588 var layers = function(baseLayers, overlays, options) { 3589 return new Layers(baseLayers, overlays, options); 3590 }; 3591 var Zoom = Control.extend({ 3592 // @section 3593 // @aka Control.Zoom options 3594 options: { 3595 position: "topleft", 3596 // @option zoomInText: String = '<span aria-hidden="true">+</span>' 3597 // The text set on the 'zoom in' button. 3598 zoomInText: '<span aria-hidden="true">+</span>', 3599 // @option zoomInTitle: String = 'Zoom in' 3600 // The title set on the 'zoom in' button. 3601 zoomInTitle: "Zoom in", 3602 // @option zoomOutText: String = '<span aria-hidden="true">−</span>' 3603 // The text set on the 'zoom out' button. 3604 zoomOutText: '<span aria-hidden="true">−</span>', 3605 // @option zoomOutTitle: String = 'Zoom out' 3606 // The title set on the 'zoom out' button. 3607 zoomOutTitle: "Zoom out" 3608 }, 3609 onAdd: function(map) { 3610 var zoomName = "leaflet-control-zoom", container = create$1("div", zoomName + " leaflet-bar"), options = this.options; 3611 this._zoomInButton = this._createButton( 3612 options.zoomInText, 3613 options.zoomInTitle, 3614 zoomName + "-in", 3615 container, 3616 this._zoomIn 3617 ); 3618 this._zoomOutButton = this._createButton( 3619 options.zoomOutText, 3620 options.zoomOutTitle, 3621 zoomName + "-out", 3622 container, 3623 this._zoomOut 3624 ); 3625 this._updateDisabled(); 3626 map.on("zoomend zoomlevelschange", this._updateDisabled, this); 3627 return container; 3628 }, 3629 onRemove: function(map) { 3630 map.off("zoomend zoomlevelschange", this._updateDisabled, this); 3631 }, 3632 disable: function() { 3633 this._disabled = true; 3634 this._updateDisabled(); 3635 return this; 3636 }, 3637 enable: function() { 3638 this._disabled = false; 3639 this._updateDisabled(); 3640 return this; 3641 }, 3642 _zoomIn: function(e) { 3643 if (!this._disabled && this._map._zoom < this._map.getMaxZoom()) { 3644 this._map.zoomIn(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1)); 3645 } 3646 }, 3647 _zoomOut: function(e) { 3648 if (!this._disabled && this._map._zoom > this._map.getMinZoom()) { 3649 this._map.zoomOut(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1)); 3650 } 3651 }, 3652 _createButton: function(html, title, className, container, fn2) { 3653 var link = create$1("a", className, container); 3654 link.innerHTML = html; 3655 link.href = "#"; 3656 link.title = title; 3657 link.setAttribute("role", "button"); 3658 link.setAttribute("aria-label", title); 3659 disableClickPropagation(link); 3660 on(link, "click", stop); 3661 on(link, "click", fn2, this); 3662 on(link, "click", this._refocusOnMap, this); 3663 return link; 3664 }, 3665 _updateDisabled: function() { 3666 var map = this._map, className = "leaflet-disabled"; 3667 removeClass(this._zoomInButton, className); 3668 removeClass(this._zoomOutButton, className); 3669 this._zoomInButton.setAttribute("aria-disabled", "false"); 3670 this._zoomOutButton.setAttribute("aria-disabled", "false"); 3671 if (this._disabled || map._zoom === map.getMinZoom()) { 3672 addClass(this._zoomOutButton, className); 3673 this._zoomOutButton.setAttribute("aria-disabled", "true"); 3674 } 3675 if (this._disabled || map._zoom === map.getMaxZoom()) { 3676 addClass(this._zoomInButton, className); 3677 this._zoomInButton.setAttribute("aria-disabled", "true"); 3678 } 3679 } 3680 }); 3681 Map2.mergeOptions({ 3682 zoomControl: true 3683 }); 3684 Map2.addInitHook(function() { 3685 if (this.options.zoomControl) { 3686 this.zoomControl = new Zoom(); 3687 this.addControl(this.zoomControl); 3688 } 3689 }); 3690 var zoom = function(options) { 3691 return new Zoom(options); 3692 }; 3693 var Scale = Control.extend({ 3694 // @section 3695 // @aka Control.Scale options 3696 options: { 3697 position: "bottomleft", 3698 // @option maxWidth: Number = 100 3699 // Maximum width of the control in pixels. The width is set dynamically to show round values (e.g. 100, 200, 500). 3700 maxWidth: 100, 3701 // @option metric: Boolean = True 3702 // Whether to show the metric scale line (m/km). 3703 metric: true, 3704 // @option imperial: Boolean = True 3705 // Whether to show the imperial scale line (mi/ft). 3706 imperial: true 3707 // @option updateWhenIdle: Boolean = false 3708 // If `true`, the control is updated on [`moveend`](#map-moveend), otherwise it's always up-to-date (updated on [`move`](#map-move)). 3709 }, 3710 onAdd: function(map) { 3711 var className = "leaflet-control-scale", container = create$1("div", className), options = this.options; 3712 this._addScales(options, className + "-line", container); 3713 map.on(options.updateWhenIdle ? "moveend" : "move", this._update, this); 3714 map.whenReady(this._update, this); 3715 return container; 3716 }, 3717 onRemove: function(map) { 3718 map.off(this.options.updateWhenIdle ? "moveend" : "move", this._update, this); 3719 }, 3720 _addScales: function(options, className, container) { 3721 if (options.metric) { 3722 this._mScale = create$1("div", className, container); 3723 } 3724 if (options.imperial) { 3725 this._iScale = create$1("div", className, container); 3726 } 3727 }, 3728 _update: function() { 3729 var map = this._map, y = map.getSize().y / 2; 3730 var maxMeters = map.distance( 3731 map.containerPointToLatLng([0, y]), 3732 map.containerPointToLatLng([this.options.maxWidth, y]) 3733 ); 3734 this._updateScales(maxMeters); 3735 }, 3736 _updateScales: function(maxMeters) { 3737 if (this.options.metric && maxMeters) { 3738 this._updateMetric(maxMeters); 3739 } 3740 if (this.options.imperial && maxMeters) { 3741 this._updateImperial(maxMeters); 3742 } 3743 }, 3744 _updateMetric: function(maxMeters) { 3745 var meters = this._getRoundNum(maxMeters), label = meters < 1e3 ? meters + " m" : meters / 1e3 + " km"; 3746 this._updateScale(this._mScale, label, meters / maxMeters); 3747 }, 3748 _updateImperial: function(maxMeters) { 3749 var maxFeet = maxMeters * 3.2808399, maxMiles, miles, feet; 3750 if (maxFeet > 5280) { 3751 maxMiles = maxFeet / 5280; 3752 miles = this._getRoundNum(maxMiles); 3753 this._updateScale(this._iScale, miles + " mi", miles / maxMiles); 3754 } else { 3755 feet = this._getRoundNum(maxFeet); 3756 this._updateScale(this._iScale, feet + " ft", feet / maxFeet); 3757 } 3758 }, 3759 _updateScale: function(scale2, text, ratio) { 3760 scale2.style.width = Math.round(this.options.maxWidth * ratio) + "px"; 3761 scale2.innerHTML = text; 3762 }, 3763 _getRoundNum: function(num) { 3764 var pow10 = Math.pow(10, (Math.floor(num) + "").length - 1), d = num / pow10; 3765 d = d >= 10 ? 10 : d >= 5 ? 5 : d >= 3 ? 3 : d >= 2 ? 2 : 1; 3766 return pow10 * d; 3767 } 3768 }); 3769 var scale = function(options) { 3770 return new Scale(options); 3771 }; 3772 var ukrainianFlag = '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="12" height="8" viewBox="0 0 12 8" class="leaflet-attribution-flag"><path fill="#4C7BE1" d="M0 0h12v4H0z"/><path fill="#FFD500" d="M0 4h12v3H0z"/><path fill="#E0BC00" d="M0 7h12v1H0z"/></svg>'; 3773 var Attribution = Control.extend({ 3774 // @section 3775 // @aka Control.Attribution options 3776 options: { 3777 position: "bottomright", 3778 // @option prefix: String|false = 'Leaflet' 3779 // The HTML text shown before the attributions. Pass `false` to disable. 3780 prefix: '<a href="https://leafletjs.com" title="A JavaScript library for interactive maps">' + (Browser.inlineSvg ? ukrainianFlag + " " : "") + "Leaflet</a>" 3781 }, 3782 initialize: function(options) { 3783 setOptions(this, options); 3784 this._attributions = {}; 3785 }, 3786 onAdd: function(map) { 3787 map.attributionControl = this; 3788 this._container = create$1("div", "leaflet-control-attribution"); 3789 disableClickPropagation(this._container); 3790 for (var i in map._layers) { 3791 if (map._layers[i].getAttribution) { 3792 this.addAttribution(map._layers[i].getAttribution()); 3793 } 3794 } 3795 this._update(); 3796 map.on("layeradd", this._addAttribution, this); 3797 return this._container; 3798 }, 3799 onRemove: function(map) { 3800 map.off("layeradd", this._addAttribution, this); 3801 }, 3802 _addAttribution: function(ev) { 3803 if (ev.layer.getAttribution) { 3804 this.addAttribution(ev.layer.getAttribution()); 3805 ev.layer.once("remove", function() { 3806 this.removeAttribution(ev.layer.getAttribution()); 3807 }, this); 3808 } 3809 }, 3810 // @method setPrefix(prefix: String|false): this 3811 // The HTML text shown before the attributions. Pass `false` to disable. 3812 setPrefix: function(prefix) { 3813 this.options.prefix = prefix; 3814 this._update(); 3815 return this; 3816 }, 3817 // @method addAttribution(text: String): this 3818 // Adds an attribution text (e.g. `'© OpenStreetMap contributors'`). 3819 addAttribution: function(text) { 3820 if (!text) { 3821 return this; 3822 } 3823 if (!this._attributions[text]) { 3824 this._attributions[text] = 0; 3825 } 3826 this._attributions[text]++; 3827 this._update(); 3828 return this; 3829 }, 3830 // @method removeAttribution(text: String): this 3831 // Removes an attribution text. 3832 removeAttribution: function(text) { 3833 if (!text) { 3834 return this; 3835 } 3836 if (this._attributions[text]) { 3837 this._attributions[text]--; 3838 this._update(); 3839 } 3840 return this; 3841 }, 3842 _update: function() { 3843 if (!this._map) { 3844 return; 3845 } 3846 var attribs = []; 3847 for (var i in this._attributions) { 3848 if (this._attributions[i]) { 3849 attribs.push(i); 3850 } 3851 } 3852 var prefixAndAttribs = []; 3853 if (this.options.prefix) { 3854 prefixAndAttribs.push(this.options.prefix); 3855 } 3856 if (attribs.length) { 3857 prefixAndAttribs.push(attribs.join(", ")); 3858 } 3859 this._container.innerHTML = prefixAndAttribs.join(' <span aria-hidden="true">|</span> '); 3860 } 3861 }); 3862 Map2.mergeOptions({ 3863 attributionControl: true 3864 }); 3865 Map2.addInitHook(function() { 3866 if (this.options.attributionControl) { 3867 new Attribution().addTo(this); 3868 } 3869 }); 3870 var attribution = function(options) { 3871 return new Attribution(options); 3872 }; 3873 Control.Layers = Layers; 3874 Control.Zoom = Zoom; 3875 Control.Scale = Scale; 3876 Control.Attribution = Attribution; 3877 control.layers = layers; 3878 control.zoom = zoom; 3879 control.scale = scale; 3880 control.attribution = attribution; 3881 var Handler = Class.extend({ 3882 initialize: function(map) { 3883 this._map = map; 3884 }, 3885 // @method enable(): this 3886 // Enables the handler 3887 enable: function() { 3888 if (this._enabled) { 3889 return this; 3890 } 3891 this._enabled = true; 3892 this.addHooks(); 3893 return this; 3894 }, 3895 // @method disable(): this 3896 // Disables the handler 3897 disable: function() { 3898 if (!this._enabled) { 3899 return this; 3900 } 3901 this._enabled = false; 3902 this.removeHooks(); 3903 return this; 3904 }, 3905 // @method enabled(): Boolean 3906 // Returns `true` if the handler is enabled 3907 enabled: function() { 3908 return !!this._enabled; 3909 } 3910 // @section Extension methods 3911 // Classes inheriting from `Handler` must implement the two following methods: 3912 // @method addHooks() 3913 // Called when the handler is enabled, should add event hooks. 3914 // @method removeHooks() 3915 // Called when the handler is disabled, should remove the event hooks added previously. 3916 }); 3917 Handler.addTo = function(map, name) { 3918 map.addHandler(name, this); 3919 return this; 3920 }; 3921 var Mixin = { Events }; 3922 var START = Browser.touch ? "touchstart mousedown" : "mousedown"; 3923 var Draggable = Evented.extend({ 3924 options: { 3925 // @section 3926 // @aka Draggable options 3927 // @option clickTolerance: Number = 3 3928 // The max number of pixels a user can shift the mouse pointer during a click 3929 // for it to be considered a valid click (as opposed to a mouse drag). 3930 clickTolerance: 3 3931 }, 3932 // @constructor L.Draggable(el: HTMLElement, dragHandle?: HTMLElement, preventOutline?: Boolean, options?: Draggable options) 3933 // Creates a `Draggable` object for moving `el` when you start dragging the `dragHandle` element (equals `el` itself by default). 3934 initialize: function(element, dragStartTarget, preventOutline2, options) { 3935 setOptions(this, options); 3936 this._element = element; 3937 this._dragStartTarget = dragStartTarget || element; 3938 this._preventOutline = preventOutline2; 3939 }, 3940 // @method enable() 3941 // Enables the dragging ability 3942 enable: function() { 3943 if (this._enabled) { 3944 return; 3945 } 3946 on(this._dragStartTarget, START, this._onDown, this); 3947 this._enabled = true; 3948 }, 3949 // @method disable() 3950 // Disables the dragging ability 3951 disable: function() { 3952 if (!this._enabled) { 3953 return; 3954 } 3955 if (Draggable._dragging === this) { 3956 this.finishDrag(true); 3957 } 3958 off(this._dragStartTarget, START, this._onDown, this); 3959 this._enabled = false; 3960 this._moved = false; 3961 }, 3962 _onDown: function(e) { 3963 if (!this._enabled) { 3964 return; 3965 } 3966 this._moved = false; 3967 if (hasClass(this._element, "leaflet-zoom-anim")) { 3968 return; 3969 } 3970 if (e.touches && e.touches.length !== 1) { 3971 if (Draggable._dragging === this) { 3972 this.finishDrag(); 3973 } 3974 return; 3975 } 3976 if (Draggable._dragging || e.shiftKey || e.which !== 1 && e.button !== 1 && !e.touches) { 3977 return; 3978 } 3979 Draggable._dragging = this; 3980 if (this._preventOutline) { 3981 preventOutline(this._element); 3982 } 3983 disableImageDrag(); 3984 disableTextSelection(); 3985 if (this._moving) { 3986 return; 3987 } 3988 this.fire("down"); 3989 var first = e.touches ? e.touches[0] : e, sizedParent = getSizedParentNode(this._element); 3990 this._startPoint = new Point(first.clientX, first.clientY); 3991 this._startPos = getPosition(this._element); 3992 this._parentScale = getScale(sizedParent); 3993 var mouseevent = e.type === "mousedown"; 3994 on(document, mouseevent ? "mousemove" : "touchmove", this._onMove, this); 3995 on(document, mouseevent ? "mouseup" : "touchend touchcancel", this._onUp, this); 3996 }, 3997 _onMove: function(e) { 3998 if (!this._enabled) { 3999 return; 4000 } 4001 if (e.touches && e.touches.length > 1) { 4002 this._moved = true; 4003 return; 4004 } 4005 var first = e.touches && e.touches.length === 1 ? e.touches[0] : e, offset2 = new Point(first.clientX, first.clientY)._subtract(this._startPoint); 4006 if (!offset2.x && !offset2.y) { 4007 return; 4008 } 4009 if (Math.abs(offset2.x) + Math.abs(offset2.y) < this.options.clickTolerance) { 4010 return; 4011 } 4012 offset2.x /= this._parentScale.x; 4013 offset2.y /= this._parentScale.y; 4014 preventDefault(e); 4015 if (!this._moved) { 4016 this.fire("dragstart"); 4017 this._moved = true; 4018 addClass(document.body, "leaflet-dragging"); 4019 this._lastTarget = e.target || e.srcElement; 4020 if (window.SVGElementInstance && this._lastTarget instanceof window.SVGElementInstance) { 4021 this._lastTarget = this._lastTarget.correspondingUseElement; 4022 } 4023 addClass(this._lastTarget, "leaflet-drag-target"); 4024 } 4025 this._newPos = this._startPos.add(offset2); 4026 this._moving = true; 4027 this._lastEvent = e; 4028 this._updatePosition(); 4029 }, 4030 _updatePosition: function() { 4031 var e = { originalEvent: this._lastEvent }; 4032 this.fire("predrag", e); 4033 setPosition(this._element, this._newPos); 4034 this.fire("drag", e); 4035 }, 4036 _onUp: function() { 4037 if (!this._enabled) { 4038 return; 4039 } 4040 this.finishDrag(); 4041 }, 4042 finishDrag: function(noInertia) { 4043 removeClass(document.body, "leaflet-dragging"); 4044 if (this._lastTarget) { 4045 removeClass(this._lastTarget, "leaflet-drag-target"); 4046 this._lastTarget = null; 4047 } 4048 off(document, "mousemove touchmove", this._onMove, this); 4049 off(document, "mouseup touchend touchcancel", this._onUp, this); 4050 enableImageDrag(); 4051 enableTextSelection(); 4052 var fireDragend = this._moved && this._moving; 4053 this._moving = false; 4054 Draggable._dragging = false; 4055 if (fireDragend) { 4056 this.fire("dragend", { 4057 noInertia, 4058 distance: this._newPos.distanceTo(this._startPos) 4059 }); 4060 } 4061 } 4062 }); 4063 function clipPolygon(points, bounds, round2) { 4064 var clippedPoints, edges = [1, 4, 2, 8], i, j, k, a, b, len, edge2, p; 4065 for (i = 0, len = points.length; i < len; i++) { 4066 points[i]._code = _getBitCode(points[i], bounds); 4067 } 4068 for (k = 0; k < 4; k++) { 4069 edge2 = edges[k]; 4070 clippedPoints = []; 4071 for (i = 0, len = points.length, j = len - 1; i < len; j = i++) { 4072 a = points[i]; 4073 b = points[j]; 4074 if (!(a._code & edge2)) { 4075 if (b._code & edge2) { 4076 p = _getEdgeIntersection(b, a, edge2, bounds, round2); 4077 p._code = _getBitCode(p, bounds); 4078 clippedPoints.push(p); 4079 } 4080 clippedPoints.push(a); 4081 } else if (!(b._code & edge2)) { 4082 p = _getEdgeIntersection(b, a, edge2, bounds, round2); 4083 p._code = _getBitCode(p, bounds); 4084 clippedPoints.push(p); 4085 } 4086 } 4087 points = clippedPoints; 4088 } 4089 return points; 4090 } 4091 function polygonCenter(latlngs, crs) { 4092 var i, j, p1, p2, f, area, x, y, center; 4093 if (!latlngs || latlngs.length === 0) { 4094 throw new Error("latlngs not passed"); 4095 } 4096 if (!isFlat(latlngs)) { 4097 console.warn("latlngs are not flat! Only the first ring will be used"); 4098 latlngs = latlngs[0]; 4099 } 4100 var centroidLatLng = toLatLng([0, 0]); 4101 var bounds = toLatLngBounds(latlngs); 4102 var areaBounds = bounds.getNorthWest().distanceTo(bounds.getSouthWest()) * bounds.getNorthEast().distanceTo(bounds.getNorthWest()); 4103 if (areaBounds < 1700) { 4104 centroidLatLng = centroid(latlngs); 4105 } 4106 var len = latlngs.length; 4107 var points = []; 4108 for (i = 0; i < len; i++) { 4109 var latlng = toLatLng(latlngs[i]); 4110 points.push(crs.project(toLatLng([latlng.lat - centroidLatLng.lat, latlng.lng - centroidLatLng.lng]))); 4111 } 4112 area = x = y = 0; 4113 for (i = 0, j = len - 1; i < len; j = i++) { 4114 p1 = points[i]; 4115 p2 = points[j]; 4116 f = p1.y * p2.x - p2.y * p1.x; 4117 x += (p1.x + p2.x) * f; 4118 y += (p1.y + p2.y) * f; 4119 area += f * 3; 4120 } 4121 if (area === 0) { 4122 center = points[0]; 4123 } else { 4124 center = [x / area, y / area]; 4125 } 4126 var latlngCenter = crs.unproject(toPoint(center)); 4127 return toLatLng([latlngCenter.lat + centroidLatLng.lat, latlngCenter.lng + centroidLatLng.lng]); 4128 } 4129 function centroid(coords) { 4130 var latSum = 0; 4131 var lngSum = 0; 4132 var len = 0; 4133 for (var i = 0; i < coords.length; i++) { 4134 var latlng = toLatLng(coords[i]); 4135 latSum += latlng.lat; 4136 lngSum += latlng.lng; 4137 len++; 4138 } 4139 return toLatLng([latSum / len, lngSum / len]); 4140 } 4141 var PolyUtil = { 4142 __proto__: null, 4143 clipPolygon, 4144 polygonCenter, 4145 centroid 4146 }; 4147 function simplify(points, tolerance) { 4148 if (!tolerance || !points.length) { 4149 return points.slice(); 4150 } 4151 var sqTolerance = tolerance * tolerance; 4152 points = _reducePoints(points, sqTolerance); 4153 points = _simplifyDP(points, sqTolerance); 4154 return points; 4155 } 4156 function pointToSegmentDistance(p, p1, p2) { 4157 return Math.sqrt(_sqClosestPointOnSegment(p, p1, p2, true)); 4158 } 4159 function closestPointOnSegment(p, p1, p2) { 4160 return _sqClosestPointOnSegment(p, p1, p2); 4161 } 4162 function _simplifyDP(points, sqTolerance) { 4163 var len = points.length, ArrayConstructor = typeof Uint8Array !== "undefined" ? Uint8Array : Array, markers = new ArrayConstructor(len); 4164 markers[0] = markers[len - 1] = 1; 4165 _simplifyDPStep(points, markers, sqTolerance, 0, len - 1); 4166 var i, newPoints = []; 4167 for (i = 0; i < len; i++) { 4168 if (markers[i]) { 4169 newPoints.push(points[i]); 4170 } 4171 } 4172 return newPoints; 4173 } 4174 function _simplifyDPStep(points, markers, sqTolerance, first, last) { 4175 var maxSqDist = 0, index2, i, sqDist; 4176 for (i = first + 1; i <= last - 1; i++) { 4177 sqDist = _sqClosestPointOnSegment(points[i], points[first], points[last], true); 4178 if (sqDist > maxSqDist) { 4179 index2 = i; 4180 maxSqDist = sqDist; 4181 } 4182 } 4183 if (maxSqDist > sqTolerance) { 4184 markers[index2] = 1; 4185 _simplifyDPStep(points, markers, sqTolerance, first, index2); 4186 _simplifyDPStep(points, markers, sqTolerance, index2, last); 4187 } 4188 } 4189 function _reducePoints(points, sqTolerance) { 4190 var reducedPoints = [points[0]]; 4191 for (var i = 1, prev = 0, len = points.length; i < len; i++) { 4192 if (_sqDist(points[i], points[prev]) > sqTolerance) { 4193 reducedPoints.push(points[i]); 4194 prev = i; 4195 } 4196 } 4197 if (prev < len - 1) { 4198 reducedPoints.push(points[len - 1]); 4199 } 4200 return reducedPoints; 4201 } 4202 var _lastCode; 4203 function clipSegment(a, b, bounds, useLastCode, round2) { 4204 var codeA = useLastCode ? _lastCode : _getBitCode(a, bounds), codeB = _getBitCode(b, bounds), codeOut, p, newCode; 4205 _lastCode = codeB; 4206 while (true) { 4207 if (!(codeA | codeB)) { 4208 return [a, b]; 4209 } 4210 if (codeA & codeB) { 4211 return false; 4212 } 4213 codeOut = codeA || codeB; 4214 p = _getEdgeIntersection(a, b, codeOut, bounds, round2); 4215 newCode = _getBitCode(p, bounds); 4216 if (codeOut === codeA) { 4217 a = p; 4218 codeA = newCode; 4219 } else { 4220 b = p; 4221 codeB = newCode; 4222 } 4223 } 4224 } 4225 function _getEdgeIntersection(a, b, code, bounds, round2) { 4226 var dx = b.x - a.x, dy = b.y - a.y, min2 = bounds.min, max2 = bounds.max, x, y; 4227 if (code & 8) { 4228 x = a.x + dx * (max2.y - a.y) / dy; 4229 y = max2.y; 4230 } else if (code & 4) { 4231 x = a.x + dx * (min2.y - a.y) / dy; 4232 y = min2.y; 4233 } else if (code & 2) { 4234 x = max2.x; 4235 y = a.y + dy * (max2.x - a.x) / dx; 4236 } else if (code & 1) { 4237 x = min2.x; 4238 y = a.y + dy * (min2.x - a.x) / dx; 4239 } 4240 return new Point(x, y, round2); 4241 } 4242 function _getBitCode(p, bounds) { 4243 var code = 0; 4244 if (p.x < bounds.min.x) { 4245 code |= 1; 4246 } else if (p.x > bounds.max.x) { 4247 code |= 2; 4248 } 4249 if (p.y < bounds.min.y) { 4250 code |= 4; 4251 } else if (p.y > bounds.max.y) { 4252 code |= 8; 4253 } 4254 return code; 4255 } 4256 function _sqDist(p1, p2) { 4257 var dx = p2.x - p1.x, dy = p2.y - p1.y; 4258 return dx * dx + dy * dy; 4259 } 4260 function _sqClosestPointOnSegment(p, p1, p2, sqDist) { 4261 var x = p1.x, y = p1.y, dx = p2.x - x, dy = p2.y - y, dot = dx * dx + dy * dy, t; 4262 if (dot > 0) { 4263 t = ((p.x - x) * dx + (p.y - y) * dy) / dot; 4264 if (t > 1) { 4265 x = p2.x; 4266 y = p2.y; 4267 } else if (t > 0) { 4268 x += dx * t; 4269 y += dy * t; 4270 } 4271 } 4272 dx = p.x - x; 4273 dy = p.y - y; 4274 return sqDist ? dx * dx + dy * dy : new Point(x, y); 4275 } 4276 function isFlat(latlngs) { 4277 return !isArray(latlngs[0]) || typeof latlngs[0][0] !== "object" && typeof latlngs[0][0] !== "undefined"; 4278 } 4279 function _flat(latlngs) { 4280 console.warn("Deprecated use of _flat, please use L.LineUtil.isFlat instead."); 4281 return isFlat(latlngs); 4282 } 4283 function polylineCenter(latlngs, crs) { 4284 var i, halfDist, segDist, dist, p1, p2, ratio, center; 4285 if (!latlngs || latlngs.length === 0) { 4286 throw new Error("latlngs not passed"); 4287 } 4288 if (!isFlat(latlngs)) { 4289 console.warn("latlngs are not flat! Only the first ring will be used"); 4290 latlngs = latlngs[0]; 4291 } 4292 var centroidLatLng = toLatLng([0, 0]); 4293 var bounds = toLatLngBounds(latlngs); 4294 var areaBounds = bounds.getNorthWest().distanceTo(bounds.getSouthWest()) * bounds.getNorthEast().distanceTo(bounds.getNorthWest()); 4295 if (areaBounds < 1700) { 4296 centroidLatLng = centroid(latlngs); 4297 } 4298 var len = latlngs.length; 4299 var points = []; 4300 for (i = 0; i < len; i++) { 4301 var latlng = toLatLng(latlngs[i]); 4302 points.push(crs.project(toLatLng([latlng.lat - centroidLatLng.lat, latlng.lng - centroidLatLng.lng]))); 4303 } 4304 for (i = 0, halfDist = 0; i < len - 1; i++) { 4305 halfDist += points[i].distanceTo(points[i + 1]) / 2; 4306 } 4307 if (halfDist === 0) { 4308 center = points[0]; 4309 } else { 4310 for (i = 0, dist = 0; i < len - 1; i++) { 4311 p1 = points[i]; 4312 p2 = points[i + 1]; 4313 segDist = p1.distanceTo(p2); 4314 dist += segDist; 4315 if (dist > halfDist) { 4316 ratio = (dist - halfDist) / segDist; 4317 center = [ 4318 p2.x - ratio * (p2.x - p1.x), 4319 p2.y - ratio * (p2.y - p1.y) 4320 ]; 4321 break; 4322 } 4323 } 4324 } 4325 var latlngCenter = crs.unproject(toPoint(center)); 4326 return toLatLng([latlngCenter.lat + centroidLatLng.lat, latlngCenter.lng + centroidLatLng.lng]); 4327 } 4328 var LineUtil = { 4329 __proto__: null, 4330 simplify, 4331 pointToSegmentDistance, 4332 closestPointOnSegment, 4333 clipSegment, 4334 _getEdgeIntersection, 4335 _getBitCode, 4336 _sqClosestPointOnSegment, 4337 isFlat, 4338 _flat, 4339 polylineCenter 4340 }; 4341 var LonLat = { 4342 project: function(latlng) { 4343 return new Point(latlng.lng, latlng.lat); 4344 }, 4345 unproject: function(point) { 4346 return new LatLng(point.y, point.x); 4347 }, 4348 bounds: new Bounds([-180, -90], [180, 90]) 4349 }; 4350 var Mercator = { 4351 R: 6378137, 4352 R_MINOR: 6356752314245179e-9, 4353 bounds: new Bounds([-2003750834279e-5, -1549657073972e-5], [2003750834279e-5, 1876465623138e-5]), 4354 project: function(latlng) { 4355 var d = Math.PI / 180, r = this.R, y = latlng.lat * d, tmp = this.R_MINOR / r, e = Math.sqrt(1 - tmp * tmp), con = e * Math.sin(y); 4356 var ts = Math.tan(Math.PI / 4 - y / 2) / Math.pow((1 - con) / (1 + con), e / 2); 4357 y = -r * Math.log(Math.max(ts, 1e-10)); 4358 return new Point(latlng.lng * d * r, y); 4359 }, 4360 unproject: function(point) { 4361 var d = 180 / Math.PI, r = this.R, tmp = this.R_MINOR / r, e = Math.sqrt(1 - tmp * tmp), ts = Math.exp(-point.y / r), phi = Math.PI / 2 - 2 * Math.atan(ts); 4362 for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) { 4363 con = e * Math.sin(phi); 4364 con = Math.pow((1 - con) / (1 + con), e / 2); 4365 dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi; 4366 phi += dphi; 4367 } 4368 return new LatLng(phi * d, point.x * d / r); 4369 } 4370 }; 4371 var index = { 4372 __proto__: null, 4373 LonLat, 4374 Mercator, 4375 SphericalMercator 4376 }; 4377 var EPSG3395 = extend({}, Earth, { 4378 code: "EPSG:3395", 4379 projection: Mercator, 4380 transformation: function() { 4381 var scale2 = 0.5 / (Math.PI * Mercator.R); 4382 return toTransformation(scale2, 0.5, -scale2, 0.5); 4383 }() 4384 }); 4385 var EPSG4326 = extend({}, Earth, { 4386 code: "EPSG:4326", 4387 projection: LonLat, 4388 transformation: toTransformation(1 / 180, 1, -1 / 180, 0.5) 4389 }); 4390 var Simple = extend({}, CRS, { 4391 projection: LonLat, 4392 transformation: toTransformation(1, 0, -1, 0), 4393 scale: function(zoom2) { 4394 return Math.pow(2, zoom2); 4395 }, 4396 zoom: function(scale2) { 4397 return Math.log(scale2) / Math.LN2; 4398 }, 4399 distance: function(latlng1, latlng2) { 4400 var dx = latlng2.lng - latlng1.lng, dy = latlng2.lat - latlng1.lat; 4401 return Math.sqrt(dx * dx + dy * dy); 4402 }, 4403 infinite: true 4404 }); 4405 CRS.Earth = Earth; 4406 CRS.EPSG3395 = EPSG3395; 4407 CRS.EPSG3857 = EPSG3857; 4408 CRS.EPSG900913 = EPSG900913; 4409 CRS.EPSG4326 = EPSG4326; 4410 CRS.Simple = Simple; 4411 var Layer = Evented.extend({ 4412 // Classes extending `L.Layer` will inherit the following options: 4413 options: { 4414 // @option pane: String = 'overlayPane' 4415 // 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. 4416 pane: "overlayPane", 4417 // @option attribution: String = null 4418 // 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. 4419 attribution: null, 4420 bubblingMouseEvents: true 4421 }, 4422 /* @section 4423 * Classes extending `L.Layer` will inherit the following methods: 4424 * 4425 * @method addTo(map: Map|LayerGroup): this 4426 * Adds the layer to the given map or layer group. 4427 */ 4428 addTo: function(map) { 4429 map.addLayer(this); 4430 return this; 4431 }, 4432 // @method remove: this 4433 // Removes the layer from the map it is currently active on. 4434 remove: function() { 4435 return this.removeFrom(this._map || this._mapToAdd); 4436 }, 4437 // @method removeFrom(map: Map): this 4438 // Removes the layer from the given map 4439 // 4440 // @alternative 4441 // @method removeFrom(group: LayerGroup): this 4442 // Removes the layer from the given `LayerGroup` 4443 removeFrom: function(obj) { 4444 if (obj) { 4445 obj.removeLayer(this); 4446 } 4447 return this; 4448 }, 4449 // @method getPane(name? : String): HTMLElement 4450 // Returns the `HTMLElement` representing the named pane on the map. If `name` is omitted, returns the pane for this layer. 4451 getPane: function(name) { 4452 return this._map.getPane(name ? this.options[name] || name : this.options.pane); 4453 }, 4454 addInteractiveTarget: function(targetEl) { 4455 this._map._targets[stamp(targetEl)] = this; 4456 return this; 4457 }, 4458 removeInteractiveTarget: function(targetEl) { 4459 delete this._map._targets[stamp(targetEl)]; 4460 return this; 4461 }, 4462 // @method getAttribution: String 4463 // Used by the `attribution control`, returns the [attribution option](#gridlayer-attribution). 4464 getAttribution: function() { 4465 return this.options.attribution; 4466 }, 4467 _layerAdd: function(e) { 4468 var map = e.target; 4469 if (!map.hasLayer(this)) { 4470 return; 4471 } 4472 this._map = map; 4473 this._zoomAnimated = map._zoomAnimated; 4474 if (this.getEvents) { 4475 var events = this.getEvents(); 4476 map.on(events, this); 4477 this.once("remove", function() { 4478 map.off(events, this); 4479 }, this); 4480 } 4481 this.onAdd(map); 4482 this.fire("add"); 4483 map.fire("layeradd", { layer: this }); 4484 } 4485 }); 4486 Map2.include({ 4487 // @method addLayer(layer: Layer): this 4488 // Adds the given layer to the map 4489 addLayer: function(layer) { 4490 if (!layer._layerAdd) { 4491 throw new Error("The provided object is not a Layer."); 4492 } 4493 var id = stamp(layer); 4494 if (this._layers[id]) { 4495 return this; 4496 } 4497 this._layers[id] = layer; 4498 layer._mapToAdd = this; 4499 if (layer.beforeAdd) { 4500 layer.beforeAdd(this); 4501 } 4502 this.whenReady(layer._layerAdd, layer); 4503 return this; 4504 }, 4505 // @method removeLayer(layer: Layer): this 4506 // Removes the given layer from the map. 4507 removeLayer: function(layer) { 4508 var id = stamp(layer); 4509 if (!this._layers[id]) { 4510 return this; 4511 } 4512 if (this._loaded) { 4513 layer.onRemove(this); 4514 } 4515 delete this._layers[id]; 4516 if (this._loaded) { 4517 this.fire("layerremove", { layer }); 4518 layer.fire("remove"); 4519 } 4520 layer._map = layer._mapToAdd = null; 4521 return this; 4522 }, 4523 // @method hasLayer(layer: Layer): Boolean 4524 // Returns `true` if the given layer is currently added to the map 4525 hasLayer: function(layer) { 4526 return stamp(layer) in this._layers; 4527 }, 4528 /* @method eachLayer(fn: Function, context?: Object): this 4529 * Iterates over the layers of the map, optionally specifying context of the iterator function. 4530 * ``` 4531 * map.eachLayer(function(layer){ 4532 * layer.bindPopup('Hello'); 4533 * }); 4534 * ``` 4535 */ 4536 eachLayer: function(method, context) { 4537 for (var i in this._layers) { 4538 method.call(context, this._layers[i]); 4539 } 4540 return this; 4541 }, 4542 _addLayers: function(layers2) { 4543 layers2 = layers2 ? isArray(layers2) ? layers2 : [layers2] : []; 4544 for (var i = 0, len = layers2.length; i < len; i++) { 4545 this.addLayer(layers2[i]); 4546 } 4547 }, 4548 _addZoomLimit: function(layer) { 4549 if (!isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom)) { 4550 this._zoomBoundLayers[stamp(layer)] = layer; 4551 this._updateZoomLevels(); 4552 } 4553 }, 4554 _removeZoomLimit: function(layer) { 4555 var id = stamp(layer); 4556 if (this._zoomBoundLayers[id]) { 4557 delete this._zoomBoundLayers[id]; 4558 this._updateZoomLevels(); 4559 } 4560 }, 4561 _updateZoomLevels: function() { 4562 var minZoom = Infinity, maxZoom = -Infinity, oldZoomSpan = this._getZoomSpan(); 4563 for (var i in this._zoomBoundLayers) { 4564 var options = this._zoomBoundLayers[i].options; 4565 minZoom = options.minZoom === void 0 ? minZoom : Math.min(minZoom, options.minZoom); 4566 maxZoom = options.maxZoom === void 0 ? maxZoom : Math.max(maxZoom, options.maxZoom); 4567 } 4568 this._layersMaxZoom = maxZoom === -Infinity ? void 0 : maxZoom; 4569 this._layersMinZoom = minZoom === Infinity ? void 0 : minZoom; 4570 if (oldZoomSpan !== this._getZoomSpan()) { 4571 this.fire("zoomlevelschange"); 4572 } 4573 if (this.options.maxZoom === void 0 && this._layersMaxZoom && this.getZoom() > this._layersMaxZoom) { 4574 this.setZoom(this._layersMaxZoom); 4575 } 4576 if (this.options.minZoom === void 0 && this._layersMinZoom && this.getZoom() < this._layersMinZoom) { 4577 this.setZoom(this._layersMinZoom); 4578 } 4579 } 4580 }); 4581 var LayerGroup = Layer.extend({ 4582 initialize: function(layers2, options) { 4583 setOptions(this, options); 4584 this._layers = {}; 4585 var i, len; 4586 if (layers2) { 4587 for (i = 0, len = layers2.length; i < len; i++) { 4588 this.addLayer(layers2[i]); 4589 } 4590 } 4591 }, 4592 // @method addLayer(layer: Layer): this 4593 // Adds the given layer to the group. 4594 addLayer: function(layer) { 4595 var id = this.getLayerId(layer); 4596 this._layers[id] = layer; 4597 if (this._map) { 4598 this._map.addLayer(layer); 4599 } 4600 return this; 4601 }, 4602 // @method removeLayer(layer: Layer): this 4603 // Removes the given layer from the group. 4604 // @alternative 4605 // @method removeLayer(id: Number): this 4606 // Removes the layer with the given internal ID from the group. 4607 removeLayer: function(layer) { 4608 var id = layer in this._layers ? layer : this.getLayerId(layer); 4609 if (this._map && this._layers[id]) { 4610 this._map.removeLayer(this._layers[id]); 4611 } 4612 delete this._layers[id]; 4613 return this; 4614 }, 4615 // @method hasLayer(layer: Layer): Boolean 4616 // Returns `true` if the given layer is currently added to the group. 4617 // @alternative 4618 // @method hasLayer(id: Number): Boolean 4619 // Returns `true` if the given internal ID is currently added to the group. 4620 hasLayer: function(layer) { 4621 var layerId = typeof layer === "number" ? layer : this.getLayerId(layer); 4622 return layerId in this._layers; 4623 }, 4624 // @method clearLayers(): this 4625 // Removes all the layers from the group. 4626 clearLayers: function() { 4627 return this.eachLayer(this.removeLayer, this); 4628 }, 4629 // @method invoke(methodName: String, â¦): this 4630 // Calls `methodName` on every layer contained in this group, passing any 4631 // additional parameters. Has no effect if the layers contained do not 4632 // implement `methodName`. 4633 invoke: function(methodName) { 4634 var args = Array.prototype.slice.call(arguments, 1), i, layer; 4635 for (i in this._layers) { 4636 layer = this._layers[i]; 4637 if (layer[methodName]) { 4638 layer[methodName].apply(layer, args); 4639 } 4640 } 4641 return this; 4642 }, 4643 onAdd: function(map) { 4644 this.eachLayer(map.addLayer, map); 4645 }, 4646 onRemove: function(map) { 4647 this.eachLayer(map.removeLayer, map); 4648 }, 4649 // @method eachLayer(fn: Function, context?: Object): this 4650 // Iterates over the layers of the group, optionally specifying context of the iterator function. 4651 // ```js 4652 // group.eachLayer(function (layer) { 4653 // layer.bindPopup('Hello'); 4654 // }); 4655 // ``` 4656 eachLayer: function(method, context) { 4657 for (var i in this._layers) { 4658 method.call(context, this._layers[i]); 4659 } 4660 return this; 4661 }, 4662 // @method getLayer(id: Number): Layer 4663 // Returns the layer with the given internal ID. 4664 getLayer: function(id) { 4665 return this._layers[id]; 4666 }, 4667 // @method getLayers(): Layer[] 4668 // Returns an array of all the layers added to the group. 4669 getLayers: function() { 4670 var layers2 = []; 4671 this.eachLayer(layers2.push, layers2); 4672 return layers2; 4673 }, 4674 // @method setZIndex(zIndex: Number): this 4675 // Calls `setZIndex` on every layer contained in this group, passing the z-index. 4676 setZIndex: function(zIndex) { 4677 return this.invoke("setZIndex", zIndex); 4678 }, 4679 // @method getLayerId(layer: Layer): Number 4680 // Returns the internal ID for a layer 4681 getLayerId: function(layer) { 4682 return stamp(layer); 4683 } 4684 }); 4685 var layerGroup = function(layers2, options) { 4686 return new LayerGroup(layers2, options); 4687 }; 4688 var FeatureGroup = LayerGroup.extend({ 4689 addLayer: function(layer) { 4690 if (this.hasLayer(layer)) { 4691 return this; 4692 } 4693 layer.addEventParent(this); 4694 LayerGroup.prototype.addLayer.call(this, layer); 4695 return this.fire("layeradd", { layer }); 4696 }, 4697 removeLayer: function(layer) { 4698 if (!this.hasLayer(layer)) { 4699 return this; 4700 } 4701 if (layer in this._layers) { 4702 layer = this._layers[layer]; 4703 } 4704 layer.removeEventParent(this); 4705 LayerGroup.prototype.removeLayer.call(this, layer); 4706 return this.fire("layerremove", { layer }); 4707 }, 4708 // @method setStyle(style: Path options): this 4709 // Sets the given path options to each layer of the group that has a `setStyle` method. 4710 setStyle: function(style2) { 4711 return this.invoke("setStyle", style2); 4712 }, 4713 // @method bringToFront(): this 4714 // Brings the layer group to the top of all other layers 4715 bringToFront: function() { 4716 return this.invoke("bringToFront"); 4717 }, 4718 // @method bringToBack(): this 4719 // Brings the layer group to the back of all other layers 4720 bringToBack: function() { 4721 return this.invoke("bringToBack"); 4722 }, 4723 // @method getBounds(): LatLngBounds 4724 // Returns the LatLngBounds of the Feature Group (created from bounds and coordinates of its children). 4725 getBounds: function() { 4726 var bounds = new LatLngBounds(); 4727 for (var id in this._layers) { 4728 var layer = this._layers[id]; 4729 bounds.extend(layer.getBounds ? layer.getBounds() : layer.getLatLng()); 4730 } 4731 return bounds; 4732 } 4733 }); 4734 var featureGroup = function(layers2, options) { 4735 return new FeatureGroup(layers2, options); 4736 }; 4737 var Icon = Class.extend({ 4738 /* @section 4739 * @aka Icon options 4740 * 4741 * @option iconUrl: String = null 4742 * **(required)** The URL to the icon image (absolute or relative to your script path). 4743 * 4744 * @option iconRetinaUrl: String = null 4745 * The URL to a retina sized version of the icon image (absolute or relative to your 4746 * script path). Used for Retina screen devices. 4747 * 4748 * @option iconSize: Point = null 4749 * Size of the icon image in pixels. 4750 * 4751 * @option iconAnchor: Point = null 4752 * The coordinates of the "tip" of the icon (relative to its top left corner). The icon 4753 * will be aligned so that this point is at the marker's geographical location. Centered 4754 * by default if size is specified, also can be set in CSS with negative margins. 4755 * 4756 * @option popupAnchor: Point = [0, 0] 4757 * The coordinates of the point from which popups will "open", relative to the icon anchor. 4758 * 4759 * @option tooltipAnchor: Point = [0, 0] 4760 * The coordinates of the point from which tooltips will "open", relative to the icon anchor. 4761 * 4762 * @option shadowUrl: String = null 4763 * The URL to the icon shadow image. If not specified, no shadow image will be created. 4764 * 4765 * @option shadowRetinaUrl: String = null 4766 * 4767 * @option shadowSize: Point = null 4768 * Size of the shadow image in pixels. 4769 * 4770 * @option shadowAnchor: Point = null 4771 * The coordinates of the "tip" of the shadow (relative to its top left corner) (the same 4772 * as iconAnchor if not specified). 4773 * 4774 * @option className: String = '' 4775 * A custom class name to assign to both icon and shadow images. Empty by default. 4776 */ 4777 options: { 4778 popupAnchor: [0, 0], 4779 tooltipAnchor: [0, 0], 4780 // @option crossOrigin: Boolean|String = false 4781 // Whether the crossOrigin attribute will be added to the tiles. 4782 // 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. 4783 // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values. 4784 crossOrigin: false 4785 }, 4786 initialize: function(options) { 4787 setOptions(this, options); 4788 }, 4789 // @method createIcon(oldIcon?: HTMLElement): HTMLElement 4790 // Called internally when the icon has to be shown, returns a `<img>` HTML element 4791 // styled according to the options. 4792 createIcon: function(oldIcon) { 4793 return this._createIcon("icon", oldIcon); 4794 }, 4795 // @method createShadow(oldIcon?: HTMLElement): HTMLElement 4796 // As `createIcon`, but for the shadow beneath it. 4797 createShadow: function(oldIcon) { 4798 return this._createIcon("shadow", oldIcon); 4799 }, 4800 _createIcon: function(name, oldIcon) { 4801 var src = this._getIconUrl(name); 4802 if (!src) { 4803 if (name === "icon") { 4804 throw new Error("iconUrl not set in Icon options (see the docs)."); 4805 } 4806 return null; 4807 } 4808 var img = this._createImg(src, oldIcon && oldIcon.tagName === "IMG" ? oldIcon : null); 4809 this._setIconStyles(img, name); 4810 if (this.options.crossOrigin || this.options.crossOrigin === "") { 4811 img.crossOrigin = this.options.crossOrigin === true ? "" : this.options.crossOrigin; 4812 } 4813 return img; 4814 }, 4815 _setIconStyles: function(img, name) { 4816 var options = this.options; 4817 var sizeOption = options[name + "Size"]; 4818 if (typeof sizeOption === "number") { 4819 sizeOption = [sizeOption, sizeOption]; 4820 } 4821 var size = toPoint(sizeOption), anchor = toPoint(name === "shadow" && options.shadowAnchor || options.iconAnchor || size && size.divideBy(2, true)); 4822 img.className = "leaflet-marker-" + name + " " + (options.className || ""); 4823 if (anchor) { 4824 img.style.marginLeft = -anchor.x + "px"; 4825 img.style.marginTop = -anchor.y + "px"; 4826 } 4827 if (size) { 4828 img.style.width = size.x + "px"; 4829 img.style.height = size.y + "px"; 4830 } 4831 }, 4832 _createImg: function(src, el) { 4833 el = el || document.createElement("img"); 4834 el.src = src; 4835 return el; 4836 }, 4837 _getIconUrl: function(name) { 4838 return Browser.retina && this.options[name + "RetinaUrl"] || this.options[name + "Url"]; 4839 } 4840 }); 4841 function icon(options) { 4842 return new Icon(options); 4843 } 4844 var IconDefault = Icon.extend({ 4845 options: { 4846 iconUrl: "marker-icon.png", 4847 iconRetinaUrl: "marker-icon-2x.png", 4848 shadowUrl: "marker-shadow.png", 4849 iconSize: [25, 41], 4850 iconAnchor: [12, 41], 4851 popupAnchor: [1, -34], 4852 tooltipAnchor: [16, -28], 4853 shadowSize: [41, 41] 4854 }, 4855 _getIconUrl: function(name) { 4856 if (typeof IconDefault.imagePath !== "string") { 4857 IconDefault.imagePath = this._detectIconPath(); 4858 } 4859 return (this.options.imagePath || IconDefault.imagePath) + Icon.prototype._getIconUrl.call(this, name); 4860 }, 4861 _stripUrl: function(path) { 4862 var strip = function(str, re, idx) { 4863 var match = re.exec(str); 4864 return match && match[idx]; 4865 }; 4866 path = strip(path, /^url\((['"])?(.+)\1\)$/, 2); 4867 return path && strip(path, /^(.*)marker-icon\.png$/, 1); 4868 }, 4869 _detectIconPath: function() { 4870 var el = create$1("div", "leaflet-default-icon-path", document.body); 4871 var path = getStyle(el, "background-image") || getStyle(el, "backgroundImage"); 4872 document.body.removeChild(el); 4873 path = this._stripUrl(path); 4874 if (path) { 4875 return path; 4876 } 4877 var link = document.querySelector('link[href$="leaflet.css"]'); 4878 if (!link) { 4879 return ""; 4880 } 4881 return link.href.substring(0, link.href.length - "leaflet.css".length - 1); 4882 } 4883 }); 4884 var MarkerDrag = Handler.extend({ 4885 initialize: function(marker2) { 4886 this._marker = marker2; 4887 }, 4888 addHooks: function() { 4889 var icon2 = this._marker._icon; 4890 if (!this._draggable) { 4891 this._draggable = new Draggable(icon2, icon2, true); 4892 } 4893 this._draggable.on({ 4894 dragstart: this._onDragStart, 4895 predrag: this._onPreDrag, 4896 drag: this._onDrag, 4897 dragend: this._onDragEnd 4898 }, this).enable(); 4899 addClass(icon2, "leaflet-marker-draggable"); 4900 }, 4901 removeHooks: function() { 4902 this._draggable.off({ 4903 dragstart: this._onDragStart, 4904 predrag: this._onPreDrag, 4905 drag: this._onDrag, 4906 dragend: this._onDragEnd 4907 }, this).disable(); 4908 if (this._marker._icon) { 4909 removeClass(this._marker._icon, "leaflet-marker-draggable"); 4910 } 4911 }, 4912 moved: function() { 4913 return this._draggable && this._draggable._moved; 4914 }, 4915 _adjustPan: function(e) { 4916 var marker2 = this._marker, map = marker2._map, speed = this._marker.options.autoPanSpeed, padding = this._marker.options.autoPanPadding, iconPos = getPosition(marker2._icon), bounds = map.getPixelBounds(), origin = map.getPixelOrigin(); 4917 var panBounds = toBounds( 4918 bounds.min._subtract(origin).add(padding), 4919 bounds.max._subtract(origin).subtract(padding) 4920 ); 4921 if (!panBounds.contains(iconPos)) { 4922 var movement = toPoint( 4923 (Math.max(panBounds.max.x, iconPos.x) - panBounds.max.x) / (bounds.max.x - panBounds.max.x) - (Math.min(panBounds.min.x, iconPos.x) - panBounds.min.x) / (bounds.min.x - panBounds.min.x), 4924 (Math.max(panBounds.max.y, iconPos.y) - panBounds.max.y) / (bounds.max.y - panBounds.max.y) - (Math.min(panBounds.min.y, iconPos.y) - panBounds.min.y) / (bounds.min.y - panBounds.min.y) 4925 ).multiplyBy(speed); 4926 map.panBy(movement, { animate: false }); 4927 this._draggable._newPos._add(movement); 4928 this._draggable._startPos._add(movement); 4929 setPosition(marker2._icon, this._draggable._newPos); 4930 this._onDrag(e); 4931 this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e)); 4932 } 4933 }, 4934 _onDragStart: function() { 4935 this._oldLatLng = this._marker.getLatLng(); 4936 this._marker.closePopup && this._marker.closePopup(); 4937 this._marker.fire("movestart").fire("dragstart"); 4938 }, 4939 _onPreDrag: function(e) { 4940 if (this._marker.options.autoPan) { 4941 cancelAnimFrame(this._panRequest); 4942 this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e)); 4943 } 4944 }, 4945 _onDrag: function(e) { 4946 var marker2 = this._marker, shadow = marker2._shadow, iconPos = getPosition(marker2._icon), latlng = marker2._map.layerPointToLatLng(iconPos); 4947 if (shadow) { 4948 setPosition(shadow, iconPos); 4949 } 4950 marker2._latlng = latlng; 4951 e.latlng = latlng; 4952 e.oldLatLng = this._oldLatLng; 4953 marker2.fire("move", e).fire("drag", e); 4954 }, 4955 _onDragEnd: function(e) { 4956 cancelAnimFrame(this._panRequest); 4957 delete this._oldLatLng; 4958 this._marker.fire("moveend").fire("dragend", e); 4959 } 4960 }); 4961 var Marker = Layer.extend({ 4962 // @section 4963 // @aka Marker options 4964 options: { 4965 // @option icon: Icon = * 4966 // Icon instance to use for rendering the marker. 4967 // See [Icon documentation](#L.Icon) for details on how to customize the marker icon. 4968 // If not specified, a common instance of `L.Icon.Default` is used. 4969 icon: new IconDefault(), 4970 // Option inherited from "Interactive layer" abstract class 4971 interactive: true, 4972 // @option keyboard: Boolean = true 4973 // Whether the marker can be tabbed to with a keyboard and clicked by pressing enter. 4974 keyboard: true, 4975 // @option title: String = '' 4976 // Text for the browser tooltip that appear on marker hover (no tooltip by default). 4977 // [Useful for accessibility](https://leafletjs.com/examples/accessibility/#markers-must-be-labelled). 4978 title: "", 4979 // @option alt: String = 'Marker' 4980 // Text for the `alt` attribute of the icon image. 4981 // [Useful for accessibility](https://leafletjs.com/examples/accessibility/#markers-must-be-labelled). 4982 alt: "Marker", 4983 // @option zIndexOffset: Number = 0 4984 // 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). 4985 zIndexOffset: 0, 4986 // @option opacity: Number = 1.0 4987 // The opacity of the marker. 4988 opacity: 1, 4989 // @option riseOnHover: Boolean = false 4990 // If `true`, the marker will get on top of others when you hover the mouse over it. 4991 riseOnHover: false, 4992 // @option riseOffset: Number = 250 4993 // The z-index offset used for the `riseOnHover` feature. 4994 riseOffset: 250, 4995 // @option pane: String = 'markerPane' 4996 // `Map pane` where the markers icon will be added. 4997 pane: "markerPane", 4998 // @option shadowPane: String = 'shadowPane' 4999 // `Map pane` where the markers shadow will be added. 5000 shadowPane: "shadowPane", 5001 // @option bubblingMouseEvents: Boolean = false 5002 // When `true`, a mouse event on this marker will trigger the same event on the map 5003 // (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used). 5004 bubblingMouseEvents: false, 5005 // @option autoPanOnFocus: Boolean = true 5006 // When `true`, the map will pan whenever the marker is focused (via 5007 // e.g. pressing `tab` on the keyboard) to ensure the marker is 5008 // visible within the map's bounds 5009 autoPanOnFocus: true, 5010 // @section Draggable marker options 5011 // @option draggable: Boolean = false 5012 // Whether the marker is draggable with mouse/touch or not. 5013 draggable: false, 5014 // @option autoPan: Boolean = false 5015 // Whether to pan the map when dragging this marker near its edge or not. 5016 autoPan: false, 5017 // @option autoPanPadding: Point = Point(50, 50) 5018 // Distance (in pixels to the left/right and to the top/bottom) of the 5019 // map edge to start panning the map. 5020 autoPanPadding: [50, 50], 5021 // @option autoPanSpeed: Number = 10 5022 // Number of pixels the map should pan by. 5023 autoPanSpeed: 10 5024 }, 5025 /* @section 5026 * 5027 * In addition to [shared layer methods](#Layer) like `addTo()` and `remove()` and [popup methods](#Popup) like bindPopup() you can also use the following methods: 5028 */ 5029 initialize: function(latlng, options) { 5030 setOptions(this, options); 5031 this._latlng = toLatLng(latlng); 5032 }, 5033 onAdd: function(map) { 5034 this._zoomAnimated = this._zoomAnimated && map.options.markerZoomAnimation; 5035 if (this._zoomAnimated) { 5036 map.on("zoomanim", this._animateZoom, this); 5037 } 5038 this._initIcon(); 5039 this.update(); 5040 }, 5041 onRemove: function(map) { 5042 if (this.dragging && this.dragging.enabled()) { 5043 this.options.draggable = true; 5044 this.dragging.removeHooks(); 5045 } 5046 delete this.dragging; 5047 if (this._zoomAnimated) { 5048 map.off("zoomanim", this._animateZoom, this); 5049 } 5050 this._removeIcon(); 5051 this._removeShadow(); 5052 }, 5053 getEvents: function() { 5054 return { 5055 zoom: this.update, 5056 viewreset: this.update 5057 }; 5058 }, 5059 // @method getLatLng: LatLng 5060 // Returns the current geographical position of the marker. 5061 getLatLng: function() { 5062 return this._latlng; 5063 }, 5064 // @method setLatLng(latlng: LatLng): this 5065 // Changes the marker position to the given point. 5066 setLatLng: function(latlng) { 5067 var oldLatLng = this._latlng; 5068 this._latlng = toLatLng(latlng); 5069 this.update(); 5070 return this.fire("move", { oldLatLng, latlng: this._latlng }); 5071 }, 5072 // @method setZIndexOffset(offset: Number): this 5073 // Changes the [zIndex offset](#marker-zindexoffset) of the marker. 5074 setZIndexOffset: function(offset2) { 5075 this.options.zIndexOffset = offset2; 5076 return this.update(); 5077 }, 5078 // @method getIcon: Icon 5079 // Returns the current icon used by the marker 5080 getIcon: function() { 5081 return this.options.icon; 5082 }, 5083 // @method setIcon(icon: Icon): this 5084 // Changes the marker icon. 5085 setIcon: function(icon2) { 5086 this.options.icon = icon2; 5087 if (this._map) { 5088 this._initIcon(); 5089 this.update(); 5090 } 5091 if (this._popup) { 5092 this.bindPopup(this._popup, this._popup.options); 5093 } 5094 return this; 5095 }, 5096 getElement: function() { 5097 return this._icon; 5098 }, 5099 update: function() { 5100 if (this._icon && this._map) { 5101 var pos = this._map.latLngToLayerPoint(this._latlng).round(); 5102 this._setPos(pos); 5103 } 5104 return this; 5105 }, 5106 _initIcon: function() { 5107 var options = this.options, classToAdd = "leaflet-zoom-" + (this._zoomAnimated ? "animated" : "hide"); 5108 var icon2 = options.icon.createIcon(this._icon), addIcon = false; 5109 if (icon2 !== this._icon) { 5110 if (this._icon) { 5111 this._removeIcon(); 5112 } 5113 addIcon = true; 5114 if (options.title) { 5115 icon2.title = options.title; 5116 } 5117 if (icon2.tagName === "IMG") { 5118 icon2.alt = options.alt || ""; 5119 } 5120 } 5121 addClass(icon2, classToAdd); 5122 if (options.keyboard) { 5123 icon2.tabIndex = "0"; 5124 icon2.setAttribute("role", "button"); 5125 } 5126 this._icon = icon2; 5127 if (options.riseOnHover) { 5128 this.on({ 5129 mouseover: this._bringToFront, 5130 mouseout: this._resetZIndex 5131 }); 5132 } 5133 if (this.options.autoPanOnFocus) { 5134 on(icon2, "focus", this._panOnFocus, this); 5135 } 5136 var newShadow = options.icon.createShadow(this._shadow), addShadow = false; 5137 if (newShadow !== this._shadow) { 5138 this._removeShadow(); 5139 addShadow = true; 5140 } 5141 if (newShadow) { 5142 addClass(newShadow, classToAdd); 5143 newShadow.alt = ""; 5144 } 5145 this._shadow = newShadow; 5146 if (options.opacity < 1) { 5147 this._updateOpacity(); 5148 } 5149 if (addIcon) { 5150 this.getPane().appendChild(this._icon); 5151 } 5152 this._initInteraction(); 5153 if (newShadow && addShadow) { 5154 this.getPane(options.shadowPane).appendChild(this._shadow); 5155 } 5156 }, 5157 _removeIcon: function() { 5158 if (this.options.riseOnHover) { 5159 this.off({ 5160 mouseover: this._bringToFront, 5161 mouseout: this._resetZIndex 5162 }); 5163 } 5164 if (this.options.autoPanOnFocus) { 5165 off(this._icon, "focus", this._panOnFocus, this); 5166 } 5167 remove(this._icon); 5168 this.removeInteractiveTarget(this._icon); 5169 this._icon = null; 5170 }, 5171 _removeShadow: function() { 5172 if (this._shadow) { 5173 remove(this._shadow); 5174 } 5175 this._shadow = null; 5176 }, 5177 _setPos: function(pos) { 5178 if (this._icon) { 5179 setPosition(this._icon, pos); 5180 } 5181 if (this._shadow) { 5182 setPosition(this._shadow, pos); 5183 } 5184 this._zIndex = pos.y + this.options.zIndexOffset; 5185 this._resetZIndex(); 5186 }, 5187 _updateZIndex: function(offset2) { 5188 if (this._icon) { 5189 this._icon.style.zIndex = this._zIndex + offset2; 5190 } 5191 }, 5192 _animateZoom: function(opt) { 5193 var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round(); 5194 this._setPos(pos); 5195 }, 5196 _initInteraction: function() { 5197 if (!this.options.interactive) { 5198 return; 5199 } 5200 addClass(this._icon, "leaflet-interactive"); 5201 this.addInteractiveTarget(this._icon); 5202 if (MarkerDrag) { 5203 var draggable = this.options.draggable; 5204 if (this.dragging) { 5205 draggable = this.dragging.enabled(); 5206 this.dragging.disable(); 5207 } 5208 this.dragging = new MarkerDrag(this); 5209 if (draggable) { 5210 this.dragging.enable(); 5211 } 5212 } 5213 }, 5214 // @method setOpacity(opacity: Number): this 5215 // Changes the opacity of the marker. 5216 setOpacity: function(opacity) { 5217 this.options.opacity = opacity; 5218 if (this._map) { 5219 this._updateOpacity(); 5220 } 5221 return this; 5222 }, 5223 _updateOpacity: function() { 5224 var opacity = this.options.opacity; 5225 if (this._icon) { 5226 setOpacity(this._icon, opacity); 5227 } 5228 if (this._shadow) { 5229 setOpacity(this._shadow, opacity); 5230 } 5231 }, 5232 _bringToFront: function() { 5233 this._updateZIndex(this.options.riseOffset); 5234 }, 5235 _resetZIndex: function() { 5236 this._updateZIndex(0); 5237 }, 5238 _panOnFocus: function() { 5239 var map = this._map; 5240 if (!map) { 5241 return; 5242 } 5243 var iconOpts = this.options.icon.options; 5244 var size = iconOpts.iconSize ? toPoint(iconOpts.iconSize) : toPoint(0, 0); 5245 var anchor = iconOpts.iconAnchor ? toPoint(iconOpts.iconAnchor) : toPoint(0, 0); 5246 map.panInside(this._latlng, { 5247 paddingTopLeft: anchor, 5248 paddingBottomRight: size.subtract(anchor) 5249 }); 5250 }, 5251 _getPopupAnchor: function() { 5252 return this.options.icon.options.popupAnchor; 5253 }, 5254 _getTooltipAnchor: function() { 5255 return this.options.icon.options.tooltipAnchor; 5256 } 5257 }); 5258 function marker(latlng, options) { 5259 return new Marker(latlng, options); 5260 } 5261 var Path = Layer.extend({ 5262 // @section 5263 // @aka Path options 5264 options: { 5265 // @option stroke: Boolean = true 5266 // Whether to draw stroke along the path. Set it to `false` to disable borders on polygons or circles. 5267 stroke: true, 5268 // @option color: String = '#3388ff' 5269 // Stroke color 5270 color: "#3388ff", 5271 // @option weight: Number = 3 5272 // Stroke width in pixels 5273 weight: 3, 5274 // @option opacity: Number = 1.0 5275 // Stroke opacity 5276 opacity: 1, 5277 // @option lineCap: String= 'round' 5278 // A string that defines [shape to be used at the end](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linecap) of the stroke. 5279 lineCap: "round", 5280 // @option lineJoin: String = 'round' 5281 // A string that defines [shape to be used at the corners](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linejoin) of the stroke. 5282 lineJoin: "round", 5283 // @option dashArray: String = null 5284 // 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). 5285 dashArray: null, 5286 // @option dashOffset: String = null 5287 // 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). 5288 dashOffset: null, 5289 // @option fill: Boolean = depends 5290 // Whether to fill the path with color. Set it to `false` to disable filling on polygons or circles. 5291 fill: false, 5292 // @option fillColor: String = * 5293 // Fill color. Defaults to the value of the [`color`](#path-color) option 5294 fillColor: null, 5295 // @option fillOpacity: Number = 0.2 5296 // Fill opacity. 5297 fillOpacity: 0.2, 5298 // @option fillRule: String = 'evenodd' 5299 // A string that defines [how the inside of a shape](https://developer.mozilla.org/docs/Web/SVG/Attribute/fill-rule) is determined. 5300 fillRule: "evenodd", 5301 // className: '', 5302 // Option inherited from "Interactive layer" abstract class 5303 interactive: true, 5304 // @option bubblingMouseEvents: Boolean = true 5305 // When `true`, a mouse event on this path will trigger the same event on the map 5306 // (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used). 5307 bubblingMouseEvents: true 5308 }, 5309 beforeAdd: function(map) { 5310 this._renderer = map.getRenderer(this); 5311 }, 5312 onAdd: function() { 5313 this._renderer._initPath(this); 5314 this._reset(); 5315 this._renderer._addPath(this); 5316 }, 5317 onRemove: function() { 5318 this._renderer._removePath(this); 5319 }, 5320 // @method redraw(): this 5321 // Redraws the layer. Sometimes useful after you changed the coordinates that the path uses. 5322 redraw: function() { 5323 if (this._map) { 5324 this._renderer._updatePath(this); 5325 } 5326 return this; 5327 }, 5328 // @method setStyle(style: Path options): this 5329 // Changes the appearance of a Path based on the options in the `Path options` object. 5330 setStyle: function(style2) { 5331 setOptions(this, style2); 5332 if (this._renderer) { 5333 this._renderer._updateStyle(this); 5334 if (this.options.stroke && style2 && Object.prototype.hasOwnProperty.call(style2, "weight")) { 5335 this._updateBounds(); 5336 } 5337 } 5338 return this; 5339 }, 5340 // @method bringToFront(): this 5341 // Brings the layer to the top of all path layers. 5342 bringToFront: function() { 5343 if (this._renderer) { 5344 this._renderer._bringToFront(this); 5345 } 5346 return this; 5347 }, 5348 // @method bringToBack(): this 5349 // Brings the layer to the bottom of all path layers. 5350 bringToBack: function() { 5351 if (this._renderer) { 5352 this._renderer._bringToBack(this); 5353 } 5354 return this; 5355 }, 5356 getElement: function() { 5357 return this._path; 5358 }, 5359 _reset: function() { 5360 this._project(); 5361 this._update(); 5362 }, 5363 _clickTolerance: function() { 5364 return (this.options.stroke ? this.options.weight / 2 : 0) + (this._renderer.options.tolerance || 0); 5365 } 5366 }); 5367 var CircleMarker = Path.extend({ 5368 // @section 5369 // @aka CircleMarker options 5370 options: { 5371 fill: true, 5372 // @option radius: Number = 10 5373 // Radius of the circle marker, in pixels 5374 radius: 10 5375 }, 5376 initialize: function(latlng, options) { 5377 setOptions(this, options); 5378 this._latlng = toLatLng(latlng); 5379 this._radius = this.options.radius; 5380 }, 5381 // @method setLatLng(latLng: LatLng): this 5382 // Sets the position of a circle marker to a new location. 5383 setLatLng: function(latlng) { 5384 var oldLatLng = this._latlng; 5385 this._latlng = toLatLng(latlng); 5386 this.redraw(); 5387 return this.fire("move", { oldLatLng, latlng: this._latlng }); 5388 }, 5389 // @method getLatLng(): LatLng 5390 // Returns the current geographical position of the circle marker 5391 getLatLng: function() { 5392 return this._latlng; 5393 }, 5394 // @method setRadius(radius: Number): this 5395 // Sets the radius of a circle marker. Units are in pixels. 5396 setRadius: function(radius) { 5397 this.options.radius = this._radius = radius; 5398 return this.redraw(); 5399 }, 5400 // @method getRadius(): Number 5401 // Returns the current radius of the circle 5402 getRadius: function() { 5403 return this._radius; 5404 }, 5405 setStyle: function(options) { 5406 var radius = options && options.radius || this._radius; 5407 Path.prototype.setStyle.call(this, options); 5408 this.setRadius(radius); 5409 return this; 5410 }, 5411 _project: function() { 5412 this._point = this._map.latLngToLayerPoint(this._latlng); 5413 this._updateBounds(); 5414 }, 5415 _updateBounds: function() { 5416 var r = this._radius, r2 = this._radiusY || r, w = this._clickTolerance(), p = [r + w, r2 + w]; 5417 this._pxBounds = new Bounds(this._point.subtract(p), this._point.add(p)); 5418 }, 5419 _update: function() { 5420 if (this._map) { 5421 this._updatePath(); 5422 } 5423 }, 5424 _updatePath: function() { 5425 this._renderer._updateCircle(this); 5426 }, 5427 _empty: function() { 5428 return this._radius && !this._renderer._bounds.intersects(this._pxBounds); 5429 }, 5430 // Needed by the `Canvas` renderer for interactivity 5431 _containsPoint: function(p) { 5432 return p.distanceTo(this._point) <= this._radius + this._clickTolerance(); 5433 } 5434 }); 5435 function circleMarker(latlng, options) { 5436 return new CircleMarker(latlng, options); 5437 } 5438 var Circle = CircleMarker.extend({ 5439 initialize: function(latlng, options, legacyOptions) { 5440 if (typeof options === "number") { 5441 options = extend({}, legacyOptions, { radius: options }); 5442 } 5443 setOptions(this, options); 5444 this._latlng = toLatLng(latlng); 5445 if (isNaN(this.options.radius)) { 5446 throw new Error("Circle radius cannot be NaN"); 5447 } 5448 this._mRadius = this.options.radius; 5449 }, 5450 // @method setRadius(radius: Number): this 5451 // Sets the radius of a circle. Units are in meters. 5452 setRadius: function(radius) { 5453 this._mRadius = radius; 5454 return this.redraw(); 5455 }, 5456 // @method getRadius(): Number 5457 // Returns the current radius of a circle. Units are in meters. 5458 getRadius: function() { 5459 return this._mRadius; 5460 }, 5461 // @method getBounds(): LatLngBounds 5462 // Returns the `LatLngBounds` of the path. 5463 getBounds: function() { 5464 var half = [this._radius, this._radiusY || this._radius]; 5465 return new LatLngBounds( 5466 this._map.layerPointToLatLng(this._point.subtract(half)), 5467 this._map.layerPointToLatLng(this._point.add(half)) 5468 ); 5469 }, 5470 setStyle: Path.prototype.setStyle, 5471 _project: function() { 5472 var lng = this._latlng.lng, lat = this._latlng.lat, map = this._map, crs = map.options.crs; 5473 if (crs.distance === Earth.distance) { 5474 var d = Math.PI / 180, latR = this._mRadius / Earth.R / d, top2 = map.project([lat + latR, lng]), bottom2 = map.project([lat - latR, lng]), p = top2.add(bottom2).divideBy(2), lat2 = map.unproject(p).lat, lngR = Math.acos((Math.cos(latR * d) - Math.sin(lat * d) * Math.sin(lat2 * d)) / (Math.cos(lat * d) * Math.cos(lat2 * d))) / d; 5475 if (isNaN(lngR) || lngR === 0) { 5476 lngR = latR / Math.cos(Math.PI / 180 * lat); 5477 } 5478 this._point = p.subtract(map.getPixelOrigin()); 5479 this._radius = isNaN(lngR) ? 0 : p.x - map.project([lat2, lng - lngR]).x; 5480 this._radiusY = p.y - top2.y; 5481 } else { 5482 var latlng2 = crs.unproject(crs.project(this._latlng).subtract([this._mRadius, 0])); 5483 this._point = map.latLngToLayerPoint(this._latlng); 5484 this._radius = this._point.x - map.latLngToLayerPoint(latlng2).x; 5485 } 5486 this._updateBounds(); 5487 } 5488 }); 5489 function circle(latlng, options, legacyOptions) { 5490 return new Circle(latlng, options, legacyOptions); 5491 } 5492 var Polyline = Path.extend({ 5493 // @section 5494 // @aka Polyline options 5495 options: { 5496 // @option smoothFactor: Number = 1.0 5497 // How much to simplify the polyline on each zoom level. More means 5498 // better performance and smoother look, and less means more accurate representation. 5499 smoothFactor: 1, 5500 // @option noClip: Boolean = false 5501 // Disable polyline clipping. 5502 noClip: false 5503 }, 5504 initialize: function(latlngs, options) { 5505 setOptions(this, options); 5506 this._setLatLngs(latlngs); 5507 }, 5508 // @method getLatLngs(): LatLng[] 5509 // Returns an array of the points in the path, or nested arrays of points in case of multi-polyline. 5510 getLatLngs: function() { 5511 return this._latlngs; 5512 }, 5513 // @method setLatLngs(latlngs: LatLng[]): this 5514 // Replaces all the points in the polyline with the given array of geographical points. 5515 setLatLngs: function(latlngs) { 5516 this._setLatLngs(latlngs); 5517 return this.redraw(); 5518 }, 5519 // @method isEmpty(): Boolean 5520 // Returns `true` if the Polyline has no LatLngs. 5521 isEmpty: function() { 5522 return !this._latlngs.length; 5523 }, 5524 // @method closestLayerPoint(p: Point): Point 5525 // Returns the point closest to `p` on the Polyline. 5526 closestLayerPoint: function(p) { 5527 var minDistance = Infinity, minPoint = null, closest = _sqClosestPointOnSegment, p1, p2; 5528 for (var j = 0, jLen = this._parts.length; j < jLen; j++) { 5529 var points = this._parts[j]; 5530 for (var i = 1, len = points.length; i < len; i++) { 5531 p1 = points[i - 1]; 5532 p2 = points[i]; 5533 var sqDist = closest(p, p1, p2, true); 5534 if (sqDist < minDistance) { 5535 minDistance = sqDist; 5536 minPoint = closest(p, p1, p2); 5537 } 5538 } 5539 } 5540 if (minPoint) { 5541 minPoint.distance = Math.sqrt(minDistance); 5542 } 5543 return minPoint; 5544 }, 5545 // @method getCenter(): LatLng 5546 // Returns the center ([centroid](https://en.wikipedia.org/wiki/Centroid)) of the polyline. 5547 getCenter: function() { 5548 if (!this._map) { 5549 throw new Error("Must add layer to map before using getCenter()"); 5550 } 5551 return polylineCenter(this._defaultShape(), this._map.options.crs); 5552 }, 5553 // @method getBounds(): LatLngBounds 5554 // Returns the `LatLngBounds` of the path. 5555 getBounds: function() { 5556 return this._bounds; 5557 }, 5558 // @method addLatLng(latlng: LatLng, latlngs?: LatLng[]): this 5559 // Adds a given point to the polyline. By default, adds to the first ring of 5560 // the polyline in case of a multi-polyline, but can be overridden by passing 5561 // a specific ring as a LatLng array (that you can earlier access with [`getLatLngs`](#polyline-getlatlngs)). 5562 addLatLng: function(latlng, latlngs) { 5563 latlngs = latlngs || this._defaultShape(); 5564 latlng = toLatLng(latlng); 5565 latlngs.push(latlng); 5566 this._bounds.extend(latlng); 5567 return this.redraw(); 5568 }, 5569 _setLatLngs: function(latlngs) { 5570 this._bounds = new LatLngBounds(); 5571 this._latlngs = this._convertLatLngs(latlngs); 5572 }, 5573 _defaultShape: function() { 5574 return isFlat(this._latlngs) ? this._latlngs : this._latlngs[0]; 5575 }, 5576 // recursively convert latlngs input into actual LatLng instances; calculate bounds along the way 5577 _convertLatLngs: function(latlngs) { 5578 var result = [], flat = isFlat(latlngs); 5579 for (var i = 0, len = latlngs.length; i < len; i++) { 5580 if (flat) { 5581 result[i] = toLatLng(latlngs[i]); 5582 this._bounds.extend(result[i]); 5583 } else { 5584 result[i] = this._convertLatLngs(latlngs[i]); 5585 } 5586 } 5587 return result; 5588 }, 5589 _project: function() { 5590 var pxBounds = new Bounds(); 5591 this._rings = []; 5592 this._projectLatlngs(this._latlngs, this._rings, pxBounds); 5593 if (this._bounds.isValid() && pxBounds.isValid()) { 5594 this._rawPxBounds = pxBounds; 5595 this._updateBounds(); 5596 } 5597 }, 5598 _updateBounds: function() { 5599 var w = this._clickTolerance(), p = new Point(w, w); 5600 if (!this._rawPxBounds) { 5601 return; 5602 } 5603 this._pxBounds = new Bounds([ 5604 this._rawPxBounds.min.subtract(p), 5605 this._rawPxBounds.max.add(p) 5606 ]); 5607 }, 5608 // recursively turns latlngs into a set of rings with projected coordinates 5609 _projectLatlngs: function(latlngs, result, projectedBounds) { 5610 var flat = latlngs[0] instanceof LatLng, len = latlngs.length, i, ring; 5611 if (flat) { 5612 ring = []; 5613 for (i = 0; i < len; i++) { 5614 ring[i] = this._map.latLngToLayerPoint(latlngs[i]); 5615 projectedBounds.extend(ring[i]); 5616 } 5617 result.push(ring); 5618 } else { 5619 for (i = 0; i < len; i++) { 5620 this._projectLatlngs(latlngs[i], result, projectedBounds); 5621 } 5622 } 5623 }, 5624 // clip polyline by renderer bounds so that we have less to render for performance 5625 _clipPoints: function() { 5626 var bounds = this._renderer._bounds; 5627 this._parts = []; 5628 if (!this._pxBounds || !this._pxBounds.intersects(bounds)) { 5629 return; 5630 } 5631 if (this.options.noClip) { 5632 this._parts = this._rings; 5633 return; 5634 } 5635 var parts = this._parts, i, j, k, len, len2, segment, points; 5636 for (i = 0, k = 0, len = this._rings.length; i < len; i++) { 5637 points = this._rings[i]; 5638 for (j = 0, len2 = points.length; j < len2 - 1; j++) { 5639 segment = clipSegment(points[j], points[j + 1], bounds, j, true); 5640 if (!segment) { 5641 continue; 5642 } 5643 parts[k] = parts[k] || []; 5644 parts[k].push(segment[0]); 5645 if (segment[1] !== points[j + 1] || j === len2 - 2) { 5646 parts[k].push(segment[1]); 5647 k++; 5648 } 5649 } 5650 } 5651 }, 5652 // simplify each clipped part of the polyline for performance 5653 _simplifyPoints: function() { 5654 var parts = this._parts, tolerance = this.options.smoothFactor; 5655 for (var i = 0, len = parts.length; i < len; i++) { 5656 parts[i] = simplify(parts[i], tolerance); 5657 } 5658 }, 5659 _update: function() { 5660 if (!this._map) { 5661 return; 5662 } 5663 this._clipPoints(); 5664 this._simplifyPoints(); 5665 this._updatePath(); 5666 }, 5667 _updatePath: function() { 5668 this._renderer._updatePoly(this); 5669 }, 5670 // Needed by the `Canvas` renderer for interactivity 5671 _containsPoint: function(p, closed) { 5672 var i, j, k, len, len2, part, w = this._clickTolerance(); 5673 if (!this._pxBounds || !this._pxBounds.contains(p)) { 5674 return false; 5675 } 5676 for (i = 0, len = this._parts.length; i < len; i++) { 5677 part = this._parts[i]; 5678 for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) { 5679 if (!closed && j === 0) { 5680 continue; 5681 } 5682 if (pointToSegmentDistance(p, part[k], part[j]) <= w) { 5683 return true; 5684 } 5685 } 5686 } 5687 return false; 5688 } 5689 }); 5690 function polyline(latlngs, options) { 5691 return new Polyline(latlngs, options); 5692 } 5693 Polyline._flat = _flat; 5694 var Polygon = Polyline.extend({ 5695 options: { 5696 fill: true 5697 }, 5698 isEmpty: function() { 5699 return !this._latlngs.length || !this._latlngs[0].length; 5700 }, 5701 // @method getCenter(): LatLng 5702 // Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the Polygon. 5703 getCenter: function() { 5704 if (!this._map) { 5705 throw new Error("Must add layer to map before using getCenter()"); 5706 } 5707 return polygonCenter(this._defaultShape(), this._map.options.crs); 5708 }, 5709 _convertLatLngs: function(latlngs) { 5710 var result = Polyline.prototype._convertLatLngs.call(this, latlngs), len = result.length; 5711 if (len >= 2 && result[0] instanceof LatLng && result[0].equals(result[len - 1])) { 5712 result.pop(); 5713 } 5714 return result; 5715 }, 5716 _setLatLngs: function(latlngs) { 5717 Polyline.prototype._setLatLngs.call(this, latlngs); 5718 if (isFlat(this._latlngs)) { 5719 this._latlngs = [this._latlngs]; 5720 } 5721 }, 5722 _defaultShape: function() { 5723 return isFlat(this._latlngs[0]) ? this._latlngs[0] : this._latlngs[0][0]; 5724 }, 5725 _clipPoints: function() { 5726 var bounds = this._renderer._bounds, w = this.options.weight, p = new Point(w, w); 5727 bounds = new Bounds(bounds.min.subtract(p), bounds.max.add(p)); 5728 this._parts = []; 5729 if (!this._pxBounds || !this._pxBounds.intersects(bounds)) { 5730 return; 5731 } 5732 if (this.options.noClip) { 5733 this._parts = this._rings; 5734 return; 5735 } 5736 for (var i = 0, len = this._rings.length, clipped; i < len; i++) { 5737 clipped = clipPolygon(this._rings[i], bounds, true); 5738 if (clipped.length) { 5739 this._parts.push(clipped); 5740 } 5741 } 5742 }, 5743 _updatePath: function() { 5744 this._renderer._updatePoly(this, true); 5745 }, 5746 // Needed by the `Canvas` renderer for interactivity 5747 _containsPoint: function(p) { 5748 var inside = false, part, p1, p2, i, j, k, len, len2; 5749 if (!this._pxBounds || !this._pxBounds.contains(p)) { 5750 return false; 5751 } 5752 for (i = 0, len = this._parts.length; i < len; i++) { 5753 part = this._parts[i]; 5754 for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) { 5755 p1 = part[j]; 5756 p2 = part[k]; 5757 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) { 5758 inside = !inside; 5759 } 5760 } 5761 } 5762 return inside || Polyline.prototype._containsPoint.call(this, p, true); 5763 } 5764 }); 5765 function polygon(latlngs, options) { 5766 return new Polygon(latlngs, options); 5767 } 5768 var GeoJSON = FeatureGroup.extend({ 5769 /* @section 5770 * @aka GeoJSON options 5771 * 5772 * @option pointToLayer: Function = * 5773 * A `Function` defining how GeoJSON points spawn Leaflet layers. It is internally 5774 * called when data is added, passing the GeoJSON point feature and its `LatLng`. 5775 * The default is to spawn a default `Marker`: 5776 * ```js 5777 * function(geoJsonPoint, latlng) { 5778 * return L.marker(latlng); 5779 * } 5780 * ``` 5781 * 5782 * @option style: Function = * 5783 * A `Function` defining the `Path options` for styling GeoJSON lines and polygons, 5784 * called internally when data is added. 5785 * The default value is to not override any defaults: 5786 * ```js 5787 * function (geoJsonFeature) { 5788 * return {} 5789 * } 5790 * ``` 5791 * 5792 * @option onEachFeature: Function = * 5793 * A `Function` that will be called once for each created `Feature`, after it has 5794 * been created and styled. Useful for attaching events and popups to features. 5795 * The default is to do nothing with the newly created layers: 5796 * ```js 5797 * function (feature, layer) {} 5798 * ``` 5799 * 5800 * @option filter: Function = * 5801 * A `Function` that will be used to decide whether to include a feature or not. 5802 * The default is to include all features: 5803 * ```js 5804 * function (geoJsonFeature) { 5805 * return true; 5806 * } 5807 * ``` 5808 * Note: dynamically changing the `filter` option will have effect only on newly 5809 * added data. It will _not_ re-evaluate already included features. 5810 * 5811 * @option coordsToLatLng: Function = * 5812 * A `Function` that will be used for converting GeoJSON coordinates to `LatLng`s. 5813 * The default is the `coordsToLatLng` static method. 5814 * 5815 * @option markersInheritOptions: Boolean = false 5816 * Whether default Markers for "Point" type Features inherit from group options. 5817 */ 5818 initialize: function(geojson, options) { 5819 setOptions(this, options); 5820 this._layers = {}; 5821 if (geojson) { 5822 this.addData(geojson); 5823 } 5824 }, 5825 // @method addData( <GeoJSON> data ): this 5826 // Adds a GeoJSON object to the layer. 5827 addData: function(geojson) { 5828 var features = isArray(geojson) ? geojson : geojson.features, i, len, feature; 5829 if (features) { 5830 for (i = 0, len = features.length; i < len; i++) { 5831 feature = features[i]; 5832 if (feature.geometries || feature.geometry || feature.features || feature.coordinates) { 5833 this.addData(feature); 5834 } 5835 } 5836 return this; 5837 } 5838 var options = this.options; 5839 if (options.filter && !options.filter(geojson)) { 5840 return this; 5841 } 5842 var layer = geometryToLayer(geojson, options); 5843 if (!layer) { 5844 return this; 5845 } 5846 layer.feature = asFeature(geojson); 5847 layer.defaultOptions = layer.options; 5848 this.resetStyle(layer); 5849 if (options.onEachFeature) { 5850 options.onEachFeature(geojson, layer); 5851 } 5852 return this.addLayer(layer); 5853 }, 5854 // @method resetStyle( <Path> layer? ): this 5855 // Resets the given vector layer's style to the original GeoJSON style, useful for resetting style after hover events. 5856 // If `layer` is omitted, the style of all features in the current layer is reset. 5857 resetStyle: function(layer) { 5858 if (layer === void 0) { 5859 return this.eachLayer(this.resetStyle, this); 5860 } 5861 layer.options = extend({}, layer.defaultOptions); 5862 this._setLayerStyle(layer, this.options.style); 5863 return this; 5864 }, 5865 // @method setStyle( <Function> style ): this 5866 // Changes styles of GeoJSON vector layers with the given style function. 5867 setStyle: function(style2) { 5868 return this.eachLayer(function(layer) { 5869 this._setLayerStyle(layer, style2); 5870 }, this); 5871 }, 5872 _setLayerStyle: function(layer, style2) { 5873 if (layer.setStyle) { 5874 if (typeof style2 === "function") { 5875 style2 = style2(layer.feature); 5876 } 5877 layer.setStyle(style2); 5878 } 5879 } 5880 }); 5881 function geometryToLayer(geojson, options) { 5882 var geometry = geojson.type === "Feature" ? geojson.geometry : geojson, coords = geometry ? geometry.coordinates : null, layers2 = [], pointToLayer = options && options.pointToLayer, _coordsToLatLng = options && options.coordsToLatLng || coordsToLatLng, latlng, latlngs, i, len; 5883 if (!coords && !geometry) { 5884 return null; 5885 } 5886 switch (geometry.type) { 5887 case "Point": 5888 latlng = _coordsToLatLng(coords); 5889 return _pointToLayer(pointToLayer, geojson, latlng, options); 5890 case "MultiPoint": 5891 for (i = 0, len = coords.length; i < len; i++) { 5892 latlng = _coordsToLatLng(coords[i]); 5893 layers2.push(_pointToLayer(pointToLayer, geojson, latlng, options)); 5894 } 5895 return new FeatureGroup(layers2); 5896 case "LineString": 5897 case "MultiLineString": 5898 latlngs = coordsToLatLngs(coords, geometry.type === "LineString" ? 0 : 1, _coordsToLatLng); 5899 return new Polyline(latlngs, options); 5900 case "Polygon": 5901 case "MultiPolygon": 5902 latlngs = coordsToLatLngs(coords, geometry.type === "Polygon" ? 1 : 2, _coordsToLatLng); 5903 return new Polygon(latlngs, options); 5904 case "GeometryCollection": 5905 for (i = 0, len = geometry.geometries.length; i < len; i++) { 5906 var geoLayer = geometryToLayer({ 5907 geometry: geometry.geometries[i], 5908 type: "Feature", 5909 properties: geojson.properties 5910 }, options); 5911 if (geoLayer) { 5912 layers2.push(geoLayer); 5913 } 5914 } 5915 return new FeatureGroup(layers2); 5916 case "FeatureCollection": 5917 for (i = 0, len = geometry.features.length; i < len; i++) { 5918 var featureLayer = geometryToLayer(geometry.features[i], options); 5919 if (featureLayer) { 5920 layers2.push(featureLayer); 5921 } 5922 } 5923 return new FeatureGroup(layers2); 5924 default: 5925 throw new Error("Invalid GeoJSON object."); 5926 } 5927 } 5928 function _pointToLayer(pointToLayerFn, geojson, latlng, options) { 5929 return pointToLayerFn ? pointToLayerFn(geojson, latlng) : new Marker(latlng, options && options.markersInheritOptions && options); 5930 } 5931 function coordsToLatLng(coords) { 5932 return new LatLng(coords[1], coords[0], coords[2]); 5933 } 5934 function coordsToLatLngs(coords, levelsDeep, _coordsToLatLng) { 5935 var latlngs = []; 5936 for (var i = 0, len = coords.length, latlng; i < len; i++) { 5937 latlng = levelsDeep ? coordsToLatLngs(coords[i], levelsDeep - 1, _coordsToLatLng) : (_coordsToLatLng || coordsToLatLng)(coords[i]); 5938 latlngs.push(latlng); 5939 } 5940 return latlngs; 5941 } 5942 function latLngToCoords(latlng, precision) { 5943 latlng = toLatLng(latlng); 5944 return latlng.alt !== void 0 ? [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision), formatNum(latlng.alt, precision)] : [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision)]; 5945 } 5946 function latLngsToCoords(latlngs, levelsDeep, closed, precision) { 5947 var coords = []; 5948 for (var i = 0, len = latlngs.length; i < len; i++) { 5949 coords.push(levelsDeep ? latLngsToCoords(latlngs[i], isFlat(latlngs[i]) ? 0 : levelsDeep - 1, closed, precision) : latLngToCoords(latlngs[i], precision)); 5950 } 5951 if (!levelsDeep && closed && coords.length > 0) { 5952 coords.push(coords[0].slice()); 5953 } 5954 return coords; 5955 } 5956 function getFeature(layer, newGeometry) { 5957 return layer.feature ? extend({}, layer.feature, { geometry: newGeometry }) : asFeature(newGeometry); 5958 } 5959 function asFeature(geojson) { 5960 if (geojson.type === "Feature" || geojson.type === "FeatureCollection") { 5961 return geojson; 5962 } 5963 return { 5964 type: "Feature", 5965 properties: {}, 5966 geometry: geojson 5967 }; 5968 } 5969 var PointToGeoJSON = { 5970 toGeoJSON: function(precision) { 5971 return getFeature(this, { 5972 type: "Point", 5973 coordinates: latLngToCoords(this.getLatLng(), precision) 5974 }); 5975 } 5976 }; 5977 Marker.include(PointToGeoJSON); 5978 Circle.include(PointToGeoJSON); 5979 CircleMarker.include(PointToGeoJSON); 5980 Polyline.include({ 5981 toGeoJSON: function(precision) { 5982 var multi = !isFlat(this._latlngs); 5983 var coords = latLngsToCoords(this._latlngs, multi ? 1 : 0, false, precision); 5984 return getFeature(this, { 5985 type: (multi ? "Multi" : "") + "LineString", 5986 coordinates: coords 5987 }); 5988 } 5989 }); 5990 Polygon.include({ 5991 toGeoJSON: function(precision) { 5992 var holes = !isFlat(this._latlngs), multi = holes && !isFlat(this._latlngs[0]); 5993 var coords = latLngsToCoords(this._latlngs, multi ? 2 : holes ? 1 : 0, true, precision); 5994 if (!holes) { 5995 coords = [coords]; 5996 } 5997 return getFeature(this, { 5998 type: (multi ? "Multi" : "") + "Polygon", 5999 coordinates: coords 6000 }); 6001 } 6002 }); 6003 LayerGroup.include({ 6004 toMultiPoint: function(precision) { 6005 var coords = []; 6006 this.eachLayer(function(layer) { 6007 coords.push(layer.toGeoJSON(precision).geometry.coordinates); 6008 }); 6009 return getFeature(this, { 6010 type: "MultiPoint", 6011 coordinates: coords 6012 }); 6013 }, 6014 // @method toGeoJSON(precision?: Number|false): Object 6015 // Coordinates values are rounded with [`formatNum`](#util-formatnum) function with given `precision`. 6016 // Returns a [`GeoJSON`](https://en.wikipedia.org/wiki/GeoJSON) representation of the layer group (as a GeoJSON `FeatureCollection`, `GeometryCollection`, or `MultiPoint`). 6017 toGeoJSON: function(precision) { 6018 var type = this.feature && this.feature.geometry && this.feature.geometry.type; 6019 if (type === "MultiPoint") { 6020 return this.toMultiPoint(precision); 6021 } 6022 var isGeometryCollection = type === "GeometryCollection", jsons = []; 6023 this.eachLayer(function(layer) { 6024 if (layer.toGeoJSON) { 6025 var json = layer.toGeoJSON(precision); 6026 if (isGeometryCollection) { 6027 jsons.push(json.geometry); 6028 } else { 6029 var feature = asFeature(json); 6030 if (feature.type === "FeatureCollection") { 6031 jsons.push.apply(jsons, feature.features); 6032 } else { 6033 jsons.push(feature); 6034 } 6035 } 6036 } 6037 }); 6038 if (isGeometryCollection) { 6039 return getFeature(this, { 6040 geometries: jsons, 6041 type: "GeometryCollection" 6042 }); 6043 } 6044 return { 6045 type: "FeatureCollection", 6046 features: jsons 6047 }; 6048 } 6049 }); 6050 function geoJSON2(geojson, options) { 6051 return new GeoJSON(geojson, options); 6052 } 6053 var geoJson = geoJSON2; 6054 var ImageOverlay = Layer.extend({ 6055 // @section 6056 // @aka ImageOverlay options 6057 options: { 6058 // @option opacity: Number = 1.0 6059 // The opacity of the image overlay. 6060 opacity: 1, 6061 // @option alt: String = '' 6062 // Text for the `alt` attribute of the image (useful for accessibility). 6063 alt: "", 6064 // @option interactive: Boolean = false 6065 // If `true`, the image overlay will emit [mouse events](#interactive-layer) when clicked or hovered. 6066 interactive: false, 6067 // @option crossOrigin: Boolean|String = false 6068 // Whether the crossOrigin attribute will be added to the image. 6069 // 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. 6070 // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values. 6071 crossOrigin: false, 6072 // @option errorOverlayUrl: String = '' 6073 // URL to the overlay image to show in place of the overlay that failed to load. 6074 errorOverlayUrl: "", 6075 // @option zIndex: Number = 1 6076 // The explicit [zIndex](https://developer.mozilla.org/docs/Web/CSS/CSS_Positioning/Understanding_z_index) of the overlay layer. 6077 zIndex: 1, 6078 // @option className: String = '' 6079 // A custom class name to assign to the image. Empty by default. 6080 className: "" 6081 }, 6082 initialize: function(url, bounds, options) { 6083 this._url = url; 6084 this._bounds = toLatLngBounds(bounds); 6085 setOptions(this, options); 6086 }, 6087 onAdd: function() { 6088 if (!this._image) { 6089 this._initImage(); 6090 if (this.options.opacity < 1) { 6091 this._updateOpacity(); 6092 } 6093 } 6094 if (this.options.interactive) { 6095 addClass(this._image, "leaflet-interactive"); 6096 this.addInteractiveTarget(this._image); 6097 } 6098 this.getPane().appendChild(this._image); 6099 this._reset(); 6100 }, 6101 onRemove: function() { 6102 remove(this._image); 6103 if (this.options.interactive) { 6104 this.removeInteractiveTarget(this._image); 6105 } 6106 }, 6107 // @method setOpacity(opacity: Number): this 6108 // Sets the opacity of the overlay. 6109 setOpacity: function(opacity) { 6110 this.options.opacity = opacity; 6111 if (this._image) { 6112 this._updateOpacity(); 6113 } 6114 return this; 6115 }, 6116 setStyle: function(styleOpts) { 6117 if (styleOpts.opacity) { 6118 this.setOpacity(styleOpts.opacity); 6119 } 6120 return this; 6121 }, 6122 // @method bringToFront(): this 6123 // Brings the layer to the top of all overlays. 6124 bringToFront: function() { 6125 if (this._map) { 6126 toFront(this._image); 6127 } 6128 return this; 6129 }, 6130 // @method bringToBack(): this 6131 // Brings the layer to the bottom of all overlays. 6132 bringToBack: function() { 6133 if (this._map) { 6134 toBack(this._image); 6135 } 6136 return this; 6137 }, 6138 // @method setUrl(url: String): this 6139 // Changes the URL of the image. 6140 setUrl: function(url) { 6141 this._url = url; 6142 if (this._image) { 6143 this._image.src = url; 6144 } 6145 return this; 6146 }, 6147 // @method setBounds(bounds: LatLngBounds): this 6148 // Update the bounds that this ImageOverlay covers 6149 setBounds: function(bounds) { 6150 this._bounds = toLatLngBounds(bounds); 6151 if (this._map) { 6152 this._reset(); 6153 } 6154 return this; 6155 }, 6156 getEvents: function() { 6157 var events = { 6158 zoom: this._reset, 6159 viewreset: this._reset 6160 }; 6161 if (this._zoomAnimated) { 6162 events.zoomanim = this._animateZoom; 6163 } 6164 return events; 6165 }, 6166 // @method setZIndex(value: Number): this 6167 // Changes the [zIndex](#imageoverlay-zindex) of the image overlay. 6168 setZIndex: function(value) { 6169 this.options.zIndex = value; 6170 this._updateZIndex(); 6171 return this; 6172 }, 6173 // @method getBounds(): LatLngBounds 6174 // Get the bounds that this ImageOverlay covers 6175 getBounds: function() { 6176 return this._bounds; 6177 }, 6178 // @method getElement(): HTMLElement 6179 // Returns the instance of [`HTMLImageElement`](https://developer.mozilla.org/docs/Web/API/HTMLImageElement) 6180 // used by this overlay. 6181 getElement: function() { 6182 return this._image; 6183 }, 6184 _initImage: function() { 6185 var wasElementSupplied = this._url.tagName === "IMG"; 6186 var img = this._image = wasElementSupplied ? this._url : create$1("img"); 6187 addClass(img, "leaflet-image-layer"); 6188 if (this._zoomAnimated) { 6189 addClass(img, "leaflet-zoom-animated"); 6190 } 6191 if (this.options.className) { 6192 addClass(img, this.options.className); 6193 } 6194 img.onselectstart = falseFn; 6195 img.onmousemove = falseFn; 6196 img.onload = bind(this.fire, this, "load"); 6197 img.onerror = bind(this._overlayOnError, this, "error"); 6198 if (this.options.crossOrigin || this.options.crossOrigin === "") { 6199 img.crossOrigin = this.options.crossOrigin === true ? "" : this.options.crossOrigin; 6200 } 6201 if (this.options.zIndex) { 6202 this._updateZIndex(); 6203 } 6204 if (wasElementSupplied) { 6205 this._url = img.src; 6206 return; 6207 } 6208 img.src = this._url; 6209 img.alt = this.options.alt; 6210 }, 6211 _animateZoom: function(e) { 6212 var scale2 = this._map.getZoomScale(e.zoom), offset2 = this._map._latLngBoundsToNewLayerBounds(this._bounds, e.zoom, e.center).min; 6213 setTransform(this._image, offset2, scale2); 6214 }, 6215 _reset: function() { 6216 var image = this._image, bounds = new Bounds( 6217 this._map.latLngToLayerPoint(this._bounds.getNorthWest()), 6218 this._map.latLngToLayerPoint(this._bounds.getSouthEast()) 6219 ), size = bounds.getSize(); 6220 setPosition(image, bounds.min); 6221 image.style.width = size.x + "px"; 6222 image.style.height = size.y + "px"; 6223 }, 6224 _updateOpacity: function() { 6225 setOpacity(this._image, this.options.opacity); 6226 }, 6227 _updateZIndex: function() { 6228 if (this._image && this.options.zIndex !== void 0 && this.options.zIndex !== null) { 6229 this._image.style.zIndex = this.options.zIndex; 6230 } 6231 }, 6232 _overlayOnError: function() { 6233 this.fire("error"); 6234 var errorUrl = this.options.errorOverlayUrl; 6235 if (errorUrl && this._url !== errorUrl) { 6236 this._url = errorUrl; 6237 this._image.src = errorUrl; 6238 } 6239 }, 6240 // @method getCenter(): LatLng 6241 // Returns the center of the ImageOverlay. 6242 getCenter: function() { 6243 return this._bounds.getCenter(); 6244 } 6245 }); 6246 var imageOverlay = function(url, bounds, options) { 6247 return new ImageOverlay(url, bounds, options); 6248 }; 6249 var VideoOverlay = ImageOverlay.extend({ 6250 // @section 6251 // @aka VideoOverlay options 6252 options: { 6253 // @option autoplay: Boolean = true 6254 // Whether the video starts playing automatically when loaded. 6255 // On some browsers autoplay will only work with `muted: true` 6256 autoplay: true, 6257 // @option loop: Boolean = true 6258 // Whether the video will loop back to the beginning when played. 6259 loop: true, 6260 // @option keepAspectRatio: Boolean = true 6261 // Whether the video will save aspect ratio after the projection. 6262 // Relevant for supported browsers. See [browser compatibility](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) 6263 keepAspectRatio: true, 6264 // @option muted: Boolean = false 6265 // Whether the video starts on mute when loaded. 6266 muted: false, 6267 // @option playsInline: Boolean = true 6268 // Mobile browsers will play the video right where it is instead of open it up in fullscreen mode. 6269 playsInline: true 6270 }, 6271 _initImage: function() { 6272 var wasElementSupplied = this._url.tagName === "VIDEO"; 6273 var vid = this._image = wasElementSupplied ? this._url : create$1("video"); 6274 addClass(vid, "leaflet-image-layer"); 6275 if (this._zoomAnimated) { 6276 addClass(vid, "leaflet-zoom-animated"); 6277 } 6278 if (this.options.className) { 6279 addClass(vid, this.options.className); 6280 } 6281 vid.onselectstart = falseFn; 6282 vid.onmousemove = falseFn; 6283 vid.onloadeddata = bind(this.fire, this, "load"); 6284 if (wasElementSupplied) { 6285 var sourceElements = vid.getElementsByTagName("source"); 6286 var sources = []; 6287 for (var j = 0; j < sourceElements.length; j++) { 6288 sources.push(sourceElements[j].src); 6289 } 6290 this._url = sourceElements.length > 0 ? sources : [vid.src]; 6291 return; 6292 } 6293 if (!isArray(this._url)) { 6294 this._url = [this._url]; 6295 } 6296 if (!this.options.keepAspectRatio && Object.prototype.hasOwnProperty.call(vid.style, "objectFit")) { 6297 vid.style["objectFit"] = "fill"; 6298 } 6299 vid.autoplay = !!this.options.autoplay; 6300 vid.loop = !!this.options.loop; 6301 vid.muted = !!this.options.muted; 6302 vid.playsInline = !!this.options.playsInline; 6303 for (var i = 0; i < this._url.length; i++) { 6304 var source = create$1("source"); 6305 source.src = this._url[i]; 6306 vid.appendChild(source); 6307 } 6308 } 6309 // @method getElement(): HTMLVideoElement 6310 // Returns the instance of [`HTMLVideoElement`](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement) 6311 // used by this overlay. 6312 }); 6313 function videoOverlay(video, bounds, options) { 6314 return new VideoOverlay(video, bounds, options); 6315 } 6316 var SVGOverlay = ImageOverlay.extend({ 6317 _initImage: function() { 6318 var el = this._image = this._url; 6319 addClass(el, "leaflet-image-layer"); 6320 if (this._zoomAnimated) { 6321 addClass(el, "leaflet-zoom-animated"); 6322 } 6323 if (this.options.className) { 6324 addClass(el, this.options.className); 6325 } 6326 el.onselectstart = falseFn; 6327 el.onmousemove = falseFn; 6328 } 6329 // @method getElement(): SVGElement 6330 // Returns the instance of [`SVGElement`](https://developer.mozilla.org/docs/Web/API/SVGElement) 6331 // used by this overlay. 6332 }); 6333 function svgOverlay(el, bounds, options) { 6334 return new SVGOverlay(el, bounds, options); 6335 } 6336 var DivOverlay = Layer.extend({ 6337 // @section 6338 // @aka DivOverlay options 6339 options: { 6340 // @option interactive: Boolean = false 6341 // If true, the popup/tooltip will listen to the mouse events. 6342 interactive: false, 6343 // @option offset: Point = Point(0, 0) 6344 // The offset of the overlay position. 6345 offset: [0, 0], 6346 // @option className: String = '' 6347 // A custom CSS class name to assign to the overlay. 6348 className: "", 6349 // @option pane: String = undefined 6350 // `Map pane` where the overlay will be added. 6351 pane: void 0, 6352 // @option content: String|HTMLElement|Function = '' 6353 // Sets the HTML content of the overlay while initializing. If a function is passed the source layer will be 6354 // passed to the function. The function should return a `String` or `HTMLElement` to be used in the overlay. 6355 content: "" 6356 }, 6357 initialize: function(options, source) { 6358 if (options && (options instanceof LatLng || isArray(options))) { 6359 this._latlng = toLatLng(options); 6360 setOptions(this, source); 6361 } else { 6362 setOptions(this, options); 6363 this._source = source; 6364 } 6365 if (this.options.content) { 6366 this._content = this.options.content; 6367 } 6368 }, 6369 // @method openOn(map: Map): this 6370 // Adds the overlay to the map. 6371 // Alternative to `map.openPopup(popup)`/`.openTooltip(tooltip)`. 6372 openOn: function(map) { 6373 map = arguments.length ? map : this._source._map; 6374 if (!map.hasLayer(this)) { 6375 map.addLayer(this); 6376 } 6377 return this; 6378 }, 6379 // @method close(): this 6380 // Closes the overlay. 6381 // Alternative to `map.closePopup(popup)`/`.closeTooltip(tooltip)` 6382 // and `layer.closePopup()`/`.closeTooltip()`. 6383 close: function() { 6384 if (this._map) { 6385 this._map.removeLayer(this); 6386 } 6387 return this; 6388 }, 6389 // @method toggle(layer?: Layer): this 6390 // Opens or closes the overlay bound to layer depending on its current state. 6391 // Argument may be omitted only for overlay bound to layer. 6392 // Alternative to `layer.togglePopup()`/`.toggleTooltip()`. 6393 toggle: function(layer) { 6394 if (this._map) { 6395 this.close(); 6396 } else { 6397 if (arguments.length) { 6398 this._source = layer; 6399 } else { 6400 layer = this._source; 6401 } 6402 this._prepareOpen(); 6403 this.openOn(layer._map); 6404 } 6405 return this; 6406 }, 6407 onAdd: function(map) { 6408 this._zoomAnimated = map._zoomAnimated; 6409 if (!this._container) { 6410 this._initLayout(); 6411 } 6412 if (map._fadeAnimated) { 6413 setOpacity(this._container, 0); 6414 } 6415 clearTimeout(this._removeTimeout); 6416 this.getPane().appendChild(this._container); 6417 this.update(); 6418 if (map._fadeAnimated) { 6419 setOpacity(this._container, 1); 6420 } 6421 this.bringToFront(); 6422 if (this.options.interactive) { 6423 addClass(this._container, "leaflet-interactive"); 6424 this.addInteractiveTarget(this._container); 6425 } 6426 }, 6427 onRemove: function(map) { 6428 if (map._fadeAnimated) { 6429 setOpacity(this._container, 0); 6430 this._removeTimeout = setTimeout(bind(remove, void 0, this._container), 200); 6431 } else { 6432 remove(this._container); 6433 } 6434 if (this.options.interactive) { 6435 removeClass(this._container, "leaflet-interactive"); 6436 this.removeInteractiveTarget(this._container); 6437 } 6438 }, 6439 // @namespace DivOverlay 6440 // @method getLatLng: LatLng 6441 // Returns the geographical point of the overlay. 6442 getLatLng: function() { 6443 return this._latlng; 6444 }, 6445 // @method setLatLng(latlng: LatLng): this 6446 // Sets the geographical point where the overlay will open. 6447 setLatLng: function(latlng) { 6448 this._latlng = toLatLng(latlng); 6449 if (this._map) { 6450 this._updatePosition(); 6451 this._adjustPan(); 6452 } 6453 return this; 6454 }, 6455 // @method getContent: String|HTMLElement 6456 // Returns the content of the overlay. 6457 getContent: function() { 6458 return this._content; 6459 }, 6460 // @method setContent(htmlContent: String|HTMLElement|Function): this 6461 // Sets the HTML content of the overlay. If a function is passed the source layer will be passed to the function. 6462 // The function should return a `String` or `HTMLElement` to be used in the overlay. 6463 setContent: function(content) { 6464 this._content = content; 6465 this.update(); 6466 return this; 6467 }, 6468 // @method getElement: String|HTMLElement 6469 // Returns the HTML container of the overlay. 6470 getElement: function() { 6471 return this._container; 6472 }, 6473 // @method update: null 6474 // Updates the overlay content, layout and position. Useful for updating the overlay after something inside changed, e.g. image loaded. 6475 update: function() { 6476 if (!this._map) { 6477 return; 6478 } 6479 this._container.style.visibility = "hidden"; 6480 this._updateContent(); 6481 this._updateLayout(); 6482 this._updatePosition(); 6483 this._container.style.visibility = ""; 6484 this._adjustPan(); 6485 }, 6486 getEvents: function() { 6487 var events = { 6488 zoom: this._updatePosition, 6489 viewreset: this._updatePosition 6490 }; 6491 if (this._zoomAnimated) { 6492 events.zoomanim = this._animateZoom; 6493 } 6494 return events; 6495 }, 6496 // @method isOpen: Boolean 6497 // Returns `true` when the overlay is visible on the map. 6498 isOpen: function() { 6499 return !!this._map && this._map.hasLayer(this); 6500 }, 6501 // @method bringToFront: this 6502 // Brings this overlay in front of other overlays (in the same map pane). 6503 bringToFront: function() { 6504 if (this._map) { 6505 toFront(this._container); 6506 } 6507 return this; 6508 }, 6509 // @method bringToBack: this 6510 // Brings this overlay to the back of other overlays (in the same map pane). 6511 bringToBack: function() { 6512 if (this._map) { 6513 toBack(this._container); 6514 } 6515 return this; 6516 }, 6517 // prepare bound overlay to open: update latlng pos / content source (for FeatureGroup) 6518 _prepareOpen: function(latlng) { 6519 var source = this._source; 6520 if (!source._map) { 6521 return false; 6522 } 6523 if (source instanceof FeatureGroup) { 6524 source = null; 6525 var layers2 = this._source._layers; 6526 for (var id in layers2) { 6527 if (layers2[id]._map) { 6528 source = layers2[id]; 6529 break; 6530 } 6531 } 6532 if (!source) { 6533 return false; 6534 } 6535 this._source = source; 6536 } 6537 if (!latlng) { 6538 if (source.getCenter) { 6539 latlng = source.getCenter(); 6540 } else if (source.getLatLng) { 6541 latlng = source.getLatLng(); 6542 } else if (source.getBounds) { 6543 latlng = source.getBounds().getCenter(); 6544 } else { 6545 throw new Error("Unable to get source layer LatLng."); 6546 } 6547 } 6548 this.setLatLng(latlng); 6549 if (this._map) { 6550 this.update(); 6551 } 6552 return true; 6553 }, 6554 _updateContent: function() { 6555 if (!this._content) { 6556 return; 6557 } 6558 var node = this._contentNode; 6559 var content = typeof this._content === "function" ? this._content(this._source || this) : this._content; 6560 if (typeof content === "string") { 6561 node.innerHTML = content; 6562 } else { 6563 while (node.hasChildNodes()) { 6564 node.removeChild(node.firstChild); 6565 } 6566 node.appendChild(content); 6567 } 6568 this.fire("contentupdate"); 6569 }, 6570 _updatePosition: function() { 6571 if (!this._map) { 6572 return; 6573 } 6574 var pos = this._map.latLngToLayerPoint(this._latlng), offset2 = toPoint(this.options.offset), anchor = this._getAnchor(); 6575 if (this._zoomAnimated) { 6576 setPosition(this._container, pos.add(anchor)); 6577 } else { 6578 offset2 = offset2.add(pos).add(anchor); 6579 } 6580 var bottom2 = this._containerBottom = -offset2.y, left2 = this._containerLeft = -Math.round(this._containerWidth / 2) + offset2.x; 6581 this._container.style.bottom = bottom2 + "px"; 6582 this._container.style.left = left2 + "px"; 6583 }, 6584 _getAnchor: function() { 6585 return [0, 0]; 6586 } 6587 }); 6588 Map2.include({ 6589 _initOverlay: function(OverlayClass, content, latlng, options) { 6590 var overlay = content; 6591 if (!(overlay instanceof OverlayClass)) { 6592 overlay = new OverlayClass(options).setContent(content); 6593 } 6594 if (latlng) { 6595 overlay.setLatLng(latlng); 6596 } 6597 return overlay; 6598 } 6599 }); 6600 Layer.include({ 6601 _initOverlay: function(OverlayClass, old, content, options) { 6602 var overlay = content; 6603 if (overlay instanceof OverlayClass) { 6604 setOptions(overlay, options); 6605 overlay._source = this; 6606 } else { 6607 overlay = old && !options ? old : new OverlayClass(options, this); 6608 overlay.setContent(content); 6609 } 6610 return overlay; 6611 } 6612 }); 6613 var Popup = DivOverlay.extend({ 6614 // @section 6615 // @aka Popup options 6616 options: { 6617 // @option pane: String = 'popupPane' 6618 // `Map pane` where the popup will be added. 6619 pane: "popupPane", 6620 // @option offset: Point = Point(0, 7) 6621 // The offset of the popup position. 6622 offset: [0, 7], 6623 // @option maxWidth: Number = 300 6624 // Max width of the popup, in pixels. 6625 maxWidth: 300, 6626 // @option minWidth: Number = 50 6627 // Min width of the popup, in pixels. 6628 minWidth: 50, 6629 // @option maxHeight: Number = null 6630 // If set, creates a scrollable container of the given height 6631 // inside a popup if its content exceeds it. 6632 // The scrollable container can be styled using the 6633 // `leaflet-popup-scrolled` CSS class selector. 6634 maxHeight: null, 6635 // @option autoPan: Boolean = true 6636 // Set it to `false` if you don't want the map to do panning animation 6637 // to fit the opened popup. 6638 autoPan: true, 6639 // @option autoPanPaddingTopLeft: Point = null 6640 // The margin between the popup and the top left corner of the map 6641 // view after autopanning was performed. 6642 autoPanPaddingTopLeft: null, 6643 // @option autoPanPaddingBottomRight: Point = null 6644 // The margin between the popup and the bottom right corner of the map 6645 // view after autopanning was performed. 6646 autoPanPaddingBottomRight: null, 6647 // @option autoPanPadding: Point = Point(5, 5) 6648 // Equivalent of setting both top left and bottom right autopan padding to the same value. 6649 autoPanPadding: [5, 5], 6650 // @option keepInView: Boolean = false 6651 // Set it to `true` if you want to prevent users from panning the popup 6652 // off of the screen while it is open. 6653 keepInView: false, 6654 // @option closeButton: Boolean = true 6655 // Controls the presence of a close button in the popup. 6656 closeButton: true, 6657 // @option autoClose: Boolean = true 6658 // Set it to `false` if you want to override the default behavior of 6659 // the popup closing when another popup is opened. 6660 autoClose: true, 6661 // @option closeOnEscapeKey: Boolean = true 6662 // Set it to `false` if you want to override the default behavior of 6663 // the ESC key for closing of the popup. 6664 closeOnEscapeKey: true, 6665 // @option closeOnClick: Boolean = * 6666 // Set it if you want to override the default behavior of the popup closing when user clicks 6667 // on the map. Defaults to the map's [`closePopupOnClick`](#map-closepopuponclick) option. 6668 // @option className: String = '' 6669 // A custom CSS class name to assign to the popup. 6670 className: "" 6671 }, 6672 // @namespace Popup 6673 // @method openOn(map: Map): this 6674 // Alternative to `map.openPopup(popup)`. 6675 // Adds the popup to the map and closes the previous one. 6676 openOn: function(map) { 6677 map = arguments.length ? map : this._source._map; 6678 if (!map.hasLayer(this) && map._popup && map._popup.options.autoClose) { 6679 map.removeLayer(map._popup); 6680 } 6681 map._popup = this; 6682 return DivOverlay.prototype.openOn.call(this, map); 6683 }, 6684 onAdd: function(map) { 6685 DivOverlay.prototype.onAdd.call(this, map); 6686 map.fire("popupopen", { popup: this }); 6687 if (this._source) { 6688 this._source.fire("popupopen", { popup: this }, true); 6689 if (!(this._source instanceof Path)) { 6690 this._source.on("preclick", stopPropagation); 6691 } 6692 } 6693 }, 6694 onRemove: function(map) { 6695 DivOverlay.prototype.onRemove.call(this, map); 6696 map.fire("popupclose", { popup: this }); 6697 if (this._source) { 6698 this._source.fire("popupclose", { popup: this }, true); 6699 if (!(this._source instanceof Path)) { 6700 this._source.off("preclick", stopPropagation); 6701 } 6702 } 6703 }, 6704 getEvents: function() { 6705 var events = DivOverlay.prototype.getEvents.call(this); 6706 if (this.options.closeOnClick !== void 0 ? this.options.closeOnClick : this._map.options.closePopupOnClick) { 6707 events.preclick = this.close; 6708 } 6709 if (this.options.keepInView) { 6710 events.moveend = this._adjustPan; 6711 } 6712 return events; 6713 }, 6714 _initLayout: function() { 6715 var prefix = "leaflet-popup", container = this._container = create$1( 6716 "div", 6717 prefix + " " + (this.options.className || "") + " leaflet-zoom-animated" 6718 ); 6719 var wrapper = this._wrapper = create$1("div", prefix + "-content-wrapper", container); 6720 this._contentNode = create$1("div", prefix + "-content", wrapper); 6721 disableClickPropagation(container); 6722 disableScrollPropagation(this._contentNode); 6723 on(container, "contextmenu", stopPropagation); 6724 this._tipContainer = create$1("div", prefix + "-tip-container", container); 6725 this._tip = create$1("div", prefix + "-tip", this._tipContainer); 6726 if (this.options.closeButton) { 6727 var closeButton = this._closeButton = create$1("a", prefix + "-close-button", container); 6728 closeButton.setAttribute("role", "button"); 6729 closeButton.setAttribute("aria-label", "Close popup"); 6730 closeButton.href = "#close"; 6731 closeButton.innerHTML = '<span aria-hidden="true">×</span>'; 6732 on(closeButton, "click", function(ev) { 6733 preventDefault(ev); 6734 this.close(); 6735 }, this); 6736 } 6737 }, 6738 _updateLayout: function() { 6739 var container = this._contentNode, style2 = container.style; 6740 style2.width = ""; 6741 style2.whiteSpace = "nowrap"; 6742 var width = container.offsetWidth; 6743 width = Math.min(width, this.options.maxWidth); 6744 width = Math.max(width, this.options.minWidth); 6745 style2.width = width + 1 + "px"; 6746 style2.whiteSpace = ""; 6747 style2.height = ""; 6748 var height = container.offsetHeight, maxHeight = this.options.maxHeight, scrolledClass = "leaflet-popup-scrolled"; 6749 if (maxHeight && height > maxHeight) { 6750 style2.height = maxHeight + "px"; 6751 addClass(container, scrolledClass); 6752 } else { 6753 removeClass(container, scrolledClass); 6754 } 6755 this._containerWidth = this._container.offsetWidth; 6756 }, 6757 _animateZoom: function(e) { 6758 var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center), anchor = this._getAnchor(); 6759 setPosition(this._container, pos.add(anchor)); 6760 }, 6761 _adjustPan: function() { 6762 if (!this.options.autoPan) { 6763 return; 6764 } 6765 if (this._map._panAnim) { 6766 this._map._panAnim.stop(); 6767 } 6768 if (this._autopanning) { 6769 this._autopanning = false; 6770 return; 6771 } 6772 var map = this._map, marginBottom = parseInt(getStyle(this._container, "marginBottom"), 10) || 0, containerHeight = this._container.offsetHeight + marginBottom, containerWidth = this._containerWidth, layerPos = new Point(this._containerLeft, -containerHeight - this._containerBottom); 6773 layerPos._add(getPosition(this._container)); 6774 var containerPos = map.layerPointToContainerPoint(layerPos), padding = toPoint(this.options.autoPanPadding), paddingTL = toPoint(this.options.autoPanPaddingTopLeft || padding), paddingBR = toPoint(this.options.autoPanPaddingBottomRight || padding), size = map.getSize(), dx = 0, dy = 0; 6775 if (containerPos.x + containerWidth + paddingBR.x > size.x) { 6776 dx = containerPos.x + containerWidth - size.x + paddingBR.x; 6777 } 6778 if (containerPos.x - dx - paddingTL.x < 0) { 6779 dx = containerPos.x - paddingTL.x; 6780 } 6781 if (containerPos.y + containerHeight + paddingBR.y > size.y) { 6782 dy = containerPos.y + containerHeight - size.y + paddingBR.y; 6783 } 6784 if (containerPos.y - dy - paddingTL.y < 0) { 6785 dy = containerPos.y - paddingTL.y; 6786 } 6787 if (dx || dy) { 6788 if (this.options.keepInView) { 6789 this._autopanning = true; 6790 } 6791 map.fire("autopanstart").panBy([dx, dy]); 6792 } 6793 }, 6794 _getAnchor: function() { 6795 return toPoint(this._source && this._source._getPopupAnchor ? this._source._getPopupAnchor() : [0, 0]); 6796 } 6797 }); 6798 var popup = function(options, source) { 6799 return new Popup(options, source); 6800 }; 6801 Map2.mergeOptions({ 6802 closePopupOnClick: true 6803 }); 6804 Map2.include({ 6805 // @method openPopup(popup: Popup): this 6806 // Opens the specified popup while closing the previously opened (to make sure only one is opened at one time for usability). 6807 // @alternative 6808 // @method openPopup(content: String|HTMLElement, latlng: LatLng, options?: Popup options): this 6809 // Creates a popup with the specified content and options and opens it in the given point on a map. 6810 openPopup: function(popup2, latlng, options) { 6811 this._initOverlay(Popup, popup2, latlng, options).openOn(this); 6812 return this; 6813 }, 6814 // @method closePopup(popup?: Popup): this 6815 // Closes the popup previously opened with [openPopup](#map-openpopup) (or the given one). 6816 closePopup: function(popup2) { 6817 popup2 = arguments.length ? popup2 : this._popup; 6818 if (popup2) { 6819 popup2.close(); 6820 } 6821 return this; 6822 } 6823 }); 6824 Layer.include({ 6825 // @method bindPopup(content: String|HTMLElement|Function|Popup, options?: Popup options): this 6826 // Binds a popup to the layer with the passed `content` and sets up the 6827 // necessary event listeners. If a `Function` is passed it will receive 6828 // the layer as the first argument and should return a `String` or `HTMLElement`. 6829 bindPopup: function(content, options) { 6830 this._popup = this._initOverlay(Popup, this._popup, content, options); 6831 if (!this._popupHandlersAdded) { 6832 this.on({ 6833 click: this._openPopup, 6834 keypress: this._onKeyPress, 6835 remove: this.closePopup, 6836 move: this._movePopup 6837 }); 6838 this._popupHandlersAdded = true; 6839 } 6840 return this; 6841 }, 6842 // @method unbindPopup(): this 6843 // Removes the popup previously bound with `bindPopup`. 6844 unbindPopup: function() { 6845 if (this._popup) { 6846 this.off({ 6847 click: this._openPopup, 6848 keypress: this._onKeyPress, 6849 remove: this.closePopup, 6850 move: this._movePopup 6851 }); 6852 this._popupHandlersAdded = false; 6853 this._popup = null; 6854 } 6855 return this; 6856 }, 6857 // @method openPopup(latlng?: LatLng): this 6858 // Opens the bound popup at the specified `latlng` or at the default popup anchor if no `latlng` is passed. 6859 openPopup: function(latlng) { 6860 if (this._popup) { 6861 if (!(this instanceof FeatureGroup)) { 6862 this._popup._source = this; 6863 } 6864 if (this._popup._prepareOpen(latlng || this._latlng)) { 6865 this._popup.openOn(this._map); 6866 } 6867 } 6868 return this; 6869 }, 6870 // @method closePopup(): this 6871 // Closes the popup bound to this layer if it is open. 6872 closePopup: function() { 6873 if (this._popup) { 6874 this._popup.close(); 6875 } 6876 return this; 6877 }, 6878 // @method togglePopup(): this 6879 // Opens or closes the popup bound to this layer depending on its current state. 6880 togglePopup: function() { 6881 if (this._popup) { 6882 this._popup.toggle(this); 6883 } 6884 return this; 6885 }, 6886 // @method isPopupOpen(): boolean 6887 // Returns `true` if the popup bound to this layer is currently open. 6888 isPopupOpen: function() { 6889 return this._popup ? this._popup.isOpen() : false; 6890 }, 6891 // @method setPopupContent(content: String|HTMLElement|Popup): this 6892 // Sets the content of the popup bound to this layer. 6893 setPopupContent: function(content) { 6894 if (this._popup) { 6895 this._popup.setContent(content); 6896 } 6897 return this; 6898 }, 6899 // @method getPopup(): Popup 6900 // Returns the popup bound to this layer. 6901 getPopup: function() { 6902 return this._popup; 6903 }, 6904 _openPopup: function(e) { 6905 if (!this._popup || !this._map) { 6906 return; 6907 } 6908 stop(e); 6909 var target = e.layer || e.target; 6910 if (this._popup._source === target && !(target instanceof Path)) { 6911 if (this._map.hasLayer(this._popup)) { 6912 this.closePopup(); 6913 } else { 6914 this.openPopup(e.latlng); 6915 } 6916 return; 6917 } 6918 this._popup._source = target; 6919 this.openPopup(e.latlng); 6920 }, 6921 _movePopup: function(e) { 6922 this._popup.setLatLng(e.latlng); 6923 }, 6924 _onKeyPress: function(e) { 6925 if (e.originalEvent.keyCode === 13) { 6926 this._openPopup(e); 6927 } 6928 } 6929 }); 6930 var Tooltip2 = DivOverlay.extend({ 6931 // @section 6932 // @aka Tooltip options 6933 options: { 6934 // @option pane: String = 'tooltipPane' 6935 // `Map pane` where the tooltip will be added. 6936 pane: "tooltipPane", 6937 // @option offset: Point = Point(0, 0) 6938 // Optional offset of the tooltip position. 6939 offset: [0, 0], 6940 // @option direction: String = 'auto' 6941 // Direction where to open the tooltip. Possible values are: `right`, `left`, 6942 // `top`, `bottom`, `center`, `auto`. 6943 // `auto` will dynamically switch between `right` and `left` according to the tooltip 6944 // position on the map. 6945 direction: "auto", 6946 // @option permanent: Boolean = false 6947 // Whether to open the tooltip permanently or only on mouseover. 6948 permanent: false, 6949 // @option sticky: Boolean = false 6950 // If true, the tooltip will follow the mouse instead of being fixed at the feature center. 6951 sticky: false, 6952 // @option opacity: Number = 0.9 6953 // Tooltip container opacity. 6954 opacity: 0.9 6955 }, 6956 onAdd: function(map) { 6957 DivOverlay.prototype.onAdd.call(this, map); 6958 this.setOpacity(this.options.opacity); 6959 map.fire("tooltipopen", { tooltip: this }); 6960 if (this._source) { 6961 this.addEventParent(this._source); 6962 this._source.fire("tooltipopen", { tooltip: this }, true); 6963 } 6964 }, 6965 onRemove: function(map) { 6966 DivOverlay.prototype.onRemove.call(this, map); 6967 map.fire("tooltipclose", { tooltip: this }); 6968 if (this._source) { 6969 this.removeEventParent(this._source); 6970 this._source.fire("tooltipclose", { tooltip: this }, true); 6971 } 6972 }, 6973 getEvents: function() { 6974 var events = DivOverlay.prototype.getEvents.call(this); 6975 if (!this.options.permanent) { 6976 events.preclick = this.close; 6977 } 6978 return events; 6979 }, 6980 _initLayout: function() { 6981 var prefix = "leaflet-tooltip", className = prefix + " " + (this.options.className || "") + " leaflet-zoom-" + (this._zoomAnimated ? "animated" : "hide"); 6982 this._contentNode = this._container = create$1("div", className); 6983 this._container.setAttribute("role", "tooltip"); 6984 this._container.setAttribute("id", "leaflet-tooltip-" + stamp(this)); 6985 }, 6986 _updateLayout: function() { 6987 }, 6988 _adjustPan: function() { 6989 }, 6990 _setPosition: function(pos) { 6991 var subX, subY, map = this._map, container = this._container, centerPoint = map.latLngToContainerPoint(map.getCenter()), tooltipPoint = map.layerPointToContainerPoint(pos), direction = this.options.direction, tooltipWidth = container.offsetWidth, tooltipHeight = container.offsetHeight, offset2 = toPoint(this.options.offset), anchor = this._getAnchor(); 6992 if (direction === "top") { 6993 subX = tooltipWidth / 2; 6994 subY = tooltipHeight; 6995 } else if (direction === "bottom") { 6996 subX = tooltipWidth / 2; 6997 subY = 0; 6998 } else if (direction === "center") { 6999 subX = tooltipWidth / 2; 7000 subY = tooltipHeight / 2; 7001 } else if (direction === "right") { 7002 subX = 0; 7003 subY = tooltipHeight / 2; 7004 } else if (direction === "left") { 7005 subX = tooltipWidth; 7006 subY = tooltipHeight / 2; 7007 } else if (tooltipPoint.x < centerPoint.x) { 7008 direction = "right"; 7009 subX = 0; 7010 subY = tooltipHeight / 2; 7011 } else { 7012 direction = "left"; 7013 subX = tooltipWidth + (offset2.x + anchor.x) * 2; 7014 subY = tooltipHeight / 2; 7015 } 7016 pos = pos.subtract(toPoint(subX, subY, true)).add(offset2).add(anchor); 7017 removeClass(container, "leaflet-tooltip-right"); 7018 removeClass(container, "leaflet-tooltip-left"); 7019 removeClass(container, "leaflet-tooltip-top"); 7020 removeClass(container, "leaflet-tooltip-bottom"); 7021 addClass(container, "leaflet-tooltip-" + direction); 7022 setPosition(container, pos); 7023 }, 7024 _updatePosition: function() { 7025 var pos = this._map.latLngToLayerPoint(this._latlng); 7026 this._setPosition(pos); 7027 }, 7028 setOpacity: function(opacity) { 7029 this.options.opacity = opacity; 7030 if (this._container) { 7031 setOpacity(this._container, opacity); 7032 } 7033 }, 7034 _animateZoom: function(e) { 7035 var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center); 7036 this._setPosition(pos); 7037 }, 7038 _getAnchor: function() { 7039 return toPoint(this._source && this._source._getTooltipAnchor && !this.options.sticky ? this._source._getTooltipAnchor() : [0, 0]); 7040 } 7041 }); 7042 var tooltip = function(options, source) { 7043 return new Tooltip2(options, source); 7044 }; 7045 Map2.include({ 7046 // @method openTooltip(tooltip: Tooltip): this 7047 // Opens the specified tooltip. 7048 // @alternative 7049 // @method openTooltip(content: String|HTMLElement, latlng: LatLng, options?: Tooltip options): this 7050 // Creates a tooltip with the specified content and options and open it. 7051 openTooltip: function(tooltip2, latlng, options) { 7052 this._initOverlay(Tooltip2, tooltip2, latlng, options).openOn(this); 7053 return this; 7054 }, 7055 // @method closeTooltip(tooltip: Tooltip): this 7056 // Closes the tooltip given as parameter. 7057 closeTooltip: function(tooltip2) { 7058 tooltip2.close(); 7059 return this; 7060 } 7061 }); 7062 Layer.include({ 7063 // @method bindTooltip(content: String|HTMLElement|Function|Tooltip, options?: Tooltip options): this 7064 // Binds a tooltip to the layer with the passed `content` and sets up the 7065 // necessary event listeners. If a `Function` is passed it will receive 7066 // the layer as the first argument and should return a `String` or `HTMLElement`. 7067 bindTooltip: function(content, options) { 7068 if (this._tooltip && this.isTooltipOpen()) { 7069 this.unbindTooltip(); 7070 } 7071 this._tooltip = this._initOverlay(Tooltip2, this._tooltip, content, options); 7072 this._initTooltipInteractions(); 7073 if (this._tooltip.options.permanent && this._map && this._map.hasLayer(this)) { 7074 this.openTooltip(); 7075 } 7076 return this; 7077 }, 7078 // @method unbindTooltip(): this 7079 // Removes the tooltip previously bound with `bindTooltip`. 7080 unbindTooltip: function() { 7081 if (this._tooltip) { 7082 this._initTooltipInteractions(true); 7083 this.closeTooltip(); 7084 this._tooltip = null; 7085 } 7086 return this; 7087 }, 7088 _initTooltipInteractions: function(remove2) { 7089 if (!remove2 && this._tooltipHandlersAdded) { 7090 return; 7091 } 7092 var onOff = remove2 ? "off" : "on", events = { 7093 remove: this.closeTooltip, 7094 move: this._moveTooltip 7095 }; 7096 if (!this._tooltip.options.permanent) { 7097 events.mouseover = this._openTooltip; 7098 events.mouseout = this.closeTooltip; 7099 events.click = this._openTooltip; 7100 if (this._map) { 7101 this._addFocusListeners(); 7102 } else { 7103 events.add = this._addFocusListeners; 7104 } 7105 } else { 7106 events.add = this._openTooltip; 7107 } 7108 if (this._tooltip.options.sticky) { 7109 events.mousemove = this._moveTooltip; 7110 } 7111 this[onOff](events); 7112 this._tooltipHandlersAdded = !remove2; 7113 }, 7114 // @method openTooltip(latlng?: LatLng): this 7115 // Opens the bound tooltip at the specified `latlng` or at the default tooltip anchor if no `latlng` is passed. 7116 openTooltip: function(latlng) { 7117 if (this._tooltip) { 7118 if (!(this instanceof FeatureGroup)) { 7119 this._tooltip._source = this; 7120 } 7121 if (this._tooltip._prepareOpen(latlng)) { 7122 this._tooltip.openOn(this._map); 7123 if (this.getElement) { 7124 this._setAriaDescribedByOnLayer(this); 7125 } else if (this.eachLayer) { 7126 this.eachLayer(this._setAriaDescribedByOnLayer, this); 7127 } 7128 } 7129 } 7130 return this; 7131 }, 7132 // @method closeTooltip(): this 7133 // Closes the tooltip bound to this layer if it is open. 7134 closeTooltip: function() { 7135 if (this._tooltip) { 7136 return this._tooltip.close(); 7137 } 7138 }, 7139 // @method toggleTooltip(): this 7140 // Opens or closes the tooltip bound to this layer depending on its current state. 7141 toggleTooltip: function() { 7142 if (this._tooltip) { 7143 this._tooltip.toggle(this); 7144 } 7145 return this; 7146 }, 7147 // @method isTooltipOpen(): boolean 7148 // Returns `true` if the tooltip bound to this layer is currently open. 7149 isTooltipOpen: function() { 7150 return this._tooltip.isOpen(); 7151 }, 7152 // @method setTooltipContent(content: String|HTMLElement|Tooltip): this 7153 // Sets the content of the tooltip bound to this layer. 7154 setTooltipContent: function(content) { 7155 if (this._tooltip) { 7156 this._tooltip.setContent(content); 7157 } 7158 return this; 7159 }, 7160 // @method getTooltip(): Tooltip 7161 // Returns the tooltip bound to this layer. 7162 getTooltip: function() { 7163 return this._tooltip; 7164 }, 7165 _addFocusListeners: function() { 7166 if (this.getElement) { 7167 this._addFocusListenersOnLayer(this); 7168 } else if (this.eachLayer) { 7169 this.eachLayer(this._addFocusListenersOnLayer, this); 7170 } 7171 }, 7172 _addFocusListenersOnLayer: function(layer) { 7173 var el = typeof layer.getElement === "function" && layer.getElement(); 7174 if (el) { 7175 on(el, "focus", function() { 7176 this._tooltip._source = layer; 7177 this.openTooltip(); 7178 }, this); 7179 on(el, "blur", this.closeTooltip, this); 7180 } 7181 }, 7182 _setAriaDescribedByOnLayer: function(layer) { 7183 var el = typeof layer.getElement === "function" && layer.getElement(); 7184 if (el) { 7185 el.setAttribute("aria-describedby", this._tooltip._container.id); 7186 } 7187 }, 7188 _openTooltip: function(e) { 7189 if (!this._tooltip || !this._map) { 7190 return; 7191 } 7192 if (this._map.dragging && this._map.dragging.moving() && !this._openOnceFlag) { 7193 this._openOnceFlag = true; 7194 var that = this; 7195 this._map.once("moveend", function() { 7196 that._openOnceFlag = false; 7197 that._openTooltip(e); 7198 }); 7199 return; 7200 } 7201 this._tooltip._source = e.layer || e.target; 7202 this.openTooltip(this._tooltip.options.sticky ? e.latlng : void 0); 7203 }, 7204 _moveTooltip: function(e) { 7205 var latlng = e.latlng, containerPoint, layerPoint; 7206 if (this._tooltip.options.sticky && e.originalEvent) { 7207 containerPoint = this._map.mouseEventToContainerPoint(e.originalEvent); 7208 layerPoint = this._map.containerPointToLayerPoint(containerPoint); 7209 latlng = this._map.layerPointToLatLng(layerPoint); 7210 } 7211 this._tooltip.setLatLng(latlng); 7212 } 7213 }); 7214 var DivIcon = Icon.extend({ 7215 options: { 7216 // @section 7217 // @aka DivIcon options 7218 iconSize: [12, 12], 7219 // also can be set through CSS 7220 // iconAnchor: (Point), 7221 // popupAnchor: (Point), 7222 // @option html: String|HTMLElement = '' 7223 // Custom HTML code to put inside the div element, empty by default. Alternatively, 7224 // an instance of `HTMLElement`. 7225 html: false, 7226 // @option bgPos: Point = [0, 0] 7227 // Optional relative position of the background, in pixels 7228 bgPos: null, 7229 className: "leaflet-div-icon" 7230 }, 7231 createIcon: function(oldIcon) { 7232 var div = oldIcon && oldIcon.tagName === "DIV" ? oldIcon : document.createElement("div"), options = this.options; 7233 if (options.html instanceof Element) { 7234 empty(div); 7235 div.appendChild(options.html); 7236 } else { 7237 div.innerHTML = options.html !== false ? options.html : ""; 7238 } 7239 if (options.bgPos) { 7240 var bgPos = toPoint(options.bgPos); 7241 div.style.backgroundPosition = -bgPos.x + "px " + -bgPos.y + "px"; 7242 } 7243 this._setIconStyles(div, "icon"); 7244 return div; 7245 }, 7246 createShadow: function() { 7247 return null; 7248 } 7249 }); 7250 function divIcon(options) { 7251 return new DivIcon(options); 7252 } 7253 Icon.Default = IconDefault; 7254 var GridLayer = Layer.extend({ 7255 // @section 7256 // @aka GridLayer options 7257 options: { 7258 // @option tileSize: Number|Point = 256 7259 // Width and height of tiles in the grid. Use a number if width and height are equal, or `L.point(width, height)` otherwise. 7260 tileSize: 256, 7261 // @option opacity: Number = 1.0 7262 // Opacity of the tiles. Can be used in the `createTile()` function. 7263 opacity: 1, 7264 // @option updateWhenIdle: Boolean = (depends) 7265 // Load new tiles only when panning ends. 7266 // `true` by default on mobile browsers, in order to avoid too many requests and keep smooth navigation. 7267 // `false` otherwise in order to display new tiles _during_ panning, since it is easy to pan outside the 7268 // [`keepBuffer`](#gridlayer-keepbuffer) option in desktop browsers. 7269 updateWhenIdle: Browser.mobile, 7270 // @option updateWhenZooming: Boolean = true 7271 // 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. 7272 updateWhenZooming: true, 7273 // @option updateInterval: Number = 200 7274 // Tiles will not update more than once every `updateInterval` milliseconds when panning. 7275 updateInterval: 200, 7276 // @option zIndex: Number = 1 7277 // The explicit zIndex of the tile layer. 7278 zIndex: 1, 7279 // @option bounds: LatLngBounds = undefined 7280 // If set, tiles will only be loaded inside the set `LatLngBounds`. 7281 bounds: null, 7282 // @option minZoom: Number = 0 7283 // The minimum zoom level down to which this layer will be displayed (inclusive). 7284 minZoom: 0, 7285 // @option maxZoom: Number = undefined 7286 // The maximum zoom level up to which this layer will be displayed (inclusive). 7287 maxZoom: void 0, 7288 // @option maxNativeZoom: Number = undefined 7289 // Maximum zoom number the tile source has available. If it is specified, 7290 // the tiles on all zoom levels higher than `maxNativeZoom` will be loaded 7291 // from `maxNativeZoom` level and auto-scaled. 7292 maxNativeZoom: void 0, 7293 // @option minNativeZoom: Number = undefined 7294 // Minimum zoom number the tile source has available. If it is specified, 7295 // the tiles on all zoom levels lower than `minNativeZoom` will be loaded 7296 // from `minNativeZoom` level and auto-scaled. 7297 minNativeZoom: void 0, 7298 // @option noWrap: Boolean = false 7299 // Whether the layer is wrapped around the antimeridian. If `true`, the 7300 // GridLayer will only be displayed once at low zoom levels. Has no 7301 // effect when the [map CRS](#map-crs) doesn't wrap around. Can be used 7302 // in combination with [`bounds`](#gridlayer-bounds) to prevent requesting 7303 // tiles outside the CRS limits. 7304 noWrap: false, 7305 // @option pane: String = 'tilePane' 7306 // `Map pane` where the grid layer will be added. 7307 pane: "tilePane", 7308 // @option className: String = '' 7309 // A custom class name to assign to the tile layer. Empty by default. 7310 className: "", 7311 // @option keepBuffer: Number = 2 7312 // When panning the map, keep this many rows and columns of tiles before unloading them. 7313 keepBuffer: 2 7314 }, 7315 initialize: function(options) { 7316 setOptions(this, options); 7317 }, 7318 onAdd: function() { 7319 this._initContainer(); 7320 this._levels = {}; 7321 this._tiles = {}; 7322 this._resetView(); 7323 }, 7324 beforeAdd: function(map) { 7325 map._addZoomLimit(this); 7326 }, 7327 onRemove: function(map) { 7328 this._removeAllTiles(); 7329 remove(this._container); 7330 map._removeZoomLimit(this); 7331 this._container = null; 7332 this._tileZoom = void 0; 7333 }, 7334 // @method bringToFront: this 7335 // Brings the tile layer to the top of all tile layers. 7336 bringToFront: function() { 7337 if (this._map) { 7338 toFront(this._container); 7339 this._setAutoZIndex(Math.max); 7340 } 7341 return this; 7342 }, 7343 // @method bringToBack: this 7344 // Brings the tile layer to the bottom of all tile layers. 7345 bringToBack: function() { 7346 if (this._map) { 7347 toBack(this._container); 7348 this._setAutoZIndex(Math.min); 7349 } 7350 return this; 7351 }, 7352 // @method getContainer: HTMLElement 7353 // Returns the HTML element that contains the tiles for this layer. 7354 getContainer: function() { 7355 return this._container; 7356 }, 7357 // @method setOpacity(opacity: Number): this 7358 // Changes the [opacity](#gridlayer-opacity) of the grid layer. 7359 setOpacity: function(opacity) { 7360 this.options.opacity = opacity; 7361 this._updateOpacity(); 7362 return this; 7363 }, 7364 // @method setZIndex(zIndex: Number): this 7365 // Changes the [zIndex](#gridlayer-zindex) of the grid layer. 7366 setZIndex: function(zIndex) { 7367 this.options.zIndex = zIndex; 7368 this._updateZIndex(); 7369 return this; 7370 }, 7371 // @method isLoading: Boolean 7372 // Returns `true` if any tile in the grid layer has not finished loading. 7373 isLoading: function() { 7374 return this._loading; 7375 }, 7376 // @method redraw: this 7377 // Causes the layer to clear all the tiles and request them again. 7378 redraw: function() { 7379 if (this._map) { 7380 this._removeAllTiles(); 7381 var tileZoom = this._clampZoom(this._map.getZoom()); 7382 if (tileZoom !== this._tileZoom) { 7383 this._tileZoom = tileZoom; 7384 this._updateLevels(); 7385 } 7386 this._update(); 7387 } 7388 return this; 7389 }, 7390 getEvents: function() { 7391 var events = { 7392 viewprereset: this._invalidateAll, 7393 viewreset: this._resetView, 7394 zoom: this._resetView, 7395 moveend: this._onMoveEnd 7396 }; 7397 if (!this.options.updateWhenIdle) { 7398 if (!this._onMove) { 7399 this._onMove = throttle(this._onMoveEnd, this.options.updateInterval, this); 7400 } 7401 events.move = this._onMove; 7402 } 7403 if (this._zoomAnimated) { 7404 events.zoomanim = this._animateZoom; 7405 } 7406 return events; 7407 }, 7408 // @section Extension methods 7409 // Layers extending `GridLayer` shall reimplement the following method. 7410 // @method createTile(coords: Object, done?: Function): HTMLElement 7411 // Called only internally, must be overridden by classes extending `GridLayer`. 7412 // Returns the `HTMLElement` corresponding to the given `coords`. If the `done` callback 7413 // is specified, it must be called when the tile has finished loading and drawing. 7414 createTile: function() { 7415 return document.createElement("div"); 7416 }, 7417 // @section 7418 // @method getTileSize: Point 7419 // Normalizes the [tileSize option](#gridlayer-tilesize) into a point. Used by the `createTile()` method. 7420 getTileSize: function() { 7421 var s = this.options.tileSize; 7422 return s instanceof Point ? s : new Point(s, s); 7423 }, 7424 _updateZIndex: function() { 7425 if (this._container && this.options.zIndex !== void 0 && this.options.zIndex !== null) { 7426 this._container.style.zIndex = this.options.zIndex; 7427 } 7428 }, 7429 _setAutoZIndex: function(compare) { 7430 var layers2 = this.getPane().children, edgeZIndex = -compare(-Infinity, Infinity); 7431 for (var i = 0, len = layers2.length, zIndex; i < len; i++) { 7432 zIndex = layers2[i].style.zIndex; 7433 if (layers2[i] !== this._container && zIndex) { 7434 edgeZIndex = compare(edgeZIndex, +zIndex); 7435 } 7436 } 7437 if (isFinite(edgeZIndex)) { 7438 this.options.zIndex = edgeZIndex + compare(-1, 1); 7439 this._updateZIndex(); 7440 } 7441 }, 7442 _updateOpacity: function() { 7443 if (!this._map) { 7444 return; 7445 } 7446 if (Browser.ielt9) { 7447 return; 7448 } 7449 setOpacity(this._container, this.options.opacity); 7450 var now = +/* @__PURE__ */ new Date(), nextFrame = false, willPrune = false; 7451 for (var key in this._tiles) { 7452 var tile = this._tiles[key]; 7453 if (!tile.current || !tile.loaded) { 7454 continue; 7455 } 7456 var fade = Math.min(1, (now - tile.loaded) / 200); 7457 setOpacity(tile.el, fade); 7458 if (fade < 1) { 7459 nextFrame = true; 7460 } else { 7461 if (tile.active) { 7462 willPrune = true; 7463 } else { 7464 this._onOpaqueTile(tile); 7465 } 7466 tile.active = true; 7467 } 7468 } 7469 if (willPrune && !this._noPrune) { 7470 this._pruneTiles(); 7471 } 7472 if (nextFrame) { 7473 cancelAnimFrame(this._fadeFrame); 7474 this._fadeFrame = requestAnimFrame(this._updateOpacity, this); 7475 } 7476 }, 7477 _onOpaqueTile: falseFn, 7478 _initContainer: function() { 7479 if (this._container) { 7480 return; 7481 } 7482 this._container = create$1("div", "leaflet-layer " + (this.options.className || "")); 7483 this._updateZIndex(); 7484 if (this.options.opacity < 1) { 7485 this._updateOpacity(); 7486 } 7487 this.getPane().appendChild(this._container); 7488 }, 7489 _updateLevels: function() { 7490 var zoom2 = this._tileZoom, maxZoom = this.options.maxZoom; 7491 if (zoom2 === void 0) { 7492 return void 0; 7493 } 7494 for (var z in this._levels) { 7495 z = Number(z); 7496 if (this._levels[z].el.children.length || z === zoom2) { 7497 this._levels[z].el.style.zIndex = maxZoom - Math.abs(zoom2 - z); 7498 this._onUpdateLevel(z); 7499 } else { 7500 remove(this._levels[z].el); 7501 this._removeTilesAtZoom(z); 7502 this._onRemoveLevel(z); 7503 delete this._levels[z]; 7504 } 7505 } 7506 var level = this._levels[zoom2], map = this._map; 7507 if (!level) { 7508 level = this._levels[zoom2] = {}; 7509 level.el = create$1("div", "leaflet-tile-container leaflet-zoom-animated", this._container); 7510 level.el.style.zIndex = maxZoom; 7511 level.origin = map.project(map.unproject(map.getPixelOrigin()), zoom2).round(); 7512 level.zoom = zoom2; 7513 this._setZoomTransform(level, map.getCenter(), map.getZoom()); 7514 falseFn(level.el.offsetWidth); 7515 this._onCreateLevel(level); 7516 } 7517 this._level = level; 7518 return level; 7519 }, 7520 _onUpdateLevel: falseFn, 7521 _onRemoveLevel: falseFn, 7522 _onCreateLevel: falseFn, 7523 _pruneTiles: function() { 7524 if (!this._map) { 7525 return; 7526 } 7527 var key, tile; 7528 var zoom2 = this._map.getZoom(); 7529 if (zoom2 > this.options.maxZoom || zoom2 < this.options.minZoom) { 7530 this._removeAllTiles(); 7531 return; 7532 } 7533 for (key in this._tiles) { 7534 tile = this._tiles[key]; 7535 tile.retain = tile.current; 7536 } 7537 for (key in this._tiles) { 7538 tile = this._tiles[key]; 7539 if (tile.current && !tile.active) { 7540 var coords = tile.coords; 7541 if (!this._retainParent(coords.x, coords.y, coords.z, coords.z - 5)) { 7542 this._retainChildren(coords.x, coords.y, coords.z, coords.z + 2); 7543 } 7544 } 7545 } 7546 for (key in this._tiles) { 7547 if (!this._tiles[key].retain) { 7548 this._removeTile(key); 7549 } 7550 } 7551 }, 7552 _removeTilesAtZoom: function(zoom2) { 7553 for (var key in this._tiles) { 7554 if (this._tiles[key].coords.z !== zoom2) { 7555 continue; 7556 } 7557 this._removeTile(key); 7558 } 7559 }, 7560 _removeAllTiles: function() { 7561 for (var key in this._tiles) { 7562 this._removeTile(key); 7563 } 7564 }, 7565 _invalidateAll: function() { 7566 for (var z in this._levels) { 7567 remove(this._levels[z].el); 7568 this._onRemoveLevel(Number(z)); 7569 delete this._levels[z]; 7570 } 7571 this._removeAllTiles(); 7572 this._tileZoom = void 0; 7573 }, 7574 _retainParent: function(x, y, z, minZoom) { 7575 var x2 = Math.floor(x / 2), y2 = Math.floor(y / 2), z2 = z - 1, coords2 = new Point(+x2, +y2); 7576 coords2.z = +z2; 7577 var key = this._tileCoordsToKey(coords2), tile = this._tiles[key]; 7578 if (tile && tile.active) { 7579 tile.retain = true; 7580 return true; 7581 } else if (tile && tile.loaded) { 7582 tile.retain = true; 7583 } 7584 if (z2 > minZoom) { 7585 return this._retainParent(x2, y2, z2, minZoom); 7586 } 7587 return false; 7588 }, 7589 _retainChildren: function(x, y, z, maxZoom) { 7590 for (var i = 2 * x; i < 2 * x + 2; i++) { 7591 for (var j = 2 * y; j < 2 * y + 2; j++) { 7592 var coords = new Point(i, j); 7593 coords.z = z + 1; 7594 var key = this._tileCoordsToKey(coords), tile = this._tiles[key]; 7595 if (tile && tile.active) { 7596 tile.retain = true; 7597 continue; 7598 } else if (tile && tile.loaded) { 7599 tile.retain = true; 7600 } 7601 if (z + 1 < maxZoom) { 7602 this._retainChildren(i, j, z + 1, maxZoom); 7603 } 7604 } 7605 } 7606 }, 7607 _resetView: function(e) { 7608 var animating = e && (e.pinch || e.flyTo); 7609 this._setView(this._map.getCenter(), this._map.getZoom(), animating, animating); 7610 }, 7611 _animateZoom: function(e) { 7612 this._setView(e.center, e.zoom, true, e.noUpdate); 7613 }, 7614 _clampZoom: function(zoom2) { 7615 var options = this.options; 7616 if (void 0 !== options.minNativeZoom && zoom2 < options.minNativeZoom) { 7617 return options.minNativeZoom; 7618 } 7619 if (void 0 !== options.maxNativeZoom && options.maxNativeZoom < zoom2) { 7620 return options.maxNativeZoom; 7621 } 7622 return zoom2; 7623 }, 7624 _setView: function(center, zoom2, noPrune, noUpdate) { 7625 var tileZoom = Math.round(zoom2); 7626 if (this.options.maxZoom !== void 0 && tileZoom > this.options.maxZoom || this.options.minZoom !== void 0 && tileZoom < this.options.minZoom) { 7627 tileZoom = void 0; 7628 } else { 7629 tileZoom = this._clampZoom(tileZoom); 7630 } 7631 var tileZoomChanged = this.options.updateWhenZooming && tileZoom !== this._tileZoom; 7632 if (!noUpdate || tileZoomChanged) { 7633 this._tileZoom = tileZoom; 7634 if (this._abortLoading) { 7635 this._abortLoading(); 7636 } 7637 this._updateLevels(); 7638 this._resetGrid(); 7639 if (tileZoom !== void 0) { 7640 this._update(center); 7641 } 7642 if (!noPrune) { 7643 this._pruneTiles(); 7644 } 7645 this._noPrune = !!noPrune; 7646 } 7647 this._setZoomTransforms(center, zoom2); 7648 }, 7649 _setZoomTransforms: function(center, zoom2) { 7650 for (var i in this._levels) { 7651 this._setZoomTransform(this._levels[i], center, zoom2); 7652 } 7653 }, 7654 _setZoomTransform: function(level, center, zoom2) { 7655 var scale2 = this._map.getZoomScale(zoom2, level.zoom), translate = level.origin.multiplyBy(scale2).subtract(this._map._getNewPixelOrigin(center, zoom2)).round(); 7656 if (Browser.any3d) { 7657 setTransform(level.el, translate, scale2); 7658 } else { 7659 setPosition(level.el, translate); 7660 } 7661 }, 7662 _resetGrid: function() { 7663 var map = this._map, crs = map.options.crs, tileSize = this._tileSize = this.getTileSize(), tileZoom = this._tileZoom; 7664 var bounds = this._map.getPixelWorldBounds(this._tileZoom); 7665 if (bounds) { 7666 this._globalTileRange = this._pxBoundsToTileRange(bounds); 7667 } 7668 this._wrapX = crs.wrapLng && !this.options.noWrap && [ 7669 Math.floor(map.project([0, crs.wrapLng[0]], tileZoom).x / tileSize.x), 7670 Math.ceil(map.project([0, crs.wrapLng[1]], tileZoom).x / tileSize.y) 7671 ]; 7672 this._wrapY = crs.wrapLat && !this.options.noWrap && [ 7673 Math.floor(map.project([crs.wrapLat[0], 0], tileZoom).y / tileSize.x), 7674 Math.ceil(map.project([crs.wrapLat[1], 0], tileZoom).y / tileSize.y) 7675 ]; 7676 }, 7677 _onMoveEnd: function() { 7678 if (!this._map || this._map._animatingZoom) { 7679 return; 7680 } 7681 this._update(); 7682 }, 7683 _getTiledPixelBounds: function(center) { 7684 var map = this._map, mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(), scale2 = map.getZoomScale(mapZoom, this._tileZoom), pixelCenter = map.project(center, this._tileZoom).floor(), halfSize = map.getSize().divideBy(scale2 * 2); 7685 return new Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize)); 7686 }, 7687 // Private method to load tiles in the grid's active zoom level according to map bounds 7688 _update: function(center) { 7689 var map = this._map; 7690 if (!map) { 7691 return; 7692 } 7693 var zoom2 = this._clampZoom(map.getZoom()); 7694 if (center === void 0) { 7695 center = map.getCenter(); 7696 } 7697 if (this._tileZoom === void 0) { 7698 return; 7699 } 7700 var pixelBounds = this._getTiledPixelBounds(center), tileRange = this._pxBoundsToTileRange(pixelBounds), tileCenter = tileRange.getCenter(), queue = [], margin = this.options.keepBuffer, noPruneRange = new Bounds( 7701 tileRange.getBottomLeft().subtract([margin, -margin]), 7702 tileRange.getTopRight().add([margin, -margin]) 7703 ); 7704 if (!(isFinite(tileRange.min.x) && isFinite(tileRange.min.y) && isFinite(tileRange.max.x) && isFinite(tileRange.max.y))) { 7705 throw new Error("Attempted to load an infinite number of tiles"); 7706 } 7707 for (var key in this._tiles) { 7708 var c = this._tiles[key].coords; 7709 if (c.z !== this._tileZoom || !noPruneRange.contains(new Point(c.x, c.y))) { 7710 this._tiles[key].current = false; 7711 } 7712 } 7713 if (Math.abs(zoom2 - this._tileZoom) > 1) { 7714 this._setView(center, zoom2); 7715 return; 7716 } 7717 for (var j = tileRange.min.y; j <= tileRange.max.y; j++) { 7718 for (var i = tileRange.min.x; i <= tileRange.max.x; i++) { 7719 var coords = new Point(i, j); 7720 coords.z = this._tileZoom; 7721 if (!this._isValidTile(coords)) { 7722 continue; 7723 } 7724 var tile = this._tiles[this._tileCoordsToKey(coords)]; 7725 if (tile) { 7726 tile.current = true; 7727 } else { 7728 queue.push(coords); 7729 } 7730 } 7731 } 7732 queue.sort(function(a, b) { 7733 return a.distanceTo(tileCenter) - b.distanceTo(tileCenter); 7734 }); 7735 if (queue.length !== 0) { 7736 if (!this._loading) { 7737 this._loading = true; 7738 this.fire("loading"); 7739 } 7740 var fragment = document.createDocumentFragment(); 7741 for (i = 0; i < queue.length; i++) { 7742 this._addTile(queue[i], fragment); 7743 } 7744 this._level.el.appendChild(fragment); 7745 } 7746 }, 7747 _isValidTile: function(coords) { 7748 var crs = this._map.options.crs; 7749 if (!crs.infinite) { 7750 var bounds = this._globalTileRange; 7751 if (!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x) || !crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y)) { 7752 return false; 7753 } 7754 } 7755 if (!this.options.bounds) { 7756 return true; 7757 } 7758 var tileBounds = this._tileCoordsToBounds(coords); 7759 return toLatLngBounds(this.options.bounds).overlaps(tileBounds); 7760 }, 7761 _keyToBounds: function(key) { 7762 return this._tileCoordsToBounds(this._keyToTileCoords(key)); 7763 }, 7764 _tileCoordsToNwSe: function(coords) { 7765 var map = this._map, tileSize = this.getTileSize(), nwPoint = coords.scaleBy(tileSize), sePoint = nwPoint.add(tileSize), nw = map.unproject(nwPoint, coords.z), se = map.unproject(sePoint, coords.z); 7766 return [nw, se]; 7767 }, 7768 // converts tile coordinates to its geographical bounds 7769 _tileCoordsToBounds: function(coords) { 7770 var bp = this._tileCoordsToNwSe(coords), bounds = new LatLngBounds(bp[0], bp[1]); 7771 if (!this.options.noWrap) { 7772 bounds = this._map.wrapLatLngBounds(bounds); 7773 } 7774 return bounds; 7775 }, 7776 // converts tile coordinates to key for the tile cache 7777 _tileCoordsToKey: function(coords) { 7778 return coords.x + ":" + coords.y + ":" + coords.z; 7779 }, 7780 // converts tile cache key to coordinates 7781 _keyToTileCoords: function(key) { 7782 var k = key.split(":"), coords = new Point(+k[0], +k[1]); 7783 coords.z = +k[2]; 7784 return coords; 7785 }, 7786 _removeTile: function(key) { 7787 var tile = this._tiles[key]; 7788 if (!tile) { 7789 return; 7790 } 7791 remove(tile.el); 7792 delete this._tiles[key]; 7793 this.fire("tileunload", { 7794 tile: tile.el, 7795 coords: this._keyToTileCoords(key) 7796 }); 7797 }, 7798 _initTile: function(tile) { 7799 addClass(tile, "leaflet-tile"); 7800 var tileSize = this.getTileSize(); 7801 tile.style.width = tileSize.x + "px"; 7802 tile.style.height = tileSize.y + "px"; 7803 tile.onselectstart = falseFn; 7804 tile.onmousemove = falseFn; 7805 if (Browser.ielt9 && this.options.opacity < 1) { 7806 setOpacity(tile, this.options.opacity); 7807 } 7808 }, 7809 _addTile: function(coords, container) { 7810 var tilePos = this._getTilePos(coords), key = this._tileCoordsToKey(coords); 7811 var tile = this.createTile(this._wrapCoords(coords), bind(this._tileReady, this, coords)); 7812 this._initTile(tile); 7813 if (this.createTile.length < 2) { 7814 requestAnimFrame(bind(this._tileReady, this, coords, null, tile)); 7815 } 7816 setPosition(tile, tilePos); 7817 this._tiles[key] = { 7818 el: tile, 7819 coords, 7820 current: true 7821 }; 7822 container.appendChild(tile); 7823 this.fire("tileloadstart", { 7824 tile, 7825 coords 7826 }); 7827 }, 7828 _tileReady: function(coords, err, tile) { 7829 if (err) { 7830 this.fire("tileerror", { 7831 error: err, 7832 tile, 7833 coords 7834 }); 7835 } 7836 var key = this._tileCoordsToKey(coords); 7837 tile = this._tiles[key]; 7838 if (!tile) { 7839 return; 7840 } 7841 tile.loaded = +/* @__PURE__ */ new Date(); 7842 if (this._map._fadeAnimated) { 7843 setOpacity(tile.el, 0); 7844 cancelAnimFrame(this._fadeFrame); 7845 this._fadeFrame = requestAnimFrame(this._updateOpacity, this); 7846 } else { 7847 tile.active = true; 7848 this._pruneTiles(); 7849 } 7850 if (!err) { 7851 addClass(tile.el, "leaflet-tile-loaded"); 7852 this.fire("tileload", { 7853 tile: tile.el, 7854 coords 7855 }); 7856 } 7857 if (this._noTilesToLoad()) { 7858 this._loading = false; 7859 this.fire("load"); 7860 if (Browser.ielt9 || !this._map._fadeAnimated) { 7861 requestAnimFrame(this._pruneTiles, this); 7862 } else { 7863 setTimeout(bind(this._pruneTiles, this), 250); 7864 } 7865 } 7866 }, 7867 _getTilePos: function(coords) { 7868 return coords.scaleBy(this.getTileSize()).subtract(this._level.origin); 7869 }, 7870 _wrapCoords: function(coords) { 7871 var newCoords = new Point( 7872 this._wrapX ? wrapNum(coords.x, this._wrapX) : coords.x, 7873 this._wrapY ? wrapNum(coords.y, this._wrapY) : coords.y 7874 ); 7875 newCoords.z = coords.z; 7876 return newCoords; 7877 }, 7878 _pxBoundsToTileRange: function(bounds) { 7879 var tileSize = this.getTileSize(); 7880 return new Bounds( 7881 bounds.min.unscaleBy(tileSize).floor(), 7882 bounds.max.unscaleBy(tileSize).ceil().subtract([1, 1]) 7883 ); 7884 }, 7885 _noTilesToLoad: function() { 7886 for (var key in this._tiles) { 7887 if (!this._tiles[key].loaded) { 7888 return false; 7889 } 7890 } 7891 return true; 7892 } 7893 }); 7894 function gridLayer(options) { 7895 return new GridLayer(options); 7896 } 7897 var TileLayer = GridLayer.extend({ 7898 // @section 7899 // @aka TileLayer options 7900 options: { 7901 // @option minZoom: Number = 0 7902 // The minimum zoom level down to which this layer will be displayed (inclusive). 7903 minZoom: 0, 7904 // @option maxZoom: Number = 18 7905 // The maximum zoom level up to which this layer will be displayed (inclusive). 7906 maxZoom: 18, 7907 // @option subdomains: String|String[] = 'abc' 7908 // 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. 7909 subdomains: "abc", 7910 // @option errorTileUrl: String = '' 7911 // URL to the tile image to show in place of the tile that failed to load. 7912 errorTileUrl: "", 7913 // @option zoomOffset: Number = 0 7914 // The zoom number used in tile URLs will be offset with this value. 7915 zoomOffset: 0, 7916 // @option tms: Boolean = false 7917 // If `true`, inverses Y axis numbering for tiles (turn this on for [TMS](https://en.wikipedia.org/wiki/Tile_Map_Service) services). 7918 tms: false, 7919 // @option zoomReverse: Boolean = false 7920 // If set to true, the zoom number used in tile URLs will be reversed (`maxZoom - zoom` instead of `zoom`) 7921 zoomReverse: false, 7922 // @option detectRetina: Boolean = false 7923 // 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. 7924 detectRetina: false, 7925 // @option crossOrigin: Boolean|String = false 7926 // Whether the crossOrigin attribute will be added to the tiles. 7927 // 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. 7928 // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values. 7929 crossOrigin: false, 7930 // @option referrerPolicy: Boolean|String = false 7931 // Whether the referrerPolicy attribute will be added to the tiles. 7932 // If a String is provided, all tiles will have their referrerPolicy attribute set to the String provided. 7933 // This may be needed if your map's rendering context has a strict default but your tile provider expects a valid referrer 7934 // (e.g. to validate an API token). 7935 // Refer to [HTMLImageElement.referrerPolicy](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/referrerPolicy) for valid String values. 7936 referrerPolicy: false 7937 }, 7938 initialize: function(url, options) { 7939 this._url = url; 7940 options = setOptions(this, options); 7941 if (options.detectRetina && Browser.retina && options.maxZoom > 0) { 7942 options.tileSize = Math.floor(options.tileSize / 2); 7943 if (!options.zoomReverse) { 7944 options.zoomOffset++; 7945 options.maxZoom = Math.max(options.minZoom, options.maxZoom - 1); 7946 } else { 7947 options.zoomOffset--; 7948 options.minZoom = Math.min(options.maxZoom, options.minZoom + 1); 7949 } 7950 options.minZoom = Math.max(0, options.minZoom); 7951 } else if (!options.zoomReverse) { 7952 options.maxZoom = Math.max(options.minZoom, options.maxZoom); 7953 } else { 7954 options.minZoom = Math.min(options.maxZoom, options.minZoom); 7955 } 7956 if (typeof options.subdomains === "string") { 7957 options.subdomains = options.subdomains.split(""); 7958 } 7959 this.on("tileunload", this._onTileRemove); 7960 }, 7961 // @method setUrl(url: String, noRedraw?: Boolean): this 7962 // Updates the layer's URL template and redraws it (unless `noRedraw` is set to `true`). 7963 // If the URL does not change, the layer will not be redrawn unless 7964 // the noRedraw parameter is set to false. 7965 setUrl: function(url, noRedraw) { 7966 if (this._url === url && noRedraw === void 0) { 7967 noRedraw = true; 7968 } 7969 this._url = url; 7970 if (!noRedraw) { 7971 this.redraw(); 7972 } 7973 return this; 7974 }, 7975 // @method createTile(coords: Object, done?: Function): HTMLElement 7976 // Called only internally, overrides GridLayer's [`createTile()`](#gridlayer-createtile) 7977 // to return an `<img>` HTML element with the appropriate image URL given `coords`. The `done` 7978 // callback is called when the tile has been loaded. 7979 createTile: function(coords, done) { 7980 var tile = document.createElement("img"); 7981 on(tile, "load", bind(this._tileOnLoad, this, done, tile)); 7982 on(tile, "error", bind(this._tileOnError, this, done, tile)); 7983 if (this.options.crossOrigin || this.options.crossOrigin === "") { 7984 tile.crossOrigin = this.options.crossOrigin === true ? "" : this.options.crossOrigin; 7985 } 7986 if (typeof this.options.referrerPolicy === "string") { 7987 tile.referrerPolicy = this.options.referrerPolicy; 7988 } 7989 tile.alt = ""; 7990 tile.src = this.getTileUrl(coords); 7991 return tile; 7992 }, 7993 // @section Extension methods 7994 // @uninheritable 7995 // Layers extending `TileLayer` might reimplement the following method. 7996 // @method getTileUrl(coords: Object): String 7997 // Called only internally, returns the URL for a tile given its coordinates. 7998 // Classes extending `TileLayer` can override this function to provide custom tile URL naming schemes. 7999 getTileUrl: function(coords) { 8000 var data = { 8001 r: Browser.retina ? "@2x" : "", 8002 s: this._getSubdomain(coords), 8003 x: coords.x, 8004 y: coords.y, 8005 z: this._getZoomForUrl() 8006 }; 8007 if (this._map && !this._map.options.crs.infinite) { 8008 var invertedY = this._globalTileRange.max.y - coords.y; 8009 if (this.options.tms) { 8010 data["y"] = invertedY; 8011 } 8012 data["-y"] = invertedY; 8013 } 8014 return template(this._url, extend(data, this.options)); 8015 }, 8016 _tileOnLoad: function(done, tile) { 8017 if (Browser.ielt9) { 8018 setTimeout(bind(done, this, null, tile), 0); 8019 } else { 8020 done(null, tile); 8021 } 8022 }, 8023 _tileOnError: function(done, tile, e) { 8024 var errorUrl = this.options.errorTileUrl; 8025 if (errorUrl && tile.getAttribute("src") !== errorUrl) { 8026 tile.src = errorUrl; 8027 } 8028 done(e, tile); 8029 }, 8030 _onTileRemove: function(e) { 8031 e.tile.onload = null; 8032 }, 8033 _getZoomForUrl: function() { 8034 var zoom2 = this._tileZoom, maxZoom = this.options.maxZoom, zoomReverse = this.options.zoomReverse, zoomOffset = this.options.zoomOffset; 8035 if (zoomReverse) { 8036 zoom2 = maxZoom - zoom2; 8037 } 8038 return zoom2 + zoomOffset; 8039 }, 8040 _getSubdomain: function(tilePoint) { 8041 var index2 = Math.abs(tilePoint.x + tilePoint.y) % this.options.subdomains.length; 8042 return this.options.subdomains[index2]; 8043 }, 8044 // stops loading all tiles in the background layer 8045 _abortLoading: function() { 8046 var i, tile; 8047 for (i in this._tiles) { 8048 if (this._tiles[i].coords.z !== this._tileZoom) { 8049 tile = this._tiles[i].el; 8050 tile.onload = falseFn; 8051 tile.onerror = falseFn; 8052 if (!tile.complete) { 8053 tile.src = emptyImageUrl; 8054 var coords = this._tiles[i].coords; 8055 remove(tile); 8056 delete this._tiles[i]; 8057 this.fire("tileabort", { 8058 tile, 8059 coords 8060 }); 8061 } 8062 } 8063 } 8064 }, 8065 _removeTile: function(key) { 8066 var tile = this._tiles[key]; 8067 if (!tile) { 8068 return; 8069 } 8070 tile.el.setAttribute("src", emptyImageUrl); 8071 return GridLayer.prototype._removeTile.call(this, key); 8072 }, 8073 _tileReady: function(coords, err, tile) { 8074 if (!this._map || tile && tile.getAttribute("src") === emptyImageUrl) { 8075 return; 8076 } 8077 return GridLayer.prototype._tileReady.call(this, coords, err, tile); 8078 } 8079 }); 8080 function tileLayer(url, options) { 8081 return new TileLayer(url, options); 8082 } 8083 var TileLayerWMS = TileLayer.extend({ 8084 // @section 8085 // @aka TileLayer.WMS options 8086 // If any custom options not documented here are used, they will be sent to the 8087 // WMS server as extra parameters in each request URL. This can be useful for 8088 // [non-standard vendor WMS parameters](https://docs.geoserver.org/stable/en/user/services/wms/vendor.html). 8089 defaultWmsParams: { 8090 service: "WMS", 8091 request: "GetMap", 8092 // @option layers: String = '' 8093 // **(required)** Comma-separated list of WMS layers to show. 8094 layers: "", 8095 // @option styles: String = '' 8096 // Comma-separated list of WMS styles. 8097 styles: "", 8098 // @option format: String = 'image/jpeg' 8099 // WMS image format (use `'image/png'` for layers with transparency). 8100 format: "image/jpeg", 8101 // @option transparent: Boolean = false 8102 // If `true`, the WMS service will return images with transparency. 8103 transparent: false, 8104 // @option version: String = '1.1.1' 8105 // Version of the WMS service to use 8106 version: "1.1.1" 8107 }, 8108 options: { 8109 // @option crs: CRS = null 8110 // Coordinate Reference System to use for the WMS requests, defaults to 8111 // map CRS. Don't change this if you're not sure what it means. 8112 crs: null, 8113 // @option uppercase: Boolean = false 8114 // If `true`, WMS request parameter keys will be uppercase. 8115 uppercase: false 8116 }, 8117 initialize: function(url, options) { 8118 this._url = url; 8119 var wmsParams = extend({}, this.defaultWmsParams); 8120 for (var i in options) { 8121 if (!(i in this.options)) { 8122 wmsParams[i] = options[i]; 8123 } 8124 } 8125 options = setOptions(this, options); 8126 var realRetina = options.detectRetina && Browser.retina ? 2 : 1; 8127 var tileSize = this.getTileSize(); 8128 wmsParams.width = tileSize.x * realRetina; 8129 wmsParams.height = tileSize.y * realRetina; 8130 this.wmsParams = wmsParams; 8131 }, 8132 onAdd: function(map) { 8133 this._crs = this.options.crs || map.options.crs; 8134 this._wmsVersion = parseFloat(this.wmsParams.version); 8135 var projectionKey = this._wmsVersion >= 1.3 ? "crs" : "srs"; 8136 this.wmsParams[projectionKey] = this._crs.code; 8137 TileLayer.prototype.onAdd.call(this, map); 8138 }, 8139 getTileUrl: function(coords) { 8140 var tileBounds = this._tileCoordsToNwSe(coords), crs = this._crs, bounds = toBounds(crs.project(tileBounds[0]), crs.project(tileBounds[1])), min2 = bounds.min, max2 = bounds.max, bbox = (this._wmsVersion >= 1.3 && this._crs === EPSG4326 ? [min2.y, min2.x, max2.y, max2.x] : [min2.x, min2.y, max2.x, max2.y]).join(","), url = TileLayer.prototype.getTileUrl.call(this, coords); 8141 return url + getParamString(this.wmsParams, url, this.options.uppercase) + (this.options.uppercase ? "&BBOX=" : "&bbox=") + bbox; 8142 }, 8143 // @method setParams(params: Object, noRedraw?: Boolean): this 8144 // Merges an object with the new parameters and re-requests tiles on the current screen (unless `noRedraw` was set to true). 8145 setParams: function(params, noRedraw) { 8146 extend(this.wmsParams, params); 8147 if (!noRedraw) { 8148 this.redraw(); 8149 } 8150 return this; 8151 } 8152 }); 8153 function tileLayerWMS(url, options) { 8154 return new TileLayerWMS(url, options); 8155 } 8156 TileLayer.WMS = TileLayerWMS; 8157 tileLayer.wms = tileLayerWMS; 8158 var Renderer = Layer.extend({ 8159 // @section 8160 // @aka Renderer options 8161 options: { 8162 // @option padding: Number = 0.1 8163 // How much to extend the clip area around the map view (relative to its size) 8164 // e.g. 0.1 would be 10% of map view in each direction 8165 padding: 0.1 8166 }, 8167 initialize: function(options) { 8168 setOptions(this, options); 8169 stamp(this); 8170 this._layers = this._layers || {}; 8171 }, 8172 onAdd: function() { 8173 if (!this._container) { 8174 this._initContainer(); 8175 addClass(this._container, "leaflet-zoom-animated"); 8176 } 8177 this.getPane().appendChild(this._container); 8178 this._update(); 8179 this.on("update", this._updatePaths, this); 8180 }, 8181 onRemove: function() { 8182 this.off("update", this._updatePaths, this); 8183 this._destroyContainer(); 8184 }, 8185 getEvents: function() { 8186 var events = { 8187 viewreset: this._reset, 8188 zoom: this._onZoom, 8189 moveend: this._update, 8190 zoomend: this._onZoomEnd 8191 }; 8192 if (this._zoomAnimated) { 8193 events.zoomanim = this._onAnimZoom; 8194 } 8195 return events; 8196 }, 8197 _onAnimZoom: function(ev) { 8198 this._updateTransform(ev.center, ev.zoom); 8199 }, 8200 _onZoom: function() { 8201 this._updateTransform(this._map.getCenter(), this._map.getZoom()); 8202 }, 8203 _updateTransform: function(center, zoom2) { 8204 var scale2 = this._map.getZoomScale(zoom2, this._zoom), viewHalf = this._map.getSize().multiplyBy(0.5 + this.options.padding), currentCenterPoint = this._map.project(this._center, zoom2), topLeftOffset = viewHalf.multiplyBy(-scale2).add(currentCenterPoint).subtract(this._map._getNewPixelOrigin(center, zoom2)); 8205 if (Browser.any3d) { 8206 setTransform(this._container, topLeftOffset, scale2); 8207 } else { 8208 setPosition(this._container, topLeftOffset); 8209 } 8210 }, 8211 _reset: function() { 8212 this._update(); 8213 this._updateTransform(this._center, this._zoom); 8214 for (var id in this._layers) { 8215 this._layers[id]._reset(); 8216 } 8217 }, 8218 _onZoomEnd: function() { 8219 for (var id in this._layers) { 8220 this._layers[id]._project(); 8221 } 8222 }, 8223 _updatePaths: function() { 8224 for (var id in this._layers) { 8225 this._layers[id]._update(); 8226 } 8227 }, 8228 _update: function() { 8229 var p = this.options.padding, size = this._map.getSize(), min2 = this._map.containerPointToLayerPoint(size.multiplyBy(-p)).round(); 8230 this._bounds = new Bounds(min2, min2.add(size.multiplyBy(1 + p * 2)).round()); 8231 this._center = this._map.getCenter(); 8232 this._zoom = this._map.getZoom(); 8233 } 8234 }); 8235 var Canvas = Renderer.extend({ 8236 // @section 8237 // @aka Canvas options 8238 options: { 8239 // @option tolerance: Number = 0 8240 // How much to extend the click tolerance around a path/object on the map. 8241 tolerance: 0 8242 }, 8243 getEvents: function() { 8244 var events = Renderer.prototype.getEvents.call(this); 8245 events.viewprereset = this._onViewPreReset; 8246 return events; 8247 }, 8248 _onViewPreReset: function() { 8249 this._postponeUpdatePaths = true; 8250 }, 8251 onAdd: function() { 8252 Renderer.prototype.onAdd.call(this); 8253 this._draw(); 8254 }, 8255 _initContainer: function() { 8256 var container = this._container = document.createElement("canvas"); 8257 on(container, "mousemove", this._onMouseMove, this); 8258 on(container, "click dblclick mousedown mouseup contextmenu", this._onClick, this); 8259 on(container, "mouseout", this._handleMouseOut, this); 8260 container["_leaflet_disable_events"] = true; 8261 this._ctx = container.getContext("2d"); 8262 }, 8263 _destroyContainer: function() { 8264 cancelAnimFrame(this._redrawRequest); 8265 delete this._ctx; 8266 remove(this._container); 8267 off(this._container); 8268 delete this._container; 8269 }, 8270 _updatePaths: function() { 8271 if (this._postponeUpdatePaths) { 8272 return; 8273 } 8274 var layer; 8275 this._redrawBounds = null; 8276 for (var id in this._layers) { 8277 layer = this._layers[id]; 8278 layer._update(); 8279 } 8280 this._redraw(); 8281 }, 8282 _update: function() { 8283 if (this._map._animatingZoom && this._bounds) { 8284 return; 8285 } 8286 Renderer.prototype._update.call(this); 8287 var b = this._bounds, container = this._container, size = b.getSize(), m = Browser.retina ? 2 : 1; 8288 setPosition(container, b.min); 8289 container.width = m * size.x; 8290 container.height = m * size.y; 8291 container.style.width = size.x + "px"; 8292 container.style.height = size.y + "px"; 8293 if (Browser.retina) { 8294 this._ctx.scale(2, 2); 8295 } 8296 this._ctx.translate(-b.min.x, -b.min.y); 8297 this.fire("update"); 8298 }, 8299 _reset: function() { 8300 Renderer.prototype._reset.call(this); 8301 if (this._postponeUpdatePaths) { 8302 this._postponeUpdatePaths = false; 8303 this._updatePaths(); 8304 } 8305 }, 8306 _initPath: function(layer) { 8307 this._updateDashArray(layer); 8308 this._layers[stamp(layer)] = layer; 8309 var order2 = layer._order = { 8310 layer, 8311 prev: this._drawLast, 8312 next: null 8313 }; 8314 if (this._drawLast) { 8315 this._drawLast.next = order2; 8316 } 8317 this._drawLast = order2; 8318 this._drawFirst = this._drawFirst || this._drawLast; 8319 }, 8320 _addPath: function(layer) { 8321 this._requestRedraw(layer); 8322 }, 8323 _removePath: function(layer) { 8324 var order2 = layer._order; 8325 var next = order2.next; 8326 var prev = order2.prev; 8327 if (next) { 8328 next.prev = prev; 8329 } else { 8330 this._drawLast = prev; 8331 } 8332 if (prev) { 8333 prev.next = next; 8334 } else { 8335 this._drawFirst = next; 8336 } 8337 delete layer._order; 8338 delete this._layers[stamp(layer)]; 8339 this._requestRedraw(layer); 8340 }, 8341 _updatePath: function(layer) { 8342 this._extendRedrawBounds(layer); 8343 layer._project(); 8344 layer._update(); 8345 this._requestRedraw(layer); 8346 }, 8347 _updateStyle: function(layer) { 8348 this._updateDashArray(layer); 8349 this._requestRedraw(layer); 8350 }, 8351 _updateDashArray: function(layer) { 8352 if (typeof layer.options.dashArray === "string") { 8353 var parts = layer.options.dashArray.split(/[, ]+/), dashArray = [], dashValue, i; 8354 for (i = 0; i < parts.length; i++) { 8355 dashValue = Number(parts[i]); 8356 if (isNaN(dashValue)) { 8357 return; 8358 } 8359 dashArray.push(dashValue); 8360 } 8361 layer.options._dashArray = dashArray; 8362 } else { 8363 layer.options._dashArray = layer.options.dashArray; 8364 } 8365 }, 8366 _requestRedraw: function(layer) { 8367 if (!this._map) { 8368 return; 8369 } 8370 this._extendRedrawBounds(layer); 8371 this._redrawRequest = this._redrawRequest || requestAnimFrame(this._redraw, this); 8372 }, 8373 _extendRedrawBounds: function(layer) { 8374 if (layer._pxBounds) { 8375 var padding = (layer.options.weight || 0) + 1; 8376 this._redrawBounds = this._redrawBounds || new Bounds(); 8377 this._redrawBounds.extend(layer._pxBounds.min.subtract([padding, padding])); 8378 this._redrawBounds.extend(layer._pxBounds.max.add([padding, padding])); 8379 } 8380 }, 8381 _redraw: function() { 8382 this._redrawRequest = null; 8383 if (this._redrawBounds) { 8384 this._redrawBounds.min._floor(); 8385 this._redrawBounds.max._ceil(); 8386 } 8387 this._clear(); 8388 this._draw(); 8389 this._redrawBounds = null; 8390 }, 8391 _clear: function() { 8392 var bounds = this._redrawBounds; 8393 if (bounds) { 8394 var size = bounds.getSize(); 8395 this._ctx.clearRect(bounds.min.x, bounds.min.y, size.x, size.y); 8396 } else { 8397 this._ctx.save(); 8398 this._ctx.setTransform(1, 0, 0, 1, 0, 0); 8399 this._ctx.clearRect(0, 0, this._container.width, this._container.height); 8400 this._ctx.restore(); 8401 } 8402 }, 8403 _draw: function() { 8404 var layer, bounds = this._redrawBounds; 8405 this._ctx.save(); 8406 if (bounds) { 8407 var size = bounds.getSize(); 8408 this._ctx.beginPath(); 8409 this._ctx.rect(bounds.min.x, bounds.min.y, size.x, size.y); 8410 this._ctx.clip(); 8411 } 8412 this._drawing = true; 8413 for (var order2 = this._drawFirst; order2; order2 = order2.next) { 8414 layer = order2.layer; 8415 if (!bounds || layer._pxBounds && layer._pxBounds.intersects(bounds)) { 8416 layer._updatePath(); 8417 } 8418 } 8419 this._drawing = false; 8420 this._ctx.restore(); 8421 }, 8422 _updatePoly: function(layer, closed) { 8423 if (!this._drawing) { 8424 return; 8425 } 8426 var i, j, len2, p, parts = layer._parts, len = parts.length, ctx = this._ctx; 8427 if (!len) { 8428 return; 8429 } 8430 ctx.beginPath(); 8431 for (i = 0; i < len; i++) { 8432 for (j = 0, len2 = parts[i].length; j < len2; j++) { 8433 p = parts[i][j]; 8434 ctx[j ? "lineTo" : "moveTo"](p.x, p.y); 8435 } 8436 if (closed) { 8437 ctx.closePath(); 8438 } 8439 } 8440 this._fillStroke(ctx, layer); 8441 }, 8442 _updateCircle: function(layer) { 8443 if (!this._drawing || layer._empty()) { 8444 return; 8445 } 8446 var p = layer._point, ctx = this._ctx, r = Math.max(Math.round(layer._radius), 1), s = (Math.max(Math.round(layer._radiusY), 1) || r) / r; 8447 if (s !== 1) { 8448 ctx.save(); 8449 ctx.scale(1, s); 8450 } 8451 ctx.beginPath(); 8452 ctx.arc(p.x, p.y / s, r, 0, Math.PI * 2, false); 8453 if (s !== 1) { 8454 ctx.restore(); 8455 } 8456 this._fillStroke(ctx, layer); 8457 }, 8458 _fillStroke: function(ctx, layer) { 8459 var options = layer.options; 8460 if (options.fill) { 8461 ctx.globalAlpha = options.fillOpacity; 8462 ctx.fillStyle = options.fillColor || options.color; 8463 ctx.fill(options.fillRule || "evenodd"); 8464 } 8465 if (options.stroke && options.weight !== 0) { 8466 if (ctx.setLineDash) { 8467 ctx.setLineDash(layer.options && layer.options._dashArray || []); 8468 } 8469 ctx.globalAlpha = options.opacity; 8470 ctx.lineWidth = options.weight; 8471 ctx.strokeStyle = options.color; 8472 ctx.lineCap = options.lineCap; 8473 ctx.lineJoin = options.lineJoin; 8474 ctx.stroke(); 8475 } 8476 }, 8477 // Canvas obviously doesn't have mouse events for individual drawn objects, 8478 // so we emulate that by calculating what's under the mouse on mousemove/click manually 8479 _onClick: function(e) { 8480 var point = this._map.mouseEventToLayerPoint(e), layer, clickedLayer; 8481 for (var order2 = this._drawFirst; order2; order2 = order2.next) { 8482 layer = order2.layer; 8483 if (layer.options.interactive && layer._containsPoint(point)) { 8484 if (!(e.type === "click" || e.type === "preclick") || !this._map._draggableMoved(layer)) { 8485 clickedLayer = layer; 8486 } 8487 } 8488 } 8489 this._fireEvent(clickedLayer ? [clickedLayer] : false, e); 8490 }, 8491 _onMouseMove: function(e) { 8492 if (!this._map || this._map.dragging.moving() || this._map._animatingZoom) { 8493 return; 8494 } 8495 var point = this._map.mouseEventToLayerPoint(e); 8496 this._handleMouseHover(e, point); 8497 }, 8498 _handleMouseOut: function(e) { 8499 var layer = this._hoveredLayer; 8500 if (layer) { 8501 removeClass(this._container, "leaflet-interactive"); 8502 this._fireEvent([layer], e, "mouseout"); 8503 this._hoveredLayer = null; 8504 this._mouseHoverThrottled = false; 8505 } 8506 }, 8507 _handleMouseHover: function(e, point) { 8508 if (this._mouseHoverThrottled) { 8509 return; 8510 } 8511 var layer, candidateHoveredLayer; 8512 for (var order2 = this._drawFirst; order2; order2 = order2.next) { 8513 layer = order2.layer; 8514 if (layer.options.interactive && layer._containsPoint(point)) { 8515 candidateHoveredLayer = layer; 8516 } 8517 } 8518 if (candidateHoveredLayer !== this._hoveredLayer) { 8519 this._handleMouseOut(e); 8520 if (candidateHoveredLayer) { 8521 addClass(this._container, "leaflet-interactive"); 8522 this._fireEvent([candidateHoveredLayer], e, "mouseover"); 8523 this._hoveredLayer = candidateHoveredLayer; 8524 } 8525 } 8526 this._fireEvent(this._hoveredLayer ? [this._hoveredLayer] : false, e); 8527 this._mouseHoverThrottled = true; 8528 setTimeout(bind(function() { 8529 this._mouseHoverThrottled = false; 8530 }, this), 32); 8531 }, 8532 _fireEvent: function(layers2, e, type) { 8533 this._map._fireDOMEvent(e, type || e.type, layers2); 8534 }, 8535 _bringToFront: function(layer) { 8536 var order2 = layer._order; 8537 if (!order2) { 8538 return; 8539 } 8540 var next = order2.next; 8541 var prev = order2.prev; 8542 if (next) { 8543 next.prev = prev; 8544 } else { 8545 return; 8546 } 8547 if (prev) { 8548 prev.next = next; 8549 } else if (next) { 8550 this._drawFirst = next; 8551 } 8552 order2.prev = this._drawLast; 8553 this._drawLast.next = order2; 8554 order2.next = null; 8555 this._drawLast = order2; 8556 this._requestRedraw(layer); 8557 }, 8558 _bringToBack: function(layer) { 8559 var order2 = layer._order; 8560 if (!order2) { 8561 return; 8562 } 8563 var next = order2.next; 8564 var prev = order2.prev; 8565 if (prev) { 8566 prev.next = next; 8567 } else { 8568 return; 8569 } 8570 if (next) { 8571 next.prev = prev; 8572 } else if (prev) { 8573 this._drawLast = prev; 8574 } 8575 order2.prev = null; 8576 order2.next = this._drawFirst; 8577 this._drawFirst.prev = order2; 8578 this._drawFirst = order2; 8579 this._requestRedraw(layer); 8580 } 8581 }); 8582 function canvas(options) { 8583 return Browser.canvas ? new Canvas(options) : null; 8584 } 8585 var vmlCreate = function() { 8586 try { 8587 document.namespaces.add("lvml", "urn:schemas-microsoft-com:vml"); 8588 return function(name) { 8589 return document.createElement("<lvml:" + name + ' class="lvml">'); 8590 }; 8591 } catch (e) { 8592 } 8593 return function(name) { 8594 return document.createElement("<" + name + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">'); 8595 }; 8596 }(); 8597 var vmlMixin = { 8598 _initContainer: function() { 8599 this._container = create$1("div", "leaflet-vml-container"); 8600 }, 8601 _update: function() { 8602 if (this._map._animatingZoom) { 8603 return; 8604 } 8605 Renderer.prototype._update.call(this); 8606 this.fire("update"); 8607 }, 8608 _initPath: function(layer) { 8609 var container = layer._container = vmlCreate("shape"); 8610 addClass(container, "leaflet-vml-shape " + (this.options.className || "")); 8611 container.coordsize = "1 1"; 8612 layer._path = vmlCreate("path"); 8613 container.appendChild(layer._path); 8614 this._updateStyle(layer); 8615 this._layers[stamp(layer)] = layer; 8616 }, 8617 _addPath: function(layer) { 8618 var container = layer._container; 8619 this._container.appendChild(container); 8620 if (layer.options.interactive) { 8621 layer.addInteractiveTarget(container); 8622 } 8623 }, 8624 _removePath: function(layer) { 8625 var container = layer._container; 8626 remove(container); 8627 layer.removeInteractiveTarget(container); 8628 delete this._layers[stamp(layer)]; 8629 }, 8630 _updateStyle: function(layer) { 8631 var stroke = layer._stroke, fill = layer._fill, options = layer.options, container = layer._container; 8632 container.stroked = !!options.stroke; 8633 container.filled = !!options.fill; 8634 if (options.stroke) { 8635 if (!stroke) { 8636 stroke = layer._stroke = vmlCreate("stroke"); 8637 } 8638 container.appendChild(stroke); 8639 stroke.weight = options.weight + "px"; 8640 stroke.color = options.color; 8641 stroke.opacity = options.opacity; 8642 if (options.dashArray) { 8643 stroke.dashStyle = isArray(options.dashArray) ? options.dashArray.join(" ") : options.dashArray.replace(/( *, *)/g, " "); 8644 } else { 8645 stroke.dashStyle = ""; 8646 } 8647 stroke.endcap = options.lineCap.replace("butt", "flat"); 8648 stroke.joinstyle = options.lineJoin; 8649 } else if (stroke) { 8650 container.removeChild(stroke); 8651 layer._stroke = null; 8652 } 8653 if (options.fill) { 8654 if (!fill) { 8655 fill = layer._fill = vmlCreate("fill"); 8656 } 8657 container.appendChild(fill); 8658 fill.color = options.fillColor || options.color; 8659 fill.opacity = options.fillOpacity; 8660 } else if (fill) { 8661 container.removeChild(fill); 8662 layer._fill = null; 8663 } 8664 }, 8665 _updateCircle: function(layer) { 8666 var p = layer._point.round(), r = Math.round(layer._radius), r2 = Math.round(layer._radiusY || r); 8667 this._setPath(layer, layer._empty() ? "M0 0" : "AL " + p.x + "," + p.y + " " + r + "," + r2 + " 0," + 65535 * 360); 8668 }, 8669 _setPath: function(layer, path) { 8670 layer._path.v = path; 8671 }, 8672 _bringToFront: function(layer) { 8673 toFront(layer._container); 8674 }, 8675 _bringToBack: function(layer) { 8676 toBack(layer._container); 8677 } 8678 }; 8679 var create = Browser.vml ? vmlCreate : svgCreate; 8680 var SVG = Renderer.extend({ 8681 _initContainer: function() { 8682 this._container = create("svg"); 8683 this._container.setAttribute("pointer-events", "none"); 8684 this._rootGroup = create("g"); 8685 this._container.appendChild(this._rootGroup); 8686 }, 8687 _destroyContainer: function() { 8688 remove(this._container); 8689 off(this._container); 8690 delete this._container; 8691 delete this._rootGroup; 8692 delete this._svgSize; 8693 }, 8694 _update: function() { 8695 if (this._map._animatingZoom && this._bounds) { 8696 return; 8697 } 8698 Renderer.prototype._update.call(this); 8699 var b = this._bounds, size = b.getSize(), container = this._container; 8700 if (!this._svgSize || !this._svgSize.equals(size)) { 8701 this._svgSize = size; 8702 container.setAttribute("width", size.x); 8703 container.setAttribute("height", size.y); 8704 } 8705 setPosition(container, b.min); 8706 container.setAttribute("viewBox", [b.min.x, b.min.y, size.x, size.y].join(" ")); 8707 this.fire("update"); 8708 }, 8709 // methods below are called by vector layers implementations 8710 _initPath: function(layer) { 8711 var path = layer._path = create("path"); 8712 if (layer.options.className) { 8713 addClass(path, layer.options.className); 8714 } 8715 if (layer.options.interactive) { 8716 addClass(path, "leaflet-interactive"); 8717 } 8718 this._updateStyle(layer); 8719 this._layers[stamp(layer)] = layer; 8720 }, 8721 _addPath: function(layer) { 8722 if (!this._rootGroup) { 8723 this._initContainer(); 8724 } 8725 this._rootGroup.appendChild(layer._path); 8726 layer.addInteractiveTarget(layer._path); 8727 }, 8728 _removePath: function(layer) { 8729 remove(layer._path); 8730 layer.removeInteractiveTarget(layer._path); 8731 delete this._layers[stamp(layer)]; 8732 }, 8733 _updatePath: function(layer) { 8734 layer._project(); 8735 layer._update(); 8736 }, 8737 _updateStyle: function(layer) { 8738 var path = layer._path, options = layer.options; 8739 if (!path) { 8740 return; 8741 } 8742 if (options.stroke) { 8743 path.setAttribute("stroke", options.color); 8744 path.setAttribute("stroke-opacity", options.opacity); 8745 path.setAttribute("stroke-width", options.weight); 8746 path.setAttribute("stroke-linecap", options.lineCap); 8747 path.setAttribute("stroke-linejoin", options.lineJoin); 8748 if (options.dashArray) { 8749 path.setAttribute("stroke-dasharray", options.dashArray); 8750 } else { 8751 path.removeAttribute("stroke-dasharray"); 8752 } 8753 if (options.dashOffset) { 8754 path.setAttribute("stroke-dashoffset", options.dashOffset); 8755 } else { 8756 path.removeAttribute("stroke-dashoffset"); 8757 } 8758 } else { 8759 path.setAttribute("stroke", "none"); 8760 } 8761 if (options.fill) { 8762 path.setAttribute("fill", options.fillColor || options.color); 8763 path.setAttribute("fill-opacity", options.fillOpacity); 8764 path.setAttribute("fill-rule", options.fillRule || "evenodd"); 8765 } else { 8766 path.setAttribute("fill", "none"); 8767 } 8768 }, 8769 _updatePoly: function(layer, closed) { 8770 this._setPath(layer, pointsToPath(layer._parts, closed)); 8771 }, 8772 _updateCircle: function(layer) { 8773 var p = layer._point, r = Math.max(Math.round(layer._radius), 1), r2 = Math.max(Math.round(layer._radiusY), 1) || r, arc = "a" + r + "," + r2 + " 0 1,0 "; 8774 var d = layer._empty() ? "M0 0" : "M" + (p.x - r) + "," + p.y + arc + r * 2 + ",0 " + arc + -r * 2 + ",0 "; 8775 this._setPath(layer, d); 8776 }, 8777 _setPath: function(layer, path) { 8778 layer._path.setAttribute("d", path); 8779 }, 8780 // SVG does not have the concept of zIndex so we resort to changing the DOM order of elements 8781 _bringToFront: function(layer) { 8782 toFront(layer._path); 8783 }, 8784 _bringToBack: function(layer) { 8785 toBack(layer._path); 8786 } 8787 }); 8788 if (Browser.vml) { 8789 SVG.include(vmlMixin); 8790 } 8791 function svg(options) { 8792 return Browser.svg || Browser.vml ? new SVG(options) : null; 8793 } 8794 Map2.include({ 8795 // @namespace Map; @method getRenderer(layer: Path): Renderer 8796 // Returns the instance of `Renderer` that should be used to render the given 8797 // `Path`. It will ensure that the `renderer` options of the map and paths 8798 // are respected, and that the renderers do exist on the map. 8799 getRenderer: function(layer) { 8800 var renderer = layer.options.renderer || this._getPaneRenderer(layer.options.pane) || this.options.renderer || this._renderer; 8801 if (!renderer) { 8802 renderer = this._renderer = this._createRenderer(); 8803 } 8804 if (!this.hasLayer(renderer)) { 8805 this.addLayer(renderer); 8806 } 8807 return renderer; 8808 }, 8809 _getPaneRenderer: function(name) { 8810 if (name === "overlayPane" || name === void 0) { 8811 return false; 8812 } 8813 var renderer = this._paneRenderers[name]; 8814 if (renderer === void 0) { 8815 renderer = this._createRenderer({ pane: name }); 8816 this._paneRenderers[name] = renderer; 8817 } 8818 return renderer; 8819 }, 8820 _createRenderer: function(options) { 8821 return this.options.preferCanvas && canvas(options) || svg(options); 8822 } 8823 }); 8824 var Rectangle = Polygon.extend({ 8825 initialize: function(latLngBounds, options) { 8826 Polygon.prototype.initialize.call(this, this._boundsToLatLngs(latLngBounds), options); 8827 }, 8828 // @method setBounds(latLngBounds: LatLngBounds): this 8829 // Redraws the rectangle with the passed bounds. 8830 setBounds: function(latLngBounds) { 8831 return this.setLatLngs(this._boundsToLatLngs(latLngBounds)); 8832 }, 8833 _boundsToLatLngs: function(latLngBounds) { 8834 latLngBounds = toLatLngBounds(latLngBounds); 8835 return [ 8836 latLngBounds.getSouthWest(), 8837 latLngBounds.getNorthWest(), 8838 latLngBounds.getNorthEast(), 8839 latLngBounds.getSouthEast() 8840 ]; 8841 } 8842 }); 8843 function rectangle(latLngBounds, options) { 8844 return new Rectangle(latLngBounds, options); 8845 } 8846 SVG.create = create; 8847 SVG.pointsToPath = pointsToPath; 8848 GeoJSON.geometryToLayer = geometryToLayer; 8849 GeoJSON.coordsToLatLng = coordsToLatLng; 8850 GeoJSON.coordsToLatLngs = coordsToLatLngs; 8851 GeoJSON.latLngToCoords = latLngToCoords; 8852 GeoJSON.latLngsToCoords = latLngsToCoords; 8853 GeoJSON.getFeature = getFeature; 8854 GeoJSON.asFeature = asFeature; 8855 Map2.mergeOptions({ 8856 // @option boxZoom: Boolean = true 8857 // Whether the map can be zoomed to a rectangular area specified by 8858 // dragging the mouse while pressing the shift key. 8859 boxZoom: true 8860 }); 8861 var BoxZoom = Handler.extend({ 8862 initialize: function(map) { 8863 this._map = map; 8864 this._container = map._container; 8865 this._pane = map._panes.overlayPane; 8866 this._resetStateTimeout = 0; 8867 map.on("unload", this._destroy, this); 8868 }, 8869 addHooks: function() { 8870 on(this._container, "mousedown", this._onMouseDown, this); 8871 }, 8872 removeHooks: function() { 8873 off(this._container, "mousedown", this._onMouseDown, this); 8874 }, 8875 moved: function() { 8876 return this._moved; 8877 }, 8878 _destroy: function() { 8879 remove(this._pane); 8880 delete this._pane; 8881 }, 8882 _resetState: function() { 8883 this._resetStateTimeout = 0; 8884 this._moved = false; 8885 }, 8886 _clearDeferredResetState: function() { 8887 if (this._resetStateTimeout !== 0) { 8888 clearTimeout(this._resetStateTimeout); 8889 this._resetStateTimeout = 0; 8890 } 8891 }, 8892 _onMouseDown: function(e) { 8893 if (!e.shiftKey || e.which !== 1 && e.button !== 1) { 8894 return false; 8895 } 8896 this._clearDeferredResetState(); 8897 this._resetState(); 8898 disableTextSelection(); 8899 disableImageDrag(); 8900 this._startPoint = this._map.mouseEventToContainerPoint(e); 8901 on(document, { 8902 contextmenu: stop, 8903 mousemove: this._onMouseMove, 8904 mouseup: this._onMouseUp, 8905 keydown: this._onKeyDown 8906 }, this); 8907 }, 8908 _onMouseMove: function(e) { 8909 if (!this._moved) { 8910 this._moved = true; 8911 this._box = create$1("div", "leaflet-zoom-box", this._container); 8912 addClass(this._container, "leaflet-crosshair"); 8913 this._map.fire("boxzoomstart"); 8914 } 8915 this._point = this._map.mouseEventToContainerPoint(e); 8916 var bounds = new Bounds(this._point, this._startPoint), size = bounds.getSize(); 8917 setPosition(this._box, bounds.min); 8918 this._box.style.width = size.x + "px"; 8919 this._box.style.height = size.y + "px"; 8920 }, 8921 _finish: function() { 8922 if (this._moved) { 8923 remove(this._box); 8924 removeClass(this._container, "leaflet-crosshair"); 8925 } 8926 enableTextSelection(); 8927 enableImageDrag(); 8928 off(document, { 8929 contextmenu: stop, 8930 mousemove: this._onMouseMove, 8931 mouseup: this._onMouseUp, 8932 keydown: this._onKeyDown 8933 }, this); 8934 }, 8935 _onMouseUp: function(e) { 8936 if (e.which !== 1 && e.button !== 1) { 8937 return; 8938 } 8939 this._finish(); 8940 if (!this._moved) { 8941 return; 8942 } 8943 this._clearDeferredResetState(); 8944 this._resetStateTimeout = setTimeout(bind(this._resetState, this), 0); 8945 var bounds = new LatLngBounds( 8946 this._map.containerPointToLatLng(this._startPoint), 8947 this._map.containerPointToLatLng(this._point) 8948 ); 8949 this._map.fitBounds(bounds).fire("boxzoomend", { boxZoomBounds: bounds }); 8950 }, 8951 _onKeyDown: function(e) { 8952 if (e.keyCode === 27) { 8953 this._finish(); 8954 this._clearDeferredResetState(); 8955 this._resetState(); 8956 } 8957 } 8958 }); 8959 Map2.addInitHook("addHandler", "boxZoom", BoxZoom); 8960 Map2.mergeOptions({ 8961 // @option doubleClickZoom: Boolean|String = true 8962 // Whether the map can be zoomed in by double clicking on it and 8963 // zoomed out by double clicking while holding shift. If passed 8964 // `'center'`, double-click zoom will zoom to the center of the 8965 // view regardless of where the mouse was. 8966 doubleClickZoom: true 8967 }); 8968 var DoubleClickZoom = Handler.extend({ 8969 addHooks: function() { 8970 this._map.on("dblclick", this._onDoubleClick, this); 8971 }, 8972 removeHooks: function() { 8973 this._map.off("dblclick", this._onDoubleClick, this); 8974 }, 8975 _onDoubleClick: function(e) { 8976 var map = this._map, oldZoom = map.getZoom(), delta = map.options.zoomDelta, zoom2 = e.originalEvent.shiftKey ? oldZoom - delta : oldZoom + delta; 8977 if (map.options.doubleClickZoom === "center") { 8978 map.setZoom(zoom2); 8979 } else { 8980 map.setZoomAround(e.containerPoint, zoom2); 8981 } 8982 } 8983 }); 8984 Map2.addInitHook("addHandler", "doubleClickZoom", DoubleClickZoom); 8985 Map2.mergeOptions({ 8986 // @option dragging: Boolean = true 8987 // Whether the map is draggable with mouse/touch or not. 8988 dragging: true, 8989 // @section Panning Inertia Options 8990 // @option inertia: Boolean = * 8991 // If enabled, panning of the map will have an inertia effect where 8992 // the map builds momentum while dragging and continues moving in 8993 // the same direction for some time. Feels especially nice on touch 8994 // devices. Enabled by default. 8995 inertia: true, 8996 // @option inertiaDeceleration: Number = 3000 8997 // The rate with which the inertial movement slows down, in pixels/second². 8998 inertiaDeceleration: 3400, 8999 // px/s^2 9000 // @option inertiaMaxSpeed: Number = Infinity 9001 // Max speed of the inertial movement, in pixels/second. 9002 inertiaMaxSpeed: Infinity, 9003 // px/s 9004 // @option easeLinearity: Number = 0.2 9005 easeLinearity: 0.2, 9006 // TODO refactor, move to CRS 9007 // @option worldCopyJump: Boolean = false 9008 // With this option enabled, the map tracks when you pan to another "copy" 9009 // of the world and seamlessly jumps to the original one so that all overlays 9010 // like markers and vector layers are still visible. 9011 worldCopyJump: false, 9012 // @option maxBoundsViscosity: Number = 0.0 9013 // If `maxBounds` is set, this option will control how solid the bounds 9014 // are when dragging the map around. The default value of `0.0` allows the 9015 // user to drag outside the bounds at normal speed, higher values will 9016 // slow down map dragging outside bounds, and `1.0` makes the bounds fully 9017 // solid, preventing the user from dragging outside the bounds. 9018 maxBoundsViscosity: 0 9019 }); 9020 var Drag = Handler.extend({ 9021 addHooks: function() { 9022 if (!this._draggable) { 9023 var map = this._map; 9024 this._draggable = new Draggable(map._mapPane, map._container); 9025 this._draggable.on({ 9026 dragstart: this._onDragStart, 9027 drag: this._onDrag, 9028 dragend: this._onDragEnd 9029 }, this); 9030 this._draggable.on("predrag", this._onPreDragLimit, this); 9031 if (map.options.worldCopyJump) { 9032 this._draggable.on("predrag", this._onPreDragWrap, this); 9033 map.on("zoomend", this._onZoomEnd, this); 9034 map.whenReady(this._onZoomEnd, this); 9035 } 9036 } 9037 addClass(this._map._container, "leaflet-grab leaflet-touch-drag"); 9038 this._draggable.enable(); 9039 this._positions = []; 9040 this._times = []; 9041 }, 9042 removeHooks: function() { 9043 removeClass(this._map._container, "leaflet-grab"); 9044 removeClass(this._map._container, "leaflet-touch-drag"); 9045 this._draggable.disable(); 9046 }, 9047 moved: function() { 9048 return this._draggable && this._draggable._moved; 9049 }, 9050 moving: function() { 9051 return this._draggable && this._draggable._moving; 9052 }, 9053 _onDragStart: function() { 9054 var map = this._map; 9055 map._stop(); 9056 if (this._map.options.maxBounds && this._map.options.maxBoundsViscosity) { 9057 var bounds = toLatLngBounds(this._map.options.maxBounds); 9058 this._offsetLimit = toBounds( 9059 this._map.latLngToContainerPoint(bounds.getNorthWest()).multiplyBy(-1), 9060 this._map.latLngToContainerPoint(bounds.getSouthEast()).multiplyBy(-1).add(this._map.getSize()) 9061 ); 9062 this._viscosity = Math.min(1, Math.max(0, this._map.options.maxBoundsViscosity)); 9063 } else { 9064 this._offsetLimit = null; 9065 } 9066 map.fire("movestart").fire("dragstart"); 9067 if (map.options.inertia) { 9068 this._positions = []; 9069 this._times = []; 9070 } 9071 }, 9072 _onDrag: function(e) { 9073 if (this._map.options.inertia) { 9074 var time = this._lastTime = +/* @__PURE__ */ new Date(), pos = this._lastPos = this._draggable._absPos || this._draggable._newPos; 9075 this._positions.push(pos); 9076 this._times.push(time); 9077 this._prunePositions(time); 9078 } 9079 this._map.fire("move", e).fire("drag", e); 9080 }, 9081 _prunePositions: function(time) { 9082 while (this._positions.length > 1 && time - this._times[0] > 50) { 9083 this._positions.shift(); 9084 this._times.shift(); 9085 } 9086 }, 9087 _onZoomEnd: function() { 9088 var pxCenter = this._map.getSize().divideBy(2), pxWorldCenter = this._map.latLngToLayerPoint([0, 0]); 9089 this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x; 9090 this._worldWidth = this._map.getPixelWorldBounds().getSize().x; 9091 }, 9092 _viscousLimit: function(value, threshold) { 9093 return value - (value - threshold) * this._viscosity; 9094 }, 9095 _onPreDragLimit: function() { 9096 if (!this._viscosity || !this._offsetLimit) { 9097 return; 9098 } 9099 var offset2 = this._draggable._newPos.subtract(this._draggable._startPos); 9100 var limit = this._offsetLimit; 9101 if (offset2.x < limit.min.x) { 9102 offset2.x = this._viscousLimit(offset2.x, limit.min.x); 9103 } 9104 if (offset2.y < limit.min.y) { 9105 offset2.y = this._viscousLimit(offset2.y, limit.min.y); 9106 } 9107 if (offset2.x > limit.max.x) { 9108 offset2.x = this._viscousLimit(offset2.x, limit.max.x); 9109 } 9110 if (offset2.y > limit.max.y) { 9111 offset2.y = this._viscousLimit(offset2.y, limit.max.y); 9112 } 9113 this._draggable._newPos = this._draggable._startPos.add(offset2); 9114 }, 9115 _onPreDragWrap: function() { 9116 var worldWidth = this._worldWidth, halfWidth = Math.round(worldWidth / 2), dx = this._initialWorldOffset, x = this._draggable._newPos.x, newX1 = (x - halfWidth + dx) % worldWidth + halfWidth - dx, newX2 = (x + halfWidth + dx) % worldWidth - halfWidth - dx, newX = Math.abs(newX1 + dx) < Math.abs(newX2 + dx) ? newX1 : newX2; 9117 this._draggable._absPos = this._draggable._newPos.clone(); 9118 this._draggable._newPos.x = newX; 9119 }, 9120 _onDragEnd: function(e) { 9121 var map = this._map, options = map.options, noInertia = !options.inertia || e.noInertia || this._times.length < 2; 9122 map.fire("dragend", e); 9123 if (noInertia) { 9124 map.fire("moveend"); 9125 } else { 9126 this._prunePositions(+/* @__PURE__ */ new Date()); 9127 var direction = this._lastPos.subtract(this._positions[0]), duration = (this._lastTime - this._times[0]) / 1e3, ease = options.easeLinearity, speedVector = direction.multiplyBy(ease / duration), speed = speedVector.distanceTo([0, 0]), limitedSpeed = Math.min(options.inertiaMaxSpeed, speed), limitedSpeedVector = speedVector.multiplyBy(limitedSpeed / speed), decelerationDuration = limitedSpeed / (options.inertiaDeceleration * ease), offset2 = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round(); 9128 if (!offset2.x && !offset2.y) { 9129 map.fire("moveend"); 9130 } else { 9131 offset2 = map._limitOffset(offset2, map.options.maxBounds); 9132 requestAnimFrame(function() { 9133 map.panBy(offset2, { 9134 duration: decelerationDuration, 9135 easeLinearity: ease, 9136 noMoveStart: true, 9137 animate: true 9138 }); 9139 }); 9140 } 9141 } 9142 } 9143 }); 9144 Map2.addInitHook("addHandler", "dragging", Drag); 9145 Map2.mergeOptions({ 9146 // @option keyboard: Boolean = true 9147 // Makes the map focusable and allows users to navigate the map with keyboard 9148 // arrows and `+`/`-` keys. 9149 keyboard: true, 9150 // @option keyboardPanDelta: Number = 80 9151 // Amount of pixels to pan when pressing an arrow key. 9152 keyboardPanDelta: 80 9153 }); 9154 var Keyboard = Handler.extend({ 9155 keyCodes: { 9156 left: [37], 9157 right: [39], 9158 down: [40], 9159 up: [38], 9160 zoomIn: [187, 107, 61, 171], 9161 zoomOut: [189, 109, 54, 173] 9162 }, 9163 initialize: function(map) { 9164 this._map = map; 9165 this._setPanDelta(map.options.keyboardPanDelta); 9166 this._setZoomDelta(map.options.zoomDelta); 9167 }, 9168 addHooks: function() { 9169 var container = this._map._container; 9170 if (container.tabIndex <= 0) { 9171 container.tabIndex = "0"; 9172 } 9173 on(container, { 9174 focus: this._onFocus, 9175 blur: this._onBlur, 9176 mousedown: this._onMouseDown 9177 }, this); 9178 this._map.on({ 9179 focus: this._addHooks, 9180 blur: this._removeHooks 9181 }, this); 9182 }, 9183 removeHooks: function() { 9184 this._removeHooks(); 9185 off(this._map._container, { 9186 focus: this._onFocus, 9187 blur: this._onBlur, 9188 mousedown: this._onMouseDown 9189 }, this); 9190 this._map.off({ 9191 focus: this._addHooks, 9192 blur: this._removeHooks 9193 }, this); 9194 }, 9195 _onMouseDown: function() { 9196 if (this._focused) { 9197 return; 9198 } 9199 var body = document.body, docEl = document.documentElement, top2 = body.scrollTop || docEl.scrollTop, left2 = body.scrollLeft || docEl.scrollLeft; 9200 this._map._container.focus(); 9201 window.scrollTo(left2, top2); 9202 }, 9203 _onFocus: function() { 9204 this._focused = true; 9205 this._map.fire("focus"); 9206 }, 9207 _onBlur: function() { 9208 this._focused = false; 9209 this._map.fire("blur"); 9210 }, 9211 _setPanDelta: function(panDelta) { 9212 var keys = this._panKeys = {}, codes = this.keyCodes, i, len; 9213 for (i = 0, len = codes.left.length; i < len; i++) { 9214 keys[codes.left[i]] = [-1 * panDelta, 0]; 9215 } 9216 for (i = 0, len = codes.right.length; i < len; i++) { 9217 keys[codes.right[i]] = [panDelta, 0]; 9218 } 9219 for (i = 0, len = codes.down.length; i < len; i++) { 9220 keys[codes.down[i]] = [0, panDelta]; 9221 } 9222 for (i = 0, len = codes.up.length; i < len; i++) { 9223 keys[codes.up[i]] = [0, -1 * panDelta]; 9224 } 9225 }, 9226 _setZoomDelta: function(zoomDelta) { 9227 var keys = this._zoomKeys = {}, codes = this.keyCodes, i, len; 9228 for (i = 0, len = codes.zoomIn.length; i < len; i++) { 9229 keys[codes.zoomIn[i]] = zoomDelta; 9230 } 9231 for (i = 0, len = codes.zoomOut.length; i < len; i++) { 9232 keys[codes.zoomOut[i]] = -zoomDelta; 9233 } 9234 }, 9235 _addHooks: function() { 9236 on(document, "keydown", this._onKeyDown, this); 9237 }, 9238 _removeHooks: function() { 9239 off(document, "keydown", this._onKeyDown, this); 9240 }, 9241 _onKeyDown: function(e) { 9242 if (e.altKey || e.ctrlKey || e.metaKey) { 9243 return; 9244 } 9245 var key = e.keyCode, map = this._map, offset2; 9246 if (key in this._panKeys) { 9247 if (!map._panAnim || !map._panAnim._inProgress) { 9248 offset2 = this._panKeys[key]; 9249 if (e.shiftKey) { 9250 offset2 = toPoint(offset2).multiplyBy(3); 9251 } 9252 if (map.options.maxBounds) { 9253 offset2 = map._limitOffset(toPoint(offset2), map.options.maxBounds); 9254 } 9255 if (map.options.worldCopyJump) { 9256 var newLatLng = map.wrapLatLng(map.unproject(map.project(map.getCenter()).add(offset2))); 9257 map.panTo(newLatLng); 9258 } else { 9259 map.panBy(offset2); 9260 } 9261 } 9262 } else if (key in this._zoomKeys) { 9263 map.setZoom(map.getZoom() + (e.shiftKey ? 3 : 1) * this._zoomKeys[key]); 9264 } else if (key === 27 && map._popup && map._popup.options.closeOnEscapeKey) { 9265 map.closePopup(); 9266 } else { 9267 return; 9268 } 9269 stop(e); 9270 } 9271 }); 9272 Map2.addInitHook("addHandler", "keyboard", Keyboard); 9273 Map2.mergeOptions({ 9274 // @section Mouse wheel options 9275 // @option scrollWheelZoom: Boolean|String = true 9276 // Whether the map can be zoomed by using the mouse wheel. If passed `'center'`, 9277 // it will zoom to the center of the view regardless of where the mouse was. 9278 scrollWheelZoom: true, 9279 // @option wheelDebounceTime: Number = 40 9280 // Limits the rate at which a wheel can fire (in milliseconds). By default 9281 // user can't zoom via wheel more often than once per 40 ms. 9282 wheelDebounceTime: 40, 9283 // @option wheelPxPerZoomLevel: Number = 60 9284 // How many scroll pixels (as reported by [L.DomEvent.getWheelDelta](#domevent-getwheeldelta)) 9285 // mean a change of one full zoom level. Smaller values will make wheel-zooming 9286 // faster (and vice versa). 9287 wheelPxPerZoomLevel: 60 9288 }); 9289 var ScrollWheelZoom = Handler.extend({ 9290 addHooks: function() { 9291 on(this._map._container, "wheel", this._onWheelScroll, this); 9292 this._delta = 0; 9293 }, 9294 removeHooks: function() { 9295 off(this._map._container, "wheel", this._onWheelScroll, this); 9296 }, 9297 _onWheelScroll: function(e) { 9298 var delta = getWheelDelta(e); 9299 var debounce2 = this._map.options.wheelDebounceTime; 9300 this._delta += delta; 9301 this._lastMousePos = this._map.mouseEventToContainerPoint(e); 9302 if (!this._startTime) { 9303 this._startTime = +/* @__PURE__ */ new Date(); 9304 } 9305 var left2 = Math.max(debounce2 - (+/* @__PURE__ */ new Date() - this._startTime), 0); 9306 clearTimeout(this._timer); 9307 this._timer = setTimeout(bind(this._performZoom, this), left2); 9308 stop(e); 9309 }, 9310 _performZoom: function() { 9311 var map = this._map, zoom2 = map.getZoom(), snap = this._map.options.zoomSnap || 0; 9312 map._stop(); 9313 var d2 = this._delta / (this._map.options.wheelPxPerZoomLevel * 4), d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2, d4 = snap ? Math.ceil(d3 / snap) * snap : d3, delta = map._limitZoom(zoom2 + (this._delta > 0 ? d4 : -d4)) - zoom2; 9314 this._delta = 0; 9315 this._startTime = null; 9316 if (!delta) { 9317 return; 9318 } 9319 if (map.options.scrollWheelZoom === "center") { 9320 map.setZoom(zoom2 + delta); 9321 } else { 9322 map.setZoomAround(this._lastMousePos, zoom2 + delta); 9323 } 9324 } 9325 }); 9326 Map2.addInitHook("addHandler", "scrollWheelZoom", ScrollWheelZoom); 9327 var tapHoldDelay = 600; 9328 Map2.mergeOptions({ 9329 // @section Touch interaction options 9330 // @option tapHold: Boolean 9331 // Enables simulation of `contextmenu` event, default is `true` for mobile Safari. 9332 tapHold: Browser.touchNative && Browser.safari && Browser.mobile, 9333 // @option tapTolerance: Number = 15 9334 // The max number of pixels a user can shift his finger during touch 9335 // for it to be considered a valid tap. 9336 tapTolerance: 15 9337 }); 9338 var TapHold = Handler.extend({ 9339 addHooks: function() { 9340 on(this._map._container, "touchstart", this._onDown, this); 9341 }, 9342 removeHooks: function() { 9343 off(this._map._container, "touchstart", this._onDown, this); 9344 }, 9345 _onDown: function(e) { 9346 clearTimeout(this._holdTimeout); 9347 if (e.touches.length !== 1) { 9348 return; 9349 } 9350 var first = e.touches[0]; 9351 this._startPos = this._newPos = new Point(first.clientX, first.clientY); 9352 this._holdTimeout = setTimeout(bind(function() { 9353 this._cancel(); 9354 if (!this._isTapValid()) { 9355 return; 9356 } 9357 on(document, "touchend", preventDefault); 9358 on(document, "touchend touchcancel", this._cancelClickPrevent); 9359 this._simulateEvent("contextmenu", first); 9360 }, this), tapHoldDelay); 9361 on(document, "touchend touchcancel contextmenu", this._cancel, this); 9362 on(document, "touchmove", this._onMove, this); 9363 }, 9364 _cancelClickPrevent: function cancelClickPrevent() { 9365 off(document, "touchend", preventDefault); 9366 off(document, "touchend touchcancel", cancelClickPrevent); 9367 }, 9368 _cancel: function() { 9369 clearTimeout(this._holdTimeout); 9370 off(document, "touchend touchcancel contextmenu", this._cancel, this); 9371 off(document, "touchmove", this._onMove, this); 9372 }, 9373 _onMove: function(e) { 9374 var first = e.touches[0]; 9375 this._newPos = new Point(first.clientX, first.clientY); 9376 }, 9377 _isTapValid: function() { 9378 return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance; 9379 }, 9380 _simulateEvent: function(type, e) { 9381 var simulatedEvent = new MouseEvent(type, { 9382 bubbles: true, 9383 cancelable: true, 9384 view: window, 9385 // detail: 1, 9386 screenX: e.screenX, 9387 screenY: e.screenY, 9388 clientX: e.clientX, 9389 clientY: e.clientY 9390 // button: 2, 9391 // buttons: 2 9392 }); 9393 simulatedEvent._simulated = true; 9394 e.target.dispatchEvent(simulatedEvent); 9395 } 9396 }); 9397 Map2.addInitHook("addHandler", "tapHold", TapHold); 9398 Map2.mergeOptions({ 9399 // @section Touch interaction options 9400 // @option touchZoom: Boolean|String = * 9401 // Whether the map can be zoomed by touch-dragging with two fingers. If 9402 // passed `'center'`, it will zoom to the center of the view regardless of 9403 // where the touch events (fingers) were. Enabled for touch-capable web 9404 // browsers. 9405 touchZoom: Browser.touch, 9406 // @option bounceAtZoomLimits: Boolean = true 9407 // Set it to false if you don't want the map to zoom beyond min/max zoom 9408 // and then bounce back when pinch-zooming. 9409 bounceAtZoomLimits: true 9410 }); 9411 var TouchZoom = Handler.extend({ 9412 addHooks: function() { 9413 addClass(this._map._container, "leaflet-touch-zoom"); 9414 on(this._map._container, "touchstart", this._onTouchStart, this); 9415 }, 9416 removeHooks: function() { 9417 removeClass(this._map._container, "leaflet-touch-zoom"); 9418 off(this._map._container, "touchstart", this._onTouchStart, this); 9419 }, 9420 _onTouchStart: function(e) { 9421 var map = this._map; 9422 if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming) { 9423 return; 9424 } 9425 var p1 = map.mouseEventToContainerPoint(e.touches[0]), p2 = map.mouseEventToContainerPoint(e.touches[1]); 9426 this._centerPoint = map.getSize()._divideBy(2); 9427 this._startLatLng = map.containerPointToLatLng(this._centerPoint); 9428 if (map.options.touchZoom !== "center") { 9429 this._pinchStartLatLng = map.containerPointToLatLng(p1.add(p2)._divideBy(2)); 9430 } 9431 this._startDist = p1.distanceTo(p2); 9432 this._startZoom = map.getZoom(); 9433 this._moved = false; 9434 this._zooming = true; 9435 map._stop(); 9436 on(document, "touchmove", this._onTouchMove, this); 9437 on(document, "touchend touchcancel", this._onTouchEnd, this); 9438 preventDefault(e); 9439 }, 9440 _onTouchMove: function(e) { 9441 if (!e.touches || e.touches.length !== 2 || !this._zooming) { 9442 return; 9443 } 9444 var map = this._map, p1 = map.mouseEventToContainerPoint(e.touches[0]), p2 = map.mouseEventToContainerPoint(e.touches[1]), scale2 = p1.distanceTo(p2) / this._startDist; 9445 this._zoom = map.getScaleZoom(scale2, this._startZoom); 9446 if (!map.options.bounceAtZoomLimits && (this._zoom < map.getMinZoom() && scale2 < 1 || this._zoom > map.getMaxZoom() && scale2 > 1)) { 9447 this._zoom = map._limitZoom(this._zoom); 9448 } 9449 if (map.options.touchZoom === "center") { 9450 this._center = this._startLatLng; 9451 if (scale2 === 1) { 9452 return; 9453 } 9454 } else { 9455 var delta = p1._add(p2)._divideBy(2)._subtract(this._centerPoint); 9456 if (scale2 === 1 && delta.x === 0 && delta.y === 0) { 9457 return; 9458 } 9459 this._center = map.unproject(map.project(this._pinchStartLatLng, this._zoom).subtract(delta), this._zoom); 9460 } 9461 if (!this._moved) { 9462 map._moveStart(true, false); 9463 this._moved = true; 9464 } 9465 cancelAnimFrame(this._animRequest); 9466 var moveFn = bind(map._move, map, this._center, this._zoom, { pinch: true, round: false }, void 0); 9467 this._animRequest = requestAnimFrame(moveFn, this, true); 9468 preventDefault(e); 9469 }, 9470 _onTouchEnd: function() { 9471 if (!this._moved || !this._zooming) { 9472 this._zooming = false; 9473 return; 9474 } 9475 this._zooming = false; 9476 cancelAnimFrame(this._animRequest); 9477 off(document, "touchmove", this._onTouchMove, this); 9478 off(document, "touchend touchcancel", this._onTouchEnd, this); 9479 if (this._map.options.zoomAnimation) { 9480 this._map._animateZoom(this._center, this._map._limitZoom(this._zoom), true, this._map.options.zoomSnap); 9481 } else { 9482 this._map._resetView(this._center, this._map._limitZoom(this._zoom)); 9483 } 9484 } 9485 }); 9486 Map2.addInitHook("addHandler", "touchZoom", TouchZoom); 9487 Map2.BoxZoom = BoxZoom; 9488 Map2.DoubleClickZoom = DoubleClickZoom; 9489 Map2.Drag = Drag; 9490 Map2.Keyboard = Keyboard; 9491 Map2.ScrollWheelZoom = ScrollWheelZoom; 9492 Map2.TapHold = TapHold; 9493 Map2.TouchZoom = TouchZoom; 9494 exports2.Bounds = Bounds; 9495 exports2.Browser = Browser; 9496 exports2.CRS = CRS; 9497 exports2.Canvas = Canvas; 9498 exports2.Circle = Circle; 9499 exports2.CircleMarker = CircleMarker; 9500 exports2.Class = Class; 9501 exports2.Control = Control; 9502 exports2.DivIcon = DivIcon; 9503 exports2.DivOverlay = DivOverlay; 9504 exports2.DomEvent = DomEvent; 9505 exports2.DomUtil = DomUtil; 9506 exports2.Draggable = Draggable; 9507 exports2.Evented = Evented; 9508 exports2.FeatureGroup = FeatureGroup; 9509 exports2.GeoJSON = GeoJSON; 9510 exports2.GridLayer = GridLayer; 9511 exports2.Handler = Handler; 9512 exports2.Icon = Icon; 9513 exports2.ImageOverlay = ImageOverlay; 9514 exports2.LatLng = LatLng; 9515 exports2.LatLngBounds = LatLngBounds; 9516 exports2.Layer = Layer; 9517 exports2.LayerGroup = LayerGroup; 9518 exports2.LineUtil = LineUtil; 9519 exports2.Map = Map2; 9520 exports2.Marker = Marker; 9521 exports2.Mixin = Mixin; 9522 exports2.Path = Path; 9523 exports2.Point = Point; 9524 exports2.PolyUtil = PolyUtil; 9525 exports2.Polygon = Polygon; 9526 exports2.Polyline = Polyline; 9527 exports2.Popup = Popup; 9528 exports2.PosAnimation = PosAnimation; 9529 exports2.Projection = index; 9530 exports2.Rectangle = Rectangle; 9531 exports2.Renderer = Renderer; 9532 exports2.SVG = SVG; 9533 exports2.SVGOverlay = SVGOverlay; 9534 exports2.TileLayer = TileLayer; 9535 exports2.Tooltip = Tooltip2; 9536 exports2.Transformation = Transformation; 9537 exports2.Util = Util; 9538 exports2.VideoOverlay = VideoOverlay; 9539 exports2.bind = bind; 9540 exports2.bounds = toBounds; 9541 exports2.canvas = canvas; 9542 exports2.circle = circle; 9543 exports2.circleMarker = circleMarker; 9544 exports2.control = control; 9545 exports2.divIcon = divIcon; 9546 exports2.extend = extend; 9547 exports2.featureGroup = featureGroup; 9548 exports2.geoJSON = geoJSON2; 9549 exports2.geoJson = geoJson; 9550 exports2.gridLayer = gridLayer; 9551 exports2.icon = icon; 9552 exports2.imageOverlay = imageOverlay; 9553 exports2.latLng = toLatLng; 9554 exports2.latLngBounds = toLatLngBounds; 9555 exports2.layerGroup = layerGroup; 9556 exports2.map = createMap; 9557 exports2.marker = marker; 9558 exports2.point = toPoint; 9559 exports2.polygon = polygon; 9560 exports2.polyline = polyline; 9561 exports2.popup = popup; 9562 exports2.rectangle = rectangle; 9563 exports2.setOptions = setOptions; 9564 exports2.stamp = stamp; 9565 exports2.svg = svg; 9566 exports2.svgOverlay = svgOverlay; 9567 exports2.tileLayer = tileLayer; 9568 exports2.tooltip = tooltip; 9569 exports2.transformation = toTransformation; 9570 exports2.version = version; 9571 exports2.videoOverlay = videoOverlay; 9572 var oldL = window.L; 9573 exports2.noConflict = function() { 9574 window.L = oldL; 9575 return this; 9576 }; 9577 window.L = exports2; 9578 }); 9579 } 9580 }); 9581 9582
9582// app/assets/javascripts/application.js 9583 var import_leaflet = __toESM(require_leaflet_src()); 9584 9585
vendor: 1,410 bytes, lines 9585-9628
9585// node_modules/@popperjs/core/lib/index.js 9586 var lib_exports = {}; 9587 __export(lib_exports, { 9588 afterMain: () => afterMain, 9589 afterRead: () => afterRead, 9590 afterWrite: () => afterWrite, 9591 applyStyles: () => applyStyles_default, 9592 arrow: () => arrow_default, 9593 auto: () => auto, 9594 basePlacements: () => basePlacements, 9595 beforeMain: () => beforeMain, 9596 beforeRead: () => beforeRead, 9597 beforeWrite: () => beforeWrite, 9598 bottom: () => bottom, 9599 clippingParents: () => clippingParents, 9600 computeStyles: () => computeStyles_default, 9601 createPopper: () => createPopper3, 9602 createPopperBase: () => createPopper, 9603 createPopperLite: () => createPopper2, 9604 detectOverflow: () => detectOverflow, 9605 end: () => end, 9606 eventListeners: () => eventListeners_default, 9607 flip: () => flip_default, 9608 hide: () => hide_default, 9609 left: () => left, 9610 main: () => main, 9611 modifierPhases: () => modifierPhases, 9612 offset: () => offset_default, 9613 placements: () => placements, 9614 popper: () => popper, 9615 popperGenerator: () => popperGenerator, 9616 popperOffsets: () => popperOffsets_default, 9617 preventOverflow: () => preventOverflow_default, 9618 read: () => read, 9619 reference: () => reference, 9620 right: () => right, 9621 start: () => start, 9622 top: () => top, 9623 variationPlacements: () => variationPlacements, 9624 viewport: () => viewport, 9625 write: () => write 9626 }); 9627 9628
vendor: 1,126 bytes, lines 9628-9658
9628// node_modules/@popperjs/core/lib/enums.js 9629 var top = "top"; 9630 var bottom = "bottom"; 9631 var right = "right"; 9632 var left = "left"; 9633 var auto = "auto"; 9634 var basePlacements = [top, bottom, right, left]; 9635 var start = "start"; 9636 var end = "end"; 9637 var clippingParents = "clippingParents"; 9638 var viewport = "viewport"; 9639 var popper = "popper"; 9640 var reference = "reference"; 9641 var variationPlacements = /* @__PURE__ */ basePlacements.reduce(function(acc, placement) { 9642 return acc.concat([placement + "-" + start, placement + "-" + end]); 9643 }, []); 9644 var placements = /* @__PURE__ */ [].concat(basePlacements, [auto]).reduce(function(acc, placement) { 9645 return acc.concat([placement, placement + "-" + start, placement + "-" + end]); 9646 }, []); 9647 var beforeRead = "beforeRead"; 9648 var read = "read"; 9649 var afterRead = "afterRead"; 9650 var beforeMain = "beforeMain"; 9651 var main = "main"; 9652 var afterMain = "afterMain"; 9653 var beforeWrite = "beforeWrite"; 9654 var write = "write"; 9655 var afterWrite = "afterWrite"; 9656 var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; 9657 9658
vendor: 169 bytes, lines 9658-9663
9658// node_modules/@popperjs/core/lib/dom-utils/getNodeName.js 9659 function getNodeName(element) { 9660 return element ? (element.nodeName || "").toLowerCase() : null; 9661 } 9662 9663
vendor: 338 bytes, lines 9663-9675
9663// node_modules/@popperjs/core/lib/dom-utils/getWindow.js 9664 function getWindow(node) { 9665 if (node == null) { 9666 return window; 9667 } 9668 if (node.toString() !== "[object Window]") { 9669 var ownerDocument = node.ownerDocument; 9670 return ownerDocument ? ownerDocument.defaultView || window : window; 9671 } 9672 return node; 9673 } 9674 9675
vendor: 589 bytes, lines 9675-9692
9675// node_modules/@popperjs/core/lib/dom-utils/instanceOf.js 9676 function isElement(node) { 9677 var OwnElement = getWindow(node).Element; 9678 return node instanceof OwnElement || node instanceof Element; 9679 } 9680 function isHTMLElement(node) { 9681 var OwnElement = getWindow(node).HTMLElement; 9682 return node instanceof OwnElement || node instanceof HTMLElement; 9683 } 9684 function isShadowRoot(node) { 9685 if (typeof ShadowRoot === "undefined") { 9686 return false; 9687 } 9688 var OwnElement = getWindow(node).ShadowRoot; 9689 return node instanceof OwnElement || node instanceof ShadowRoot; 9690 } 9691 9692
vendor: 2,121 bytes, lines 9692-9760
9692// node_modules/@popperjs/core/lib/modifiers/applyStyles.js 9693 function applyStyles(_ref) { 9694 var state = _ref.state; 9695 Object.keys(state.elements).forEach(function(name) { 9696 var style = state.styles[name] || {}; 9697 var attributes = state.attributes[name] || {}; 9698 var element = state.elements[name]; 9699 if (!isHTMLElement(element) || !getNodeName(element)) { 9700 return; 9701 } 9702 Object.assign(element.style, style); 9703 Object.keys(attributes).forEach(function(name2) { 9704 var value = attributes[name2]; 9705 if (value === false) { 9706 element.removeAttribute(name2); 9707 } else { 9708 element.setAttribute(name2, value === true ? "" : value); 9709 } 9710 }); 9711 }); 9712 } 9713 function effect(_ref2) { 9714 var state = _ref2.state; 9715 var initialStyles = { 9716 popper: { 9717 position: state.options.strategy, 9718 left: "0", 9719 top: "0", 9720 margin: "0" 9721 }, 9722 arrow: { 9723 position: "absolute" 9724 }, 9725 reference: {} 9726 }; 9727 Object.assign(state.elements.popper.style, initialStyles.popper); 9728 state.styles = initialStyles; 9729 if (state.elements.arrow) { 9730 Object.assign(state.elements.arrow.style, initialStyles.arrow); 9731 } 9732 return function() { 9733 Object.keys(state.elements).forEach(function(name) { 9734 var element = state.elements[name]; 9735 var attributes = state.attributes[name] || {}; 9736 var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); 9737 var style = styleProperties.reduce(function(style2, property) { 9738 style2[property] = ""; 9739 return style2; 9740 }, {}); 9741 if (!isHTMLElement(element) || !getNodeName(element)) { 9742 return; 9743 } 9744 Object.assign(element.style, style); 9745 Object.keys(attributes).forEach(function(attribute) { 9746 element.removeAttribute(attribute); 9747 }); 9748 }); 9749 }; 9750 } 9751 var applyStyles_default = { 9752 name: "applyStyles", 9753 enabled: true, 9754 phase: "write", 9755 fn: applyStyles, 9756 effect, 9757 requires: ["computeStyles"] 9758 }; 9759 9760
vendor: 145 bytes, lines 9760-9765
9760// node_modules/@popperjs/core/lib/utils/getBasePlacement.js 9761 function getBasePlacement(placement) { 9762 return placement.split("-")[0]; 9763 } 9764 9765
vendor: 122 bytes, lines 9765-9770
9765// node_modules/@popperjs/core/lib/utils/math.js 9766 var max = Math.max; 9767 var min = Math.min; 9768 var round = Math.round; 9769 9770
vendor: 359 bytes, lines 9770-9781
9770// node_modules/@popperjs/core/lib/utils/userAgent.js 9771 function getUAString() { 9772 var uaData = navigator.userAgentData; 9773 if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) { 9774 return uaData.brands.map(function(item) { 9775 return item.brand + "/" + item.version; 9776 }).join(" "); 9777 } 9778 return navigator.userAgent; 9779 } 9780 9781
vendor: 170 bytes, lines 9781-9786
9781// node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js 9782 function isLayoutViewport() { 9783 return !/^((?!chrome|android).)*safari/i.test(getUAString()); 9784 } 9785 9786
vendor: 1,264 bytes, lines 9786-9819
9786// node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js 9787 function getBoundingClientRect(element, includeScale, isFixedStrategy) { 9788 if (includeScale === void 0) { 9789 includeScale = false; 9790 } 9791 if (isFixedStrategy === void 0) { 9792 isFixedStrategy = false; 9793 } 9794 var clientRect = element.getBoundingClientRect(); 9795 var scaleX = 1; 9796 var scaleY = 1; 9797 if (includeScale && isHTMLElement(element)) { 9798 scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1; 9799 scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1; 9800 } 9801 var _ref = isElement(element) ? getWindow(element) : window, visualViewport = _ref.visualViewport; 9802 var addVisualOffsets = !isLayoutViewport() && isFixedStrategy; 9803 var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX; 9804 var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY; 9805 var width = clientRect.width / scaleX; 9806 var height = clientRect.height / scaleY; 9807 return { 9808 width, 9809 height, 9810 top: y, 9811 right: x + width, 9812 bottom: y + height, 9813 left: x, 9814 x, 9815 y 9816 }; 9817 } 9818 9819
vendor: 519 bytes, lines 9819-9838
9819// node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js 9820 function getLayoutRect(element) { 9821 var clientRect = getBoundingClientRect(element); 9822 var width = element.offsetWidth; 9823 var height = element.offsetHeight; 9824 if (Math.abs(clientRect.width - width) <= 1) { 9825 width = clientRect.width; 9826 } 9827 if (Math.abs(clientRect.height - height) <= 1) { 9828 height = clientRect.height; 9829 } 9830 return { 9831 x: element.offsetLeft, 9832 y: element.offsetTop, 9833 width, 9834 height 9835 }; 9836 } 9837 9838
vendor: 474 bytes, lines 9838-9855
9838// node_modules/@popperjs/core/lib/dom-utils/contains.js 9839 function contains(parent, child) { 9840 var rootNode = child.getRootNode && child.getRootNode(); 9841 if (parent.contains(child)) { 9842 return true; 9843 } else if (rootNode && isShadowRoot(rootNode)) { 9844 var next = child; 9845 do { 9846 if (next && parent.isSameNode(next)) { 9847 return true; 9848 } 9849 next = next.parentNode || next.host; 9850 } while (next); 9851 } 9852 return false; 9853 } 9854 9855
vendor: 169 bytes, lines 9855-9860
9855// node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js 9856 function getComputedStyle2(element) { 9857 return getWindow(element).getComputedStyle(element); 9858 } 9859 9860
vendor: 176 bytes, lines 9860-9865
9860// node_modules/@popperjs/core/lib/dom-utils/isTableElement.js 9861 function isTableElement(element) { 9862 return ["table", "td", "th"].indexOf(getNodeName(element)) >= 0; 9863 } 9864 9865
vendor: 276 bytes, lines 9865-9873
9865// node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js 9866 function getDocumentElement(element) { 9867 return ((isElement(element) ? element.ownerDocument : ( 9868 // $FlowFixMe[prop-missing] 9869 element.document 9870 )) || window.document).documentElement; 9871 } 9872 9873
vendor: 680 bytes, lines 9873-9890
9873// node_modules/@popperjs/core/lib/dom-utils/getParentNode.js 9874 function getParentNode(element) { 9875 if (getNodeName(element) === "html") { 9876 return element; 9877 } 9878 return ( 9879 // this is a quicker (but less type safe) way to save quite some bytes from the bundle 9880 // $FlowFixMe[incompatible-return] 9881 // $FlowFixMe[prop-missing] 9882 element.assignedSlot || // step into the shadow DOM of the parent of a slotted node 9883 element.parentNode || // DOM Element detected 9884 (isShadowRoot(element) ? element.host : null) || // ShadowRoot detected 9885 // $FlowFixMe[incompatible-call]: HTMLElement is a Node 9886 getDocumentElement(element) 9887 ); 9888 } 9889 9890
vendor: 1,849 bytes, lines 9890-9933
9890// node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js 9891 function getTrueOffsetParent(element) { 9892 if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837 9893 getComputedStyle2(element).position === "fixed") { 9894 return null; 9895 } 9896 return element.offsetParent; 9897 } 9898 function getContainingBlock(element) { 9899 var isFirefox = /firefox/i.test(getUAString()); 9900 var isIE = /Trident/i.test(getUAString()); 9901 if (isIE && isHTMLElement(element)) { 9902 var elementCss = getComputedStyle2(element); 9903 if (elementCss.position === "fixed") { 9904 return null; 9905 } 9906 } 9907 var currentNode = getParentNode(element); 9908 if (isShadowRoot(currentNode)) { 9909 currentNode = currentNode.host; 9910 } 9911 while (isHTMLElement(currentNode) && ["html", "body"].indexOf(getNodeName(currentNode)) < 0) { 9912 var css = getComputedStyle2(currentNode); 9913 if (css.transform !== "none" || css.perspective !== "none" || css.contain === "paint" || ["transform", "perspective"].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === "filter" || isFirefox && css.filter && css.filter !== "none") { 9914 return currentNode; 9915 } else { 9916 currentNode = currentNode.parentNode; 9917 } 9918 } 9919 return null; 9920 } 9921 function getOffsetParent(element) { 9922 var window2 = getWindow(element); 9923 var offsetParent = getTrueOffsetParent(element); 9924 while (offsetParent && isTableElement(offsetParent) && getComputedStyle2(offsetParent).position === "static") { 9925 offsetParent = getTrueOffsetParent(offsetParent); 9926 } 9927 if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle2(offsetParent).position === "static")) { 9928 return window2; 9929 } 9930 return offsetParent || getContainingBlock(element) || window2; 9931 } 9932 9933
vendor: 191 bytes, lines 9933-9938
9933// node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js 9934 function getMainAxisFromPlacement(placement) { 9935 return ["top", "bottom"].indexOf(placement) >= 0 ? "x" : "y"; 9936 } 9937 9938
vendor: 259 bytes, lines 9938-9947
9938// node_modules/@popperjs/core/lib/utils/within.js 9939 function within(min2, value, max2) { 9940 return max(min2, min(value, max2)); 9941 } 9942 function withinMaxClamp(min2, value, max2) { 9943 var v = within(min2, value, max2); 9944 return v > max2 ? max2 : v; 9945 } 9946 9947
vendor: 185 bytes, lines 9947-9957
9947// node_modules/@popperjs/core/lib/utils/getFreshSideObject.js 9948 function getFreshSideObject() { 9949 return { 9950 top: 0, 9951 right: 0, 9952 bottom: 0, 9953 left: 0 9954 }; 9955 } 9956 9957
vendor: 184 bytes, lines 9957-9962
9957// node_modules/@popperjs/core/lib/utils/mergePaddingObject.js 9958 function mergePaddingObject(paddingObject) { 9959 return Object.assign({}, getFreshSideObject(), paddingObject); 9960 } 9961 9962
vendor: 219 bytes, lines 9962-9970
9962// node_modules/@popperjs/core/lib/utils/expandToHashMap.js 9963 function expandToHashMap(value, keys) { 9964 return keys.reduce(function(hashMap, key) { 9965 hashMap[key] = value; 9966 return hashMap; 9967 }, {}); 9968 } 9969 9970
vendor: 2,756 bytes, lines 9970-10032
9970// node_modules/@popperjs/core/lib/modifiers/arrow.js 9971 var toPaddingObject = function toPaddingObject2(padding, state) { 9972 padding = typeof padding === "function" ? padding(Object.assign({}, state.rects, { 9973 placement: state.placement 9974 })) : padding; 9975 return mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); 9976 }; 9977 function arrow(_ref) { 9978 var _state$modifiersData$; 9979 var state = _ref.state, name = _ref.name, options = _ref.options; 9980 var arrowElement = state.elements.arrow; 9981 var popperOffsets2 = state.modifiersData.popperOffsets; 9982 var basePlacement = getBasePlacement(state.placement); 9983 var axis = getMainAxisFromPlacement(basePlacement); 9984 var isVertical = [left, right].indexOf(basePlacement) >= 0; 9985 var len = isVertical ? "height" : "width"; 9986 if (!arrowElement || !popperOffsets2) { 9987 return; 9988 } 9989 var paddingObject = toPaddingObject(options.padding, state); 9990 var arrowRect = getLayoutRect(arrowElement); 9991 var minProp = axis === "y" ? top : left; 9992 var maxProp = axis === "y" ? bottom : right; 9993 var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets2[axis] - state.rects.popper[len]; 9994 var startDiff = popperOffsets2[axis] - state.rects.reference[axis]; 9995 var arrowOffsetParent = getOffsetParent(arrowElement); 9996 var clientSize = arrowOffsetParent ? axis === "y" ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; 9997 var centerToReference = endDiff / 2 - startDiff / 2; 9998 var min2 = paddingObject[minProp]; 9999 var max2 = clientSize - arrowRect[len] - paddingObject[maxProp]; 10000 var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; 10001 var offset2 = within(min2, center, max2); 10002 var axisProp = axis; 10003 state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset2, _state$modifiersData$.centerOffset = offset2 - center, _state$modifiersData$); 10004 } 10005 function effect2(_ref2) { 10006 var state = _ref2.state, options = _ref2.options; 10007 var _options$element = options.element, arrowElement = _options$element === void 0 ? "[data-popper-arrow]" : _options$element; 10008 if (arrowElement == null) { 10009 return; 10010 } 10011 if (typeof arrowElement === "string") { 10012 arrowElement = state.elements.popper.querySelector(arrowElement); 10013 if (!arrowElement) { 10014 return; 10015 } 10016 } 10017 if (!contains(state.elements.popper, arrowElement)) { 10018 return; 10019 } 10020 state.elements.arrow = arrowElement; 10021 } 10022 var arrow_default = { 10023 name: "arrow", 10024 enabled: true, 10025 phase: "main", 10026 fn: arrow, 10027 effect: effect2, 10028 requires: ["popperOffsets"], 10029 requiresIfExists: ["preventOverflow"] 10030 }; 10031 10032
vendor: 137 bytes, lines 10032-10037
10032// node_modules/@popperjs/core/lib/utils/getVariation.js 10033 function getVariation(placement) { 10034 return placement.split("-")[1]; 10035 } 10036 10037
vendor: 4,936 bytes, lines 10037-10158
10037// node_modules/@popperjs/core/lib/modifiers/computeStyles.js 10038 var unsetSides = { 10039 top: "auto", 10040 right: "auto", 10041 bottom: "auto", 10042 left: "auto" 10043 }; 10044 function roundOffsetsByDPR(_ref, win) { 10045 var x = _ref.x, y = _ref.y; 10046 var dpr = win.devicePixelRatio || 1; 10047 return { 10048 x: round(x * dpr) / dpr || 0, 10049 y: round(y * dpr) / dpr || 0 10050 }; 10051 } 10052 function mapToStyles(_ref2) { 10053 var _Object$assign2; 10054 var popper2 = _ref2.popper, popperRect = _ref2.popperRect, placement = _ref2.placement, variation = _ref2.variation, offsets = _ref2.offsets, position = _ref2.position, gpuAcceleration = _ref2.gpuAcceleration, adaptive = _ref2.adaptive, roundOffsets = _ref2.roundOffsets, isFixed = _ref2.isFixed; 10055 var _offsets$x = offsets.x, x = _offsets$x === void 0 ? 0 : _offsets$x, _offsets$y = offsets.y, y = _offsets$y === void 0 ? 0 : _offsets$y; 10056 var _ref3 = typeof roundOffsets === "function" ? roundOffsets({ 10057 x, 10058 y 10059 }) : { 10060 x, 10061 y 10062 }; 10063 x = _ref3.x; 10064 y = _ref3.y; 10065 var hasX = offsets.hasOwnProperty("x"); 10066 var hasY = offsets.hasOwnProperty("y"); 10067 var sideX = left; 10068 var sideY = top; 10069 var win = window; 10070 if (adaptive) { 10071 var offsetParent = getOffsetParent(popper2); 10072 var heightProp = "clientHeight"; 10073 var widthProp = "clientWidth"; 10074 if (offsetParent === getWindow(popper2)) { 10075 offsetParent = getDocumentElement(popper2); 10076 if (getComputedStyle2(offsetParent).position !== "static" && position === "absolute") { 10077 heightProp = "scrollHeight"; 10078 widthProp = "scrollWidth"; 10079 } 10080 } 10081 offsetParent = offsetParent; 10082 if (placement === top || (placement === left || placement === right) && variation === end) { 10083 sideY = bottom; 10084 var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : ( 10085 // $FlowFixMe[prop-missing] 10086 offsetParent[heightProp] 10087 ); 10088 y -= offsetY - popperRect.height; 10089 y *= gpuAcceleration ? 1 : -1; 10090 } 10091 if (placement === left || (placement === top || placement === bottom) && variation === end) { 10092 sideX = right; 10093 var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : ( 10094 // $FlowFixMe[prop-missing] 10095 offsetParent[widthProp] 10096 ); 10097 x -= offsetX - popperRect.width; 10098 x *= gpuAcceleration ? 1 : -1; 10099 } 10100 } 10101 var commonStyles = Object.assign({ 10102 position 10103 }, adaptive && unsetSides); 10104 var _ref4 = roundOffsets === true ? roundOffsetsByDPR({ 10105 x, 10106 y 10107 }, getWindow(popper2)) : { 10108 x, 10109 y 10110 }; 10111 x = _ref4.x; 10112 y = _ref4.y; 10113 if (gpuAcceleration) { 10114 var _Object$assign; 10115 return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? "0" : "", _Object$assign[sideX] = hasX ? "0" : "", _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); 10116 } 10117 return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : "", _Object$assign2[sideX] = hasX ? x + "px" : "", _Object$assign2.transform = "", _Object$assign2)); 10118 } 10119 function computeStyles(_ref5) { 10120 var state = _ref5.state, options = _ref5.options; 10121 var _options$gpuAccelerat = options.gpuAcceleration, gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, _options$adaptive = options.adaptive, adaptive = _options$adaptive === void 0 ? true : _options$adaptive, _options$roundOffsets = options.roundOffsets, roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; 10122 var commonStyles = { 10123 placement: getBasePlacement(state.placement), 10124 variation: getVariation(state.placement), 10125 popper: state.elements.popper, 10126 popperRect: state.rects.popper, 10127 gpuAcceleration, 10128 isFixed: state.options.strategy === "fixed" 10129 }; 10130 if (state.modifiersData.popperOffsets != null) { 10131 state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { 10132 offsets: state.modifiersData.popperOffsets, 10133 position: state.options.strategy, 10134 adaptive, 10135 roundOffsets 10136 }))); 10137 } 10138 if (state.modifiersData.arrow != null) { 10139 state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { 10140 offsets: state.modifiersData.arrow, 10141 position: "absolute", 10142 adaptive: false, 10143 roundOffsets 10144 }))); 10145 } 10146 state.attributes.popper = Object.assign({}, state.attributes.popper, { 10147 "data-popper-placement": state.placement 10148 }); 10149 } 10150 var computeStyles_default = { 10151 name: "computeStyles", 10152 enabled: true, 10153 phase: "beforeWrite", 10154 fn: computeStyles, 10155 data: {} 10156 }; 10157 10158
vendor: 1,293 bytes, lines 10158-10196
10158// node_modules/@popperjs/core/lib/modifiers/eventListeners.js 10159 var passive = { 10160 passive: true 10161 }; 10162 function effect3(_ref) { 10163 var state = _ref.state, instance = _ref.instance, options = _ref.options; 10164 var _options$scroll = options.scroll, scroll = _options$scroll === void 0 ? true : _options$scroll, _options$resize = options.resize, resize = _options$resize === void 0 ? true : _options$resize; 10165 var window2 = getWindow(state.elements.popper); 10166 var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); 10167 if (scroll) { 10168 scrollParents.forEach(function(scrollParent) { 10169 scrollParent.addEventListener("scroll", instance.update, passive); 10170 }); 10171 } 10172 if (resize) { 10173 window2.addEventListener("resize", instance.update, passive); 10174 } 10175 return function() { 10176 if (scroll) { 10177 scrollParents.forEach(function(scrollParent) { 10178 scrollParent.removeEventListener("scroll", instance.update, passive); 10179 }); 10180 } 10181 if (resize) { 10182 window2.removeEventListener("resize", instance.update, passive); 10183 } 10184 }; 10185 } 10186 var eventListeners_default = { 10187 name: "eventListeners", 10188 enabled: true, 10189 phase: "write", 10190 fn: function fn() { 10191 }, 10192 effect: effect3, 10193 data: {} 10194 }; 10195 10196
vendor: 323 bytes, lines 10196-10209
10196// node_modules/@popperjs/core/lib/utils/getOppositePlacement.js 10197 var hash = { 10198 left: "right", 10199 right: "left", 10200 bottom: "top", 10201 top: "bottom" 10202 }; 10203 function getOppositePlacement(placement) { 10204 return placement.replace(/left|right|bottom|top/g, function(matched) { 10205 return hash[matched]; 10206 }); 10207 } 10208 10209
vendor: 291 bytes, lines 10209-10220
10209// node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js 10210 var hash2 = { 10211 start: "end", 10212 end: "start" 10213 }; 10214 function getOppositeVariationPlacement(placement) { 10215 return placement.replace(/start|end/g, function(matched) { 10216 return hash2[matched]; 10217 }); 10218 } 10219 10220
vendor: 266 bytes, lines 10220-10231
10220// node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js 10221 function getWindowScroll(node) { 10222 var win = getWindow(node); 10223 var scrollLeft = win.pageXOffset; 10224 var scrollTop = win.pageYOffset; 10225 return { 10226 scrollLeft, 10227 scrollTop 10228 }; 10229 } 10230 10231
vendor: 223 bytes, lines 10231-10236
10231// node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js 10232 function getWindowScrollBarX(element) { 10233 return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; 10234 } 10235 10236
vendor: 749 bytes, lines 10236-10262
10236// node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js 10237 function getViewportRect(element, strategy) { 10238 var win = getWindow(element); 10239 var html = getDocumentElement(element); 10240 var visualViewport = win.visualViewport; 10241 var width = html.clientWidth; 10242 var height = html.clientHeight; 10243 var x = 0; 10244 var y = 0; 10245 if (visualViewport) { 10246 width = visualViewport.width; 10247 height = visualViewport.height; 10248 var layoutViewport = isLayoutViewport(); 10249 if (layoutViewport || !layoutViewport && strategy === "fixed") { 10250 x = visualViewport.offsetLeft; 10251 y = visualViewport.offsetTop; 10252 } 10253 } 10254 return { 10255 width, 10256 height, 10257 x: x + getWindowScrollBarX(element), 10258 y 10259 }; 10260 } 10261 10262
vendor: 879 bytes, lines 10262-10283
10262// node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js 10263 function getDocumentRect(element) { 10264 var _element$ownerDocumen; 10265 var html = getDocumentElement(element); 10266 var winScroll = getWindowScroll(element); 10267 var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; 10268 var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); 10269 var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); 10270 var x = -winScroll.scrollLeft + getWindowScrollBarX(element); 10271 var y = -winScroll.scrollTop; 10272 if (getComputedStyle2(body || html).direction === "rtl") { 10273 x += max(html.clientWidth, body ? body.clientWidth : 0) - width; 10274 } 10275 return { 10276 width, 10277 height, 10278 x, 10279 y 10280 }; 10281 } 10282 10283
vendor: 364 bytes, lines 10283-10289
10283// node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js 10284 function isScrollParent(element) { 10285 var _getComputedStyle = getComputedStyle2(element), overflow = _getComputedStyle.overflow, overflowX = _getComputedStyle.overflowX, overflowY = _getComputedStyle.overflowY; 10286 return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); 10287 } 10288 10289
vendor: 352 bytes, lines 10289-10300
10289// node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js 10290 function getScrollParent(node) { 10291 if (["html", "body", "#document"].indexOf(getNodeName(node)) >= 0) { 10292 return node.ownerDocument.body; 10293 } 10294 if (isHTMLElement(node) && isScrollParent(node)) { 10295 return node; 10296 } 10297 return getScrollParent(getParentNode(node)); 10298 } 10299 10300
vendor: 794 bytes, lines 10300-10317
10300// node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js 10301 function listScrollParents(element, list) { 10302 var _element$ownerDocumen; 10303 if (list === void 0) { 10304 list = []; 10305 } 10306 var scrollParent = getScrollParent(element); 10307 var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); 10308 var win = getWindow(scrollParent); 10309 var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; 10310 var updatedList = list.concat(target); 10311 return isBody ? updatedList : ( 10312 // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here 10313 updatedList.concat(listScrollParents(getParentNode(target))) 10314 ); 10315 } 10316 10317
vendor: 257 bytes, lines 10317-10327
10317// node_modules/@popperjs/core/lib/utils/rectToClientRect.js 10318 function rectToClientRect(rect) { 10319 return Object.assign({}, rect, { 10320 left: rect.x, 10321 top: rect.y, 10322 right: rect.x + rect.width, 10323 bottom: rect.y + rect.height 10324 }); 10325 } 10326 10327
vendor: 2,466 bytes, lines 10327-10373
10327// node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js 10328 function getInnerBoundingClientRect(element, strategy) { 10329 var rect = getBoundingClientRect(element, false, strategy === "fixed"); 10330 rect.top = rect.top + element.clientTop; 10331 rect.left = rect.left + element.clientLeft; 10332 rect.bottom = rect.top + element.clientHeight; 10333 rect.right = rect.left + element.clientWidth; 10334 rect.width = element.clientWidth; 10335 rect.height = element.clientHeight; 10336 rect.x = rect.left; 10337 rect.y = rect.top; 10338 return rect; 10339 } 10340 function getClientRectFromMixedType(element, clippingParent, strategy) { 10341 return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element))); 10342 } 10343 function getClippingParents(element) { 10344 var clippingParents2 = listScrollParents(getParentNode(element)); 10345 var canEscapeClipping = ["absolute", "fixed"].indexOf(getComputedStyle2(element).position) >= 0; 10346 var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; 10347 if (!isElement(clipperElement)) { 10348 return []; 10349 } 10350 return clippingParents2.filter(function(clippingParent) { 10351 return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== "body"; 10352 }); 10353 } 10354 function getClippingRect(element, boundary, rootBoundary, strategy) { 10355 var mainClippingParents = boundary === "clippingParents" ? getClippingParents(element) : [].concat(boundary); 10356 var clippingParents2 = [].concat(mainClippingParents, [rootBoundary]); 10357 var firstClippingParent = clippingParents2[0]; 10358 var clippingRect = clippingParents2.reduce(function(accRect, clippingParent) { 10359 var rect = getClientRectFromMixedType(element, clippingParent, strategy); 10360 accRect.top = max(rect.top, accRect.top); 10361 accRect.right = min(rect.right, accRect.right); 10362 accRect.bottom = min(rect.bottom, accRect.bottom); 10363 accRect.left = max(rect.left, accRect.left); 10364 return accRect; 10365 }, getClientRectFromMixedType(element, firstClippingParent, strategy)); 10366 clippingRect.width = clippingRect.right - clippingRect.left; 10367 clippingRect.height = clippingRect.bottom - clippingRect.top; 10368 clippingRect.x = clippingRect.left; 10369 clippingRect.y = clippingRect.top; 10370 return clippingRect; 10371 } 10372 10373
vendor: 1,646 bytes, lines 10373-10428
10373// node_modules/@popperjs/core/lib/utils/computeOffsets.js 10374 function computeOffsets(_ref) { 10375 var reference2 = _ref.reference, element = _ref.element, placement = _ref.placement; 10376 var basePlacement = placement ? getBasePlacement(placement) : null; 10377 var variation = placement ? getVariation(placement) : null; 10378 var commonX = reference2.x + reference2.width / 2 - element.width / 2; 10379 var commonY = reference2.y + reference2.height / 2 - element.height / 2; 10380 var offsets; 10381 switch (basePlacement) { 10382 case top: 10383 offsets = { 10384 x: commonX, 10385 y: reference2.y - element.height 10386 }; 10387 break; 10388 case bottom: 10389 offsets = { 10390 x: commonX, 10391 y: reference2.y + reference2.height 10392 }; 10393 break; 10394 case right: 10395 offsets = { 10396 x: reference2.x + reference2.width, 10397 y: commonY 10398 }; 10399 break; 10400 case left: 10401 offsets = { 10402 x: reference2.x - element.width, 10403 y: commonY 10404 }; 10405 break; 10406 default: 10407 offsets = { 10408 x: reference2.x, 10409 y: reference2.y 10410 }; 10411 } 10412 var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; 10413 if (mainAxis != null) { 10414 var len = mainAxis === "y" ? "height" : "width"; 10415 switch (variation) { 10416 case start: 10417 offsets[mainAxis] = offsets[mainAxis] - (reference2[len] / 2 - element[len] / 2); 10418 break; 10419 case end: 10420 offsets[mainAxis] = offsets[mainAxis] + (reference2[len] / 2 - element[len] / 2); 10421 break; 10422 default: 10423 } 10424 } 10425 return offsets; 10426 } 10427 10428
vendor: 2,766 bytes, lines 10428-10466
10428// node_modules/@popperjs/core/lib/utils/detectOverflow.js 10429 function detectOverflow(state, options) { 10430 if (options === void 0) { 10431 options = {}; 10432 } 10433 var _options = options, _options$placement = _options.placement, placement = _options$placement === void 0 ? state.placement : _options$placement, _options$strategy = _options.strategy, strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, _options$boundary = _options.boundary, boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, _options$rootBoundary = _options.rootBoundary, rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, _options$elementConte = _options.elementContext, elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, _options$altBoundary = _options.altBoundary, altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, _options$padding = _options.padding, padding = _options$padding === void 0 ? 0 : _options$padding; 10434 var paddingObject = mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements)); 10435 var altContext = elementContext === popper ? reference : popper; 10436 var popperRect = state.rects.popper; 10437 var element = state.elements[altBoundary ? altContext : elementContext]; 10438 var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy); 10439 var referenceClientRect = getBoundingClientRect(state.elements.reference); 10440 var popperOffsets2 = computeOffsets({ 10441 reference: referenceClientRect, 10442 element: popperRect, 10443 strategy: "absolute", 10444 placement 10445 }); 10446 var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets2)); 10447 var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; 10448 var overflowOffsets = { 10449 top: clippingClientRect.top - elementClientRect.top + paddingObject.top, 10450 bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, 10451 left: clippingClientRect.left - elementClientRect.left + paddingObject.left, 10452 right: elementClientRect.right - clippingClientRect.right + paddingObject.right 10453 }; 10454 var offsetData = state.modifiersData.offset; 10455 if (elementContext === popper && offsetData) { 10456 var offset2 = offsetData[placement]; 10457 Object.keys(overflowOffsets).forEach(function(key) { 10458 var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; 10459 var axis = [top, bottom].indexOf(key) >= 0 ? "y" : "x"; 10460 overflowOffsets[key] += offset2[axis] * multiply; 10461 }); 10462 } 10463 return overflowOffsets; 10464 } 10465 10466
vendor: 1,383 bytes, lines 10466-10496
10466// node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js 10467 function computeAutoPlacement(state, options) { 10468 if (options === void 0) { 10469 options = {}; 10470 } 10471 var _options = options, placement = _options.placement, boundary = _options.boundary, rootBoundary = _options.rootBoundary, padding = _options.padding, flipVariations = _options.flipVariations, _options$allowedAutoP = _options.allowedAutoPlacements, allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; 10472 var variation = getVariation(placement); 10473 var placements2 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function(placement2) { 10474 return getVariation(placement2) === variation; 10475 }) : basePlacements; 10476 var allowedPlacements = placements2.filter(function(placement2) { 10477 return allowedAutoPlacements.indexOf(placement2) >= 0; 10478 }); 10479 if (allowedPlacements.length === 0) { 10480 allowedPlacements = placements2; 10481 } 10482 var overflows = allowedPlacements.reduce(function(acc, placement2) { 10483 acc[placement2] = detectOverflow(state, { 10484 placement: placement2, 10485 boundary, 10486 rootBoundary, 10487 padding 10488 })[getBasePlacement(placement2)]; 10489 return acc; 10490 }, {}); 10491 return Object.keys(overflows).sort(function(a, b) { 10492 return overflows[a] - overflows[b]; 10493 }); 10494 } 10495 10496
vendor: 4,356 bytes, lines 10496-10602
10496// node_modules/@popperjs/core/lib/modifiers/flip.js 10497 function getExpandedFallbackPlacements(placement) { 10498 if (getBasePlacement(placement) === auto) { 10499 return []; 10500 } 10501 var oppositePlacement = getOppositePlacement(placement); 10502 return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; 10503 } 10504 function flip(_ref) { 10505 var state = _ref.state, options = _ref.options, name = _ref.name; 10506 if (state.modifiersData[name]._skip) { 10507 return; 10508 } 10509 var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, specifiedFallbackPlacements = options.fallbackPlacements, padding = options.padding, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, _options$flipVariatio = options.flipVariations, flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, allowedAutoPlacements = options.allowedAutoPlacements; 10510 var preferredPlacement = state.options.placement; 10511 var basePlacement = getBasePlacement(preferredPlacement); 10512 var isBasePlacement = basePlacement === preferredPlacement; 10513 var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); 10514 var placements2 = [preferredPlacement].concat(fallbackPlacements).reduce(function(acc, placement2) { 10515 return acc.concat(getBasePlacement(placement2) === auto ? computeAutoPlacement(state, { 10516 placement: placement2, 10517 boundary, 10518 rootBoundary, 10519 padding, 10520 flipVariations, 10521 allowedAutoPlacements 10522 }) : placement2); 10523 }, []); 10524 var referenceRect = state.rects.reference; 10525 var popperRect = state.rects.popper; 10526 var checksMap = /* @__PURE__ */ new Map(); 10527 var makeFallbackChecks = true; 10528 var firstFittingPlacement = placements2[0]; 10529 for (var i = 0; i < placements2.length; i++) { 10530 var placement = placements2[i]; 10531 var _basePlacement = getBasePlacement(placement); 10532 var isStartVariation = getVariation(placement) === start; 10533 var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; 10534 var len = isVertical ? "width" : "height"; 10535 var overflow = detectOverflow(state, { 10536 placement, 10537 boundary, 10538 rootBoundary, 10539 altBoundary, 10540 padding 10541 }); 10542 var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; 10543 if (referenceRect[len] > popperRect[len]) { 10544 mainVariationSide = getOppositePlacement(mainVariationSide); 10545 } 10546 var altVariationSide = getOppositePlacement(mainVariationSide); 10547 var checks = []; 10548 if (checkMainAxis) { 10549 checks.push(overflow[_basePlacement] <= 0); 10550 } 10551 if (checkAltAxis) { 10552 checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); 10553 } 10554 if (checks.every(function(check) { 10555 return check; 10556 })) { 10557 firstFittingPlacement = placement; 10558 makeFallbackChecks = false; 10559 break; 10560 } 10561 checksMap.set(placement, checks); 10562 } 10563 if (makeFallbackChecks) { 10564 var numberOfChecks = flipVariations ? 3 : 1; 10565 var _loop = function _loop2(_i2) { 10566 var fittingPlacement = placements2.find(function(placement2) { 10567 var checks2 = checksMap.get(placement2); 10568 if (checks2) { 10569 return checks2.slice(0, _i2).every(function(check) { 10570 return check; 10571 }); 10572 } 10573 }); 10574 if (fittingPlacement) { 10575 firstFittingPlacement = fittingPlacement; 10576 return "break"; 10577 } 10578 }; 10579 for (var _i = numberOfChecks; _i > 0; _i--) { 10580 var _ret = _loop(_i); 10581 if (_ret === "break") 10582 break; 10583 } 10584 } 10585 if (state.placement !== firstFittingPlacement) { 10586 state.modifiersData[name]._skip = true; 10587 state.placement = firstFittingPlacement; 10588 state.reset = true; 10589 } 10590 } 10591 var flip_default = { 10592 name: "flip", 10593 enabled: true, 10594 phase: "main", 10595 fn: flip, 10596 requiresIfExists: ["offset"], 10597 data: { 10598 _skip: false 10599 } 10600 }; 10601 10602
vendor: 1,856 bytes, lines 10602-10656
10602// node_modules/@popperjs/core/lib/modifiers/hide.js 10603 function getSideOffsets(overflow, rect, preventedOffsets) { 10604 if (preventedOffsets === void 0) { 10605 preventedOffsets = { 10606 x: 0, 10607 y: 0 10608 }; 10609 } 10610 return { 10611 top: overflow.top - rect.height - preventedOffsets.y, 10612 right: overflow.right - rect.width + preventedOffsets.x, 10613 bottom: overflow.bottom - rect.height + preventedOffsets.y, 10614 left: overflow.left - rect.width - preventedOffsets.x 10615 }; 10616 } 10617 function isAnySideFullyClipped(overflow) { 10618 return [top, right, bottom, left].some(function(side) { 10619 return overflow[side] >= 0; 10620 }); 10621 } 10622 function hide(_ref) { 10623 var state = _ref.state, name = _ref.name; 10624 var referenceRect = state.rects.reference; 10625 var popperRect = state.rects.popper; 10626 var preventedOffsets = state.modifiersData.preventOverflow; 10627 var referenceOverflow = detectOverflow(state, { 10628 elementContext: "reference" 10629 }); 10630 var popperAltOverflow = detectOverflow(state, { 10631 altBoundary: true 10632 }); 10633 var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); 10634 var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); 10635 var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); 10636 var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); 10637 state.modifiersData[name] = { 10638 referenceClippingOffsets, 10639 popperEscapeOffsets, 10640 isReferenceHidden, 10641 hasPopperEscaped 10642 }; 10643 state.attributes.popper = Object.assign({}, state.attributes.popper, { 10644 "data-popper-reference-hidden": isReferenceHidden, 10645 "data-popper-escaped": hasPopperEscaped 10646 }); 10647 } 10648 var hide_default = { 10649 name: "hide", 10650 enabled: true, 10651 phase: "main", 10652 requiresIfExists: ["preventOverflow"], 10653 fn: hide 10654 }; 10655 10656
vendor: 1,462 bytes, lines 10656-10695
10656// node_modules/@popperjs/core/lib/modifiers/offset.js 10657 function distanceAndSkiddingToXY(placement, rects, offset2) { 10658 var basePlacement = getBasePlacement(placement); 10659 var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; 10660 var _ref = typeof offset2 === "function" ? offset2(Object.assign({}, rects, { 10661 placement 10662 })) : offset2, skidding = _ref[0], distance = _ref[1]; 10663 skidding = skidding || 0; 10664 distance = (distance || 0) * invertDistance; 10665 return [left, right].indexOf(basePlacement) >= 0 ? { 10666 x: distance, 10667 y: skidding 10668 } : { 10669 x: skidding, 10670 y: distance 10671 }; 10672 } 10673 function offset(_ref2) { 10674 var state = _ref2.state, options = _ref2.options, name = _ref2.name; 10675 var _options$offset = options.offset, offset2 = _options$offset === void 0 ? [0, 0] : _options$offset; 10676 var data = placements.reduce(function(acc, placement) { 10677 acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset2); 10678 return acc; 10679 }, {}); 10680 var _data$state$placement = data[state.placement], x = _data$state$placement.x, y = _data$state$placement.y; 10681 if (state.modifiersData.popperOffsets != null) { 10682 state.modifiersData.popperOffsets.x += x; 10683 state.modifiersData.popperOffsets.y += y; 10684 } 10685 state.modifiersData[name] = data; 10686 } 10687 var offset_default = { 10688 name: "offset", 10689 enabled: true, 10690 phase: "main", 10691 requires: ["popperOffsets"], 10692 fn: offset 10693 }; 10694 10695
vendor: 479 bytes, lines 10695-10713
10695// node_modules/@popperjs/core/lib/modifiers/popperOffsets.js 10696 function popperOffsets(_ref) { 10697 var state = _ref.state, name = _ref.name; 10698 state.modifiersData[name] = computeOffsets({ 10699 reference: state.rects.reference, 10700 element: state.rects.popper, 10701 strategy: "absolute", 10702 placement: state.placement 10703 }); 10704 } 10705 var popperOffsets_default = { 10706 name: "popperOffsets", 10707 enabled: true, 10708 phase: "read", 10709 fn: popperOffsets, 10710 data: {} 10711 }; 10712 10713
vendor: 129 bytes, lines 10713-10718
10713// node_modules/@popperjs/core/lib/utils/getAltAxis.js 10714 function getAltAxis(axis) { 10715 return axis === "x" ? "y" : "x"; 10716 } 10717 10718
vendor: 5,548 bytes, lines 10718-10811
10718// node_modules/@popperjs/core/lib/modifiers/preventOverflow.js 10719 function preventOverflow(_ref) { 10720 var state = _ref.state, options = _ref.options, name = _ref.name; 10721 var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, padding = options.padding, _options$tether = options.tether, tether = _options$tether === void 0 ? true : _options$tether, _options$tetherOffset = options.tetherOffset, tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; 10722 var overflow = detectOverflow(state, { 10723 boundary, 10724 rootBoundary, 10725 padding, 10726 altBoundary 10727 }); 10728 var basePlacement = getBasePlacement(state.placement); 10729 var variation = getVariation(state.placement); 10730 var isBasePlacement = !variation; 10731 var mainAxis = getMainAxisFromPlacement(basePlacement); 10732 var altAxis = getAltAxis(mainAxis); 10733 var popperOffsets2 = state.modifiersData.popperOffsets; 10734 var referenceRect = state.rects.reference; 10735 var popperRect = state.rects.popper; 10736 var tetherOffsetValue = typeof tetherOffset === "function" ? tetherOffset(Object.assign({}, state.rects, { 10737 placement: state.placement 10738 })) : tetherOffset; 10739 var normalizedTetherOffsetValue = typeof tetherOffsetValue === "number" ? { 10740 mainAxis: tetherOffsetValue, 10741 altAxis: tetherOffsetValue 10742 } : Object.assign({ 10743 mainAxis: 0, 10744 altAxis: 0 10745 }, tetherOffsetValue); 10746 var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null; 10747 var data = { 10748 x: 0, 10749 y: 0 10750 }; 10751 if (!popperOffsets2) { 10752 return; 10753 } 10754 if (checkMainAxis) { 10755 var _offsetModifierState$; 10756 var mainSide = mainAxis === "y" ? top : left; 10757 var altSide = mainAxis === "y" ? bottom : right; 10758 var len = mainAxis === "y" ? "height" : "width"; 10759 var offset2 = popperOffsets2[mainAxis]; 10760 var min2 = offset2 + overflow[mainSide]; 10761 var max2 = offset2 - overflow[altSide]; 10762 var additive = tether ? -popperRect[len] / 2 : 0; 10763 var minLen = variation === start ? referenceRect[len] : popperRect[len]; 10764 var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; 10765 var arrowElement = state.elements.arrow; 10766 var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { 10767 width: 0, 10768 height: 0 10769 }; 10770 var arrowPaddingObject = state.modifiersData["arrow#persistent"] ? state.modifiersData["arrow#persistent"].padding : getFreshSideObject(); 10771 var arrowPaddingMin = arrowPaddingObject[mainSide]; 10772 var arrowPaddingMax = arrowPaddingObject[altSide]; 10773 var arrowLen = within(0, referenceRect[len], arrowRect[len]); 10774 var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis; 10775 var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis; 10776 var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); 10777 var clientOffset = arrowOffsetParent ? mainAxis === "y" ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; 10778 var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0; 10779 var tetherMin = offset2 + minOffset - offsetModifierValue - clientOffset; 10780 var tetherMax = offset2 + maxOffset - offsetModifierValue; 10781 var preventedOffset = within(tether ? min(min2, tetherMin) : min2, offset2, tether ? max(max2, tetherMax) : max2); 10782 popperOffsets2[mainAxis] = preventedOffset; 10783 data[mainAxis] = preventedOffset - offset2; 10784 } 10785 if (checkAltAxis) { 10786 var _offsetModifierState$2; 10787 var _mainSide = mainAxis === "x" ? top : left; 10788 var _altSide = mainAxis === "x" ? bottom : right; 10789 var _offset = popperOffsets2[altAxis]; 10790 var _len = altAxis === "y" ? "height" : "width"; 10791 var _min = _offset + overflow[_mainSide]; 10792 var _max = _offset - overflow[_altSide]; 10793 var isOriginSide = [top, left].indexOf(basePlacement) !== -1; 10794 var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0; 10795 var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis; 10796 var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max; 10797 var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max); 10798 popperOffsets2[altAxis] = _preventedOffset; 10799 data[altAxis] = _preventedOffset - _offset; 10800 } 10801 state.modifiersData[name] = data; 10802 } 10803 var preventOverflow_default = { 10804 name: "preventOverflow", 10805 enabled: true, 10806 phase: "main", 10807 fn: preventOverflow, 10808 requiresIfExists: ["offset"] 10809 }; 10810 10811
vendor: 212 bytes, lines 10811-10819
10811// node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js 10812 function getHTMLElementScroll(element) { 10813 return { 10814 scrollLeft: element.scrollLeft, 10815 scrollTop: element.scrollTop 10816 }; 10817 } 10818 10819
vendor: 258 bytes, lines 10819-10828
10819// node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js 10820 function getNodeScroll(node) { 10821 if (node === getWindow(node) || !isHTMLElement(node)) { 10822 return getWindowScroll(node); 10823 } else { 10824 return getHTMLElementScroll(node); 10825 } 10826 } 10827 10828
vendor: 1,643 bytes, lines 10828-10872
10828// node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js 10829 function isElementScaled(element) { 10830 var rect = element.getBoundingClientRect(); 10831 var scaleX = round(rect.width) / element.offsetWidth || 1; 10832 var scaleY = round(rect.height) / element.offsetHeight || 1; 10833 return scaleX !== 1 || scaleY !== 1; 10834 } 10835 function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { 10836 if (isFixed === void 0) { 10837 isFixed = false; 10838 } 10839 var isOffsetParentAnElement = isHTMLElement(offsetParent); 10840 var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent); 10841 var documentElement = getDocumentElement(offsetParent); 10842 var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed); 10843 var scroll = { 10844 scrollLeft: 0, 10845 scrollTop: 0 10846 }; 10847 var offsets = { 10848 x: 0, 10849 y: 0 10850 }; 10851 if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { 10852 if (getNodeName(offsetParent) !== "body" || // https://github.com/popperjs/popper-core/issues/1078 10853 isScrollParent(documentElement)) { 10854 scroll = getNodeScroll(offsetParent); 10855 } 10856 if (isHTMLElement(offsetParent)) { 10857 offsets = getBoundingClientRect(offsetParent, true); 10858 offsets.x += offsetParent.clientLeft; 10859 offsets.y += offsetParent.clientTop; 10860 } else if (documentElement) { 10861 offsets.x = getWindowScrollBarX(documentElement); 10862 } 10863 } 10864 return { 10865 x: rect.left + scroll.scrollLeft - offsets.x, 10866 y: rect.top + scroll.scrollTop - offsets.y, 10867 width: rect.width, 10868 height: rect.height 10869 }; 10870 } 10871 10872
vendor: 1,109 bytes, lines 10872-10909
10872// node_modules/@popperjs/core/lib/utils/orderModifiers.js 10873 function order(modifiers) { 10874 var map = /* @__PURE__ */ new Map(); 10875 var visited = /* @__PURE__ */ new Set(); 10876 var result = []; 10877 modifiers.forEach(function(modifier) { 10878 map.set(modifier.name, modifier); 10879 }); 10880 function sort(modifier) { 10881 visited.add(modifier.name); 10882 var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); 10883 requires.forEach(function(dep) { 10884 if (!visited.has(dep)) { 10885 var depModifier = map.get(dep); 10886 if (depModifier) { 10887 sort(depModifier); 10888 } 10889 } 10890 }); 10891 result.push(modifier); 10892 } 10893 modifiers.forEach(function(modifier) { 10894 if (!visited.has(modifier.name)) { 10895 sort(modifier); 10896 } 10897 }); 10898 return result; 10899 } 10900 function orderModifiers(modifiers) { 10901 var orderedModifiers = order(modifiers); 10902 return modifierPhases.reduce(function(acc, phase) { 10903 return acc.concat(orderedModifiers.filter(function(modifier) { 10904 return modifier.phase === phase; 10905 })); 10906 }, []); 10907 } 10908 10909
vendor: 367 bytes, lines 10909-10925
10909// node_modules/@popperjs/core/lib/utils/debounce.js 10910 function debounce(fn2) { 10911 var pending; 10912 return function() { 10913 if (!pending) { 10914 pending = new Promise(function(resolve) { 10915 Promise.resolve().then(function() { 10916 pending = void 0; 10917 resolve(fn2()); 10918 }); 10919 }); 10920 } 10921 return pending; 10922 }; 10923 } 10924 10925
vendor: 557 bytes, lines 10925-10940
10925// node_modules/@popperjs/core/lib/utils/mergeByName.js 10926 function mergeByName(modifiers) { 10927 var merged = modifiers.reduce(function(merged2, current) { 10928 var existing = merged2[current.name]; 10929 merged2[current.name] = existing ? Object.assign({}, existing, current, { 10930 options: Object.assign({}, existing.options, current.options), 10931 data: Object.assign({}, existing.data, current.data) 10932 }) : current; 10933 return merged2; 10934 }, {}); 10935 return Object.keys(merged).map(function(key) { 10936 return merged[key]; 10937 }); 10938 } 10939 10940
vendor: 5,699 bytes, lines 10940-11081
10940// node_modules/@popperjs/core/lib/createPopper.js 10941 var DEFAULT_OPTIONS = { 10942 placement: "bottom", 10943 modifiers: [], 10944 strategy: "absolute" 10945 }; 10946 function areValidElements() { 10947 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 10948 args[_key] = arguments[_key]; 10949 } 10950 return !args.some(function(element) { 10951 return !(element && typeof element.getBoundingClientRect === "function"); 10952 }); 10953 } 10954 function popperGenerator(generatorOptions) { 10955 if (generatorOptions === void 0) { 10956 generatorOptions = {}; 10957 } 10958 var _generatorOptions = generatorOptions, _generatorOptions$def = _generatorOptions.defaultModifiers, defaultModifiers3 = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, _generatorOptions$def2 = _generatorOptions.defaultOptions, defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; 10959 return function createPopper4(reference2, popper2, options) { 10960 if (options === void 0) { 10961 options = defaultOptions; 10962 } 10963 var state = { 10964 placement: "bottom", 10965 orderedModifiers: [], 10966 options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), 10967 modifiersData: {}, 10968 elements: { 10969 reference: reference2, 10970 popper: popper2 10971 }, 10972 attributes: {}, 10973 styles: {} 10974 }; 10975 var effectCleanupFns = []; 10976 var isDestroyed = false; 10977 var instance = { 10978 state, 10979 setOptions: function setOptions(setOptionsAction) { 10980 var options2 = typeof setOptionsAction === "function" ? setOptionsAction(state.options) : setOptionsAction; 10981 cleanupModifierEffects(); 10982 state.options = Object.assign({}, defaultOptions, state.options, options2); 10983 state.scrollParents = { 10984 reference: isElement(reference2) ? listScrollParents(reference2) : reference2.contextElement ? listScrollParents(reference2.contextElement) : [], 10985 popper: listScrollParents(popper2) 10986 }; 10987 var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers3, state.options.modifiers))); 10988 state.orderedModifiers = orderedModifiers.filter(function(m) { 10989 return m.enabled; 10990 }); 10991 runModifierEffects(); 10992 return instance.update(); 10993 }, 10994 // Sync update â it will always be executed, even if not necessary. This 10995 // is useful for low frequency updates where sync behavior simplifies the 10996 // logic. 10997 // For high frequency updates (e.g. `resize` and `scroll` events), always 10998 // prefer the async Popper#update method 10999 forceUpdate: function forceUpdate() { 11000 if (isDestroyed) { 11001 return; 11002 } 11003 var _state$elements = state.elements, reference3 = _state$elements.reference, popper3 = _state$elements.popper; 11004 if (!areValidElements(reference3, popper3)) { 11005 return; 11006 } 11007 state.rects = { 11008 reference: getCompositeRect(reference3, getOffsetParent(popper3), state.options.strategy === "fixed"), 11009 popper: getLayoutRect(popper3) 11010 }; 11011 state.reset = false; 11012 state.placement = state.options.placement; 11013 state.orderedModifiers.forEach(function(modifier) { 11014 return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); 11015 }); 11016 for (var index = 0; index < state.orderedModifiers.length; index++) { 11017 if (state.reset === true) { 11018 state.reset = false; 11019 index = -1; 11020 continue; 11021 } 11022 var _state$orderedModifie = state.orderedModifiers[index], fn2 = _state$orderedModifie.fn, _state$orderedModifie2 = _state$orderedModifie.options, _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, name = _state$orderedModifie.name; 11023 if (typeof fn2 === "function") { 11024 state = fn2({ 11025 state, 11026 options: _options, 11027 name, 11028 instance 11029 }) || state; 11030 } 11031 } 11032 }, 11033 // Async and optimistically optimized update â it will not be executed if 11034 // not necessary (debounced to run at most once-per-tick) 11035 update: debounce(function() { 11036 return new Promise(function(resolve) { 11037 instance.forceUpdate(); 11038 resolve(state); 11039 }); 11040 }), 11041 destroy: function destroy() { 11042 cleanupModifierEffects(); 11043 isDestroyed = true; 11044 } 11045 }; 11046 if (!areValidElements(reference2, popper2)) { 11047 return instance; 11048 } 11049 instance.setOptions(options).then(function(state2) { 11050 if (!isDestroyed && options.onFirstUpdate) { 11051 options.onFirstUpdate(state2); 11052 } 11053 }); 11054 function runModifierEffects() { 11055 state.orderedModifiers.forEach(function(_ref) { 11056 var name = _ref.name, _ref$options = _ref.options, options2 = _ref$options === void 0 ? {} : _ref$options, effect4 = _ref.effect; 11057 if (typeof effect4 === "function") { 11058 var cleanupFn = effect4({ 11059 state, 11060 name, 11061 instance, 11062 options: options2 11063 }); 11064 var noopFn = function noopFn2() { 11065 }; 11066 effectCleanupFns.push(cleanupFn || noopFn); 11067 } 11068 }); 11069 } 11070 function cleanupModifierEffects() { 11071 effectCleanupFns.forEach(function(fn2) { 11072 return fn2(); 11073 }); 11074 effectCleanupFns = []; 11075 } 11076 return instance; 11077 }; 11078 } 11079 var createPopper = /* @__PURE__ */ popperGenerator(); 11080 11081
vendor: 254 bytes, lines 11081-11087
11081// node_modules/@popperjs/core/lib/popper-lite.js 11082 var defaultModifiers = [eventListeners_default, popperOffsets_default, computeStyles_default, applyStyles_default]; 11083 var createPopper2 = /* @__PURE__ */ popperGenerator({ 11084 defaultModifiers 11085 }); 11086 11087
vendor: 353 bytes, lines 11087-11093
11087// node_modules/@popperjs/core/lib/popper.js 11088 var defaultModifiers2 = [eventListeners_default, popperOffsets_default, computeStyles_default, applyStyles_default, offset_default, flip_default, preventOverflow_default, arrow_default, hide_default]; 11089 var createPopper3 = /* @__PURE__ */ popperGenerator({ 11090 defaultModifiers: defaultModifiers2 11091 }); 11092 11093
vendor: 124,430 bytes, lines 11093-14743
11093// node_modules/bootstrap/dist/js/bootstrap.esm.js 11094 var elementMap = /* @__PURE__ */ new Map(); 11095 var Data = { 11096 set(element, key, instance) { 11097 if (!elementMap.has(element)) { 11098 elementMap.set(element, /* @__PURE__ */ new Map()); 11099 } 11100 const instanceMap = elementMap.get(element); 11101 if (!instanceMap.has(key) && instanceMap.size !== 0) { 11102 console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`); 11103 return; 11104 } 11105 instanceMap.set(key, instance); 11106 }, 11107 get(element, key) { 11108 if (elementMap.has(element)) { 11109 return elementMap.get(element).get(key) || null; 11110 } 11111 return null; 11112 }, 11113 remove(element, key) { 11114 if (!elementMap.has(element)) { 11115 return; 11116 } 11117 const instanceMap = elementMap.get(element); 11118 instanceMap.delete(key); 11119 if (instanceMap.size === 0) { 11120 elementMap.delete(element); 11121 } 11122 } 11123 }; 11124 var MAX_UID = 1e6; 11125 var MILLISECONDS_MULTIPLIER = 1e3; 11126 var TRANSITION_END = "transitionend"; 11127 var parseSelector = (selector) => { 11128 if (selector && window.CSS && window.CSS.escape) { 11129 selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`); 11130 } 11131 return selector; 11132 }; 11133 var toType = (object) => { 11134 if (object === null || object === void 0) { 11135 return `${object}`; 11136 } 11137 return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase(); 11138 }; 11139 var getUID = (prefix) => { 11140 do { 11141 prefix += Math.floor(Math.random() * MAX_UID); 11142 } while (document.getElementById(prefix)); 11143 return prefix; 11144 }; 11145 var getTransitionDurationFromElement = (element) => { 11146 if (!element) { 11147 return 0; 11148 } 11149 let { 11150 transitionDuration, 11151 transitionDelay 11152 } = window.getComputedStyle(element); 11153 const floatTransitionDuration = Number.parseFloat(transitionDuration); 11154 const floatTransitionDelay = Number.parseFloat(transitionDelay); 11155 if (!floatTransitionDuration && !floatTransitionDelay) { 11156 return 0; 11157 } 11158 transitionDuration = transitionDuration.split(",")[0]; 11159 transitionDelay = transitionDelay.split(",")[0]; 11160 return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER; 11161 }; 11162 var triggerTransitionEnd = (element) => { 11163 element.dispatchEvent(new Event(TRANSITION_END)); 11164 }; 11165 var isElement2 = (object) => { 11166 if (!object || typeof object !== "object") { 11167 return false; 11168 } 11169 if (typeof object.jquery !== "undefined") { 11170 object = object[0]; 11171 } 11172 return typeof object.nodeType !== "undefined"; 11173 }; 11174 var getElement = (object) => { 11175 if (isElement2(object)) { 11176 return object.jquery ? object[0] : object; 11177 } 11178 if (typeof object === "string" && object.length > 0) { 11179 return document.querySelector(parseSelector(object)); 11180 } 11181 return null; 11182 }; 11183 var isVisible = (element) => { 11184 if (!isElement2(element) || element.getClientRects().length === 0) { 11185 return false; 11186 } 11187 const elementIsVisible = getComputedStyle(element).getPropertyValue("visibility") === "visible"; 11188 const closedDetails = element.closest("details:not([open])"); 11189 if (!closedDetails) { 11190 return elementIsVisible; 11191 } 11192 if (closedDetails !== element) { 11193 const summary = element.closest("summary"); 11194 if (summary && summary.parentNode !== closedDetails) { 11195 return false; 11196 } 11197 if (summary === null) { 11198 return false; 11199 } 11200 } 11201 return elementIsVisible; 11202 }; 11203 var isDisabled = (element) => { 11204 if (!element || element.nodeType !== Node.ELEMENT_NODE) { 11205 return true; 11206 } 11207 if (element.classList.contains("disabled")) { 11208 return true; 11209 } 11210 if (typeof element.disabled !== "undefined") { 11211 return element.disabled; 11212 } 11213 return element.hasAttribute("disabled") && element.getAttribute("disabled") !== "false"; 11214 }; 11215 var findShadowRoot = (element) => { 11216 if (!document.documentElement.attachShadow) { 11217 return null; 11218 } 11219 if (typeof element.getRootNode === "function") { 11220 const root = element.getRootNode(); 11221 return root instanceof ShadowRoot ? root : null; 11222 } 11223 if (element instanceof ShadowRoot) { 11224 return element; 11225 } 11226 if (!element.parentNode) { 11227 return null; 11228 } 11229 return findShadowRoot(element.parentNode); 11230 }; 11231 var noop = () => { 11232 }; 11233 var reflow = (element) => { 11234 element.offsetHeight; 11235 }; 11236 var getjQuery = () => { 11237 if (window.jQuery && !document.body.hasAttribute("data-bs-no-jquery")) { 11238 return window.jQuery; 11239 } 11240 return null; 11241 }; 11242 var DOMContentLoadedCallbacks = []; 11243 var onDOMContentLoaded = (callback) => { 11244 if (document.readyState === "loading") { 11245 if (!DOMContentLoadedCallbacks.length) { 11246 document.addEventListener("DOMContentLoaded", () => { 11247 for (const callback2 of DOMContentLoadedCallbacks) { 11248 callback2(); 11249 } 11250 }); 11251 } 11252 DOMContentLoadedCallbacks.push(callback); 11253 } else { 11254 callback(); 11255 } 11256 }; 11257 var isRTL = () => document.documentElement.dir === "rtl"; 11258 var defineJQueryPlugin = (plugin) => { 11259 onDOMContentLoaded(() => { 11260 const $ = getjQuery(); 11261 if ($) { 11262 const name = plugin.NAME; 11263 const JQUERY_NO_CONFLICT = $.fn[name]; 11264 $.fn[name] = plugin.jQueryInterface; 11265 $.fn[name].Constructor = plugin; 11266 $.fn[name].noConflict = () => { 11267 $.fn[name] = JQUERY_NO_CONFLICT; 11268 return plugin.jQueryInterface; 11269 }; 11270 } 11271 }); 11272 }; 11273 var execute = (possibleCallback, args = [], defaultValue = possibleCallback) => { 11274 return typeof possibleCallback === "function" ? possibleCallback.call(...args) : defaultValue; 11275 }; 11276 var executeAfterTransition = (callback, transitionElement, waitForTransition = true) => { 11277 if (!waitForTransition) { 11278 execute(callback); 11279 return; 11280 } 11281 const durationPadding = 5; 11282 const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding; 11283 let called = false; 11284 const handler = ({ 11285 target 11286 }) => { 11287 if (target !== transitionElement) { 11288 return; 11289 } 11290 called = true; 11291 transitionElement.removeEventListener(TRANSITION_END, handler); 11292 execute(callback); 11293 }; 11294 transitionElement.addEventListener(TRANSITION_END, handler); 11295 setTimeout(() => { 11296 if (!called) { 11297 triggerTransitionEnd(transitionElement); 11298 } 11299 }, emulatedDuration); 11300 }; 11301 var getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => { 11302 const listLength = list.length; 11303 let index = list.indexOf(activeElement); 11304 if (index === -1) { 11305 return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]; 11306 } 11307 index += shouldGetNext ? 1 : -1; 11308 if (isCycleAllowed) { 11309 index = (index + listLength) % listLength; 11310 } 11311 return list[Math.max(0, Math.min(index, listLength - 1))]; 11312 }; 11313 var namespaceRegex = /[^.]*(?=\..*)\.|.*/; 11314 var stripNameRegex = /\..*/; 11315 var stripUidRegex = /::\d+$/; 11316 var eventRegistry = {}; 11317 var uidEvent = 1; 11318 var customEvents = { 11319 mouseenter: "mouseover", 11320 mouseleave: "mouseout" 11321 }; 11322 var nativeEvents = /* @__PURE__ */ new Set(["click", "dblclick", "mouseup", "mousedown", "contextmenu", "mousewheel", "DOMMouseScroll", "mouseover", "mouseout", "mousemove", "selectstart", "selectend", "keydown", "keypress", "keyup", "orientationchange", "touchstart", "touchmove", "touchend", "touchcancel", "pointerdown", "pointermove", "pointerup", "pointerleave", "pointercancel", "gesturestart", "gesturechange", "gestureend", "focus", "blur", "change", "reset", "select", "submit", "focusin", "focusout", "load", "unload", "beforeunload", "resize", "move", "DOMContentLoaded", "readystatechange", "error", "abort", "scroll"]); 11323 function makeEventUid(element, uid) { 11324 return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++; 11325 } 11326 function getElementEvents(element) { 11327 const uid = makeEventUid(element); 11328 element.uidEvent = uid; 11329 eventRegistry[uid] = eventRegistry[uid] || {}; 11330 return eventRegistry[uid]; 11331 } 11332 function bootstrapHandler(element, fn2) { 11333 return function handler(event) { 11334 hydrateObj(event, { 11335 delegateTarget: element 11336 }); 11337 if (handler.oneOff) { 11338 EventHandler.off(element, event.type, fn2); 11339 } 11340 return fn2.apply(element, [event]); 11341 }; 11342 } 11343 function bootstrapDelegationHandler(element, selector, fn2) { 11344 return function handler(event) { 11345 const domElements = element.querySelectorAll(selector); 11346 for (let { 11347 target 11348 } = event; target && target !== this; target = target.parentNode) { 11349 for (const domElement of domElements) { 11350 if (domElement !== target) { 11351 continue; 11352 } 11353 hydrateObj(event, { 11354 delegateTarget: target 11355 }); 11356 if (handler.oneOff) { 11357 EventHandler.off(element, event.type, selector, fn2); 11358 } 11359 return fn2.apply(target, [event]); 11360 } 11361 } 11362 }; 11363 } 11364 function findHandler(events, callable, delegationSelector = null) { 11365 return Object.values(events).find((event) => event.callable === callable && event.delegationSelector === delegationSelector); 11366 } 11367 function normalizeParameters(originalTypeEvent, handler, delegationFunction) { 11368 const isDelegated = typeof handler === "string"; 11369 const callable = isDelegated ? delegationFunction : handler || delegationFunction; 11370 let typeEvent = getTypeEvent(originalTypeEvent); 11371 if (!nativeEvents.has(typeEvent)) { 11372 typeEvent = originalTypeEvent; 11373 } 11374 return [isDelegated, callable, typeEvent]; 11375 } 11376 function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) { 11377 if (typeof originalTypeEvent !== "string" || !element) { 11378 return; 11379 } 11380 let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); 11381 if (originalTypeEvent in customEvents) { 11382 const wrapFunction = (fn3) => { 11383 return function(event) { 11384 if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) { 11385 return fn3.call(this, event); 11386 } 11387 }; 11388 }; 11389 callable = wrapFunction(callable); 11390 } 11391 const events = getElementEvents(element); 11392 const handlers = events[typeEvent] || (events[typeEvent] = {}); 11393 const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null); 11394 if (previousFunction) { 11395 previousFunction.oneOff = previousFunction.oneOff && oneOff; 11396 return; 11397 } 11398 const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, "")); 11399 const fn2 = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable); 11400 fn2.delegationSelector = isDelegated ? handler : null; 11401 fn2.callable = callable; 11402 fn2.oneOff = oneOff; 11403 fn2.uidEvent = uid; 11404 handlers[uid] = fn2; 11405 element.addEventListener(typeEvent, fn2, isDelegated); 11406 } 11407 function removeHandler(element, events, typeEvent, handler, delegationSelector) { 11408 const fn2 = findHandler(events[typeEvent], handler, delegationSelector); 11409 if (!fn2) { 11410 return; 11411 } 11412 element.removeEventListener(typeEvent, fn2, Boolean(delegationSelector)); 11413 delete events[typeEvent][fn2.uidEvent]; 11414 } 11415 function removeNamespacedHandlers(element, events, typeEvent, namespace) { 11416 const storeElementEvent = events[typeEvent] || {}; 11417 for (const [handlerKey, event] of Object.entries(storeElementEvent)) { 11418 if (handlerKey.includes(namespace)) { 11419 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector); 11420 } 11421 } 11422 } 11423 function getTypeEvent(event) { 11424 event = event.replace(stripNameRegex, ""); 11425 return customEvents[event] || event; 11426 } 11427 var EventHandler = { 11428 on(element, event, handler, delegationFunction) { 11429 addHandler(element, event, handler, delegationFunction, false); 11430 }, 11431 one(element, event, handler, delegationFunction) { 11432 addHandler(element, event, handler, delegationFunction, true); 11433 }, 11434 off(element, originalTypeEvent, handler, delegationFunction) { 11435 if (typeof originalTypeEvent !== "string" || !element) { 11436 return; 11437 } 11438 const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); 11439 const inNamespace = typeEvent !== originalTypeEvent; 11440 const events = getElementEvents(element); 11441 const storeElementEvent = events[typeEvent] || {}; 11442 const isNamespace = originalTypeEvent.startsWith("."); 11443 if (typeof callable !== "undefined") { 11444 if (!Object.keys(storeElementEvent).length) { 11445 return; 11446 } 11447 removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null); 11448 return; 11449 } 11450 if (isNamespace) { 11451 for (const elementEvent of Object.keys(events)) { 11452 removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1)); 11453 } 11454 } 11455 for (const [keyHandlers, event] of Object.entries(storeElementEvent)) { 11456 const handlerKey = keyHandlers.replace(stripUidRegex, ""); 11457 if (!inNamespace || originalTypeEvent.includes(handlerKey)) { 11458 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector); 11459 } 11460 } 11461 }, 11462 trigger(element, event, args) { 11463 if (typeof event !== "string" || !element) { 11464 return null; 11465 } 11466 const $ = getjQuery(); 11467 const typeEvent = getTypeEvent(event); 11468 const inNamespace = event !== typeEvent; 11469 let jQueryEvent = null; 11470 let bubbles = true; 11471 let nativeDispatch = true; 11472 let defaultPrevented = false; 11473 if (inNamespace && $) { 11474 jQueryEvent = $.Event(event, args); 11475 $(element).trigger(jQueryEvent); 11476 bubbles = !jQueryEvent.isPropagationStopped(); 11477 nativeDispatch = !jQueryEvent.isImmediatePropagationStopped(); 11478 defaultPrevented = jQueryEvent.isDefaultPrevented(); 11479 } 11480 const evt = hydrateObj(new Event(event, { 11481 bubbles, 11482 cancelable: true 11483 }), args); 11484 if (defaultPrevented) { 11485 evt.preventDefault(); 11486 } 11487 if (nativeDispatch) { 11488 element.dispatchEvent(evt); 11489 } 11490 if (evt.defaultPrevented && jQueryEvent) { 11491 jQueryEvent.preventDefault(); 11492 } 11493 return evt; 11494 } 11495 }; 11496 function hydrateObj(obj, meta = {}) { 11497 for (const [key, value] of Object.entries(meta)) { 11498 try { 11499 obj[key] = value; 11500 } catch (_unused) { 11501 Object.defineProperty(obj, key, { 11502 configurable: true, 11503 get() { 11504 return value; 11505 } 11506 }); 11507 } 11508 } 11509 return obj; 11510 } 11511 function normalizeData(value) { 11512 if (value === "true") { 11513 return true; 11514 } 11515 if (value === "false") { 11516 return false; 11517 } 11518 if (value === Number(value).toString()) { 11519 return Number(value); 11520 } 11521 if (value === "" || value === "null") { 11522 return null; 11523 } 11524 if (typeof value !== "string") { 11525 return value; 11526 } 11527 try { 11528 return JSON.parse(decodeURIComponent(value)); 11529 } catch (_unused) { 11530 return value; 11531 } 11532 } 11533 function normalizeDataKey(key) { 11534 return key.replace(/[A-Z]/g, (chr) => `-${chr.toLowerCase()}`); 11535 } 11536 var Manipulator = { 11537 setDataAttribute(element, key, value) { 11538 element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value); 11539 }, 11540 removeDataAttribute(element, key) { 11541 element.removeAttribute(`data-bs-${normalizeDataKey(key)}`); 11542 }, 11543 getDataAttributes(element) { 11544 if (!element) { 11545 return {}; 11546 } 11547 const attributes = {}; 11548 const bsKeys = Object.keys(element.dataset).filter((key) => key.startsWith("bs") && !key.startsWith("bsConfig")); 11549 for (const key of bsKeys) { 11550 let pureKey = key.replace(/^bs/, ""); 11551 pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1); 11552 attributes[pureKey] = normalizeData(element.dataset[key]); 11553 } 11554 return attributes; 11555 }, 11556 getDataAttribute(element, key) { 11557 return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`)); 11558 } 11559 }; 11560 var Config = class { 11561 // Getters 11562 static get Default() { 11563 return {}; 11564 } 11565 static get DefaultType() { 11566 return {}; 11567 } 11568 static get NAME() { 11569 throw new Error('You have to implement the static method "NAME", for each component!'); 11570 } 11571 _getConfig(config) { 11572 config = this._mergeConfigObj(config); 11573 config = this._configAfterMerge(config); 11574 this._typeCheckConfig(config); 11575 return config; 11576 } 11577 _configAfterMerge(config) { 11578 return config; 11579 } 11580 _mergeConfigObj(config, element) { 11581 const jsonConfig = isElement2(element) ? Manipulator.getDataAttribute(element, "config") : {}; 11582 return { 11583 ...this.constructor.Default, 11584 ...typeof jsonConfig === "object" ? jsonConfig : {}, 11585 ...isElement2(element) ? Manipulator.getDataAttributes(element) : {}, 11586 ...typeof config === "object" ? config : {} 11587 }; 11588 } 11589 _typeCheckConfig(config, configTypes = this.constructor.DefaultType) { 11590 for (const [property, expectedTypes] of Object.entries(configTypes)) { 11591 const value = config[property]; 11592 const valueType = isElement2(value) ? "element" : toType(value); 11593 if (!new RegExp(expectedTypes).test(valueType)) { 11594 throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`); 11595 } 11596 } 11597 } 11598 }; 11599 var VERSION = "5.3.5"; 11600 var BaseComponent = class extends Config { 11601 constructor(element, config) { 11602 super(); 11603 element = getElement(element); 11604 if (!element) { 11605 return; 11606 } 11607 this._element = element; 11608 this._config = this._getConfig(config); 11609 Data.set(this._element, this.constructor.DATA_KEY, this); 11610 } 11611 // Public 11612 dispose() { 11613 Data.remove(this._element, this.constructor.DATA_KEY); 11614 EventHandler.off(this._element, this.constructor.EVENT_KEY); 11615 for (const propertyName of Object.getOwnPropertyNames(this)) { 11616 this[propertyName] = null; 11617 } 11618 } 11619 _queueCallback(callback, element, isAnimated = true) { 11620 executeAfterTransition(callback, element, isAnimated); 11621 } 11622 _getConfig(config) { 11623 config = this._mergeConfigObj(config, this._element); 11624 config = this._configAfterMerge(config); 11625 this._typeCheckConfig(config); 11626 return config; 11627 } 11628 // Static 11629 static getInstance(element) { 11630 return Data.get(getElement(element), this.DATA_KEY); 11631 } 11632 static getOrCreateInstance(element, config = {}) { 11633 return this.getInstance(element) || new this(element, typeof config === "object" ? config : null); 11634 } 11635 static get VERSION() { 11636 return VERSION; 11637 } 11638 static get DATA_KEY() { 11639 return `bs.${this.NAME}`; 11640 } 11641 static get EVENT_KEY() { 11642 return `.${this.DATA_KEY}`; 11643 } 11644 static eventName(name) { 11645 return `${name}${this.EVENT_KEY}`; 11646 } 11647 }; 11648 var getSelector = (element) => { 11649 let selector = element.getAttribute("data-bs-target"); 11650 if (!selector || selector === "#") { 11651 let hrefAttribute = element.getAttribute("href"); 11652 if (!hrefAttribute || !hrefAttribute.includes("#") && !hrefAttribute.startsWith(".")) { 11653 return null; 11654 } 11655 if (hrefAttribute.includes("#") && !hrefAttribute.startsWith("#")) { 11656 hrefAttribute = `#${hrefAttribute.split("#")[1]}`; 11657 } 11658 selector = hrefAttribute && hrefAttribute !== "#" ? hrefAttribute.trim() : null; 11659 } 11660 return selector ? selector.split(",").map((sel) => parseSelector(sel)).join(",") : null; 11661 }; 11662 var SelectorEngine = { 11663 find(selector, element = document.documentElement) { 11664 return [].concat(...Element.prototype.querySelectorAll.call(element, selector)); 11665 }, 11666 findOne(selector, element = document.documentElement) { 11667 return Element.prototype.querySelector.call(element, selector); 11668 }, 11669 children(element, selector) { 11670 return [].concat(...element.children).filter((child) => child.matches(selector)); 11671 }, 11672 parents(element, selector) { 11673 const parents = []; 11674 let ancestor = element.parentNode.closest(selector); 11675 while (ancestor) { 11676 parents.push(ancestor); 11677 ancestor = ancestor.parentNode.closest(selector); 11678 } 11679 return parents; 11680 }, 11681 prev(element, selector) { 11682 let previous = element.previousElementSibling; 11683 while (previous) { 11684 if (previous.matches(selector)) { 11685 return [previous]; 11686 } 11687 previous = previous.previousElementSibling; 11688 } 11689 return []; 11690 }, 11691 // TODO: this is now unused; remove later along with prev() 11692 next(element, selector) { 11693 let next = element.nextElementSibling; 11694 while (next) { 11695 if (next.matches(selector)) { 11696 return [next]; 11697 } 11698 next = next.nextElementSibling; 11699 } 11700 return []; 11701 }, 11702 focusableChildren(element) { 11703 const focusables = ["a", "button", "input", "textarea", "select", "details", "[tabindex]", '[contenteditable="true"]'].map((selector) => `${selector}:not([tabindex^="-"])`).join(","); 11704 return this.find(focusables, element).filter((el) => !isDisabled(el) && isVisible(el)); 11705 }, 11706 getSelectorFromElement(element) { 11707 const selector = getSelector(element); 11708 if (selector) { 11709 return SelectorEngine.findOne(selector) ? selector : null; 11710 } 11711 return null; 11712 }, 11713 getElementFromSelector(element) { 11714 const selector = getSelector(element); 11715 return selector ? SelectorEngine.findOne(selector) : null; 11716 }, 11717 getMultipleElementsFromSelector(element) { 11718 const selector = getSelector(element); 11719 return selector ? SelectorEngine.find(selector) : []; 11720 } 11721 }; 11722 var enableDismissTrigger = (component, method = "hide") => { 11723 const clickEvent = `click.dismiss${component.EVENT_KEY}`; 11724 const name = component.NAME; 11725 EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function(event) { 11726 if (["A", "AREA"].includes(this.tagName)) { 11727 event.preventDefault(); 11728 } 11729 if (isDisabled(this)) { 11730 return; 11731 } 11732 const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`); 11733 const instance = component.getOrCreateInstance(target); 11734 instance[method](); 11735 }); 11736 }; 11737 var NAME$f = "alert"; 11738 var DATA_KEY$a = "bs.alert"; 11739 var EVENT_KEY$b = `.${DATA_KEY$a}`; 11740 var EVENT_CLOSE = `close${EVENT_KEY$b}`; 11741 var EVENT_CLOSED = `closed${EVENT_KEY$b}`; 11742 var CLASS_NAME_FADE$5 = "fade"; 11743 var CLASS_NAME_SHOW$8 = "show"; 11744 var Alert = class _Alert extends BaseComponent { 11745 // Getters 11746 static get NAME() { 11747 return NAME$f; 11748 } 11749 // Public 11750 close() { 11751 const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE); 11752 if (closeEvent.defaultPrevented) { 11753 return; 11754 } 11755 this._element.classList.remove(CLASS_NAME_SHOW$8); 11756 const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5); 11757 this._queueCallback(() => this._destroyElement(), this._element, isAnimated); 11758 } 11759 // Private 11760 _destroyElement() { 11761 this._element.remove(); 11762 EventHandler.trigger(this._element, EVENT_CLOSED); 11763 this.dispose(); 11764 } 11765 // Static 11766 static jQueryInterface(config) { 11767 return this.each(function() { 11768 const data = _Alert.getOrCreateInstance(this); 11769 if (typeof config !== "string") { 11770 return; 11771 } 11772 if (data[config] === void 0 || config.startsWith("_") || config === "constructor") { 11773 throw new TypeError(`No method named "${config}"`); 11774 } 11775 data[config](this); 11776 }); 11777 } 11778 }; 11779 enableDismissTrigger(Alert, "close"); 11780 defineJQueryPlugin(Alert); 11781 var NAME$e = "button"; 11782 var DATA_KEY$9 = "bs.button"; 11783 var EVENT_KEY$a = `.${DATA_KEY$9}`; 11784 var DATA_API_KEY$6 = ".data-api"; 11785 var CLASS_NAME_ACTIVE$3 = "active"; 11786 var SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle="button"]'; 11787 var EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`; 11788 var Button = class _Button extends BaseComponent { 11789 // Getters 11790 static get NAME() { 11791 return NAME$e; 11792 } 11793 // Public 11794 toggle() { 11795 this._element.setAttribute("aria-pressed", this._element.classList.toggle(CLASS_NAME_ACTIVE$3)); 11796 } 11797 // Static 11798 static jQueryInterface(config) { 11799 return this.each(function() { 11800 const data = _Button.getOrCreateInstance(this); 11801 if (config === "toggle") { 11802 data[config](); 11803 } 11804 }); 11805 } 11806 }; 11807 EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, (event) => { 11808 event.preventDefault(); 11809 const button = event.target.closest(SELECTOR_DATA_TOGGLE$5); 11810 const data = Button.getOrCreateInstance(button); 11811 data.toggle(); 11812 }); 11813 defineJQueryPlugin(Button); 11814 var NAME$d = "swipe"; 11815 var EVENT_KEY$9 = ".bs.swipe"; 11816 var EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`; 11817 var EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`; 11818 var EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`; 11819 var EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`; 11820 var EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`; 11821 var POINTER_TYPE_TOUCH = "touch"; 11822 var POINTER_TYPE_PEN = "pen"; 11823 var CLASS_NAME_POINTER_EVENT = "pointer-event"; 11824 var SWIPE_THRESHOLD = 40; 11825 var Default$c = { 11826 endCallback: null, 11827 leftCallback: null, 11828 rightCallback: null 11829 }; 11830 var DefaultType$c = { 11831 endCallback: "(function|null)", 11832 leftCallback: "(function|null)", 11833 rightCallback: "(function|null)" 11834 }; 11835 var Swipe = class _Swipe extends Config { 11836 constructor(element, config) { 11837 super(); 11838 this._element = element; 11839 if (!element || !_Swipe.isSupported()) { 11840 return; 11841 } 11842 this._config = this._getConfig(config); 11843 this._deltaX = 0; 11844 this._supportPointerEvents = Boolean(window.PointerEvent); 11845 this._initEvents(); 11846 } 11847 // Getters 11848 static get Default() { 11849 return Default$c; 11850 } 11851 static get DefaultType() { 11852 return DefaultType$c; 11853 } 11854 static get NAME() { 11855 return NAME$d; 11856 } 11857 // Public 11858 dispose() { 11859 EventHandler.off(this._element, EVENT_KEY$9); 11860 } 11861 // Private 11862 _start(event) { 11863 if (!this._supportPointerEvents) { 11864 this._deltaX = event.touches[0].clientX; 11865 return; 11866 } 11867 if (this._eventIsPointerPenTouch(event)) { 11868 this._deltaX = event.clientX; 11869 } 11870 } 11871 _end(event) { 11872 if (this._eventIsPointerPenTouch(event)) { 11873 this._deltaX = event.clientX - this._deltaX; 11874 } 11875 this._handleSwipe(); 11876 execute(this._config.endCallback); 11877 } 11878 _move(event) { 11879 this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX; 11880 } 11881 _handleSwipe() { 11882 const absDeltaX = Math.abs(this._deltaX); 11883 if (absDeltaX <= SWIPE_THRESHOLD) { 11884 return; 11885 } 11886 const direction = absDeltaX / this._deltaX; 11887 this._deltaX = 0; 11888 if (!direction) { 11889 return; 11890 } 11891 execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback); 11892 } 11893 _initEvents() { 11894 if (this._supportPointerEvents) { 11895 EventHandler.on(this._element, EVENT_POINTERDOWN, (event) => this._start(event)); 11896 EventHandler.on(this._element, EVENT_POINTERUP, (event) => this._end(event)); 11897 this._element.classList.add(CLASS_NAME_POINTER_EVENT); 11898 } else { 11899 EventHandler.on(this._element, EVENT_TOUCHSTART, (event) => this._start(event)); 11900 EventHandler.on(this._element, EVENT_TOUCHMOVE, (event) => this._move(event)); 11901 EventHandler.on(this._element, EVENT_TOUCHEND, (event) => this._end(event)); 11902 } 11903 } 11904 _eventIsPointerPenTouch(event) { 11905 return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH); 11906 } 11907 // Static 11908 static isSupported() { 11909 return "ontouchstart" in document.documentElement || navigator.maxTouchPoints > 0; 11910 } 11911 }; 11912 var NAME$c = "carousel"; 11913 var DATA_KEY$8 = "bs.carousel"; 11914 var EVENT_KEY$8 = `.${DATA_KEY$8}`; 11915 var DATA_API_KEY$5 = ".data-api"; 11916 var ARROW_LEFT_KEY$1 = "ArrowLeft"; 11917 var ARROW_RIGHT_KEY$1 = "ArrowRight"; 11918 var TOUCHEVENT_COMPAT_WAIT = 500; 11919 var ORDER_NEXT = "next"; 11920 var ORDER_PREV = "prev"; 11921 var DIRECTION_LEFT = "left"; 11922 var DIRECTION_RIGHT = "right"; 11923 var EVENT_SLIDE = `slide${EVENT_KEY$8}`; 11924 var EVENT_SLID = `slid${EVENT_KEY$8}`; 11925 var EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`; 11926 var EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`; 11927 var EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`; 11928 var EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`; 11929 var EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`; 11930 var EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`; 11931 var CLASS_NAME_CAROUSEL = "carousel"; 11932 var CLASS_NAME_ACTIVE$2 = "active"; 11933 var CLASS_NAME_SLIDE = "slide"; 11934 var CLASS_NAME_END = "carousel-item-end"; 11935 var CLASS_NAME_START = "carousel-item-start"; 11936 var CLASS_NAME_NEXT = "carousel-item-next"; 11937 var CLASS_NAME_PREV = "carousel-item-prev"; 11938 var SELECTOR_ACTIVE = ".active"; 11939 var SELECTOR_ITEM = ".carousel-item"; 11940 var SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM; 11941 var SELECTOR_ITEM_IMG = ".carousel-item img"; 11942 var SELECTOR_INDICATORS = ".carousel-indicators"; 11943 var SELECTOR_DATA_SLIDE = "[data-bs-slide], [data-bs-slide-to]"; 11944 var SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]'; 11945 var KEY_TO_DIRECTION = { 11946 [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT, 11947 [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT 11948 }; 11949 var Default$b = { 11950 interval: 5e3, 11951 keyboard: true, 11952 pause: "hover", 11953 ride: false, 11954 touch: true, 11955 wrap: true 11956 }; 11957 var DefaultType$b = { 11958 interval: "(number|boolean)", 11959 // TODO:v6 remove boolean support 11960 keyboard: "boolean", 11961 pause: "(string|boolean)", 11962 ride: "(boolean|string)", 11963 touch: "boolean", 11964 wrap: "boolean" 11965 }; 11966 var Carousel = class _Carousel extends BaseComponent { 11967 constructor(element, config) { 11968 super(element, config); 11969 this._interval = null; 11970 this._activeElement = null; 11971 this._isSliding = false; 11972 this.touchTimeout = null; 11973 this._swipeHelper = null; 11974 this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element); 11975 this._addEventListeners(); 11976 if (this._config.ride === CLASS_NAME_CAROUSEL) { 11977 this.cycle(); 11978 } 11979 } 11980 // Getters 11981 static get Default() { 11982 return Default$b; 11983 } 11984 static get DefaultType() { 11985 return DefaultType$b; 11986 } 11987 static get NAME() { 11988 return NAME$c; 11989 } 11990 // Public 11991 next() { 11992 this._slide(ORDER_NEXT); 11993 } 11994 nextWhenVisible() { 11995 if (!document.hidden && isVisible(this._element)) { 11996 this.next(); 11997 } 11998 } 11999 prev() { 12000 this._slide(ORDER_PREV); 12001 } 12002 pause() { 12003 if (this._isSliding) { 12004 triggerTransitionEnd(this._element); 12005 } 12006 this._clearInterval(); 12007 } 12008 cycle() { 12009 this._clearInterval(); 12010 this._updateInterval(); 12011 this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval); 12012 } 12013 _maybeEnableCycle() { 12014 if (!this._config.ride) { 12015 return; 12016 } 12017 if (this._isSliding) { 12018 EventHandler.one(this._element, EVENT_SLID, () => this.cycle()); 12019 return; 12020 } 12021 this.cycle(); 12022 } 12023 to(index) { 12024 const items = this._getItems(); 12025 if (index > items.length - 1 || index < 0) { 12026 return; 12027 } 12028 if (this._isSliding) { 12029 EventHandler.one(this._element, EVENT_SLID, () => this.to(index)); 12030 return; 12031 } 12032 const activeIndex = this._getItemIndex(this._getActive()); 12033 if (activeIndex === index) { 12034 return; 12035 } 12036 const order2 = index > activeIndex ? ORDER_NEXT : ORDER_PREV; 12037 this._slide(order2, items[index]); 12038 } 12039 dispose() { 12040 if (this._swipeHelper) { 12041 this._swipeHelper.dispose(); 12042 } 12043 super.dispose(); 12044 } 12045 // Private 12046 _configAfterMerge(config) { 12047 config.defaultInterval = config.interval; 12048 return config; 12049 } 12050 _addEventListeners() { 12051 if (this._config.keyboard) { 12052 EventHandler.on(this._element, EVENT_KEYDOWN$1, (event) => this._keydown(event)); 12053 } 12054 if (this._config.pause === "hover") { 12055 EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause()); 12056 EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle()); 12057 } 12058 if (this._config.touch && Swipe.isSupported()) { 12059 this._addTouchEventListeners(); 12060 } 12061 } 12062 _addTouchEventListeners() { 12063 for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) { 12064 EventHandler.on(img, EVENT_DRAG_START, (event) => event.preventDefault()); 12065 } 12066 const endCallBack = () => { 12067 if (this._config.pause !== "hover") { 12068 return; 12069 } 12070 this.pause(); 12071 if (this.touchTimeout) { 12072 clearTimeout(this.touchTimeout); 12073 } 12074 this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval); 12075 }; 12076 const swipeConfig = { 12077 leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)), 12078 rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)), 12079 endCallback: endCallBack 12080 }; 12081 this._swipeHelper = new Swipe(this._element, swipeConfig); 12082 } 12083 _keydown(event) { 12084 if (/input|textarea/i.test(event.target.tagName)) { 12085 return; 12086 } 12087 const direction = KEY_TO_DIRECTION[event.key]; 12088 if (direction) { 12089 event.preventDefault(); 12090 this._slide(this._directionToOrder(direction)); 12091 } 12092 } 12093 _getItemIndex(element) { 12094 return this._getItems().indexOf(element); 12095 } 12096 _setActiveIndicatorElement(index) { 12097 if (!this._indicatorsElement) { 12098 return; 12099 } 12100 const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement); 12101 activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2); 12102 activeIndicator.removeAttribute("aria-current"); 12103 const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement); 12104 if (newActiveIndicator) { 12105 newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2); 12106 newActiveIndicator.setAttribute("aria-current", "true"); 12107 } 12108 } 12109 _updateInterval() { 12110 const element = this._activeElement || this._getActive(); 12111 if (!element) { 12112 return; 12113 } 12114 const elementInterval = Number.parseInt(element.getAttribute("data-bs-interval"), 10); 12115 this._config.interval = elementInterval || this._config.defaultInterval; 12116 } 12117 _slide(order2, element = null) { 12118 if (this._isSliding) { 12119 return; 12120 } 12121 const activeElement = this._getActive(); 12122 const isNext = order2 === ORDER_NEXT; 12123 const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap); 12124 if (nextElement === activeElement) { 12125 return; 12126 } 12127 const nextElementIndex = this._getItemIndex(nextElement); 12128 const triggerEvent = (eventName) => { 12129 return EventHandler.trigger(this._element, eventName, { 12130 relatedTarget: nextElement, 12131 direction: this._orderToDirection(order2), 12132 from: this._getItemIndex(activeElement), 12133 to: nextElementIndex 12134 }); 12135 }; 12136 const slideEvent = triggerEvent(EVENT_SLIDE); 12137 if (slideEvent.defaultPrevented) { 12138 return; 12139 } 12140 if (!activeElement || !nextElement) { 12141 return; 12142 } 12143 const isCycling = Boolean(this._interval); 12144 this.pause(); 12145 this._isSliding = true; 12146 this._setActiveIndicatorElement(nextElementIndex); 12147 this._activeElement = nextElement; 12148 const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END; 12149 const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV; 12150 nextElement.classList.add(orderClassName); 12151 reflow(nextElement); 12152 activeElement.classList.add(directionalClassName); 12153 nextElement.classList.add(directionalClassName); 12154 const completeCallBack = () => { 12155 nextElement.classList.remove(directionalClassName, orderClassName); 12156 nextElement.classList.add(CLASS_NAME_ACTIVE$2); 12157 activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName); 12158 this._isSliding = false; 12159 triggerEvent(EVENT_SLID); 12160 }; 12161 this._queueCallback(completeCallBack, activeElement, this._isAnimated()); 12162 if (isCycling) { 12163 this.cycle(); 12164 } 12165 } 12166 _isAnimated() { 12167 return this._element.classList.contains(CLASS_NAME_SLIDE); 12168 } 12169 _getActive() { 12170 return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element); 12171 } 12172 _getItems() { 12173 return SelectorEngine.find(SELECTOR_ITEM, this._element); 12174 } 12175 _clearInterval() { 12176 if (this._interval) { 12177 clearInterval(this._interval); 12178 this._interval = null; 12179 } 12180 } 12181 _directionToOrder(direction) { 12182 if (isRTL()) { 12183 return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT; 12184 } 12185 return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV; 12186 } 12187 _orderToDirection(order2) { 12188 if (isRTL()) { 12189 return order2 === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT; 12190 } 12191 return order2 === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT; 12192 } 12193 // Static 12194 static jQueryInterface(config) { 12195 return this.each(function() { 12196 const data = _Carousel.getOrCreateInstance(this, config); 12197 if (typeof config === "number") { 12198 data.to(config); 12199 return; 12200 } 12201 if (typeof config === "string") { 12202 if (data[config] === void 0 || config.startsWith("_") || config === "constructor") { 12203 throw new TypeError(`No method named "${config}"`); 12204 } 12205 data[config](); 12206 } 12207 }); 12208 } 12209 }; 12210 EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function(event) { 12211 const target = SelectorEngine.getElementFromSelector(this); 12212 if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) { 12213 return; 12214 } 12215 event.preventDefault(); 12216 const carousel = Carousel.getOrCreateInstance(target); 12217 const slideIndex = this.getAttribute("data-bs-slide-to"); 12218 if (slideIndex) { 12219 carousel.to(slideIndex); 12220 carousel._maybeEnableCycle(); 12221 return; 12222 } 12223 if (Manipulator.getDataAttribute(this, "slide") === "next") { 12224 carousel.next(); 12225 carousel._maybeEnableCycle(); 12226 return; 12227 } 12228 carousel.prev(); 12229 carousel._maybeEnableCycle(); 12230 }); 12231 EventHandler.on(window, EVENT_LOAD_DATA_API$3, () => { 12232 const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE); 12233 for (const carousel of carousels) { 12234 Carousel.getOrCreateInstance(carousel); 12235 } 12236 }); 12237 defineJQueryPlugin(Carousel); 12238 var NAME$b = "collapse"; 12239 var DATA_KEY$7 = "bs.collapse"; 12240 var EVENT_KEY$7 = `.${DATA_KEY$7}`; 12241 var DATA_API_KEY$4 = ".data-api"; 12242 var EVENT_SHOW$6 = `show${EVENT_KEY$7}`; 12243 var EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`; 12244 var EVENT_HIDE$6 = `hide${EVENT_KEY$7}`; 12245 var EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`; 12246 var EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`; 12247 var CLASS_NAME_SHOW$7 = "show"; 12248 var CLASS_NAME_COLLAPSE = "collapse"; 12249 var CLASS_NAME_COLLAPSING = "collapsing"; 12250 var CLASS_NAME_COLLAPSED = "collapsed"; 12251 var CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`; 12252 var CLASS_NAME_HORIZONTAL = "collapse-horizontal"; 12253 var WIDTH = "width"; 12254 var HEIGHT = "height"; 12255 var SELECTOR_ACTIVES = ".collapse.show, .collapse.collapsing"; 12256 var SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle="collapse"]'; 12257 var Default$a = { 12258 parent: null, 12259 toggle: true 12260 }; 12261 var DefaultType$a = { 12262 parent: "(null|element)", 12263 toggle: "boolean" 12264 }; 12265 var Collapse = class _Collapse extends BaseComponent { 12266 constructor(element, config) { 12267 super(element, config); 12268 this._isTransitioning = false; 12269 this._triggerArray = []; 12270 const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4); 12271 for (const elem of toggleList) { 12272 const selector = SelectorEngine.getSelectorFromElement(elem); 12273 const filterElement = SelectorEngine.find(selector).filter((foundElement) => foundElement === this._element); 12274 if (selector !== null && filterElement.length) { 12275 this._triggerArray.push(elem); 12276 } 12277 } 12278 this._initializeChildren(); 12279 if (!this._config.parent) { 12280 this._addAriaAndCollapsedClass(this._triggerArray, this._isShown()); 12281 } 12282 if (this._config.toggle) { 12283 this.toggle(); 12284 } 12285 } 12286 // Getters 12287 static get Default() { 12288 return Default$a; 12289 } 12290 static get DefaultType() { 12291 return DefaultType$a; 12292 } 12293 static get NAME() { 12294 return NAME$b; 12295 } 12296 // Public 12297 toggle() { 12298 if (this._isShown()) { 12299 this.hide(); 12300 } else { 12301 this.show(); 12302 } 12303 } 12304 show() { 12305 if (this._isTransitioning || this._isShown()) { 12306 return; 12307 } 12308 let activeChildren = []; 12309 if (this._config.parent) { 12310 activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter((element) => element !== this._element).map((element) => _Collapse.getOrCreateInstance(element, { 12311 toggle: false 12312 })); 12313 } 12314 if (activeChildren.length && activeChildren[0]._isTransitioning) { 12315 return; 12316 } 12317 const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6); 12318 if (startEvent.defaultPrevented) { 12319 return; 12320 } 12321 for (const activeInstance of activeChildren) { 12322 activeInstance.hide(); 12323 } 12324 const dimension = this._getDimension(); 12325 this._element.classList.remove(CLASS_NAME_COLLAPSE); 12326 this._element.classList.add(CLASS_NAME_COLLAPSING); 12327 this._element.style[dimension] = 0; 12328 this._addAriaAndCollapsedClass(this._triggerArray, true); 12329 this._isTransitioning = true; 12330 const complete = () => { 12331 this._isTransitioning = false; 12332 this._element.classList.remove(CLASS_NAME_COLLAPSING); 12333 this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7); 12334 this._element.style[dimension] = ""; 12335 EventHandler.trigger(this._element, EVENT_SHOWN$6); 12336 }; 12337 const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); 12338 const scrollSize = `scroll${capitalizedDimension}`; 12339 this._queueCallback(complete, this._element, true); 12340 this._element.style[dimension] = `${this._element[scrollSize]}px`; 12341 } 12342 hide() { 12343 if (this._isTransitioning || !this._isShown()) { 12344 return; 12345 } 12346 const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6); 12347 if (startEvent.defaultPrevented) { 12348 return; 12349 } 12350 const dimension = this._getDimension(); 12351 this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`; 12352 reflow(this._element); 12353 this._element.classList.add(CLASS_NAME_COLLAPSING); 12354 this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7); 12355 for (const trigger of this._triggerArray) { 12356 const element = SelectorEngine.getElementFromSelector(trigger); 12357 if (element && !this._isShown(element)) { 12358 this._addAriaAndCollapsedClass([trigger], false); 12359 } 12360 } 12361 this._isTransitioning = true; 12362 const complete = () => { 12363 this._isTransitioning = false; 12364 this._element.classList.remove(CLASS_NAME_COLLAPSING); 12365 this._element.classList.add(CLASS_NAME_COLLAPSE); 12366 EventHandler.trigger(this._element, EVENT_HIDDEN$6); 12367 }; 12368 this._element.style[dimension] = ""; 12369 this._queueCallback(complete, this._element, true); 12370 } 12371 _isShown(element = this._element) { 12372 return element.classList.contains(CLASS_NAME_SHOW$7); 12373 } 12374 // Private 12375 _configAfterMerge(config) { 12376 config.toggle = Boolean(config.toggle); 12377 config.parent = getElement(config.parent); 12378 return config; 12379 } 12380 _getDimension() { 12381 return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT; 12382 } 12383 _initializeChildren() { 12384 if (!this._config.parent) { 12385 return; 12386 } 12387 const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4); 12388 for (const element of children) { 12389 const selected = SelectorEngine.getElementFromSelector(element); 12390 if (selected) { 12391 this._addAriaAndCollapsedClass([element], this._isShown(selected)); 12392 } 12393 } 12394 } 12395 _getFirstLevelChildren(selector) { 12396 const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent); 12397 return SelectorEngine.find(selector, this._config.parent).filter((element) => !children.includes(element)); 12398 } 12399 _addAriaAndCollapsedClass(triggerArray, isOpen) { 12400 if (!triggerArray.length) { 12401 return; 12402 } 12403 for (const element of triggerArray) { 12404 element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen); 12405 element.setAttribute("aria-expanded", isOpen); 12406 } 12407 } 12408 // Static 12409 static jQueryInterface(config) { 12410 const _config = {}; 12411 if (typeof config === "string" && /show|hide/.test(config)) { 12412 _config.toggle = false; 12413 } 12414 return this.each(function() { 12415 const data = _Collapse.getOrCreateInstance(this, _config); 12416 if (typeof config === "string") { 12417 if (typeof data[config] === "undefined") { 12418 throw new TypeError(`No method named "${config}"`); 12419 } 12420 data[config](); 12421 } 12422 }); 12423 } 12424 }; 12425 EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function(event) { 12426 if (event.target.tagName === "A" || event.delegateTarget && event.delegateTarget.tagName === "A") { 12427 event.preventDefault(); 12428 } 12429 for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) { 12430 Collapse.getOrCreateInstance(element, { 12431 toggle: false 12432 }).toggle(); 12433 } 12434 }); 12435 defineJQueryPlugin(Collapse); 12436 var NAME$a = "dropdown"; 12437 var DATA_KEY$6 = "bs.dropdown"; 12438 var EVENT_KEY$6 = `.${DATA_KEY$6}`; 12439 var DATA_API_KEY$3 = ".data-api"; 12440 var ESCAPE_KEY$2 = "Escape"; 12441 var TAB_KEY$1 = "Tab"; 12442 var ARROW_UP_KEY$1 = "ArrowUp"; 12443 var ARROW_DOWN_KEY$1 = "ArrowDown"; 12444 var RIGHT_MOUSE_BUTTON = 2; 12445 var EVENT_HIDE$5 = `hide${EVENT_KEY$6}`; 12446 var EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`; 12447 var EVENT_SHOW$5 = `show${EVENT_KEY$6}`; 12448 var EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`; 12449 var EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`; 12450 var EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`; 12451 var EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`; 12452 var CLASS_NAME_SHOW$6 = "show"; 12453 var CLASS_NAME_DROPUP = "dropup"; 12454 var CLASS_NAME_DROPEND = "dropend"; 12455 var CLASS_NAME_DROPSTART = "dropstart"; 12456 var CLASS_NAME_DROPUP_CENTER = "dropup-center"; 12457 var CLASS_NAME_DROPDOWN_CENTER = "dropdown-center"; 12458 var SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)'; 12459 var SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`; 12460 var SELECTOR_MENU = ".dropdown-menu"; 12461 var SELECTOR_NAVBAR = ".navbar"; 12462 var SELECTOR_NAVBAR_NAV = ".navbar-nav"; 12463 var SELECTOR_VISIBLE_ITEMS = ".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)"; 12464 var PLACEMENT_TOP = isRTL() ? "top-end" : "top-start"; 12465 var PLACEMENT_TOPEND = isRTL() ? "top-start" : "top-end"; 12466 var PLACEMENT_BOTTOM = isRTL() ? "bottom-end" : "bottom-start"; 12467 var PLACEMENT_BOTTOMEND = isRTL() ? "bottom-start" : "bottom-end"; 12468 var PLACEMENT_RIGHT = isRTL() ? "left-start" : "right-start"; 12469 var PLACEMENT_LEFT = isRTL() ? "right-start" : "left-start"; 12470 var PLACEMENT_TOPCENTER = "top"; 12471 var PLACEMENT_BOTTOMCENTER = "bottom"; 12472 var Default$9 = { 12473 autoClose: true, 12474 boundary: "clippingParents", 12475 display: "dynamic", 12476 offset: [0, 2], 12477 popperConfig: null, 12478 reference: "toggle" 12479 }; 12480 var DefaultType$9 = { 12481 autoClose: "(boolean|string)", 12482 boundary: "(string|element)", 12483 display: "string", 12484 offset: "(array|string|function)", 12485 popperConfig: "(null|object|function)", 12486 reference: "(string|element|object)" 12487 }; 12488 var Dropdown = class _Dropdown extends BaseComponent { 12489 constructor(element, config) { 12490 super(element, config); 12491 this._popper = null; 12492 this._parent = this._element.parentNode; 12493 this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent); 12494 this._inNavbar = this._detectNavbar(); 12495 } 12496 // Getters 12497 static get Default() { 12498 return Default$9; 12499 } 12500 static get DefaultType() { 12501 return DefaultType$9; 12502 } 12503 static get NAME() { 12504 return NAME$a; 12505 } 12506 // Public 12507 toggle() { 12508 return this._isShown() ? this.hide() : this.show(); 12509 } 12510 show() { 12511 if (isDisabled(this._element) || this._isShown()) { 12512 return; 12513 } 12514 const relatedTarget = { 12515 relatedTarget: this._element 12516 }; 12517 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget); 12518 if (showEvent.defaultPrevented) { 12519 return; 12520 } 12521 this._createPopper(); 12522 if ("ontouchstart" in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) { 12523 for (const element of [].concat(...document.body.children)) { 12524 EventHandler.on(element, "mouseover", noop); 12525 } 12526 } 12527 this._element.focus(); 12528 this._element.setAttribute("aria-expanded", true); 12529 this._menu.classList.add(CLASS_NAME_SHOW$6); 12530 this._element.classList.add(CLASS_NAME_SHOW$6); 12531 EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget); 12532 } 12533 hide() { 12534 if (isDisabled(this._element) || !this._isShown()) { 12535 return; 12536 } 12537 const relatedTarget = { 12538 relatedTarget: this._element 12539 }; 12540 this._completeHide(relatedTarget); 12541 } 12542 dispose() { 12543 if (this._popper) { 12544 this._popper.destroy(); 12545 } 12546 super.dispose(); 12547 } 12548 update() { 12549 this._inNavbar = this._detectNavbar(); 12550 if (this._popper) { 12551 this._popper.update(); 12552 } 12553 } 12554 // Private 12555 _completeHide(relatedTarget) { 12556 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget); 12557 if (hideEvent.defaultPrevented) { 12558 return; 12559 } 12560 if ("ontouchstart" in document.documentElement) { 12561 for (const element of [].concat(...document.body.children)) { 12562 EventHandler.off(element, "mouseover", noop); 12563 } 12564 } 12565 if (this._popper) { 12566 this._popper.destroy(); 12567 } 12568 this._menu.classList.remove(CLASS_NAME_SHOW$6); 12569 this._element.classList.remove(CLASS_NAME_SHOW$6); 12570 this._element.setAttribute("aria-expanded", "false"); 12571 Manipulator.removeDataAttribute(this._menu, "popper"); 12572 EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget); 12573 } 12574 _getConfig(config) { 12575 config = super._getConfig(config); 12576 if (typeof config.reference === "object" && !isElement2(config.reference) && typeof config.reference.getBoundingClientRect !== "function") { 12577 throw new TypeError(`${NAME$a.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`); 12578 } 12579 return config; 12580 } 12581 _createPopper() { 12582 if (typeof lib_exports === "undefined") { 12583 throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org/docs/v2/)"); 12584 } 12585 let referenceElement = this._element; 12586 if (this._config.reference === "parent") { 12587 referenceElement = this._parent; 12588 } else if (isElement2(this._config.reference)) { 12589 referenceElement = getElement(this._config.reference); 12590 } else if (typeof this._config.reference === "object") { 12591 referenceElement = this._config.reference; 12592 } 12593 const popperConfig = this._getPopperConfig(); 12594 this._popper = createPopper3(referenceElement, this._menu, popperConfig); 12595 } 12596 _isShown() { 12597 return this._menu.classList.contains(CLASS_NAME_SHOW$6); 12598 } 12599 _getPlacement() { 12600 const parentDropdown = this._parent; 12601 if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) { 12602 return PLACEMENT_RIGHT; 12603 } 12604 if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) { 12605 return PLACEMENT_LEFT; 12606 } 12607 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) { 12608 return PLACEMENT_TOPCENTER; 12609 } 12610 if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) { 12611 return PLACEMENT_BOTTOMCENTER; 12612 } 12613 const isEnd = getComputedStyle(this._menu).getPropertyValue("--bs-position").trim() === "end"; 12614 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) { 12615 return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP; 12616 } 12617 return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM; 12618 } 12619 _detectNavbar() { 12620 return this._element.closest(SELECTOR_NAVBAR) !== null; 12621 } 12622 _getOffset() { 12623 const { 12624 offset: offset2 12625 } = this._config; 12626 if (typeof offset2 === "string") { 12627 return offset2.split(",").map((value) => Number.parseInt(value, 10)); 12628 } 12629 if (typeof offset2 === "function") { 12630 return (popperData) => offset2(popperData, this._element); 12631 } 12632 return offset2; 12633 } 12634 _getPopperConfig() { 12635 const defaultBsPopperConfig = { 12636 placement: this._getPlacement(), 12637 modifiers: [{ 12638 name: "preventOverflow", 12639 options: { 12640 boundary: this._config.boundary 12641 } 12642 }, { 12643 name: "offset", 12644 options: { 12645 offset: this._getOffset() 12646 } 12647 }] 12648 }; 12649 if (this._inNavbar || this._config.display === "static") { 12650 Manipulator.setDataAttribute(this._menu, "popper", "static"); 12651 defaultBsPopperConfig.modifiers = [{ 12652 name: "applyStyles", 12653 enabled: false 12654 }]; 12655 } 12656 return { 12657 ...defaultBsPopperConfig, 12658 ...execute(this._config.popperConfig, [void 0, defaultBsPopperConfig]) 12659 }; 12660 } 12661 _selectMenuItem({ 12662 key, 12663 target 12664 }) { 12665 const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter((element) => isVisible(element)); 12666 if (!items.length) { 12667 return; 12668 } 12669 getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus(); 12670 } 12671 // Static 12672 static jQueryInterface(config) { 12673 return this.each(function() { 12674 const data = _Dropdown.getOrCreateInstance(this, config); 12675 if (typeof config !== "string") { 12676 return; 12677 } 12678 if (typeof data[config] === "undefined") { 12679 throw new TypeError(`No method named "${config}"`); 12680 } 12681 data[config](); 12682 }); 12683 } 12684 static clearMenus(event) { 12685 if (event.button === RIGHT_MOUSE_BUTTON || event.type === "keyup" && event.key !== TAB_KEY$1) { 12686 return; 12687 } 12688 const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN); 12689 for (const toggle of openToggles) { 12690 const context = _Dropdown.getInstance(toggle); 12691 if (!context || context._config.autoClose === false) { 12692 continue; 12693 } 12694 const composedPath = event.composedPath(); 12695 const isMenuTarget = composedPath.includes(context._menu); 12696 if (composedPath.includes(context._element) || context._config.autoClose === "inside" && !isMenuTarget || context._config.autoClose === "outside" && isMenuTarget) { 12697 continue; 12698 } 12699 if (context._menu.contains(event.target) && (event.type === "keyup" && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) { 12700 continue; 12701 } 12702 const relatedTarget = { 12703 relatedTarget: context._element 12704 }; 12705 if (event.type === "click") { 12706 relatedTarget.clickEvent = event; 12707 } 12708 context._completeHide(relatedTarget); 12709 } 12710 } 12711 static dataApiKeydownHandler(event) { 12712 const isInput = /input|textarea/i.test(event.target.tagName); 12713 const isEscapeEvent = event.key === ESCAPE_KEY$2; 12714 const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key); 12715 if (!isUpOrDownEvent && !isEscapeEvent) { 12716 return; 12717 } 12718 if (isInput && !isEscapeEvent) { 12719 return; 12720 } 12721 event.preventDefault(); 12722 const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE$3, event.delegateTarget.parentNode); 12723 const instance = _Dropdown.getOrCreateInstance(getToggleButton); 12724 if (isUpOrDownEvent) { 12725 event.stopPropagation(); 12726 instance.show(); 12727 instance._selectMenuItem(event); 12728 return; 12729 } 12730 if (instance._isShown()) { 12731 event.stopPropagation(); 12732 instance.hide(); 12733 getToggleButton.focus(); 12734 } 12735 } 12736 }; 12737 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler); 12738 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler); 12739 EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus); 12740 EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus); 12741 EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function(event) { 12742 event.preventDefault(); 12743 Dropdown.getOrCreateInstance(this).toggle(); 12744 }); 12745 defineJQueryPlugin(Dropdown); 12746 var NAME$9 = "backdrop"; 12747 var CLASS_NAME_FADE$4 = "fade"; 12748 var CLASS_NAME_SHOW$5 = "show"; 12749 var EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`; 12750 var Default$8 = { 12751 className: "modal-backdrop", 12752 clickCallback: null, 12753 isAnimated: false, 12754 isVisible: true, 12755 // if false, we use the backdrop helper without adding any element to the dom 12756 rootElement: "body" 12757 // give the choice to place backdrop under different elements 12758 }; 12759 var DefaultType$8 = { 12760 className: "string", 12761 clickCallback: "(function|null)", 12762 isAnimated: "boolean", 12763 isVisible: "boolean", 12764 rootElement: "(element|string)" 12765 }; 12766 var Backdrop = class extends Config { 12767 constructor(config) { 12768 super(); 12769 this._config = this._getConfig(config); 12770 this._isAppended = false; 12771 this._element = null; 12772 } 12773 // Getters 12774 static get Default() { 12775 return Default$8; 12776 } 12777 static get DefaultType() { 12778 return DefaultType$8; 12779 } 12780 static get NAME() { 12781 return NAME$9; 12782 } 12783 // Public 12784 show(callback) { 12785 if (!this._config.isVisible) { 12786 execute(callback); 12787 return; 12788 } 12789 this._append(); 12790 const element = this._getElement(); 12791 if (this._config.isAnimated) { 12792 reflow(element); 12793 } 12794 element.classList.add(CLASS_NAME_SHOW$5); 12795 this._emulateAnimation(() => { 12796 execute(callback); 12797 }); 12798 } 12799 hide(callback) { 12800 if (!this._config.isVisible) { 12801 execute(callback); 12802 return; 12803 } 12804 this._getElement().classList.remove(CLASS_NAME_SHOW$5); 12805 this._emulateAnimation(() => { 12806 this.dispose(); 12807 execute(callback); 12808 }); 12809 } 12810 dispose() { 12811 if (!this._isAppended) { 12812 return; 12813 } 12814 EventHandler.off(this._element, EVENT_MOUSEDOWN); 12815 this._element.remove(); 12816 this._isAppended = false; 12817 } 12818 // Private 12819 _getElement() { 12820 if (!this._element) { 12821 const backdrop = document.createElement("div"); 12822 backdrop.className = this._config.className; 12823 if (this._config.isAnimated) { 12824 backdrop.classList.add(CLASS_NAME_FADE$4); 12825 } 12826 this._element = backdrop; 12827 } 12828 return this._element; 12829 } 12830 _configAfterMerge(config) { 12831 config.rootElement = getElement(config.rootElement); 12832 return config; 12833 } 12834 _append() { 12835 if (this._isAppended) { 12836 return; 12837 } 12838 const element = this._getElement(); 12839 this._config.rootElement.append(element); 12840 EventHandler.on(element, EVENT_MOUSEDOWN, () => { 12841 execute(this._config.clickCallback); 12842 }); 12843 this._isAppended = true; 12844 } 12845 _emulateAnimation(callback) { 12846 executeAfterTransition(callback, this._getElement(), this._config.isAnimated); 12847 } 12848 }; 12849 var NAME$8 = "focustrap"; 12850 var DATA_KEY$5 = "bs.focustrap"; 12851 var EVENT_KEY$5 = `.${DATA_KEY$5}`; 12852 var EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`; 12853 var EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`; 12854 var TAB_KEY = "Tab"; 12855 var TAB_NAV_FORWARD = "forward"; 12856 var TAB_NAV_BACKWARD = "backward"; 12857 var Default$7 = { 12858 autofocus: true, 12859 trapElement: null 12860 // The element to trap focus inside of 12861 }; 12862 var DefaultType$7 = { 12863 autofocus: "boolean", 12864 trapElement: "element" 12865 }; 12866 var FocusTrap = class extends Config { 12867 constructor(config) { 12868 super(); 12869 this._config = this._getConfig(config); 12870 this._isActive = false; 12871 this._lastTabNavDirection = null; 12872 } 12873 // Getters 12874 static get Default() { 12875 return Default$7; 12876 } 12877 static get DefaultType() { 12878 return DefaultType$7; 12879 } 12880 static get NAME() { 12881 return NAME$8; 12882 } 12883 // Public 12884 activate() { 12885 if (this._isActive) { 12886 return; 12887 } 12888 if (this._config.autofocus) { 12889 this._config.trapElement.focus(); 12890 } 12891 EventHandler.off(document, EVENT_KEY$5); 12892 EventHandler.on(document, EVENT_FOCUSIN$2, (event) => this._handleFocusin(event)); 12893 EventHandler.on(document, EVENT_KEYDOWN_TAB, (event) => this._handleKeydown(event)); 12894 this._isActive = true; 12895 } 12896 deactivate() { 12897 if (!this._isActive) { 12898 return; 12899 } 12900 this._isActive = false; 12901 EventHandler.off(document, EVENT_KEY$5); 12902 } 12903 // Private 12904 _handleFocusin(event) { 12905 const { 12906 trapElement 12907 } = this._config; 12908 if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) { 12909 return; 12910 } 12911 const elements = SelectorEngine.focusableChildren(trapElement); 12912 if (elements.length === 0) { 12913 trapElement.focus(); 12914 } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) { 12915 elements[elements.length - 1].focus(); 12916 } else { 12917 elements[0].focus(); 12918 } 12919 } 12920 _handleKeydown(event) { 12921 if (event.key !== TAB_KEY) { 12922 return; 12923 } 12924 this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD; 12925 } 12926 }; 12927 var SELECTOR_FIXED_CONTENT = ".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"; 12928 var SELECTOR_STICKY_CONTENT = ".sticky-top"; 12929 var PROPERTY_PADDING = "padding-right"; 12930 var PROPERTY_MARGIN = "margin-right"; 12931 var ScrollBarHelper = class { 12932 constructor() { 12933 this._element = document.body; 12934 } 12935 // Public 12936 getWidth() { 12937 const documentWidth = document.documentElement.clientWidth; 12938 return Math.abs(window.innerWidth - documentWidth); 12939 } 12940 hide() { 12941 const width = this.getWidth(); 12942 this._disableOverFlow(); 12943 this._setElementAttributes(this._element, PROPERTY_PADDING, (calculatedValue) => calculatedValue + width); 12944 this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, (calculatedValue) => calculatedValue + width); 12945 this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, (calculatedValue) => calculatedValue - width); 12946 } 12947 reset() { 12948 this._resetElementAttributes(this._element, "overflow"); 12949 this._resetElementAttributes(this._element, PROPERTY_PADDING); 12950 this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING); 12951 this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN); 12952 } 12953 isOverflowing() { 12954 return this.getWidth() > 0; 12955 } 12956 // Private 12957 _disableOverFlow() { 12958 this._saveInitialAttribute(this._element, "overflow"); 12959 this._element.style.overflow = "hidden"; 12960 } 12961 _setElementAttributes(selector, styleProperty, callback) { 12962 const scrollbarWidth = this.getWidth(); 12963 const manipulationCallBack = (element) => { 12964 if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) { 12965 return; 12966 } 12967 this._saveInitialAttribute(element, styleProperty); 12968 const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty); 12969 element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`); 12970 }; 12971 this._applyManipulationCallback(selector, manipulationCallBack); 12972 } 12973 _saveInitialAttribute(element, styleProperty) { 12974 const actualValue = element.style.getPropertyValue(styleProperty); 12975 if (actualValue) { 12976 Manipulator.setDataAttribute(element, styleProperty, actualValue); 12977 } 12978 } 12979 _resetElementAttributes(selector, styleProperty) { 12980 const manipulationCallBack = (element) => { 12981 const value = Manipulator.getDataAttribute(element, styleProperty); 12982 if (value === null) { 12983 element.style.removeProperty(styleProperty); 12984 return; 12985 } 12986 Manipulator.removeDataAttribute(element, styleProperty); 12987 element.style.setProperty(styleProperty, value); 12988 }; 12989 this._applyManipulationCallback(selector, manipulationCallBack); 12990 } 12991 _applyManipulationCallback(selector, callBack) { 12992 if (isElement2(selector)) { 12993 callBack(selector); 12994 return; 12995 } 12996 for (const sel of SelectorEngine.find(selector, this._element)) { 12997 callBack(sel); 12998 } 12999 } 13000 }; 13001 var NAME$7 = "modal"; 13002 var DATA_KEY$4 = "bs.modal"; 13003 var EVENT_KEY$4 = `.${DATA_KEY$4}`; 13004 var DATA_API_KEY$2 = ".data-api"; 13005 var ESCAPE_KEY$1 = "Escape"; 13006 var EVENT_HIDE$4 = `hide${EVENT_KEY$4}`; 13007 var EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`; 13008 var EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`; 13009 var EVENT_SHOW$4 = `show${EVENT_KEY$4}`; 13010 var EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`; 13011 var EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`; 13012 var EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`; 13013 var EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`; 13014 var EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`; 13015 var EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`; 13016 var CLASS_NAME_OPEN = "modal-open"; 13017 var CLASS_NAME_FADE$3 = "fade"; 13018 var CLASS_NAME_SHOW$4 = "show"; 13019 var CLASS_NAME_STATIC = "modal-static"; 13020 var OPEN_SELECTOR$1 = ".modal.show"; 13021 var SELECTOR_DIALOG = ".modal-dialog"; 13022 var SELECTOR_MODAL_BODY = ".modal-body"; 13023 var SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle="modal"]'; 13024 var Default$6 = { 13025 backdrop: true, 13026 focus: true, 13027 keyboard: true 13028 }; 13029 var DefaultType$6 = { 13030 backdrop: "(boolean|string)", 13031 focus: "boolean", 13032 keyboard: "boolean" 13033 }; 13034 var Modal = class _Modal extends BaseComponent { 13035 constructor(element, config) { 13036 super(element, config); 13037 this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element); 13038 this._backdrop = this._initializeBackDrop(); 13039 this._focustrap = this._initializeFocusTrap(); 13040 this._isShown = false; 13041 this._isTransitioning = false; 13042 this._scrollBar = new ScrollBarHelper(); 13043 this._addEventListeners(); 13044 } 13045 // Getters 13046 static get Default() { 13047 return Default$6; 13048 } 13049 static get DefaultType() { 13050 return DefaultType$6; 13051 } 13052 static get NAME() { 13053 return NAME$7; 13054 } 13055 // Public 13056 toggle(relatedTarget) { 13057 return this._isShown ? this.hide() : this.show(relatedTarget); 13058 } 13059 show(relatedTarget) { 13060 if (this._isShown || this._isTransitioning) { 13061 return; 13062 } 13063 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, { 13064 relatedTarget 13065 }); 13066 if (showEvent.defaultPrevented) { 13067 return; 13068 } 13069 this._isShown = true; 13070 this._isTransitioning = true; 13071 this._scrollBar.hide(); 13072 document.body.classList.add(CLASS_NAME_OPEN); 13073 this._adjustDialog(); 13074 this._backdrop.show(() => this._showElement(relatedTarget)); 13075 } 13076 hide() { 13077 if (!this._isShown || this._isTransitioning) { 13078 return; 13079 } 13080 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4); 13081 if (hideEvent.defaultPrevented) { 13082 return; 13083 } 13084 this._isShown = false; 13085 this._isTransitioning = true; 13086 this._focustrap.deactivate(); 13087 this._element.classList.remove(CLASS_NAME_SHOW$4); 13088 this._queueCallback(() => this._hideModal(), this._element, this._isAnimated()); 13089 } 13090 dispose() { 13091 EventHandler.off(window, EVENT_KEY$4); 13092 EventHandler.off(this._dialog, EVENT_KEY$4); 13093 this._backdrop.dispose(); 13094 this._focustrap.deactivate(); 13095 super.dispose(); 13096 } 13097 handleUpdate() { 13098 this._adjustDialog(); 13099 } 13100 // Private 13101 _initializeBackDrop() { 13102 return new Backdrop({ 13103 isVisible: Boolean(this._config.backdrop), 13104 // 'static' option will be translated to true, and booleans will keep their value, 13105 isAnimated: this._isAnimated() 13106 }); 13107 } 13108 _initializeFocusTrap() { 13109 return new FocusTrap({ 13110 trapElement: this._element 13111 }); 13112 } 13113 _showElement(relatedTarget) { 13114 if (!document.body.contains(this._element)) { 13115 document.body.append(this._element); 13116 } 13117 this._element.style.display = "block"; 13118 this._element.removeAttribute("aria-hidden"); 13119 this._element.setAttribute("aria-modal", true); 13120 this._element.setAttribute("role", "dialog"); 13121 this._element.scrollTop = 0; 13122 const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog); 13123 if (modalBody) { 13124 modalBody.scrollTop = 0; 13125 } 13126 reflow(this._element); 13127 this._element.classList.add(CLASS_NAME_SHOW$4); 13128 const transitionComplete = () => { 13129 if (this._config.focus) { 13130 this._focustrap.activate(); 13131 } 13132 this._isTransitioning = false; 13133 EventHandler.trigger(this._element, EVENT_SHOWN$4, { 13134 relatedTarget 13135 }); 13136 }; 13137 this._queueCallback(transitionComplete, this._dialog, this._isAnimated()); 13138 } 13139 _addEventListeners() { 13140 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, (event) => { 13141 if (event.key !== ESCAPE_KEY$1) { 13142 return; 13143 } 13144 if (this._config.keyboard) { 13145 this.hide(); 13146 return; 13147 } 13148 this._triggerBackdropTransition(); 13149 }); 13150 EventHandler.on(window, EVENT_RESIZE$1, () => { 13151 if (this._isShown && !this._isTransitioning) { 13152 this._adjustDialog(); 13153 } 13154 }); 13155 EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, (event) => { 13156 EventHandler.one(this._element, EVENT_CLICK_DISMISS, (event2) => { 13157 if (this._element !== event.target || this._element !== event2.target) { 13158 return; 13159 } 13160 if (this._config.backdrop === "static") { 13161 this._triggerBackdropTransition(); 13162 return; 13163 } 13164 if (this._config.backdrop) { 13165 this.hide(); 13166 } 13167 }); 13168 }); 13169 } 13170 _hideModal() { 13171 this._element.style.display = "none"; 13172 this._element.setAttribute("aria-hidden", true); 13173 this._element.removeAttribute("aria-modal"); 13174 this._element.removeAttribute("role"); 13175 this._isTransitioning = false; 13176 this._backdrop.hide(() => { 13177 document.body.classList.remove(CLASS_NAME_OPEN); 13178 this._resetAdjustments(); 13179 this._scrollBar.reset(); 13180 EventHandler.trigger(this._element, EVENT_HIDDEN$4); 13181 }); 13182 } 13183 _isAnimated() { 13184 return this._element.classList.contains(CLASS_NAME_FADE$3); 13185 } 13186 _triggerBackdropTransition() { 13187 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1); 13188 if (hideEvent.defaultPrevented) { 13189 return; 13190 } 13191 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 13192 const initialOverflowY = this._element.style.overflowY; 13193 if (initialOverflowY === "hidden" || this._element.classList.contains(CLASS_NAME_STATIC)) { 13194 return; 13195 } 13196 if (!isModalOverflowing) { 13197 this._element.style.overflowY = "hidden"; 13198 } 13199 this._element.classList.add(CLASS_NAME_STATIC); 13200 this._queueCallback(() => { 13201 this._element.classList.remove(CLASS_NAME_STATIC); 13202 this._queueCallback(() => { 13203 this._element.style.overflowY = initialOverflowY; 13204 }, this._dialog); 13205 }, this._dialog); 13206 this._element.focus(); 13207 } 13208 /** 13209 * The following methods are used to handle overflowing modals 13210 */ 13211 _adjustDialog() { 13212 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 13213 const scrollbarWidth = this._scrollBar.getWidth(); 13214 const isBodyOverflowing = scrollbarWidth > 0; 13215 if (isBodyOverflowing && !isModalOverflowing) { 13216 const property = isRTL() ? "paddingLeft" : "paddingRight"; 13217 this._element.style[property] = `${scrollbarWidth}px`; 13218 } 13219 if (!isBodyOverflowing && isModalOverflowing) { 13220 const property = isRTL() ? "paddingRight" : "paddingLeft"; 13221 this._element.style[property] = `${scrollbarWidth}px`; 13222 } 13223 } 13224 _resetAdjustments() { 13225 this._element.style.paddingLeft = ""; 13226 this._element.style.paddingRight = ""; 13227 } 13228 // Static 13229 static jQueryInterface(config, relatedTarget) { 13230 return this.each(function() { 13231 const data = _Modal.getOrCreateInstance(this, config); 13232 if (typeof config !== "string") { 13233 return; 13234 } 13235 if (typeof data[config] === "undefined") { 13236 throw new TypeError(`No method named "${config}"`); 13237 } 13238 data[config](relatedTarget); 13239 }); 13240 } 13241 }; 13242 EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function(event) { 13243 const target = SelectorEngine.getElementFromSelector(this); 13244 if (["A", "AREA"].includes(this.tagName)) { 13245 event.preventDefault(); 13246 } 13247 EventHandler.one(target, EVENT_SHOW$4, (showEvent) => { 13248 if (showEvent.defaultPrevented) { 13249 return; 13250 } 13251 EventHandler.one(target, EVENT_HIDDEN$4, () => { 13252 if (isVisible(this)) { 13253 this.focus(); 13254 } 13255 }); 13256 }); 13257 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1); 13258 if (alreadyOpen) { 13259 Modal.getInstance(alreadyOpen).hide(); 13260 } 13261 const data = Modal.getOrCreateInstance(target); 13262 data.toggle(this); 13263 }); 13264 enableDismissTrigger(Modal); 13265 defineJQueryPlugin(Modal); 13266 var NAME$6 = "offcanvas"; 13267 var DATA_KEY$3 = "bs.offcanvas"; 13268 var EVENT_KEY$3 = `.${DATA_KEY$3}`; 13269 var DATA_API_KEY$1 = ".data-api"; 13270 var EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`; 13271 var ESCAPE_KEY = "Escape"; 13272 var CLASS_NAME_SHOW$3 = "show"; 13273 var CLASS_NAME_SHOWING$1 = "showing"; 13274 var CLASS_NAME_HIDING = "hiding"; 13275 var CLASS_NAME_BACKDROP = "offcanvas-backdrop"; 13276 var OPEN_SELECTOR = ".offcanvas.show"; 13277 var EVENT_SHOW$3 = `show${EVENT_KEY$3}`; 13278 var EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`; 13279 var EVENT_HIDE$3 = `hide${EVENT_KEY$3}`; 13280 var EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`; 13281 var EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`; 13282 var EVENT_RESIZE = `resize${EVENT_KEY$3}`; 13283 var EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`; 13284 var EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`; 13285 var SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle="offcanvas"]'; 13286 var Default$5 = { 13287 backdrop: true, 13288 keyboard: true, 13289 scroll: false 13290 }; 13291 var DefaultType$5 = { 13292 backdrop: "(boolean|string)", 13293 keyboard: "boolean", 13294 scroll: "boolean" 13295 }; 13296 var Offcanvas = class _Offcanvas extends BaseComponent { 13297 constructor(element, config) { 13298 super(element, config); 13299 this._isShown = false; 13300 this._backdrop = this._initializeBackDrop(); 13301 this._focustrap = this._initializeFocusTrap(); 13302 this._addEventListeners(); 13303 } 13304 // Getters 13305 static get Default() { 13306 return Default$5; 13307 } 13308 static get DefaultType() { 13309 return DefaultType$5; 13310 } 13311 static get NAME() { 13312 return NAME$6; 13313 } 13314 // Public 13315 toggle(relatedTarget) { 13316 return this._isShown ? this.hide() : this.show(relatedTarget); 13317 } 13318 show(relatedTarget) { 13319 if (this._isShown) { 13320 return; 13321 } 13322 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, { 13323 relatedTarget 13324 }); 13325 if (showEvent.defaultPrevented) { 13326 return; 13327 } 13328 this._isShown = true; 13329 this._backdrop.show(); 13330 if (!this._config.scroll) { 13331 new ScrollBarHelper().hide(); 13332 } 13333 this._element.setAttribute("aria-modal", true); 13334 this._element.setAttribute("role", "dialog"); 13335 this._element.classList.add(CLASS_NAME_SHOWING$1); 13336 const completeCallBack = () => { 13337 if (!this._config.scroll || this._config.backdrop) { 13338 this._focustrap.activate(); 13339 } 13340 this._element.classList.add(CLASS_NAME_SHOW$3); 13341 this._element.classList.remove(CLASS_NAME_SHOWING$1); 13342 EventHandler.trigger(this._element, EVENT_SHOWN$3, { 13343 relatedTarget 13344 }); 13345 }; 13346 this._queueCallback(completeCallBack, this._element, true); 13347 } 13348 hide() { 13349 if (!this._isShown) { 13350 return; 13351 } 13352 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3); 13353 if (hideEvent.defaultPrevented) { 13354 return; 13355 } 13356 this._focustrap.deactivate(); 13357 this._element.blur(); 13358 this._isShown = false; 13359 this._element.classList.add(CLASS_NAME_HIDING); 13360 this._backdrop.hide(); 13361 const completeCallback = () => { 13362 this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING); 13363 this._element.removeAttribute("aria-modal"); 13364 this._element.removeAttribute("role"); 13365 if (!this._config.scroll) { 13366 new ScrollBarHelper().reset(); 13367 } 13368 EventHandler.trigger(this._element, EVENT_HIDDEN$3); 13369 }; 13370 this._queueCallback(completeCallback, this._element, true); 13371 } 13372 dispose() { 13373 this._backdrop.dispose(); 13374 this._focustrap.deactivate(); 13375 super.dispose(); 13376 } 13377 // Private 13378 _initializeBackDrop() { 13379 const clickCallback = () => { 13380 if (this._config.backdrop === "static") { 13381 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); 13382 return; 13383 } 13384 this.hide(); 13385 }; 13386 const isVisible2 = Boolean(this._config.backdrop); 13387 return new Backdrop({ 13388 className: CLASS_NAME_BACKDROP, 13389 isVisible: isVisible2, 13390 isAnimated: true, 13391 rootElement: this._element.parentNode, 13392 clickCallback: isVisible2 ? clickCallback : null 13393 }); 13394 } 13395 _initializeFocusTrap() { 13396 return new FocusTrap({ 13397 trapElement: this._element 13398 }); 13399 } 13400 _addEventListeners() { 13401 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, (event) => { 13402 if (event.key !== ESCAPE_KEY) { 13403 return; 13404 } 13405 if (this._config.keyboard) { 13406 this.hide(); 13407 return; 13408 } 13409 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); 13410 }); 13411 } 13412 // Static 13413 static jQueryInterface(config) { 13414 return this.each(function() { 13415 const data = _Offcanvas.getOrCreateInstance(this, config); 13416 if (typeof config !== "string") { 13417 return; 13418 } 13419 if (data[config] === void 0 || config.startsWith("_") || config === "constructor") { 13420 throw new TypeError(`No method named "${config}"`); 13421 } 13422 data[config](this); 13423 }); 13424 } 13425 }; 13426 EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function(event) { 13427 const target = SelectorEngine.getElementFromSelector(this); 13428 if (["A", "AREA"].includes(this.tagName)) { 13429 event.preventDefault(); 13430 } 13431 if (isDisabled(this)) { 13432 return; 13433 } 13434 EventHandler.one(target, EVENT_HIDDEN$3, () => { 13435 if (isVisible(this)) { 13436 this.focus(); 13437 } 13438 }); 13439 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR); 13440 if (alreadyOpen && alreadyOpen !== target) { 13441 Offcanvas.getInstance(alreadyOpen).hide(); 13442 } 13443 const data = Offcanvas.getOrCreateInstance(target); 13444 data.toggle(this); 13445 }); 13446 EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => { 13447 for (const selector of SelectorEngine.find(OPEN_SELECTOR)) { 13448 Offcanvas.getOrCreateInstance(selector).show(); 13449 } 13450 }); 13451 EventHandler.on(window, EVENT_RESIZE, () => { 13452 for (const element of SelectorEngine.find("[aria-modal][class*=show][class*=offcanvas-]")) { 13453 if (getComputedStyle(element).position !== "fixed") { 13454 Offcanvas.getOrCreateInstance(element).hide(); 13455 } 13456 } 13457 }); 13458 enableDismissTrigger(Offcanvas); 13459 defineJQueryPlugin(Offcanvas); 13460 var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; 13461 var DefaultAllowlist = { 13462 // Global attributes allowed on any supplied element below. 13463 "*": ["class", "dir", "id", "lang", "role", ARIA_ATTRIBUTE_PATTERN], 13464 a: ["target", "href", "title", "rel"], 13465 area: [], 13466 b: [], 13467 br: [], 13468 col: [], 13469 code: [], 13470 dd: [], 13471 div: [], 13472 dl: [], 13473 dt: [], 13474 em: [], 13475 hr: [], 13476 h1: [], 13477 h2: [], 13478 h3: [], 13479 h4: [], 13480 h5: [], 13481 h6: [], 13482 i: [], 13483 img: ["src", "srcset", "alt", "title", "width", "height"], 13484 li: [], 13485 ol: [], 13486 p: [], 13487 pre: [], 13488 s: [], 13489 small: [], 13490 span: [], 13491 sub: [], 13492 sup: [], 13493 strong: [], 13494 u: [], 13495 ul: [] 13496 }; 13497 var uriAttributes = /* @__PURE__ */ new Set(["background", "cite", "href", "itemtype", "longdesc", "poster", "src", "xlink:href"]); 13498 var SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i; 13499 var allowedAttribute = (attribute, allowedAttributeList) => { 13500 const attributeName = attribute.nodeName.toLowerCase(); 13501 if (allowedAttributeList.includes(attributeName)) { 13502 if (uriAttributes.has(attributeName)) { 13503 return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue)); 13504 } 13505 return true; 13506 } 13507 return allowedAttributeList.filter((attributeRegex) => attributeRegex instanceof RegExp).some((regex) => regex.test(attributeName)); 13508 }; 13509 function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) { 13510 if (!unsafeHtml.length) { 13511 return unsafeHtml; 13512 } 13513 if (sanitizeFunction && typeof sanitizeFunction === "function") { 13514 return sanitizeFunction(unsafeHtml); 13515 } 13516 const domParser = new window.DOMParser(); 13517 const createdDocument = domParser.parseFromString(unsafeHtml, "text/html"); 13518 const elements = [].concat(...createdDocument.body.querySelectorAll("*")); 13519 for (const element of elements) { 13520 const elementName = element.nodeName.toLowerCase(); 13521 if (!Object.keys(allowList).includes(elementName)) { 13522 element.remove(); 13523 continue; 13524 } 13525 const attributeList = [].concat(...element.attributes); 13526 const allowedAttributes = [].concat(allowList["*"] || [], allowList[elementName] || []); 13527 for (const attribute of attributeList) { 13528 if (!allowedAttribute(attribute, allowedAttributes)) { 13529 element.removeAttribute(attribute.nodeName); 13530 } 13531 } 13532 } 13533 return createdDocument.body.innerHTML; 13534 } 13535 var NAME$5 = "TemplateFactory"; 13536 var Default$4 = { 13537 allowList: DefaultAllowlist, 13538 content: {}, 13539 // { selector : text , selector2 : text2 , } 13540 extraClass: "", 13541 html: false, 13542 sanitize: true, 13543 sanitizeFn: null, 13544 template: "<div></div>" 13545 }; 13546 var DefaultType$4 = { 13547 allowList: "object", 13548 content: "object", 13549 extraClass: "(string|function)", 13550 html: "boolean", 13551 sanitize: "boolean", 13552 sanitizeFn: "(null|function)", 13553 template: "string" 13554 }; 13555 var DefaultContentType = { 13556 entry: "(string|element|function|null)", 13557 selector: "(string|element)" 13558 }; 13559 var TemplateFactory = class extends Config { 13560 constructor(config) { 13561 super(); 13562 this._config = this._getConfig(config); 13563 } 13564 // Getters 13565 static get Default() { 13566 return Default$4; 13567 } 13568 static get DefaultType() { 13569 return DefaultType$4; 13570 } 13571 static get NAME() { 13572 return NAME$5; 13573 } 13574 // Public 13575 getContent() { 13576 return Object.values(this._config.content).map((config) => this._resolvePossibleFunction(config)).filter(Boolean); 13577 } 13578 hasContent() { 13579 return this.getContent().length > 0; 13580 } 13581 changeContent(content) { 13582 this._checkContent(content); 13583 this._config.content = { 13584 ...this._config.content, 13585 ...content 13586 }; 13587 return this; 13588 } 13589 toHtml() { 13590 const templateWrapper = document.createElement("div"); 13591 templateWrapper.innerHTML = this._maybeSanitize(this._config.template); 13592 for (const [selector, text] of Object.entries(this._config.content)) { 13593 this._setContent(templateWrapper, text, selector); 13594 } 13595 const template = templateWrapper.children[0]; 13596 const extraClass = this._resolvePossibleFunction(this._config.extraClass); 13597 if (extraClass) { 13598 template.classList.add(...extraClass.split(" ")); 13599 } 13600 return template; 13601 } 13602 // Private 13603 _typeCheckConfig(config) { 13604 super._typeCheckConfig(config); 13605 this._checkContent(config.content); 13606 } 13607 _checkContent(arg) { 13608 for (const [selector, content] of Object.entries(arg)) { 13609 super._typeCheckConfig({ 13610 selector, 13611 entry: content 13612 }, DefaultContentType); 13613 } 13614 } 13615 _setContent(template, content, selector) { 13616 const templateElement = SelectorEngine.findOne(selector, template); 13617 if (!templateElement) { 13618 return; 13619 } 13620 content = this._resolvePossibleFunction(content); 13621 if (!content) { 13622 templateElement.remove(); 13623 return; 13624 } 13625 if (isElement2(content)) { 13626 this._putElementInTemplate(getElement(content), templateElement); 13627 return; 13628 } 13629 if (this._config.html) { 13630 templateElement.innerHTML = this._maybeSanitize(content); 13631 return; 13632 } 13633 templateElement.textContent = content; 13634 } 13635 _maybeSanitize(arg) { 13636 return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg; 13637 } 13638 _resolvePossibleFunction(arg) { 13639 return execute(arg, [void 0, this]); 13640 } 13641 _putElementInTemplate(element, templateElement) { 13642 if (this._config.html) { 13643 templateElement.innerHTML = ""; 13644 templateElement.append(element); 13645 return; 13646 } 13647 templateElement.textContent = element.textContent; 13648 } 13649 }; 13650 var NAME$4 = "tooltip"; 13651 var DISALLOWED_ATTRIBUTES = /* @__PURE__ */ new Set(["sanitize", "allowList", "sanitizeFn"]); 13652 var CLASS_NAME_FADE$2 = "fade"; 13653 var CLASS_NAME_MODAL = "modal"; 13654 var CLASS_NAME_SHOW$2 = "show"; 13655 var SELECTOR_TOOLTIP_INNER = ".tooltip-inner"; 13656 var SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`; 13657 var EVENT_MODAL_HIDE = "hide.bs.modal"; 13658 var TRIGGER_HOVER = "hover"; 13659 var TRIGGER_FOCUS = "focus"; 13660 var TRIGGER_CLICK = "click"; 13661 var TRIGGER_MANUAL = "manual"; 13662 var EVENT_HIDE$2 = "hide"; 13663 var EVENT_HIDDEN$2 = "hidden"; 13664 var EVENT_SHOW$2 = "show"; 13665 var EVENT_SHOWN$2 = "shown"; 13666 var EVENT_INSERTED = "inserted"; 13667 var EVENT_CLICK$1 = "click"; 13668 var EVENT_FOCUSIN$1 = "focusin"; 13669 var EVENT_FOCUSOUT$1 = "focusout"; 13670 var EVENT_MOUSEENTER = "mouseenter"; 13671 var EVENT_MOUSELEAVE = "mouseleave"; 13672 var AttachmentMap = { 13673 AUTO: "auto", 13674 TOP: "top", 13675 RIGHT: isRTL() ? "left" : "right", 13676 BOTTOM: "bottom", 13677 LEFT: isRTL() ? "right" : "left" 13678 }; 13679 var Default$3 = { 13680 allowList: DefaultAllowlist, 13681 animation: true, 13682 boundary: "clippingParents", 13683 container: false, 13684 customClass: "", 13685 delay: 0, 13686 fallbackPlacements: ["top", "right", "bottom", "left"], 13687 html: false, 13688 offset: [0, 6], 13689 placement: "top", 13690 popperConfig: null, 13691 sanitize: true, 13692 sanitizeFn: null, 13693 selector: false, 13694 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 13695 title: "", 13696 trigger: "hover focus" 13697 }; 13698 var DefaultType$3 = { 13699 allowList: "object", 13700 animation: "boolean", 13701 boundary: "(string|element)", 13702 container: "(string|element|boolean)", 13703 customClass: "(string|function)", 13704 delay: "(number|object)", 13705 fallbackPlacements: "array", 13706 html: "boolean", 13707 offset: "(array|string|function)", 13708 placement: "(string|function)", 13709 popperConfig: "(null|object|function)", 13710 sanitize: "boolean", 13711 sanitizeFn: "(null|function)", 13712 selector: "(string|boolean)", 13713 template: "string", 13714 title: "(string|element|function)", 13715 trigger: "string" 13716 }; 13717 var Tooltip = class _Tooltip extends BaseComponent { 13718 constructor(element, config) { 13719 if (typeof lib_exports === "undefined") { 13720 throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org/docs/v2/)"); 13721 } 13722 super(element, config); 13723 this._isEnabled = true; 13724 this._timeout = 0; 13725 this._isHovered = null; 13726 this._activeTrigger = {}; 13727 this._popper = null; 13728 this._templateFactory = null; 13729 this._newContent = null; 13730 this.tip = null; 13731 this._setListeners(); 13732 if (!this._config.selector) { 13733 this._fixTitle(); 13734 } 13735 } 13736 // Getters 13737 static get Default() { 13738 return Default$3; 13739 } 13740 static get DefaultType() { 13741 return DefaultType$3; 13742 } 13743 static get NAME() { 13744 return NAME$4; 13745 } 13746 // Public 13747 enable() { 13748 this._isEnabled = true; 13749 } 13750 disable() { 13751 this._isEnabled = false; 13752 } 13753 toggleEnabled() { 13754 this._isEnabled = !this._isEnabled; 13755 } 13756 toggle() { 13757 if (!this._isEnabled) { 13758 return; 13759 } 13760 if (this._isShown()) { 13761 this._leave(); 13762 return; 13763 } 13764 this._enter(); 13765 } 13766 dispose() { 13767 clearTimeout(this._timeout); 13768 EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler); 13769 if (this._element.getAttribute("data-bs-original-title")) { 13770 this._element.setAttribute("title", this._element.getAttribute("data-bs-original-title")); 13771 } 13772 this._disposePopper(); 13773 super.dispose(); 13774 } 13775 show() { 13776 if (this._element.style.display === "none") { 13777 throw new Error("Please use show on visible elements"); 13778 } 13779 if (!(this._isWithContent() && this._isEnabled)) { 13780 return; 13781 } 13782 const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2)); 13783 const shadowRoot = findShadowRoot(this._element); 13784 const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element); 13785 if (showEvent.defaultPrevented || !isInTheDom) { 13786 return; 13787 } 13788 this._disposePopper(); 13789 const tip = this._getTipElement(); 13790 this._element.setAttribute("aria-describedby", tip.getAttribute("id")); 13791 const { 13792 container 13793 } = this._config; 13794 if (!this._element.ownerDocument.documentElement.contains(this.tip)) { 13795 container.append(tip); 13796 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED)); 13797 } 13798 this._popper = this._createPopper(tip); 13799 tip.classList.add(CLASS_NAME_SHOW$2); 13800 if ("ontouchstart" in document.documentElement) { 13801 for (const element of [].concat(...document.body.children)) { 13802 EventHandler.on(element, "mouseover", noop); 13803 } 13804 } 13805 const complete = () => { 13806 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2)); 13807 if (this._isHovered === false) { 13808 this._leave(); 13809 } 13810 this._isHovered = false; 13811 }; 13812 this._queueCallback(complete, this.tip, this._isAnimated()); 13813 } 13814 hide() { 13815 if (!this._isShown()) { 13816 return; 13817 } 13818 const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2)); 13819 if (hideEvent.defaultPrevented) { 13820 return; 13821 } 13822 const tip = this._getTipElement(); 13823 tip.classList.remove(CLASS_NAME_SHOW$2); 13824 if ("ontouchstart" in document.documentElement) { 13825 for (const element of [].concat(...document.body.children)) { 13826 EventHandler.off(element, "mouseover", noop); 13827 } 13828 } 13829 this._activeTrigger[TRIGGER_CLICK] = false; 13830 this._activeTrigger[TRIGGER_FOCUS] = false; 13831 this._activeTrigger[TRIGGER_HOVER] = false; 13832 this._isHovered = null; 13833 const complete = () => { 13834 if (this._isWithActiveTrigger()) { 13835 return; 13836 } 13837 if (!this._isHovered) { 13838 this._disposePopper(); 13839 } 13840 this._element.removeAttribute("aria-describedby"); 13841 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2)); 13842 }; 13843 this._queueCallback(complete, this.tip, this._isAnimated()); 13844 } 13845 update() { 13846 if (this._popper) { 13847 this._popper.update(); 13848 } 13849 } 13850 // Protected 13851 _isWithContent() { 13852 return Boolean(this._getTitle()); 13853 } 13854 _getTipElement() { 13855 if (!this.tip) { 13856 this.tip = this._createTipElement(this._newContent || this._getContentForTemplate()); 13857 } 13858 return this.tip; 13859 } 13860 _createTipElement(content) { 13861 const tip = this._getTemplateFactory(content).toHtml(); 13862 if (!tip) { 13863 return null; 13864 } 13865 tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2); 13866 tip.classList.add(`bs-${this.constructor.NAME}-auto`); 13867 const tipId = getUID(this.constructor.NAME).toString(); 13868 tip.setAttribute("id", tipId); 13869 if (this._isAnimated()) { 13870 tip.classList.add(CLASS_NAME_FADE$2); 13871 } 13872 return tip; 13873 } 13874 setContent(content) { 13875 this._newContent = content; 13876 if (this._isShown()) { 13877 this._disposePopper(); 13878 this.show(); 13879 } 13880 } 13881 _getTemplateFactory(content) { 13882 if (this._templateFactory) { 13883 this._templateFactory.changeContent(content); 13884 } else { 13885 this._templateFactory = new TemplateFactory({ 13886 ...this._config, 13887 // the `content` var has to be after `this._config` 13888 // to override config.content in case of popover 13889 content, 13890 extraClass: this._resolvePossibleFunction(this._config.customClass) 13891 }); 13892 } 13893 return this._templateFactory; 13894 } 13895 _getContentForTemplate() { 13896 return { 13897 [SELECTOR_TOOLTIP_INNER]: this._getTitle() 13898 }; 13899 } 13900 _getTitle() { 13901 return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute("data-bs-original-title"); 13902 } 13903 // Private 13904 _initializeOnDelegatedTarget(event) { 13905 return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig()); 13906 } 13907 _isAnimated() { 13908 return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2); 13909 } 13910 _isShown() { 13911 return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2); 13912 } 13913 _createPopper(tip) { 13914 const placement = execute(this._config.placement, [this, tip, this._element]); 13915 const attachment = AttachmentMap[placement.toUpperCase()]; 13916 return createPopper3(this._element, tip, this._getPopperConfig(attachment)); 13917 } 13918 _getOffset() { 13919 const { 13920 offset: offset2 13921 } = this._config; 13922 if (typeof offset2 === "string") { 13923 return offset2.split(",").map((value) => Number.parseInt(value, 10)); 13924 } 13925 if (typeof offset2 === "function") { 13926 return (popperData) => offset2(popperData, this._element); 13927 } 13928 return offset2; 13929 } 13930 _resolvePossibleFunction(arg) { 13931 return execute(arg, [this._element, this._element]); 13932 } 13933 _getPopperConfig(attachment) { 13934 const defaultBsPopperConfig = { 13935 placement: attachment, 13936 modifiers: [{ 13937 name: "flip", 13938 options: { 13939 fallbackPlacements: this._config.fallbackPlacements 13940 } 13941 }, { 13942 name: "offset", 13943 options: { 13944 offset: this._getOffset() 13945 } 13946 }, { 13947 name: "preventOverflow", 13948 options: { 13949 boundary: this._config.boundary 13950 } 13951 }, { 13952 name: "arrow", 13953 options: { 13954 element: `.${this.constructor.NAME}-arrow` 13955 } 13956 }, { 13957 name: "preSetPlacement", 13958 enabled: true, 13959 phase: "beforeMain", 13960 fn: (data) => { 13961 this._getTipElement().setAttribute("data-popper-placement", data.state.placement); 13962 } 13963 }] 13964 }; 13965 return { 13966 ...defaultBsPopperConfig, 13967 ...execute(this._config.popperConfig, [void 0, defaultBsPopperConfig]) 13968 }; 13969 } 13970 _setListeners() { 13971 const triggers = this._config.trigger.split(" "); 13972 for (const trigger of triggers) { 13973 if (trigger === "click") { 13974 EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, (event) => { 13975 const context = this._initializeOnDelegatedTarget(event); 13976 context.toggle(); 13977 }); 13978 } else if (trigger !== TRIGGER_MANUAL) { 13979 const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1); 13980 const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1); 13981 EventHandler.on(this._element, eventIn, this._config.selector, (event) => { 13982 const context = this._initializeOnDelegatedTarget(event); 13983 context._activeTrigger[event.type === "focusin" ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; 13984 context._enter(); 13985 }); 13986 EventHandler.on(this._element, eventOut, this._config.selector, (event) => { 13987 const context = this._initializeOnDelegatedTarget(event); 13988 context._activeTrigger[event.type === "focusout" ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget); 13989 context._leave(); 13990 }); 13991 } 13992 } 13993 this._hideModalHandler = () => { 13994 if (this._element) { 13995 this.hide(); 13996 } 13997 }; 13998 EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler); 13999 } 14000 _fixTitle() { 14001 const title = this._element.getAttribute("title"); 14002 if (!title) { 14003 return; 14004 } 14005 if (!this._element.getAttribute("aria-label") && !this._element.textContent.trim()) { 14006 this._element.setAttribute("aria-label", title); 14007 } 14008 this._element.setAttribute("data-bs-original-title", title); 14009 this._element.removeAttribute("title"); 14010 } 14011 _enter() { 14012 if (this._isShown() || this._isHovered) { 14013 this._isHovered = true; 14014 return; 14015 } 14016 this._isHovered = true; 14017 this._setTimeout(() => { 14018 if (this._isHovered) { 14019 this.show(); 14020 } 14021 }, this._config.delay.show); 14022 } 14023 _leave() { 14024 if (this._isWithActiveTrigger()) { 14025 return; 14026 } 14027 this._isHovered = false; 14028 this._setTimeout(() => { 14029 if (!this._isHovered) { 14030 this.hide(); 14031 } 14032 }, this._config.delay.hide); 14033 } 14034 _setTimeout(handler, timeout) { 14035 clearTimeout(this._timeout); 14036 this._timeout = setTimeout(handler, timeout); 14037 } 14038 _isWithActiveTrigger() { 14039 return Object.values(this._activeTrigger).includes(true); 14040 } 14041 _getConfig(config) { 14042 const dataAttributes = Manipulator.getDataAttributes(this._element); 14043 for (const dataAttribute of Object.keys(dataAttributes)) { 14044 if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) { 14045 delete dataAttributes[dataAttribute]; 14046 } 14047 } 14048 config = { 14049 ...dataAttributes, 14050 ...typeof config === "object" && config ? config : {} 14051 }; 14052 config = this._mergeConfigObj(config); 14053 config = this._configAfterMerge(config); 14054 this._typeCheckConfig(config); 14055 return config; 14056 } 14057 _configAfterMerge(config) { 14058 config.container = config.container === false ? document.body : getElement(config.container); 14059 if (typeof config.delay === "number") { 14060 config.delay = { 14061 show: config.delay, 14062 hide: config.delay 14063 }; 14064 } 14065 if (typeof config.title === "number") { 14066 config.title = config.title.toString(); 14067 } 14068 if (typeof config.content === "number") { 14069 config.content = config.content.toString(); 14070 } 14071 return config; 14072 } 14073 _getDelegateConfig() { 14074 const config = {}; 14075 for (const [key, value] of Object.entries(this._config)) { 14076 if (this.constructor.Default[key] !== value) { 14077 config[key] = value; 14078 } 14079 } 14080 config.selector = false; 14081 config.trigger = "manual"; 14082 return config; 14083 } 14084 _disposePopper() { 14085 if (this._popper) { 14086 this._popper.destroy(); 14087 this._popper = null; 14088 } 14089 if (this.tip) { 14090 this.tip.remove(); 14091 this.tip = null; 14092 } 14093 } 14094 // Static 14095 static jQueryInterface(config) { 14096 return this.each(function() { 14097 const data = _Tooltip.getOrCreateInstance(this, config); 14098 if (typeof config !== "string") { 14099 return; 14100 } 14101 if (typeof data[config] === "undefined") { 14102 throw new TypeError(`No method named "${config}"`); 14103 } 14104 data[config](); 14105 }); 14106 } 14107 }; 14108 defineJQueryPlugin(Tooltip); 14109 var NAME$3 = "popover"; 14110 var SELECTOR_TITLE = ".popover-header"; 14111 var SELECTOR_CONTENT = ".popover-body"; 14112 var Default$2 = { 14113 ...Tooltip.Default, 14114 content: "", 14115 offset: [0, 8], 14116 placement: "right", 14117 template: '<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>', 14118 trigger: "click" 14119 }; 14120 var DefaultType$2 = { 14121 ...Tooltip.DefaultType, 14122 content: "(null|string|element|function)" 14123 }; 14124 var Popover = class _Popover extends Tooltip { 14125 // Getters 14126 static get Default() { 14127 return Default$2; 14128 } 14129 static get DefaultType() { 14130 return DefaultType$2; 14131 } 14132 static get NAME() { 14133 return NAME$3; 14134 } 14135 // Overrides 14136 _isWithContent() { 14137 return this._getTitle() || this._getContent(); 14138 } 14139 // Private 14140 _getContentForTemplate() { 14141 return { 14142 [SELECTOR_TITLE]: this._getTitle(), 14143 [SELECTOR_CONTENT]: this._getContent() 14144 }; 14145 } 14146 _getContent() { 14147 return this._resolvePossibleFunction(this._config.content); 14148 } 14149 // Static 14150 static jQueryInterface(config) { 14151 return this.each(function() { 14152 const data = _Popover.getOrCreateInstance(this, config); 14153 if (typeof config !== "string") { 14154 return; 14155 } 14156 if (typeof data[config] === "undefined") { 14157 throw new TypeError(`No method named "${config}"`); 14158 } 14159 data[config](); 14160 }); 14161 } 14162 }; 14163 defineJQueryPlugin(Popover); 14164 var NAME$2 = "scrollspy"; 14165 var DATA_KEY$2 = "bs.scrollspy"; 14166 var EVENT_KEY$2 = `.${DATA_KEY$2}`; 14167 var DATA_API_KEY = ".data-api"; 14168 var EVENT_ACTIVATE = `activate${EVENT_KEY$2}`; 14169 var EVENT_CLICK = `click${EVENT_KEY$2}`; 14170 var EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`; 14171 var CLASS_NAME_DROPDOWN_ITEM = "dropdown-item"; 14172 var CLASS_NAME_ACTIVE$1 = "active"; 14173 var SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]'; 14174 var SELECTOR_TARGET_LINKS = "[href]"; 14175 var SELECTOR_NAV_LIST_GROUP = ".nav, .list-group"; 14176 var SELECTOR_NAV_LINKS = ".nav-link"; 14177 var SELECTOR_NAV_ITEMS = ".nav-item"; 14178 var SELECTOR_LIST_ITEMS = ".list-group-item"; 14179 var SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`; 14180 var SELECTOR_DROPDOWN = ".dropdown"; 14181 var SELECTOR_DROPDOWN_TOGGLE$1 = ".dropdown-toggle"; 14182 var Default$1 = { 14183 offset: null, 14184 // TODO: v6 @deprecated, keep it for backwards compatibility reasons 14185 rootMargin: "0px 0px -25%", 14186 smoothScroll: false, 14187 target: null, 14188 threshold: [0.1, 0.5, 1] 14189 }; 14190 var DefaultType$1 = { 14191 offset: "(number|null)", 14192 // TODO v6 @deprecated, keep it for backwards compatibility reasons 14193 rootMargin: "string", 14194 smoothScroll: "boolean", 14195 target: "element", 14196 threshold: "array" 14197 }; 14198 var ScrollSpy = class _ScrollSpy extends BaseComponent { 14199 constructor(element, config) { 14200 super(element, config); 14201 this._targetLinks = /* @__PURE__ */ new Map(); 14202 this._observableSections = /* @__PURE__ */ new Map(); 14203 this._rootElement = getComputedStyle(this._element).overflowY === "visible" ? null : this._element; 14204 this._activeTarget = null; 14205 this._observer = null; 14206 this._previousScrollData = { 14207 visibleEntryTop: 0, 14208 parentScrollTop: 0 14209 }; 14210 this.refresh(); 14211 } 14212 // Getters 14213 static get Default() { 14214 return Default$1; 14215 } 14216 static get DefaultType() { 14217 return DefaultType$1; 14218 } 14219 static get NAME() { 14220 return NAME$2; 14221 } 14222 // Public 14223 refresh() { 14224 this._initializeTargetsAndObservables(); 14225 this._maybeEnableSmoothScroll(); 14226 if (this._observer) { 14227 this._observer.disconnect(); 14228 } else { 14229 this._observer = this._getNewObserver(); 14230 } 14231 for (const section of this._observableSections.values()) { 14232 this._observer.observe(section); 14233 } 14234 } 14235 dispose() { 14236 this._observer.disconnect(); 14237 super.dispose(); 14238 } 14239 // Private 14240 _configAfterMerge(config) { 14241 config.target = getElement(config.target) || document.body; 14242 config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin; 14243 if (typeof config.threshold === "string") { 14244 config.threshold = config.threshold.split(",").map((value) => Number.parseFloat(value)); 14245 } 14246 return config; 14247 } 14248 _maybeEnableSmoothScroll() { 14249 if (!this._config.smoothScroll) { 14250 return; 14251 } 14252 EventHandler.off(this._config.target, EVENT_CLICK); 14253 EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, (event) => { 14254 const observableSection = this._observableSections.get(event.target.hash); 14255 if (observableSection) { 14256 event.preventDefault(); 14257 const root = this._rootElement || window; 14258 const height = observableSection.offsetTop - this._element.offsetTop; 14259 if (root.scrollTo) { 14260 root.scrollTo({ 14261 top: height, 14262 behavior: "smooth" 14263 }); 14264 return; 14265 } 14266 root.scrollTop = height; 14267 } 14268 }); 14269 } 14270 _getNewObserver() { 14271 const options = { 14272 root: this._rootElement, 14273 threshold: this._config.threshold, 14274 rootMargin: this._config.rootMargin 14275 }; 14276 return new IntersectionObserver((entries) => this._observerCallback(entries), options); 14277 } 14278 // The logic of selection 14279 _observerCallback(entries) { 14280 const targetElement = (entry) => this._targetLinks.get(`#${entry.target.id}`); 14281 const activate = (entry) => { 14282 this._previousScrollData.visibleEntryTop = entry.target.offsetTop; 14283 this._process(targetElement(entry)); 14284 }; 14285 const parentScrollTop = (this._rootElement || document.documentElement).scrollTop; 14286 const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop; 14287 this._previousScrollData.parentScrollTop = parentScrollTop; 14288 for (const entry of entries) { 14289 if (!entry.isIntersecting) { 14290 this._activeTarget = null; 14291 this._clearActiveClass(targetElement(entry)); 14292 continue; 14293 } 14294 const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop; 14295 if (userScrollsDown && entryIsLowerThanPrevious) { 14296 activate(entry); 14297 if (!parentScrollTop) { 14298 return; 14299 } 14300 continue; 14301 } 14302 if (!userScrollsDown && !entryIsLowerThanPrevious) { 14303 activate(entry); 14304 } 14305 } 14306 } 14307 _initializeTargetsAndObservables() { 14308 this._targetLinks = /* @__PURE__ */ new Map(); 14309 this._observableSections = /* @__PURE__ */ new Map(); 14310 const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target); 14311 for (const anchor of targetLinks) { 14312 if (!anchor.hash || isDisabled(anchor)) { 14313 continue; 14314 } 14315 const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element); 14316 if (isVisible(observableSection)) { 14317 this._targetLinks.set(decodeURI(anchor.hash), anchor); 14318 this._observableSections.set(anchor.hash, observableSection); 14319 } 14320 } 14321 } 14322 _process(target) { 14323 if (this._activeTarget === target) { 14324 return; 14325 } 14326 this._clearActiveClass(this._config.target); 14327 this._activeTarget = target; 14328 target.classList.add(CLASS_NAME_ACTIVE$1); 14329 this._activateParents(target); 14330 EventHandler.trigger(this._element, EVENT_ACTIVATE, { 14331 relatedTarget: target 14332 }); 14333 } 14334 _activateParents(target) { 14335 if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) { 14336 SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1); 14337 return; 14338 } 14339 for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) { 14340 for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) { 14341 item.classList.add(CLASS_NAME_ACTIVE$1); 14342 } 14343 } 14344 } 14345 _clearActiveClass(parent) { 14346 parent.classList.remove(CLASS_NAME_ACTIVE$1); 14347 const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE$1}`, parent); 14348 for (const node of activeNodes) { 14349 node.classList.remove(CLASS_NAME_ACTIVE$1); 14350 } 14351 } 14352 // Static 14353 static jQueryInterface(config) { 14354 return this.each(function() { 14355 const data = _ScrollSpy.getOrCreateInstance(this, config); 14356 if (typeof config !== "string") { 14357 return; 14358 } 14359 if (data[config] === void 0 || config.startsWith("_") || config === "constructor") { 14360 throw new TypeError(`No method named "${config}"`); 14361 } 14362 data[config](); 14363 }); 14364 } 14365 }; 14366 EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => { 14367 for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) { 14368 ScrollSpy.getOrCreateInstance(spy); 14369 } 14370 }); 14371 defineJQueryPlugin(ScrollSpy); 14372 var NAME$1 = "tab"; 14373 var DATA_KEY$1 = "bs.tab"; 14374 var EVENT_KEY$1 = `.${DATA_KEY$1}`; 14375 var EVENT_HIDE$1 = `hide${EVENT_KEY$1}`; 14376 var EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`; 14377 var EVENT_SHOW$1 = `show${EVENT_KEY$1}`; 14378 var EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`; 14379 var EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}`; 14380 var EVENT_KEYDOWN = `keydown${EVENT_KEY$1}`; 14381 var EVENT_LOAD_DATA_API = `load${EVENT_KEY$1}`; 14382 var ARROW_LEFT_KEY = "ArrowLeft"; 14383 var ARROW_RIGHT_KEY = "ArrowRight"; 14384 var ARROW_UP_KEY = "ArrowUp"; 14385 var ARROW_DOWN_KEY = "ArrowDown"; 14386 var HOME_KEY = "Home"; 14387 var END_KEY = "End"; 14388 var CLASS_NAME_ACTIVE = "active"; 14389 var CLASS_NAME_FADE$1 = "fade"; 14390 var CLASS_NAME_SHOW$1 = "show"; 14391 var CLASS_DROPDOWN = "dropdown"; 14392 var SELECTOR_DROPDOWN_TOGGLE = ".dropdown-toggle"; 14393 var SELECTOR_DROPDOWN_MENU = ".dropdown-menu"; 14394 var NOT_SELECTOR_DROPDOWN_TOGGLE = `:not(${SELECTOR_DROPDOWN_TOGGLE})`; 14395 var SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]'; 14396 var SELECTOR_OUTER = ".nav-item, .list-group-item"; 14397 var SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`; 14398 var SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; 14399 var SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`; 14400 var SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`; 14401 var Tab = class _Tab extends BaseComponent { 14402 constructor(element) { 14403 super(element); 14404 this._parent = this._element.closest(SELECTOR_TAB_PANEL); 14405 if (!this._parent) { 14406 return; 14407 } 14408 this._setInitialAttributes(this._parent, this._getChildren()); 14409 EventHandler.on(this._element, EVENT_KEYDOWN, (event) => this._keydown(event)); 14410 } 14411 // Getters 14412 static get NAME() { 14413 return NAME$1; 14414 } 14415 // Public 14416 show() { 14417 const innerElem = this._element; 14418 if (this._elemIsActive(innerElem)) { 14419 return; 14420 } 14421 const active = this._getActiveElem(); 14422 const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE$1, { 14423 relatedTarget: innerElem 14424 }) : null; 14425 const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW$1, { 14426 relatedTarget: active 14427 }); 14428 if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) { 14429 return; 14430 } 14431 this._deactivate(active, innerElem); 14432 this._activate(innerElem, active); 14433 } 14434 // Private 14435 _activate(element, relatedElem) { 14436 if (!element) { 14437 return; 14438 } 14439 element.classList.add(CLASS_NAME_ACTIVE); 14440 this._activate(SelectorEngine.getElementFromSelector(element)); 14441 const complete = () => { 14442 if (element.getAttribute("role") !== "tab") { 14443 element.classList.add(CLASS_NAME_SHOW$1); 14444 return; 14445 } 14446 element.removeAttribute("tabindex"); 14447 element.setAttribute("aria-selected", true); 14448 this._toggleDropDown(element, true); 14449 EventHandler.trigger(element, EVENT_SHOWN$1, { 14450 relatedTarget: relatedElem 14451 }); 14452 }; 14453 this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1)); 14454 } 14455 _deactivate(element, relatedElem) { 14456 if (!element) { 14457 return; 14458 } 14459 element.classList.remove(CLASS_NAME_ACTIVE); 14460 element.blur(); 14461 this._deactivate(SelectorEngine.getElementFromSelector(element)); 14462 const complete = () => { 14463 if (element.getAttribute("role") !== "tab") { 14464 element.classList.remove(CLASS_NAME_SHOW$1); 14465 return; 14466 } 14467 element.setAttribute("aria-selected", false); 14468 element.setAttribute("tabindex", "-1"); 14469 this._toggleDropDown(element, false); 14470 EventHandler.trigger(element, EVENT_HIDDEN$1, { 14471 relatedTarget: relatedElem 14472 }); 14473 }; 14474 this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1)); 14475 } 14476 _keydown(event) { 14477 if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key)) { 14478 return; 14479 } 14480 event.stopPropagation(); 14481 event.preventDefault(); 14482 const children = this._getChildren().filter((element) => !isDisabled(element)); 14483 let nextActiveElement; 14484 if ([HOME_KEY, END_KEY].includes(event.key)) { 14485 nextActiveElement = children[event.key === HOME_KEY ? 0 : children.length - 1]; 14486 } else { 14487 const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key); 14488 nextActiveElement = getNextActiveElement(children, event.target, isNext, true); 14489 } 14490 if (nextActiveElement) { 14491 nextActiveElement.focus({ 14492 preventScroll: true 14493 }); 14494 _Tab.getOrCreateInstance(nextActiveElement).show(); 14495 } 14496 } 14497 _getChildren() { 14498 return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent); 14499 } 14500 _getActiveElem() { 14501 return this._getChildren().find((child) => this._elemIsActive(child)) || null; 14502 } 14503 _setInitialAttributes(parent, children) { 14504 this._setAttributeIfNotExists(parent, "role", "tablist"); 14505 for (const child of children) { 14506 this._setInitialAttributesOnChild(child); 14507 } 14508 } 14509 _setInitialAttributesOnChild(child) { 14510 child = this._getInnerElement(child); 14511 const isActive = this._elemIsActive(child); 14512 const outerElem = this._getOuterElement(child); 14513 child.setAttribute("aria-selected", isActive); 14514 if (outerElem !== child) { 14515 this._setAttributeIfNotExists(outerElem, "role", "presentation"); 14516 } 14517 if (!isActive) { 14518 child.setAttribute("tabindex", "-1"); 14519 } 14520 this._setAttributeIfNotExists(child, "role", "tab"); 14521 this._setInitialAttributesOnTargetPanel(child); 14522 } 14523 _setInitialAttributesOnTargetPanel(child) { 14524 const target = SelectorEngine.getElementFromSelector(child); 14525 if (!target) { 14526 return; 14527 } 14528 this._setAttributeIfNotExists(target, "role", "tabpanel"); 14529 if (child.id) { 14530 this._setAttributeIfNotExists(target, "aria-labelledby", `${child.id}`); 14531 } 14532 } 14533 _toggleDropDown(element, open) { 14534 const outerElem = this._getOuterElement(element); 14535 if (!outerElem.classList.contains(CLASS_DROPDOWN)) { 14536 return; 14537 } 14538 const toggle = (selector, className) => { 14539 const element2 = SelectorEngine.findOne(selector, outerElem); 14540 if (element2) { 14541 element2.classList.toggle(className, open); 14542 } 14543 }; 14544 toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE); 14545 toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW$1); 14546 outerElem.setAttribute("aria-expanded", open); 14547 } 14548 _setAttributeIfNotExists(element, attribute, value) { 14549 if (!element.hasAttribute(attribute)) { 14550 element.setAttribute(attribute, value); 14551 } 14552 } 14553 _elemIsActive(elem) { 14554 return elem.classList.contains(CLASS_NAME_ACTIVE); 14555 } 14556 // Try to get the inner element (usually the .nav-link) 14557 _getInnerElement(elem) { 14558 return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem); 14559 } 14560 // Try to get the outer element (usually the .nav-item) 14561 _getOuterElement(elem) { 14562 return elem.closest(SELECTOR_OUTER) || elem; 14563 } 14564 // Static 14565 static jQueryInterface(config) { 14566 return this.each(function() { 14567 const data = _Tab.getOrCreateInstance(this); 14568 if (typeof config !== "string") { 14569 return; 14570 } 14571 if (data[config] === void 0 || config.startsWith("_") || config === "constructor") { 14572 throw new TypeError(`No method named "${config}"`); 14573 } 14574 data[config](); 14575 }); 14576 } 14577 }; 14578 EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function(event) { 14579 if (["A", "AREA"].includes(this.tagName)) { 14580 event.preventDefault(); 14581 } 14582 if (isDisabled(this)) { 14583 return; 14584 } 14585 Tab.getOrCreateInstance(this).show(); 14586 }); 14587 EventHandler.on(window, EVENT_LOAD_DATA_API, () => { 14588 for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) { 14589 Tab.getOrCreateInstance(element); 14590 } 14591 }); 14592 defineJQueryPlugin(Tab); 14593 var NAME = "toast"; 14594 var DATA_KEY = "bs.toast"; 14595 var EVENT_KEY = `.${DATA_KEY}`; 14596 var EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`; 14597 var EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`; 14598 var EVENT_FOCUSIN = `focusin${EVENT_KEY}`; 14599 var EVENT_FOCUSOUT = `focusout${EVENT_KEY}`; 14600 var EVENT_HIDE = `hide${EVENT_KEY}`; 14601 var EVENT_HIDDEN = `hidden${EVENT_KEY}`; 14602 var EVENT_SHOW = `show${EVENT_KEY}`; 14603 var EVENT_SHOWN = `shown${EVENT_KEY}`; 14604 var CLASS_NAME_FADE = "fade"; 14605 var CLASS_NAME_HIDE = "hide"; 14606 var CLASS_NAME_SHOW = "show"; 14607 var CLASS_NAME_SHOWING = "showing"; 14608 var DefaultType = { 14609 animation: "boolean", 14610 autohide: "boolean", 14611 delay: "number" 14612 }; 14613 var Default = { 14614 animation: true, 14615 autohide: true, 14616 delay: 5e3 14617 }; 14618 var Toast = class _Toast extends BaseComponent { 14619 constructor(element, config) { 14620 super(element, config); 14621 this._timeout = null; 14622 this._hasMouseInteraction = false; 14623 this._hasKeyboardInteraction = false; 14624 this._setListeners(); 14625 } 14626 // Getters 14627 static get Default() { 14628 return Default; 14629 } 14630 static get DefaultType() { 14631 return DefaultType; 14632 } 14633 static get NAME() { 14634 return NAME; 14635 } 14636 // Public 14637 show() { 14638 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW); 14639 if (showEvent.defaultPrevented) { 14640 return; 14641 } 14642 this._clearTimeout(); 14643 if (this._config.animation) { 14644 this._element.classList.add(CLASS_NAME_FADE); 14645 } 14646 const complete = () => { 14647 this._element.classList.remove(CLASS_NAME_SHOWING); 14648 EventHandler.trigger(this._element, EVENT_SHOWN); 14649 this._maybeScheduleHide(); 14650 }; 14651 this._element.classList.remove(CLASS_NAME_HIDE); 14652 reflow(this._element); 14653 this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING); 14654 this._queueCallback(complete, this._element, this._config.animation); 14655 } 14656 hide() { 14657 if (!this.isShown()) { 14658 return; 14659 } 14660 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE); 14661 if (hideEvent.defaultPrevented) { 14662 return; 14663 } 14664 const complete = () => { 14665 this._element.classList.add(CLASS_NAME_HIDE); 14666 this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW); 14667 EventHandler.trigger(this._element, EVENT_HIDDEN); 14668 }; 14669 this._element.classList.add(CLASS_NAME_SHOWING); 14670 this._queueCallback(complete, this._element, this._config.animation); 14671 } 14672 dispose() { 14673 this._clearTimeout(); 14674 if (this.isShown()) { 14675 this._element.classList.remove(CLASS_NAME_SHOW); 14676 } 14677 super.dispose(); 14678 } 14679 isShown() { 14680 return this._element.classList.contains(CLASS_NAME_SHOW); 14681 } 14682 // Private 14683 _maybeScheduleHide() { 14684 if (!this._config.autohide) { 14685 return; 14686 } 14687 if (this._hasMouseInteraction || this._hasKeyboardInteraction) { 14688 return; 14689 } 14690 this._timeout = setTimeout(() => { 14691 this.hide(); 14692 }, this._config.delay); 14693 } 14694 _onInteraction(event, isInteracting) { 14695 switch (event.type) { 14696 case "mouseover": 14697 case "mouseout": { 14698 this._hasMouseInteraction = isInteracting; 14699 break; 14700 } 14701 case "focusin": 14702 case "focusout": { 14703 this._hasKeyboardInteraction = isInteracting; 14704 break; 14705 } 14706 } 14707 if (isInteracting) { 14708 this._clearTimeout(); 14709 return; 14710 } 14711 const nextElement = event.relatedTarget; 14712 if (this._element === nextElement || this._element.contains(nextElement)) { 14713 return; 14714 } 14715 this._maybeScheduleHide(); 14716 } 14717 _setListeners() { 14718 EventHandler.on(this._element, EVENT_MOUSEOVER, (event) => this._onInteraction(event, true)); 14719 EventHandler.on(this._element, EVENT_MOUSEOUT, (event) => this._onInteraction(event, false)); 14720 EventHandler.on(this._element, EVENT_FOCUSIN, (event) => this._onInteraction(event, true)); 14721 EventHandler.on(this._element, EVENT_FOCUSOUT, (event) => this._onInteraction(event, false)); 14722 } 14723 _clearTimeout() { 14724 clearTimeout(this._timeout); 14725 this._timeout = null; 14726 } 14727 // Static 14728 static jQueryInterface(config) { 14729 return this.each(function() { 14730 const data = _Toast.getOrCreateInstance(this, config); 14731 if (typeof config === "string") { 14732 if (typeof data[config] === "undefined") { 14733 throw new TypeError(`No method named "${config}"`); 14734 } 14735 data[config](this); 14736 } 14737 }); 14738 } 14739 }; 14740 enableDismissTrigger(Toast); 14741 defineJQueryPlugin(Toast); 14742 14743
vendor: 373 bytes, lines 14743-14754
14743// node_modules/timeago.js/esm/lang/en_US.js 14744 var EN_US = ["second", "minute", "hour", "day", "week", "month", "year"]; 14745 function en_US_default(diff, idx) { 14746 if (idx === 0) 14747 return ["just now", "right now"]; 14748 var unit = EN_US[Math.floor(idx / 2)]; 14749 if (diff > 1) 14750 unit += "s"; 14751 return [diff + " " + unit + " ago", "in " + diff + " " + unit]; 14752 } 14753 14754
vendor: 374 bytes, lines 14754-14763
14754// node_modules/timeago.js/esm/lang/zh_CN.js 14755 var ZH_CN = ["\u79D2", "\u5206\u949F", "\u5C0F\u65F6", "\u5929", "\u5468", "\u4E2A\u6708", "\u5E74"]; 14756 function zh_CN_default(diff, idx) { 14757 if (idx === 0) 14758 return ["\u521A\u521A", "\u7247\u523B\u540E"]; 14759 var unit = ZH_CN[~~(idx / 2)]; 14760 return [diff + " " + unit + "\u524D", diff + " " + unit + "\u540E"]; 14761 } 14762 14763
vendor: 231 bytes, lines 14763-14772
14763// node_modules/timeago.js/esm/register.js 14764 var Locales = {}; 14765 var register = function(locale, func) { 14766 Locales[locale] = func; 14767 }; 14768 var getLocale = function(locale) { 14769 return Locales[locale] || Locales["en_US"]; 14770 }; 14771 14772
vendor: 1,386 bytes, lines 14772-14818
14772// node_modules/timeago.js/esm/utils/date.js 14773 var SEC_ARRAY = [ 14774 60, 14775 60, 14776 24, 14777 7, 14778 365 / 7 / 12, 14779 12 14780 ]; 14781 function toDate(input) { 14782 if (input instanceof Date) 14783 return input; 14784 if (!isNaN(input) || /^\d+$/.test(input)) 14785 return new Date(parseInt(input)); 14786 input = (input || "").trim().replace(/\.\d+/, "").replace(/-/, "/").replace(/-/, "/").replace(/(\d)T(\d)/, "$1 $2").replace(/Z/, " UTC").replace(/([+-]\d\d):?(\d\d)/, " $1$2"); 14787 return new Date(input); 14788 } 14789 function formatDiff(diff, localeFunc) { 14790 var agoIn = diff < 0 ? 1 : 0; 14791 diff = Math.abs(diff); 14792 var totalSec = diff; 14793 var idx = 0; 14794 for (; diff >= SEC_ARRAY[idx] && idx < SEC_ARRAY.length; idx++) { 14795 diff /= SEC_ARRAY[idx]; 14796 } 14797 diff = Math.floor(diff); 14798 idx *= 2; 14799 if (diff > (idx === 0 ? 9 : 1)) 14800 idx += 1; 14801 return localeFunc(diff, idx, totalSec)[agoIn].replace("%s", diff.toString()); 14802 } 14803 function diffSec(date, relativeDate) { 14804 var relDate = relativeDate ? toDate(relativeDate) : /* @__PURE__ */ new Date(); 14805 return (+relDate - +toDate(date)) / 1e3; 14806 } 14807 function nextInterval(diff) { 14808 var rst = 1, i = 0, d = Math.abs(diff); 14809 for (; diff >= SEC_ARRAY[i] && i < SEC_ARRAY.length; i++) { 14810 diff /= SEC_ARRAY[i]; 14811 rst *= SEC_ARRAY[i]; 14812 } 14813 d = d % rst; 14814 d = d ? rst - d : rst; 14815 return Math.ceil(d); 14816 } 14817 14818
vendor: 353 bytes, lines 14818-14830
14818// node_modules/timeago.js/esm/utils/dom.js 14819 var ATTR_TIMEAGO_TID = "timeago-id"; 14820 function getDateAttribute(node) { 14821 return node.getAttribute("datetime"); 14822 } 14823 function setTimerId(node, timerId) { 14824 node.setAttribute(ATTR_TIMEAGO_TID, timerId); 14825 } 14826 function getTimerId(node) { 14827 return parseInt(node.getAttribute(ATTR_TIMEAGO_TID)); 14828 } 14829 14830
vendor: 854 bytes, lines 14830-14855
14830// node_modules/timeago.js/esm/realtime.js 14831 var TIMER_POOL = {}; 14832 var clear = function(tid) { 14833 clearTimeout(tid); 14834 delete TIMER_POOL[tid]; 14835 }; 14836 function run(node, date, localeFunc, opts) { 14837 clear(getTimerId(node)); 14838 var relativeDate = opts.relativeDate, minInterval = opts.minInterval; 14839 var diff = diffSec(date, relativeDate); 14840 node.innerText = formatDiff(diff, localeFunc); 14841 var tid = setTimeout(function() { 14842 run(node, date, localeFunc, opts); 14843 }, Math.min(Math.max(nextInterval(diff), minInterval || 1) * 1e3, 2147483647)); 14844 TIMER_POOL[tid] = 0; 14845 setTimerId(node, tid); 14846 } 14847 function render(nodes, locale, opts) { 14848 var nodeList = nodes.length ? nodes : [nodes]; 14849 nodeList.forEach(function(node) { 14850 run(node, getDateAttribute(node), getLocale(locale), opts || {}); 14851 }); 14852 return nodeList; 14853 } 14854 14855
vendor: 115 bytes, lines 14855-14859
14855// node_modules/timeago.js/esm/index.js 14856 register("en_US", en_US_default); 14857 register("zh_CN", zh_CN_default); 14858 14859
14859// app/assets/javascripts/application.js 14860 var adsbygoogle; 14861 (function() { 14862 var COLORS = ["orange", "yellow", "green", "darkgreen", "blue", "purple", "pink", "paleblue", "brown", "red"]; 14863 var HEX_COLORS = ["#fd8c08", "#ffed5b", "#96ec7c", "#01be00", "#6a97ff", "#c89aff", "#fdaaff", "#bbe3ff", "#cb9c7b", "#ff766a"]; 14864 window.initializeMaps = function() { 14865 var baseLayers = {}; 14866 var latLngFromStr = function(str) { 14867 var latlngstrs = str.split(","); 14868 return [parseFloat(latlngstrs[0]), parseFloat(latlngstrs[1])]; 14869 }; 14870 var drawLabel = function(row, canvas, map, index, marker) { 14871 var labelTd = row.querySelector('div.marker[data-quakeIndex="' + index + '"]'); 14872 var handler = function() { 14873 var infoWindowContentDiv = row.querySelector('.quake-info-container[data-quakeIndex="' + index + '"] template').content.firstElementChild.cloneNode(true); 14874 ; 14875 return infoWindowContentDiv.innerHTML; 14876 }; 14877 marker.bindPopup(handler, { offset: [0, -20] }); 14878 labelTd.addEventListener("click", function() { 14879 marker.togglePopup(); 14880 }); 14881 }; 14882 var drawMarker = function(latLng, magnitude, map, index, canvas) { 14883 var myIcon = import_leaflet.default.divIcon({ className: "marker marker-" + COLORS[index], iconSize: [12, 20], iconAnchor: [6, 20] }); 14884 var marker = import_leaflet.default.marker(latLng, { icon: myIcon }).addTo(map); 14885 return marker; 14886 }; 14887 var drawCircle = function(latLng, size, map, index) { 14888 var quakeCircle; 14889 var circleOptions = { 14890 color: HEX_COLORS[index], 14891 opacity: 0.8, 14892 weight: 2, 14893 fillColor: HEX_COLORS[index], 14894 fillOpacity: 0.25, 14895 radius: size 14896 }; 14897 quakeCircle = import_leaflet.default.circle(latLng, circleOptions).addTo(map); 14898 return quakeCircle; 14899 }; 14900 var drawMap = function(row, canvas, center, latLngTuples, magnitudes, depths, radiuses, drawMagnitude) { 14901 var index = 0; 14902 var map = import_leaflet.default.map(canvas, { scrollWheelZoom: false, attributionControl: false, zoomAnimation: false, fadeAnimation: false, markerZoomAnimation: false }).setView(center, 13); 14903 var attribution = import_leaflet.default.control.attribution({ prefix: false }).addTo(map); 14904 import_leaflet.default.control.scale().addTo(map); 14905 var NatGeoAtt = `<a title="Content may not reflect National Geographic's current map policy. Sources: National Geographic, Esri, DeLorme, HERE, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, increment P Corp." href="http://www.arcgis.com/home/item.html?id=b9b1b422198944fbbd5250b3241691b6">Map data: National Geographic, Esri,...</a> | Powered by <a href="http://esri.com">Esri</a>`; 14906 var streetAtt = 'Map data: Esri, HERE, DeLorme, NGA, USGS | Powered by <a href="http://esri.com">Esri</a>'; 14907 var urlTemplate = "https://server.arcgisonline.com/arcgis/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}"; 14908 import_leaflet.default.tileLayer(urlTemplate, { 14909 attribution: NatGeoAtt, 14910 maxZoom: 12 14911 }).addTo(map); 14912 var url = "https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}"; 14913 import_leaflet.default.tileLayer(url, { 14914 minZoom: 13, 14915 maxZoom: 18 14916 }).addTo(map); 14917 map.on("zoomend", function(e) { 14918 if (map.getZoom() > 12) { 14919 attribution.removeAttribution(streetAtt); 14920 attribution.removeAttribution(NatGeoAtt); 14921 attribution.addAttribution(streetAtt); 14922 } 14923 if (map.getZoom() <= 12) { 14924 attribution.removeAttribution(NatGeoAtt); 14925 attribution.removeAttribution(streetAtt); 14926 attribution.addAttribution(NatGeoAtt); 14927 } 14928 }); 14929 map.on("popupopen", function() { 14930 render(document.querySelectorAll("abbr.timeago")); 14931 }); 14932 var markerGroup = new import_leaflet.default.featureGroup(); 14933 latLngTuples.forEach(function(el) { 14934 var latLng = latLngFromStr(el); 14935 if (latLng[1] > 0) { 14936 latLng[1] = latLng[1] - 360; 14937 } 14938 var marker = drawMarker(latLng, magnitudes[index], map, index, canvas); 14939 markerGroup.addLayer(marker); 14940 var radius = parseFloat(radiuses[index] || (Math.pow(parseFloat(magnitudes[index]), 5) + 1e3) * 15); 14941 if (drawMagnitude) { 14942 var circle = drawCircle(latLng, radius, map, index); 14943 markerGroup.addLayer(circle); 14944 } 14945 drawLabel(row, canvas, map, index, marker, circle); 14946 index++; 14947 }); 14948 var zoom = canvas.getAttribute("data-zoom"); 14949 if (zoom) { 14950 map.setZoom(parseInt(zoom)); 14951 } else if (latLngTuples.length > 1) { 14952 map.fitBounds(markerGroup.getBounds()); 14953 } else { 14954 map.setZoom(7); 14955 } 14956 var drawFirePerimeters = canvas.getAttribute("data-show-fire-perimeters") === "true"; 14957 if (drawFirePerimeters) { 14958 fetch("https://services3.arcgis.com/T4QMspbfLg3qTGWY/arcgis/rest/services/WFIGS_Interagency_Perimeters_Current/FeatureServer/replicafilescache/WFIGS_Interagency_Perimeters_Current_1526902131246806732.geojson").then(function(response) { 14959 response.json().then(function(jsonData) { 14960 import_leaflet.default.geoJSON(jsonData, { style: { color: "#df6a2f", weight: 1.5 }, onEachFeature: function(feature, layer) { 14961 } }).addTo(map); 14962 }); 14963 }); 14964 var handler = function(intensity) { 14965 return "<p>" + intensity + " Smoke</p>"; 14966 }; 14967 var drawOtherFires = function() { 14968 var bounds = map.getBounds(); 14969 var myIcon = import_leaflet.default.icon({ 14970 iconUrl: "/assets/fire.png", 14971 iconSize: [20, 20], 14972 popupAnchor: [0, -20] 14973 }); 14974 fetch("/f/within/" + bounds.getNorth() + "/" + bounds.getWest() + "/" + bounds.getSouth() + "/" + bounds.getE
14974ast()).then(function(response) { 14975 response.json().then(function(jsonData) { 14976 var layer = import_leaflet.default.geoJSON(jsonData, { pointToLayer: function(point) { 14977 var marker = import_leaflet.default.circleMarker(point.geometry.coordinates, { stroke: false, radius: 9, color: "#ffA500", fillOpacity: 1 }); 14978 marker.bindPopup(function() { 14979 return '<a href="/f/fires' + point.properties.url_path + '">' + point.properties.title + "</a>"; 14980 }); 14981 return marker; 14982 } }).addTo(map); 14983 }); 14984 }); 14985 }; 14986 drawOtherFires(); 14987 } 14988 }; 14989 function isOnScreen(element, margin) { 14990 var rect = element.getBoundingClientRect(); 14991 var html = document.documentElement; 14992 return rect.top >= 0 - margin && rect.top <= (window.innerHeight || html.clientHeight) + margin || rect.bottom >= 0 - margin && rect.bottom <= (window.innerHeight || html.clientHeight) + margin; 14993 } 14994 var createMap = function(row) { 14995 var canvas = row.querySelector(".quakes-multi-map-canvas"); 14996 var latLngTuples = canvas.getAttribute("data-coordinates").split(";"); 14997 var magnitudes = canvas.getAttribute("data-magnitudes").split(";"); 14998 var radiuses = (canvas.getAttribute("data-radiuses") || "").split(";"); 14999 var depths = canvas.getAttribute("data-depths").split(";"); 15000 var citytuple = canvas.getAttribute("data-city"); 15001 var drawMagnitude = canvas.getAttribute("data-no-draw-magnitude") !== "true"; 15002 var center; 15003 if (citytuple) { 15004 center = latLngFromStr(citytuple); 15005 } else { 15006 center = latLngFromStr(latLngTuples[0]); 15007 } 15008 if (center[1] > 0) { 15009 center[1] = center[1] - 360; 15010 } 15011 window.requestAnimationFrame(function() { 15012 drawMap(row, canvas, center, latLngTuples, magnitudes, depths, radiuses, drawMagnitude); 15013 }); 15014 }; 15015 var loadAds = function() { 15016 var i = 0; 15017 document.querySelectorAll(".adplaceholder").forEach(function(el) { 15018 var adItem = document.createElement("ins"); 15019 adItem.setAttribute("style", "display:block"); 15020 adItem.setAttribute("class", "adsbygoogle"); 15021 adItem.setAttribute("data-ad-client", "ca-pub-6219004123561661"); 15022 adItem.setAttribute("data-ad-slot", "3301756469"); 15023 adItem.setAttribute("data-ad-format", "auto"); 15024 adItem.setAttribute("data-full-width-responsive", "true"); 15025 el.parentNode.replaceChild(adItem, el); 15026 (adsbygoogle = window.adsbygoogle || []).push({}); 15027 i++; 15028 }); 15029 }; 15030 var loadVisibleMaps = function() { 15031 var i = 0; 15032 document.querySelectorAll(".quakes-multi-map-row").forEach(function(el) { 15033 if (el.getAttribute("data-loaded") != "true" && isOnScreen(el, 200)) { 15034 createMap(el); 15035 el.setAttribute("data-loaded", "true"); 15036 } 15037 i++; 15038 }); 15039 }; 15040 loadVisibleMaps(); 15041 loadAds(); 15042 window.addEventListener("scroll", function() { 15043 window.requestAnimationFrame(function() { 15044 loadVisibleMaps(); 15045 }); 15046 }, { passive: true }); 15047 }; 15048 var loadHandler = function() { 15049 if (document.querySelector(".quakes-multi-map-canvas")) { 15050 window.requestAnimationFrame(initializeMaps); 15051 } 15052 render(document.querySelectorAll("abbr.timeago")); 15053 document.querySelectorAll(".local-time").forEach(function(item, i) { 15054 var date = new Date(item.innerText); 15055 var options = { weekday: "long", year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "numeric", timeZoneName: "short" }; 15056 item.innerText = date.toLocaleString(void 0, options); 15057 }); 15058 document.querySelectorAll(".local-time-short").forEach(function(item, i) { 15059 var date = new Date(item.innerText);
15060 var options = { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit", hour12: false, timeZoneName: "short" }; 15061 item.innerText = date.toLocaleString(void 0, options); 15062 }); 15063 }; 15064 if (document.readyState !== "loading") { 15065 loadHandler(); 15066 } else { 15067 window.addEventListener("DOMContentLoaded", loadHandler); 15068 } 15069 })(); 15070})(); 15071/*! Bundled license information: 15072 15073leaflet/dist/leaflet-src.js: 15074 (* @preserve 15075 * Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com 15076 * (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade 15077 *) 15078 15079bootstrap/dist/js/bootstrap.esm.js: 15080 (*! 15081 * Bootstrap v5.3.5 (https://getbootstrap.com/) 15082 * Copyright 2011-2025 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 15083 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 15084 *) 15085*/ 15086;
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.