PageSourceSearch

https://www.bankinter.com/file_source/Common/res/js/core-functions.js

js bankinter.com collected 2026-10-02 02:18:24 UTC 100,214 bytes, 2,617 lines download raw bytes

1let isIE, resizeTimer, firstTab = false;
2let bkjs = {
3  commons: {
4    // Declaración correcta sin leak global
5    isIE: false,
6
7    msieversion() {
8      this.isIE = /MSIE|Trident|Edge/.test(window.navigator.userAgent);
9      return this.isIE;
10    },
11
12    goToIdTarget() {
13      // 1. Inyectar parámetro idtarget en enlaces
14      document.querySelectorAll('[id-target]').forEach((elem) => {
15        const href = elem.getAttribute('href') || '';
16        const separator = href.includes('?') ? '&' : '?';
17        const targetId = elem.getAttribute('id-target');
18        elem.setAttribute('href', `${href}${separator}idtarget=${targetId}`);
19      });
20
21      // 2. Procesar navegación por idtarget en URL
22      const params = new URLSearchParams(document.location.search);
23      const tabId = params.get('idtarget');
24
25      if (tabId) {
26        const targetElem = document.getElementById(tabId);
27        if (targetElem) {
28          const button = targetElem.querySelector('button') || targetElem;
29          button.click();
30          location.href = `#${tabId}`;
31        }
32      }
33    },
34
35    toggleHeaderSize() {
36      if (this.isIE) return;
37
38      const header = document.querySelector('.header_NW');
39      if (!header || header.classList.contains('privada_NW')) return;
40
41      const logo = document.getElementById('logo_NW');
42      const logoIE = document.getElementById('logo_IE_min');
43      const scrollLimit = 5;
44
45      window.addEventListener('scroll', () => {
46        if (document.body.getBoundingClientRect().width < 990) return;
47
48        const isScrolled = window.pageYOffset > scrollLimit;
49
50        if (logo) logo.classList.toggle('logo_NW_min', isScrolled);
51        header.classList.toggle('min', isScrolled);
52
53        if (logoIE) {
54          const mainLogo = logoIE.querySelector('.logo_IE');
55          const minLogo = logoIE.querySelector('.logo_IE_min');
56
57          if (mainLogo) mainLogo.classList.toggle('d-none', isScrolled);
58          if (minLogo) minLogo.classList.toggle('d-none', !isScrolled);
59        }
60      }, { passive: true });
61    },
62
63    setMainContentPaddingTop() {
64      const mainContent = document.querySelector('.main-content:not(.blog)');
65      const headerBkWem = document.querySelector('.header-bk-wem');
66      const secondLevel = document.querySelector('.secondLevel');
67      const header = document.querySelector('header');
68      const reporting = document.querySelector('.header-rp');
69
70      if (reporting) {
71        document.documentElement.style.height = '100%';
72      }
73
74      if (header && !headerBkWem && !reporting && mainContent) {
75        let totalPadding = header.getBoundingClientRect().height;
76        if (secondLevel) {
77          totalPadding += secondLevel.getBoundingClientRect().height;
78        }
79        mainContent.style.paddingTop = `${totalPadding}px`;
80      }
81    },
82
83    cleanMenuRoboadvisor() {
84      document.querySelectorAll('.header-bk-wem__sublistul').forEach((menu) => {
85        if (menu.firstElementChild) {
86          menu.firstElementChild.classList.remove('col-lg-8');
87        }
88      });
89    },
90
91    setMenuActiveOption() {
92      const currentPath = document.location.pathname;
93
94      document.querySelectorAll('.header-bk-wem__sublist-link').forEach((link) => {
95        const isPathMatch = link.pathname === currentPath && !link.href.includes('#');
96        const isHrefIncluded = currentPath.includes(link.getAttribute('href'));
97
98        if (isPathMatch || isHrefIncluded) {
99          link.setAttribute('header-link-submenu-active', 'true');
100        }
101      });
102
103      const activeSubMenu = document.querySelector('.header-bk-wem__sublist-link--active-link');
104      if (activeSubMenu) {
105        const parentListItem = activeSubMenu.closest('.header-bk-wem__list-item');
106        if (parentListItem) {
107          const subLink = parentListItem.querySelector('.header-bk-wem__sublist-link');
108          if (subLink) subLink.classList.add('header-bk-wem__sublist-link--active');
109        }
110      }
111    },
112
113    setBodyMarginBottom() {
114      const footer = document.querySelector('.footer');
115      if (footer) {
116        const isDesktop = document.body.getBoundingClientRect().width > 990;
117        const footerHeight = isDesktop ? footer.getBoundingClientRect().height : 0;
118        document.body.style.marginBottom = `${footerHeight}px`;
119      }
120    },
121
122    loadingButton() {
123      document.querySelectorAll('.btn--loading').forEach((btn) => {
124        btn.addEventListener('click', (e) => {
125          const target = e.currentTarget;
126          target.classList.add('btn--loading-disabled');
127          target.setAttribute('disabled', 'true');
128        });
129      });
130    },
131
132    closeLayer() {
133      document.querySelectorAll('.element-to-close').forEach((layer) => {
134        const closeBtn = layer.querySelector('.close');
135        if (closeBtn) {
136          closeBtn.addEventListener('click', () => {
137            layer.style.display = 'none';
138          });
139        }
140      });
141    },
142
143    classesToEl(element, action, className) {
144      if (!element) return;
145      if (action === 'add') element.classList.add(className);
146      else if (action === 'remove') element.classList.remove(className);
147      else if (action === 'toggle') element.classList.toggle(className);
148    },
149
150    disableButton(element) {
151      if (element) element.setAttribute('disabled', 'true');
152    },
153
154    enableButton(element) {
155      if (element) element.removeAttribute('disabled');
156    },
157
158    isElementInScreen(selector, jsonArray = []) {
159      const element = document.querySelector(selector);
160      if (!element) return;
161
162      const screenBottom = window.innerHeight;
163      let eventFired = false;
164
165      const checkAndTrigger = () => {
166        if (!eventFired && element.getBoundingClientRect().bottom <= screenBottom) {
167          jsonArray.forEach((json) => bkjs.gtm.doEventAnalyticsPromoViewEEC(json));
168          eventFired = true;
169        }
170      };
171
172      checkAndTrigger();
173      window.addEventListener('scroll', checkAndTrigger, { passive: true });
174    },
175
176    isElementContentBoxInScreen(selector, jsonArray = []) {
177      const element = document.querySelector(selector);
178      if (!element) return;
179
180      const marker = element.closest('.content-box');
181      if (!marker) return;
182
183      const screenBottom = window.innerHeight;
184      let eventFired = false;
185
186      const checkAndTrigger = () => {
187        if (!eventFired && marker.getBoundingClientRect().bottom <= screenBottom) {
188          jsonArray.forEach((json) => bkjs.gtm.doEventAnalyticsPromoViewEEC(json));
189          eventFired = true;
190        }
191      };
192
193      checkAndTrigger();
194      window.addEventListener('scroll', checkAndTrigger, { passive: true });
195    },
196
197    mainBannerCarousel() {
198      document.querySelectorAll('.main-banner-carrousel .main-banner__square').forEach((btn) => {
199        btn.addEventListener('click', function () {
200          const firstSlide = this.closest('.main-banner-carrousel__slide:first-child');
201          if (!firstSlide) return;
202
203          const nextSlide = firstSlide.nextElementSibling;
204          if (nextSlide) {
205            nextSlide.classList.add('active');
206            firstSlide.classList.remove('active');
207
208            const lastSlide = document.querySelector('.main-banner-carrousel__slide:last-child');
209            if (lastSlide) {
210              setTimeout(() => lastSlide.after(firstSlide), 600);
211            }
212          }
213        });
214      });
215    },
216
217    setElementSticky(selector) {
218      const element = document.querySelector(selector);
219      if (!element) return;
220
221      const screenBottom = window.innerHeight;
222      const footer = document.querySelector('.footer') || document.querySelector('.footer-gray');
223      const footerHeight = footer ? footer.getBoundingClientRect().height : 0;
224      const stickyHeight = element.getBoundingClientRect().height;
225      const featuredBox = document.querySelector('.featured-box');
226
227      const isBlocked = featuredBox && (
228        featuredBox.classList.contains('featured-box_sticky--bloqued') ||
229        featuredBox.classList.contains('featured-box--sticky-bloqued')
230      );
231
232      if (isBlocked) {
233        element.classList.add('featured-box_sticky');
234        return true;
235      }
236
237      window.addEventListener('scroll', () => {
238        let totalHeight;
239        const isDesktop = document.body.getBoundingClientRect().width >= 768;
240        const isSticky = element.classList.contains('featured-box_sticky');
241
242        if (isDesktop && !isSticky && element.getBoundingClientRect().bottom <= screenBottom) {
243          element.classList.add('featured-box_sticky');
244          totalHeight = footerHeight + stickyHeight;
245
246          if (footer) {
247            footer.style.paddingBottom = `${stickyHeight}px`;
248            footer.style.bottom = `-${stickyHeight}px`;
249          }
250        }
251
252        const wrapper = element.closest('.featured-box__wrapper');
253        if (isSticky && wrapper && wrapper.getBoundingClientRect().top > (screenBottom - element.getBoundingClientRect().height)) {
254          element.classList.remove('featured-box_sticky');
255        }
256
257        if (document.body.getBoundingClientRect().width > 990) {
258          document.body.style.marginBottom = totalHeight ? `${totalHeight}px` : '0px';
259        }
260      }, { passive: true });
261    },
262
263    equalSize(parentSelector, childSelector, extraHeight = 0) {
264      const extra = typeof extraHeight === 'number' ? extraHeight : 0;
265
266      document.querySelectorAll(parentSelector).forEach((parent) => {
267        if (!parent || !parent.firstElementChild) return;
268
269        const isEqualSize = parent.classList.contains('equal-size') || parent.firstElementChild.classList.contains('equal-size');
270        if (!isEqualSize) return;
271
272        const children = parent.querySelectorAll(childSelector);
273        let maxHeight = 0;
274
275        children.forEach((child) => {
276          child.removeAttribute('style');
277          const height = child.getBoundingClientRect().height;
278          if (height > maxHeight) maxHeight = height;
279        });
280
281        maxHeight += extra;
282        const isMobile = window.innerWidth < 576;
283
284        children.forEach((child) => {
285          child.style.height = isMobile ? 'auto' : `${maxHeight}px`;
286        });
287      });
288    },
289
290    equalSizeNoParentElement(selector) {
291      const boxes = document.querySelectorAll(selector);
292      if (!boxes.length) return;
293
294      let maxHeight = 0;
295      boxes.forEach((box) => {
296        const height = box.getBoundingClientRect().height;
297        if (height > maxHeight) maxHeight = height;
298      });
299
300      boxes.forEach((box) => {
301        box.style.height = `${maxHeight}px`;
302      });
303    },
304
305    analyzeFormContent() {
306      const inputGroups = document.querySelectorAll('.form__input-group');
307      inputGroups.forEach((group) => {
308        const input = group.querySelector('input');
309        if (input && input.value !== '') {
310          input.classList.add('has-contain');
311        }
312      });
313      this.changeFormEvent(inputGroups);
314    },
315
316    changeFormEvent(groups) {
317      groups.forEach((group) => {
318        const input = group.querySelector('input');
319        if (!input) return;
320
321        const type = input.getAttribute('type');
322        if (type === 'button' || type === 'submit') return;
323
324        input.addEventListener('input', function () {
325          this.classList.toggle('has-contain', this.value !== '');
326        });
327      });
328    },
329
330    setFocusOnOpenedElement(element) {
331      if (element && typeof element.focus === 'function') {
332        element.focus();
333      }
334    },
335
336    opinatorPagaComodoAbandono() {
337      try {
338        const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
339        if (isMobile || window.location.href.includes('creditopagacomodo')) return;
340
341        const flagOpi = sessionStorage.getItem('mostrarOpiPagaComodo');
342        if (flagOpi !== 'S') return;
343
344        const persCript = sessionStorage.getItem('persCript');
345        const opiDestino = 'BK-APP-PARTICULARES-PAGACOMODO-ABANDONO';
346
347        const scriptTag = document.createElement('script');
348        scriptTag.src = '/res/js/bancaParticulares/opina/opina-min-23.js';
349        const firstScript = document.getElementsByTagName('script')[0];
350        firstScript.parentNode.insertBefore(scriptTag, firstScript);
351
352        setTimeout(() => {
353          if (window.OPINATOR) {
354            OPINATOR.mustShowOpi(
355              opiDestino,
356              persCript,
357              () => {
358                OPINATOR.showOpi(opiDestino, persCript);
359                console.log('sat ok');
360              },
361              () => console.log('sat ko')
362            );
363          }
364        }, 2000);
365
366        sessionStorage.removeItem('mostrarOpiPagaComodo');
367        sessionStorage.removeItem('persCript');
368      } catch (error) {
369        // Manejo silencioso original
370      }
371    }
372  },
373
374  animateHeight: {
375    collapseSectionAccesible(element) {
376      if (!element) return;
377      const target = element.nextElementSibling || element;
378
379      // Medir la altura actual antes de colapsar
380      const sectionHeight = target.scrollHeight;
381      const elementTransition = target.style.transition;
382
383      // Preparar el elemento para la transición desde su altura actual
384      target.style.transition = '';
385      requestAnimationFrame(() => {
386        target.style.height = `${sectionHeight}px`;
387        target.style.transition = elementTransition;
388
389        // En el siguiente frame, colapsamos a 0
390        requestAnimationFrame(() => {
391          target.style.height = '0px';
392          element.setAttribute('data-collapsed', 'true');
393        });
394      });
395
396      // Ocultar al finalizar la transición o forzar el atributo de accesibilidad
397      target.setAttribute('hidden', 'hidden');
398    },
399
400    expandSectionAccesible(element) {
401      if (!element) return;
402      const target = element.nextElementSibling || element;
403
404      target.removeAttribute('hidden');
405      target.style.height = '';
406      element.setAttribute('data-collapsed', 'false');
407    }
408  },
409  components: {
410    slideRiskIndicator(riskIndicatorId) {
411      const element = document.getElementById(riskIndicatorId);
412      if (!element) return;
413
414      const buttons = element.querySelectorAll('.carousel__controls__button');
415      const isSpecialIndicator = riskIndicatorId.includes('risk-indicator02b');
416      const prevElem = element.previousElementSibling;
417
418      if (isSpecialIndicator && prevElem) {
419        let legend = prevElem.querySelector('.risk-indicator-legend');
420        if (!legend) {
421          legend = document.createElement('div');
422          legend.className = 'risk-indicator-legend';
423          legend.textContent = 'Cuenta y Depósito';
424          prevElem.appendChild(legend);
425        }
426      }
427
428      buttons.forEach((btn) => {
429        btn.addEventListener('click', (e) => {
430          const currentBtn = e.currentTarget;
431
432          // Cambiar botón activo
433          const activeBtn = element.querySelector('.carousel__controls__button.active');
434          if (activeBtn) activeBtn.classList.remove('active');
435          currentBtn.classList.add('active');
436
437          // Eliminar clases 'slide1'..'slide5' de forma limpia
438          element.className = element.className.replace(/\bslide\d+\b/g, '').trim();
439
440          // Agregar la nueva clase de slide
441          const targetSlide = currentBtn.dataset.slide;
442          if (targetSlide) {
443            element.classList.add(`slide${targetSlide}`);
444          }
445
446          // Actualizar leyenda en caso especial
447          if (isSpecialIndicator && prevElem) {
448            const legend = prevElem.querySelector('.risk-indicator-legend');
449            if (legend) {
450              legend.textContent = (targetSlide === '3') ? 'Sólo para el Depósito' : 'Cuenta y Depósito';
451            }
452          }
453        });
454      });
455    },
456    toggleDropdown() {
457      let elements = document.querySelectorAll('.dropdown-toggle');
458
459      function clickToggleDropdown(e) {
460        this.closest('.dropdown').classList.toggle('opened');
461        if (this.closest('.dropdown').classList.contains('opened')) {
462          e.currentTarget.setAttribute('aria-expanded', 'true');
463          bkjs.commons.setFocusOnOpenedElement(this.closest('.dropdown').querySelector('.dropdown-menu'));
464          e.currentTarget.closest('.dropdown').querySelector('.dropdown-menu').querySelectorAll('li')[0].querySelector('a').focus();
465        } else {
466          e.currentTarget.setAttribute('aria-expanded', 'false');
467          e.currentTarget.blur();
468        }
469      }
470
471      function focusDropdown(e) {
472        if (e.keyCode === 38 && document.activeElement === childElements[0]) {
473          e.preventDefault();
474          e.stopPropagation();
475          return false;
476        } else {
477          document.activeElement.closest('li').previousElementSibling.querySelector('a').focus();
478        }
479        if (e.keyCode === 40 && document.activeElement === childElements[elementsLength]) {
480          e.preventDefault();
481          e.stopPropagation();
482          return false;
483        } else {
484          document.activeElement.closest('li').nextElementSibling.querySelector('a').focus();
485        }
486        if (e.keyCode === 27) {
487          document.activeElement.closest('.dropdown').classList.remove('opened');
488          document.activeElement.closest('.dropdown').querySelector('.dropdown-toggle').focus();
489        }
490      }
491
492      for (let i = elements.length - 1; i >= 0; i--) {
493        elements[i].addEventListener('click', clickToggleDropdown);
494        let childElements = elements[i].closest('.dropdown').querySelector('.dropdown-menu').querySelectorAll('li a');
495        for (let j = 0; j < childElements.length; j++) {
496          let child = childElements[j];
497          child.addEventListener('keydown', focusDropdown);
498        }
499      }
500      let elements2 = document.querySelectorAll('.dropdown__toggle');
501
502      function clickDropdown(e) {
503        this.closest('.dropdown').classList.toggle('dropdown--opened');
504        if (this.closest('.dropdown').classList.contains('dropdown--opened')) {
505          e.currentTarget.setAttribute('aria-expanded', 'true');
506          bkjs.commons.setFocusOnOpenedElement(this.closest('.dropdown').querySelector('.dropdown__menu'));
507          e.currentTarget.closest('.dropdown').querySelector('.dropdown__menu').querySelectorAll('li')[0].querySelector('a').focus();
508        } else {
509          e.currentTarget.setAttribute('aria-expanded', 'false');
510          e.currentTarget.blur();
511        }
512      }
513
514      for (let w = elements2.length - 1; w >= 0; w--) {
515        elements2[w].addEventListener('click', clickDropdown);
516        let childElements2 = elements2[w].closest('.dropdown').querySelector('.dropdown__menu').querySelectorAll('li a');
517        for (let d = 0; d < childElements2.length; d++) {
518          let elementsLength2 = childElements2.length - 1;
519          let child2 = childElements2[d];
520          child2.addEventListener('keydown', function (e) {
521            if (e.keyCode === 38) {
522              e.preventDefault();
523              if (document.activeElement === childElements2[0]) {
524                return false;
525              } else {
526                document.activeElement.closest('li').previousElementSibling.querySelector('a').focus();
527              }
528              e.stopPropagation();
529            } else if (e.keyCode === 40) {
530              e.preventDefault();
531              if (document.activeElement === childElements2[elementsLength2]) {
532                return false;
533              } else {
534                document.activeElement.closest('li').nextElementSibling.querySelector('a').focus();
535              }
536              e.stopPropagation();
537            } else if (e.keyCode === 27) {
538              document.activeElement.closest('.dropdown').classList.remove('dropdown--opened');
539              document.activeElement.closest('.dropdown').querySelector('.dropdown__toggle').focus();
540            }
541          });
542        }
543      }
544    },
545    toggleCheckboxEllipsis() {
546      document.querySelectorAll('.checkbox-ellipsis').forEach((element) => {
547        // Manejador de click
548        element.addEventListener('click', (e) => {
549          const target = e.currentTarget;
550          bkjs.commons.classesToEl(target, 'toggle', 'checkbox-ellipsis--opened');
551
552          const isOpened = target.classList.contains('checkbox-ellipsis--opened');
553          target.setAttribute('aria-expanded', isOpened ? 'true' : 'false');
554        });
555
556        // Manejador para la interacción con teclado (Enter / Espacio)
557        element.addEventListener('keyup', (e) => {
558          const isEnter = e.key === 'Enter' || e.keyCode === 13;
559          const isSpace = e.key === ' ' || e.key === 'Spacebar' || e.keyCode === 32;
560
561          if (isEnter || isSpace) {
562            e.preventDefault();
563            e.currentTarget.click();
564          }
565        });
566      });
567    },
568    toggleInfoAdd() {
569      document.querySelectorAll('.additional-info__desplegable').forEach((element) => {
570        // Manejador de click
571        element.addEventListener('click', (e) => {
572          const target = e.currentTarget;
573          bkjs.commons.classesToEl(target, 'toggle', 'additional-info__desplegable--opened');
574
575          const isOpened = target.classList.contains('additional-info__desplegable--opened');
576          target.setAttribute('aria-expanded', isOpened ? 'true' : 'false');
577        });
578
579        // Manejador de interacción por teclado (Enter / Espacio)
580        element.addEventListener('keyup', (e) => {
581          const isEnter = e.key === 'Enter' || e.keyCode === 13;
582          const isSpace = e.key === ' ' || e.key === 'Spacebar' || e.keyCode === 32;
583
584          if (isEnter || isSpace) {
585            e.preventDefault();
586            e.currentTarget.click();
587          }
588        });
589      });
590    },
591    _toggleVideoControl(selector, targetRelation) {
592      document.querySelectorAll(selector).forEach((btn) => {
593        btn.addEventListener('click', (e) => {
594          const current = e.currentTarget;
595          const target = targetRelation === 'next' ? current.nextElementSibling : current.previousElementSibling;
596
597          if (target) {
598            bkjs.commons.classesToEl(current, 'add', 'd-none');
599            bkjs.commons.classesToEl(target, 'remove', 'd-none');
600          }
601        });
602      });
603    },
604    playVideo() {
605      this._toggleVideoControl('.video__container__controls__play', 'next');
606    },
607    pauseVideo() {
608      this._toggleVideoControl('.video__container__controls__pause', 'prev');
609    },
610    volumeOffVideo() {
611      this._toggleVideoControl('.video__container__controls__volume_on', 'prev');
612    },
613    volumeOnVideo() {
614      this._toggleVideoControl('.video__container__controls__volume_off', 'next');
615    },
616    expandVideo() {
617      this._toggleVideoControl('.video__container__controls__expand', 'next');
618    },
619    restoreVideo() {
620      this._toggleVideoControl('.video__container__controls__restore', 'prev');
621    },
622    sliderVentajas(startSlider) {
623      const element = document.getElementById(startSlider);
624      if (!element) return;
625
626      element.querySelectorAll('.carousel__controls__button').forEach((btn) => {
627        btn.addEventListener('click', (e) => {
628          const currentBtn = e.currentTarget;
629
630          // Quitar estado activo del botón anterior y activado del actual
631          const activeBtn = element.querySelector('.carousel__controls__button.active');
632          if (activeBtn) {
633            bkjs.commons.classesToEl(activeBtn, 'remove', 'active');
634          }
635          bkjs.commons.classesToEl(currentBtn, 'add', 'active');
636
637          // Limpiar todas las clases de tipo slideN dinámicamente
638          element.className = element.className.replace(/\bslide\d+\b/g, '').trim();
639
640          // Aplicar la nueva clase según el dataset
641          const slideIndex = currentBtn.dataset.slide;
642          if (slideIndex) {
643            bkjs.commons.classesToEl(element, 'add', `slide${slideIndex}`);
644          }
645        });
646      });
647    },
648
649    openModal() {
650      const elements = document.querySelectorAll('.launch-modal');
651
652      elements.forEach((btn) => {
653        btn.addEventListener('click', (e) => {
654          e.stopPropagation();
655          e.preventDefault();
656
657          const rootModalElement = document.activeElement;
658          const modalTarget = e.currentTarget.dataset.target;
659          if (!modalTarget) return;
660
661          const modalEl = document.getElementById(modalTarget);
662          if (!modalEl) return;
663
664          // 1. Añadir clases de apertura al modal y al body
665          bkjs.commons.classesToEl(modalEl, 'add', 'opened');
666          bkjs.commons.classesToEl(modalEl, 'add', 'modal--opened');
667          bkjs.commons.classesToEl(document.body, 'add', 'no-scroll');
668
669          // 2. Ajuste dinámico de dimensiones de imagen (Scoped al modal actual)
670          const modalContent = modalEl.querySelector('.modal__content');
671          if (modalContent) {
672            const altoModal = modalContent.clientHeight;
673            const modalImage = modalEl.querySelector('.modal__image');
674            const modalImgTag = modalEl.querySelector('.modal__image img');
675
676            if (modalImage) {
677              modalImage.style.height = `${altoModal}px`;
678            }
679            if (modalImgTag) {
680              modalImgTag.style.width = `${altoModal}px`;
681            }
682          }
683
684          // 3. Métodos accesibilidad y controles
685          if (bkjs.components) {
686            if (typeof bkjs.components.closeModalBtnFooter === 'function') {
687              bkjs.components.closeModalBtnFooter();
688            }
689            if (typeof bkjs.components.accesibleModal === 'function') {
690              bkjs.components.accesibleModal(rootModalElement, 'modal1');
691            }
692          }
693
694          // 4. Analytics
695          if (typeof callAnalyticsEvent === 'function') {
696            const isOtp = modalEl.classList.contains('otp');
697            callAnalyticsEvent({
698              component_name: isOtp ? modalTarget : 'html libre',
699              type: 'modal',
700              event_name: 'modal_open',
701              position: modalTarget.toLowerCase(),
702              event: 'eventga'
703            });
704          }
705        });
706      });
707    },
708
709    closeModal(rootModalElement) {
710      // Función auxiliar para desbloquear el scroll del body sólo si no quedan modales abiertos
711      const checkAndUnlockScroll = () => {
712        const openModalsSelector = `
713      .modal.opened:not(.modal--demo),
714      .modal.modal--opened:not(.modal--demo),
715      .modal-empresas.opened:not(.modal--demo),
716      .modal-empresas.modal--opened:not(.modal--demo),
717      .modal-filtro.opened,
718      .modal-filtro.modal--opened
719    `;
720
721        const hasOpenModals = document.querySelectorAll(openModalsSelector).length > 0;
722        if (!hasOpenModals) {
723          bkjs.commons.classesToEl(document.body, 'remove', 'no-scroll');
724        }
725      };
726
727      // 1. Manejador unificado para modales estándar y de empresas
728      const closeButtons = document.querySelectorAll('.modal__close-button, .message__close');
729      closeButtons.forEach((btn) => {
730        btn.addEventListener('click', (e) => {
731          e.stopPropagation();
732
733          const modal = e.currentTarget.closest('.modal') || e.currentTarget.closest('.modal-empresas');
734          if (!modal) return;
735
736          bkjs.commons.classesToEl(modal, 'remove', 'opened');
737          bkjs.commons.classesToEl(modal, 'remove', 'modal--opened');
738
739          checkAndUnlockScroll();
740
741          if (rootModalElement && typeof rootModalElement.focus === 'function') {
742            rootModalElement.focus();
743          }
744        });
745      });
746
747      // 2. Manejador unificado para modales de tipo filtro
748      const filterCloseButtons = document.querySelectorAll('.modal-filtro__close-button');
749      filterCloseButtons.forEach((btn) => {
750        btn.addEventListener('click', (e) => {
751          e.stopPropagation();
752
753          const modal = e.currentTarget.closest('.modal-filtro');
754          if (!modal) return;
755
756          bkjs.commons.classesToEl(modal, 'remove', 'opened');
757          bkjs.commons.classesToEl(modal, 'remove', 'modal--opened');
758
759          checkAndUnlockScroll();
760
761          if (rootModalElement && typeof rootModalElement.focus === 'function') {
762            rootModalElement.focus();
763          }
764        });
765      });
766    },
767
768    closeModalBtnFooter() {
769      document.querySelectorAll('.modal').forEach((modal) => {
770        const footerCloseBtn = modal.querySelector('.modal__close-button--footer');
771        const headerCloseBtn = modal.querySelector('.modal__close-button');
772
773        if (footerCloseBtn && headerCloseBtn && !footerCloseBtn.dataset.boundClose) {
774          footerCloseBtn.dataset.boundClose = 'true';
775          footerCloseBtn.addEventListener('click', () => {
776            headerCloseBtn.click();
777          });
778        }
779      });
780    },
781
782    accesibleModal(rootModalElement, modalType) {
783      const modal = document.querySelector('.modal--opened');
784      if (!modal) return;
785
786      const getFocusList = (element) => {
787        if (!element) return [];
788        const selector = 'a[href], area[href], input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex="0"]';
789        return Array.from(element.querySelectorAll(selector));
790      };
791
792      const getModalFocusableElements = (type) => {
793        if (type === 'modal2') {
794          const message = modal.querySelector('.modal__content__message');
795          return getFocusList(message);
796        }
797
798        if (type === 'modal1') {
799          const header = modal.querySelector('.modal__content__header');
800          const body = modal.querySelector('.modal__content__body');
801          const footer = modal.querySelector('.modal__content__footer');
802
803          return [
804            ...getFocusList(header),
805            ...getFocusList(body),
806            ...getFocusList(footer)
807          ];
808        }
809
810        return [];
811      };
812
813      const focusableEls = getModalFocusableElements(modalType);
814      if (!focusableEls.length) return;
815
816      // Enfocar automáticamente el primer elemento interactivo
817      focusableEls[0].focus();
818
819      modal.addEventListener('keydown', (e) => {
820        const isTab = e.key === 'Tab' || e.keyCode === 9;
821        const isEsc = e.key === 'Escape' || e.keyCode === 27;
822
823        if (isTab) {
824          if (focusableEls.length === 1) {
825            e.preventDefault();
826            return;
827          }
828
829          const firstFocusableEl = focusableEls[0];
830          const lastFocusableEl = focusableEls[focusableEls.length - 1];
831
832          if (e.shiftKey && document.activeElement === firstFocusableEl) {
833            e.preventDefault();
834            lastFocusableEl.focus();
835          } else if (!e.shiftKey && document.activeElement === lastFocusableEl) {
836            e.preventDefault();
837            firstFocusableEl.focus();
838          }
839        } else if (isEsc) {
840          const currentModal = e.currentTarget.closest('.modal, .modal-empresas, .modal-filtro');
841          if (currentModal) {
842            bkjs.commons.classesToEl(currentModal, 'remove', 'opened');
843            bkjs.commons.classesToEl(currentModal, 'remove', 'modal--opened');
844          }
845
846          const openModalsSelector = '.modal.opened, .modal.modal--opened, .modal-empresas.opened, .modal-empresas.modal--opened, .modal-filtro.opened, .modal-filtro.modal--opened';
847          if (document.querySelectorAll(openModalsSelector).length === 0) {
848            bkjs.commons.classesToEl(document.body, 'remove', 'no-scroll');
849          }
850
851          if (rootModalElement && typeof rootModalElement.focus === 'function') {
852            rootModalElement.focus();
853          }
854        }
855      });
856    },
857    openClausula() {
858      let element = document.querySelector('.clausula__show');
859      if (element) {
860        element.addEventListener('click', function (e) {
861          e.stopPropagation();
862          e.preventDefault();
863          document.querySelector('.clausula_text').classList.add('clausula_text--show');
864        });
865      }
866    },
867    closeClausula() {
868      let element = document.querySelector('.clausula__close');
869      if (element) {
870        element.addEventListener('click', function (e) {
871          e.stopPropagation();
872          e.preventDefault();
873          document.querySelector('.clausula_text').classList.remove('clausula_text--show');
874        });
875      }
876    },
877    closeButtonSticky() {
878      let iconCloseSticky = document.querySelector('.featured-box_sticky button .icon--close-16');
879      if (iconCloseSticky) {
880        iconCloseSticky.closest('button').addEventListener('click', function (e) {
881          e.stopPropagation();
882          e.preventDefault();
883          this.closest('.featured-box__wrapper').classList.add('d-none');
884        });
885      }
886    },
887    closeBackdropModal() {
888      let elements = document.querySelectorAll('.modal');
889      for (let ff = 0; ff < elements.length; ff++) {
890        if (elements[ff].dataset.closeBackdrop) {
891          if (!elements[ff].classList.contains('modal--bloqueada')) {
892            elements[ff].querySelectorAll('.modal__backdrop')[0].addEventListener('click', function (e) {
893              e.stopPropagation();
894              bkjs.commons.classesToEl(e.currentTarget.closest('.modal'), 'remove', 'opened');
895              if(e.currentTarget.closest('.modal').classList.contains('otp')){
896                callAnalyticsEvent({
897                  'component_name': e.currentTarget.closest('.modal').getAttribute('id'),
898                  'event_name': 'modal_close',
899                  'type': 'modal',
900                  'position': e.currentTarget.closest('.modal').getAttribute('id'),
901                  'element': '[]',
902                  'event': 'eventga'
903                });
904              }
905              if (document.querySelectorAll('.modal.opened').length == 0) {
906                bkjs.commons.classesToEl(document.body, 'remove', 'no-scroll');
907              }
908            });
909          } else {
910            elements[ff].querySelectorAll('.modal__backdrop')[0].addEventListener('click', function (e) {
911              e.stopPropagation();
912            });
913          }
914        }
915      }
916
917      let elementsBEM = document.querySelectorAll('.modal');
918      for (let gg = 0; gg < elementsBEM.length; gg++) {
919        if (elementsBEM[gg].dataset.closeBackdrop) {
920          elementsBEM[gg].querySelectorAll('.modal__backdrop')[0].addEventListener('click', function (e) {
921            e.stopPropagation();
922            bkjs.commons.classesToEl(e.currentTarget.closest('.modal'), 'remove', 'modal--opened');
923            if (document.querySelectorAll('.modal.opened, .modal.modal--opened').length == 0) {
924              bkjs.commons.classesToEl(document.body, 'remove', 'no-scroll');
925            }
926          });
927        }
928      }
929    },
930    openMessage: function () {
931      function clickOpenMessage(e) {
932        rootModalElement = document.activeElement;
933        e.stopPropagation();
934        e.preventDefault();
935        let elementToShow = e.currentTarget.closest('.modal');
936        if (elementToShow) {
937          let buttonToDisable = elementToShow.querySelector('.modal__close-button');
938          bkjs.commons.classesToEl(elementToShow, 'add', 'message_opened');
939          bkjs.commons.disableButton(buttonToDisable);
940        }
941        bkjs.components.accesibleModal(rootModalElement, 'modal2');
942      }
943
944      let elements = document.querySelectorAll('.message__show');
945      let rootModalElement;
946      for (let hh = 0; hh < elements.length; hh++) {
947        elements[hh].addEventListener('click', clickOpenMessage);
948      }
949
950      function clickOpenMessageBEM(e) {
951        rootModalElement = document.activeElement;
952        e.stopPropagation();
953        e.preventDefault();
954        let elementToShow = e.currentTarget.closest('.modal');
955        let buttonToDisable = elementToShow.querySelector('.modal__close-button');
956        bkjs.commons.classesToEl(elementToShow, 'add', 'modal--message-opened');
957        bkjs.commons.disableButton(buttonToDisable);
958        bkjs.components.accesibleModal(rootModalElement, 'modal2');
959      }
960
961      let elementsBEM = document.querySelectorAll('.modal__message-show');
962      for (let ii = 0; ii < elementsBEM.length; ii++) {
963        elementsBEM[i].addEventListener('click', clickOpenMessageBEM);
964      }
965    },
966    closeMessage: function () {
967      function clickMessage(e) {
968        e.stopPropagation();
969        e.preventDefault();
970        let elementToShow = e.currentTarget.closest('.modal');
971        let body = document.querySelector('body');
972        bkjs.commons.classesToEl(elementToShow, 'remove', 'message_opened');
973        bkjs.commons.classesToEl(elementToShow, 'remove', 'opened');
974        if (document.querySelectorAll('.modal.opened').length == 0) {
975          bkjs.commons.classesToEl(body, 'remove', 'no-scroll');
976        }
977        let buttonToEnable = elementToShow.querySelector('.modal__close-button');
978        bkjs.commons.enableButton(buttonToEnable);
979      }
980
981      let elements = document.querySelectorAll('.message__close');
982      for (let i = 0; i < elements.length; i++) {
983        elements[i].addEventListener('click', clickMessage);
984      }
985
986      function clickMessageBEM(e) {
987        e.stopPropagation();
988        e.preventDefault();
989        let elementToShowBEM = e.currentTarget.closest('.modal');
990        bkjs.commons.classesToEl(elementToShowBEM, 'remove', 'modal--message-opened');
991        let buttonToEnableBEM = elementToShowBEM.querySelector('.modal__close-button');
992        bkjs.commons.enableButton(buttonToEnableBEM);
993      }
994
995      let elementsBEM = document.querySelectorAll('.message__close');
996      for (let r = 0; r < elementsBEM.length; r++) {
997        elementsBEM[r].addEventListener('click', clickMessageBEM);
998      }
999    },
1000    getValueFilterTabs: function (group, elements, gtmUrl) {
1001      let parentElement = document.querySelector(group);
1002      let childElements = parentElement.querySelectorAll(elements);
1003      let elementValue;
1004
1005      function clickFilterTabs(e) {
1006        elementValue = e.currentTarget.dataset.elementValue;
1007        let activeElement = parentElement.querySelector('.filters__element_active');
1008        if (activeElement) {
1009          bkjs.commons.classesToEl(activeElement, 'remove', 'filters__element_active');
1010          activeElement.removeAttribute('aria-selected');
1011        }
1012        bkjs.commons.classesToEl(e.currentTarget, 'add', 'filters__element_active');
1013        e.currentTarget.setAttribute('aria-selected', true);
1014        bkjs.components.showElementsFilterTabs(elementValue);
1015      }
1016
1017      for (let ll = childElements.length - 1; ll >= 0; ll--) {
1018        childElements[ll].addEventListener('click', clickFilterTabs);
1019      }
1020    },
1021    showElementsFilterTabs(elementValue) {
1022      document.querySelector('.filter__boxes__show-all').querySelector('button').click();
1023      document.querySelector('.filter__boxes__show-all').classList.add('d-none');
1024      let parentElement = document.querySelector('.filter__boxes');
1025      let childElements = parentElement.querySelectorAll('[data-match-values]');
1026      let childElementsShown;
1027      for (let i = childElements.length - 1; i >= 0; i--) {
1028        let possibleValues = childElements[i].dataset.matchValues;
1029        if (elementValue === 'reset' || possibleValues.indexOf(elementValue) > -1) {
1030          bkjs.components.orderElementsFilter(elementValue, childElements);
1031          let classes = Array.from(childElements[i].classList);
1032          for (let j = 0; j < classes.length; j++) {
1033            if (classes[j].indexOf('order') > -1) {
1034              childElements[i].classList.remove(classes[j]);
1035            }
1036          }
1037          bkjs.commons.classesToEl(childElements[i], 'add', 'order-' + childElements[i].dataset.f
1037ilterOrder);
1038          if (childElements[i].querySelector('[data-order]')) {
1039            childElements[i].querySelector('[data-order]').setAttribute('data-order', childElements[i].dataset.filterOrder);
1040          }
1041          bkjs.commons.classesToEl(childElements[i], 'remove', 'd-none');
1042        } else {
1043          bkjs.commons.classesToEl(childElements[i], 'add', 'd-none');
1044          bkjs.commons.classesToEl(parentElement.querySelector('.filter__boxes__show-all'), 'add', 'd-none');
1045        }
1046      }
1047      childElementsShown = parentElement.querySelectorAll('[data-match-values]:not(.d-none)');
1048      for (let jj = 0; jj < childElementsShown.length; jj++) {
1049        childElementsShown[jj].setAttribute('data-gtm-order', jj + 1);
1050      }
1051    },
1052    orderElementsFilter: function (elementValue, childElements) {
1053      let subChildElements = Array.from(childElements);
1054      subChildElements = subChildElements.splice(1);
1055      let ingresosFijosValues = [1, 2, 3, 4, 5, 6, 7, 8, 9];
1056      let noIngresosFijosValues = [5, 6, 7, 1, 8, 3, 2, 4, 9];
1057      let compratidosValues = [4, 5, 6, 2, 1, 7, 3, 8, 9];
1058      let menor22Values = [2, 3, 4, 5, 6, 1, 7, 8, 9];
1059      switch (elementValue) {
1060        case 'ingresosFijos':
1061          for (let v = 0; v < subChildElements.length; v++) {
1062            subChildElements[v].setAttribute('data-filter-order', ingresosFijosValues[v]);
1063          }
1064          break;
1065        case 'noIngresosFijos':
1066          for (let f = 0; f < subChildElements.length; f++) {
1067            subChildElements[f].setAttribute('data-filter-order', noIngresosFijosValues[f]);
1068          }
1069          break;
1070        case 'compratidos':
1071          for (let l = 0; l < subChildElements.length; l++) {
1072            subChildElements[l].setAttribute('data-filter-order', compratidosValues[l]);
1073          }
1074          break;
1075        case 'menor22':
1076          for (let p = 0; p < subChildElements.length; p++) {
1077            subChildElements[p].setAttribute('data-filter-order', menor22Values[p]);
1078          }
1079          break;
1080        default:
1081          for (let w = 0; w < subChildElements.length; w++) {
1082            subChildElements[w].setAttribute('data-filter-order', (w + 1));
1083          }
1084      }
1085    },
1086    showAllElements() {
1087      let showAllButtons = document.querySelectorAll('.filter__boxes__show-all');
1088      for (let z = showAllButtons.length - 1; z >= 0; z--) {
1089        showAllButtons[z].querySelector('button').addEventListener('click', function (e) {
1090          let contenedorDivs = document.querySelector('.filter__boxes_truncated');
1091          if (contenedorDivs) {
1092            let qchildren = contenedorDivs.querySelectorAll('.content-box__footer');
1093            for (let c = 0; c < qchildren.length; c++) {
1094              if (qchildren[c].querySelector('.text-link')) {
1095                let posicion = qchildren[c].querySelector('.text-link');
1096                bkjs.commons.classesToEl(posicion, 'remove', 'd-none');
1097              }
1098            }
1099          }
1100          bkjs.commons.classesToEl(e.currentTarget.closest('.filter__boxes'), 'remove', 'filter__boxes_truncated');
1101          bkjs.commons.classesToEl(e.currentTarget.closest('.filter__boxes__show-all'), 'add', 'd-none');
1102        });
1103      }
1104    },
1105    showBoxesElements() {
1106      let showAllButtons = document.querySelector('.filter__boxes__show-all');
1107      let topTodos = showAllButtons.getBoundingClientRect().top;
1108      let contenedorDivs = document.querySelector('.filter__boxes_truncated');
1109      if (contenedorDivs !== -1) {
1110        let qchildren = contenedorDivs.getElementsByClassName('content-box__footer');
1111        for (let o = 0; o < qchildren.length; o++) {
1112          let posicion = qchildren[o].querySelector('.text-link');
1113          if (posicion !== -1) {
1114            let posBox = posicion.getBoundingClientRect().bottom;
1115            if (posBox > topTodos) {
1116              bkjs.commons.classesToEl(posicion, 'add', 'd-none');
1117            }
1118          }
1119        }
1120      }
1121    },
1122    launchJumpContent() {
1123      const jumpContent = document.getElementById('jumpContent');
1124      if (jumpContent) {
1125        jumpContent.addEventListener('keydown', (e) => {
1126          if (e.key === 'Enter') {
1127            const button = e.target.closest('button');
1128            if (!button) return;
1129            const href = button.getAttribute('href');
1130            if (!href) return;
1131            const targetElement = document.querySelector(href);
1132            if (targetElement) {
1133              targetElement.focus();
1134            }
1135          }
1136        });
1137        document.addEventListener('keydown', (event) => {
1138          if (event.key === 'Tab') {
1139            document.getElementById('jumpContent').style.display = 'block';
1140          } else {
1141            document.getElementById('jumpContent').style.display = 'none';
1142          }
1143        });
1144      }
1145    },
1146    toggleConditionsFaqAccesible() {
1147      let elements = document.querySelectorAll('.conditions-faqs__item__clickable');
1148      for (let u = elements.length - 1; u >= 0; u--) {
1149        elements[u].addEventListener('click', function (e) {
1150          let initialHeight = e.currentTarget.offsetHeight + parseInt(window.getComputedStyle(e.currentTarget).marginTop) + parseInt(window.getComputedStyle(e.currentTarget).marginBottom);
1151          let collapsibleElement = e.currentTarget.closest('.conditions-faqs__item__collapsible');
1152          let isCollapsed = collapsibleElement.getAttribute('data-collapsed') === 'true';
1153          if (isCollapsed) {
1154            bkjs.animateHeight.expandSectionAccesible(collapsibleElement);
1155            e.currentTarget.closest('.conditions-faqs__item__collapsible').setAttribute('data-collapsed', 'false');
1156            e.currentTarget.closest('.conditions-faqs__item__collapsible').setAttribute('aria-expanded', 'true');
1157          } else {
1158            bkjs.animateHeight.collapseSectionAccesible(collapsibleElement, initialHeight);
1159            e.currentTarget.closest('.conditions-faqs__item__collapsible').setAttribute('aria-expanded', 'false');
1160          }
1161        });
1162      }
1163      let faqsDesplegable = document.querySelectorAll('.conditions-faqs__item');
1164      faqsDesplegable.forEach(function (desplegable) {
1165        let desplegableTrigger = desplegable.querySelector('.conditions-faqs__title');
1166        let desplegableContent = desplegable.querySelector('.conditions-faqs__content');
1167        if (desplegableTrigger) {
1168          desplegableTrigger.addEventListener("click", () => {
1169            if (desplegable && desplegableContent) {
1170              if (desplegable.getAttribute('data-collapsed') == "true") {
1171                desplegable.style.overflow = "initial";
1172                desplegableContent.style.overflow = "initial";
1173              } else {
1174                desplegable.style.overflow = "hidden";
1175                desplegableContent.style.overflow = "hidden";
1176              }
1177            }
1178          });
1179        }
1180      });
1181
1182      let elemOpen = document.querySelectorAll('.conditions-faqs--opened .conditions-faqs__item')
1183      if (document.querySelectorAll('.conditions-faqs--opened').length > 0) {
1184        elemOpen.forEach(function (_value, index) {
1185          elemOpen[index].setAttribute("data-collapsed", "false");
1186          elemOpen[index].setAttribute("aria-expanded", "true");
1187          elemOpen[index].setAttribute('style', '');
1188          if (elemOpen[index].nextElementSibling) {
1189            elemOpen[index].nextElementSibling.removeAttribute('hidden');
1190          }
1191        });
1192      }
1193      let elementsFocusable = document.querySelectorAll('.conditions-faqs__item');
1194      for (let t = elementsFocusable.length - 1; t >= 0; t--) {
1195        elementsFocusable[t].addEventListener('keyup', function (e) {
1196          let key = event.which || event.keyCode;
1197          if (key === 13 || key === 32) {
1198            if (e.currentTarget.querySelector('.conditions-faqs__item__toggle')) e.currentTarget.querySelector('.conditions-faqs__item__toggle').click();
1199            if (e.currentTarget.querySelector('.conditions-faqs__toggle')) e.currentTarget.querySelector('.conditions-faqs__toggle').click();
1200          }
1201        });
1202      }
1203      let elementsBEM = document.querySelectorAll('.conditions__item-clickable');
1204      for (let r = elementsBEM.length - 1; r >= 0; r--) {
1205        elementsBEM[r].addEventListener('click', function (e) {
1206          let initialHeight = e.currentTarget.offsetHeight + parseInt(window.getComputedStyle(e.currentTarget).marginTop) + parseInt(window.getComputedStyle(e.currentTarget).marginBottom);
1207          let collapsibleElement = e.currentTarget.closest('.conditions__item-collapsible');
1208          let isCollapsed = collapsibleElement.getAttribute('data-collapsed') === 'true';
1209          if (isCollapsed) {
1210            bkjs.animateHeight.expandSectionAccesible(collapsibleElement);
1211            e.currentTarget.closest('.conditions__item-collapsible').setAttribute('data-collapsed', 'false');
1212          } else {
1213            bkjs.animateHeight.collapseSectionAccesible(collapsibleElement, initialHeight);
1214          }
1215        });
1216      }
1217    },
1218    toggleContentBoxTab() {
1219      let productFeaturesList = document.getElementsByClassName('product-features');
1220      let buttons = document.querySelectorAll('.toggle-content-box-tab');
1221
1222      function clickToggleContentBoxTab(e) {
1223        let pfeat = e.currentTarget.closest('.product-features');
1224        let activeButton = pfeat ? pfeat.querySelector('.opened') : null;
1225        if (productFeaturesList.length > 1) {
1226          for (let k = 0; k < productFeaturesList.length; k++) {
1227            let openedList = productFeaturesList[k].querySelectorAll('.opened');
1228            for (let h = 0; h < openedList.length; h++) {
1229              if (!e.currentTarget.classList.contains('opened')) {
1230                openedList[h].classList.remove('opened');
1231              }
1232            }
1233          }
1234        }
1235        if (activeButton && activeButton !== e.currentTarget) {
1236          bkjs.commons.classesToEl(activeButton, 'remove', 'opened');
1237        }
1238        if (e.currentTarget.classList.contains('opened')) {
1239          bkjs.commons.classesToEl(e.currentTarget, 'remove', 'opened');
1240          let selfItem = e.currentTarget.getAttribute('data-tab-value');
1241          let openedItem = document.querySelector('#tab' + selfItem);
1242          if (openedItem) {
1243            openedItem.setAttribute('aria-expanded', false);
1244          }
1245
1246        } else {
1247          bkjs.commons.classesToEl(e.currentTarget, 'add', 'opened');
1248          let selfItem2 = e.currentTarget.getAttribute('data-tab-value');
1249          let openedItem2 = document.querySelector('#tab' + selfItem2);
1250          if (openedItem2) {
1251            openedItem2.setAttribute('aria-expanded', true);
1252          }
1253        }
1254        let tabValue = e.currentTarget.dataset.tabValue;
1255        let activeContent = document.querySelector('.openedContent');
1256        if (activeContent && activeContent.dataset.tabContent !== tabValue) {
1257          let previousActiveContent = activeContent.getAttribute('data-tab-content');
1258          let openedItem3 = document.querySelector('#tab' + previousActiveContent);
1259          if (openedItem3) {
1260            openedItem3.setAttribute('aria-expanded', false);
1261          }
1262          bkjs.commons.classesToEl(activeContent, 'remove', 'openedContent');
1263        }
1264        let contentToActive = document.querySelector('[data-tab-content="' + tabValue + '"]');
1265        bkjs.commons.classesToEl(contentToActive, 'toggle', 'openedContent');
1266      }
1267
1268      for (let i = buttons.length - 1; i >= 0; i--) {
1269        buttons[i].addEventListener('click', clickToggleContentBoxTab);
1270      }
1271    },
1272    accesibleIconSelectorRadio() {
1273      let radioIconSelector = document.querySelectorAll('.icon-selector input[type="radio"]');
1274      if (radioIconSelector && radioIconSelector.length) {
1275        for (let i = 0; i < radioIconSelector.length; i++) {
1276          radioIconSelector[i].addEventListener('click', clickIconSelectorRadioOptions.bind(this));
1277          radioIconSelector[i].addEventListener('keydown', keydownIconSelectorRadioOptions.bind(this, i));
1278        }
1279      }
1280
1281      function clickIconSelectorRadioOptions(e) {
1282        let counter = 0;
1283        for (i = 0; i < radioIconSelector.length; i++) {
1284          if (radioIconSelector[i].checked) {
1285            counter++;
1286            radioIconSelector[i].parentNode.setAttribute('aria-checked', 'true');
1287          } else {
1288            radioIconSelector[i].parentNode.setAttribute('aria-checked', 'false');
1289          }
1290        }
1291      }
1292
1293      function keydownIconSelectorRadioOptions(idx) {
1294        if (event.keyCode === 32 || event.keyCode === 13) {
1295          event.preventDefault();
1296          radioIconSelector[idx].checked = !radioIconSelector[idx].checked;
1297          let radioArr = Array.prototype.slice.call(radioIconSelector);
1298          radioArr.forEach(function (radio) {
1299            radio.parentNode.setAttribute('aria-checked', 'false');
1300          });
1301          let hasChecked = radioArr.some(function (radioIconSelector) {
1302            return radioIconSelector.checked;
1303          });
1304          if (hasChecked) {
1305            radioIconSelector[idx].parentNode.setAttribute('aria-checked', 'true');
1306          } else {
1307            radioIconSelector[idx].parentNode.setAttribute('aria-checked', 'false');
1308          }
1309        }
1310        if (event.keyCode === 37) {
1311          event.preventDefault();
1312          if (idx > 0) {
1313            radioIconSelector[idx - 1].focus();
1314          }
1315        }
1316        if (event.keyCode === 39) {
1317          event.preventDefault();
1318          if (idx < radioIconSelector.length - 1) {
1319            radioIconSelector[idx + 1].focus();
1320          }
1321        }
1322      }
1323    },
1324    initSmoothHrefMode() {
1325      document.querySelectorAll('a[href^="#"]').forEach(function (anchor) {
1326        anchor.addEventListener('click', function (e) {
1327          var href = this.getAttribute('href');
1328
1329          if (!href || !href.startsWith('#')) {
1330            if (href) {
1331              location.href = href;
1332            }
1333          } else {
1334            e.preventDefault();
1335            if (href !== '#') {
1336              try {
1337                var target = document.querySelector(href);
1338                if (target) {
1339                  target.scrollIntoView({
1340                    behavior: 'smooth'
1341                  });
1342                }
1343              } catch (error) {
1344                // Manejo de errores por selectores inválidos
1345              }
1346            }
1347          }
1348        });
1349      });
1350    },
1351    clickFiltersModal() {
1352      let filters = document.querySelectorAll('.modal-filtro .filter');
1353      for (let i = 0; i < filters.length; i++) {
1354        filters[i].addEventListener('click', function (e) {
1355          let filterActive = e.currentTarget.querySelector('.filter__content--active');
1356          if (filterActive) {
1357            e.currentTarget.closest('.modal-filtro__content').querySelector('.action-bar--filter').classList.add('d-none');
1358          } else {
1359            e.currentTarget.closest('.modal-filtro__content').querySelector('.action-bar--filter').classList.remove('d-none');
1360          }
1361        });
1362      }
1363    },
1364    clickFilters() {
1365      let FILTER = 'filter';
1366      let SELECTOR = 'filter--selector';
1367      let CALENDAR = 'filter--calendar';
1368      let RANGE = 'filter--range';
1369
1370      function clickOut(evt) {
1371        if (!evt) return;
1372        const actions = [
1373          {
1374            selector: SELECTOR,
1375            nodes: '.filter__selector',
1376            action: node => node.classList.add('d-none')
1377          },
1378          {
1379            selector: FILTER,
1380            nodes: '.modal-filtro .action-bar--filter',
1381            action: node => node.classList.remove('d-none'),
1382            single: true
1383          },
1384          {
1385            selector: CALENDAR,
1386            nodes: '.filter--calendar__content',
1387            action: node => node.parentNode.classList.remove('filter__content--active')
1388          },
1389          {
1390            selector: RANGE,
1391            nodes: '.filter__bloq-range',
1392            action: node => node.parentNode.classList.remove('filter__content--active')
1393          }
1394        ];
1395        actions.forEach(({ selector, nodes, action, single }) => {
1396          if (!hasSomeParentTheClass(evt.target, selector)) {
1397            const elements = single ? [document.querySelector(nodes)].filter(Boolean) : document.querySelectorAll(nodes);
1398            elements.forEach(action);
1399          }
1400        });
1401      }
1402
1403      if (document.body) document.body.addEventListener("click", clickOut);
1404
1405      function hasSomeParentTheClass(element, className) {
1406        do {
1407          if (element.classList && element.classList.contains(className)) {
1408            return true;
1409          }
1410          element = element.parentNode;
1411        } while (element);
1412        return false;
1413      }
1414    },
1415    ctaStickyMobile() {
1416      if (window.innerWidth < 768) {
1417        if (document.querySelector('.cta-box--fixed-mobile')) {
1418          document.querySelector('footer').style.bottom = document.querySelector('.cta-box--fixed-mobile').querySelector('.cta-box__wrapper').clientHeight + 'px';
1419        }
1420      }
1421    },
1422    toggleCtaInterval(initElement, endElement) {
1423      if (window.innerWidth > 767) {
1424        if (document.querySelector('.cta-box--interval-init')) {
1425          let element = document.querySelector(initElement);
1426          let elementEnd = document.querySelector(endElement);
1427          let windowHeight = window.innerHeight;
1428          bkjs.components.toggleCtaBox(element, elementEnd, windowHeight);
1429          window.addEventListener('scroll', function () {
1430            if (window.innerWidth > 767) {
1431              bkjs.components.toggleCtaBox(element, elementEnd, windowHeight);
1432            }
1433          }, {
1434            passive: true
1435          });
1436        }
1437      }
1438      bkjs.components.calcPositionFixed();
1439    },
1440    toggleCtaBox(element, elementEnd, windowHeight) {
1441      if (element.getBoundingClientRect().top <= 100 && elementEnd.getBoundingClientRect().top >= document.querySelector('.cta-box--interval-init').clientHeight + 100) {
1442        document.querySelector('.cta-box--interval-init').classList.remove('cta-box--sticky');
1443        document.querySelector('.cta-box--interval-init').classList.add('cta-box--interval');
1444        document.querySelector('.cta-box--interval-init').removeAttribute('style');
1445
1446      } else {
1447        if (element.getBoundingClientRect().top <= 100 && elementEnd.getBoundingClientRect().top > 0) {
1448          document.querySelector('.cta-box--interval-init').classList.remove('cta-box--sticky');
1449          document.querySelector('.cta-box--interval-init').classList.add('cta-box--interval');
1450          let pixeles = document.querySelector('.cta-box--interval-init').clientHeight - elementEnd.getBoundingClientRect().top;
1451          if (pixeles > 0 || -1 * pixeles < 100) pixeles = -1 * pixeles;
1452          document.querySelector('.cta-box--interval-init').style.top = pixeles + 'px';
1453        } else {
1454          document.querySelector('.cta-box--interval-init').removeAttribute('style');
1455          document.querySelector('.cta-box--interval-init').classList.add('cta-box--sticky');
1456          document.querySelector('.cta-box--interval-init').classList.remove('cta-box--interval');
1457        }
1458
1459      }
1460    },
1461    calcPositionFixed() {
1462      if (window.innerWidth > 767) {
1463        if (document.querySelector('.cta-box--fixed')) {
1464          if (document.querySelector('.cta-box--fixed.cta-box--fixed-left')) {
1465            let fixedElement = document.querySelector('.cta-box--fixed-left');
1466            let positionLeft = (window.innerWidth - document.querySelector('.container').offsetWidth - 16) / 2;
1467            let positionVertical = window.innerHeight / 4;
1468            fixedElement.style.position = 'fixed';
1469            fixedElement.style.left = positionLeft + 'px';
1470            fixedElement.style.top = positionVertical + 'px';
1471          } else {
1472            let fixedElement = document.querySelector('.cta-box--fixed');
1473            let positionRight = (window.innerWidth - document.querySelector('.container').offsetWidth - 16) / 2;
1474            let positionVertical = window.innerHeight / 4;
1475            fixedElement.style.position = 'fixed';
1476            fixedElement.style.right = positionRight + 'px';
1477            fixedElement.style.top = positionVertical + 'px';
1478          }
1479        }
1480      }
1481    }
1482  },
1483  swipe: {
1484    position(e) {
1485      const touch = e.changedTouches ? e.changedTouches[0] : e;
1486      return {
1487        x: touch.pageX,
1488        y: touch.pageY
1489      };
1490    },
1491
1492    onSwipe(elem, callback) {
1493      if (!elem || typeof callback !== 'function') return;
1494
1495      const minDistance = 80;
1496      const maxTime = 400;
1497      let startTime = 0;
1498      let startPos = { x: 0, y: 0 };
1499
1500      const start = (e) => {
1501        startTime = Date.now();
1502        startPos = this.position(e);
1503      };
1504
1505      const end = (e) => {
1506        if (!startTime) return;
1507
1508        const elapsedTime = Date.now() - startTime;
1509        const newPos = this.position(e);
1510        const offsetX = newPos.x - startPos.x;
1511        const offsetY = newPos.y - startPos.y;
1512        const absX = Math.abs(offsetX);
1513        const absY = Math.abs(offsetY);
1514
1515        let direction = '';
1516        let distance = 0;
1517
1518        if (absX > absY) {
1519          direction = offsetX > 0 ? 'right' : 'left';
1520          distance = absX;
1521        } else {
1522          direction = offsetY > 0 ? 'down' : 'up';
1523          distance = absY;
1524        }
1525
1526        if (elapsedTime <= maxTime && distance >= minDistance) {
1527          callback(direction);
1528        }
1529      };
1530
1531      elem.addEventListener('touchstart', start, { passive: true });
1532      elem.addEventListener('mousedown', start);
1533      elem.addEventListener('touchend', end, { passive: true });
1534      elem.addEventListener('mouseup', end);
1535    }
1536  },
1537  gtm: {
1538    // Variables de estado para el carrusel
1539    _carouselState: {
1540      nodo: null,
1541      initialX: 0
1542    },
1543
1544    _pushToDataLayer(data) {
1545      if (typeof window.dataLayer !== 'undefined') {
1546        window.dataLayer.push(data);
1547      }
1548    },
1549
1550    doEventAnalytics(category, action, label, value) {
1551      this._pushToDataLayer({ category, action, label, value, event: 'eventga' });
1552    },
1553
1554    doEventAnalyticsExtended(category, action, label, type, position, element, order, value) {
1555      this._pushToDataLayer({
1556        category,
1557        action,
1558        label,
1559        type,
1560        position,
1561        element,
1562        order,
1563        value,
1564        event: 'eventga'
1565      });
1566    },
1567
1568    doEventAnalyticsEdit(e, category, action, label, type, position, element, order, value) {
1569      const target = e ? e.currentTarget : null;
1570      const elementText = target ? target.innerText : '';
1571      const finalLabel = target ? target.href : label;
1572
1573      // Sanitización moderna de acentos/diacríticos usando NFD + Regex limpia
1574      let cleanElement = elementText
1575      .normalize('NFD')
1576      .replace(/[\u0300-\u036f]/g, '')
1577      .toLowerCase()
1578      .replace(/[^a-z0-9]/g, '');
1579
1580      this._pushToDataLayer({
1581        category,
1582        action,
1583        label: finalLabel,
1584        type,
1585        position,
1586        element: cleanElement,
1587        order,
1588        value,
1589        event: 'eventga'
1590      });
1591    },
1592
1593    doEventAnalyticsTabs(category, action, label, type, position, element, order, value) {
1594      const activeFilter = document.querySelector('.filters__element_active');
1595      const positionAX = activeFilter ? activeFilter.getAttribute('aria-controls') : position;
1596
1597      this._pushToDataLayer({
1598        category,
1599        action,
1600        label,
1601        type,
1602        position: positionAX,
1603        element,
1604        order,
1605        value,
1606        event: 'eventga'
1607      });
1608    },
1609
1610    doEventAnalyticsSmart(category, action, label, type, position, element, order, value) {
1611      this._pushToDataLayer({
1612        category,
1613        action,
1614        label,
1615        type,
1616        position: `${position} - cabecera`,
1617        element,
1618        order,
1619        value,
1620        event: 'eventga'
1621      });
1622    },
1623
1624    doVirtualUrl(virtualUrl) {
1625      this._pushToDataLayer({ virtualUrl, event: 'virtualurl' });
1626    },
1627
1628    launchGtmAccordion(element, dataPosition, dataElement, order) {
1629      if (!element) return;
1630      const parentDiv = element.closest('div');
1631      const isParentOpened = parentDiv && parentDiv.classList.contains('opened');
1632      const isElementOpened = element.classList.contains('opened');
1633
1634      if (!isParentOpened || !isElementOpened) {
1635        this.doEventAnalyticsExtended('Navegacion', 'Enlace interno', '#', 'enlace', dataPosition, dataElement, order, undefined);
1636      }
1637    },
1638
1639    launchGtmFaqs(element, order) {
1640      if (element && !element.classList.contains('opened')) {
1641        this.doEventAnalyticsExtended('Navegacion', 'Enlace interno', '#', 'enlace', 'Faqs', 'Preguntas frecuentes', order, undefined);
1642      }
1643    },
1644
1645    doEventAnalyticsWithDimensions(category, action, label, value, dimensions = {}) {
1646      if (typeof window.dataLayer === 'undefined') return;
1647
1648      const objEvent = {
1649        category,
1650        action,
1651        label,
1652        value,
1653        event: 'eventga',
1654        ...dimensions
1655      };
1656
1657      window.dataLayer.push(objEvent);
1658    },
1659
1660    doEventAnalyticsWithCarrusel(e) {
1661      const activeSlide = document.querySelector('.carousel__slide--active');
1662      if (activeSlide && e.touches && e.touches[0]) {
1663        this._carouselState.nodo = activeSlide.getAttribute('data-description');
1664        this._carouselState.initialX = e.touches[0].clientX;
1665      }
1666    },
1667
1668    doEventAnalyticsWithCarruselEnd(e, product) {
1669      const { initialX, nodo } = this._carouselState;
1670      if (!initialX || !e.touches || !e.touches[0]) return;
1671
1672      const currentX = e.touches[0].clientX;
1673      const etiqueta = initialX > currentX ? 'Desplazar Izquierda' : 'Desplazar Derecha';
1674
1675      this._carouselState.initialX = 0;
1676
1677      setTimeout(() => {
1678        const activeSlide = document.querySelector('.carousel__slide--active');
1679        if (!activeSlide) return;
1680
1681        const descriptionNew = activeSlide.getAttribute('data-description');
1682        if (nodo !== descriptionNew) {
1683          const position = activeSlide.getAttribute('data-index-number');
1684          this.doEventAnalyticsWithDimensions('Interaccion', 'Carrusel', etiqueta, undefined, {
1685            product,
1686            position: 'caracteristicas producto',
1687            element: descriptionNew,
1688            type: 'swipe',
1689            order: position
1690          });
1691        }
1692      }, 200);
1693    },
1694
1695    doEventAnalyticsEnhancedEEC(name, id, price, brand, category) {
1696      this._pushToDataLayer({
1697        event: 'detail',
1698        ecommerce: {
1699          detail: {
1700            products: [{ name, id, price, brand, category }]
1701          }
1702        }
1703      });
1704    },
1705
1706    doEventAnalyticsEnhancedAddEEC(name, id, price, brand, category, quantity) {
1707      this._pushToDataLayer({
1708        event: 'addToCart',
1709        ecommerce: {
1710          currencyCode: 'EUR',
1711          add: {
1712            products: [{ name, id, price, brand, category, quantity }]
1713          }
1714        }
1715      });
1716    },
1717
1718    doEventAnalyticsPromoViewEEC(json) {
1719      if (json) this._pushToDataLayer(json);
1720    }
1721  },
1722  nbol:{
1723    launchModal()  {
1724      const translations = {
1725        es: {
1726          cerrarModal: "Cerrar modal",
1727          messageTitleCliente: "Soy cliente",
1728          messageTitleTextCliente: "Haciendo clic en el enlace, abandonarás la página web de Bankinter y serás redirigido a una página web externa propiedad de Mapfre.",
1729          btnCliente: "Simula y contrata",
1730          messageTitleNoCliente: "No soy cliente",
1731          messageTitleTextNoCliente: "Para continuar con la simulación y<br>posterior contratación de tu seguro,<br>llama al <strong>901 13 13 13</strong>."
1732        },
1733        en: {
1734          cerrarModal: "Close modal window",
1735          messageTitleCliente: "I'm a customer",
1736          messageTitleTextCliente: "When you click on the link you will leave the Bankinter website and be redirected to an external website owned by Mapfre.",
1737          btnCliente: "Calculate it then purchase it",
1738          messageTitleNoCliente: "I'm not a customer",
1739          messageTitleTextNoCliente: "To continue with the calculation and<br>then purchase your policy,<br>call <strong>901 13 13 13</strong>."
1740        },
1741        ca: {
1742          cerrarModal: "Tancar modal",
1743          messageTitleCliente: "Soc client",
1744          messageTitleTextCliente: "Fent clic a l'enllaç, abandonaràs el lloc web de Bankinter i seràs redirigit a una pàgina web externa propietat de Mapfre.",
1745          btnCliente: "Simula i contracta",
1746          messageTitleNoCliente: "No soc client",
1747          messageTitleTextNoCliente: "Per continuar amb la simulació i<br>posterior contractació de la teva assegurança,<br> truca al <strong>901 13 13 13</strong>."
1748        }
1749      };
1750
1751      const lang = (document.documentElement.lang || "es").slice(0, 2).toLowerCase();
1752      const t = translations[lang] || translations.es;
1753
1754      const htmlModal = `
1755            <div class="modal" id="modalNav" data-close-backdrop="true" tabindex="-1" role="dialog" style="z-index: 2000;">
1756              <div class="modal__backdrop"></div>
1757              <div class="container" role="document">
1758                <div class="row justify-content-center">
1759                  <div class="col-12 col-md-7 h-75">
1760                    <div class="modal__content">
1761                      <div class="modal__content__header">
1762                        <button type="button" class="btn btn--dark btn--rounded modal__close-button">
1763                          <span class="icon-fallback-text">
1764                            <span class="icon icon--close-16 icon--24" aria-hidden="true"></span>
1765                            <span class="text">${t.cerrarModal}</span>
1766                          </span>
1767                        </button>
1768                      </div>
1769                      <div class="modal__content__body">
1770                        <div class="modal__content__body__wrapper row">
1771                          <div class="col-12 col-lg-6">
1772                            <div>
1773                              <span class="d-flex h5 margin-bottom_16 message__title">${t.messageTitleCliente}</span>
1774                              ${t.messageTitleTextCliente}
1775                            </div>
1776                            <a href="https://precio.mapfre.es/calcular-seguro-salud-global/es
1776/fecha-inicio-seguro?origen=BKT&PPPO=MAPFRES**" 
1777                               onclick="bkjs.gtm.doEventAnalyticsExtended('Interaccion','Simulador seguro salud','Iniciar proceso clientes','Boton','popup','simula y contrata','1','1')" 
1778                               target="_blank" 
1779                               class="btn btn--primary margin-top_16 margin-bottom_16" 
1780                               tabindex="0">
1781                              <span class="text">${t.btnCliente}</span>
1782                            </a>
1783                          </div>
1784                          <div class="col-12 col-lg-6">
1785                            <div>
1786                              <span class="d-flex h5 margin-bottom_16 message__title">${t.messageTitleNoCliente}</span>
1787                              ${t.messageTitleTextNoCliente}
1788                            </div>
1789                          </div>
1790                        </div>
1791                        <div class="modal__content__footer"></div>
1792                      </div>
1793                    </div>
1794                  </div>
1795                </div>
1796              </div>
1797            </div>`;
1798
1799      document.querySelectorAll('.header-bk-wem__sublist-item a[data-target]').forEach((link) => {
1800        link.classList.add('launch-modal');
1801        link.href = '#';
1802      });
1803
1804      const mainEl = document.querySelector('main');
1805      if (mainEl) {
1806        mainEl.insertAdjacentHTML('afterend', htmlModal);
1807
1808      }
1809    }
1810  }
1811
1812};
1813
1814(() => {
1815  // ==========================================
1816  // 1. OBJETO BKJSBLOG OPTIMIZADO
1817  // ==========================================
1818  window.bkjsBlog = {
1819    _carouselState: { nodo: null, initialX: 0 },
1820
1821    components: {
1822      toggleDropdownElement(selector, targetClass, activeClass) {
1823        const targets = document.querySelectorAll(selector);
1824        const overlay = document.querySelector(".overlay");
1825
1826        targets.forEach((el) => {
1827          el.addEventListener("click", (e) => {
1828            const target = e.currentTarget.closest(targetClass);
1829            if (!target) return;
1830
1831            const isOpened = target.classList.contains(activeClass);
1832            bkjs.commons.classesToEl(target, isOpened ? "remove" : "add", activeClass);
1833            if (overlay) {
1834              bkjs.commons.classesToEl(overlay, isOpened ? "remove" : "add", "overlay--opened");
1835            }
1836          });
1837        });
1838
1839        if (overlay && !overlay.dataset.hasDropdownListener) {
1840          overlay.addEventListener("click", () => {
1841            const header = document.querySelector(".header-blog");
1842            if (header) {
1843              bkjs.commons.classesToEl(header, "remove", "header-blog--menu-opened");
1844              bkjs.commons.classesToEl(header, "remove", "header-blog--search-opened");
1845            }
1846            bkjs.commons.classesToEl(overlay, "remove", "overlay--opened");
1847          });
1848          overlay.dataset.hasDropdownListener = "true";
1849        }
1850      },
1851
1852      toggleMenuList() {
1853        const menuBox = document.querySelector(".menu-box");
1854
1855        document.querySelectorAll(".menu-box__show-more").forEach((btn) => {
1856          btn.addEventListener("click", (e) => {
1857            e.stopPropagation();
1858            const isOpened = e.currentTarget.classList.contains("menu-box__show-more--opened");
1859            const action = isOpened ? "remove" : "add";
1860
1861            if (menuBox) bkjs.commons.classesToEl(menuBox, action, "menu-box--opened");
1862            bkjs.commons.classesToEl(e.currentTarget, action, "menu-box__show-more--opened");
1863          });
1864        });
1865      },
1866
1867      formFullWidth() {
1868        document.querySelectorAll('.form-fw input[type="text"]').forEach((input) => {
1869          input.addEventListener("keyup", (e) => {
1870            const form = e.currentTarget.closest(".form-fw");
1871            if (!form) return;
1872
1873            const hasValue = Boolean(e.currentTarget.value && e.currentTarget.value !== "undefined");
1874            bkjs.commons.classesToEl(form, hasValue ? "add" : "remove", "form-fw--submit");
1875          });
1876        });
1877      },
1878
1879      toggleTabs(tabSelector, contentSelector) {
1880        const tabClass = tabSelector.replace(".", "") + "--active";
1881        const contentClass = contentSelector.replace(".", "") + "--active";
1882
1883        document.querySelectorAll(tabSelector).forEach((tab) => {
1884          tab.addEventListener("click", (e) => {
1885            e.stopPropagation();
1886            const targetId = e.currentTarget.dataset.elementValue;
1887            const container = e.currentTarget.closest(":has(" + tabSelector + ")") || e.currentTarget.parentElement.parentElement.parentElement;
1888
1889            container.querySelectorAll(tabSelector).forEach((el) => bkjs.commons.classesToEl(el, "remove", tabClass));
1890            bkjs.commons.classesToEl(e.currentTarget, "add", tabClass);
1891
1892            container.querySelectorAll(contentSelector).forEach((el) => bkjs.commons.classesToEl(el, "remove", contentClass));
1893
1894            const targetEl = document.getElementById(targetId);
1895            if (targetEl) {
1896              bkjs.commons.classesToEl(targetEl, "add", contentClass);
1897              targetEl.focus();
1898            }
1899          });
1900        });
1901      },
1902
1903      popover() {
1904        const popovers = document.querySelectorAll(".popover");
1905        const windowWidth = window.innerWidth;
1906        const sideMargins = windowWidth >= 768 ? 35 : -3;
1907
1908        popovers.forEach((popover, index) => {
1909          popover.id = `popover-${index}`;
1910          const items = popover.querySelectorAll(".popover__item");
1911
1912          items.forEach((item) => {
1913            item.id = `popover-text-${index}`;
1914            const rect = item.getBoundingClientRect();
1915
1916            if (rect.right > windowWidth) {
1917              item.style.left = `${windowWidth - sideMargins - rect.right}px`;
1918            } else if (rect.left > windowWidth) {
1919              item.style.left = `${windowWidth + sideMargins - rect.left}px`;
1920            } else if (rect.left <= 100) {
1921              item.style.left = "0px";
1922              item.style.marginLeft = "0px";
1923            }
1924          });
1925        });
1926      },
1927
1928      whenElementContentBoxInScreen(selector, t, o, n, s, r, a, c) {
1929        const element = document.querySelector(selector);
1930        if (!element) return;
1931
1932        const container = element.closest(".crm-messages__container");
1933        if (!container) return;
1934
1935        let triggered = false;
1936
1937        const observer = new IntersectionObserver(
1938          (entries) => {
1939            entries.forEach((entry) => {
1940              if (entry.isIntersecting && !triggered) {
1941                triggered = true;
1942
1943                if (r && window.innerWidth >= 768) {
1944                  bkjsBlog.gtm.doEventAnalyticsPromoViewEEC(t, o, n, s);
1945                  bkjsBlog.gtm.doEventAnalyticsPromoViewEEC(a, c, n, s);
1946                } else {
1947                  bkjsBlog.gtm.doEventAnalyticsPromoViewEEC(t, o, n, s);
1948                }
1949
1950                observer.disconnect();
1951              }
1952            });
1953          },
1954          { threshold: 1.0 }
1955        );
1956
1957        observer.observe(container);
1958      },
1959    },
1960
1961    gtm: {
1962      _pushToDataLayer(data) {
1963        if (typeof dataLayer !== "undefined") {
1964          dataLayer.push(data);
1965        }
1966      },
1967
1968      doEventAnalytics(category, action, label, value) {
1969        this._pushToDataLayer({ category, action, label, value, event: "eventga" });
1970      },
1971
1972      doEventAnalyticsExtended(category, action, label, type, position, element, order, value) {
1973        this._pushToDataLayer({ category, action, label, type, position, element, order, value, event: "eventga" });
1974      },
1975
1976      doVirtualUrl(virtualUrl) {
1977        this._pushToDataLayer({ virtualUrl, event: "virtualurl" });
1978      },
1979
1980      launchGtmAccordion(el, label, type, position) {
1981        const parentDiv = el.closest("div");
1982        const isOpened = parentDiv?.classList.contains("opened") && el.classList.contains("opened");
1983
1984        if (!isOpened) {
1985          bkjs.gtm.doEventAnalyticsExtended("Navegacion", "Enlace interno", "#", "enlace", label, type, position, undefined);
1986        }
1987      },
1988
1989      launchGtmFaqs(el, order) {
1990        if (!el.classList.contains("opened")) {
1991          bkjs.gtm.doEventAnalyticsExtended("Navegacion", "Enlace interno", "#", "enlace", "Faqs", "Preguntas frecuentes", order, undefined);
1992        }
1993      },
1994
1995      doEventAnalyticsWithDimensions(category, action, label, value, dimensions) {
1996        if (typeof dataLayer === "undefined") return;
1997
1998        const payload = { category, action, label, value, event: "eventga" };
1999        if (dimensions && typeof dimensions === "object") {
2000          Object.assign(payload, dimensions);
2001        }
2002        dataLayer.push(payload);
2003      },
2004
2005      doEventAnalyticsWithCarrusel(e) {
2006        const activeSlide = document.querySelector(".carousel__slide--active");
2007        const description = activeSlide?.getAttribute("data-description") || null;
2008        const x = e?.touches?.[0]?.clientX ?? null;
2009
2010        bkjsBlog._carouselState.nodo = description;
2011        bkjsBlog._carouselState.initialX = x;
2012      },
2013
2014      doEventAnalyticsWithCarruselEnd(e, product) {
2015        const { initialX, nodo } = bkjsBlog._carouselState;
2016
2017        if (initialX && initialX !== 0 && e?.touches?.[0]) {
2018          const currentX = e.touches[0].clientX;
2019          const etiqueta = initialX > currentX ? "Desplazar Izquierda" : "Desplazar Derecha";
2020          bkjsBlog._carouselState.initialX = 0;
2021
2022          setTimeout(() => {
2023            const activeSlide = document.querySelector(".carousel__slide--active");
2024            const descriptionNew = activeSlide?.getAttribute("data-description") || null;
2025
2026            if (nodo !== descriptionNew && activeSlide) {
2027              const order = activeSlide.getAttribute("data-index-number");
2028              bkjs.gtm.doEventAnalyticsWithDimensions("Interaccion", "Carrusel", etiqueta, undefined, {
2029                product,
2030                position: "caracteristicas producto",
2031                element: descriptionNew,
2032                type: "swipe",
2033                order,
2034              });
2035            }
2036          }, 200);
2037        }
2038      },
2039
2040      doEventAnalyticsEnhancedEEC(name, id, price, brand, category) {
2041        this._pushToDataLayer({
2042          event: "detail",
2043          ecommerce: { detail: { products: [{ name, id, price, brand, category }] } },
2044        });
2045      },
2046
2047      doEventAnalyticsEnhancedAddEEC(name, id, price, brand, category, quantity) {
2048        this._pushToDataLayer({
2049          event: "addToCart",
2050          ecommerce: {
2051            currencyCode: "EUR",
2052            add: { products: [{ name, id, price, brand, category, quantity }] },
2053          },
2054        });
2055      },
2056
2057      doEventAnalyticsPromoViewEEC(id, name, creative, position) {
2058        this._pushToDataLayer({
2059          event: "ecommerce.js",
2060          ecommerce: { promoView: { promotions: [{ id, name, creative, position }] } },
2061        });
2062      },
2063
2064      doEventAnalyticsPromoClickEEC(id, name, creative, position) {
2065        if (typeof dataLayer === "undefined") return;
2066
2067        dataLayer.push({
2068          event: "ecommerce.js",
2069          ecommerce: { promoClick: { promotions: [{ id, name, creative, position }] } },
2070        });
2071        dataLayer.push({ event: "eventga" });
2072      },
2073
2074      _getSubscriptionValue() {
2075        const checkboxes = document.querySelectorAll(".suscribirse__checkbox--modal");
2076        if (checkboxes.length < 2) return undefined;
2077
2078        const [cb1, cb2] = checkboxes;
2079        if (cb1.checked && cb2.checked) return "Diario-Semanal";
2080        if (cb1.checked) return "Diario";
2081        if (cb2.checked) return "Semanal";
2082        return undefined;
2083      },
2084
2085      doEventAnalyticsSubscription() {
2086        this._pushToDataLayer({
2087          category: "Interaccion",
2088          action: "Newsletter - Blog",
2089          label: "Solicitar suscripcion",
2090          value: this._getSubscriptionValue(),
2091          event: "eventga",
2092        });
2093      },
2094
2095      doEventAnalyticsCorrectSubscription() {
2096        this._pushToDataLayer({
2097          category: "Conversion",
2098          action: "Newsletter - Blog",
2099          label: "Confirmar suscripcion",
2100          value: this._getSubscriptionValue(),
2101          event: "eventga",
2102        });
2103      },
2104
2105      doEventAnalyticsSocialNetwork(action, label, position) {
2106        this._pushToDataLayer({ category: "Interaccion", action, label, position, event: "eventga" });
2107      },
2108
2109      doEventInteractionPromotion(id, name, creative, position) {
2110        this._pushToDataLayer({
2111          event: "ecommerce.js",
2112          ecommerce: { promoClick: { promotions: [{ id, name, creative, position }] } },
2113          eventCallback() {},
2114        });
2115      },
2116    },
2117
2118    setShareSticky(selector) {
2119      const el = document.querySelector(selector);
2120      if (!el) return;
2121
2122      const initialTop = el.getBoundingClientRect().top + window.scrollY;
2123
2124      window.addEventListener(
2125        "scroll",
2126        () => {
2127          const isSticky = window.scrollY >= initialTop;
2128          const hasClass = el.classList.contains("share__content--sticky");
2129
2130          if (isSticky && !hasClass) {
2131            bkjs.commons.classesToEl(el, "add", "share__content--sticky");
2132          } else if (!isSticky && hasClass) {
2133            bkjs.commons.classesToEl(el, "remove", "share__content--sticky");
2134          }
2135        },
2136        { passive: true }
2137      );
2138    },
2139  };
2140
2141  // Matriz compartida para cálculos de equalSize (reutilizada en init y resize)
2142  const EQUAL_SIZE_PAIRS = [
2143    ['.product-features', '.section-heading__title'],
2144    ['.product-features', '.section-heading__description'],
2145    ['.product-features', '.section-heading'],
2146    ['.product-features', '.content-box__content__title'],
2147    ['.product-features', '.content-box__content-title'],
2148    ['.product-features', '.content-box__content p'],
2149    ['.simple-info', '.simple-info__title'],
2150    ['.simple-info', 'p'],
2151    ['.content-box', '.section-heading__title'],
2152    ['.content-box', '.section-heading__description'],
2153    ['.content-box', '.section-heading p'],
2154    ['.filter__boxes', '.section-heading__title'],
2155    ['.filter__boxes', '.content-box__content'],
2156    ['.simulador-result', '.nombre-simulador'],
2157    ['.simulador-result', '.pagos-simulador'],
2158    ['.simulador-result', '.impuestos-simulador'],
2159    ['.simulador-result', '.button-simulador'],
2160    ['.carousel__inner', '.content-box'],
2161    ['.content-swap', '.content-box__content'],
2162    ['.cols-equal-size', '.content-box p'],
2163    ['.cols-equal-size', '.section-heading_second'],
2164    ['.cols-equal-size', '.content-box__content'],
2165    ['.featured-box__multiple', '.featured-box']
2166  ];
2167
2168  // Helper Debounce
2169  function debounce(fn, delay = 150) {
2170    let timeoutId;
2171    return function (...args) {
2172      clearTimeout(timeoutId);
2173      timeoutId = setTimeout(() => fn.apply(this, args), delay);
2174    };
2175  }
2176
2177  // ==========================================
2178  // 2. INICIALIZACIÓN DOMCONTENTLOADED
2179  // ==========================================
2180  document.addEventListener("DOMContentLoaded", function () {
2181    const dSiteName = document.body?.dataset?.sitename ?? null;
2182    if (dSiteName === 'NBOL') {
2183      bkjs.nbol.launchModal();
2184    }
2185
2186    bkjs.components.closeModal();
2187
2188    // --- LÓGICA DEL BLOG ---
2189    if (dSiteName === 'Blog') {
2190      const { components, setShareSticky } = bkjsBlog;
2191      components.toggleDropdownElement(".button__header-menu", ".header-blog", "header-blog--menu-opened");
2192      components.toggleDropdownElement(".button__header-search", ".header-blog", "header-blog--search-opened");
2193      components.toggleMenuList();
2194      components.formFullWidth();
2195      setShareSticky(".share__content");
2196      ajustFooterMobile();
2197
2198      if (window.innerWidth <= 1165) {
2199        requestAnimationFrame(() => components.popover());
2200      }
2201
2202      const socialBtn = document.querySelector(".button__header-menu-social");
2203      if (socialBtn) {
2204        const socialMediaMenu = document.querySelector(".header-blog__menu-social-media");
2205        const socialIcon = document.querySelector(".header-blog__social");
2206        const linkSueldo = document.querySelector(".header-blog__link-calculadora-sueldo-neto");
2207
2208        socialBtn.addEventListener("click", () => {
2209          socialMediaMenu?.classList.toggle("d-none");
2210
2211          if (socialIcon) {
2212            const isShare = socialIcon.classList.contains("icon--share-16");
2213            socialIcon.classList.toggle("icon--share-16", !isShare);
2214            socialIcon.classList.toggle("icon--close-16", isShare);
2215
2216            if (linkSueldo && window.innerWidth >= 768) {
2217              linkSueldo.classList.toggle("d-none", isShare);
2218              linkSueldo.classList.toggle("d-md-block", !isShare);
2219            }
2220          }
2221        });
2222      }
2223    }
2224
2225
2226    // --- COMMONS Y COMPONENTS GENERALES ---
2227    const { commons, components } = bkjs;
2228
2229    commons.msieversion();
2230    commons.toggleHeaderSize();
2231    commons.setMainContentPaddingTop();
2232    commons.loadingButton();
2233
2234    if (dSiteName === 'roboadvisor') {
2235      commons.cleanMenuRoboadvisor();
2236      components.closeButtonSticky();
2237    }
2238
2239
2240    commons.setMenuActiveOption();
2241    commons.closeLayer();
2242    commons.analyzeFormContent();
2243    components.toggleDropdown();
2244    commons.opinatorPagaComodoAbandono();
2245    components.toggleCheckboxEllipsis();
2246    components.openModal();
2247    components.openMessage();
2248    components.closeMessage();
2249    components.openClausula();
2250    components.closeClausula();
2251    components.accesibleIconSelectorRadio();
2252    components.clickFilters();
2253    components.clickFiltersModal();
2254    components.initSmoothHrefMode();
2255    commons.mainBannerCarousel();
2256    components.launchJumpContent();
2257    commons.equalSizeNoParentElement('.card--simple-equal-size');
2258    commons.equalSizeNoParentElement('.card__body-grid-equal-size');
2259
2260    // --- AJUSTES POR SITENAME ---
2261    if (['NBOL', 'Broker'].includes(dSiteName)) {
2262      if (document.querySelector('.breadcrumbs__item')) {
2263        document.querySelector('.header-bk-wem')?.classList.add('header-bk-wem--container-mobile--breadcrumb');
2264      }
2265    }
2266
2267    if (['NBOL', 'Empresas', 'Broker'].includes(dSiteName)) {
2268      const footerGray = document.querySelector('.footer-gray');
2269      const featuredSticky = document.querySelector('.featured-box_sticky');
2270      const footer = document.querySelector('.footer');
2271
2272      if (footerGray) {
2273        document.body.classList.add('footer-gray-body');
2274        if (featuredSticky) {
2275          footerGray.style.paddingBottom = '104px';
2276        }
2277      }
2278
2279      if (footer && featuredSticky) {
2280        footer.style.paddingBottom = `${featuredSticky.offsetHeight}px`;
2281      }
2282    }
2283
2284    commons.goToIdTarget();
2285    components.toggleCtaInterval('#init-cta', '#end-cta');
2286    components.ctaStickyMobile();
2287
2288    // --- CÁLCULO INICIAL EQUAL-SIZE ---
2289    if (document.querySelector('.equal-size')) {
2290      requestAnimationFrame(() => {
2291        EQUAL_SIZE_PAIRS.forEach(([parent, target]) => commons.equalSize(parent, target));
2292
2293        const extraSize = window.innerWidth >= 768 ? 64 : 100;
2294        commons.equalSize('.filter__boxes--element-wrapper', '.filter__boxes--element', extraSize);
2295
2296        if (window.innerWidth >= 1024) {
2297          commons.equalSize('.graph-row', '.container-graph');
2298        }
2299      });
2300    }
2301
2302    // --- EVENTO DE CLICK EN FILTROS (ASIGNACIÓN ÚNICA) ---
2303    document.querySelectorAll('.filters__element').forEach((element) => {
2304      element.addEventListener('click', () => {
2305        const extraSize = window.innerWidth >= 768 ? 64 : 100;
2306        bkjs.commons.equalSize('.filter__boxes--element-wrapper', '.filter__boxes--element', extraSize);
2307      });
2308    });
2309
2310    if (document.querySelector('.simple-info--equal-size') && window.innerWidth > 991) {
2311      commons.equalSizeNoParentElement('.simple-info--equal-size');
2312    }
2313
2314    jsPropagateParamsUrl();
2315  });
2316
2317  // ==========================================
2318  // 3. EVENTO RESIZE CON DEBOUNCE
2319  // ==========================================
2320  const handleResize = () => {
2321    const { commons, components } = bkjs;
2322    const dSiteName = document.body?.dataset?.sitename ?? null;
2323    commons.setMainContentPaddingTop();
2324    components.calcPositionFixed();
2325    components.ctaStickyMobile();
2326
2327    // B) Lógica específica del Blog en Resize
2328    if (dSiteName === 'Blog') {
2329      if (typeof ajustFooterMobile === 'function') ajustFooterMobile();
2330
2331      document.querySelectorAll('.popover__item').forEach((item) => {
2332        item.style.left = '';
2333      });
2334
2335      if (window.innerWidth <= 1165) {
2336        bkjsBlog.components.popover();
2337      }
2338    }
2339
2340    // C) Lógica de Cajas e Info Simple
2341    const simpleInfoBoxes = document.querySelectorAll('.simple-info--equal-size');
2342    if (simpleInfoBoxes.length > 0) {
2343      simpleInfoBoxes.forEach((box) => box.removeAttribute('style'));
2344      if (window.innerWidth >= 992) {
2345        commons.equalSizeNoParentElement('.simple-info--equal-size');
2346      }
2347    }
2348
2349    // D) Recálculo de alturas con requestAnimationFrame
2350    requestAnimationFrame(() => {
2351      EQUAL_SIZE_PAIRS.forEach(([parent, target]) => commons.equalSize(parent, target));
2352
2353      const extraSize = window.innerWidth >= 768 ? 64 : 100;
2354      commons.equalSize('.filter__boxes--element-wrapper', '.filter__boxes--element', extraSize);
2355
2356      if (window.innerWidth >= 1024) {
2357        commons.equalSize('.graph-row', '.container-graph');
2358      }
2359    });
2360  };
2361
2362  window.addEventListener('resize', debounce(handleResize, 150));
2363})();
2364
2365
2366function elementVisible(e) {
2367  if (null == e) return !1;
2368  let t = e.getBoundingClientRect();
2369  return t.top >= 0 && t.left >= 0 && t.right <= (window.innerWidth || document.documentElement.clientWidth) && t.bottom <= (window.innerHeight || document.documentElement.clientHeight);
2370}
2371
2372function ajustFooterMobile() {
2373  setTimeout(function () {
2374    if (window.innerWidth < 576) {
2375      if (document.querySelector('.share')) {
2376        document.querySelector('footer').style.paddingBottom = document.querySelector('.share').clientHeight + 'px';
2377        if (document.querySelector('.floating-link--sticky')) {
2378          document.querySelector('.floating-link--sticky').querySelector('.featured-box').style.bottom = document.querySelector('.share').clientHeight;
2379          document.querySelector('footer').style.paddingBottom = (document.querySelector('.share').clientHeight + document.querySelector('.floating-link--sticky').querySelector('.featured-box').clientHeight) + 'px';
2380        }
2381        if (document.querySelector('.featured-box--sticky-bloqued')) {
2382          document.querySelector('.featured-box--sticky-bloqued').style.bottom = document.querySelector('.share').clientHeight + 'px';
2383          document.querySelector('footer').style.paddingBottom = (document.querySelector('.share').clientHeight + document.querySelector('.featured-box--sticky-bloqued').clientHeight) + 'px';
2384        }
2385      } else {
2386        if (document.querySelector('.floating-link--sticky')) {
2387          document.querySelector('footer').style.paddingBottom = document.querySelector('.floating-link--sticky').querySelector('.featured-box').clientHeight + 'px';
2388        }
2389        if (document.querySelector('.featured-box--sticky-bloqued')) {
2390          document.querySelector('footer').style.paddingBottom = +document.querySelector('.featured-box--sticky-bloqued').clientHeight + 'px';
2391        }
2392      }
2393    }
2394  }, 1000);
2395}
2396
2397//UCPM
2398async function sha256(value) {
2399  const encoder = new TextEncoder();
2400  const data = encoder.encode(value);
2401  const hashBuffer = await crypto.subtle.digest('SHA-256', data);
2402  const hashBytes = new Uint8Array(hashBuffer);
2403  return Array.from(hashBytes, byte => byte.toString(16).padStart(2, '0')).join('');
2404}
2405
2406function formatIntNumberE164(phone) {
2407  const cleaned = phone.replace(/[^\d+]/g, "");
2408  if (cleaned.startsWith("+")) return cleaned;
2409  if (cleaned.startsWith("00")) return `+${cleaned.slice(2)}`;
2410  return `+34${cleaned}`;
2411}
2412
2413async function callUCPM(data) {
2414  const input = document.querySelector('[name="ucpm-code"]');
2415  if (!input || !input.value) {
2416    return;
2417  }
2418  const token = await callUCPMobtainToken(input.value);
2419  if (!token) return;
2420  return await callUCPMSaveElem(token, data);
2421}
2422
2423
2424async function callUCPMobtainToken(code) {
2425  const hostnameAPiUcpm = typeof hostnameApi !== "undefined" ? hostnameApi : "https://brokerapi.bankinter.com";
2426  const url = `${hostnameAPiUcpm}/api/consentmanager/v1/collectionPoints/${encodeURIComponent(code)}/token`;
2427    try {
2428      const response = await fetch(url, {
2429        headers: { "Accept": "application/json" }
2430      });
2431      if (!response.ok) throw new Error(`HTTP Error: ${response.status}`);
2432      return await response.json();
2433  } catch (error) {
2434    console.log("Error llamando al endpoint:", error);
2435    return null;
2436  }
2437}
2438
2439async function callUCPMSaveElem(JWTcode, data) {
2440  const hostnameAPiUcpm = typeof hostnameApi !== "undefined" ? hostnameApi : "https://brokerapi.bankinter.com";
2441  const url = `${hostnameAPiUcpm}/api/consentmanager/v1/request/consentReceipts`;
2442  const dataObject = objectToKeyValueArray(data);
2443  const dataMap = Object.fromEntries(
2444    dataObject.map(({ key, value }) => [key, value])
2445  );
2446
2447  const componentName = dataMap.component_name;
2448  const purposes = dataMap.purposes;
2449
2450  const keyMap = {
2451    mkt_hash_id_02: "PhoneHashed",
2452    mkt_hash_id_01: "EmailHashed",
2453    mkt_id_02: "Phone",
2454    mkt_id_01: "Email",
2455    nombre_apellidos: "Name"
2456  };
2457
2458  const dataObjectFilteredRenamed = dataObject
2459  .filter(({ key }) =>
2459 key in keyMap)
2460  .map(({ key, value }) => ({
2461    key: keyMap[key],
2462    value
2463  }));
2464
2465  const mktInfo = getMktInfo(dataObject);
2466
2467  const hn = window.location.hostname;
2468  const isTest = !(hn.endsWith('.com') || hn.endsWith('.es') || hn.endsWith('.ie'));
2469
2470  const body = {
2471    requestInformation: JWTcode.token,
2472    identifier: mktInfo.id,
2473    identifierType: mktInfo.type,
2474    dataElements: dataObjectFilteredRenamed,
2475    purposes: purposes,
2476    customPayload: [
2477      {key:"formProcess", value: componentName},
2478      {key:"formStep",value:"paso1"},
2479      {key:"formUrl",value:  window.location.href},
2480
2481    ],
2482    test: isTest
2483  };
2484
2485  try {
2486    const response = await fetch(url, {
2487      method: "POST",
2488      headers: {
2489        "Content-Type": "application/json"
2490      },
2491      body: JSON.stringify(body)
2492    });
2493
2494    return response.ok ? "OK" : "KO";
2495  } catch (error) {
2496    console.log("Error al llamar al endpoint:", error);
2497    return "KO";
2498  }
2499}
2500
2501function getMktInfo(obj) {
2502  const mkt01 = obj.find(el => el.key === 'mkt_id_01');
2503  if (mkt01) return {
2504    id: mkt01.value,
2505    type: "Email"
2506  };
2507  const mkt02 = obj.find(el => el.key === 'mkt_id_02');
2508  if (mkt02) return {
2509    id: mkt02.value,
2510    type: "Phone"
2511  };
2512  return null;
2513}
2514
2515function objectToKeyValueArray(obj) {
2516  return Object.entries(obj)
2517  .filter(([_, value]) =>
2518    typeof value === 'string' ||
2519    (Array.isArray(value) && value.every(v => typeof v === 'string'))
2520  )
2521  .map(([key, value]) => ({
2522    key,
2523    value
2524  }));
2525}
2526
2527function obtenerUCPMPurposes() {
2528    const inputs = document.querySelectorAll('input[type="checkbox"][ucpm-purpose]:checked');
2529    const values = Array.from(inputs, input => input.getAttribute('ucpm-purpose')).filter(Boolean);
2530    return [...new Set(values)];
2531}
2532
2533let codeOTPOperative='';
2534
2535async function launchOTPUCPM(data) {
2536  try{
2537    bkrRestDataNew.commons.loadRestHeader();
2538  }catch(error){}
2539  const modal = data.closest('.modal');
2540  if (!modal) return;
2541  const email = modal.querySelector('.otp-email').value;
2542  const name = modal.querySelector('.otp-name').value;
2543
2544  let hostnameApiOTP = typeof hostnameApi !== "undefined" ? hostnameApi : "https://brokerapi.bankinter.com";
2545  const url = `${hostnameApiOTP}/api/investmentacademymgmt/v1/otpOperatives`;
2546  try {
2547    const response = await fetch(url, {
2548      method: "POST",
2549      headers: {"Content-Type": "application/json"},
2550      body: JSON.stringify({ email, name, operativeType: 'investment_academy_access' })
2551    });
2552
2553    if (!response.ok) {
2554      throw new Error(`Error HTTP: ${response.status}`);
2555    }
2556    const resjson = await response.json();
2557    codeOTPOperative =resjson.id;
2558  } catch (error) {
2559    console.log("Error al llamar al endpoint:", error);
2560  }
2561}
2562async function launchOTPUCPMCode(data) {
2563  const code = data.closest('.modal').querySelector('.otp-code').value;
2564  const hostnameApiOTP = typeof hostnameApi !== "undefined" ? hostnameApi : "https://brokerapi.bankinter.com";
2565  const url = `${hostnameApiOTP}/api/investmentacademymgmt/v1/otpOperatives/${codeOTPOperative}`;
2566  try {
2567    const response = await fetch(url, {
2568      method: "POST",
2569      headers: {"Content-Type": "application/json"},
2570      body: JSON.stringify({otp: code})
2571    });
2572    return response.ok ? "OK" : "KO";
2573  } catch (error) {
2574    console.log("Error al llamar al endpoint:", error);
2575    return "KO";
2576  }
2577}
2578
2579function jsPropagateParamsUrl(){
2580  const landingParams = new URLSearchParams(window.location.search);
2581  if (!landingParams.toString()) {
2582    return;
2583  }
2584  document.querySelectorAll('.js-propagate-params').forEach(function (link) {
2585    const url = new URL(link.href, window.location.origin);
2586
2587    landingParams.forEach(function (value, key) {
2588      if (!url.searchParams.has(key)) {
2589        url.searchParams.append(key, value);
2590      }
2591    });
2592
2593    link.href = url.toString();
2594  });
2595}
2596
2597document.addEventListener('click', function(event) {
2598  const link = event.target.closest('a.link-with-params-onboarding');
2599  if (!link) return;
2600  event.preventDefault();
2601  const originalHref = link.getAttribute('href');
2602
2603  try {
2604    const url = new URL(originalHref, window.location.origin);
2605    // Comprobamos si la variable existe, es un objeto y no es null
2606    if (typeof URL_PARAMS === 'object' && URL_PARAMS !== null) {
2607      Object.entries(URL_PARAMS).forEach(([key, value]) => {
2608        if (value !== null && value !== undefined && value !== '') {
2609          url.searchParams.set(key, value);
2610        }
2611      });
2612    }
2613    window.location.href = url.toString();
2614  } catch (error) {
2615    window.location.href = originalHref;
2616  }
2617});

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.