PageSourceSearch

https://www.theasianbanker.com/public/js/theme.js

js theasianbanker.com collected 2026-09-24 18:04:10 UTC 50,207 bytes, 1,468 lines download raw bytes

1/* eslint-disable no-unused-vars */
2// eslint-disable-next-line no-undef
3var $ = jQuery.noConflict();
4
5let UomoSections = {};
6let UomoElements = {};
7
8let UomoSelectors = {
9  pageBackDropActiveClass: 'page-overlay_visible',
10  quantityControl: '.qty-control',
11  scrollToTopId: 'scrollTop',
12  $pageBackDrop: document.querySelector('.page-overlay'),
13  scrollWidth:   window.innerWidth - document.body.clientWidth + 'px',
14  jsContentVisible: '.js-content_visible',
15  starRatingControl: '.star-rating .star-rating__star-icon',
16}
17
18// Utility functions
19let UomoHelpers = {
20  isMobile: false,
21  sideStkEl: {},
22
23  debounce: (callback, wait, immediate = false) => {
24    let timeout = null;
25
26    return function() {
27      const callNow = immediate && !timeout;
28      const next = () => callback.apply(this, arguments);
29
30      clearTimeout(timeout);
31      timeout = setTimeout(next, wait);
32
33      if (callNow) {
34        next();
35      }
36    }
37  },
38
39  showPageBackdrop: () => {
40    UomoSelectors.$pageBackDrop && UomoSelectors.$pageBackDrop.classList.add(UomoSelectors.pageBackDropActiveClass);
41    document.body.classList.add('overflow-hidden');
42    document.body.style.paddingRight = UomoSelectors.scrollWidth;
43    document.querySelectorAll('.header_sticky, .footer-mobile').forEach(element => {
44      element.style.borderRight = UomoSelectors.scrollWidth + ' solid transparent';
45    });
46  },
47
48  hidePageBackdrop: () => {
49    UomoSelectors.$pageBackDrop && UomoSelectors.$pageBackDrop.classList.remove(UomoSelectors.pageBackDropActiveClass);
50    document.body.classList.remove('overflow-hidden');
51    document.body.style.paddingRight = '';
52    document.querySelectorAll('.header_sticky, .footer-mobile').forEach(element => {
53      element.style.borderRight = '';
54    });
55  },
56
57  hideHoverComponents: () => {
58    document.querySelectorAll(UomoSelectors.jsContentVisible).forEach( el => {
59      el.classList.remove(UomoSelectors.jsContentVisible.substring(1));
60    });
61  },
62
63  updateDeviceSize: () => {
64    return window.innerWidth < 992
65  }
66};
67
68function purecookieDismiss() {
69  setCookie("purecookieDismiss", "1", 7), pureFadeOut("cookieConsentContainer")
70}
71
72function setCookie(e, o, i) {
73  var t = "";
74  if (i) {
75    var n = new Date;
76    n.setTime(n.getTime() + 24 * i * 60 * 60 * 1e3), t = "; expires=" + n.toUTCString()
77  }
78  document.cookie = e + "=" + (o || "") + t + "; path=/"
79}
80
81function pureFadeOut(e) {
82  var o = document.getElementById(e);
83  o.style.opacity = 1,
84    function e() {
85      (o.style.opacity -= .02) < 0 ? o.style.display = "none" : requestAnimationFrame(e)
86    }()
87}
88
89(function () {
90  'use strict';
91
92  // Scroll bar width
93  const scrollBarWidth = window.innerWidth - document.body.clientWidth
94
95  // Components appear after click
96  UomoElements.JsHoverContent = (function () {
97    function JsHoverContent () {
98      const visibleClass = UomoSelectors.jsContentVisible.substring(1);
99
100      document.querySelectorAll('.js-hover__open').forEach(el => {
101        el.addEventListener('click', (e) => {
102          e.preventDefault();
103
104          const $container = e.currentTarget.closest('.hover-container');
105          if ($container.classList.contains(visibleClass)) {
106            $container.classList.remove(visibleClass);
107            // e.stopPropagation();
108          } else {
109            UomoHelpers.hideHoverComponents();
110            $container.classList.add(visibleClass);
111          }
112        });
113      });
114
115      document.addEventListener('click', (e) => {
116        if (!e.target.closest(UomoSelectors.jsContentVisible)) {
117          UomoHelpers.hideHoverComponents();
118        }
119      });
120    }
121
122
123    return JsHoverContent;
124  })();
125
126  UomoElements.QtyControl = (function () {
127    function QtyControl () {
128      document.querySelectorAll(UomoSelectors.quantityControl).forEach(function($qty) {
129        if ($qty.classList.contains('qty-initialized')) {
130          return;
131        }
132
133        $qty.classList.add('qty-initialized');
134        const $reduce = $qty.querySelector('.qty-control__reduce');
135        const $increase = $qty.querySelector('.qty-control__increase');
136        const $number = $qty.querySelector('.qty-control__number');
137
138        $reduce.addEventListener('click', function() {
139          $number.value = parseInt($number.value) > 1 ? parseInt($number.value) - 1 : parseInt($number.value);
140        });
141
142        $increase.addEventListener('click', function() {
143          $number.value = parseInt($number.value) + 1;
144        });
145      });
146    }
147
148    return QtyControl;
149  })();
150
151  UomoElements.ScrollToTop = (function () {
152    function ScrollToTop () {
153      const $scrollTop = document.getElementById(UomoSelectors.scrollToTopId);
154
155      if (!$scrollTop) {
156        return;
157      }
158
159      $scrollTop.addEventListener('click', function(event) {
160        event.preventDefault();
161        event.stopPropagation();
162        window.scrollTo(window.scrollX, 0);
163      });
164
165      let scrolled = false;
166      window.addEventListener('scroll', function() {
167        if ( 250 < window.scrollY && !scrolled ) {
168          $scrollTop.classList.remove('visually-hidden');
169          scrolled = true;
170        }
171
172        if ( 250 > window.scrollY && scrolled ) {
173          $scrollTop.classList.add('visually-hidden');
174          scrolled = false;
175        }
176      });
177    }
178
179    return ScrollToTop;
180  })();
181
182  UomoElements.Search = (function() {
183    function Search() {
184      // Declare variables
185      this.selectors = {
186        container: '.search-field',
187        inputBox: '.search-field__input',
188        searchSuggestItem: '.search-suggestion a.menu-link',
189        searchFieldActor: '.search-field__actor',
190        resetButton: '.search-popup__reset',
191        searchCategorySelector: '.js-search-select',
192        resultContainer: '.search-result',
193        ajaxURL: './search.html'
194      }
195
196      this.searchInputFocusedClass = 'search-field__focused';
197
198      this.$containers = document.querySelectorAll(this.selectors.container);
199
200      this._initSearchSelect();
201      this._initSearchReset();
202      this._initSearchInputFocus();
203      this._initAjaxSearch();
204
205      this._handleAjaxSearch = this._handleAjaxSearch.bind(this);
206      this._updateSearchResult = this._updateSearchResult.bind(this);
207    }
208
209    Search.prototype = Object.assign({}, Search.prototype, {
210      _initSearchSelect: function () {
211        const _this = this;
212        this.$containers.forEach( el => {
213          /**
214           * Filter suggestion list on input
215           */
216
217          const $inputBox = el.querySelector(_this.selectors.inputBox);
218          $inputBox && $inputBox.addEventListener('keyup', (e) => {
219            const filterValue = e.currentTarget.value.toUpperCase();
220            el.querySelectorAll(_this.selectors.searchSuggestItem).forEach( el => {
221              const txtValue = el.innerText;
222
223              if (txtValue.toUpperCase().indexOf(filterValue) > -1) {
224                el.style.display = "";
225              } else {
226                el.style.display = "none";
227              }
228            });
229          });
230
231          /**
232           * Search category selector
233           */
234          el.querySelectorAll(_this.selectors.searchCategorySelector).forEach( scs => {
235            scs.addEventListener('click', function(e) {
236              e.preventDefault();
237              const $s_f_a = el.querySelector(_this.selectors.searchFieldActor);
238              if ($s_f_a) {
239                $s_f_a.value = e.target.innerText;
240              }
241            });
242          });
243        })
244      },
245
246      _removeFormActiveClass($eventEl) {
247        const $parentDiv = $eventEl.closest(this.selectors.container);
248        $parentDiv.classList.remove(this.searchInputFocusedClass);
249      },
250
251      _initSearchReset: function () {
252        const _this = this;
253        document.querySelectorAll(this.selectors.resetButton).forEach( el => {
254          el.addEventListener('click', function(e) {
255            const $parentDiv = e.target.closest(_this.selectors.container);
256            const $inputBox = $parentDiv.querySelector(_this.selectors.inputBox);
257            const $rc = $parentDiv.querySelector(_this.selectors.resultContainer);
258
259            $inputBox.value = '';
260            $rc.innerHtml = '';
261            _this._removeFormActiveClass(e.target);
262          });
263        })
264      },
265
266      _initSearchInputFocus: function () {
267        const _this = this;
268
269        document.querySelectorAll(this.selectors.inputBox).forEach( el => {
270          el.addEventListener('blur', function(e) {
271            if (e.target.value.length == 0) {
272              _this._removeFormActiveClass(e.target);
273            }
274          })
275        });
276      },
277
278      _initAjaxSearch: function () {
279        const _this = this;
280        document.querySelectorAll(this.selectors.inputBox).forEac
280h( el => {
281          el.addEventListener('keyup', (event) => {
282            if (event.target.value.length == 0) {
283              _this._removeFormActiveClass(event.target);
284            } else {
285              _this._handleAjaxSearch(event, _this);
286            }
287          });
288        })
289      },
290
291      _handleAjaxSearch: UomoHelpers.debounce((event, _this) => {
292        const $form = event.target.closest(_this.selectors.container);
293        const method = $form ? $form.method : 'GET';
294        const url = _this.selectors.ajaxURL;
295
296        url && fetch(url, { method: method }).then(function (response) {
297          if (response.ok) {
298            return response.text();
299          } else {
300            return Promise.reject(response);
301          }
302        }).then(function(data) {
303          _this._updateSearchResult(data, $form);
304        }).catch(function (err) {
305          _this._handleAjaxSearchError(err.message, $form);
306        });
307      }, 180),
308
309      _updateSearchResult: function(data, $form) {
310        const $ajaxDom = new DOMParser().parseFromString(data, 'text/html');
311        // Get filtered result dom
312        const $f_r = $ajaxDom.querySelector('.search-result');
313        $form.querySelector(this.selectors.resultContainer).innerHTML = $f_r.innerHTML;
314        $form.classList.add(this.searchInputFocusedClass);
315      },
316
317      _handleAjaxSearchError: function (error, $form) {
318        $form.classList.remove(this.searchInputFocusedClass);
319        console.log(error);
320      }
321    });
322
323    return Search
324  })();
325
326  // Aside Popup
327  UomoElements.Aside = (function () {
328    function Aside () {
329      this.selectors = {
330        activator:    '.js-open-aside',
331        closeBtn:     '.js-close-aside',
332        activeClass:  'aside_visible'
333      }
334
335      this.$asideActivators = document.querySelectorAll(this.selectors.activator);
336      this.$closeBtns = document.querySelectorAll(this.selectors.closeBtn);
337
338      this._init();
339      this._initCloseActions();
340      this._initBackDropClick();
341    }
342
343    Aside.prototype = Object.assign({}, Aside.prototype, {
344      _init: function () {
345        const _this = this;
346        $(document).on("click", this.selectors.activator, function(e) {
347          e.preventDefault();
348          
349          const targetElId = $(this).data("aside");
350          const $targetAside = document.getElementById(targetElId);
351
352          UomoHelpers.showPageBackdrop();
353          $targetAside && $targetAside.classList.add(_this.selectors.activeClass);
354        });
355      },
356
357      _initCloseActions: function () {
358        const _this = this;
359        this.$closeBtns.forEach( el => {
360          el.addEventListener('click', (event) => {
361            event.preventDefault();
362            _this._closeAside();
363          });
364        });
365      },
366
367      _initBackDropClick() {
368        if (UomoSelectors.$pageBackDrop) {
369          UomoSelectors.$pageBackDrop.addEventListener('click', () => {
370            this._closeAside();
371          });
372        }
373      },
374
375      _closeAside: function () {
376        UomoHelpers.hidePageBackdrop();
377        document.querySelectorAll('.' + this.selectors.activeClass).forEach( el => {
378          el.classList.remove(this.selectors.activeClass);
379        });
380      }
381    });
382
383    return Aside;
384  })();
385
386  UomoElements.Countdown = (function () {
387    function Countdown (container) {
388      this.selectors = {
389        element: '.js-countdown'
390      }
391
392      this.$container = container || document.body;
393
394      this._init()
395    }
396
397    Countdown.prototype = Object.assign({}, Countdown.prototype, {
398      _init: function () {
399        const _this = this;
400        const $countdowns = this.$container.querySelectorAll(this.selectors.element);
401        $countdowns.forEach(function($el) {
402          _this._initElement($el);
403        });
404      },
405
406      _initElement($el) {
407        // eslint-disable-next-line no-undef
408        const timer = new countdown({
409          target: $el
410        });
411      }
412    });
413
414
415    return Countdown;
416  })();
417
418  UomoElements.ShopViewChange = (function () {
419    function ShopViewChange () {
420      this.selectors = {
421        element: '.js-cols-size',
422        activeClass: 'btn-link_active'
423      }
424
425      this.$buttons = document.querySelectorAll(this.selectors.element);
426
427      this._init();
428    }
429
430    ShopViewChange.prototype = Object.assign({}, ShopViewChange.prototype, {
431      _init: function () {
432        const _this = this;
433        this.$buttons.forEach(function($btn) {
434          $btn.addEventListener('click', function(event) {
435            event.preventDefault();
436            const targetDomId = $btn.dataset.target;
437            _this._resetActiveLinks();
438            this.classList.add(_this.selectors.activeClass);
439            const newCol = $btn.dataset.cols;
440            _this._changeViewCols(targetDomId, newCol);
441          });
442        });
443      },
444
445      _changeViewCols(parentId, newCol) {
446        const $targetDom = document.getElementById(parentId);
447        if ($targetDom) {
448          $targetDom.classList.remove(
449            'row-cols-xl-2', 'row-cols-xl-3', 'row-cols-xl-4', 'row-cols-xl-5', 'row-cols-xl-6',
450            'row-cols-lg-2', 'row-cols-lg-3', 'row-cols-lg-4', 'row-cols-lg-5', 'row-cols-lg-6');
451          $targetDom.classList.add('row-cols-xl-' + newCol, 'row-cols-lg-' + newCol);
452        }
453      },
454
455      _resetActiveLinks() {
456        const _this = this;
457        document.querySelectorAll(`${this.selectors.element}.${this.selectors.activeClass}`).forEach($el => {
458          $el.classList.remove(_this.selectors.activeClass);
459        });
460      }
461    });
462
463    return ShopViewChange;
464  })();
465
466  UomoElements.Filters = (function () {
467    function Filters () {
468      this.selectors = {
469        element: '.js-filter',
470        activeClass: 'swatch_active',
471      }
472
473      this.$buttons = document.querySelectorAll(this.selectors.element);
474
475      this._init();
476    }
477
478    Filters.prototype = Object.assign({}, Filters.prototype, {
479      _init: function () {
480        const _this = this;
481        this.$buttons.forEach(function($btn) {
482          $btn.addEventListener('click', function(event) {
483            event.preventDefault();
484            _this._toggleActive($btn);
485          });
486        });
487      },
488
489      _toggleActive($btn) {
490        if ($btn.classList.contains(this.selectors.activeClass)) {
491          $btn.classList.remove(this.selectors.activeClass);
492        } else {
493          $btn.classList.add(this.selectors.activeClass);
494        }
495      }
496    });
497
498
499    return Filters;
500  })();
501
502  UomoElements.StickyElement = (function () {
503    function StickyElement () {
504      this.selectors = {
505        element: '.side-sticky'
506      }
507
508      this.$stickies = document.querySelectorAll(this.selectors.element);
509      this._updateStatus = this._updateStatus.bind(this);
510      this._init();
511    }
512
513    StickyElement.prototype = Object.assign({}, StickyElement.prototype, {
514      _init: function () {
515        if (UomoHelpers.isMobile) {
516          return;
517        }
518
519        this.$stickies.forEach(function($sticky) {
520          const $grid = $sticky.previousElementSibling || $sticky.nextElementSibling;
521          const $target = $grid.offsetHeight > $sticky.offsetHeight ? $sticky : $grid;
522
523          $target.lastKnownY = window.scrollY;
524          if (!UomoHelpers.sideStkEl.currentTop) {
525            UomoHelpers.sideStkEl.currentTop = 0;
526          } else {
527            return;
528          }
529
530
531          UomoHelpers.sideStkEl.initialTopOffset = parseInt(window.getComputedStyle($target).top);
532        });
533
534        window.addEventListener('scroll', this._updateStatus);
535      },
536
537      _updateStatus() {
538        const _this = this;
539
540        _this.$stickies.forEach(function($sticky) {
541          const $grid = $sticky.previousElementSibling || $sticky.nextElementSibling;
542          const $target = $grid.offsetHeight > $sticky.offsetHeight ? $sticky : $grid;
543
544          var bounds = $target.getBoundingClientRect(),
545              maxTop = bounds.top + window.scrollY - $target.offsetTop + UomoHelpers.sideStkEl.initialTopOffset,
546              minTop = $target.clientHeight - window.innerHeight + 30;
547
548          if (window.scrollY < $target.lastKnownY) {
549            UomoHelpers.sideStkEl.currentTop -= window.scrollY - $target.lastKnownY;
550          } else {
551            UomoHelpers.sideStkEl.currentTop += $target.lastKnownY - window.scrollY;
552          }
553
554
555          UomoHelpers.sideStkEl.currentTop = Math.min(Math.max(UomoHelpers.sideStkEl.currentTop, -minTop), maxTop, UomoHelpers.sideStkEl.initialTopOffset);
556          $target.lastKnownY = window.scrollY;
557
558          $target.style.top = UomoHelpers.sideStkEl.currentTop + 'px';
559        });
560      }
561    });
562
563
564    return StickyElement;
565  })();
566
567  // Header Section
568  UomoSections.Header = (function () {
569    function Header () {
570      this.selectors = {
571        header: '.header',
572        mobileHeader: '.header-mobile',
573        mobileMenuActivator: '.mobile-nav-activator',
574        mobileMenu: '.navigation',
575        mobileMenuActiveClass: 'mobile-menu-opened',
576        mobileSubNavOpen: '.js-nav-right',
577        mobileSubNavClose: '.js-nav-left',
578        mobileSubNavHiddenClass: 'd-none',
579        stickyHeader: '.header_sticky',
580        stickyActiveClass: 'header_sticky-active',
581      }
582
583      // Set sticky active class from
584      this.stickyMinPos = 25;
585      this.stkHd = false;
586
587      this._init = this._init.bind(this);
588      this._stickyScrollHander = this._stickyScrollHander.bind(this);
589      this._init();
590      window.addEventListener('resize', this._init);
591    }
592
593    Header.prototype = Object.assign({}, Header.prototype, {
594      _init: function () {
595        const headerClass = UomoHelpers.isMobile ? this.selectors.mobileHeader : this.selectors.header;
596
597        this.lastScrollTop = 0;
598        this.$header = document.querySelector(headerClass);
599
600        if (!this.$header) {
601          return;
602        }
603
604        if (!UomoHelpers.isMobile) {
605          this._initMenuPosition();
606        } else {
607          this._initMobileMenu();
608        }
609
610        this._initStickyHeader();
611      },
612
613      _initMobileMenu: function() {
614        const _this = this;
615        const mobileMenuActivator = this.$header.querySelector(this.selectors.mobileMenuActivator);
616        const $mobileDropdown = this.$header.querySelector(this.selectors.mobileMenu);
617        let transformLeft = 0;
618        if ($mobileDropdown) {
619          mobileMenuActivator && $(mobileMenuActivator).off('click').on('click', function(event) {
620            event.preventDefault();
621            if (document.body.classList.contains(_this.selectors.mobileMenuActiveClass)) {
622              document.body.classList.remove(_this.selectors.mobileMenuActiveClass);
623              _this.$header.style.paddingRight = '';
624              $mobileDropdown.style.paddingRight = '';
625            } else {
626              document.body.classList.add(_this.selectors.mobileMenuActiveClass);
627              _this.$header.style.paddingRight = UomoSelectors.scrollWidth;
628              $mobileDropdown.style.paddingRight = UomoSelectors.scrollWidth;
629            }
630          });
631
632          const $mobileMenu = $mobileDropdown.querySelector('.navigation__list');
633          let menuMaxHeight = $mobileMenu.offsetHeight;
634          $mobileMenu && $mobileMenu.querySelectorAll(_this.selectors.mobileSubNavOpen).forEach($btn => {
635            $btn.addEventListener('click', function(event) {
636              event.preventDefault;
637              $btn.nextElementSibling.classList.remove(_this.selectors.mobileSubNavHiddenClass);
638
639              transformLeft -= 100;
640              if (menuMaxHeight < $btn.nextElementSibling.offsetHeight) {
641                $mobileMenu.style.transform = 'translateX(' + transformLeft.toString() + '%)';
642                $mobileMenu.style.minHeight = $btn.nextElementSibling.offsetHeight + 'px';
643              } else {
644                $mobileMenu.style.transform = 'translateX(' + transformLeft.toString() + '%)';
645                $mobileMenu.style.minHeight = menuMaxHeight + 'px';
646              }
647            });
648          });
649
650
651          $mobileMenu && $mobileMenu.querySelectorAll(_this.selectors.mobileSubNavClose).forEach($btn => {
652            $btn.addEventListener('click', function(event) {
653              event.preventDefault;
654              transformLeft += 100;
655              $mobileMenu.style.transform = 'translateX(' + transformLeft.toString() + '%)';
656              $btn.parentElement.classList.add(_this.selectors.mobileSubNavHiddenClass);
657              const $wrapper = $btn.closest('.sub-menu');
658              if ($wrapper) {
659                const minHeight = menuMaxHeight < $wrapper.offsetHeight ? $wrapper.offsetHeight : menuMaxHeight;
660                $mobileMenu.style.minHeight = minHeight + 'px';
661              }
662            });
663          });
664        }
665      },
666
667      _initStickyHeader: function () {
668        if (this.$header.classList.contains(this.selectors.stickyHeader)) {
669          return;
670        }
671
672        const _this = this;
673        let headerHeight = this.$header.offsetHeight;
674        if(this.$header.classList.contains("header-transparent-bg")) {
675          headerHeight = 0;
676
677          if(document.querySelectorAll(".header-transparent-bg .header-top").length > 0) {
678            headerHeight = document.querySelector(".header-transparent-bg .header-top").offsetHeight;
679          }
680        }
681
682        document.querySelector("main").style.paddingTop = headerHeight + 'px';
683        _this.$header.classList.add('position-absolute');
684
685        document.removeEventListener('scroll', this._stickyScrollHander);
686        document.addEventListener('scroll', this._stickyScrollHander);
687      },
688
689      _initMenuPosition () {
690        const _this = this;
691        _this.$header.querySelectorAll('.box-menu').forEach( el => {
692          _this._setBoxMenuPosition(el)
693        });
694
695        _this.$header.querySelectorAll('.default-menu').forEach( el => {
696          _this._setDefaultMenuPosition(el)
697        });
698      },
699
700      _setBoxMenuPosition (menu) {
701        const limitR = window.innerWidth - menu.offsetWidth - scrollBarWidth;
702        const limitL = 0;
703        const menuPaddingLeft = parseInt(window.getComputedStyle(menu, null).getPropertyValue('padding-left'));
704        const parentPaddingLeft = parseInt(window.getComputedStyle(menu.previousElementSibling, null).getPropertyValue('padding-left'));
705        const centerPos = menu.previousElementSibling.offsetLeft - menuPaddingLeft + parentPaddingLeft;
706
707        let menuPos = centerPos;
708        if (centerPos < limitL) {
709          menuPos = limitL;
710        } else if (centerPos > limitR) {
711          menuPos = limitR;
712        }
713
714        menu.style.left = `${menuPos}px`;
715      },
716
717      _setDefaultMenuPosition (menu) {
718        const limitR = window.innerWidth - menu.offsetWidth - scrollBarWidth;
719        const limitL = 0;
720        const menuPaddingLeft = parseInt(window.getComputedStyle(menu, null).getPropertyValue('padding-left'));
721        const parentPaddingLeft = parseInt(window.getComputedStyle(menu.previousElementSibling, null).getPropertyValue('padding-left'));
722        const centerPos = menu.previousElementSibling.offsetLeft - menuPaddingLeft + parentPaddingLeft;
723
724        let menuPos = centerPos;
725        if (centerPos < limitL) {
726          menuPos = limitL;
727        } else if (centerPos > limitR) {
728          menuPos = limitR;
729        }
730
731        menu.style.left = `${menuPos}px`;
732      },
733
734      _stickyScrollHander() {
735        if (this.$header.classList.contains("sticky_disabled")) {
736          return;
737        }
738        const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop;
739
740        if (currentScrollTop > this.lastScrollTop || currentScrollTop < this.stickyMinPos) {
741          this.$header.classList.remove(this.selectors.stickyActiveClass);
742          this.$header.classList.add('position-absolute');
743        } else if (currentScrollTop > this.stickyMinPos) {
744          this.$header.classList.add(this.selectors.stickyActiveClass);
745          this.$header.classList.remove('position-absolute');
746        }
747
748        this.lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop;
749      }
750    });
751
752
753    return Header;
754  })();
755
756  // Footer Section
757  UomoSections.Footer = (function () {
758    function Footer () {
759      this.selectors = {
760        footer: '.footer-mobile'
761      }
762      this.$footer = document.querySelector(this.selectors.footer);
763
764      this._init = this._init.bind(this);
765      this._init();
766      window.addEventListener('resize', this._init);
767    }
768
769    Footer.prototype = Object.assign({}, Footer.prototype, {
770      _init: function() {
771        if (!this.$footer || !UomoHelpers.isMobile) {
772          return;
773        }
774
775        setTimeout(() => {
776          this._initStickyFooter();
777        }, 750);
778      },
779
780      _initStickyFooter: function () {
781        const height = this.$footer.offsetHeight;
782
783        document.body.style.paddingBottom = height + 'px';
784        this.$footer.classList.add('position-fixed');
785        setTimeout(() => {
786          this.$footer.classList.add('footer-mobile_initialized');
787        }, 750);
788      },
789    });
790
791
792    return Footer;
793  })();
794
795  // Customer login form
796  UomoSections.CustomerSideForm = (function () {
797    function CustomerSideForm () {
798      this.selectors = {
799        aside:        '.aside.customer-forms',
800        formsWrapper:  '.customer-forms__wrapper',
801        // registerActivator:  '.js-show-register',
802        loginActivator:     '.js-show-login'
803      }
804
805      this.$aside = document.querySelector(this.selectors.aside);
806      if (!this.$aside) {
807        return false;
808      }
809
810      this.$formsWrapper = this.$aside.querySelector(this.selectors.formsWrapper);
811      this.$registerActivator = this.$aside.querySelector(this.selectors.registerActivator);
812      this.$loginActivator = this.$aside.querySelector(this.selectors.loginActivator);
813
814      this.$formsWrapper && this._showLoginForm()
815      this.$formsWrapper && this._showRegisterForm()
816    }
817
818    CustomerSideForm.prototype = Object.assign({}, CustomerSideForm.prototype, {
819      _showLoginForm: function () {
820        this.$loginActivator.addEventListener('click', () => {
821          this.$formsWrapper.style.left = 0;
822        });
823      },
824
825     
826    });
827
828    return CustomerSideForm;
829  })();
830
831  UomoSections.CartDrawer = (function () {
832    function CartDrawer () {
833      this.selectors = {
834        aside:            '.aside.cart-drawer',
835        asideHeader:      '.aside-header',
836        cartItemRemover:  '.js-cart-item-remove',
837        cartActions:      '.cart-drawer-actions',
838        cartItemsList:    '.cart-drawer-items-list'
839      }
840
841      this.asideContentMargin = 30;
842
843      this.$aside = document.querySelector(this.selectors.aside);
844      if (!this.$aside) {
845        return false;
846      }
847
848      this.$header = this.$aside.querySelector(this.selectors.asideHeader);
849      this.$actions = this.$aside.querySelector(this.selectors.cartActions);
850      this.$list = this.$aside.querySelector(this.selectors.cartItemsList);
851
852      setTimeout(() => {
853        this._initCartItemsList();
854        this._initCartItemRemoval();
855      }, 1000);
856    }
857
858    CartDrawer.prototype = Object.assign({}, CartDrawer.prototype, {
859      _initCartItemsList: function () {
860        if (!UomoHelpers.isMobile) {
861          return;
862        }
863
864        const drawerHeight = this.$aside.offsetHeight;
865        const headerHeight = this.$header ? this.$header.offsetHeight : 0;
866        const actionsHeader = this.$actions ? this.$actions.offsetHeight : 0;
867
868        if (this.$list) {
869          this.$list.style.maxHeight = drawerHeight - headerHeight - actionsHeader - this.asideContentMargin * 2 + 'px';
870        }
871      },
872
873      _initCartItemRemoval: function () {
874        this.$aside.querySelectorAll(this.selectors.cartItemRemover).forEach( el => {
875          el.addEventListener('click', (event) => {
876            event.preventDefault();
877            const $parentEl = event.target.parentElement;
878            const $divider  = $parentEl.nextElementSibling;
879            $parentEl.classList.add('_removed');
880            $divider && $divider.classList.contains('cart-drawer-divider') && $divider.classList.add('_removed');
881            setTimeout(() => {
882              $parentEl.remove();
883              $divider && $divider.classList.contains('cart-drawer-divider') && $divider.remove();
884            }, 350);
885          });
886        });
887      }
888    });
889
890    return CartDrawer;
891  })();
892
893  UomoSections.SwiperSlideshow = (function () {
894    function SwiperSlideshow () {
895      this.selectors = {
896        container: '.js-swiper-slider'
897      }
898
899      this.$containers = document.querySelectorAll(this.selectors.container);
900      this._initSliders();
901    }
902
903    SwiperSlideshow.prototype = Object.assign({}, SwiperSlideshow.prototype, {
904      _initSliders() {
905        this.$containers.forEach(function($sliderContainer) {
906          if ($sliderContainer.classList.contains('swiper-container-initialized')) {
907            return;
908          }
909
910          let settings = {
911            autoplay: 0,
912            slidesPerView: 1,
913            loop: true,
914            navigation: {
915              nextEl: ".pc__img-next",
916              prevEl: ".pc__img-prev"
917            }
918          };
919
920          if ($sliderContainer.classList.contains('swiper-number-pagination')) {
921            settings = Object.assign(settings, {
922              pagination: {
923                "el": ".slideshow-pagination",
924                "type": "bullets",
925                "clickable": true,
926                renderBullet: function(index, className) {
927                  return '<span class="' + className + '">' + (index + 1).toString().padStart(2, '0') + '</span>';
928                }
929              }
930            });
931          }
932
933          if ($sliderContainer.dataset.settings) {
934            settings = Object.assign(settings, JSON.parse($sliderContainer.dataset.settings));
935          }
936
937          if ($sliderContainer.querySelectorAll('.swiper-slide').length > 1) {
938            // eslint-disable-next-line no-undef
939            new Swiper($sliderContainer, settings);
940          } else {
941            $sliderContainer.classList.add('swiper-container-initialized');
942            const $active_slide = $sliderContainer.querySelector('.swiper-slide');
943            $active_slide && $active_slide.classList.add('swiper-slide-active');
944          }
945        });
946      }
947    });
948
949    return SwiperSlideshow;
950  })();
951
952  UomoSections.ProductSingleMedia = (function () {
953    function ProductSingleMedia () {
954      this.selectors = {
955        container: '.product-single__media'
956      }
957
958      this.$containers = $(this.selectors.container);
959      this._initProductMedia();
960    }
961
962    function setSlideHeight(that){
963      $('.product-single__thumbnail .swiper-slide').css({height:'auto'});
964          var currentSlide = that.activeIndex;
965          var newHeight = $(that.slides[currentSlide]).height();
966  
967          $('.product-single__thumbnail .swiper-wrapper, .product-single__thumbnail .swiper-slide').css({ height : newHeight })
968          that.update();
969     }
970
971    ProductSingleMedia.prototype = Object.assign({}, ProductSingleMedia.prototype, {
972      _initProductMedia() {
973        this.$containers.each(function() {
974          if ($(this).hasClass('product-media-initialized')) {
975            return;
976          }
977
978          let media_type = $(this).data('media-type');
979
980          $(this).addClass(media_type);
981
982          if (media_type == 'vertical-thumbnail') {
983            var galleryThumbs = new Swiper(".product-single__thumbnail .swiper-container", {
984              direction: 'vertical',
985              slidesPerView: 6,
986              spaceBetween: 0,
987              freeMode: true,
988              breakpoints: {
989                0: {
990                  direction: 'horizontal',
991                  slidesPerView: 4,
992                },
993                992: {
994                  direction: 'vertical',
995                }
996              },
997              on: {
998                init:function(){
999                  setSlideHeight(this);
1000                },
1001                slideChangeTransitionEnd:function(){
1002                  setSlideHeight(this);
1003                }
1004              }
1005            });
1006            var galleryMain = new Swiper(".product-single__image .swiper-container", {
1007              direction: 'horizontal',
1008              slidesPerView: 1,
1009              spaceBetween: 32,
1010              mousewheel: false,
1011              navigation: {
1012                nextEl: '.swiper-button-next',
1013                prevEl: '.swiper-button-prev'
1014              },
1015              grabCursor: true,
1016              thumbs: {
1017                swiper: galleryThumbs
1018              },
1019              on: {
1020                slideChangeTransitionStart: function() {
1021                  galleryThumbs.slideTo(galleryMain.activeIndex);
1022                }
1023              }
1024            });
1025          } else if (media_type == 'vertical-dot') {
1026            var galleryMain = new Swiper(".product-single__image .swiper-container", {
1027              direction: 'horizontal',
1028              slidesPerView: 1,
1029              spaceBetween: 32,
1030              mousewheel: false,
1031              grabCursor: true,
1032              pagination: {
1033                el: ".product-single__image .swiper-pagination",
1034                type: "bullets",
1035                clickable: true
1036              },
1037            });
1038          } else if (media_type == 'scroll-snap') {
1039            // $("html").addClass("snap");
1040
1041            // window.addEventListener('scroll', function() {
1042            //   if ( $(".product-single__media").height() - $(window).height() < window.scrollY ) {
1043            //     $("html").removeClass("snap");
1044            //   } else {
1045            //     $("html").addClass("snap");
1046            //   }
1047            // });
1048          } else if (media_type == 'horizontal-thumbnail') {
1049            var galleryThumbs = new Swiper(".product-single__thumbnail .swiper-container", {
1050              direction: 'horizontal',
1051              slidesPerView: 6,
1052              spaceBetween: 0,
1053              freeMode: true,
1054              breakpoints: {
1055                0: {
1056                  slidesPerView: 4,
1057                },
1058                992: {
1059                  slidesPerView: 7,
1060                }
1061              }
1062            });
1063            var galleryMain = new Swiper(".product-single__image .swiper-container", {
1064              direction: 'horizontal',
1065              slidesPerView: 1,
1066              spaceBetween: 32,
1067              mousewheel: false,
1068              navigation: {
1069                nextEl: '.swiper-button-next',
1070                prevEl: '.swiper-button-prev'
1071              },
1072              grabCursor: true,
1073              thumbs: {
1074                swiper: galleryThumbs
1075              },
1076              on: {
1077                slideChangeTransitionStart: function() {
1078                  galleryThumbs.slideTo(galleryMain.activeIndex);
1079                }
1080              }
1081            });
1082          }
1083
1084          $(this).addClass('product-media-initialized');
1085        });
1086      }
1087    });
1088
1089    return ProductSingleMedia;
1090  })();
1091
1092  UomoElements.StarRating = (function () {
1093    function StarRating () {
1094      let stars = Array.from(document.querySelectorAll(UomoSelectors.starRatingControl));
1095      let user_selected_star = document.querySelector('#form-input-rating');
1096
1097      stars.forEach(star => {
1098        // Mouseover event
1099        star.addEventListener('mouseover', (e) => {
1100          stars.forEach((item, current_index) => {
1101            if (current_index <= stars.indexOf(e.target)) {
1102              item.classList.add('is-overed');
1103            } else {
1104              item.classList.remove('is-overed');
1105            }
1106          })
1107        })
1108      
1109        // Mouseover event
1110        star.addEventListener('mouseleave', (e) => {
1111          stars.forEach((item) => {
1112            item.classList.remove('is-overed');
1113          })
1114        })
1115      
1116        // Click event
1117        star.addEventListener('click', (e) => {
1118          const selected_index = stars.indexOf(e.target);
1119          user_selected_star.value = selected_index + 1;
1120          stars.forEach((item, current_index) => {
1121            if (current_index <= stars.indexOf(e.target)) {
1122              item.classList.add('is-selected');
1123            } else {
1124              item.classList.remove('is-selected');
1125            }
1126          })
1127        })
1128      })
1129    }
1130
1131    return StarRating;
1132  })();
1133
1134  class Uomo {
1135    constructor() {
1136      this.initCookieConsient();
1137      this.initAccessories();
1138      this.initMultiSelect();
1139      this.initBsTooltips();
1140      this.initRangeSlider();
1141
1142      new UomoElements.JsHoverContent();
1143      new UomoElements.Search();
1144      new UomoElements.Aside();
1145      new UomoElements.QtyControl();
1146      new UomoElements.ScrollToTop();
1147      new UomoElements.Countdown();
1148      new UomoElements.ShopViewChange();
1149      new UomoElements.Filters();
1150      new UomoElements.StickyElement();
1151      new UomoElements.StarRating();
1152
1153      new UomoSections.Header();
1154      new UomoSections.Footer();
1155      new UomoSections.CustomerSideForm();
1156      new UomoSections.CartDrawer();
1157      new UomoSections.SwiperSlideshow();
1158      new UomoSections.ProductSingleMedia();
1159    }
1160
1161    initCookieConsient() {
1162      const purecookieDesc = "In order to provide you a personalized shopping experience, our site uses cookies. By continuing to use this site, you are agreeing to our cookie policy.",
1163      purecookieButton = "Accept";
1164
1165      function pureFadeIn(e, o) {
1166        var i = document.getElementById(e);
1167        i.style.opacity = 0, i.style.display = o || "none",
1168        function e() {
1169          var o = parseFloat(i.style.opacity);
1170          (o += .02) > 1 || (i.style.opacity = o, requestAnimationFrame(e))
1171        }()
1172      }
1173
1174      function getCookie(e) {
1175        for (var o = e + "=", i = document.cookie.split(";"), t = 0; t < i.length; t++) {
1176          for (var n = i[t];" " == n.charAt(0);) {
1177            n = n.substring(1, n.length);
1178          }
1179          if (0 == n.indexOf(o))
1180            return n.substring(o.length, n.length)
1181        }
1182        return null
1183      }
1184
1185      function appendHtml(el, str) {
1186        var div = document.createElement('div');
1187        div.innerHTML = str;
1188        while (div.children.length > 0) {
1189          el.appendChild(div.children[0]);
1190        }
1191      }
1192
1193      // getCookie("purecookieDismiss") || (appendHtml(document.body, '<div class="cookieConsentContainer" id="cookieConsentContainer"><div class="cookieDesc"><p>' + purecookieDesc + '</p></div><div class="cookieButton"><a onClick="purecookieDismiss();">' + purecookieButton + "</a></div></div>"), pureFadeIn("cookieConsentContainer"))
1194    }
1195
1196    initAccessories() {
1197      // Check if device is mobile on resize
1198      window.addEventListener('resize', function() {
1199        UomoHelpers.isMobile = UomoHelpers.updateDeviceSize();
1200      });
1201    }
1202
1203    initMultiSelect() {
1204      // Declare variables
1205      const $containers = document.querySelectorAll('.multi-select');
1206
1207      this._initMultiSelect($containers);
1208    }
1209
1210    _initMultiSelect($containers) {
1211      $containers.forEach( el => {
1212        const $component = el;
1213        const $list = el.querySelector('.multi-select__list');
1214        const $select = $component.querySelector('select');
1215        const $actor = $component.querySelector('.multi-select__actor');
1216
1217        /**
1218         * Change hero value when selecting item
1219         */
1220        const $selectArray = $component.querySelectorAll('.js-multi-select');
1221        $selectArray.forEach( el => {
1222          el.addEventListener('click', function(e) {
1223            e.preventDefault();
1224
1225            const optionIndex = (Array.prototype.indexOf.call($list.children, e.currentTarget)).toString();
1226            const selectedOption = $select.options[optionIndex];
1227
1228            if (selectedOption && !selectedOption.selected) {
1229              e.currentTarget.classList.add('mult-select__item_selected');
1230              selectedOption.selected = true;
1231            } else {
1232              e.currentTarget.classList.remove('mult-select__item_selected');
1233              selectedOption.selected = false;
1234            }
1235
1236            if ($actor && !$actor.classList.contains('js-no-update')) {
1237              let content = $actor.dataset.placeholder;
1238              if ($select.selectedIndex > -1) {
1239                content = '';
1240                for (let i = 0; i < $select.selectedOptions.length; i++) {
1241                  const $option = $select.selectedOptions[i];
1242                  content = content + $option.innerText;
1243                  if (i < $select.selectedOptions.length - 1) {
1244                    content = content + ', ';
1245                  }
1246                }
1247              }
1248
1249              $actor.innerText = content;
1250            }
1251          });
1252        });
1253      });
1254    }
1255
1256    initBsTooltips() {
1257      const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
1258      tooltipTriggerList.map(function (tooltipTriggerEl) {
1259        // eslint-disable-next-line no-undef
1260        return new bootstrap.Tooltip(tooltipTriggerEl)
1261      });
1262    }
1263
1264    initRangeSlider() {
1265      const selectors = {
1266        elementClass: '.price-range-slider',
1267        minElement: '.price-range__min',
1268        maxElement: '.price-range__max'
1269      }
1270
1271      document.querySelectorAll(selectors.elementClass).forEach($se => {
1272        // $se = sliderElement
1273        const currency = $se.dataset.currency;
1274
1275        if ($se) {
1276          // eslint-disable-next-line no-undef
1277          const priceRange = new Slider($se, {
1278            tooltip_split: true,
1279            formatter: function(value) {
1280              return currency + value;
1281            },
1282          });
1283
1284          priceRange.on('slideStop', (value) => {
1285            const $minEl = $se.parentElement.querySelector(selectors.minElement);
1286            const $maxEl = $se.parentElement.querySelector(selectors.maxElement);
1287            $minEl.innerText = currency + value[0];
1288            $maxEl.innerText = currency + value[1];
1289          });
1290        }
1291      });
1292    }
1293  }
1294
1295  document.addEventListener("DOMContentLoaded", function() {
1296    // Init theme
1297    UomoHelpers.isMobile = UomoHelpers.updateDeviceSize();
1298    new Uomo();
1299  });
1300
1301  $('a[data-bs-toggle="tab"]').on('shown.bs.tab', function(e) {
1302    var paneTarget = $(e.target).attr('href');
1303    var $thePane = $('.tab-pane' + paneTarget);
1304    if ($thePane.find('.swiper-container').length > 0 && 0 === $thePane.find('.swiper-slide-active').length) {
1305      document.querySelectorAll('.tab-pane' + paneTarget + ' .swiper-container').forEach( function(item) {
1306        item.swiper.update();
1307        item.swiper.lazy.load();
1308      });
1309     }
1310  });
1311
1312  $('#quickView.modal').on('shown.bs.modal', function(e) {
1313    var paneTarget = "#quickView";
1314    var $thePane = $('.modal' + paneTarget);
1315    if ($thePane.find('.swiper-container').length > 0 && 0 === $thePane.find('.swiper-slide-active').length) {
1316      document.querySelectorAll('.modal' + paneTarget + ' .swiper-container').forEach( function(item) {
1317        item.swiper.update();
1318        item.swiper.lazy.load();
1319      });
1320     }
1321  });
1322
1323  var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'))
1324  var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
1325    return new bootstrap.Popover(popoverTriggerEl, {'html':true})
1326  });
1327
1328  $('.shopping-cart .btn-checkout').on('click', function() {
1329    window.location.href='./shop_checkout.html';
1330  });
1331
1332  $('.checkout-form .btn-checkout').on('click', function() {
1333    window.location.href='./shop_order_complete.html';
1334  });
1335
1336  $(document).on('click', '.cart-table .remove-cart', function(e) {
1337    e.preventDefault();
1338
1339    let parentEl = $(this).closest('tr');
1340    $(parentEl).addClass('_removed');
1341    setTimeout(() => {
1342      $(parentEl).remove();
1343    }, 350);
1344  });
1345
1346  // document.querySelector('.js-show-register').addEventListener('click', function(e) {
1347  //   document.querySelector(this.getAttribute("href")).click();
1348  // });
1349
1350  $(document).on('click', 'button.js-add-wishlist, a.add-to-wishlist', function() {
1351    if($(this).hasClass("active"))
1352      $(this).removeClass("active");
1353    else
1354      $(this).addClass("active");
1355    return false;
1356  });
1357
1358  if($('[data-fancybox="gallery"]').length > 0) {
1359    $('[data-fancybox="gallery"]').fancybox({
1360      backFocus: false
1361    });
1362  }
1363
1364  $(window).on("scroll", function() {
1365    if($(".mobile_fixed-btn_wrapper").length > 0) {
1366      if($(this).width() < 992 && $(this).width() >= 768) {
1367        if($(this).scrollTop() + $(this).height() - 76 <= $(".mobile_fixed-btn_wrapper").offset().top && $(this).scrollTop() > $(this).height()) {
1368          $(".mobile_fixed-btn_wrapper > .button-wrapper").addClass("fixed-btn");
1369        } else {
1370          $(".mobile_fixed-btn_wrapper > .button-wrapper").removeClass("fixed-btn");
1371        }
1372      } else if($(this).width() < 768) {
1373        if($(this).scrollTop() + $(this).height() - 124 <= $(".mobile_fixed-btn_wrapper").offset().top && $(this).scrollTop() > $(this).height()) {
1374          $(".mobile_fixed-btn_wrapper > .button-wrapper").addClass("fixed-btn");
1375        } else {
1376          $(".mobile_fixed-btn_wrapper > .button-wrapper").removeClass("fixed-btn");
1377        }
1378      } else {
1379        $(".mobile_fixed-btn_wrapper > .button-wrapper").removeClass("fixed-btn");
1380      }
1381    }
1382  });
1383
1384  window.onload = () => {
1385    if($("#newsletterPopup").length > 0)
1386      $("#newsletterPopup").modal("show");
1387
1388    $('.btn-video-player').each(function() {
1389      $(this).on("click", function() {
1390        if ($(this).hasClass("playing")) {
1391          $(this).removeClass("playing");
1392          $($(this).data("video")).get(0).pause();
1393        } else {
1394          $(this).addClass("playing");
1395          $($(this).data("video")).get(0).play();
1396        }
1397      });
1398
1399      const btn_player = $(this);
1400  
1401      $($(this).data("video")).on("ended", function() {
1402        $(btn_player).removeClass("playing");
1403        this.currentTime = 0;
1404      });
1405    });
1406  }
1407})($);
1408
1409(function () {
1410  'use strict'
1411
1412  // Fetch all the forms we want to apply custom Bootstrap validation styles to
1413  var forms = document.querySelectorAll('.needs-validation')
1414
1415  // Loop over them and prevent submission
1416  Array.prototype.slice.call(forms)
1417    .forEach(function (form) {
1418      form.addEventListener('submit', function (event) {
1419        if (!form.checkValidity()) {
1420          event.preventDefault();
1421          event.stopPropagation();
1422        }
1423
1424        form.querySelectorAll("input[data-cf-pwd]").forEach(function (el) {
1425          if(form.querySelector(el.getAttribute("data-cf-pwd")).value != el.value) {
1426            event.preventDefault();
1427            event.stopPropagation();
1428          }
1429        });
1430
1431        form.classList.add('was-validated')
1432      }, false);
1433
1434      form.querySelectorAll("input[data-cf-pwd]").forEach(function (el) {
1435        el.addEventListener('keyup', function (event) {
1436          if (!el.value || form.querySelector(el.getAttribute("data-cf-pwd")).value != el.value) {
1437            el.classList.add("is-invalid");
1438            el.classList.remove("is-valid");
1439            el.setCustomValidity("Invalid field.");
1440          } else {
1441            el.classList.remove("is-invalid");
1442            el.classList.add("is-valid");
1443            el.setCustomValidity("");
1444          }
1445        });
1446        form.querySelector(el.getAttribute("data-cf-pwd")).addEventListener('keyup', function (event) {
1447          if (!el.value || form.querySelector(el.getAttribute("data-cf-pwd")).value != el.value) {
1448            el.classList.add("is-invalid");
1449            el.classList.remove("is-valid");
1450            el.setCustomValidity("Invalid field.");
1451          } else {
1452            el.classList.remove("is-invalid");
1453            el.classList.add("is-valid");
1454            el.setCustomValidity("");
1455          }
1456        });
1457      });
1458    });
1459})();
1460
1461window.addEventListener('load', () => {
1462  try {
1463    let url = window.location.href.split('#').pop();
1464    document.querySelector('#'+url).click();
1465  } catch {
1466
1467  }
1468});

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.