PageSourceSearch

https://maps.lloretdemar.org/embed.js

js lloretdemar.org collected 2026-09-24 09:59:47 UTC 56,924 bytes, 1,518 lines download raw bytes

1window.boldest = window.boldest || {};
2
3//
4// frame Comunication
5//
6window.boldest.MapIframeCom = {
7    waitingEventsList: [],
8    initialize: function()  {
9      var that = this;
10      // window.boldest.MapIframe.log('EMB MapIframeCom initialize', that.waitingEventsList);
11
12      // lock viewport zoomControl
13      document.getElementsByTagName('meta')['viewport'].content='initial-scale=1.0, maximum-scale=1.0, user-scalable=no';
14
15      window.addEventListener("message", function(event){that.receiveMessage(event);}, false);
16    },
17    receiveMessage: function(event) {
18      var that = this;
19
20      // window.boldest.MapIframe.log('EMB MapIframeCom receiveMessage', event.data.eventName);
21      for( var ind=0 ; ind < that.waitingEventsList.length ; ind++ ) {
22
23        if( typeof that.waitingEventsList[ind] != 'undefined' && that.waitingEventsList[ind].eventName == event.data.eventName ) {
24          that.waitingEventsList[ind].callback( event.data.params );
25        }
26      }
27
28    },
29    on: function( eventName, callback ) {
30      var that = this;
31      // window.boldest.MapIframe.log('EMB MapIframeCom on', eventName);
32      that.waitingEventsList.push({
33        eventName: eventName,
34        callback: callback
35      });
36    },
37    trigger: function( frameObj, eventName, eventParams ) {
38      var that = this;
39      // window.boldest.MapIframe.log("EMB MapIframeCom trigger",eventName);
40
41      var eventData = {
42        eventName: eventName,
43        params: eventParams
44      };
45
46      try {
47        frameObj.bwExplorerFrame.contentWindow.postMessage( eventData , '*');
48      }
49      catch(err) {
50        console.log('bwidget iframe post message fail. Checkk CORS and that you are on same port', err);
51      }
52    }
53};
54
55//
56// frame UI
57//
58window.boldest.MapIframe = {
59    halted: false,
60    ready: false,
61    integration: 'full',
62    embedDivId: "bWidgetMap",
63    embedDiv: false,
64    headerHeight: 0,
65    bwExplorerFrame: false,
66    bwExplorerFrameBg: false,
67    bwCurtain: false,
68    bwShowCurtain: true,
69    bwShowButtons: false,
70    hideMapListWhenMobile: false,
71    bwTakemeout: false,
72    bwViewMap: false,
73    bwViewMapText: '',
74    bwViewMapUse: false,
75    bwTakemeoutText: '',
76    extraMarginTop: 300, //in px
77    extraListHeight: 200, //in px
78    extraMarginDown: 400, //in px
79    ignoreBottomContent: false,
80    mapScrollwheel: false,
81    scrollLocked: false,
82
83    bwCatLabel : '',
84    bwDisableRedirectOnModal : false,
85    bwFilterButtonText : false,
86
87    firstTimeBwEmbedView: false, // false: no se ha mostrado nunca, true: se ha mostrado al menos una vez
88    firstTimeBwEmbedViewTx: false, // Buble de envio al BW
89    firstTimeBwEmbedViewRx: false, // Recibido en el BW
90
91    swithedMapOnMobile: false,
92    actScroll : 0,
93
94    initializeAllDone: false,
95    lazyLoadTimeouts: [],
96    lazyLoadObserver: null,
97    lazyLoadScrollHandler: null,
98    lazyLoadIdleCallbackId: null,
99
100    initializeAll: function(force = false)  {
101      var that = this;
102      that.log("EMB: initializeAll", force);
103
104      if (that.initializeAllDone == true) {
105        return;
106      }
107
108      var elemEmbedDiv = document.getElementById( that.embedDivId )
109      if( typeof elemEmbedDiv == 'undefined' || elemEmbedDiv == null) {
110        return;
111      }
112
113      // New attribute 'loadprofile'
114      var loadProfile = elemEmbedDiv.getAttribute('loadprofile');
115      if (loadProfile !== 'lazy' && loadProfile !== 'ondemand') {
116        loadProfile = 'force'; // Default value
117      }
118
119      // loadProfile ondemand, wait for it to be forced
120      if (!force && loadProfile === 'ondemand') {
121        return;
122      }
123
124      // loadProfile force, activating force for compatibility
125      if (loadProfile === 'force') {
126        force = true;
127      }
128
129      // If forced, execute immediately
130      if (force) {
131        that.initializeAllDone = true;
132        that.lazyLoadingCleanup();
133
134        try {
135          window.boldest.MapIframeCom.initialize();
136          window.boldest.MapIframe.initialize();
137          window.boldest.PageIframe.initialize();
138        } catch (error) {
139          throw error; // Send error to console
140        }
141
142        return;
143      }
144
145      // At this point, loadProfile is 'lazy'. Use lazy loading strategy
146      that.lazyLoadingStrategy(elemEmbedDiv);
147    },
148    lazyLoadingStrategy: function (elemEmbedDiv) {
149      var that = this;
150
151      // Timeouts en milisegundos
152      const TIMEOUT_IDLE_CALLBACK_DELAY = 1000; // Delay interno del requestIdleCallback
153      const TIMEOUT_IDLE_CALLBACK_MAX = 2000;   // Timeout máximo del requestIdleCallback
154
155      const TIMEOUT_VISIBLE_FALLBACK = 2000;    // Fallback para navegadores sin requestIdleCallback
156      const VISIBLE_PIXELS_MARGIN = '100px';    // Margen para IntersectionObserver
157
158      const TIMEOUT_OBSERVER_FALLBACK = 5000;   // Fallback si IntersectionObserver no dispara
159      const TIMEOUT_SCROLL_FALLBACK = 5000;     // Fallback si scroll listener no dispara
160
161      // Decidir según visibilidad del widget
162      // Considera visible si cualquier parte del widget está en viewport
163      var rect = elemEmbedDiv.getBoundingClientRect();
164      var viewportHeight = window.innerHeight || document.documentElement.clientHeight;
165      var viewportWidth = window.innerWidth || document.documentElement.clientWidth;
166      var isVisibleInitially = (
167        rect.top < viewportHeight &&
168        rect.bottom > 0 &&
169        rect.left < viewportWidth &&
170        rect.right > 0
171      );
172
173      if (isVisibleInitially) {
174        // Widget visible → requestIdleCallback
175        // console.log("EMB: initializeAll: widget above the fold, using requestIdleCallback");
176
177        if ('requestIdleCallback' in window) {
178          that.lazyLoadIdleCallbackId = requestIdleCallback(function () {
179            that.lazyLoadIdleCallbackId = null; // Limpiar después de ejecutar
180            var timeoutId = setTimeout(function () {
181              console.log("EMB: initializeAll true by requestIdleCallback timeout");
182              that.initializeAll(true); // Forzar ejecución
183            }, TIMEOUT_IDLE_CALLBACK_DELAY);
184            that.lazyLoadTimeouts.push(timeoutId);
185          }, { timeout: TIMEOUT_IDLE_CALLBACK_MAX });
186        } else {
187          // Fallback para navegadores antiguos
188          var timeoutId = setTimeout(function () {
189            console.log("EMB: initializeAll true by requestIdleCallback fallback timeout");
190            that.initializeAll(true); // Forzar ejecución
191          }, TIMEOUT_VISIBLE_FALLBACK);
192          that.lazyLoadTimeouts.push(timeoutId);
193        }
194      } else {
195        // Widget NO visible → IntersectionObserver
196        // console.log("EMB: initializeAll: widget below the fold, using IntersectionObserver");
197
198        if ('IntersectionObserver' in window) {
199          that.lazyLoadObserver = new IntersectionObserver(function (entries) {
200            entries.forEach(function (entry) {
201              if (entry.isIntersecting) {
202                console.log("EMB: initializeAll true by IntersectionObserver");
203
204                // Desconectar INMEDIATAMENTE para evitar múltiples ejecuciones
205                that.lazyLoadObserver.disconnect();
206                that.lazyLoadObserver = null;
207
208                that.initializeAll(true); // Forzar ejecución
209              }
210            });
211          }, { rootMargin: VISIBLE_PIXELS_MARGIN });
212
213          that.lazyLoadObserver.observe(elemEmbedDiv);
214
215          // Fallback: cargar después de N segundos aunque no sea visible
216          var timeoutId = setTimeout(function () {
217            console.log("EMB: initializeAll true by IntersectionObserver timeout");
218            that.initializeAll(true); // Forzar ejecución
219          }, TIMEOUT_OBSERVER_FALLBACK);
220          that.lazyLoadTimeouts.push(timeoutId);
221
222        } else {
223          // Fallback para navegadores sin IntersectionObserver
224          // console.log("EMB: initializeAll true by scroll fallback");
225
226          // Variables para throttle
227          var lastScrollCheck = 0;
228          var SCROLL_THROTTLE_MS = 200;
229
230          that.lazyLoadScrollHandler = function checkScroll() {
231            // Throttle: limitar comprobaciones a cada 200ms
232            var now = Date.now();
233            if (now - lastScrollCheck < SCROLL_THROTTLE_MS) {
234              return;
235            }
236            lastScrollCheck = now;
237
238            var rect = elemEmbedDiv.getBoundingClientRect();
239            if (rect.top < window.innerHeight + 100) {
240              console.log("EMB: initializeAll true by IntersectionObserver fallback");
241              that.initializeAll(true); // Forzar ejecución
242              // Listener se remueve en lazyLoadingCleanup
243            }
244          };
245
246          // Compatibilidad IE11: try-catch para passive
247          try {
248            window.addEventListener('scroll', that.lazyLoadScrollHandler, { passive: true });
249          } catch (e) {
250            window.addEventListener('scroll', that.lazyLoadScrollHandler, false);
251          }
252
253          // Fallback timeout
254          var timeoutId = setTimeout(function () {
255            console.log("EMB: initializeAll true by IntersectionObserver fallback timeout");
256            that.initializeAll(true); // Forzar ejecución
257          }, TIMEOUT_SCROLL_FALLBACK);
258          that.lazyLoadTimeouts.push(timeoutId);
259        }
260      }
261    },
262    lazyLoadingCleanup: function () {
263      var that = this;
264
265      // Cancelar todos los timeouts
266      if (that.lazyLoadTimeouts && that.lazyLoadTimeouts.length > 0) {
267        that.lazyLoadTimeouts.forEach(function (timeoutId) {
268          clearTimeout(timeoutId);
269        });
270        that.lazyLoadTimeouts = [];
271        // console.log("EMB Cleared lazy load timeouts");
272      }
273
274      // Cancelar requestIdleCallback pendiente
275      if (that.lazyLoadIdleCallbackId) {
276        if ('cancelIdleCallback' in window) {
277          cancelIdleCallback(that.lazyLoadIdleCallbackId);
278        }
279        that.lazyLoadIdleCallbackId = null;
280        // console.log("EMB Cancelled idle callback");
281      }
282
283      // Desconectar IntersectionObserver
284      if (that.lazyLoadObserver) {
285        that.lazyLoadObserver.disconnect();
286        that.lazyLoadObserver = null;
287        // console.log("EMB Disconnected IntersectionObserver");
288      }
289
290      // Remover scroll listener
291      if (that.lazyLoadScrollHandler) {
292        window.removeEventListener('scroll', that.lazyLoadScrollHandler);
293        that.lazyLoadScrollHandler = null;
294        // console.log("EMB Removed scroll listener");
295      }
296    },
297
298    initialize: function()  {
299      var that = this;
300
301      if(that.halted == true) {
302        return;
303      }
304
305      console.log(window.location.href);
306
307      that.embedDiv = document.getElementById( that.embedDivId );
308      // exit on enbedDivNot present
309      if( typeof that.embedDiv == 'undefined' || that.embedDiv == null) {
310        return;
311      }
312      if(that.embedDiv.getAttribute('integration') != null) {
313        that.integration = that.embedDiv.getAttribute('integration');
314      }
315
316      if( that.embedDiv.getAttribute('showButtons') != null && that.embedDiv.getAttribute('showButtons') != 'false') {
317        that.bwShowButtons = true;
318      }
319
320      if(
321        ( that.embedDiv.getAttribute('showCurtain') != null && that.embedDiv.getAttribute('showCurtain') == 'false' ) ||
322        ( that.integration != 'full' )
323      ) {
324        that.bwShowCurtain = false;
325      }
326
327      if( that.embedDiv.getAttribute('hideMapListWhenMobile') != null && that.embedDiv.getAttribute('hideMapListWhenMobile') == 'true' ) {
328        that.hideMapListWhenMobile = true;
329      }
330
331
332      if(that.embedDiv.getAttribute('viewMapText') != null ) {
333        that.bwViewMapText = that.embedDiv.getAttribute('viewMapText');
334      }
335      if(that.embedDiv.getAttribute('takemeoutText') != null) {
336        that.bwTakemeoutText = that.embedDiv.getAttribute('takemeoutText');
337      }
338
339      if(that.embedDiv.getAttribute('catLabel') != null ) {
340        that.bwCatLabel = that.embedDiv.getAttribute('catLabel');
341      }
342
343      if(that.embedDiv.getAttribute('disableRedirect') != null ) {
344        that.bwDisableRedirectOnModal = that.embedDiv.getAttribute('disableRedirect');
345      }
346
347      if(that.embedDiv.getAttribute('filterButtonText') != null ) {
348        that.bwFilterButtonText = that.embedDiv.getAttribute('filterButtonText');
349      }
350
351      that.btn_out_img = 'embed_btn_up.png';
352      that.setContainers();
353
354      // generic top Height
355      if(that.embedDiv.getAttribute('topHeight') != null) {
356        that.headerHeight = parseInt(that.embedDiv.getAttribute('topHeight')); // generic
357      }
358
359      // xs: Extra small <576px
360      if(that.embedDiv.getAttribute('topHeightXs') != null && window.innerWidth < 576 ) {
361        that.headerHeight = parseInt(that.embedDiv.getAttribute('topHeightXs'));
362      }
363
364      // sm: Small ≥576px
365      if(that.embedDiv.getAttribute('topHeightSm') != null && window.innerWidth >= 576 ) {
366        that.headerHeight = parseInt(that.embedDiv.getAttribute('topHeightSm'));
367      }
368
369      // lg: Large ≥992px
370      if(that.embedDiv.getAttribute('topHeightLg') != null && window.innerWidth >= 992 ) {
371        that.headerHeight = parseInt(that.embedDiv.getAttribute('topHeightLg'));
372      }
373
374      // xl: Extra large ≥1200px
375      if(that.embedDiv.getAttribute('topHeightXl') != null && window.innerWidth >= 1200  ) {
376        that.headerHeight = parseInt(that.embedDiv.getAttribute('topHeightXl'));
377      }
378
379      that.headerQuery = that.embedDiv.getAttribute('headerQuery');
380      if (that.headerQuery != null){
381        that.headerHeight = document.querySelector(that.headerQuery).offsetHeight;
382      }
383
384      if(that.embedDiv.getAttribute('mapScrollwheel') != null) {
385        if( that.embedDiv.getAttribute('mapScrollwheel') == 'false' ) {
386          that.mapScrollwheel = false;
387        }
388        else
389        if( that.embedDiv.getAttribute('mapScrollwheel') == 'true' ) {
390          that.mapScrollwheel = true;
391        }
392
393      }
394
395      that.ignoreBottomContent = that.embedDiv.getAttribute("ignoreBottomContent");
396      that.bwExplorerFrame = document.getElementById("bwExplorerFrame");
397      that.bwExplorerFrameBg = document.getElementById("bwExplorerFrameBg");
398      that.bwCurtain = document.getElementById("bwCurtain");
399      that.bwTakemeout = document.getElementById("bwTakemeout");
400      that.bwViewMap = document.getElementById("bwViewMap");
401
402
403      // curtain dimensions
404      that.bwCurtain.style.width = document.body.scrollWidth+"px";
405      that.bwCurtain.style.height = window.innerHeight - that.headerHeight+"px";
406      that.bwCurtain.style.left = "calc(50% - 50vw)";
407      that.bwCurtain.style.position = 'absolute';
408      that.bwCurtain.style.zIndex = that.bwExplorerFrame.style.zIndex + 1;
409      that.bwCurtain.style.backgroundColor = "white";
410      that.bwCurtain.style.opacity = "0.5";
411      that.bwCurtain.style.cursor = "pointer";
412      if( that.bwShowCurtain != true) {
413        that.bwCurtain.style.display = "none";
414      }
415
416      //that.bwViewMap.style.height = that.bwTakemeout.style.height = "20px";
417      that.bwViewMap.style.right = that.bwTakemeout.style.right = "30px";
418      that.bwViewMap.style.bottom = that.bwTakemeout.style.bottom = "60px";
419      that.bwViewMap.style.padding = that.bwTakemeout.style.padding = "15px";
420      that.bwViewMap.style.padding = that.bwTakemeout.style.paddingTop = "11px";
421      that.bwViewMap.style.padding = that.bwTakemeout.style.paddingBottom = "11px";
422
423      that.bwViewMap.style.cursor = that.bwTakemeout.style.cursor = "pointer";
424
425      that.bwViewMap.style.color = that.bwTakemeout.style.color = "#fff";
426      that.bwViewMap.style.fontSize = that.bwTakemeout.style.fontSize = "15px";
427      that.bwViewMap.style.border = that.bwTakemeout.style.border = "2px solid #fff";
428      that.bwViewMap.style.zIndex = that.bwTakemeout.style.zIndex = that.bwCurtain.style.zIndex + 1;
429      that.bwViewMap.style.boxShadow = that.bwTakemeout.style.boxShadow = '0 2px 4px rgba(0,0,0,0.5)';
430      that.bwViewMap.style.fontWeight = that.bwTakemeout.style.fontWeight = 'bold';
431      that.bwViewMap.style.borderRadius = that.bwTakemeout.style.borderRadius = '3px';
432      that.bwViewMap.style.position = that.bwTakemeout.style.position = 'fixed';
433
434      if(that.embedDiv.getAttribute('btnColor') == null) {
435        that.bwViewMap.style.backgroundColor = that.bwTakemeout.style.backgroundColor = "#000";
436      }
437      else {
438        that.bwViewMap.style.backgroundColor = that.bwTakemeout.style.backgroundColor = that.embedDiv.getAttribute('btnColor');
439      }
440
441      // iframe dimensions
442      if( that.integration == 'full' ) {
443        document.body.style.overflowX ='hidden';
444
445        that.bwExplorerFrameBg.style.height= window.innerHeight - that.headerHeight+"px";
446        that.bwExplorerFrame.style.height= window.innerHeight - that.headerHeight+"px";
447
448        that.bwExplorerFrame.style.position = 'absolute';
449        ////that.log("top",that.bwExplorerFrame.style.top);
450        //that.bwExplorerFrame.style.top= 0+"px";
451
452        that.bwExplorerFrame.style.left = "calc(50% - 50vw)";
453        // antes that.bwExplorerFrame.style.width = '100%';
454        // antes that.bwExplorerFrame.style.left = '0px';
455        that.bwExplorerFrame.style.width = document.body.scrollWidth+"px";
456        that.bwExplorerFrame.style.maxWidth = "none";
457        that.bwViewMap.style.display = 'inherit';
458        document.getElementById( "bwBtnGroup" ).style.display = "inherit";
459      }
460      else
461      if( that.integration == 'segment' ) {
462        that.embedDiv.style.height="100%";
463        that.bwExplorerFrame.style.height= "100%";
464        that.bwExplorerFrame.style.width= "100%";
465      }
466      else
467      if( that.integration == 'modal' ) {
468
469        that.embedDiv.style.position = "fixed";
470        that.embedDiv.style.top = "0px";
471        that.embedDiv.style.left = "0px";
472        that.embedDiv.style.width = "100%";
473        that.embedDiv.style.height = "100%";
474
475        that.bwCurtain.style.position = "absolute";
476        that.bwCurtain.style.top = "0px";
477        that.bwCurtain.style.left = "0px";
478        that.bwCurtain.style.width = "100%";
479        that.bwCurtain.style.height = "100vh";
480        that.bwCurtain.style.backgroundColor = "black";
481        that.bwCurtain.style.opacity = "0.5";
482        that.bwCurtain.style.display = "inherit";
483
484        document.body.style.overflowX = 'hidden';
485
486
487        that.bwTakemeout.style.height = "40px";
488        that.bwTakemeout.style.padding = "0px";
489        that.bwTakemeout.style.paddingTop = "8px";
490        that.bwTakemeout.style.cursor = "pointer";
491        that.bwTakemeout.style.fontSize = "16px";
492        that.bwTakemeout.style.border = "0px";
493        that.bwTakemeout.style.boxShadow = '0 2px 4px rgba(0,0,0,0.5)';
494        that.bwTakemeout.style.fontWeight = 'bold';
495        that.bwTakemeout.style.borderTopLeftRadius = '10px';
496        that.bwTakemeout.style.borderTopRightRadius = '10px';
497        that.bwTakemeout.style.borderBottomLeftRadius = '0px';
498        that.bwTakemeout.style.borderBottomRightRadius = '0px';
499        that.bwTakemeout.style.boxShadow = '0 0px 0px rgba(0,0,0,0)';
500        that.bwTakemeout.style.right = "auto";
501        that.bwTakemeout.style.bottom = "auto";
502        that.bwTakemeout.style.left = "50%";  // Establecer el 50% del ancho del contenedor
503        that.bwTakemeout.style.transform = "translateX(-50%)";
504
505        that.bwCurtain.onclick = function() {
506          that.modalClose();
507        };
508
509        that.bwExplorerFrame.style.position = 'absolute';
510        // si ancho de pantalla es menor que 768px
511        if( window.innerWidth < 768 ) {
512          that.bwExplorerFrame.style.top = '40px';
513          that.bwExplorerFrame.style.left = '3px';
514          that.bwExplorerFrame.style.width = 'calc(100% - 6px)';
515          that.bwExplorerFrame.style.height = 'calc(100% - 40px)';
516          that.bwExplorerFrame.style.border = "1px solid #fff";
517          that.bwTakemeout.style.top = "0px";
518        }
519        else {
520          that.bwExplorerFrame.style.top = '60px';
521          that.bwExplorerFrame.style.left = '20px';
522          that.bwExplorerFrame.style.width = 'calc(100% - 40px)';
523          that.bwExplorerFrame.style.height = 'calc(100% - 80px)';
524          that.bwExplorerFrame.style.border = "10px solid #fff";
525
526          that.bwTakemeout.style.top = "20px";
527        }
528        that.bwExplorerFrame.style.maxWidth = "none";
529        that.bwExplorerFrame.style.boxShadow = "5px 5px 5px rgba(0, 0, 0, 0.5)";
530        that.btn_out_img = 'embed_btn_close.png';
531
532        that.bwTakemeout.innerHTML = that.bwTakemeoutText+" <img style=\"width:17px !important;\" src=\""+that.embedDiv.getAttribute('embedUrl')+"/"+that.btn_out_img+"\">";
533
534
535        that.ignoreBottomContent = 'true';
536        that.modalClose()
537      }
538
539
540      // Asignar rol "button" y aria-label
541      that.bwViewMap.setAttribute('role', 'button');
542      that.bwViewMap.setAttribute('aria-label', 'View map');
543
544
545
546
547
548      // events
549      that.embedDiv.getAttribute('onFocus');
550      that.embedDiv.getAttribute('onFocusOut')
551
552
553      window.addEventListener('scroll', function(e) {
554        that.onScroll();
555      });
556      window.addEventListener('resize', function(e){
557        that.onWindowResize();
558      });
559
560      window.onscroll = function(ev) {
561        if (document.body.scrollHeight - window.innerHeight - window.scrollY < 40) {
562          //window.boldest.MapIframeCom.trigger(that, 'parentScrollForceBottom', {});
563          window.boldest.MapIframeCom.trigger(that, 'parentScroll', {}); // evita a desaparición do scroll do mapa ao interactuar co pai.
564        }
565      };
566
567
568      that.bwTakemeout.addEventListener("click", function(){
569        //window.scrollTo(0, that.bwExplorerFrame.offsetTop-200);
570        if( that.integration == 'modal' ) {
571          that.modalClose();
572        }
573        else{
574          window.scrollTo({
575            left: 0,
576            top: that.bwExplorerFrame.offsetTop-200,
577            behavior: 'smooth'
578          });
579        }
580      });
581      that.bwViewMap.addEventListener("click", function(){
582        //window.scrollTo(0, window.pageYOffset + that.bwExplorerFrame.getBoundingClientRect().top+that.extraMarginTop);
583
584        var distanciaY;
585
586        if( that.integration == 'segment' ) {
587          distanciaY = window.pageYOffset + that.bwExplorerFrame.getBoundingClientRect().top - 60;
588        }
589        else {
590          distanciaY = window.pageYOffset + that.bwExplorerFrame.getBoundingClientRect().top + that.extraMarginTop;
591        }
592
593        window.scrollTo({
594          left: 0,
595          top: distanciaY,
596          behavior: 'smooth'
597        });
598      });
599
600      that.bwCurtain.addEventListener("click", function(){
601        that.scrollTop();
602      });
603    },
604
605    setContainers: function() {
606      var that = this;
607      // that.log("EMB setContainers");
608
609      var integration = that.embedDiv.getAttribute('integration');
610      var mainUri = that.embedDiv.getAttribute('embedMainUri');
611
612      //var uriRegex = /(\#greenmap\:)(.*)/g;;
613      var uriRegex = new RegExp("(\#"+that.embedDiv.getAttribute('parentUriPrefix')+")(.*)", 'i');
614      if(location.hash != '' && uriRegex.exec(location.hash) ) {
615        mainUri = uriRegex.exec(location.hash)[2];
616      }
617
618      if (integration == 'modal') {
619        that.log('ZZZ ANCHO MapIframe setContainers: mainUri#pxw'+window.innerWidth);
620        mainUri = mainUri + '#pxw'+window.innerWidth;
621      }
622
623      var buttonsVisibility = 'display:none;';
624      if(that.bwShowButtons) {
625        buttonsVisibility = ''
626      }
627
628      that.preLoadIframe();
629
630      var iframeUrl = that.embedDiv.getAttribute('embedUrl') + mainUri;
631      that.embedDiv.innerHTML = ""+
632      "<div id=\"bwCurtain\"></div>" +
633      "<div style=\""+ buttonsVisibility +"\" >" +
634        "<div id=\"bwBtnGroup\" style=\"display:none;\">" +
635          "<div id=\"bwTakemeout\" style=\"display:none;\"><span class=\"text\">"+that.bwTakemeoutText+" </span><img  style=\"width:17px !important;\" src=\""+that.embedDiv.getAttribute('embedUrl')+"/"+that.btn_out_img+"\"></div>" +
636          "<div id=\"bwViewMap\" style=\"display:none;\"><span class=\"text\">"+that.bwViewMapText+" </span><img style=\"width:17px !important;margin-left: 6px;margin-right: 4px;display: inherit;float: right;\" src=\""+that.embedDiv.getAttribute('embedUrl')+"/embed_btn_down.png\"></div>" +
637        "</div>" +
638      "</div>" +
639      "<iframe id=\"bwExplorerFrame\" src=\""+iframeUrl+"\" frameBorder=\"0\" onload=\"window.boldest.MapIframe.onLoadIframe()\"></iframe>" +
640      "<div id=\"bwExplorerFrameBg\"></div>";
641    },
642
643
644    preLoadIframe: function() {
645      var that=this;
646
647      window.boldest.MapIframeCom.on('log', function (ev) {
648        that.log('EMB preLoadIframe log iframe', ev.txt);
649      });
650
651      window.boldest.MapIframeCom.on('evalCode', function (ev) {
652        eval(ev.code);
653      });
654
655      window.boldest.MapIframeCom.on('logDisable', function () {
656        // that.log('EMB preLoadIframe embes.js console log off');
657        that.log = function () {}; // disable log
658      });
659
660      window.boldest.MapIframeCom.on('gtmInitialize', function (params) {
661        // that.log('EMB preLoadIframe GTAGlog embed.js window.boldest.MapIframeCom.on gtmInitialize', params);
662        that.gtmInitialize(params);
663      });
664
665      window.boldest.MapIframeCom.on('ready', function (ev) {
666        that.ready = true;
667      });
668
669
670      window.boldest.MapIframeCom.on('SonAskForParentAttributes', function(ev){
671
672        window.boldest.MapIframeCom.trigger(that, 'parentSendParentAttributes', {
673          parentUrl: window.location.href,
674          landingResId: that.getLandingResId(),
675          mapScrollwheel: that.mapScrollwheel,
676          bwCatLabel: that.bwCatLabel ? that.bwCatLabel : false,
677          //bwDisableRedirectOnModal: (that.integration=='modal') ? that.bwDisableRedirectOnModal : false,
678          bwDisableRedirectOnModal: that.bwDisableRedirectOnModal ? that.bwDisableRedirectOnModal : false,
679          bwFilterButtonText: that.bwFilterButtonText ? that.bwFilterButtonText : false,
680          integration: that.integration,
681          hideMapListWhenMobile: that.hideMapListWhenMobile
682        })
683      });
684
685
686      // Orientado a landing nativa
687      window.boldest.MapIframeCom.on('hideBackToExp', function (ev) {
688        if(document.getElementById("btnBackLanding")){
689          document.getElementById("btnBackLanding").style.display = "none";
690        }
691      });
692
693      window.boldest.MapIframeCom.on('showBackToExp', function (ev) {
694        if (document.getElementById("btnBackLanding")){
695          document.getElementById("btnBackLanding").style.display = "inherit";
696        }
697      });
698
699
700      window.boldest.MapIframeCom.on('hideButtons', function(ev) {
701        if( that.integration != 'modal' ) {
702          document.getElementById( "bwBtnGroup" ).style.display = "none";
703        }
704      });
705
706      window.boldest.MapIframeCom.on('showButtons', function(ev) {
707        document.getElementById( "bwBtnGroup" ).style.display = "inherit";
708      });
709
710
711      window.boldest.MapIframeCom.on('setUrlParent', function(ev){
712        //window.location.hash = 'greenmap/'+ev.url;
713        if( ev.url != '' ) {
714
715          var url = ev.url.startsWith('/') ? ev.url.substring(1) : ev.url;
716          history.pushState(null, null, '#' + that.embedDiv.getAttribute('parentUriPrefix') + '/' + url);
717        }
718        else {
719          history.pushState(null, null, ' ');
720        }
721        window.boldest.MapIframeCom.trigger(that, 'parentUrlChanged', {containerUrl:window.location.href});
722      });
723
724      window.boldest.MapIframeCom.on('gotoUrl', function(ev){
725        window.location = ev.url;
726      });
727
728      window.boldest.MapIframeCom.on('gotoUrlNewTab', function(ev){
729        window.open(ev.url, '_blank', 'noopener,noreferrer');
730      });
731
732      window.boldest.MapIframeCom.on('scrollTop', function(){
733        that.scrollTop();
734      });
735
736      window.boldest.MapIframeCom.on('scrollLock', function(){
737        that.scrollLock();
738      });
739
740      window.boldest.MapIframeCom.on('scrollUnLock', function(){
741        that.scrollUnLock();
742      });
743
744      window.boldest.MapIframeCom.on('updateInterfaceAttributes', function (ev) {
745        that.updateInterfaceAttributes(ev);
746      });
747
748      window.boldest.MapIframeCom.on('hideBackUrlBox', function(){
749        if( document.getElementsByClassName('backUrlBox').length > 0 ) {
750          document.getElementsByClassName('backUrlBox')[0].style.display = 'none';
751        }
752      });
753
754      window.boldest.MapIframeCom.on('showBackUrlBox', function(){
755        if( document.getElementsByClassName('backUrlBox').length > 0 ) {
756          document.getElementsByClassName('backUrlBox')[0].style.display = 'inherit';
757        }
758      });
759
760      if( that.integration == 'full') {
761        window.boldest.MapIframeCom.on( 'listChange', function(ev) {
762          // that.log('listChange');
763
764          if( typeof ev.listHeight != 'undefined' ) {
765            if( window.innerHeight - that.headerHeight < ev.listHeight ) {
766              that.bwExplorerFrameBg.style.height = ev.listHeight + that.extraMarginTop + that.extraListHeight +that.extraMarginDown + "px";
767              window.boldest.MapIframeCom.trigger(that, 'enableScroll', {} );
768              that.onScroll();
769            }
770            else {
771              // that.log('non teño alto')
772              that.bwExplorerFrameBg.style.height = window.innerHeight - that.headerHeight + that.extraMarginTop + that.extraListHeight + that.extraMarginDown  + "px";
773              window.boldest.MapIframeCom.on('scrollLock', function(){
774                that.scrollLock();
775              });
776            }
777          }
778
779        });
780      }
781      else{
782        if( that.integration == 'segment') {
783          window.boldest.MapIframeCom.on( 'listChange', function(ev) {
784            window.boldest.MapIframeCom.trigger(that, 'enableScroll', {} );
785            if(that.swithedMapOnMobile == false) {
786              that.swithedMapOnMobile = true;
787              window.boldest.MapIframeCom.trigger(that, 'switchMapOnMobile', {} );
788            }
789
790          });
791        }
792        else{
793          if( that.integration == 'modal') {
794            window.boldest.MapIframeCom.on( 'listChange', function(ev) {
795              if( typeof ev.listHeight != 'undefined' ) {
796                if( window.innerHeight - that.headerHeight < ev.listHeight ) {
797                  window.boldest.MapIframeCom.trigger(that, 'enableScroll', {} );
798                  that.onScroll();
799                }
800              }
801            });
802          }
803        }
804      }
805    },
806
807    getLandingResId: function() {
808      var that = this;
809      var landResId = false;
810      var landing = document.getElementsByClassName('resourceAppLanding');
811      if( landing.length === 1 ) {
812        var labId = landing[0].getAttribute('data-labels').split(',').find( el => el.indexOf('id_')===0 );
813        landResId = ( labId ) ? labId.substring(3) : false;
814      }
815      return landResId;
816    },
817
818    onLoadIframe: function() {
819      var that= this;
820      // that.log("EMB onLoadIframe");
821
822      that.embedDiv.setAttribute( 'iframeloaded', 1 );
823
824      that.checkFirstTimeBwEmbedView(); // Verificamos si se esta mostrando el bwViewMap por primera vez
825
826      if( that.integration == 'full' || that.integration == 'modal') {
827        that.onScroll();
828      }
829      else if( that.integration == 'segment' ) {
830        that.onScrollSegment();
831        // segment variant must center when next events are triggered
832        window.boldest.MapIframeCom.on( 'scrollGallery', function(ev){
833          that.centerSegment();
834        });
835        window.boldest.MapIframeCom.on( 'duOpen', function(ev){
836          that.centerSegment();
837        });
838        window.boldest.MapIframeCom.on('setFiltersValuesFromSon', function(ev){
839          that.centerSegment();
840        });
841        window.boldest.MapIframeCom.on('mobileChooseInterfaceMap', function(ev){
842          that.centerSegment();
843        });
844        window.boldest.MapIframeCom.on('mobileChooseInterfaceList', function(ev){
845          that.centerSegment();
846        });
847        window.boldest.MapIframeCom.on('mapChanged', function(ev){
848          that.centerSegment();
849        });
850      }
851    },
852
853    onScroll: function() {
854      var that = this;
855      // that.log("EMB onScroll");
856
857      that.checkFirstTimeBwEmbedView(); // Verificamos si se esta mostrando el bwViewMap por primera vez
858
859      ////that.log("Scroll!", window.scrollY, that.embedDiv.getBoundingClientRect().top, that.embedDiv.getBoundingClientRect().top+window.innerHeight);
860      if( that.integration == 'full' ) {
861        if( that.embedDiv.getBoundingClientRect().top <= that.headerHeight && that.embedDiv.getBoundingClientRect().top-window.innerHeight+parseInt(that.bwExplorerFrameBg.style.height)  >= 0 ) {
862          that.onScrollOnFocus();
863        }
864        else {
865          that.onScrollOnFocusOut();
866        }
867      }
868      else if( that.integration == 'segment' ) {
869        that.scrollSegmentChecks();
870      }
871    },
872
873    onScrollOnFocus: function() {
874      var that = this;
875      // that.log("EMB onScrollOnFocus pegado");
876
877      that.bwTakemeout.style.display = 'inherit';
878      that.bwViewMap.style.display = 'none';
879
880      that.bwCurtain.style.display = 'none';
881      that.bwExplorerFrame.style.position = 'fixed';
882      that.bwExplorerFrame.style.top= that.headerHeight+"px";
883
884      if( (that.embedDiv.getBoundingClientRect().top + that.extraMarginTop -window.innerHeight) > ( -parseInt(that.bwExplorerFrameBg.style.height) + that.extraMarginTop + that.extraMarginDown)  ) {
885        window.boldest.MapIframeCom.trigger(that, 'parentScroll', {ScrollY: that.embedDiv.getBoundingClientRect().top + that.extraMarginTop} );
886        //that.log('pp',that.bwExplorerFrameBg.style.height, that.embedDiv.getBoundingClientRect().top);
887      }
888      else {
889
890        // that.log('EMB onScrollOnFocus pegar scroll al fondo!!')
891        window.boldest.MapIframeCom.trigger(that, 'parentScrollForceBottom', {});
892      }
893      window.boldest.MapIframeCom.trigger(that, 'onFocus', {});
894      eval( that.embedDiv.getAttribute('onFocus') );
895    },
896
897    onScrollOnFocusOut: function(){
898      var that = this;
899      // that.log("EMB onScrollOnFocusOut");
900
901      if (typeof that.bwTakemeout !== 'undefined'){
902        that.bwTakemeout.style.display = 'none';
903      }
904
905      that.bwViewMap.style.display = 'inherit';
906      that.bwViewMapUse = true;
907
908      if( that.bwShowCurtain == true ) {
909        that.bwCurtain.style.display = 'inline';
910      }
911
912      if( that.scrollLocked == false ) {
913        if(  that.integration != 'modal' && that.embedDiv.getBoundingClientRect().top > that.headerHeight && that.embedDiv.getBoundingClientRect().top+parseInt(that.bwExplorerFrameBg.style.height)  > that.headerHeight ) { // situa arriba
914          // that.log("EMB onScrollOnFocusOut por arriba");
915          that.bwExplorerFrame.style.position = 'absolute';
916          that.bwExplorerFrame.style.top= "";
917          that.bwCurtain.style.top= "";
918
919          window.boldest.MapIframeCom.trigger(that, 'parentScroll', {ScrollY: 0} );
920        }
921        else if( that.ignoreBottomContent != 'true' ) {
922          // that.log("EMB onScrollOnFocusOut por debajo");
923          that.bwExplorerFrame.style.position = 'absolute';
924          that.bwExplorerFrame.style.top = that.embedDiv.offsetTop+ parseInt(that.bwExplorerFrameBg.style.height) - parseInt(that.bwExplorerFrame.style.height) + 'px';
925          that.bwCurtain.style.top = that.embedDiv.offsetTop+ parseInt(that.bwExplorerFrameBg.style.height) - parseInt(that.bwExplorerFrame.style.height) + 'px';
926
927          //window.boldest.MapIframeCom.trigger(that, 'parentScroll', {ScrollY: that.embedDiv.getBoundingClientRect().bottom} );
928          window.boldest.MapIframeCom.trigger(that, 'parentScrollForceBottom', {});
929
930        }
931        else {
932          that.bwTakemeout.style.display = 'inherit';
933          that.bwViewMap.style.display = 'none';
934        }
935        eval( that.embedDiv.getAttribute('onFocusOut') );
936        window.boldest.MapIframeCom.trigger(that, 'onFocusOut', {});
937      }
938      else {
939
940        // that.log("EMB onScrollOnFocusOut Bloqueado");
941        if(
942          that.embedDiv.getBoundingClientRect().top > that.headerHeight &&
943          that.embedDiv.getBoundingClientRect().top+parseInt(that.bwExplorerFrameBg.style.height)  > that.headerHeight
944        ) {
945          window.boldest.MapIframeCom.trigger(that, 'parentScroll', {ScrollY: 0} );
946          that.bwCurtain.style.display = 'none';
947        }
948        else if( that.ignoreBottomContent != 'true' ) {
949          window.boldest.MapIframeCom.trigger(that, 'parentScroll', {ScrollY: that.embedDiv.getBoundingClientRect().bottom} );
950        }
951
952      }
953    },
954
955    centerSegment: function() {
956      var that = this;
957      // Excepción para evitar el centrado automático del mapa en landings (pedido 14/07/26)
958      if (window.innerWidth < 768) {
959        return;
960      }
961
962      var sobra = window.innerHeight - (that.embedDiv.getBoundingClientRect().bottom -that.embedDiv.getBoundingClientRect().top);
963      var topPos = that.embedDiv.getBoundingClientRect().top + window.pageYOffset - sobra + 8;
964      window.scrollTo({ top: topPos, behavior: 'smooth' });
965    },
966
967    modalOpen: function() {
968      var that = this;
969      that.initializeAll(true); // Granted that everything is initialized
970      that.modalOpenReal();
971    },
972
973    modalOpenReal: function() {
974      var that = this;
975      that.bloquearScroll();
976      that.embedDiv.style.display = 'inherit';
977      that.bwTakemeout.style.display = 'inherit';
978      that.bwCurtain.style.display = 'inherit';
979
980      var elements = document.body.getElementsByTagName('*');
981      var maxZIndex = Array.from(elements).reduce(function (maxZ, element) {
982        var computedStyle = window.getComputedStyle(element);
983        var position = computedStyle.getPropertyValue('position');
984        that.bwCurtain.style.cursor = "auto";
985        if (position !== 'static') {
986          var zIndex = parseInt(computedStyle.getPropertyValue('z-index')) || 1;
987          return Math.max(maxZ, zIndex);
988        }
989
990        return maxZ;
991      }, 0);
992      that.embedDiv.style.zIndex = maxZIndex + 1;
993      that.bwCurtain.style.zIndex = maxZIndex + 2;
994      that.bwExplorerFrame.style.zIndex = maxZIndex + 3;
995      that.bwTakemeout.style.zIndex = maxZIndex + 3;
996
997      // bwBtnGroup z-index always above curtain when is visible
998      document.getElementById( "bwBtnGroup" ).style.position = "relative";
999      document.getElementById( "bwBtnGroup" ).style.zIndex = that.bwCurtain.style.zIndex + 1;
1000      // Show bwTakemeout as soon as the modal opens, without waiting for the iframe's 'showButtons' (sent once the map finishes loading)
1001      document.getElementById( "bwBtnGroup" ).style.display = "inherit";
1002
1003      // Ajuste fino en una franja de ancho de pantalla muy particular
1004      if( window.innerWidth >= 768 && window.innerWidth < 830 ) {
1005        that.log('ZZZ ANCHO MapIframe modalOpen: retirando todo espacio lateral');
1006        that.bwExplorerFrame.style.left = '0';
1007        that.bwExplorerFrame.style.width = '100%';
1008        that.bwExplorerFrame.style.borderLeftWidth = 0;
1009        that.bwExplorerFrame.style.borderRightWidth = 0;
1010      }
1011
1012      var closeImgElement = that.bwTakemeout.querySelector('img');
1013      if (closeImgElement) {
1014        closeImgElement.style.float = 'right';
1015        closeImgElement.style.marginTop = '2px';
1016      }
1017
1018      if( window.innerWidth < 768 ) {
1019        closeImgElement.style.marginLeft = '10px';
1020        that.bwTakemeout.style.paddingLeft = '15px';
1021        that.bwTakemeout.style.paddingRight = '10px';
1022      }
1023      else {
1024        closeImgElement.style.marginLeft = '20px';
1025        that.bwTakemeout.style.paddingLeft = '25px';
1026        that.bwTakemeout.style.paddingRight = '10px';
1027        //that.bwTakemeout.style.top = '0';
1028      }
1029
1030      // that.originScrollPosition = window.scrollY;
1031      window.boldest.MapIframeCom.trigger(that, 'modalOpen', {} );
1032    },
1033
1034    modalClose: function() {
1035      var that = this;
1036      that.log("EMB: modalClose");
1037      that.embedDiv.style.display = 'none';
1038      that.originScrollPosition = false
1039      that.desbloquearScroll();
1040      window.boldest.MapIframeCom.trigger(that, 'modalClose', {} );
1041    },
1042
1043    bloquearScroll: function() {
1044      var that = this;
1045      that.log("EMB: bloquearScroll");
1046      var scrollPosition = [
1047        self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
1048        self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
1049      ];
1050      var html = document.getElementsByTagName('html')[0];
1051      html.style.position = 'fixed';
1052      html.style.overflowY = 'scroll';
1053      html.style.width = '100%';
1054      html.style.top = '-' + scrollPosition[1] + 'px';
1055      that.actScroll = scrollPosition[1]; // Guardamos la posición del scroll para devolverla al desbloquear
1056    },
1057
1058    desbloquearScroll: function() {
1059      var that = this;
1060      that.log("EMB: desbloquearScroll");
1061      var html = document.getElementsByTagName('html')[0];
1062      html.style.position = '';
1063      html.style.overflowY = '';
1064      html.style.width = '';
1065      html.style.top = '';
1066      window.scrollTo(0, that.actScroll); // Devolvemos la página al punto donde estaba
1067    },
1068
1069
1070    // only for segment mode
1071    onScrollSegment: function() {
1072      var that = this;
1073      // that.log("EMB onScrollSegment");
1074
1075      that.bwTakemeout.style.display = 'none';
1076
1077      // that.log("EMB onScrollSegment checkVisibility", that.bwViewMap.checkVisibility() );
1078      that.bwViewMap.style.display = 'inherit';
1079      that.scrollSegmentSetUse();
1080    },
1081
1082    scrollSegmentSetUse: function() {
1083      var that = this;
1084
1085      // Manejo de bwViewMap (si se visualizan los botones)
1086      if(that.bwShowButtons) {
1087        var bwViewMapRect = that.bwViewMap.getBoundingClientRect();
1088        var bwViewMapTop = bwViewMapRect.top;
1089
1090        // bwViewMap is fixed-positioned, so offsetTop stays at 0 when only bottom is set.
1091        if( bwViewMapRect.height > 0 ) {
1092          // that.log("EMB scrollSegmentSetUse FUNCIONA", bwViewMapTop );
1093          that.bwViewMapUse = true;
1094
1095          // Guardamos porque con display:none el rect se resetea.
1096          that.bwViewMap.lastOffsetTop = bwViewMapTop;
1097          // Controlamos si el boton queda mas bajo que el mapa
1098          if( bwViewMapTop > that.embedDiv.getBoundingClientRect().bottom ) {
1099            // children[0] = img
1100            that.bwViewMap.children[0].src = that.embedDiv.getAttribute('embedUrl')+'/'+that.btn_out_img;
1101          }
1102
1103          // Lanzado para el chequeo inicial
1104          that.scrollSegmentChecks();
1105        }
1106        else {
1107          // that.log("EMB scrollSegmentSetUse FALLA ...REINTENTA" );
1108          setTimeout(function() {
1109            that.scrollSegmentSetUse();
1110          }, 200);
1111        }
1112      }
1113    },
1114
1115    scrollSegmentChecks: function( force = false ) {
1116      var that = this;
1117      // that.log("EMB scrollSegmentChecks");
1118
1119      // Manejo de bwViewMap (si se visualizan los botones)
1120      if(that.bwShowButtons) {
1121        var over = 100; // px
1122        var bwPos = that.embedDiv.getBoundingClientRect();
1123
1124        if( that.bwViewMapUse ) { // Si ya lo estamos usando
1125          // that.log( "EMB scrollSegmentChecks Fun ",
1126          //   that.bwViewMap.style.display, that.bwViewMap.offsetTop,
1127          //   that.bwViewMap.getBoundingClientRect(), bwPos );
1128
1129          if( that.bwViewMap.style.display === 'inherit' ) {
1130            // that.log("EMB scrollSegmentChecks inherit");
1131            var btTop = that.bwViewMap.getBoundingClientRect().top;
1132            if( btTop > bwPos.top+over && btTop < bwPos.bottom ) {
1133              // that.log( "EMB scrollSegmentChecks SET none", btTop, bwPos.top );
1134              that.bwViewMap.lastOffsetTop = btTop; // guardamos porque con display:none el rect se resetea
1135              that.bwViewMap.style.display = 'none';
1136            }
1137          }
1138          else {
1139            if( that.bwViewMap.lastOffsetTop < bwPos.top+over ) {
1140              // that.log( "EMB scrollSegmentChecks SET inherit up", that.bwViewMap.offsetTop, bwPos.top );
1141              that.bwViewMap.style.display = 'inherit';
1142              // children[0] = img
1143              that.bwViewMap.children[0].src = that.embedDiv.getAttribute('embedUrl')+'/embed_btn_down.png';
1144            }
1145            else if( that.bwViewMap.lastOffsetTop > bwPos.bottom ) {
1146              // that.log( "EMB scrollSegmentChecks SET inherit down", that.bwViewMap.offsetTop, bwPos.top );
1147              that.bwViewMap.style.display = 'inherit';
1148              // children[0] = img
1149              that.bwViewMap.children[0].src = that.embedDiv.getAttribute('embedUrl')+'/'+that.btn_out_img;
1150            }
1151          }
1152        }
1153      }
1154    },
1155
1156    getDistanceFromTop: function ( elem ) {
1157      var that = this;
1158      // that.log("EMB getDistanceFromTop");
1159      var location = 0;
1160      if (elem.offsetParent) {
1161        do {
1162          location += elem.offsetTop;
1163          elem = elem.offsetParent;
1164        } while (elem);
1165      }
1166      return location >= 0 ? location : 0;
1167    },
1168
1169    scrollTop: function() {
1170      var that = this;
1171      // that.log("EMB scrollTop");
1172
1173      if( that.integration == 'full') {
1174        //window.scrollTo(0, (that.bwExplorerFrameBg.offsetTop+that.extraMarginTop) );  // antiguo scroll top
1175        window.scrollTo(0,  window.pageYOffset+that.embedDiv.getBoundingClientRect().top+that.extraMarginTop);
1176        //that.log(0,  window.pageYOffset , that.embedDiv.getBoundingClientRect().top , that.extraMarginTop);
1177        window.boldest.MapIframeCom.trigger(that, 'parentScroll', {ScrollY: 0} );
1178      }
1179    },
1180
1181    onWindowResize: function() {
1182      var that = this;
1183
1184
1185      if( that.integration == 'full' || that.integration == 'modal' ) {
1186        //window.scrollTo(0, 0);
1187        //that.log('window_resize', window.innerHeight - that.headerHeight+"px");
1188
1189        // iframe dimensions
1190        that.bwExplorerFrameBg.style.height= 3000000+"px";
1191        //that.bwExplorerFrameBg.style.height= window.innerHeight - that.headerHeight+"px";
1192        that.bwExplorerFrame.style.height= window.innerHeight - that.headerHeight+"px";
1193        that.bwExplorerFrame.style.width= window.innerWidth+"px";
1194
1195        // curtain dimensions
1196        that.bwCurtain.style.height = window.innerHeight - that.headerHeight+"px";
1197        that.bwCurtain.style.width = window.innerWidth+"px";
1198
1199        //that.onScroll();
1200      }
1201      else
1202      if( that.integration == 'segment' ) {
1203        that.bwExplorerFrame.style.height= "100%";
1204        that.bwExplorerFrame.style.width= "100%";
1205      }
1206    },
1207
1208    onWindowResizeAntiguo: function() {
1209      var that = this;
1210
1211      //window.scrollTo(0, 0);
1212
1213      // iframe dimensions
1214
1215      that.bwExplorerFrameBg.style.height= window.innerHeight - that.headerHeight+"px";
1216      that.bwExplorerFrame.style.height= window.innerHeight - that.headerHeight+"px";
1217
1218      // curtain dimensions
1219      that.bwCurtain.style.height = window.innerHeight - that.headerHeight+"px";
1220
1221
1222      //that.onScroll();
1223    },
1224
1225    scrollUnLock: function() {
1226      var that = this;
1227      that.scrollLocked = false;
1228    },
1229
1230    scrollLock: function() {
1231      var that = this;
1232      that.scrollLocked = true;
1233    },
1234
1235    updateInterfaceAttributes: function(attr){
1236      var that = this;
1237      if (document.getElementById("btnBackLanding") != null) {
1238        that.log('UPDATE INTERFACE ATTRIBUTES', attr);
1239        if (attr.onMap != false) {
1240          document.getElementById("btnBackLanding").classList.add('onMap');
1241          document.getElementById("btnBackLanding").classList.remove('onList');
1242        }
1243        else{
1244          document.getElementById("btnBackLanding").classList.remove('onMap');
1245          document.getElementById("btnBackLanding").classList.add('onList');
1246        }
1247      }
1248    },
1249
1250
1251    // Verificamos si se esta mostrando el bwViewMap por primera vez
1252    checkFirstTimeBwEmbedView: function() {
1253      var that = this;
1254      if( !this.firstTimeBwEmbedView) {
1255        var wHeight = window.innerHeight;
1256        var ifRect = this.embedDiv.getBoundingClientRect();
1257        var dTop = parseInt(ifRect.top);
1258        var dBot = (-1)*parseInt(ifRect.top+ifRect.height-wHeight);
1259
1260        var ifH4 = ifRect.height/4; // 25% del alto del iframe
1261        var wH2 = wHeight/2;        // 50% del alto de la ventana
1262
1263        var dentro = false;
1264        dentro = dentro || ( dTop < 0 && ifH4+dTop > 0 ); // B.inf. 25% del bw por encima
1265        dentro = dentro || ( dTop >= 0 && wH2-dTop > 0 ); // B.inf. 50% superior de la ventana
1266        dentro = dentro || ( dBot < 0 && ifH4+dBot > 0 ); // B.sup. 25% del bw por debajo
1267        dentro = dentro || ( dBot >= 0 && wH2-dBot > 0 ); // B.sup. 50% inferior de la ventana
1268        if( dentro ) {
1269          this.setFirstTimeBwEmbedView();
1270        }
1271      }
1272    },
1273    setFirstTimeBwEmbedView: function() {
1274      var that = this;
1275      // that.log("EMB checkFirstTimeBwEmbedView DENTRO" );
1276
1277      that.firstTimeBwEmbedView = true;
1278
1279      // Recibe ACK del BW
1280      window.boldest.MapIframeCom.on('firstTimeBwEmbedViewRx', function () {
1281        // that.log('EMB firstTimeBwEmbedViewRx MapIframeCom.on');
1282        that.firstTimeBwEmbedViewRx = true;
1283      });
1284
1285      // Envia firstTimeBwEmbedView hasta recibir ACK
1286      window.boldest.MapIframeCom.trigger(that, 'firstTimeBwEmbedView', true);
1287      that.firstTimeBwEmbedViewTx = setInterval( function() {
1288        if( that.firstTimeBwEmbedViewRx ) {
1289          clearInterval( that.firstTimeBwEmbedViewTx );
1290          that.firstTimeBwEmbedViewTx = false;
1291        }
1292        else {
1293          // Enviando firstTimeBwEmbedView
1294          window.boldest.MapIframeCom.trigger(that, 'firstTimeBwEmbedView', true);
1295        }
1296      }, 500 );
1297    },
1298
1299    setFiltersFromParent: function( filters ) {
1300      var that = this;
1301      var filtersData = {
1302        mainCategory: null,
1303        filtermap: null,
1304        routeDuration: null,
1305        routeDistance: null,
1306        routeDifficulty: null,
1307        routeCircular: null,
1308      };
1309      if( filters.referenceFilterBy != null ) {
1310        filtersData.referenceFilterBy = filters.referenceFilterBy;
1311      }
1312      if( filters.mainCategory != null ) {
1313        filtersData.mainCategory = filters.mainCategory;
1314      }
1315      if(filters.filtermap != null) {
1316        filtersData.filtermap = filters.filtermap;
1317      }
1318      var distanceSource = 'none';
1319      var distanceValue = null;
1320      if(filters.routeDistance != null) {
1321        distanceSource = 'routeDistance';
1322        distanceValue = filters.routeDistance;
1323      }
1324      else if(filters.routeDuration != null) {
1325        distanceSource = 'routeDuration';
1326        distanceValue = filters.routeDuration;
1327      }
1328      else if(filters.distance != null) {
1329        distanceSource = 'distance';
1330        distanceValue = filters.distance;
1331      }
1332      if(distanceValue != null) {
1333        // Keep both keys to support desktop/mobile + legacy integrations.
1334        filtersData.routeDistance = distanceValue;
1335        filtersData.routeDuration = distanceValue;
1336      }
1337      if(filters.routeDifficulty != null) {
1338        filtersData.routeDifficulty = filters.routeDifficulty;
1339      }
1340      if(filters.routeCircular != null) {
1341        filtersData.routeCircular = filters.routeCircular;
1342      }
1343
1344      window.boldest.MapIframeCom.trigger(that, 'setFiltersValuesFromParent', filtersData);
1345    },
1346
1347    onSetFiltersFromSon: function( setFiltersCallback ) {
1348      var that = this;
1349      window.boldest.MapIframeCom.on('setFiltersValuesFromSon', function (filters) {
1350        var filtersData = {
1351          mainCategory: null,
1352          filtermap: null,
1353          routeDuration: null,
1354          routeDistance: null,
1355          routeDifficulty: null,
1356          routeCircular: null,
1357        };
1358        if( filters.mainCategory != null ) {
1359          filtersData.mainCategory = filters.mainCategory;
1360        }
1361        if(filters.filtermap != null) {
1362          filtersData.filtermap = filters.filtermap;
1363        }
1364        if(filters.routeDuration != null) {
1365          filtersData.routeDuration = filters.routeDuration;
1366        }
1367        if(filters.routeDistance != null) {
1368          filtersData.routeDistance = filters.routeDistance;
1369        }
1370        if(filters.routeDistance != null) {
1371          // Convenience alias for host pages that use filters.distance.
1372          filtersData.distance = filters.routeDistance;
1373        }
1374        else if(filters.routeDuration != null) {
1375          filtersData.distance = filters.routeDuration;
1376        }
1377        if(filters.routeDifficulty != null) {
1378          filtersData.routeDifficulty = filters.routeDifficulty;
1379        }
1380        if(filters.routeCircular != null) {
1381          filtersData.routeCircular = filters.routeCircular;
1382        }
1383        setFiltersCallback(filtersData);
1384      });
1385    },
1386
1387    gtmInitialize: function( gtmKey ) {
1388      var that = this;
1389
1390      // that.log( "GTAGlog embed ckAcepto init", gtmKey, window.location.pathname );
1391
1392      var loadGtmScript = document.createElement( 'script' );
1393      loadGtmScript.type = 'text/javascript';
1394      loadGtmScript.text = "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':" +
1395        "new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0]," +
1396        "j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=" +
1397        "'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);" +
1398        "})(window,document,'script','dataBWLandLayer','" + gtmKey + "');";
1399      document.body.appendChild( loadGtmScript );
1400
1401      // Processa gtag en landing con layer propio
1402      that.gtag = function gtag() {
1403        // that.log('GTAGlog embed.js gtag', arguments, window.location.pathname);
1404        dataBWLandLayer.push(arguments);
1405      }
1406
1407      // Recibe gtag del iframe BW
1408      window.boldest.MapIframeCom.on('gtag', function ( params ) {
1409        // that.log('GTAGlog embed.js MapIframeCom.on gtag', params, window.location.pathname);
1410        that.gtag( ...params );
1411      });
1412
1413      // Recibe gtagPush del iframe BW (para gtag pasados)
1414      window.boldest.MapIframeCom.on('gtagPush', function ( params ) {
1415        // that.log('GTAGlog embed.js MapIframeCom.on gtagPush', params, window.location.pathname);
1416        dataBWLandLayer.push( params );
1417      });
1418
1419      // that.log( "GTAGlog embed.js enviando gtmInitializeDone" );
1420      window.boldest.MapIframeCom.trigger(that, 'gtmInitializeDone', true);
1421    },
1422
1423    log: function() {
1424      console.log.apply( console, arguments ); // console.log( arguments );
1425    },
1426
1427    isFrameReady: function() {
1428      var that = this;
1429      return that.firstTimeBwEmbedViewRx;
1430    },
1431
1432    halt: function() {
1433      var that = this;
1434      that.halted = true;
1435    },
1436};
1437
1438//
1439// frame Page
1440//
1441window.boldest.PageIframe = {
1442    embedDivId: "bWidgetPage",
1443    embedDiv: false,
1444    container: false,
1445    bwExplorerFrame: false,
1446
1447    initialize: function() {
1448      var that = this;
1449
1450      that.embedDiv = document.getElementById( that.embedDivId );
1451      if( typeof that.embedDiv == 'undefined' || that.embedDiv == null ) {
1452        return;
1453      }
1454
1455      that.showLoading();
1456      that.setContainers();
1457      that.bwExplorerFrame = document.getElementById("bwPageFrame");
1458      window.boldest.MapIframeCom.on('firstLoad', function (params) {
1459        that.hideLoading();
1460        that.setHeight(params.height);
1461      });
1462      window.boldest.MapIframeCom.on('updateHeight', function (params) {
1463        that.setHeight(params.newHeight);
1464      });
1465    },
1466
1467    setContainers: function() {
1468      var that = this;
1469      var mainUri = that.embedDiv.getAttribute('embedMainUri');
1470      var iframeUrl = that.embedDiv.getAttribute('embedUrl') + mainUri;
1471      that.embedDiv.innerHTML = "" +
1472        "<iframe "+
1473          "id=\"bwPageFrame\" " +
1474          "src=\""+iframeUrl+"\" " +
1475          "width=\"100%\" " +
1476          "height=\"0\" " +
1477          "scrolling=\"no\" " +
1478          "frameborder=\"0\" " +
1479          "onload=\"window.boldest.PageIframe.onLoadIframe()\">" +
1480        "</iframe>" +
1481        "<div id=\"bwPageFrameLoading\"></div>";
1482    },
1483
1484    hideLoading: function() {
1485      var that = this;
1486    },
1487
1488    showLoading: function() {
1489      var that = this;
1490    },
1491
1492    setHeight: function( height ) {
1493      var that = this;
1494      var bwPageFrame = document.getElementById("bwPageFrame");
1495      bwPageFrame.style.height = height + "px";
1496    },
1497
1498    onLoadIframe: function() {
1499      var that = this;
1500      var bwPageFrame = document.getElementById("bwPageFrame");
1501    }
1502
1503};
1504
1505//
1506// EVENT LISTENERS
1507//
1508document.addEventListener( "DOMContentLoaded", function(event) {
1509  // console.log("EMB DOMContentLoaded listener: initializeAll");
1510  window.boldest.MapIframe.initializeAll();
1511});
1512
1513//
1514// Legacy support
1515//
1516window.MapIframeCom = window.boldest.MapIframeCom;
1517window.MapIframe = window.boldest.MapIframe;
1518window.PageIframe = window.boldest.PageIframe;

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.