PageSourceSearch

https://www.farmaciasbrava.com.br/staticfiles/js/carrosseis.js

js farmaciasbrava.com.br collected 2026-09-24 10:42:35 UTC 32,872 bytes, 926 lines download raw bytes

1/*
2* Carregamento de scripts dos carrosseis e criação da lógica de inicialização dos elementos
3*/
4
5const CAROUSEL_PRESETS = {
6  xs: {
7    breakpoints: {
8      0:    { slidesPerView: 5, spaceBetween: 3 },
9      768:  { slidesPerView: 8, spaceBetween: 4 },
10      1024: { slidesPerView: 12,   spaceBetween: 5 },
11    },
12  },
13  sm: {
14    breakpoints: {
15      0:    { slidesPerView: 4.5, spaceBetween: 5 },
16      768:  { slidesPerView: 6.5, spaceBetween: 5 },
17      1024: { slidesPerView: 10,   spaceBetween: 5 },
18    },
19  },
20  md: {
21    breakpoints: {
22      0:    { slidesPerView: 3.1, spaceBetween: 5 },
23      768:  { slidesPerView: 3.5, spaceBetween: 5 },
24      1024: { slidesPerView: 6,   spaceBetween: 15 },
25    },
26  },
27  lg: {
28    breakpoints: {
29      0:    { slidesPerView: 2.1, spaceBetween: 5 },
30      768:  { slidesPerView: 2.5, spaceBetween: 5 },
31      1024: { slidesPerView: 4,   spaceBetween: 10 },
32    },
33  },
34  xl: {
35    breakpoints: {
36      0:    { slidesPerView: 1.1, spaceBetween: 5 },
37      768:  { slidesPerView: 2, spaceBetween: 5 },
38      1024: { slidesPerView: 3,    spaceBetween: 15 },
39    },
40  },
41  one: {
42    breakpoints: {
43      0:    { slidesPerView: 1,   spaceBetween: 0 },
44      768:  { slidesPerView: 1, spaceBetween: 0 },
45      1024: { slidesPerView: 1, spaceBetween: 0 },
46    },
47  },
48  two: {
49    breakpoints: {
50      0:    { slidesPerView: 1.1,   spaceBetween: 5 },
51      768:  { slidesPerView: 2.1,   spaceBetween: 8 },
52      1024: { slidesPerView: 2,   spaceBetween: 12 },
53    },
54  },
55  three: {
56    breakpoints: {
57      0:    { slidesPerView: 1.1, spaceBetween: 5 },
58      768:  { slidesPerView: 2.1,   spaceBetween: 8 },
59      1024: { slidesPerView: 3,   spaceBetween: 15 },
60    },
61  },
62  four: {
63    breakpoints: {
64      0:    { slidesPerView: 1.1, spaceBetween: 5 },
65      768:  { slidesPerView: 2.1,   spaceBetween: 8 },
66      1024: { slidesPerView: 4,   spaceBetween: 10 },
67    },
68  },
69  five: {
70    breakpoints: {
71      0:    { slidesPerView: 2.1, spaceBetween: 5 },
72      768:  { slidesPerView: 3.1,   spaceBetween: 8 },
73      1024: { slidesPerView: 5,   spaceBetween: 15 },
74    },
75  },
76  six: {
77    breakpoints: {
78      0:    { slidesPerView: 2.1, spaceBetween: 5 },
79      768:  { slidesPerView: 3.1,   spaceBetween: 8 },
80      1024: { slidesPerView: 6,   spaceBetween: 15 },
81    },
82  },
83  two_complete: {
84    breakpoints: {
85      0:    { slidesPerView: 1, spaceBetween: 5 },
86      768:  { slidesPerView: 2, spaceBetween: 8 },
87      1024: { slidesPerView: 2, spaceBetween: 12 },
88    },
89  },
90  three_complete: {
91    breakpoints: {
92      0:    { slidesPerView: 1, spaceBetween: 5 },
93      768:  { slidesPerView: 2, spaceBetween: 8 },
94      1024: { slidesPerView: 3, spaceBetween: 12 },
95    },
96  },
97  pilulas_sm: {
98    breakpoints: {
99      0:    { slidesPerView: 2, spaceBetween: 10 },
100      768:  { slidesPerView: 3, spaceBetween: 15 },
101      1024: { slidesPerView: 6, spaceBetween: 20 },
102    },
103  },
104  pilulas_md: {
105    breakpoints: {
106      0:    { slidesPerView: 2.5, spaceBetween: 10 },
107      768:  { slidesPerView: 4,   spaceBetween: 15 },
108      1024: { slidesPerView: 7,   spaceBetween: 20 },
109    },
110  },
111  pilulas_lg: {
112    breakpoints: {
113      0:    { slidesPerView: 3,   spaceBetween: 10 },
114      768:  { slidesPerView: 4.5, spaceBetween: 15 },
115      1024: { slidesPerView: 8,   spaceBetween: 20 },
116    },
117  },
118};
119
120const INFORMACOES_PRESETS = {
121  three: {
122    breakpoints: {
123      0:    { slidesPerView: 1.1, spaceBetween: 5 },
124      768:  { slidesPerView: 2.1,   spaceBetween: 8 },
125      1024: { slidesPerView: 3,   spaceBetween: 15 },
126    },
127  },
128  four: {
129    breakpoints: {
130      0:    { slidesPerView: 1.1, spaceBetween: 5 },
131      768:  { slidesPerView: 2.1,   spaceBetween: 8 },
132      1024: { slidesPerView: 4,   spaceBetween: 10 },
133    },
134  },
135  five: {
136    breakpoints: {
137      0:    { slidesPerView: 1.1, spaceBetween: 5 },
138      768:  { slidesPerView: 2.1,   spaceBetween: 8 },
139      1024: { slidesPerView: 5,   spaceBetween: 15 },
140    },
141  }
142}
143
144const VIDEOS_PRESETS = {
145  two: {
146    breakpoints: {
147      0:    { slidesPerView: 1, spaceBetween: 5 },
148      768:  { slidesPerView: 1, spaceBetween: 5 },
149      1024: { slidesPerView: 2, spaceBetween: 5 },
150    },
151  },
152};
153
154const PRESET_PRODUTOS = {
155  padrao: {
156    breakpoints: {
157      0:    { slidesPerView: 2, spaceBetween: 5  },
158      768:  { slidesPerView: 3.1, spaceBetween: 5  },
159      1024: { slidesPerView: 5,   spaceBetween: 25 },
160    },
161  },
162  scrollbar: {
163    breakpoints: {
164      0:    { slidesPerView: 2, spaceBetween: 5  },
165      768:  { slidesPerView: 3.1, spaceBetween: 5  },
166      1024: { slidesPerView: 5,   spaceBetween: 25 },
167    },
168    pagination: false,
169    scrollbar: true,
170    navigation: true,
171  },
172  lg: {
173    breakpoints: {
174      0:    { slidesPerView: 1, spaceBetween: 5  },
175      768:  { slidesPerView: 2.5, spaceBetween: 5  },
176      1024: { slidesPerView: 3,   spaceBetween: 28 },
177    },
178  },
179  horizontal: {
180    breakpoints: {
181      0:    { slidesPerView: 1, spaceBetween: 5  },
182      768:  { slidesPerView: 2.5, spaceBetween: 5  },
183      1024: { slidesPerView: 4,   spaceBetween: 10 },
184    },
185  },
186};
187
188
189function criarCarrosselDeImagens(selector, preset) {
190  const carrosseis = document.querySelectorAll(selector);
191  if (!carrosseis.length) return;
192
193  carrosseis.forEach((el, index) => {
194    if (el.swiper) return;
195
196    el.querySelectorAll('.slide').forEach(slide => slide.classList.add('swiper-slide'));
197
198    const paginationEl  = el.querySelector('.swiper-pagination');
199    const scrollbarEl  = el.querySelector('.swiper-scrollbar');
200    const nextEl = el.querySelector('.swiper-button-next');
201    const prevEl = el.querySelector('.swiper-button-prev');
202
203    new Swiper(el, {
204      direction: 'horizontal',
205      loop: el.dataset.loop == 'true' ? true : false,
206      autoplay: el.dataset.autoplay == 'true'
207      ? { delay: 6000, disableOnInteraction: true } 
208      : false,
209      ...preset,
210      pagination: paginationEl
211        ? { el: paginationEl, clickable: true, enabled: true }
212        : { enabled: false },
213      scrollbar: scrollbarEl
214        ? { el: scrollbarEl, draggable: true, enabled: true }
215        : { enabled: false },
216      navigation: (nextEl && prevEl)
217        ? { nextEl, prevEl, enabled: true }
218        : { enabled: false },
219    });
220
221    const wrapper = el.querySelector('.swiper-wrapper');
222    if (wrapper) wrapper.className = 'swiper-wrapper';
223    if (paginationEl) wrapper.classList.add('mb-11');
224    if (scrollbarEl) wrapper.classList.add('mb-8');
225
226    el.querySelectorAll('img.hidden').forEach(img => img.classList.remove('hidden'));
227
228    try {
229      el.querySelectorAll('a, .slide a').forEach((a, index) => {
230        a.addEventListener('click', () => {
231          if (typeof filtroParaDadosAnaliticos === 'function') {
232            const slide = a.closest('.swiper-slide');
233            const type = el.dataset.carrosselImagensTitulo || 'carrossel-imagens';
234            const posicao = slide?.dataset.swiperSlideIndex
235                              ? Number(slide.dataset.swiperSlideIndex) + 1 
236                              : null;
237            
238            filtroParaDadosAnaliticos('MenuAndCallToAction', {
239              event: 'click_banner',
240              content_type: type,
241              content_id: a.href || 'imagem_sem_id',
242              position: posicao || 1,
243              section: el?.dataset?.carrosselImagensSection || 'home'
244            });
245          }
246        });
247      });
248    } catch(_) {}
249  });
250};
251
252function criarCarrosselDeProdutosGenerico(selector, preset) {
253
254  const carrosseis = document.querySelectorAll(selector);
255  if (!carrosseis.length) return;
256
257  carrosseis.forEach((el) => {
258    if (el.swiper) return;
259
260    el.querySelectorAll('.slide').forEach(slide => slide.classList.add('swiper-slide'));
261    
262    /*
263    * Ao carregar os componentes com o JS do navegador desabilitado, a aparência inicial do carrossel deve ser parecida com o carrossel carregado via JS
264    * Devido a isso, é necessário o bloco abaixo para remover as estilizações utilizadas para isso antes de inicializar o carrossel
265    * NÃO APAGAR E NÃO REMOVER AS CLASSES DO CADASTRO DO COMPONENTE SEM TESTAR O LAYOUT COM O JS DESABILITADO NO NAVEGADOR
266    */
267    if(el.querySelector('.swiper-wrapper'))
268      el.querySelector('.swiper-wrapper').classList?.remove('justify-between', 'gap-x-5', 'overflow-x-auto')
269    el.querySelectorAll('.slide').forEach(slide => {
270      slide.style.width = 'inherit'
271    })
272
273    const paginationEl = el.querySelector('.swiper-pagination');
274    const scrollbarEl  = el.querySelector('.swiper-scrollbar');
275    const nextEl       = el.querySelector('.swiper-button-next');
276    const prevEl       = el.querySelector('.swiper-button-prev');
277
278    new Swiper(el, {
279      
280      direction: 'horizontal',
281      loop: el.dataset.loop == 'true' ? true : false,
282      centeredSlides: false,
283      autoplay: el.dataset.autoplay == 'true' ? true : false
284        ? { delay: 6000, disableOnInteraction: true }
285        : false,
286      breakpoints: preset.breakpoints,
287      pagination: preset.pagination || paginationEl
288        ? { el: paginationEl, clickable: true, enabled: true }
289        : { enabled: false },
290      scrollbar: preset.scrollbar || scrollbarEl
291        ? { el: scrollbarEl, draggable: false, enabled: true }
292        : { enabled: false },
293      navigation: (nextEl && prevEl)
294        ? { nextEl, prevEl, enabled: true }
295        : { enabled: false },
296    });
297
298    const wrapper = el.querySelector('.swiper-wrapper');
299    if (wrapper) {
300      wrapper.classList.add('swiper-wrapper');
301      if (paginationEl) wrapper.classList.add('mb-11');
302      if (scrollbarEl) wrapper.classList.add('mb-8');
303      if (!paginationEl && !scrollbarEl) wrapper.classList.add('mb-3');
304    }
305
306    el.querySelectorAll('.swiper-slide.hidden, img.hidden')
307      .forEach(node => node.classList.remove('hidden'));
308
309    // SelectItem em clique de cards deste carrossel
310    try {
311      el.querySelectorAll('a, .slide a').forEach((a) => {
312        if (a.dataset.selectItemBound === '1') return;
313        a.dataset.selectItemBound = '1';
314
315        a.addEventListener('click', function (event) {
316          try {
317            if (typeof filtroParaDadosAnaliticos !== 'function') return;
318
319            const link = event.currentTarget;
320            const slide = link?.closest('.swiper-slide');
321            if (!slide) return;
322
323            const produtoEl = link.closest('[data-cd-produto]');
324            const cdProduto = produtoEl?.getAttribute('data-cd-produto') || '';
325            if (!cdProduto) return;
326
327            const nomeProduto = slide
328              ?.querySelector('[data-target="nome-produto"]')
329              ?.textContent
330              ?.replace(/\s+/g, ' ')
331              ?.trim() || '';
332
333            // quantidade
334            const qtdEl = slide.querySelector('[data-toggle="container_qtd_produto"]');
335            const qtdContainerVal = Number(qtdEl?.dataset?.valor);
336            const quantidade =
337              Number(slide?.dataset?.qtd_produto) > 1 ? Number(slide?.dataset?.qtd_produto) :
338              (Number.isFinite(qtdContainerVal) ? qtdContainerVal : 1);
339
340            // preço unitário (extrai BRL com vírgula)
341            const preco = slide?.dataset?.vlr_referencia || '';
342            const num = (s) => {
343              const t = String(s || '').replace(/[^0-9,\.]/g, '');
344              return t
345                ? (t.includes(',') ? +t.replace(/\./g, '').replace(',', '.') : +t)
346                : 0;
347            };
348            const unit = num(preco);
349            const qty = quantidade || 1;
350
351            const listId = 'carrossel_produtos';
352            const listName = el.dataset.carrosselTitulo || 'carrossel-produtos';
353            const posicao = slide?.dataset.swiperSlideIndex
354              ? Number(slide.dataset.swiperSlideIndex) + 1
355              : null;
356
357            filtroParaDadosAnaliticos('SelectItem', {
358              event: 'select_item',
359              item_list_name: listName,
360              item_list_id: listId + '_' + posicao,
361              items: [{
362                id: String(cdProduto),
363                item_name: nomeProduto,
364                price: unit,
365                quantidade: qty,
366                index: posicao || 1,
367                item_list_name: listName,
368                item_list_id: listId + '_' + posicao,
369              }]
370            });
371          } catch (e) {
372            console.error(e);
373          }
374        }, { once: false });
375      });
376    } catch (_) {}
377  });
378}
379
380function criarCarrosselItensGenerico(selector, preset) {
381  const carrosseis = document.querySelectorAll(selector);
382  if (!carrosseis.length) return;
383
384  carrosseis.forEach((el) => {
385    if (el.swiper) return;
386
387    el.querySelectorAll('.slide').forEach(slide => slide.classList.add('swiper-slide'));
388
389    /*
390    * Ao carregar os componentes com o JS do navegador desabilitado, a aparência inicial do carrossel deve ser parecida com o carrossel carregado via JS
391    * Devido a isso, é necessário o bloco abaixo para remover as estilizações utilizadas para isso antes de inicializar o carrossel
392    * NÃO APAGAR E NÃO REMOVER AS CLASSES DO CADASTRO DO COMPONENTE SEM TESTAR O LAYOUT COM O JS DESABILITADO NO NAVEGADOR
393    */
394    if(el.querySelector('.swiper-wrapper'))
395      el.querySelector('.swiper-wrapper').classList?.remove('justify-between', 'gap-x-5', 'overflow-x-auto')
396
397    const paginationEl  = el.querySelector('.swiper-pagination');
398    const scrollbarEl  = el.querySelector('.swiper-scrollbar');
399    const nextEl = el.querySelector('.swiper-button-next');
400    const prevEl = el.querySelector('.swiper-button-prev');
401
402    new Swiper(el, {
403      direction: 'horizontal',
404      loop: el.dataset.loop == 'true' ? true : false,
405      centeredSlides: false,
406      autoplay: el.dataset.autoplay == 'true'
407        ? { delay: 6000, disableOnInteraction: true }
408        : false,
409      ...preset,
410      pagination: paginationEl
411        ? { el: paginationEl, clickable: true, enabled: true }
412        : { enabled: false },
413      scrollbar: scrollbarEl
414        ? { el: scrollbarEl, draggable: true, enabled: true }
415        : { enabled: false },
416      navigation: (nextEl && prevEl)
417        ? { nextEl, prevEl, enabled: true }
418        : { enabled: false },
419    });
420
421    const wrapper = el.querySelector('.swiper-wrapper');
422      if (wrapper) wrapper.className = 'swiper-wrapper';
423      // if (paginationEl) wrapper.classList.add('mb-7');
424      // if (scrollbarEl) wrapper.classList.add('mb-3');
425      if (paginationEl) wrapper.classList.add('mb-11');
426      if (scrollbarEl) wrapper.classList.add('mb-8');
427
428    if(el.dataset.background){
429      const color = el.dataset.background;
430      if (color)  wrapper.classList.add(color.trim());
431    }
432
433    if(el.dataset.rounded){
434      const radius = el.dataset.rounded;
435      if (radius) wrapper.classList.add(radius.trim());
436    }
437
438    el.querySelectorAll('.swiper-slide.hidden, img.hidden')
439      .forEach(node => node.classList.remove('hidden'));
440
441    try {
442      const componenteRoot = el.closest('[data-componente-nome]');
443      el.querySelectorAll('a, .slide a').forEach((a, index) => {
444        if (a.dataset.analyticsBound === 'true') return;
445        a.dataset.analyticsBound = 'true';
446
447        a.addEventListener('click', () => {
448          if (typeof filtroParaDadosAnaliticos !== 'function') return;
449
450          const slide = a.closest('.swiper-slide');
451          const posicao = slide?.dataset?.swiperSlideIndex
452            ? Number(slide.dataset.swiperSlideIndex) + 1
453            : index + 1;
454          const img = a.querySelector('img');
455          const contentId =
456            a.getAttribute('href') ||
457            a.href ||
458            img?.getAttribute('src') ||
459            'item_sem_id';
460
461          filtroParaDadosAnaliticos('MenuAndCallToAction', {
462            event: 'click_item_carrossel',
463            content_type: componenteRoot?.dataset?.componenteNome || 'carrossel-itens',
464            content_id: contentId,
465            position: posicao || 1,
466            section: componenteRoot?.dataset?.componenteSection || 'home'
467          });
468        }, { once: false });
469      });
470    } catch (_) {}
471  });
472}
473
474function criarCarrosselFaixaPromocional(selector, preset) {
475  const carrosseis = document.querySelectorAll(selector);
476  if (!carrosseis.length) return;
477
478  carrosseis.forEach((el, index) => {
479    if (el.swiper) return;
480
481    const paginationEl  = el.querySelector('.swiper-pagination');
482    const scrollbarEl  = el.querySelector('.swiper-scrollbar');
483    const nextEl = el.querySelector('.swiper-button-next');
484    const prevEl = el.querySelector('.swiper-button-prev');
485
486    new Swiper(el, {
487      direction: 'horizontal',
488      loop: el.dataset.loop == 'true' ? true : false,
489      autoplay: el.dataset.autoplay == 'true'
490      ? { delay: 4000, disableOnInteraction: true } 
491      : false,
492      ...preset,
493      pagination: paginationEl
494        ? { el: paginationEl, clickable: true, enabled: true }
495        : { enabled: false },
496      scrollbar: scrollbarEl
497        ? { el: scrollbarEl, draggable: true, enabled: true }
498        : { enabled: false },
499      navigation: (nextEl && prevEl)
500        ? { nextEl, prevEl, enabled: true }
501        : { enabled: false },
502    });
503
504    const wrapper = el.querySelector('.swiper-wrapper');
505    if (wrapper) wrapper.className = 'swiper-wrapper';
506    if (paginationEl) wrapper.classList.add('mb-11');
507    if (scrollbarEl) wrapper.classList.add('mb-8');
508
509    el.querySelectorAll('img.hidden').forEach(img => img.classList.remove('hidden'));
510
511    try {
512      el.querySelectorAll('a, .slide a').forEach((a, index) => {
513        a.addEventListener('click', () => {
514          if (typeof filtroParaDadosAnaliticos === 'function') {
515            const slide = a.closest('.swiper-slide');
516            const type = el.dataset.carrosselFaixaPromocionalTitulo || 'carrossel-faixa-promocional';
517            const posicao = slide?.dataset.swiperSlideIndex
518                              ? Number(slide.dataset.swiperSlideIndex) + 1 
519                              : null;
520            
521            filtroParaDadosAnaliticos('MenuAndCallToAction', {
522              event: 'click_banner',
523              content_type: type,
524              content_id: a.href || 'imagem_sem_id',
525              position: posicao || 1,
526              section: el?.dataset?.carrosselFaixaPromocionalSection || 'home'
527            });
528          }
529        });
530      });
531    } catch(_) {}
532  });
533};
534
535const criarCarrosselDePilulas = () => {
536
537  const carrosseis = document.querySelectorAll('.carrossel-pilulas');
538  if (!carrosseis.length) return;
539  
540  carrosseis.forEach((el, index) => {
541    if (el.swiper) return;
542
543    el.querySelectorAll('.slide').forEach(slide => slide.classList.add('swiper-slide'));
544
545    /*
546    * Ao carregar os componentes com o JS do navegador desabilitado, a aparência inicial do carrossel deve ser parecida com o carrossel carregado via JS
547    * Devido a isso, é necessário o bloco abaixo para remover as estilizações utilizadas para isso antes de inicializar o carrossel
548    * NÃO APAGAR E NÃO REMOVER AS CLASSES DO CADASTRO DO COMPONENTE SEM TESTAR O LAYOUT COM O JS DESABILITADO NO NAVEGADOR
549    */
550    if(el.querySelector('.swiper-wrapper'))
551      el.querySelector('.swiper-wrapper').classList?.remove('justify-between', 'gap-x-5', 'overflow-x-auto')
552
553    const paginationEl  = el.querySelector('.swiper-pagination');
554    const scrollbarEl  = el.querySelector('.swiper-scrollbar');
555    const nextEl = el.querySelector('.swiper-button-next');
556    const prevEl = el.querySelector('.swiper-button-prev');
557
558    const preset = CAROUSEL_PRESETS['pilulas_' + el.dataset.preset] || CAROUSEL_PRESETS.pilulas_lg;
559
560    new Swiper(el, {
561      direction: 'horizontal',
562      centeredSlides: false,
563      loop: el.dataset.loop == 'true' ? true : false,
564      autoplay: el.dataset.autoplay == 'true'
565      ? { delay: 6000, disableOnInteraction: true }
566      : false,
567      pagination: paginationEl
568        ? { el: paginationEl, clickable: true, enabled: true }
569        : { enabled: false },
570      scrollbar: scrollbarEl
571        ? { el: scrollbarEl, draggable: true, enabled: true }
572        : { enabled: false },
573      navigation: (nextEl && prevEl)
574        ? { nextEl, prevEl, enabled: true }
575        : { enabled: false },
576      breakpoints: preset.breakpoints
577    });
578
579    const wrapper = el.querySelector('.swiper-wrapper');
580    if (wrapper) wrapper.className = 'swiper-wrapper';
581    if (paginationEl) wrapper.classList.add('mb-11');
582    if (scrollbarEl) wrapper.classList.add('mb-8');
583
584    el.querySelectorAll('.swiper-slide.hidden, img.hidden')
585      .forEach(node => node.classList.remove('hidden'));
586
587    try {
588      el.querySelectorAll('a, .slide a').forEach((a, index) => {
589        a.addEventListener('click', () => {
590          if (typeof filtroParaDadosAnaliticos === 'function') {
591
592            const slide = a.closest('.swiper-slide');
593            const type = el.dataset.carrosselPilulas || 'carrossel-pilulas';
594            const posicao = slide?.dataset.swiperSlideIndex
595                              ? Number(slide.dataset.swiperSlideIndex) + 1 
596                              : null;
597            
598            filtroParaDadosAnaliticos('MenuAndCallToAction', {
599              event: 'click_pilula',
600              content_type: type,
601              content_id: a.href || 'pílula_sem_id',
602              position: posicao || 1,
603              section: el?.dataset?.carrosselPilulasSection || 'home'
604            });
605          }
606        });
607      });
608    } catch(_) {}
609  });
610}
611
612const criarCarrosselCategoriasMobile = () => {
613
614  const carrosseis = document.querySelectorAll('.carrossel-categorias-mobile');
615  if (!carrosseis.length) return;
616  
617  carrosseis.forEach((el, index) => {
618    if (el.swiper) return;
619
620    el.querySelectorAll('.slide').forEach(slide => slide.classList.add('swiper-slide'));
621
622    /*
623    * Ao carregar os componentes com o JS do navegador desabilitado, a aparência inicial do carrossel deve ser parecida com o carrossel carregado via JS
624    * Devido a isso, é necessário o bloco abaixo para remover as estilizações utilizadas para isso antes de inicializar o carrossel
625    * NÃO APAGAR E NÃO REMOVER AS CLASSES DO CADASTRO DO COMPONENTE SEM TESTAR O LAYOUT COM O JS DESABILITADO NO NAVEGADOR
626    * hide-scrollbar junto com justify-between, gap-x-5, overflow-x-auto para esconder o scrollbar mas manter funcionalidade de rolagem
627    */
628    if(el.querySelector('.swiper-wrapper'))
629      el.querySelector('.swiper-wrapper').classList?.remove('justify-between', 'gap-x-5', 'overflow-x-auto')
630
631    const paginationEl  = el.querySelector('.swiper-pagination');
632    const scrollbarEl  = el.querySelector('.swiper-scrollbar');
633    const nextEl = el.querySelector('.swiper-button-next');
634    const prevEl = el.querySelector('.swiper-button-prev');
635
636
637    new Swiper(el, {
638      direction: 'horizontal',
639      centeredSlides: false,
640      loop: el.dataset.loop == 'true' ? true : false,
641      autoplay: el.dataset.autoplay == 'true'
642      ? { delay: 6000, disableOnInteraction: true } 
643      : false,
644      pagination: paginationEl
645        ? { el: paginationEl, clickable: true, enabled: true }
646        : { enabled: false },
647      scrollbar: scrollbarEl
648        ? { el: scrollbarEl, draggable: true, enabled: true }
649        : { enabled: false },
650      navigation: (nextEl && prevEl)
651        ? { nextEl, prevEl, enabled: true }
652        : { enabled: false },
653      breakpoints: {
654        0: {
655          slidesPerView: 3,
656          spaceBetween: 5,
657        },
658        768: {
659          slidesPerView: 5.5,
660          spaceBetween: 15,
661        },
662        1024: {
663          slidesPerView: 8,
664          spaceBetween: 20,
665        }
666      }
667    });
668
669    const wrapper = el.querySelector('.swiper-wrapper');
670    if (wrapper) wrapper.className = 'swiper-wrapper';
671    if (paginationEl) wrapper.classList.add('mb-11');
672    if (scrollbarEl) wrapper.classList.add('mb-8');
673
674    el.querySelectorAll('.swiper-slide.hidden, img.hidden')
675      .forEach(node => node.classList.remove('hidden'));
676
677    try {
678      el.querySelectorAll('a, .slide a').forEach((a, index) => {
679        a.addEventListener('click', () => {
680          if (typeof filtroParaDadosAnaliticos === 'function') {
681
682            const slide = a.closest('.swiper-slide');
683            const type = el.dataset.carrosselCategoriasMobile || 'carrossel-categorias-mobile';
684            const posicao = slide?.dataset.swiperSlideIndex
685                              ? Number(slide.dataset.swiperSlideIndex) + 1 
686                              : null;
687            
688            filtroParaDadosAnaliticos('MenuAndCallToAction', {
689              event: 'click_categorias-mobile',
690              content_type: type,
691              content_id: a.href || 'categoria_sem_id',
692              position: posicao || 1,
693              section: el?.dataset?.carrosselCategoriasMobileSection || 'home'
694            });
695          }
696        });
697      });
698    } catch(_) {}
699  });
700}
701
702const vincularAnalyticsDoisBannersFixos = () => {
703  const componentes = document.querySelectorAll('[data-componente-nome="dois-banners"]');
704  if (!componentes.length) return;
705
706  componentes.forEach((componente) => {
707    const links = componente.querySelectorAll('a');
708    links.forEach((a, index) => {
709      if (a.dataset.analyticsBound === 'true') return;
710      a.dataset.analyticsBound = 'true';
711
712      a.addEventListener('click', () => {
713        try {
714          if (typeof filtroParaDadosAnaliticos !== 'function') return;
715
716          const img = a.querySelector('img');
717          const contentId =
718            a.getAttribute('href') ||
719            a.href ||
720            img?.getAttribute('src') ||
721            'banner_sem_id';
722
723          filtroParaDadosAnaliticos('MenuAndCallToAction', {
724            event: 'click_banner',
725            content_type: componente?.dataset?.componenteNome || 'dois-banners',
726            content_id: contentId,
727            position: index + 1,
728            section: componente?.dataset?.componenteSection || 'home'
729          });
730        } catch (_) {}
731      });
732    });
733  });
734};
735
736//Carrossel de produto principal da pagina de produto
737const criarCarrosselDeProdutoPrincipal = () => {
738
739  const thumbsEl = document.querySelector('.thumbsSwiper');
740  const thumbsDirecao = document.querySelector('.thumbsHorizontal') ? true : false;
741  const mainEl = document.querySelector('.mainSwiper');
742  const isMobile = window.matchMedia("(max-width: 768px)").matches;
743  const mainSlides = Array.from(document.querySelectorAll('.mainSwiper .swiper-slide'))
744  const thumbsSlides = Array.from(document.querySelectorAll('.thumbsSwiper .swiper-slide'))
745
746  const ocultarSlidesAntesInit = () => {
747    if (!mainSlides.length) return
748    mainSlides.forEach((slide, index) => {
749      slide.classList.toggle('hidden', index !== 0)
750    })
751  }
752
753  const ocultarThumbsAntesInit = () => {
754    if (!thumbsSlides.length) return
755    thumbsSlides.forEach((slide, index) => {
756      slide.classList.toggle('hidden', index !== 0)
757    })
758  }
759
760  const exibirSlidesAposInit = () => {
761    if (!mainSlides.length) return
762    mainSlides.forEach((slide) => slide.classList.remove('hidden'))
763  }
764
765  const exibirThumbsAposInit = () => {
766    if (!thumbsSlides.length) return
767    thumbsSlides.forEach((slide) => slide.classList.remove('hidden'))
768  }
769
770  if (!mainEl || mainEl.swiper) return;
771
772  ocultarSlidesAntesInit()
773  ocultarThumbsAntesInit()
774
775  if (isMobile) {
776    const mainSwiper = new Swiper(".mainSwiper", {
777      spaceBetween: 10,
778      pagination: {
779        el: '.swiper-pagination',
780        clickable: true
781      },
782      on: {
783        init: () => {
784          exibirSlidesAposInit()
785          exibirThumbsAposInit()
786        }
787      }
788    });
789    mainSwiper.on('afterInit', exibirSlidesAposInit)
790    mainSwiper.on('afterInit', exibirThumbsAposInit)
791  } else if (thumbsEl && thumbsDirecao) {
792    const thumbsSwiper = new Swiper(".thumbsSwiper", {
793    direction: "horizontal",
794    slidesPerView: 'auto',
795    spaceBetween: 8,
796    freeMode: true,
797    watchSlidesProgress: true,
798    navigation: {
799        nextEl: ".swiper-button-next",
800        prevEl: ".swiper-button-prev",
801      },
802    scrollbar: {
803      el: '.swiper-scrollbar',
804      draggable: true,
805    },
806    mousewheel: {
807      releaseOnEdges: true, // Permite scroll contínuo ao chegar no limite
808      sensitivity: 1,        // Pode aumentar se quiser rolar mais suave
809    },
810    slideToClickedSlide: true,
811  });
812
813    const mainSwiper = new Swiper(".mainSwiper", {
814      spaceBetween: 1,
815      thumbs: {
816        swiper: thumbsSwiper,
817      },
818      on: {
819        init: () => {
820          exibirSlidesAposInit()
821          exibirThumbsAposInit()
822        }
823      }
824    });
825    mainSwiper.on('afterInit', exibirSlidesAposInit)
826    mainSwiper.on('afterInit', exibirThumbsAposInit)
827  } else if (thumbsEl && !thumbsDirecao) {
828    const thumbsSwiper = new Swiper(".thumbsSwiper", {
829      direction: "vertical",
830      slidesPerView: 5,
831      spaceBetween: 8,
832      freeMode: true,
833      watchSlidesProgress: true,
834      scrollbar: {
835        el: '.swiper-scrollbar',
836        draggable: true,
837      },
838      mousewheel: {
839        releaseOnEdges: true, // Permite scroll contínuo ao chegar no limite
840        sensitivity: 1,        // Pode aumentar se quiser rolar mais suave
841      },
842      slideToClickedSlide: true,
843    });
844
845    const mainSwiper = new Swiper(".mainSwiper", {
846      spaceBetween: 1,
847      thumbs: {
848        swiper: thumbsSwiper,
849      },
850      on: {
851        init: () => {
852          exibirSlidesAposInit()
853          exibirThumbsAposInit()
854        }
855      }
856    });
857    mainSwiper.on('afterInit', exibirSlidesAposInit)
858    mainSwiper.on('afterInit', exibirThumbsAposInit)
859  }
860};
861
862document.addEventListener('DOMContentLoaded', () => {
863
864  if (window.matchMedia("(min-width: 990px)").matches) {
865    document.querySelectorAll('.img-zoom-produto').forEach(el => {
866      $(el).imagezoomsl({
867        zoomrange: [2, 2]
868      });
869    });
870  }
871});
872
873const criarCarrosseis = () => {
874  criarCarrosselDeProdutoPrincipal()
875  criarCarrosselDeProdutosGenerico('.carrossel-produtos-padrao', PRESET_PRODUTOS.padrao)
876  criarCarrosselDeProdutosGenerico('.carrossel-produtos-scrollbar', PRESET_PRODUTOS.scrollbar)
877  criarCarrosselDeProdutosGenerico('.carrossel-produtos-lg', PRESET_PRODUTOS.lg)
878  criarCarrosselFaixaPromocional('.carrossel-faixa-promocional-one', CAROUSEL_PRESETS.one)
879  criarCarrosselDeImagens('.carrossel-imagens-one', CAROUSEL_PRESETS.one)
880  criarCarrosselDeImagens('.carrossel-imagens-two', CAROUSEL_PRESETS.two_complete)
881  criarCarrosselDeImagens('.carrossel-imagens-three', CAROUSEL_PRESETS.three_complete)
882  criarCarrosselItensGenerico('.carrossel-itens-xs', CAROUSEL_PRESETS.xs);
883  criarCarrosselItensGenerico('.carrossel-itens-sm', CAROUSEL_PRESETS.sm);
884  criarCarrosselItensGenerico('.carrossel-itens-md', CAROUSEL_PRESETS.md);
885  criarCarrosselItensGenerico('.carrossel-itens-lg', CAROUSEL_PRESETS.lg);
886  criarCarrosselItensGenerico('.carrossel-itens-xl', CAROUSEL_PRESETS.xl);
887  criarCarrosselItensGenerico('.carrossel-itens-three', CAROUSEL_PRESETS.three);
888  criarCarrosselItensGenerico('.carrossel-itens-five', CAROUSEL_PRESETS.five);
889  criarCarrosselItensGenerico('.carrossel-itens-six', CAROUSEL_PRESETS.six);
890  criarCarrosselItensGenerico('.carrossel-imagens-redondas-sm', CAROUSEL_PRESETS.sm);
891  criarCarrosselItensGenerico('.carrossel-imagens-redondas-md', CAROUSEL_PRESETS.md);
892  criarCarrosselItensGenerico('.carrossel-imagens-redondas-lg', CAROUSEL_PRESETS.lg);
893  criarCarrosselItensGenerico('.carrossel-informacoes-three', INFORMACOES_PRESETS.three);
894  criarCarrosselItensGenerico('.carrossel-informacoes-four', INFORMACOES_PRESETS.four);
895  criarCarrosselItensGenerico('.carrossel-informacoes-five', INFORMACOES_PRESETS.five);
896  criarCarrosselItensGenerico('.carrossel-videos-two', VIDEOS_PRESETS.two);
897 
898
899  criarCarrosselDePilulas();
900  criarCarrosselCategoriasMobile();
901  vincularAnalyticsDoisBannersFixos();
902}
903
904// Garante que loadScript e loadLink estejam disponíveis antes de usar
905function inicializarCarrosseis() {
906  if (typeof loadScript === 'undefined' || typeof loadLink === 'undefined') {
907    // Se ainda não estiverem disponíveis, tenta novamente após um pequeno delay
908    setTimeout(inicializarCarrosseis, 50);
909    return;
910  }
911
912  loadLink(`https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css`)
913  loadScript(`https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js`, () => {
914    _swiperCarregado = true
915    criarCarrosseis()
916    // const debouncedResizeCarrosseis = debounce(criarCarrosseis, 300);
917    // window.addEventListener("resize", debouncedResizeCarrosseis);
918  })
919}
920
921// Tenta inicializar imediatamente, ou aguarda o DOM estar pronto
922if (document.readyState === 'loading') {
923  document.addEventListener('DOMContentLoaded', inicializarCarrosseis);
924} else {
925  inicializarCarrosseis();
926}

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.