@rsltda/components 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1145 @@
1
+ var D = Object.defineProperty;
2
+ var q = (C, b, e) => b in C ? D(C, b, { enumerable: !0, configurable: !0, writable: !0, value: e }) : C[b] = e;
3
+ var s = (C, b, e) => q(C, typeof b != "symbol" ? b + "" : b, e);
4
+ function U(C, b) {
5
+ customElements.get(C) || customElements.define(C, b);
6
+ }
7
+ const I = "#1e88e5", L = "/assets/fontawesome/css/all.min.css", F = "https://cdn.rsltda.cl/logos/marker/", Z = "https://ap2.rs-shop.cl/web/PuntosMapas", O = {
8
+ ktm: "#ff6600"
9
+ }, M = {
10
+ sucursal: 0,
11
+ distribuidor: 1
12
+ }, R = ["norte", "rm", "centro", "sur"], $ = {
13
+ norte: "Zona Norte",
14
+ rm: "RM",
15
+ centro: "Zona Centro",
16
+ sur: "Zona Sur"
17
+ }, N = {
18
+ 0: "Sucursales",
19
+ 1: "Distribuidores"
20
+ }, T = 720 * 60 * 60 * 1e3, G = "rs-map-cache", P = "points", B = {
21
+ "region de arica y parinacota": "norte",
22
+ "arica y parinacota": "norte",
23
+ "region de tarapaca": "norte",
24
+ tarapaca: "norte",
25
+ "region de antofagasta": "norte",
26
+ antofagasta: "norte",
27
+ "region de atacama": "norte",
28
+ atacama: "norte",
29
+ "region de coquimbo": "norte",
30
+ coquimbo: "norte",
31
+ "region de valparaiso": "centro",
32
+ valparaiso: "centro",
33
+ "region del libertador general bernardo o higgins": "centro",
34
+ "region del libertador general bernardo o'higgins": "centro",
35
+ "libertador bernardo o'higgins": "centro",
36
+ ohiggins: "centro",
37
+ "region del maule": "centro",
38
+ maule: "centro",
39
+ "region de nuble": "centro",
40
+ nuble: "centro",
41
+ "region del biobio": "centro",
42
+ biobio: "centro",
43
+ "region metropolitana de santiago": "rm",
44
+ "region metropolitana": "rm",
45
+ rm: "rm",
46
+ santiago: "rm",
47
+ "region de la araucania": "sur",
48
+ araucania: "sur",
49
+ "region de los rios": "sur",
50
+ "los rios": "sur",
51
+ "region de los lagos": "sur",
52
+ "los lagos": "sur",
53
+ "region de aysen del general carlos ibanez del campo": "sur",
54
+ "region de aysen": "sur",
55
+ aysen: "sur",
56
+ "region de magallanes y la antartica chilena": "sur",
57
+ magallanes: "sur"
58
+ }, m = class m extends HTMLElement {
59
+ constructor() {
60
+ super();
61
+ s(this, "root");
62
+ s(this, "mapEl");
63
+ s(this, "map");
64
+ s(this, "markers", []);
65
+ s(this, "marca", "");
66
+ s(this, "marcaKey", "default");
67
+ s(this, "tipo", "");
68
+ s(this, "tipoCode", null);
69
+ s(this, "pointsController");
70
+ s(this, "points", []);
71
+ s(this, "pointsByZone", {
72
+ norte: [],
73
+ rm: [],
74
+ centro: [],
75
+ sur: []
76
+ });
77
+ s(this, "initialViewApplied", !1);
78
+ s(this, "zonesContainer");
79
+ s(this, "componentMessageEl");
80
+ s(this, "mapLayoutEl");
81
+ s(this, "zoneButtons", []);
82
+ s(this, "nearestButton");
83
+ s(this, "panelTitleEl");
84
+ s(this, "activeZone", "all");
85
+ s(this, "mapHeight", "");
86
+ s(this, "googleMapsApiKey", "");
87
+ s(this, "pointsApiUrl", Z);
88
+ s(this, "markerIconBaseUrl", F);
89
+ s(this, "defaultMarkerIconUrl", "");
90
+ s(this, "pointsCacheTtlMs", T);
91
+ s(this, "panAnimationFrame", null);
92
+ s(this, "highlightTimeout", null);
93
+ s(this, "isSyncingInitialAttributes", !1);
94
+ s(this, "refreshQueued", !1);
95
+ s(this, "handleZoneButtonClick", (e) => {
96
+ const n = e.currentTarget.dataset.zone;
97
+ n && (this.setActiveZone(n), this.scrollToZoneSection(n));
98
+ });
99
+ s(this, "handleNearestClick", () => {
100
+ if (!navigator.geolocation) {
101
+ alert("La geolocalizacion no esta soportada en este navegador.");
102
+ return;
103
+ }
104
+ navigator.geolocation.getCurrentPosition(
105
+ (e) => {
106
+ const { latitude: t, longitude: n } = e.coords, a = this.findNearestPoint(t, n);
107
+ a ? (this.centerMapOnPoint(Number(a.lat), Number(a.lng)), this.scrollToPointCard(a.id)) : alert("No hay puntos disponibles para calcular la tienda cercana.");
108
+ },
109
+ () => {
110
+ alert("No se pudo obtener tu ubicacion.");
111
+ }
112
+ );
113
+ });
114
+ m.ensureFontAwesome(), this.root = this.attachShadow({ mode: "open" }), this.root.innerHTML = `
115
+ <link rel="stylesheet" href="${L}" />
116
+ <style>
117
+ :host {
118
+ display: block;
119
+ width: 100%;
120
+ height: var(--map-height, 520px);
121
+ --rs-map-accent: ${I};
122
+ }
123
+ .map-layout {
124
+ display: grid;
125
+ grid-template-columns: minmax(0, 2.5fr) minmax(220px, 1fr);
126
+ gap: 16px;
127
+ width: 100%;
128
+ height: 100%;
129
+ }
130
+ .map-panel,
131
+ #map {
132
+ width: 100%;
133
+ height: 100%;
134
+ animation: mapSlide 90s infinite;
135
+ animation-timing-function: ease-in-out;
136
+ }
137
+ .map-panel {
138
+ border-radius: 8px;
139
+ overflow: hidden;
140
+ border: 2px solid var(--rs-map-accent);
141
+ }
142
+ #map {
143
+ background: #f5f5f5;
144
+ }
145
+ .component-shell {
146
+ display: flex;
147
+ flex-direction: column;
148
+ height: 100%;
149
+ }
150
+ .component-message {
151
+ margin: 0;
152
+ font-size: 1rem;
153
+ color: #555;
154
+ text-align: center;
155
+ padding: 24px 12px;
156
+ display: flex;
157
+ align-items: center;
158
+ justify-content: center;
159
+ flex: 1;
160
+ }
161
+ .component-message[hidden] {
162
+ display: none;
163
+ }
164
+ .map-layout[hidden] {
165
+ display: none;
166
+ }
167
+ .points-panel {
168
+ border: 1px solid #e0e0e0;
169
+ border-radius: 8px;
170
+ border-top: 4px solid var(--rs-map-accent);
171
+ padding: 16px;
172
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
173
+ background: #fff;
174
+ display: flex;
175
+ flex-direction: column;
176
+ overflow: hidden;
177
+ }
178
+ .panel-message {
179
+ margin: 0;
180
+ font-size: 0.95rem;
181
+ color: #555;
182
+ text-align: center;
183
+ padding: 32px 12px;
184
+ }
185
+ .panel-content[hidden] {
186
+ display: none;
187
+ }
188
+ .points-panel h2 {
189
+ margin: 0 0 8px;
190
+ font-size: 1rem;
191
+ color: var(--rs-map-accent);
192
+ }
193
+ .zone-filters {
194
+ display: flex;
195
+ gap: 8px;
196
+ margin-bottom: 12px;
197
+ overflow-x: auto;
198
+ padding-bottom: 8px;
199
+ flex-wrap: nowrap;
200
+ }
201
+ .zone-button {
202
+ border: 1px solid var(--rs-map-accent);
203
+ border-radius: 999px;
204
+ padding: 6px 12px;
205
+ font-size: 0.85rem;
206
+ background: transparent;
207
+ color: var(--rs-map-accent);
208
+ cursor: pointer;
209
+ transition: background 0.2s ease, color 0.2s ease;
210
+ text-align: center;
211
+ white-space: nowrap;
212
+ }
213
+ .zone-button:hover,
214
+ .zone-button:focus-visible {
215
+ background: var(--rs-map-accent);
216
+ color: #fff;
217
+ }
218
+ .zone-button.is-active {
219
+ background: var(--rs-map-accent);
220
+ color: #fff;
221
+ }
222
+ .zone-button--secondary {
223
+ flex-shrink: 0;
224
+ border-color: #444;
225
+ color: #444;
226
+ }
227
+ .zone-button--secondary i {
228
+ margin-right: 6px;
229
+ }
230
+ .panel-header {
231
+ margin-bottom: 12px;
232
+ display: flex;
233
+ align-items: center;
234
+ justify-content: space-between;
235
+ gap: 12px;
236
+ }
237
+ .panel-header h2[data-panel-title] {
238
+ margin: 0;
239
+ font-size: 1.25rem;
240
+ }
241
+ .zones-container {
242
+ display: flex;
243
+ flex-direction: column;
244
+ gap: 16px;
245
+ flex: 1;
246
+ overflow-y: auto;
247
+ }
248
+ .zone-section {
249
+ border-top: 2px solid #eee;
250
+ padding-top: 12px;
251
+ }
252
+ .zone-section[hidden] {
253
+ display: none;
254
+ }
255
+ .zone-section__header {
256
+ display: flex;
257
+ align-items: baseline;
258
+ justify-content: space-between;
259
+ margin: 0 0 8px;
260
+ font-weight: 600;
261
+ color: #333;
262
+ }
263
+ .zone-section__empty {
264
+ margin: 0;
265
+ font-size: 0.85rem;
266
+ color: #777;
267
+ }
268
+ .zone-section__list {
269
+ display: flex;
270
+ flex-direction: column;
271
+ gap: 10px;
272
+ }
273
+ .point-card {
274
+ border: 1px solid #e6e6e6;
275
+ border-radius: 8px;
276
+ padding: 10px;
277
+ background: #fff;
278
+ display: flex;
279
+ flex-direction: column;
280
+ gap: 6px;
281
+ overflow: hidden;
282
+ transition: border 0.2s ease, box-shadow 0.2s ease;
283
+ }
284
+ .point-card--highlight {
285
+ border: 2px solid var(--rs-map-accent);
286
+ box-shadow: 0 0 0 2px rgba(30, 136, 229, 0.2);
287
+ animation: highlightFade 3s forwards;
288
+ }
289
+ @keyframes highlightFade {
290
+ 0% {
291
+ border-color: var(--rs-map-accent);
292
+ box-shadow: 0 0 0 2px rgba(30, 136, 229, 0.2);
293
+ }
294
+ 80% {
295
+ border-color: #111;
296
+ box-shadow: 0 0 0 2px rgba(17, 17, 17, 0.2);
297
+ }
298
+ 100% {
299
+ border-color: #e6e6e6;
300
+ box-shadow: none;
301
+ }
302
+ }
303
+ .point-card__title {
304
+ margin: -10px -10px 8px;
305
+ padding: 10px;
306
+ font-size: 0.95rem;
307
+ font-weight: 600;
308
+ text-align: center;
309
+ color: #fff;
310
+ background: var(--rs-map-accent);
311
+ }
312
+ .point-card__focus {
313
+ border: 1px solid var(--rs-map-accent);
314
+ border-radius: 999px;
315
+ padding: 4px 12px;
316
+ font-size: 0.8rem;
317
+ background: transparent;
318
+ color: var(--rs-map-accent);
319
+ cursor: pointer;
320
+ align-self: flex-start;
321
+ margin-top: 8px;
322
+ }
323
+ .point-card__focus:hover,
324
+ .point-card__focus:focus-visible {
325
+ background: var(--rs-map-accent);
326
+ color: #fff;
327
+ }
328
+ @media (max-width: 768px) {
329
+ .map-layout {
330
+ grid-template-columns: 1fr;
331
+ }
332
+ .map-panel {
333
+ display: none;
334
+ }
335
+ .panel-header {
336
+ flex-direction: column;
337
+ align-items: stretch;
338
+ }
339
+ .zone-filters {
340
+ flex-wrap: wrap;
341
+ }
342
+ .point-card__focus {
343
+ display: none;
344
+ }
345
+ }
346
+ .point-card__address,
347
+ .point-card__meta,
348
+ .point-card__contact {
349
+ margin: 0;
350
+ font-size: 0.85rem;
351
+ color: #555;
352
+ }
353
+ .point-card__contact {
354
+ margin: 0 0 6px;
355
+ font-size: 0.85rem;
356
+ color: #555;
357
+ }
358
+ .point-card__contact-title {
359
+ display: flex;
360
+ align-items: center;
361
+ gap: 6px;
362
+ font-weight: 600;
363
+ color: #333;
364
+ margin-bottom: 4px;
365
+ }
366
+ .point-card__phone-list {
367
+ list-style: none;
368
+ padding: 0;
369
+ margin: 0;
370
+ display: flex;
371
+ flex-direction: column;
372
+ gap: 4px;
373
+ }
374
+ .point-card__phone-item {
375
+ display: flex;
376
+ gap: 8px;
377
+ align-items: flex-start;
378
+ }
379
+ .point-card__phone-icon {
380
+ width: 16px;
381
+ display: inline-flex;
382
+ justify-content: center;
383
+ color: var(--rs-map-accent);
384
+ font-size: 0.85rem;
385
+ }
386
+ .point-card__phone-content {
387
+ display: flex;
388
+ flex-direction: column;
389
+ gap: 2px;
390
+ }
391
+ .point-card__phone-name {
392
+ font-weight: 600;
393
+ color: #333;
394
+ }
395
+ .point-card__phone-number {
396
+ font-family: 'Segoe UI', system-ui, sans-serif;
397
+ font-size: 0.85rem;
398
+ }
399
+ .point-card__phone-number--link {
400
+ color: var(--rs-map-accent);
401
+ text-decoration: none;
402
+ }
403
+ .point-card__phone-number--link:hover,
404
+ .point-card__phone-number--link:focus-visible {
405
+ text-decoration: underline;
406
+ }
407
+ .point-card__address-block {
408
+ display: flex;
409
+ flex-direction: column;
410
+ gap: 2px;
411
+ }
412
+ .point-card__details {
413
+ display: flex;
414
+ flex-direction: column;
415
+ gap: 6px;
416
+ margin-top: 6px;
417
+ }
418
+ .point-card__details[hidden] {
419
+ display: none;
420
+ }
421
+ .point-card__toggle {
422
+ border: 1px solid var(--rs-map-accent);
423
+ border-radius: 16px;
424
+ padding: 4px 10px;
425
+ background: transparent;
426
+ color: var(--rs-map-accent);
427
+ font-size: 0.8rem;
428
+ cursor: pointer;
429
+ align-self: flex-start;
430
+ display: inline-flex;
431
+ align-items: center;
432
+ gap: 6px;
433
+ }
434
+ .point-card__toggle:hover,
435
+ .point-card__toggle:focus-visible {
436
+ background: var(--rs-map-accent);
437
+ color: #fff;
438
+ }
439
+ .point-card__actions {
440
+ display: flex;
441
+ flex-direction: column;
442
+ align-items: flex-start;
443
+ gap: 6px;
444
+ margin-top: 8px;
445
+ }
446
+ .point-card__action {
447
+ display: inline-flex;
448
+ align-items: center;
449
+ gap: 6px;
450
+ font-size: 0.8rem;
451
+ }
452
+ .point-card__actions a.point-card__action {
453
+ color: var(--rs-map-accent);
454
+ text-decoration: none;
455
+ border-bottom: 1px solid transparent;
456
+ }
457
+ .point-card__actions a.point-card__action:hover,
458
+ .point-card__actions a.point-card__action:focus-visible {
459
+ border-color: currentColor;
460
+ }
461
+ .point-card__actions .point-card__action i {
462
+ font-size: 0.85rem;
463
+ }
464
+ .point-card__actions .point-card__action--text {
465
+ color: #444;
466
+ }
467
+ .point-card__extra {
468
+ margin: 0;
469
+ font-size: 0.8rem;
470
+ color: #444;
471
+ }
472
+ .point-card__extra a {
473
+ color: var(--rs-map-accent);
474
+ text-decoration: none;
475
+ display: inline-flex;
476
+ align-items: center;
477
+ gap: 4px;
478
+ }
479
+ .point-card__extra a:hover,
480
+ .point-card__extra a:focus-visible {
481
+ color: #444;
482
+ text-decoration: underline;
483
+ }
484
+ .point-card__extra-icon {
485
+ font-size: 0.75rem;
486
+ }
487
+ .empty-state {
488
+ margin: 0;
489
+ font-size: 0.9rem;
490
+ color: #777;
491
+ text-align: center;
492
+ }
493
+ .points-panel p {
494
+ margin: 0;
495
+ color: #666;
496
+ font-size: 0.9rem;
497
+ }
498
+ </style>
499
+ <div class="component-shell">
500
+ <p class="component-message" data-component-message>Cargando puntos...</p>
501
+ <div class="map-layout" data-map-layout hidden>
502
+ <div class="map-panel">
503
+ <div id="map"></div>
504
+ </div>
505
+ <aside class="points-panel" aria-live="polite">
506
+ <div class="zone-filters" role="group" aria-label="Filtrar por zona">
507
+ <button class="zone-button" type="button" data-zone="norte" data-label="Zona Norte" aria-pressed="false">Zona Norte</button>
508
+ <button class="zone-button" type="button" data-zone="rm" data-label="RM" aria-pressed="false">RM</button>
509
+ <button class="zone-button" type="button" data-zone="centro" data-label="Zona Centro" aria-pressed="false">Zona Centro</button>
510
+ <button class="zone-button" type="button" data-zone="sur" data-label="Zona Sur" aria-pressed="false">Zona Sur</button>
511
+ </div>
512
+ <div class="panel-header">
513
+ <h2 data-panel-title>Puntos del mapa</h2>
514
+ <button class="zone-button zone-button--secondary" type="button" data-action="nearest">
515
+ <i class="fa-solid fa-location-dot" aria-hidden="true"></i>
516
+ Buscar tienda cercana
517
+ </button>
518
+ </div>
519
+ <div class="zones-container" data-zone-container></div>
520
+ </aside>
521
+ </div>
522
+ </div>
523
+ `;
524
+ }
525
+ static get observedAttributes() {
526
+ return [
527
+ "marca",
528
+ "tipo",
529
+ "height",
530
+ "google-maps-key",
531
+ "points-api-url",
532
+ "cache-days",
533
+ "marker-icon-base",
534
+ "marker-icon-default"
535
+ ];
536
+ }
537
+ connectedCallback() {
538
+ this.mapEl = this.root.querySelector("#map"), this.panelTitleEl = this.root.querySelector("[data-panel-title]"), this.zonesContainer = this.root.querySelector("[data-zone-container]"), this.componentMessageEl = this.root.querySelector("[data-component-message]"), this.mapLayoutEl = this.root.querySelector("[data-map-layout]"), this.zoneButtons = Array.from(this.root.querySelectorAll("[data-zone]")), this.nearestButton = this.root.querySelector('[data-action="nearest"]'), this.zoneButtons.forEach((e) => e.addEventListener("click", this.handleZoneButtonClick)), this.nearestButton && this.nearestButton.addEventListener("click", this.handleNearestClick), this.updateZoneButtons(), this.setMapHeight(this.getAttribute("height")), this.setComponentState("loading"), this.syncAttributesToState();
539
+ }
540
+ disconnectedCallback() {
541
+ var e;
542
+ (e = this.pointsController) == null || e.abort(), this.zoneButtons.forEach((t) => t.removeEventListener("click", this.handleZoneButtonClick)), this.nearestButton && this.nearestButton.removeEventListener("click", this.handleNearestClick);
543
+ }
544
+ attributeChangedCallback(e, t, n) {
545
+ e === "marca" ? this.setMarca(n != null ? n : "") : e === "tipo" ? this.setTipo(n != null ? n : "") : e === "height" ? this.setMapHeight(n) : e === "google-maps-key" ? this.setGoogleMapsKey(n) : e === "points-api-url" ? this.setPointsApiUrl(n) : e === "cache-days" ? this.setCacheDays(n) : e === "marker-icon-base" ? this.setMarkerIconBase(n) : e === "marker-icon-default" && this.setDefaultMarkerIcon(n);
546
+ }
547
+ loadGoogleMaps() {
548
+ return window._rsGoogleMapsLoaded ? Promise.resolve().then(() => {
549
+ this.initMap();
550
+ }) : this.googleMapsApiKey ? (m.googleMapsLoaderPromise || (m.googleMapsLoaderPromise = new Promise((e, t) => {
551
+ const n = document.querySelector('script[data-rs-google-maps="true"]');
552
+ if (n) {
553
+ n.addEventListener("load", () => e(), { once: !0 }), n.addEventListener(
554
+ "error",
555
+ () => t(new Error("Error al cargar la API de Google Maps")),
556
+ { once: !0 }
557
+ );
558
+ return;
559
+ }
560
+ const a = document.createElement("script"), r = new URLSearchParams({
561
+ key: this.googleMapsApiKey,
562
+ v: "weekly"
563
+ });
564
+ a.src = `https://maps.googleapis.com/maps/api/js?${r.toString()}`, a.async = !0, a.defer = !0, a.dataset.rsGoogleMaps = "true", a.onload = () => {
565
+ window._rsGoogleMapsLoaded = !0, e();
566
+ }, a.onerror = () => {
567
+ m.googleMapsLoaderPromise = null, t(new Error("Error al cargar la API de Google Maps"));
568
+ }, document.head.appendChild(a);
569
+ })), m.googleMapsLoaderPromise.then(() => {
570
+ window._rsGoogleMapsLoaded = !0, this.initMap();
571
+ }).catch((e) => {
572
+ console.error(e instanceof Error ? e.message : "Error al cargar la API de Google Maps");
573
+ })) : (console.error('Falta la clave de Google Maps. Define el atributo "google-maps-key" en <rs-map>.'), Promise.resolve());
574
+ }
575
+ initMap() {
576
+ const e = window.google;
577
+ if (!e) {
578
+ console.error("Google Maps aun no esta disponible.");
579
+ return;
580
+ }
581
+ const t = this.getInitialCenter();
582
+ this.map = new e.maps.Map(this.mapEl, {
583
+ center: t,
584
+ zoom: 14,
585
+ mapTypeId: "roadmap"
586
+ }), this.points.length && this.updateMarkers(this.points);
587
+ }
588
+ getInitialCenter() {
589
+ const e = this.getFirstValidPoint();
590
+ return e || { lat: -33.4489, lng: -70.6693 };
591
+ }
592
+ getFirstValidPoint() {
593
+ for (const e of this.points) {
594
+ const t = Number(e.lat), n = Number(e.lng);
595
+ if (Number.isFinite(t) && Number.isFinite(n))
596
+ return { lat: t, lng: n };
597
+ }
598
+ return null;
599
+ }
600
+ syncAttributesToState() {
601
+ var e, t;
602
+ this.isSyncingInitialAttributes = !0, this.setMarca((e = this.getAttribute("marca")) != null ? e : ""), this.setTipo((t = this.getAttribute("tipo")) != null ? t : ""), this.setGoogleMapsKey(this.getAttribute("google-maps-key")), this.setPointsApiUrl(this.getAttribute("points-api-url")), this.setCacheDays(this.getAttribute("cache-days")), this.setMarkerIconBase(this.getAttribute("marker-icon-base")), this.setDefaultMarkerIcon(this.getAttribute("marker-icon-default")), this.isSyncingInitialAttributes = !1, this.queueRefreshPoints();
603
+ }
604
+ setMapHeight(e) {
605
+ const t = (e != null ? e : "").trim();
606
+ if (!t) {
607
+ this.mapHeight = "", this.style.removeProperty("--map-height");
608
+ return;
609
+ }
610
+ this.mapHeight = t, this.style.setProperty("--map-height", t);
611
+ }
612
+ setGoogleMapsKey(e) {
613
+ this.googleMapsApiKey = (e != null ? e : "").trim(), this.googleMapsApiKey && this.isConnected && this.loadGoogleMaps();
614
+ }
615
+ setPointsApiUrl(e) {
616
+ const t = (e != null ? e : "").trim();
617
+ this.pointsApiUrl = t || Z, this.pointsApiUrl && this.isConnected && !this.isSyncingInitialAttributes && this.queueRefreshPoints();
618
+ }
619
+ setCacheDays(e) {
620
+ const t = (e != null ? e : "").trim();
621
+ if (!t) {
622
+ this.pointsCacheTtlMs = T;
623
+ return;
624
+ }
625
+ const n = Number(t);
626
+ if (!Number.isFinite(n) || n < 0) {
627
+ this.pointsCacheTtlMs = T;
628
+ return;
629
+ }
630
+ this.pointsCacheTtlMs = n * 24 * 60 * 60 * 1e3;
631
+ }
632
+ setMarkerIconBase(e) {
633
+ const t = (e != null ? e : "").trim();
634
+ if (!t) {
635
+ this.markerIconBaseUrl = F;
636
+ return;
637
+ }
638
+ this.markerIconBaseUrl = t.endsWith("/") ? t : `${t}/`;
639
+ }
640
+ setDefaultMarkerIcon(e) {
641
+ this.defaultMarkerIconUrl = (e != null ? e : "").trim();
642
+ }
643
+ setMarca(e) {
644
+ this.marca = e.trim(), this.marcaKey = this.normalizeBrandKey(this.marca), this.applyBrandColor(), this.isSyncingInitialAttributes || this.queueRefreshPoints();
645
+ }
646
+ setTipo(e) {
647
+ this.tipo = e.trim(), this.tipoCode = this.normalizeTipo(this.tipo), this.updatePanelTitle(), this.isSyncingInitialAttributes || this.queueRefreshPoints();
648
+ }
649
+ queueRefreshPoints() {
650
+ this.refreshQueued || (this.refreshQueued = !0, queueMicrotask(() => {
651
+ this.refreshQueued = !1, this.refreshPoints();
652
+ }));
653
+ }
654
+ get marcaFilter() {
655
+ return this.marca;
656
+ }
657
+ get tipoFilter() {
658
+ return this.tipo;
659
+ }
660
+ updatePanelTitle() {
661
+ if (!this.panelTitleEl)
662
+ return;
663
+ const e = this.getTipoLabel();
664
+ this.panelTitleEl.textContent = e != null ? e : "Puntos del mapa";
665
+ }
666
+ getTipoLabel() {
667
+ if (this.tipoCode !== null && this.tipoCode in N)
668
+ return N[this.tipoCode];
669
+ const e = this.tipo.trim().toLowerCase(), t = e && e in M ? M[e] : null;
670
+ return t !== null && t in N ? N[t] : null;
671
+ }
672
+ applyBrandColor() {
673
+ var t;
674
+ const e = (t = O[this.marcaKey]) != null ? t : I;
675
+ this.style.setProperty("--rs-map-accent", e);
676
+ }
677
+ normalizeTipo(e) {
678
+ if (!e)
679
+ return null;
680
+ const t = e.trim().toLowerCase();
681
+ if (t in M)
682
+ return M[t];
683
+ const n = Number(t);
684
+ return Number.isFinite(n) && (n === 0 || n === 1) ? n : null;
685
+ }
686
+ async refreshPoints() {
687
+ var h;
688
+ if (!this.isConnected || !this.marca || this.tipoCode === null)
689
+ return;
690
+ if (!this.pointsApiUrl) {
691
+ console.error('Falta la URL de la API de puntos. Define el atributo "points-api-url" en <rs-map>.'), this.setComponentState("error");
692
+ return;
693
+ }
694
+ (h = this.pointsController) == null || h.abort();
695
+ const e = new AbortController();
696
+ this.pointsController = e;
697
+ const t = new URLSearchParams({
698
+ marca: this.marca,
699
+ tipo: String(this.tipoCode)
700
+ }), n = this.pointsApiUrl.includes("?"), a = n && !/[?&]$/.test(this.pointsApiUrl), r = n ? a ? "&" : "" : "?", c = `${this.pointsApiUrl}${r}${t.toString()}`, i = this.getPointsCacheKey(c), l = await this.readPointsCache(i), d = l && Date.now() - l.timestamp < this.pointsCacheTtlMs;
701
+ if (l) {
702
+ if (this.applyPointsPayload(l.data), this.setComponentState("ready"), d)
703
+ return;
704
+ } else
705
+ this.setComponentState("loading");
706
+ try {
707
+ const p = await fetch(c, {
708
+ signal: e.signal
709
+ });
710
+ if (!p.ok)
711
+ throw new Error(`Respuesta ${p.status}`);
712
+ const u = await p.json();
713
+ if (!Array.isArray(u))
714
+ throw new Error("La respuesta de puntos no es valida.");
715
+ const y = u;
716
+ await this.writePointsCache(i, y), this.applyPointsPayload(y), this.setComponentState("ready");
717
+ } catch (p) {
718
+ if (p instanceof DOMException && p.name === "AbortError")
719
+ return;
720
+ if (l) {
721
+ console.warn("Se mantienen puntos cacheados por error al refrescar el mapa", p);
722
+ return;
723
+ }
724
+ console.error("No se pudieron cargar los puntos del mapa", p), this.setComponentState("error");
725
+ }
726
+ }
727
+ applyPointsPayload(e) {
728
+ this.points = this.transformPoints(e), this.renderPoints(this.points), this.initialViewApplied = !1, this.updateMarkers(this.points);
729
+ }
730
+ getPointsCacheKey(e) {
731
+ return `rs-map:points:${e}`;
732
+ }
733
+ async readPointsCache(e) {
734
+ const t = await this.readPointsCacheFromIndexedDb(e);
735
+ if (t)
736
+ return t;
737
+ try {
738
+ const n = window.localStorage.getItem(e);
739
+ if (!n)
740
+ return null;
741
+ const a = JSON.parse(n);
742
+ return !a || !Array.isArray(a.data) || !Number.isFinite(a.timestamp) ? (window.localStorage.removeItem(e), null) : a;
743
+ } catch {
744
+ return null;
745
+ }
746
+ }
747
+ async writePointsCache(e, t) {
748
+ const n = {
749
+ timestamp: Date.now(),
750
+ data: t
751
+ };
752
+ await this.writePointsCacheToIndexedDb(e, n);
753
+ try {
754
+ window.localStorage.setItem(e, JSON.stringify(n));
755
+ } catch {
756
+ }
757
+ }
758
+ async readPointsCacheFromIndexedDb(e) {
759
+ const t = await m.openPointsCacheDb();
760
+ return t ? new Promise((n) => {
761
+ const c = t.transaction(P, "readonly").objectStore(P).get(e);
762
+ c.onsuccess = () => {
763
+ const i = c.result;
764
+ if (!i || !Array.isArray(i.data) || !Number.isFinite(i.timestamp)) {
765
+ n(null);
766
+ return;
767
+ }
768
+ n({
769
+ timestamp: i.timestamp,
770
+ data: i.data
771
+ });
772
+ }, c.onerror = () => n(null);
773
+ }) : null;
774
+ }
775
+ async writePointsCacheToIndexedDb(e, t) {
776
+ const n = await m.openPointsCacheDb();
777
+ n && await new Promise((a) => {
778
+ const i = n.transaction(P, "readwrite").objectStore(P).put({
779
+ key: e,
780
+ timestamp: t.timestamp,
781
+ data: t.data
782
+ });
783
+ i.onsuccess = () => a(), i.onerror = () => a();
784
+ });
785
+ }
786
+ static openPointsCacheDb() {
787
+ return typeof window == "undefined" || !("indexedDB" in window) ? Promise.resolve(null) : (m.pointsCacheDbPromise || (m.pointsCacheDbPromise = new Promise((e) => {
788
+ const t = window.indexedDB.open(G, 1);
789
+ t.onupgradeneeded = () => {
790
+ const n = t.result;
791
+ n.objectStoreNames.contains(P) || n.createObjectStore(P, { keyPath: "key" });
792
+ }, t.onsuccess = () => e(t.result), t.onerror = () => e(null);
793
+ })), m.pointsCacheDbPromise);
794
+ }
795
+ transformPoints(e) {
796
+ return e.map((t) => ({
797
+ ...t,
798
+ zone: this.getZoneForPoint(t)
799
+ }));
800
+ }
801
+ renderPoints(e) {
802
+ if (!this.zonesContainer)
803
+ return;
804
+ const t = this.groupPoints(e);
805
+ this.pointsByZone = t, this.updateZoneButtonCounts();
806
+ const n = document.createDocumentFragment();
807
+ R.forEach((a) => {
808
+ const r = document.createElement("section");
809
+ r.className = "zone-section", r.dataset.zoneSection = a;
810
+ const c = document.createElement("div");
811
+ c.className = "zone-section__header";
812
+ const i = document.createElement("span");
813
+ if (i.textContent = $[a], c.appendChild(i), r.appendChild(c), t[a].length === 0) {
814
+ const l = document.createElement("p");
815
+ l.className = "zone-section__empty", l.textContent = "Sin puntos en esta zona.", r.appendChild(l);
816
+ } else {
817
+ const l = document.createElement("div");
818
+ l.className = "zone-section__list", t[a].forEach((d) => {
819
+ l.appendChild(this.createPointCard(d));
820
+ }), r.appendChild(l);
821
+ }
822
+ n.appendChild(r);
823
+ }), this.zonesContainer.replaceChildren(n), this.updateZoneVisibility();
824
+ }
825
+ groupPoints(e) {
826
+ const t = {
827
+ norte: [],
828
+ rm: [],
829
+ centro: [],
830
+ sur: []
831
+ };
832
+ return e.forEach((n) => {
833
+ t[n.zone].push(n);
834
+ }), t;
835
+ }
836
+ createPointCard(e) {
837
+ var y;
838
+ const t = document.createElement("article");
839
+ t.className = "point-card", t.dataset.pointId = String(e.id);
840
+ const n = document.createElement("h3");
841
+ n.className = "point-card__title", n.textContent = e.titulo || "Sin nombre", t.appendChild(n);
842
+ const a = document.createElement("div");
843
+ a.className = "point-card__address-block";
844
+ const r = document.createElement("p");
845
+ if (r.className = "point-card__address", r.textContent = e.direccion || "Sin direccion", a.appendChild(r), e.comuna_name) {
846
+ const o = document.createElement("p");
847
+ o.className = "point-card__meta", o.textContent = e.comuna_name, a.appendChild(o);
848
+ }
849
+ if (e.provincia_name) {
850
+ const o = document.createElement("p");
851
+ o.className = "point-card__meta", o.textContent = e.provincia_name, a.appendChild(o);
852
+ }
853
+ if (e.region_name) {
854
+ const o = document.createElement("p");
855
+ o.className = "point-card__meta", o.textContent = e.region_name, a.appendChild(o);
856
+ }
857
+ t.appendChild(a);
858
+ let c = null;
859
+ const i = Number(e.lat), l = Number(e.lng);
860
+ if (Number.isFinite(i) && Number.isFinite(l)) {
861
+ c = document.createElement("button"), c.type = "button", c.className = "point-card__focus";
862
+ const o = this.createIconElement("fa-solid fa-location-crosshairs");
863
+ c.appendChild(o), c.appendChild(document.createTextNode(" Ver en el mapa")), c.addEventListener("click", () => {
864
+ this.focusPointWithZoom(i, l), this.scrollToPointCard(e.id);
865
+ });
866
+ }
867
+ const d = document.createElement("div");
868
+ d.className = "point-card__details", d.hidden = !0;
869
+ let h = !1;
870
+ const p = document.createElement("div");
871
+ p.className = "point-card__actions";
872
+ let u = null;
873
+ if (e.url && e.url !== "#") {
874
+ const o = document.createElement("a");
875
+ o.href = e.url, o.target = "_blank", o.rel = "noopener noreferrer", o.className = "point-card__action";
876
+ const g = this.createIconElement("fa-solid fa-globe");
877
+ o.appendChild(g), o.appendChild(document.createTextNode("Sitio web")), p.appendChild(o);
878
+ }
879
+ if (e.email) {
880
+ const o = document.createElement("a");
881
+ o.href = `mailto:${e.email}`, o.target = "_blank", o.rel = "noopener noreferrer", o.className = "point-card__action point-card__action--text";
882
+ const g = this.createIconElement("fa-solid fa-envelope");
883
+ o.appendChild(g), o.appendChild(document.createTextNode(e.email)), p.appendChild(o);
884
+ }
885
+ if (p.childElementCount && (d.appendChild(p), h = !0), (y = e.telefonos) != null && y.length) {
886
+ const o = document.createElement("div");
887
+ o.className = "point-card__contact";
888
+ const g = document.createElement("div");
889
+ g.className = "point-card__contact-title";
890
+ const f = this.createIconElement("fa-solid fa-phone");
891
+ g.appendChild(f), g.appendChild(document.createTextNode("Telefonos")), o.appendChild(g);
892
+ const _ = document.createElement("ul");
893
+ _.className = "point-card__phone-list", e.telefonos.slice().sort((x, w) => x.orden - w.orden).forEach((x) => {
894
+ const w = document.createElement("li");
895
+ w.className = "point-card__phone-item";
896
+ const k = document.createElement("span");
897
+ if (k.className = "point-card__phone-icon", x.whatsapp) {
898
+ const z = this.createIconElement("fa-brands fa-whatsapp");
899
+ k.appendChild(z);
900
+ } else
901
+ k.textContent = "-";
902
+ w.appendChild(k);
903
+ const A = document.createElement("div");
904
+ A.className = "point-card__phone-content";
905
+ const S = document.createElement("span");
906
+ S.className = "point-card__phone-name", S.textContent = x.nombre, A.appendChild(S);
907
+ const E = x.whatsapp ? document.createElement("a") : document.createElement("span");
908
+ if (E.className = "point-card__phone-number", x.whatsapp) {
909
+ const z = this.getWhatsappLink(x.telefono);
910
+ z && (E.href = z, E.target = "_blank", E.rel = "noopener noreferrer", E.classList.add("point-card__phone-number--link"));
911
+ }
912
+ E.textContent = x.telefono, A.appendChild(E), w.appendChild(A), _.appendChild(w);
913
+ }), o.appendChild(_), d.appendChild(o), h = !0;
914
+ }
915
+ if (e.adicional) {
916
+ const o = document.createElement("p");
917
+ o.className = "point-card__extra", o.innerHTML = e.adicional, o.querySelectorAll("a").forEach((g) => {
918
+ g.classList.add("point-card__extra-link");
919
+ const f = this.createIconElement("fa-solid fa-arrow-up-right-from-square");
920
+ f.classList.add("point-card__extra-icon"), g.appendChild(f);
921
+ }), d.appendChild(o), h = !0;
922
+ }
923
+ if (e.googlelink) {
924
+ u = document.createElement("a"), u.href = e.googlelink, u.target = "_blank", u.rel = "noopener noreferrer", u.className = "point-card__action";
925
+ const o = this.createIconElement("fa-solid fa-map-location-dot");
926
+ u.appendChild(o), u.appendChild(document.createTextNode("Google Maps"));
927
+ }
928
+ if (u) {
929
+ const o = document.createElement("div");
930
+ o.className = "point-card__actions", o.appendChild(u), d.appendChild(o), h = !0;
931
+ }
932
+ if (h) {
933
+ const o = document.createElement("button");
934
+ o.type = "button", o.className = "point-card__toggle";
935
+ const g = this.createIconElement("fa-solid fa-circle-info"), f = document.createElement("span");
936
+ f.textContent = "Mas informacion", o.appendChild(g), o.appendChild(f), o.addEventListener("click", () => {
937
+ const _ = d.hidden;
938
+ d.hidden = !_, f.textContent = _ ? "Ocultar informacion" : "Mas informacion", g.className = _ ? "fa-solid fa-circle-xmark" : "fa-solid fa-circle-info";
939
+ }), t.appendChild(o), t.appendChild(d);
940
+ }
941
+ return c && t.appendChild(c), t;
942
+ }
943
+ getZoneForPoint(e) {
944
+ const t = this.normalizeRegionName(e.region_name || "");
945
+ return t && t in B ? B[t] : t.includes("metropolitana") ? "rm" : t.includes("araucania") || t.includes("rios") || t.includes("lagos") || t.includes("aysen") || t.includes("magallanes") ? "sur" : t.includes("arica") || t.includes("tarapaca") || t.includes("antofagasta") || t.includes("atacama") || t.includes("coquimbo") ? "norte" : "centro";
946
+ }
947
+ normalizeRegionName(e) {
948
+ return e.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").trim();
949
+ }
950
+ normalizeBrandKey(e) {
951
+ return e && e.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "") || "default";
952
+ }
953
+ getMarkerIcon() {
954
+ const e = this.marcaKey || "default";
955
+ return this.markerIconBaseUrl ? `${this.markerIconBaseUrl}${e}.png` : this.defaultMarkerIconUrl ? this.defaultMarkerIconUrl : null;
956
+ }
957
+ updateMarkers(e) {
958
+ const t = window.google;
959
+ if (!t || !this.map)
960
+ return;
961
+ this.markers.forEach((i) => i.setMap(null)), this.markers = [];
962
+ const n = e.filter((i) => {
963
+ const l = Number(i.lat), d = Number(i.lng);
964
+ return Number.isFinite(l) && Number.isFinite(d);
965
+ });
966
+ if (!n.length)
967
+ return;
968
+ const a = new t.maps.LatLngBounds(), r = this.getMarkerIcon(), c = r && this.map ? {
969
+ url: r,
970
+ scaledSize: new t.maps.Size(36, 36),
971
+ anchor: new t.maps.Point(18, 36)
972
+ } : void 0;
973
+ if (n.forEach((i) => {
974
+ const l = Number(i.lat), d = Number(i.lng), h = new t.maps.Marker({
975
+ map: this.map,
976
+ position: { lat: l, lng: d },
977
+ title: i.titulo,
978
+ icon: c
979
+ });
980
+ this.markers.push(h);
981
+ const p = h.getPosition();
982
+ p && a.extend(p);
983
+ }), !this.initialViewApplied && this.markers.length) {
984
+ const i = this.markers[0].getPosition();
985
+ if (i) {
986
+ this.map.setCenter(i), this.map.setZoom(14), this.initialViewApplied = !0;
987
+ return;
988
+ }
989
+ }
990
+ if (this.markers.length === 1) {
991
+ const i = this.markers[0].getPosition();
992
+ i && this.map.setCenter(i), this.map.setZoom(14);
993
+ } else
994
+ this.map.fitBounds(a);
995
+ }
996
+ setActiveZone(e) {
997
+ }
998
+ scrollToZoneSection(e) {
999
+ if (!this.zonesContainer)
1000
+ return;
1001
+ const t = this.zonesContainer.querySelector(`[data-zone-section="${e}"]`);
1002
+ t && t.scrollIntoView({ behavior: "smooth", block: "start" });
1003
+ }
1004
+ updateZoneButtons() {
1005
+ this.zoneButtons.forEach((e) => {
1006
+ const t = e.dataset.zone, n = this.activeZone === t;
1007
+ e.classList.toggle("is-active", n), e.setAttribute("aria-pressed", String(n));
1008
+ });
1009
+ }
1010
+ updateZoneButtonCounts() {
1011
+ this.zoneButtons.forEach((e) => {
1012
+ e.dataset.zone;
1013
+ const t = e.dataset.label || e.textContent || "";
1014
+ e.textContent = t;
1015
+ });
1016
+ }
1017
+ updateZoneVisibility() {
1018
+ if (!this.zonesContainer)
1019
+ return;
1020
+ this.zonesContainer.querySelectorAll("[data-zone-section]").forEach((t) => {
1021
+ t.removeAttribute("hidden");
1022
+ });
1023
+ }
1024
+ findNearestPoint(e, t) {
1025
+ if (!this.points.length)
1026
+ return null;
1027
+ let n = null, a = 1 / 0;
1028
+ return this.points.forEach((r) => {
1029
+ const c = Number(r.lat), i = Number(r.lng);
1030
+ if (!Number.isFinite(c) || !Number.isFinite(i))
1031
+ return;
1032
+ const l = this.haversine(e, t, c, i);
1033
+ l < a && (a = l, n = r);
1034
+ }), n;
1035
+ }
1036
+ haversine(e, t, n, a) {
1037
+ const r = (p) => p * Math.PI / 180, i = r(n - e), l = r(a - t), d = Math.sin(i / 2) * Math.sin(i / 2) + Math.cos(r(e)) * Math.cos(r(n)) * Math.sin(l / 2) * Math.sin(l / 2);
1038
+ return 6371e3 * (2 * Math.atan2(Math.sqrt(d), Math.sqrt(1 - d)));
1039
+ }
1040
+ scrollToPointCard(e) {
1041
+ if (!this.zonesContainer)
1042
+ return;
1043
+ const t = this.zonesContainer.querySelector(`[data-point-id="${e}"]`);
1044
+ t && (t.scrollIntoView({ behavior: "smooth", block: "center" }), this.highlightPointCard(t));
1045
+ }
1046
+ highlightPointCard(e) {
1047
+ var t;
1048
+ this.highlightTimeout !== null && (clearTimeout(this.highlightTimeout), this.highlightTimeout = null), (t = this.zonesContainer) == null || t.querySelectorAll(".point-card--highlight").forEach((n) => {
1049
+ n.classList.remove("point-card--highlight");
1050
+ }), e.classList.add("point-card--highlight"), this.highlightTimeout = window.setTimeout(() => {
1051
+ e.classList.remove("point-card--highlight"), this.highlightTimeout = null;
1052
+ }, 3500);
1053
+ }
1054
+ setComponentState(e) {
1055
+ if (!(!this.componentMessageEl || !this.mapLayoutEl))
1056
+ if (e === "ready")
1057
+ this.componentMessageEl.setAttribute("hidden", ""), this.mapLayoutEl.removeAttribute("hidden");
1058
+ else {
1059
+ const t = e === "loading" ? "Cargando puntos..." : "Mapa temporalmente no disponible";
1060
+ this.componentMessageEl.textContent = t, this.componentMessageEl.removeAttribute("hidden"), this.mapLayoutEl.setAttribute("hidden", "");
1061
+ }
1062
+ }
1063
+ centerMapOnPoint(e, t, n = 14) {
1064
+ if (!window.google || !this.map || !Number.isFinite(e) || !Number.isFinite(t))
1065
+ return;
1066
+ const r = typeof this.map.getZoom == "function" ? this.map.getZoom() : null, c = !r || r < n;
1067
+ this.animateMapPan(e, t, () => {
1068
+ c && this.map.setZoom(n);
1069
+ });
1070
+ }
1071
+ async focusPointWithZoom(e, t) {
1072
+ !window.google || !this.map || !Number.isFinite(e) || !Number.isFinite(t) || (await this.animateZoomTo(8, 800), await this.wait(500), await new Promise((a) => {
1073
+ this.animateMapPan(e, t, a);
1074
+ }), await this.wait(500), await this.animateZoomTo(18, 800));
1075
+ }
1076
+ wait(e) {
1077
+ return new Promise((t) => {
1078
+ window.setTimeout(t, e);
1079
+ });
1080
+ }
1081
+ async animateZoomTo(e, t = 600) {
1082
+ if (!window.google || !this.map || typeof this.map.getZoom != "function" || typeof this.map.setZoom != "function")
1083
+ return;
1084
+ const a = this.map.getZoom();
1085
+ if (!Number.isFinite(a)) {
1086
+ this.map.setZoom(e);
1087
+ return;
1088
+ }
1089
+ const r = e - a;
1090
+ if (Math.abs(r) < 0.01) {
1091
+ this.map.setZoom(e);
1092
+ return;
1093
+ }
1094
+ await new Promise((c) => {
1095
+ const i = performance.now(), l = (h) => 1 - Math.pow(1 - h, 3), d = (h) => {
1096
+ const p = h - i, u = Math.min(p / t, 1), y = l(u), o = a + r * y;
1097
+ this.map.setZoom(Math.round(o * 100) / 100), u < 1 ? requestAnimationFrame(d) : (this.map.setZoom(e), c());
1098
+ };
1099
+ requestAnimationFrame(d);
1100
+ });
1101
+ }
1102
+ animateMapPan(e, t, n) {
1103
+ if (!window.google || !this.map)
1104
+ return;
1105
+ this.panAnimationFrame !== null && (cancelAnimationFrame(this.panAnimationFrame), this.panAnimationFrame = null);
1106
+ const r = this.map.getCenter();
1107
+ if (!r) {
1108
+ this.map.setCenter({ lat: e, lng: t }), n == null || n();
1109
+ return;
1110
+ }
1111
+ const c = r.lat(), i = r.lng(), l = e - c, d = t - i, h = 600, p = performance.now(), u = (o) => 1 - Math.pow(1 - o, 3), y = (o) => {
1112
+ const g = o - p, f = Math.min(g / h, 1), _ = u(f), x = c + l * _, w = i + d * _;
1113
+ this.map.setCenter({ lat: x, lng: w }), f < 1 ? this.panAnimationFrame = requestAnimationFrame(y) : (this.panAnimationFrame = null, n == null || n());
1114
+ };
1115
+ this.panAnimationFrame = requestAnimationFrame(y);
1116
+ }
1117
+ static ensureFontAwesome() {
1118
+ if (m.fontAwesomeAttached)
1119
+ return;
1120
+ if (document.querySelector(`link[href="${L}"]`)) {
1121
+ m.fontAwesomeAttached = !0;
1122
+ return;
1123
+ }
1124
+ const t = document.createElement("link");
1125
+ t.rel = "stylesheet", t.href = L, t.crossOrigin = "anonymous", t.referrerPolicy = "no-referrer", t.addEventListener("load", () => {
1126
+ m.fontAwesomeAttached = !0;
1127
+ }), document.head.appendChild(t);
1128
+ }
1129
+ createIconElement(e) {
1130
+ const t = document.createElement("i");
1131
+ return t.className = e, t.setAttribute("aria-hidden", "true"), t;
1132
+ }
1133
+ getWhatsappLink(e) {
1134
+ const t = e.replace(/\D+/g, "");
1135
+ return t ? `https://wa.me/${t}` : null;
1136
+ }
1137
+ };
1138
+ s(m, "tag", "rs-map"), s(m, "googleMapsLoaderPromise", null), s(m, "pointsCacheDbPromise", null), s(m, "fontAwesomeAttached", !1);
1139
+ let v = m;
1140
+ U(v.tag, v);
1141
+ export {
1142
+ v as RsMap,
1143
+ U as safeDefine
1144
+ };
1145
+ //# sourceMappingURL=rs-components.es.js.map