UNPKG

@infobus/vue

Version:

Vue components and composables for public transportation websites using GTFS data through the Infobús API

1,248 lines (1,247 loc) 307 kB
import { ref as Lt, computed as Et, defineComponent as Cn, watch as ze, onMounted as zn, onUnmounted as kn, openBlock as G, createElementBlock as q, unref as et, createElementVNode as K, toDisplayString as mt, createCommentVNode as pt, renderSlot as ci, Fragment as rs, renderList as as, normalizeClass as hs, normalizeStyle as us } from "vue"; function En(O) { const it = Lt(!1), u = Lt(null); return { isLoading: it, error: u, makeRequest: async (m, N = {}) => { it.value = !0, u.value = null; try { const x = new URL(m, O.baseUrl), D = { "Content-Type": "application/json", ...N.headers }; O.apiKey && (D.Authorization = `Bearer ${O.apiKey}`); const p = await fetch(x.toString(), { ...N, headers: D, signal: AbortSignal.timeout(O.timeout || 1e4) }); if (!p.ok) throw new Error(`HTTP error! status: ${p.status}`); const Q = await p.json(); if (Q.success === !1) throw new Error(Q.error || Q.message || "API request failed"); return Q.data || Q; } catch (x) { const D = x instanceof Error ? x.message : "Unknown error"; throw u.value = D, new Error(D); } finally { it.value = !1; } } }; } function ls(O) { const { isLoading: it, error: u, makeRequest: Y } = En(O), m = Lt(null), N = Lt(null), x = Et(() => { var T; return ((T = m.value) == null ? void 0 : T.trips) || []; }), D = Et(() => { var T; return ((T = m.value) == null ? void 0 : T.stop_info) || null; }), p = Et(() => { var T; return ((T = m.value) == null ? void 0 : T.last_updated) || null; }), Q = async (T, c = {}) => { try { const b = new URLSearchParams({ stop_id: T, ...c.limit && { limit: c.limit.toString() }, ...c.routeId && { route_id: c.routeId }, ...c.directionId !== void 0 && { direction_id: c.directionId.toString() }, ...c.includeRealtime !== void 0 && { realtime: c.includeRealtime.toString() } }), J = await Y( `/next-trips?${b.toString()}` ); return m.value = J, N.value = /* @__PURE__ */ new Date(), J.trips; } catch (b) { throw console.error("Error fetching next trips:", b), b; } }; return { isLoading: it, error: u, data: m, trips: x, stopInfo: D, lastUpdated: p, lastFetch: N, fetchNextTrips: Q, refresh: async (T, c = {}) => await Q(T, c), getTripsByRoute: (T) => x.value.filter((c) => c.route_id === T), getNextTrips: (T) => x.value.slice(0, T), isStale: (T = 5) => N.value ? ((/* @__PURE__ */ new Date()).getTime() - N.value.getTime()) / (1e3 * 60) > T : !0 }; } const cs = { class: "infobus-next-trips" }, ds = { key: 0, class: "stop-info" }, fs = { class: "stop-name" }, _s = { key: 0, class: "stop-description" }, ms = { key: 1, class: "loading" }, ps = { key: 2, class: "error" }, vs = { class: "error-message" }, gs = { key: 3, class: "no-trips" }, ys = { key: 4, class: "trips-container" }, ws = { key: 0, class: "last-updated" }, xs = { class: "trips-list" }, Ps = { class: "route-info" }, Ls = { class: "route-long-name" }, Ts = { class: "trip-details" }, bs = { class: "headsign" }, Ms = { class: "times" }, Ss = { class: "scheduled-time" }, Cs = { key: 0, class: "estimated-time" }, zs = { key: 1, class: "delay" }, ks = { key: 0, class: "accessibility" }, Es = { key: 0, class: "wheelchair-accessible", title: "Accesible para sillas de ruedas" }, Is = { key: 1, class: "bikes-allowed", title: "Permite bicicletas" }, Zs = { key: 1, class: "refresh-section" }, Os = ["disabled"], Bs = /* @__PURE__ */ Cn({ __name: "InfobusNextTrips", props: { stopId: {}, config: {}, limit: { default: 10 }, routeId: {}, directionId: {}, includeRealtime: { type: Boolean, default: !0 }, autoRefresh: { type: Boolean, default: !1 }, refreshInterval: { default: 6e4 }, showStopInfo: { type: Boolean, default: !0 }, showLastUpdated: { type: Boolean, default: !0 }, showRefreshButton: { type: Boolean, default: !0 }, showAccessibility: { type: Boolean, default: !0 }, maxTrips: { default: 5 } }, emits: ["tripsLoaded", "error", "refresh"], setup(O, { emit: it }) { const u = O, Y = it, { isLoading: m, error: N, trips: x, stopInfo: D, lastUpdated: p, fetchNextTrips: Q, refresh: $, isStale: z } = ls(u.config), B = Lt(null), Tt = Et(() => x.value.slice(0, u.maxTrips)), T = Et(() => ({ limit: u.limit, routeId: u.routeId, directionId: u.directionId, includeRealtime: u.includeRealtime })), c = async () => { try { Y("refresh"); const k = await $(u.stopId, T.value); Y("tripsLoaded", k); } catch (k) { const j = k instanceof Error ? k.message : "Error al actualizar"; Y("error", j); } }, b = () => { u.autoRefresh && u.refreshInterval > 0 && (B.value = setInterval(c, u.refreshInterval)); }, J = () => { B.value && (clearInterval(B.value), B.value = null); }, nt = (k) => { try { return new Date(k).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }); } catch { return k; } }, E = (k) => { try { return new Date(k).toLocaleString(); } catch { return k; } }, lt = (k) => { const j = k.route_color || "#007bff", F = k.route_text_color || "#ffffff"; return { backgroundColor: `#${j}`, color: `#${F}` }; }; return ze(() => u.stopId, async (k) => { k && await c(); }), ze(() => [u.routeId, u.directionId, u.limit], async () => { await c(); }), zn(async () => { await c(), b(); }), kn(() => { J(); }), (k, j) => (G(), q("div", cs, [ k.showStopInfo && et(D) ? (G(), q("div", ds, [ K("h3", fs, mt(et(D).stop_name), 1), et(D).stop_desc ? (G(), q("p", _s, mt(et(D).stop_desc), 1)) : pt("", !0) ])) : pt("", !0), et(m) ? (G(), q("div", ms, [ ci(k.$slots, "loading", {}, () => [ j[0] || (j[0] = K("div", { class: "spinner" }, null, -1)), j[1] || (j[1] = K("p", null, "Cargando próximos viajes...", -1)) ], !0) ])) : et(N) ? (G(), q("div", ps, [ ci(k.$slots, "error", { error: et(N) }, () => [ K("p", vs, mt(et(N)), 1), K("button", { onClick: c, class: "retry-button" }, " Reintentar ") ], !0) ])) : et(x).length === 0 ? (G(), q("div", gs, [ ci(k.$slots, "no-trips", {}, () => [ j[2] || (j[2] = K("p", null, "No hay viajes disponibles para esta parada.", -1)) ], !0) ])) : (G(), q("div", ys, [ k.showLastUpdated && et(p) ? (G(), q("div", ws, [ K("small", null, "Última actualización: " + mt(E(et(p))), 1) ])) : pt("", !0), K("div", xs, [ (G(!0), q(rs, null, as(Tt.value, (F) => (G(), q("div", { key: F.trip_id, class: hs(["trip-item", { "has-delay": F.delay && F.delay > 0 }]) }, [ K("div", Ps, [ K("span", { class: "route-short-name", style: us(lt(F)) }, mt(F.route_short_name), 5), K("span", Ls, mt(F.route_long_name), 1) ]), K("div", Ts, [ K("div", bs, mt(F.trip_headsign), 1), K("div", Ms, [ K("span", Ss, mt(nt(F.arrival_time)), 1), F.estimated_arrival && F.estimated_arrival !== F.arrival_time ? (G(), q("span", Cs, " (" + mt(nt(F.estimated_arrival)) + ") ", 1)) : pt("", !0), F.delay && F.delay > 0 ? (G(), q("span", zs, " +" + mt(Math.round(F.delay / 60)) + "min ", 1)) : pt("", !0) ]) ]), k.showAccessibility ? (G(), q("div", ks, [ F.wheelchair_accessible === 1 ? (G(), q("span", Es, " ♿ ")) : pt("", !0), F.bikes_allowed === 1 ? (G(), q("span", Is, " 🚲 ")) : pt("", !0) ])) : pt("", !0) ], 2))), 128)) ]), k.showRefreshButton ? (G(), q("div", Zs, [ K("button", { onClick: c, class: "refresh-button", disabled: et(m) }, " 🔄 Actualizar ", 8, Os) ])) : pt("", !0) ])) ])); } }); const In = (O, it) => { const u = O.__vccOpts || O; for (const [Y, m] of it) u[Y] = m; return u; }, As = /* @__PURE__ */ In(Bs, [["__scopeId", "data-v-518e5bb3"]]); function Rs(O) { const { isLoading: it, error: u, makeRequest: Y } = En(O), m = Lt(null), N = Lt(null), x = Et(() => { var c; return ((c = m.value) == null ? void 0 : c.shapes) || null; }), D = Et(() => { var c; return ((c = m.value) == null ? void 0 : c.route_info) || null; }), p = Et(() => { var c, b; return ((b = (c = m.value) == null ? void 0 : c.shapes) == null ? void 0 : b.features) || []; }), Q = async (c, b = {}) => { try { const J = new URLSearchParams({ route_id: c, ...b.directionId !== void 0 && { direction_id: b.directionId.toString() }, ...b.includeStops !== void 0 && { include_stops: b.includeStops.toString() }, ...b.simplify !== void 0 && { simplify: b.simplify.toString() }, ...b.format && { format: b.format } }), nt = await Y( `/geo-shapes?${J.toString()}` ); return m.value = nt, N.value = /* @__PURE__ */ new Date(), nt.shapes; } catch (J) { throw console.error("Error fetching route shapes:", J), J; } }, $ = async (c, b = {}) => await Q(c, b), z = (c) => p.value.filter( (b) => b.properties.direction_id === c ), B = () => { const c = []; return p.value.forEach((b) => { b.geometry.type === "LineString" && c.push(...b.geometry.coordinates); }), c; }; return { isLoading: it, error: u, data: m, shapes: x, routeInfo: D, features: p, lastFetch: N, fetchRouteShapes: Q, refresh: $, getShapesByDirection: z, getAllCoordinates: B, getBounds: () => { const c = B(); if (c.length === 0) return null; const b = c.map((nt) => nt[1]), J = c.map((nt) => nt[0]); return { north: Math.max(...b), south: Math.min(...b), east: Math.max(...J), west: Math.min(...J) }; }, isStale: (c = 30) => N.value ? ((/* @__PURE__ */ new Date()).getTime() - N.value.getTime()) / (1e3 * 60) > c : !0 }; } var Ns = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}; function Ds(O) { return O && O.__esModule && Object.prototype.hasOwnProperty.call(O, "default") ? O.default : O; } var fi = { exports: {} }; /* @preserve * Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com * (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade */ (function(O, it) { (function(u, Y) { Y(it); })(Ns, function(u) { var Y = "1.9.4"; function m(t) { var e, i, n, o; for (i = 1, n = arguments.length; i < n; i++) { o = arguments[i]; for (e in o) t[e] = o[e]; } return t; } var N = Object.create || function() { function t() { } return function(e) { return t.prototype = e, new t(); }; }(); function x(t, e) { var i = Array.prototype.slice; if (t.bind) return t.bind.apply(t, i.call(arguments, 1)); var n = i.call(arguments, 2); return function() { return t.apply(e, n.length ? n.concat(i.call(arguments)) : arguments); }; } var D = 0; function p(t) { return "_leaflet_id" in t || (t._leaflet_id = ++D), t._leaflet_id; } function Q(t, e, i) { var n, o, s, r; return r = function() { n = !1, o && (s.apply(i, o), o = !1); }, s = function() { n ? o = arguments : (t.apply(i, arguments), setTimeout(r, e), n = !0); }, s; } function $(t, e, i) { var n = e[1], o = e[0], s = n - o; return t === n && i ? t : ((t - o) % s + s) % s + o; } function z() { return !1; } function B(t, e) { if (e === !1) return t; var i = Math.pow(10, e === void 0 ? 6 : e); return Math.round(t * i) / i; } function Tt(t) { return t.trim ? t.trim() : t.replace(/^\s+|\s+$/g, ""); } function T(t) { return Tt(t).split(/\s+/); } function c(t, e) { Object.prototype.hasOwnProperty.call(t, "options") || (t.options = t.options ? N(t.options) : {}); for (var i in e) t.options[i] = e[i]; return t.options; } function b(t, e, i) { var n = []; for (var o in t) n.push(encodeURIComponent(i ? o.toUpperCase() : o) + "=" + encodeURIComponent(t[o])); return (!e || e.indexOf("?") === -1 ? "?" : "&") + n.join("&"); } var J = /\{ *([\w_ -]+) *\}/g; function nt(t, e) { return t.replace(J, function(i, n) { var o = e[n]; if (o === void 0) throw new Error("No value provided for variable " + i); return typeof o == "function" && (o = o(e)), o; }); } var E = Array.isArray || function(t) { return Object.prototype.toString.call(t) === "[object Array]"; }; function lt(t, e) { for (var i = 0; i < t.length; i++) if (t[i] === e) return i; return -1; } var k = "data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="; function j(t) { return window["webkit" + t] || window["moz" + t] || window["ms" + t]; } var F = 0; function _i(t) { var e = +/* @__PURE__ */ new Date(), i = Math.max(0, 16 - (e - F)); return F = e + i, window.setTimeout(t, i); } var ke = window.requestAnimationFrame || j("RequestAnimationFrame") || _i, mi = window.cancelAnimationFrame || j("CancelAnimationFrame") || j("CancelRequestAnimationFrame") || function(t) { window.clearTimeout(t); }; function st(t, e, i) { if (i && ke === _i) t.call(e); else return ke.call(window, x(t, e)); } function ct(t) { t && mi.call(window, t); } var Zn = { __proto__: null, extend: m, create: N, bind: x, get lastId() { return D; }, stamp: p, throttle: Q, wrapNum: $, falseFn: z, formatNum: B, trim: Tt, splitWords: T, setOptions: c, getParamString: b, template: nt, isArray: E, indexOf: lt, emptyImageUrl: k, requestFn: ke, cancelFn: mi, requestAnimFrame: st, cancelAnimFrame: ct }; function bt() { } bt.extend = function(t) { var e = function() { c(this), this.initialize && this.initialize.apply(this, arguments), this.callInitHooks(); }, i = e.__super__ = this.prototype, n = N(i); n.constructor = e, e.prototype = n; for (var o in this) Object.prototype.hasOwnProperty.call(this, o) && o !== "prototype" && o !== "__super__" && (e[o] = this[o]); return t.statics && m(e, t.statics), t.includes && (On(t.includes), m.apply(null, [n].concat(t.includes))), m(n, t), delete n.statics, delete n.includes, n.options && (n.options = i.options ? N(i.options) : {}, m(n.options, t.options)), n._initHooks = [], n.callInitHooks = function() { if (!this._initHooksCalled) { i.callInitHooks && i.callInitHooks.call(this), this._initHooksCalled = !0; for (var s = 0, r = n._initHooks.length; s < r; s++) n._initHooks[s].call(this); } }, e; }, bt.include = function(t) { var e = this.prototype.options; return m(this.prototype, t), t.options && (this.prototype.options = e, this.mergeOptions(t.options)), this; }, bt.mergeOptions = function(t) { return m(this.prototype.options, t), this; }, bt.addInitHook = function(t) { var e = Array.prototype.slice.call(arguments, 1), i = typeof t == "function" ? t : function() { this[t].apply(this, e); }; return this.prototype._initHooks = this.prototype._initHooks || [], this.prototype._initHooks.push(i), this; }; function On(t) { if (!(typeof L > "u" || !L || !L.Mixin)) { t = E(t) ? t : [t]; for (var e = 0; e < t.length; e++) t[e] === L.Mixin.Events && 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); } } var ut = { /* @method on(type: String, fn: Function, context?: Object): this * 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'`). * * @alternative * @method on(eventMap: Object): this * Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}` */ on: function(t, e, i) { if (typeof t == "object") for (var n in t) this._on(n, t[n], e); else { t = T(t); for (var o = 0, s = t.length; o < s; o++) this._on(t[o], e, i); } return this; }, /* @method off(type: String, fn?: Function, context?: Object): this * 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. * * @alternative * @method off(eventMap: Object): this * Removes a set of type/listener pairs. * * @alternative * @method off: this * Removes all listeners to all events on the object. This includes implicitly attached events. */ off: function(t, e, i) { if (!arguments.length) delete this._events; else if (typeof t == "object") for (var n in t) this._off(n, t[n], e); else { t = T(t); for (var o = arguments.length === 1, s = 0, r = t.length; s < r; s++) o ? this._off(t[s]) : this._off(t[s], e, i); } return this; }, // attach listener (without syntactic sugar now) _on: function(t, e, i, n) { if (typeof e != "function") { console.warn("wrong listener type: " + typeof e); return; } if (this._listens(t, e, i) === !1) { i === this && (i = void 0); var o = { fn: e, ctx: i }; n && (o.once = !0), this._events = this._events || {}, this._events[t] = this._events[t] || [], this._events[t].push(o); } }, _off: function(t, e, i) { var n, o, s; if (this._events && (n = this._events[t], !!n)) { if (arguments.length === 1) { if (this._firingCount) for (o = 0, s = n.length; o < s; o++) n[o].fn = z; delete this._events[t]; return; } if (typeof e != "function") { console.warn("wrong listener type: " + typeof e); return; } var r = this._listens(t, e, i); if (r !== !1) { var a = n[r]; this._firingCount && (a.fn = z, this._events[t] = n = n.slice()), n.splice(r, 1); } } }, // @method fire(type: String, data?: Object, propagate?: Boolean): this // Fires an event of the specified type. You can optionally provide a data // object — the first argument of the listener function will contain its // properties. The event can optionally be propagated to event parents. fire: function(t, e, i) { if (!this.listens(t, i)) return this; var n = m({}, e, { type: t, target: this, sourceTarget: e && e.sourceTarget || this }); if (this._events) { var o = this._events[t]; if (o) { this._firingCount = this._firingCount + 1 || 1; for (var s = 0, r = o.length; s < r; s++) { var a = o[s], h = a.fn; a.once && this.off(t, h, a.ctx), h.call(a.ctx || this, n); } this._firingCount--; } } return i && this._propagateEvent(n), this; }, // @method listens(type: String, propagate?: Boolean): Boolean // @method listens(type: String, fn: Function, context?: Object, propagate?: Boolean): Boolean // Returns `true` if a particular event type has any listeners attached to it. // The verification can optionally be propagated, it will return `true` if parents have the listener attached to it. listens: function(t, e, i, n) { typeof t != "string" && console.warn('"string" type argument expected'); var o = e; typeof e != "function" && (n = !!e, o = void 0, i = void 0); var s = this._events && this._events[t]; if (s && s.length && this._listens(t, o, i) !== !1) return !0; if (n) { for (var r in this._eventParents) if (this._eventParents[r].listens(t, e, i, n)) return !0; } return !1; }, // returns the index (number) or false _listens: function(t, e, i) { if (!this._events) return !1; var n = this._events[t] || []; if (!e) return !!n.length; i === this && (i = void 0); for (var o = 0, s = n.length; o < s; o++) if (n[o].fn === e && n[o].ctx === i) return o; return !1; }, // @method once(…): this // Behaves as [`on(…)`](#evented-on), except the listener will only get fired once and then removed. once: function(t, e, i) { if (typeof t == "object") for (var n in t) this._on(n, t[n], e, !0); else { t = T(t); for (var o = 0, s = t.length; o < s; o++) this._on(t[o], e, i, !0); } return this; }, // @method addEventParent(obj: Evented): this // Adds an event parent - an `Evented` that will receive propagated events addEventParent: function(t) { return this._eventParents = this._eventParents || {}, this._eventParents[p(t)] = t, this; }, // @method removeEventParent(obj: Evented): this // Removes an event parent, so it will stop receiving propagated events removeEventParent: function(t) { return this._eventParents && delete this._eventParents[p(t)], this; }, _propagateEvent: function(t) { for (var e in this._eventParents) this._eventParents[e].fire(t.type, m({ layer: t.target, propagatedFrom: t.target }, t), !0); } }; ut.addEventListener = ut.on, ut.removeEventListener = ut.clearAllEventListeners = ut.off, ut.addOneTimeEventListener = ut.once, ut.fireEvent = ut.fire, ut.hasEventListeners = ut.listens; var Yt = bt.extend(ut); function g(t, e, i) { this.x = i ? Math.round(t) : t, this.y = i ? Math.round(e) : e; } var pi = Math.trunc || function(t) { return t > 0 ? Math.floor(t) : Math.ceil(t); }; g.prototype = { // @method clone(): Point // Returns a copy of the current point. clone: function() { return new g(this.x, this.y); }, // @method add(otherPoint: Point): Point // Returns the result of addition of the current and the given points. add: function(t) { return this.clone()._add(v(t)); }, _add: function(t) { return this.x += t.x, this.y += t.y, this; }, // @method subtract(otherPoint: Point): Point // Returns the result of subtraction of the given point from the current. subtract: function(t) { return this.clone()._subtract(v(t)); }, _subtract: function(t) { return this.x -= t.x, this.y -= t.y, this; }, // @method divideBy(num: Number): Point // Returns the result of division of the current point by the given number. divideBy: function(t) { return this.clone()._divideBy(t); }, _divideBy: function(t) { return this.x /= t, this.y /= t, this; }, // @method multiplyBy(num: Number): Point // Returns the result of multiplication of the current point by the given number. multiplyBy: function(t) { return this.clone()._multiplyBy(t); }, _multiplyBy: function(t) { return this.x *= t, this.y *= t, this; }, // @method scaleBy(scale: Point): Point // Multiply each coordinate of the current point by each coordinate of // `scale`. In linear algebra terms, multiply the point by the // [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation) // defined by `scale`. scaleBy: function(t) { return new g(this.x * t.x, this.y * t.y); }, // @method unscaleBy(scale: Point): Point // Inverse of `scaleBy`. Divide each coordinate of the current point by // each coordinate of `scale`. unscaleBy: function(t) { return new g(this.x / t.x, this.y / t.y); }, // @method round(): Point // Returns a copy of the current point with rounded coordinates. round: function() { return this.clone()._round(); }, _round: function() { return this.x = Math.round(this.x), this.y = Math.round(this.y), this; }, // @method floor(): Point // Returns a copy of the current point with floored coordinates (rounded down). floor: function() { return this.clone()._floor(); }, _floor: function() { return this.x = Math.floor(this.x), this.y = Math.floor(this.y), this; }, // @method ceil(): Point // Returns a copy of the current point with ceiled coordinates (rounded up). ceil: function() { return this.clone()._ceil(); }, _ceil: function() { return this.x = Math.ceil(this.x), this.y = Math.ceil(this.y), this; }, // @method trunc(): Point // Returns a copy of the current point with truncated coordinates (rounded towards zero). trunc: function() { return this.clone()._trunc(); }, _trunc: function() { return this.x = pi(this.x), this.y = pi(this.y), this; }, // @method distanceTo(otherPoint: Point): Number // Returns the cartesian distance between the current and the given points. distanceTo: function(t) { t = v(t); var e = t.x - this.x, i = t.y - this.y; return Math.sqrt(e * e + i * i); }, // @method equals(otherPoint: Point): Boolean // Returns `true` if the given point has the same coordinates. equals: function(t) { return t = v(t), t.x === this.x && t.y === this.y; }, // @method contains(otherPoint: Point): Boolean // Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values). contains: function(t) { return t = v(t), Math.abs(t.x) <= Math.abs(this.x) && Math.abs(t.y) <= Math.abs(this.y); }, // @method toString(): String // Returns a string representation of the point for debugging purposes. toString: function() { return "Point(" + B(this.x) + ", " + B(this.y) + ")"; } }; function v(t, e, i) { return t instanceof g ? t : E(t) ? new g(t[0], t[1]) : t == null ? t : typeof t == "object" && "x" in t && "y" in t ? new g(t.x, t.y) : new g(t, e, i); } function A(t, e) { if (t) for (var i = e ? [t, e] : t, n = 0, o = i.length; n < o; n++) this.extend(i[n]); } A.prototype = { // @method extend(point: Point): this // Extends the bounds to contain the given point. // @alternative // @method extend(otherBounds: Bounds): this // Extend the bounds to contain the given bounds extend: function(t) { var e, i; if (!t) return this; if (t instanceof g || typeof t[0] == "number" || "x" in t) e = i = v(t); else if (t = rt(t), e = t.min, i = t.max, !e || !i) return this; return !this.min && !this.max ? (this.min = e.clone(), this.max = i.clone()) : (this.min.x = Math.min(e.x, this.min.x), this.max.x = Math.max(i.x, this.max.x), this.min.y = Math.min(e.y, this.min.y), this.max.y = Math.max(i.y, this.max.y)), this; }, // @method getCenter(round?: Boolean): Point // Returns the center point of the bounds. getCenter: function(t) { return v( (this.min.x + this.max.x) / 2, (this.min.y + this.max.y) / 2, t ); }, // @method getBottomLeft(): Point // Returns the bottom-left point of the bounds. getBottomLeft: function() { return v(this.min.x, this.max.y); }, // @method getTopRight(): Point // Returns the top-right point of the bounds. getTopRight: function() { return v(this.max.x, this.min.y); }, // @method getTopLeft(): Point // Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)). getTopLeft: function() { return this.min; }, // @method getBottomRight(): Point // Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)). getBottomRight: function() { return this.max; }, // @method getSize(): Point // Returns the size of the given bounds getSize: function() { return this.max.subtract(this.min); }, // @method contains(otherBounds: Bounds): Boolean // Returns `true` if the rectangle contains the given one. // @alternative // @method contains(point: Point): Boolean // Returns `true` if the rectangle contains the given point. contains: function(t) { var e, i; return typeof t[0] == "number" || t instanceof g ? t = v(t) : t = rt(t), t instanceof A ? (e = t.min, i = t.max) : e = i = t, e.x >= this.min.x && i.x <= this.max.x && e.y >= this.min.y && i.y <= this.max.y; }, // @method intersects(otherBounds: Bounds): Boolean // Returns `true` if the rectangle intersects the given bounds. Two bounds // intersect if they have at least one point in common. intersects: function(t) { t = rt(t); var e = this.min, i = this.max, n = t.min, o = t.max, s = o.x >= e.x && n.x <= i.x, r = o.y >= e.y && n.y <= i.y; return s && r; }, // @method overlaps(otherBounds: Bounds): Boolean // Returns `true` if the rectangle overlaps the given bounds. Two bounds // overlap if their intersection is an area. overlaps: function(t) { t = rt(t); var e = this.min, i = this.max, n = t.min, o = t.max, s = o.x > e.x && n.x < i.x, r = o.y > e.y && n.y < i.y; return s && r; }, // @method isValid(): Boolean // Returns `true` if the bounds are properly initialized. isValid: function() { return !!(this.min && this.max); }, // @method pad(bufferRatio: Number): Bounds // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction. // For example, a ratio of 0.5 extends the bounds by 50% in each direction. // Negative values will retract the bounds. pad: function(t) { var e = this.min, i = this.max, n = Math.abs(e.x - i.x) * t, o = Math.abs(e.y - i.y) * t; return rt( v(e.x - n, e.y - o), v(i.x + n, i.y + o) ); }, // @method equals(otherBounds: Bounds): Boolean // Returns `true` if the rectangle is equivalent to the given bounds. equals: function(t) { return t ? (t = rt(t), this.min.equals(t.getTopLeft()) && this.max.equals(t.getBottomRight())) : !1; } }; function rt(t, e) { return !t || t instanceof A ? t : new A(t, e); } function at(t, e) { if (t) for (var i = e ? [t, e] : t, n = 0, o = i.length; n < o; n++) this.extend(i[n]); } at.prototype = { // @method extend(latlng: LatLng): this // Extend the bounds to contain the given point // @alternative // @method extend(otherBounds: LatLngBounds): this // Extend the bounds to contain the given bounds extend: function(t) { var e = this._southWest, i = this._northEast, n, o; if (t instanceof I) n = t, o = t; else if (t instanceof at) { if (n = t._southWest, o = t._northEast, !n || !o) return this; } else return t ? this.extend(M(t) || W(t)) : this; return !e && !i ? (this._southWest = new I(n.lat, n.lng), this._northEast = new I(o.lat, o.lng)) : (e.lat = Math.min(n.lat, e.lat), e.lng = Math.min(n.lng, e.lng), i.lat = Math.max(o.lat, i.lat), i.lng = Math.max(o.lng, i.lng)), this; }, // @method pad(bufferRatio: Number): LatLngBounds // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction. // For example, a ratio of 0.5 extends the bounds by 50% in each direction. // Negative values will retract the bounds. pad: function(t) { var e = this._southWest, i = this._northEast, n = Math.abs(e.lat - i.lat) * t, o = Math.abs(e.lng - i.lng) * t; return new at( new I(e.lat - n, e.lng - o), new I(i.lat + n, i.lng + o) ); }, // @method getCenter(): LatLng // Returns the center point of the bounds. getCenter: function() { return new I( (this._southWest.lat + this._northEast.lat) / 2, (this._southWest.lng + this._northEast.lng) / 2 ); }, // @method getSouthWest(): LatLng // Returns the south-west point of the bounds. getSouthWest: function() { return this._southWest; }, // @method getNorthEast(): LatLng // Returns the north-east point of the bounds. getNorthEast: function() { return this._northEast; }, // @method getNorthWest(): LatLng // Returns the north-west point of the bounds. getNorthWest: function() { return new I(this.getNorth(), this.getWest()); }, // @method getSouthEast(): LatLng // Returns the south-east point of the bounds. getSouthEast: function() { return new I(this.getSouth(), this.getEast()); }, // @method getWest(): Number // Returns the west longitude of the bounds getWest: function() { return this._southWest.lng; }, // @method getSouth(): Number // Returns the south latitude of the bounds getSouth: function() { return this._southWest.lat; }, // @method getEast(): Number // Returns the east longitude of the bounds getEast: function() { return this._northEast.lng; }, // @method getNorth(): Number // Returns the north latitude of the bounds getNorth: function() { return this._northEast.lat; }, // @method contains(otherBounds: LatLngBounds): Boolean // Returns `true` if the rectangle contains the given one. // @alternative // @method contains (latlng: LatLng): Boolean // Returns `true` if the rectangle contains the given point. contains: function(t) { typeof t[0] == "number" || t instanceof I || "lat" in t ? t = M(t) : t = W(t); var e = this._southWest, i = this._northEast, n, o; return t instanceof at ? (n = t.getSouthWest(), o = t.getNorthEast()) : n = o = t, n.lat >= e.lat && o.lat <= i.lat && n.lng >= e.lng && o.lng <= i.lng; }, // @method intersects(otherBounds: LatLngBounds): Boolean // Returns `true` if the rectangle intersects the given bounds. Two bounds intersect if they have at least one point in common. intersects: function(t) { t = W(t); var e = this._southWest, i = this._northEast, n = t.getSouthWest(), o = t.getNorthEast(), s = o.lat >= e.lat && n.lat <= i.lat, r = o.lng >= e.lng && n.lng <= i.lng; return s && r; }, // @method overlaps(otherBounds: LatLngBounds): Boolean // Returns `true` if the rectangle overlaps the given bounds. Two bounds overlap if their intersection is an area. overlaps: function(t) { t = W(t); var e = this._southWest, i = this._northEast, n = t.getSouthWest(), o = t.getNorthEast(), s = o.lat > e.lat && n.lat < i.lat, r = o.lng > e.lng && n.lng < i.lng; return s && r; }, // @method toBBoxString(): String // Returns a string with bounding box coordinates in a 'southwest_lng,southwest_lat,northeast_lng,northeast_lat' format. Useful for sending requests to web services that return geo data. toBBoxString: function() { return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(","); }, // @method equals(otherBounds: LatLngBounds, maxMargin?: Number): Boolean // Returns `true` if the rectangle is equivalent (within a small margin of error) to the given bounds. The margin of error can be overridden by setting `maxMargin` to a small number. equals: function(t, e) { return t ? (t = W(t), this._southWest.equals(t.getSouthWest(), e) && this._northEast.equals(t.getNorthEast(), e)) : !1; }, // @method isValid(): Boolean // Returns `true` if the bounds are properly initialized. isValid: function() { return !!(this._southWest && this._northEast); } }; function W(t, e) { return t instanceof at ? t : new at(t, e); } function I(t, e, i) { if (isNaN(t) || isNaN(e)) throw new Error("Invalid LatLng object: (" + t + ", " + e + ")"); this.lat = +t, this.lng = +e, i !== void 0 && (this.alt = +i); } I.prototype = { // @method equals(otherLatLng: LatLng, maxMargin?: Number): Boolean // Returns `true` if the given `LatLng` point is at the same position (within a small margin of error). The margin of error can be overridden by setting `maxMargin` to a small number. equals: function(t, e) { if (!t) return !1; t = M(t); var i = Math.max( Math.abs(this.lat - t.lat), Math.abs(this.lng - t.lng) ); return i <= (e === void 0 ? 1e-9 : e); }, // @method toString(): String // Returns a string representation of the point (for debugging purposes). toString: function(t) { return "LatLng(" + B(this.lat, t) + ", " + B(this.lng, t) + ")"; }, // @method distanceTo(otherLatLng: LatLng): Number // Returns the distance (in meters) to the given `LatLng` calculated using the [Spherical Law of Cosines](https://en.wikipedia.org/wiki/Spherical_law_of_cosines). distanceTo: function(t) { return It.distance(this, M(t)); }, // @method wrap(): LatLng // Returns a new `LatLng` object with the longitude wrapped so it's always between -180 and +180 degrees. wrap: function() { return It.wrapLatLng(this); }, // @method toBounds(sizeInMeters: Number): LatLngBounds // Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`. toBounds: function(t) { var e = 180 * t / 40075017, i = e / Math.cos(Math.PI / 180 * this.lat); return W( [this.lat - e, this.lng - i], [this.lat + e, this.lng + i] ); }, clone: function() { return new I(this.lat, this.lng, this.alt); } }; function M(t, e, i) { return t instanceof I ? t : E(t) && typeof t[0] != "object" ? t.length === 3 ? new I(t[0], t[1], t[2]) : t.length === 2 ? new I(t[0], t[1]) : null : t == null ? t : typeof t == "object" && "lat" in t ? new I(t.lat, "lng" in t ? t.lng : t.lon, t.alt) : e === void 0 ? null : new I(t, e, i); } var Mt = { // @method latLngToPoint(latlng: LatLng, zoom: Number): Point // Projects geographical coordinates into pixel coordinates for a given zoom. latLngToPoint: function(t, e) { var i = this.projection.project(t), n = this.scale(e); return this.transformation._transform(i, n); }, // @method pointToLatLng(point: Point, zoom: Number): LatLng // The inverse of `latLngToPoint`. Projects pixel coordinates on a given // zoom into geographical coordinates. pointToLatLng: function(t, e) { var i = this.scale(e), n = this.transformation.untransform(t, i); return this.projection.unproject(n); }, // @method project(latlng: LatLng): Point // Projects geographical coordinates into coordinates in units accepted for // this CRS (e.g. meters for EPSG:3857, for passing it to WMS services). project: function(t) { return this.projection.project(t); }, // @method unproject(point: Point): LatLng // Given a projected coordinate returns the corresponding LatLng. // The inverse of `project`. unproject: function(t) { return this.projection.unproject(t); }, // @method scale(zoom: Number): Number // Returns the scale used when transforming projected coordinates into // pixel coordinates for a particular zoom. For example, it returns // `256 * 2^zoom` for Mercator-based CRS. scale: function(t) { return 256 * Math.pow(2, t); }, // @method zoom(scale: Number): Number // Inverse of `scale()`, returns the zoom level corresponding to a scale // factor of `scale`. zoom: function(t) { return Math.log(t / 256) / Math.LN2; }, // @method getProjectedBounds(zoom: Number): Bounds // Returns the projection's bounds scaled and transformed for the provided `zoom`. getProjectedBounds: function(t) { if (this.infinite) return null; var e = this.projection.bounds, i = this.scale(t), n = this.transformation.transform(e.min, i), o = this.transformation.transform(e.max, i); return new A(n, o); }, // @method distance(latlng1: LatLng, latlng2: LatLng): Number // Returns the distance between two geographical coordinates. // @property code: String // Standard code name of the CRS passed into WMS services (e.g. `'EPSG:3857'`) // // @property wrapLng: Number[] // An array of two numbers defining whether the longitude (horizontal) coordinate // axis wraps around a given range and how. Defaults to `[-180, 180]` in most // geographical CRSs. If `undefined`, the longitude axis does not wrap around. // // @property wrapLat: Number[] // Like `wrapLng`, but for the latitude (vertical) axis. // wrapLng: [min, max], // wrapLat: [min, max], // @property infinite: Boolean // If true, the coordinate space will be unbounded (infinite in both axes) infinite: !1, // @method wrapLatLng(latlng: LatLng): LatLng // Returns a `LatLng` where lat and lng has been wrapped according to the // CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds. wrapLatLng: function(t) { var e = this.wrapLng ? $(t.lng, this.wrapLng, !0) : t.lng, i = this.wrapLat ? $(t.lat, this.wrapLat, !0) : t.lat, n = t.alt; return new I(i, e, n); }, // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds // Returns a `LatLngBounds` with the same size as the given one, ensuring // that its center is within the CRS's bounds. // Only accepts actual `L.LatLngBounds` instances, not arrays. wrapLatLngBounds: function(t) { var e = t.getCenter(), i = this.wrapLatLng(e), n = e.lat - i.lat, o = e.lng - i.lng; if (n === 0 && o === 0) return t; var s = t.getSouthWest(), r = t.getNorthEast(), a = new I(s.lat - n, s.lng - o), h = new I(r.lat - n, r.lng - o); return new at(a, h); } }, It = m({}, Mt, { wrapLng: [-180, 180], // Mean Earth Radius, as recommended for use by // the International Union of Geodesy and Geophysics, // see https://rosettacode.org/wiki/Haversine_formula R: 6371e3, // distance between two geographical points using spherical law of cosines approximation distance: function(t, e) { var i = Math.PI / 180, n = t.lat * i, o = e.lat * i, s = Math.sin((e.lat - t.lat) * i / 2), r = Math.sin((e.lng - t.lng) * i / 2), a = s * s + Math.cos(n) * Math.cos(o) * r * r, h = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return this.R * h; } }), vi = 6378137, Ee = { R: vi, MAX_LATITUDE: 85.0511287798, project: function(t) { var e = Math.PI / 180, i = this.MAX_LATITUDE, n = Math.max(Math.min(i, t.lat), -i), o = Math.sin(n * e); return new g( this.R * t.lng * e, this.R * Math.log((1 + o) / (1 - o)) / 2 ); }, unproject: function(t) { var e = 180 / Math.PI; return new I( (2 * Math.atan(Math.exp(t.y / this.R)) - Math.PI / 2) * e, t.x * e / this.R ); }, bounds: function() { var t = vi * Math.PI; return new A([-t, -t], [t, t]); }() }; function Ie(t, e, i, n) { if (E(t)) { this._a = t[0], this._b = t[1], this._c = t[2], this._d = t[3]; return; } this._a = t, this._b = e, this._c = i, this._d = n; } Ie.prototype = { // @method transform(point: Point, scale?: Number): Point // Returns a transformed point, optionally multiplied by the given scale. // Only accepts actual `L.Point` instances, not arrays. transform: function(t, e) { return this._transform(t.clone(), e); }, // destructive transform (faster) _transform: function(t, e) { return e = e || 1, t.x = e * (this._a * t.x + this._b), t.y = e * (this._c * t.y + this._d), t; }, // @method untransform(point: Point, scale?: Number): Point // Returns the reverse transformation of the given point, optionally divided // by the given scale. Only accepts actual `L.Point` instances, not arrays. untransform: function(t, e) { return e = e || 1, new g( (t.x / e - this._b) / this._a, (t.y / e - this._d) / this._c ); } }; function $t(t, e, i, n) { return new Ie(t, e, i, n); } var Ze = m({}, It, { code: "EPSG:3857", projection: Ee, transformation: function() { var t = 0.5 / (Math.PI * Ee.R); return $t(t, 0.5, -t, 0.5); }() }), Bn = m({}, Ze, { code: "EPSG:900913" }); function gi(t) { return document.createElementNS("http://www.w3.org/2000/svg", t); } function yi(t, e) { var i = "", n, o, s, r, a, h; for (n = 0, s = t.length; n < s; n++) { for (a = t[n], o = 0, r = a.length; o < r; o++) h = a[o], i += (o ? "L" : "M") + h.x + " " + h.y; i += e ? f.svg ? "z" : "x" : ""; } return i || "M0 0"; } var Oe = document.documentElement.style, le = "ActiveXObject" in window, An = le && !document.addEventListener, wi = "msLaunchUri" in navigator && !("documentMode" in document), Be = yt("webkit"), xi = yt("android"), Pi = yt("android 2") || yt("android 3"), Rn = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10), Nn = xi && yt("Google") && Rn < 537 && !("AudioNode" in window), Ae = !!window.opera, Li = !wi && yt("chrome"), Ti = yt("gecko") && !Be && !Ae && !le, Dn = !Li && yt("safari"), bi = yt("phantom"), Mi = "OTransition" in Oe, Fn = navigator.platform.indexOf("Win") === 0, Si = le && "transition" in Oe, Re = "WebKitCSSMatrix" in window && "m11" in new window.WebKitCSSMatrix() && !Pi, Ci = "MozPerspective" in Oe, Hn = !window.L_DISABLE_3D && (Si || Re || Ci) && !Mi && !bi, Jt = typeof orientation < "u" || yt("mobile"), Wn = Jt && Be, Un = Jt && Re, zi = !window.PointerEvent && window.MSPointerEvent, ki = !!(window.PointerEvent || zi), Ei = "ontouchstart" in window || !!window.TouchEvent, Vn = !window.L_NO_TOUCH && (Ei || ki), Gn = Jt && Ae, qn = Jt && Ti, jn = (window.devicePixelRatio || window.screen.deviceXDPI / window.screen.logicalXDPI) > 1, Kn = function() { var t = !1; try { var e = Object.defineProperty({}, "passive", { get: function() { t = !0; } }); window.addEventListener("testPassiveEventSupport", z, e), window.removeEventListener("testPassiveEventSupport", z, e); } catch { } return t; }(), Yn = function() { return !!document.createElement("canvas").getContext; }(), Ne = !!(document.createElementNS && gi("svg").createSVGRect), $n = !!Ne && function() { var t = document.createElement("div"); return t.innerHTML = "<svg/>", (t.firstChild && t.firstChild.namespaceURI) === "http://www.w3.org/2000/svg"; }(), Jn = !Ne && function() { try { var t = document.createElement("div"); t.innerHTML = '<v:shape adj="1"/>';