PageSourceSearch

https://ergowebshop.de/templates/FIRE/js/jtl.evo.js?v=505

js ergowebshop.de collected 2026-10-10 02:04:53 UTC 49,874 bytes, 1,269 lines download raw bytes

1(function () {
2    'use strict';
3
4    if (!$.evo) {
5        $.evo = {};
6    }
7
8    var EvoClass = function() {};
9
10    EvoClass.prototype = {
11        options: {
12            captcha: {},
13            scrollSearch: '.smoothscroll-top-search'
14        },
15
16        constructor: EvoClass,
17
18        generateSlickSlider: function() {
19            let self = this;
20
21            const observer = new window.IntersectionObserver(entries => {
22                for (const entry of entries) {
23                    if (entry.isIntersecting) {
24                        let mainNode = $(entry.target);
25                        mainNode.removeClass('slick-lazy');
26                        if (!mainNode.hasClass('slick-initialized')) {
27                            mainNode.find('.product-wrapper').removeClass('mx-auto ml-auto-util mr-auto');
28                            self.initSlick(mainNode, mainNode.data('slick-type'), mainNode.data('display-counts'));
29                            mainNode.find('.slick-active a:first-child').attr({
30                                'tabindex': '-1'
31                            });
32
33                        }
34                    }
35                }
36            }, {
37                root: null,
38                threshold: 0.1, // set offset 0.1 means trigger if atleast 10% of element in viewport
39            })
40
41            document.querySelectorAll('.slick-lazy').forEach(function(slickItem) {
42                observer.observe(slickItem)
43            });
44
45            document.querySelectorAll('.slick-lazy').forEach(function(slickItem) {
46                let startX;
47                let supportsPassive = false;
48                try {
49                    let opts = Object.defineProperty({}, 'passive', {
50                        get: function() {
51                            supportsPassive = true;
52                        }
53                    });
54                    window.addEventListener("testPassive", null, opts);
55                    window.removeEventListener("testPassive", null, opts);
56                } catch (e) {}
57
58                slickItem.addEventListener('touchstart', function (e) {
59                    startX = e.changedTouches[0].pageX;
60
61                },supportsPassive ? { passive: true } : false);
62                slickItem.addEventListener('touchmove', function (e) {
63                    let mainNode = $(this);
64                    if (!mainNode.hasClass('slick-initialized')
65                        && Math.abs(startX - e.changedTouches[0].pageX) > 80
66                    ) {
67                        mainNode.removeClass('slick-lazy');
68                        mainNode.find('.product-wrapper').removeClass('mx-auto ml-auto-util mr-auto');
69                        self.initSlick(mainNode, mainNode.data('slick-type'), mainNode.data('display-counts'));
70                        let slickOptions = mainNode.slick('getSlick');
71                        if(slickOptions.slideCount > mainNode.slick('slickGetOption', 'slidesToShow')) {
72                            let goTo;
73                            $.each(slickOptions.originalSettings.responsive, function (key, value) {
74                                if (value.breakpoint === slickOptions.activeBreakpoint
75                                    && value.settings.slidesToShow !== undefined
76                                ) {
77                                    goTo = value.settings.slidesToShow;
78                                }
79                            });
80                            if (goTo === undefined) {
81                                goTo = slickOptions.originalSettings.slidesToScroll
82                            }
83                            mainNode.slick('slickGoTo', goTo || 2);
84                        }
85                    }
86                }, supportsPassive ? { passive: true } : false);
87            });
88        },
89
90        initSlick: function (node, sliderType, displayCounts = '') {
91            displayCounts = displayCounts.split(',');
92            displayCounts = [
93                parseInt(displayCounts[0]) || 2,
94                parseInt(displayCounts[1]) || 3,
95                parseInt(displayCounts[2]) || 5,
96                parseInt(displayCounts[3]) || 7,
97            ];
98            let sliderOptions = {
99                'box-slider' : {
100                    rows:           0,
101                    arrows:         false,
102                    lazyLoad:       'ondemand',
103                    slidesToShow:   1,
104                    slidesToScroll: 1,
105                    mobileFirst:    true,
106                    responsive: [
107                        {
108                            breakpoint: 992,
109                            settings: {
110                                arrows: true,
111                            }
112                        }
113                    ]
114                },
115                'slider-half' : {
116                    rows:         0,
117                    arrows:       false,
118                    lazyLoad:     'ondemand',
119                    mobileFirst:    true,
120                    slidesToShow: 2,
121                    slidesToScroll: 2,
122                    responsive:   [
123                        {
124                            breakpoint: 992,
125                            settings: {
126                                arrows: true,
127                            }
128                        },
129                        {
130                            breakpoint: 1300,
131                            settings: {
132                                slidesToShow: 3,
133                                slidesToScroll: 3,
134                                arrows: true,
135                            }
136                        }
137                    ]
138                },
139                'slider-three' : {
140                    rows:         0,
141                    arrows:       false,
142                    lazyLoad:     'ondemand',
143                    mobileFirst:    true,
144                    slidesToShow: 1,
145                    slidesToScroll: 1,
146                    responsive:   [
147                        {
148                            breakpoint: 768,
149                            settings: {
150                                slidesToShow: 2,
151                                slidesToScroll: 2,
152                            }
153                        },
154                        {
155                            breakpoint: 992,
156                            settings: {
157                                arrows: true,
158                            }
159                        },
160                        {
161                            breakpoint: 1300,
162                            settings: {
163                                arrows: true,
164                                slidesToShow: 3,
165                                slidesToScroll: 3,
166                            }
167                        }
168                    ]
169                },
170                'product-slider' : {
171                    rows:           0,
172                    arrows:         false,
173                    lazyLoad:       'ondemand',
174                    slidesToShow:   displayCounts[0] || 2,
175                    slidesToScroll: displayCounts[0] || 2,
176                    mobileFirst:    true,
177                    responsive:     [
178                        {
179                            breakpoint: 768,
180                            settings: {
181                                slidesToShow: displayCounts[1] || 3,
182                                slidesToScroll: displayCounts[1] || 3,
183                            }
184                        },
185                        {
186                            breakpoint: 992,
187                            settings: {
188                                slidesToShow: displayCounts[2] || 5,
189                                slidesToScroll: displayCounts[2] || 5,
190                                arrows: true,
191                            }
192                        },
193                        {
194                            breakpoint: 1300,
195                            settings: {
196                                slidesToShow: displayCounts[3] || 7,
197                                slidesToScroll: displayCounts[3] || 7,
198                                arrows: true,
199                            }
200                        }
201                    ]
202                },
203                'news-slider' : {
204                    rows:           0,
205                    slidesToShow:   1,
206                    slidesToScroll: 1,
207                    arrows:         false,
208                    infinite:       false,
209                    lazyLoad:       'ondemand',
210                    mobileFirst:    true,
211                    responsive:     [
212                        {
213                            breakpoint: 768,
214                            settings: {
215                                slidesToShow: 2,
216                                slidesToScroll: 2,
217                            }
218                        },
219                        {
220                            breakpoint: 992,
221                            settings: {
222                                slidesToShow:3,
223                                slidesToScroll: 3,
224                                arrows: true
225                            }
226                        },
227                        {
228                            breakpoint: 1300,
229                            settings: {
230                                slidesToShow:5,
231                                slidesToScroll: 5,
232                                arrows: true
233                            }
234                        }
235                    ]
236                },
237                'freegift' : {
238                    rows:         0,
239                    slidesToShow:   3,
240                    slidesToScroll: 3,
241                    arrows:   false,
242                    infinite: false,
243                    responsive: [
244                        {
245                            breakpoint: 768,
246                            settings: {
247                                slidesToShow: 2,
248                                slidesToScroll: 2,
249                            }
250                        },
251                        {
252                            breakpoint: 992,
253                            settings: {
254                                arrows: true
255                            }
256                        }
257                    ]
258                },
259                'gallery' : {
260                    rows:     0,
261                    lazyLoad: 'ondemand',
262                    infinite: true,
263                    dots:     false,
264                    arrows:   true,
265                    speed: 500,
266                    fade: true,
267                    cssEase: 'linear',
268                    asNavFor: '#gallery_preview',
269                    responsive:     [
270                        {
271                            breakpoint: 992,
272                            settings: {
273                                dots: true
274                            }
275                        }
276                    ]
277                },
278                'gallery_preview' : {
279                    rows:           0,
280                    lazyLoad:       'ondemand',
281                    slidesToShow:   5,
282                    slidesToScroll: 1,
283                    asNavFor:       '#gallery',
284                    dots:           false,
285                    arrows:         true,
286                    focusOnSelect:  true,
287                    responsive:     [
288                        {
289                            breakpoint: 768,
290                            settings:   {
291                                slidesToShow: 4,
292                                slidesToScroll: 1,
293                            }
294                        },
295                        {
296                            breakpoint: 576,
297                            settings: {
298                                slidesToShow: 3,
299                                slidesToScroll: 1,
300                            }
301                        }
302                    ]
303                }
304            };
305            if ($('#content').hasClass('col-lg-9')) {
306                sliderOptions['news-slider']['slidesToShow'] = 2;
307            }
308            if (sliderType === 'gallery_preview') {
309                sliderType = 'gallery';
310                node = $('#gallery');
311            }
312            if (sliderType === 'gallery') {
313                $('.js-gallery-images').removeClass('d-none');
314                $('.slick-inital-arrow').remove();
315                $('.initial-slick-dots').remove();
316                $('#gallery_preview').slick(sliderOptions['gallery_preview']);
317            }
318
319            return node.slick(sliderOptions[sliderType]);
320        },
321
322        scrollStuff: function() {
323            var breakpoint = 0,
324                pos,
325                sidePanel = $('#sidepanel_left');
326
327            if(sidePanel.length) {
328                breakpoint = sidePanel.position().top + sidePanel.hiddenDimension('height');
329            }
330
331            pos = breakpoint - $(this).scrollTop();
332
333            if ($(this).scrollTop() > 200 && !$('#to-top').hasClass('active')) {
334                $('#to-top').addClass('active');
335            } else if($(this).scrollTop() < 200 && $('#to-top').hasClass('active')) {
336                $('#to-top').removeClass('active');
337            }
338
339            if ($(window).width() > 768) {
340                var $document = $(document),
341                    $element = $('.navbar-fixed-top'),
342                    className = 'nav-closed';
343
344                $document.scroll(function() {
345                    $element.toggleClass(className, $document.scrollTop() >= 150);
346                });
347
348            }
349        },
350
351        productTabsPriceFlow: function() {
352            var dateFormat = 'DD.MM.YYYY';
353            if ($('html').attr('lang') !== 'de') {
354                dateFormat = 'MM/DD/YYYY';
355            }
356            var chartOptions = {
357                responsive:       true,
358                scaleBeginAtZero: false,
359                aspectRatio:3,
360                tooltips: {
361                    callbacks: {
362                        label: function (tooltipItem, data) {
363                            var label = window.chartDataTooltip;
364                            label += Math.round(tooltipItem.yLabel * 100) / 100;
365                            label += ' '+window.chartDataCurrency;
366                            return label;
367                        }
368                    }
369                },
370                scales: {
371                    xAxes: [{
372                        type: 'time',
373                        time: {
374                            parser: 'DD.MM.YYYY',
375                            // round: 'day'
376                            tooltipFormat: dateFormat
377                        },
378                        display: false
379                    }],
380                }
381            };
382            if (typeof window.priceHistoryChart !== 'undefined' && window.priceHistoryChart === null) {
383                window.priceHistoryChart = new Chart(window.ctx, {
384                    type: 'line',
385                    data: window.chartData,
386                    options: chartOptions
387                });
388            }
389        },
390
391        tooltips: function() {
392            $('[data-toggle="tooltip"]').tooltip();
393        },
394
395        bootlint: function() {
396            (function(){
397                var p = window.alert;
398                var s = document.createElement("script");
399                window.alert = function() {
400                    console.info(arguments);
401                };
402                s.onload = function() {
403                    bootlint.showLintReportForCurrentDocument([]);
404                    window.alert = p;
405                };
406                s.src = "https://maxcdn.bootstrapcdn.com/bootlint/latest/bootlint.min.js";
407                document.body.appendChild(s);
408            })();
409        },
410
411        showNotify: function(options) {
412            eModal.alert({
413                size: 'xl',
414                buttons: false,
415                title: options.title,
416                message: options.text,
417                keyboard: true,
418                tabindex: -1})
419                .then(
420                 function() {
421                    $.evo.generateSlickSlider();
422                     $.evo.salepix().SalepixSwiperSlider(); //SALEPIX ADDED
423                }
424            );
425        },
426
427        popupDep: function() {
428            $('#main-wrapper').on('click', '.popup-dep', function(e) {
429                var id    = '#popup' + $(this).attr('id'),
430                    title = $(this).attr('title'),
431                    html  = $(id).html();
432                eModal.alert({
433                    message: html,
434                    title: title,
435                    keyboard: true,
436                    buttons: false,
437                    tabindex: -1})
438                    .then(
439                        function () {
440                            //the modal just copies all the html.. so we got duplicate IDs which confuses recaptcha
441                            var recaptcha = $('.tmp-modal-content .g-recaptcha');
442                            if (recaptcha.length === 1) {
443                                var siteKey = recaptcha.data('sitekey'),
444                                    newRecaptcha = $('<div />');
445                                if (typeof  siteKey !== 'undefined') {
446                                    //create empty recapcha div, give it a unique id and delete the old one
447                                    newRecaptcha.attr('id', 'popup-recaptcha').addClass('g-recaptcha form-group');
448                                    recaptcha.replaceWith(newRecaptcha);
449                                    grecaptcha.render('popup-recaptcha', {
450                                        'sitekey' : siteKey,
451                                        'callback' : 'captcha_filled'
452
453                                    });
454                                }
455                            }
456                            addValidationListener();
457                            $('.g-recaptcha-response').attr('required', true);
458                        }
459                    );
460                return false;
461            });
462        },
463
464        popover: function() {
465            /*
466             * <a data-toggle="popover" data-ref="#popover-content123">Click me</a>
467             * <div id="popover-content123" class="popover">content here</div>
468             */
469            $('[data-toggle="popover"]').popover({
470                html: true,
471                sanitize: false,
472                content: function() {
473                    var ref = $(this).attr('data-ref');
474                    return $(ref).html();
475                }
476            });
477        },
478
479        smoothScrollToAnchor: function(href, pushToHistory) {
480            var anchorRegex = /^#[\w\-]+$/;
481            if (!anchorRegex.test(href)) {
482                return false;
483            }
484
485            var target, targetOffset;
486            target = $('#' + href.slice(1));
487
488            if (target.length > 0) {
489                // scroll below the static megamenu
490                var nav         = $('#jtl-nav-wrapper.sticky-top');
491                var fixedOffset = nav.length > 0 ? nav.outerHeight() : 0;
492
493                targetOffset = target.offset().top - fixedOffset - parseInt(target.css('margin-top'));
494                $('html, body').animate({scrollTop: targetOffset});
495
496                if (pushToHistory) {
497                    history.pushState({}, document.title, location.pathname + href);
498                }
499
500                return true;
501            }
502
503            return false;
504        },
505
506        smoothScroll: function() {
507            var supportHistory = (history && history.pushState) ? true : false;
508            var that = this;
509
510            this.smoothScrollToAnchor(location.hash, false);
511            $(document).delegate('a[href^="#"]', 'click', function(e) {
512                var elem = e.target;
513                if (!e.isDefaultPrevented()) {
514                    // only runs if no other click event is fired
515                    if (that.smoothScrollToAnchor(elem.getAttribute('href'), supportHistory)) {
516                        e.preventDefault();
517                    }
518                }
519            });
520        },
521
522        initSkipToScroll: function() {
523            // set focus on skip-to links
524            let links = $('.btn-skip-to');
525            var that = this;
526
527            links.on('click', function(e) {
528                let url    = new URL(e.target.href);
529                let target = url.hash;
530
531                that.smoothScrollToAnchor(target, false);
532                $(target).focus();
533            });
534        },
535
536        initScrollSearchEvent: function() {
537            this.destroyScrollSearchEvent();
538            let lastScroll       = 0,
539                $scrollTopSearch = $(this.options.scrollSearch);
540            if ($scrollTopSearch.length) {
541                $(document).on('scroll.search', function () {
542                    let newScroll = $(this).scrollTop();
543                    if (newScroll < lastScroll) {
544                        if ($(window).scrollTop() > 100) {
545                            $scrollTopSearch.removeClass('d-none');
546                        } else {
547                            $scrollTopSearch.addClass('d-none');
548                        }
549                    } else {
550                        $scrollTopSearch.addClass('d-none');
551                    }
552                    lastScroll = newScroll;
553                });
554            }
555        },
556
557        destroyScrollSearchEvent: function() {
558            $(this.options.scrollSearch).addClass('d-none');
559            $(document).off('scroll.search');
560        },
561
562        initScrollEvents: function() {
563            this.initScrollSearchEvent();
564
565            //scroll top button
566            let toTopbuttonVisible     = false,
567                $toTopbutton           = $('.smoothscroll-top'),
568                toTopbuttonActiveClass = 'show';
569
570            function scrolltoTop() {
571                $(window).scrollTop(0);
572            }
573
574            function handleVisibilityTopButton() {
575                let currentPosition = $(window).scrollTop();
576                if (currentPosition > 800) {
577                    if (!toTopbuttonVisible) {
578                        $toTopbutton.addClass(toTopbuttonActiveClass);
579                        toTopbuttonVisible = true;
580                    }
581                } else if (toTopbuttonVisible) {
582                    toTopbuttonVisible = false;
583                    $toTopbutton.removeClass(toTopbuttonActiveClass)
584                }
585            }
586
587            if ($toTopbutton.length) {
588                $(window).on('scroll', handleVisibilityTopButton);
589                if (("ontouchstart" in document.documentElement)) {
590                    document.querySelector('.smoothscroll-top').addEventListener("mousemove", (event) => {
591                        window.scrollTo({
592                            top: 0,
593                            behavior: 'smooth',
594                        });
595                    });
596                } else {
597                    $toTopbutton.on('click', scrolltoTop);
598                }
599                handleVisibilityTopButton();
600            }
601        },
602
603        resetForParallax: function() {
604            $(window).trigger('resize').trigger('scroll');
605        },
606
607        addCartBtnAnimation: function() {
608            var animating = false;
609
610            initCustomization();
611
612            function initCustomization() {
613                var addToCartBtn = $('#add-to-cart button[type="submit"]'),
614                    form         = $('#buy_form');
615                //detect click on the add-to-cart button
616                form.on('submit', function(e) {
617                    if(!animating ) {
618                        //animate if not already animating
619                        animating =  true;
620
621                        addToCartBtn.addClass('is-added').find('path').eq(0).animate({
622                            //draw the check icon
623                            'stroke-dashoffset':0
624                        }, 300, function(){
625                            setTimeout(function(){
626                                addToCartBtn.removeClass('is-added').find('span.btn-basket-check').on('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
627                                    //wait for the end of the transition to reset the check icon
628                                    addToCartBtn.find('path').eq(0).css('stroke-dashoffset', '19.79');
629                                    animating =  false;
630                                });
631
632                                if( $('.no-csstransitions').length > 0 ) {
633                                    // check if browser doesn't support css transitions
634                                    addToCartBtn.find('path').eq(0).css('stroke-dashoffset', '19.79');
635                                    animating =  false;
636                                }
637                            }, 600);
638                        });
639                    }
640                });
641            }
642
643        },
644
645        checkout: function() {
646            // show only the first submit button (i.g. the button from payment plugin)
647            var $submits = $('#checkout-shipping-payment')
648                .closest('form')
649                .find('button[type="submit"]');
650            $submits.addClass('d-none');
651            $submits.first().removeClass('d-none');
652
653            $('input[name="Versandart"]', '#checkout-shipping-payment').on('change', function() {
654                var id    = parseInt($(this).val());
655                var $form = $(this).closest('form');
656                if (isNaN(id)) {
657                    return;
658                }
659
660                $form.find('fieldset, button[type="submit"]')
661                    .attr('disabled', true);
662
663                var urlInstance = null;
664                if ($form.length === 1 && $form.attr('action') !== undefined) {
665                    urlInstance = new URL($form.attr('action'));
666                    urlInstance.searchParams.append('kVersandart', '' + id);
667                }
668                var url = urlInstance === null
669                    ? $('#jtl-io-path').data('path') + '/bestellvorgang.php?kVersandart=' + id
670                    : urlInstance.href;
671                $.evo.loadContent(url, function() {
672                    $.evo.checkout();
673                }, null, true);
674            });
675
676            $('#country').on('change', function (e) {
677                var val = $(this).find(':selected').val();
678
679                $.evo.io().call('checkDeliveryCountry', [val], {}, function (error, data) {
680                    var $shippingSwitch = $('#checkout_register_shipping_address');
681
682                    if (data.response) {
683                        $shippingSwitch.removeAttr('disabled');
684                        $shippingSwitch.parent().removeClass('d-none');
685                    } else {
686                        $shippingSwitch.attr('disabled', true);
687                        $shippingSwitch.parent().addClass('d-none');
688                        if ($shippingSwitch.prop('checked')) {
689                            $shippingSwitch.prop('checked', false);
690                            $('#select-shipping-address').collapse('show');
691                        }
692                    }
693                });
694            });
695        },
696
697        loadContent: function(url, callback, error, animation, wrapper) {
698            var that        = this;
699            var $wrapper    = (typeof wrapper === 'undefined' || wrapper.length === 0) ? $('#result-wrapper') : $(wrapper);
700            var ajaxOptions = {data: 'isAjax'};
701            if (animation) {
702                $wrapper.addClass('loading');
703            }
704
705            that.trigger('load.evo.content', { url: url });
706
707            $.ajax(url, ajaxOptions).done(function(html) {
708                var $data = $(html);
709                if (animation) {
710                    $data.addClass('loading');
711                }
712                $wrapper.replaceWith($data);
713                $wrapper = $data;
714                if (typeof callback === 'function') {
715                    callback();
716                }
717            })
718            .fail(function() {
719                if (typeof error === 'function') {
720                    error();
721                }
722            })
723            .always(function() {
724                $wrapper.removeClass('loading');
725                that.trigger('contentLoaded'); // compatibility
726                that.trigger('loaded.evo.content', { url: url });
727            });
728        },
729
730        startSpinner: function (target) {
731            target = target || $('body');
732            if ($('.jtl-spinner').length === 0) {
733                target.append('<div class="jtl-spinner"><i class="fa fa-spinner fa-pulse"></i></div>');
734            }
735        },
736
737        stopSpinner: function () {
738            $('.jtl-spinner').remove();
739        },
740
741        trigger: function(event, args) {
742            $(document).trigger('evo:' + event, args);
743            return this;
744        },
745
746        error: function() {
747            if (console && console.error) {
748                if (1 in arguments && arguments[1] === 'abort') {
749                    console.info(arguments);
750                } else {
751                    console.error(arguments);
752                }
753            }
754        },
755
756        addInactivityCheck: function(wrapper, timeoutMS = 500, stopEnter = false) {
757            var timeoutID,
758                that = this,
759                currentBox;
760
761            setup();
762
763            function setup() {
764                $(wrapper + ' .form-counter input, ' + wrapper + ' .choose_quantity input').on('change',resetTimer);
765                $(wrapper + ' .form-counter .btn-decrement, ' + wrapper + ' .form-counter .btn-increment')
766                    .on('click keydown',resetTimer)
767                    .on('touchstart',resetTimer,{passive: true});
768                if (stopEnter) {
769                    $(wrapper + ' input.quantity').on('keypress', function (e) {
770                        if (e.key === 'Enter') {
771                            return false;
772                        } else {
773                            resetTimer(e);
774                        }
775                    });
776                }
777            }
778
779            function startTimer() {
780                timeoutID = window.setTimeout(goInactive, timeoutMS);
781            }
782
783            function resetTimer(e) {
784                // prevents form submit on navigating via tab-key
785                if (e.keyCode !== 9) {
786                    if (wrapper === '#wl-items-form') {
787                        currentBox = $(e.target).closest('.productbox-inner');
788                    }
789                    if (timeoutID == undefined) {
790                        startTimer();
791                    }
792                    window.clearTimeout(timeoutID);
793
794                    startTimer();
795                }
796            }
797
798            function goInactive() {
799                if (wrapper === '#cart-form') {
800                    $(wrapper).submit();
801                } else if (wrapper === '#wl-items-form') {
802                    that.updateWishlistItem(currentBox);
803                }
804            }
805        },
806
807        updateWishlistItem: function($wrapper) {
808            let formID   = 'wl-items-form';
809            $.evo.extended().startSpinner($wrapper);
810            $.evo.io().call(
811                'updateWishlistItem',
812                [
813                    parseInt($('#' + formID + ' input[name="kWunschliste"]').val()),
814                    $.evo.io().getFormValues(formID)
815                ],
816                $(this) , function(error, data) {
817                    $.evo.extended().stopSpinner();
818                    $wrapper.removeClass('loading');
819                });
820        },
821
822        fixStickyElements: function() {
823            var sticky    = '.cart-summary';
824            var navHeight = $('#jtl-nav-wrapper').outerHeight(true);
825            navHeight = navHeight === undefined ? 0 : parseInt(navHeight + 40);
826            $(sticky).css('top', navHeight);
827        },
828
829        setWishlistVisibilitySwitches: function() {
830            $('.wl-visibility-switch').on('change', function () {
831                $.evo.io().call(
832                    'setWishlistVisibility',
833                    [$(this).data('wl-id'), $(this).is(":checked"), $('.
833jtl_token').val()],
834                    $(this),
835                    function(error, data) {
836                    if (error) {
837                        return;
838                    }
839                    var $wlPrivate    = $('span[data-switch-label-state="private-' + data.response.wlID + '"]'),
840                        $wlPublic     = $('span[data-switch-label-state="public-' + data.response.wlID + '"]'),
841                        $wlURLWrapper = $('#wishlist-url-wrapper'),
842                        $wlURL        = $('#wishlist-url');
843                    if (data.response.state) {
844                        $wlPrivate.addClass('d-none');
845                        $wlPublic.removeClass('d-none');
846                        $wlURLWrapper.removeClass('d-none');
847                        $wlURL.val($wlURL.data('static-route') + data.response.url)
848                    } else {
849                        $wlPrivate.removeClass('d-none');
850                        $wlPublic.addClass('d-none');
851                        $wlURLWrapper.addClass('d-none');
852                    }
853                });
854            });
855        },
856
857        setDeliveryAdressDefaultSwitches: function() {
858            $('.la-default-switch').on('change', function () {
859                let input = $(this);
860                $('.la-default-switch').each(function() {
861                    if (input.attr('id') !== $(this).attr('id')) {
862                        $(this).prop('checked', false);
863                    } else {
864                        $(this).prop('checked', true);
865                    }
866                });
867                $.evo.io().call(
868                    'setDeliveryaddressDefault',
869                    [$(this).data('la-id'), $('.jtl_token').val()],
870                    $(this), function(error, data) {
871                        if (error) {
872                            return;
873                        }
874                        if (!data.response.result) {
875                            input.prop('checked', false);
876                        }
877                    }
878                );
879            });
880        },
881
882        initEModals: function () {
883            $('.author-modal').on('click', function (e) {
884                e.preventDefault();
885                let modalID = $(this).data('target');
886                eModal.alert({
887                    title: $(modalID).attr('title'),
888                    message: $(modalID).html(),
889                    buttons: false
890                });
891            });
892        },
893
894        //SALEPIX MODIFY
895        initPriceSlider: function ($wrappers, redirect) {
896            $wrappers.each(function() {
897                let
898                    $wrapper = $(this),
899                    priceRange      = $wrapper.find('[data-id="js-price-range"]').val(),
900                    priceRangeID    = $wrapper.find('[data-id="js-price-range-id"]').val(),
901                    priceRangeMin   = 0,
902                    priceRangeMax   = $wrapper.find('[data-id="js-price-range-max"]').val(),
903                    currentPriceMin = priceRangeMin,
904                    currentPriceMax = priceRangeMax,
905                    $priceRangeFrom = $("#" + priceRangeID + "-from"),
906                    $priceRangeTo = $("#" + priceRangeID + "-to"),
907                    $priceSlider = document.getElementById(priceRangeID);
908                if($priceSlider === null) {
909                    return;
910                }
911                if (priceRange) {
912                    let priceRangeMinMax = priceRange.split('_');
913                    currentPriceMin = priceRangeMinMax[0];
914                    currentPriceMax = priceRangeMinMax[1];
915                    $priceRangeFrom.val(currentPriceMin);
916                    $priceRangeTo.val(currentPriceMax);
917                }
918                noUiSlider.create($priceSlider, {
919                    start: [parseInt(currentPriceMin), parseInt(currentPriceMax)],
920                    connect: true,
921                    range: {
922                        'min': parseInt(priceRangeMin),
923                        'max': parseInt(priceRangeMax)
924                    },
925                    step: 1,
926                    format: {
927                        to: function (value) {
928                            return parseInt(value);
929                        },
930                        from: function (value) {
931                            return parseInt(value);
932                        }
933                    },
934                    handleAttributes: [
935                        { 'aria-label': 'lower' },
936                        { 'aria-label': 'upper' },
937                    ],
938                });
939                $priceSlider.noUiSlider.on('change', function (values, handle) {
940                    setTimeout(function(){
941                        $.evo.redirectToNewPriceRange(values[0] + '_' + values[1], redirect, $wrapper);
942                    },0);
943                });
944                $priceSlider.noUiSlider.on('update', function (values, handle) {
945                    $priceRangeFrom.val(values[0]);
946                    $priceRangeTo.val(values[1]);
947                });
948                $('.price-range-input').on('change', function () {
949                    let prFrom = parseInt($priceRangeFrom.val()),
950                        prTo = parseInt($priceRangeTo.val());
951                    $.evo.redirectToNewPriceRange(
952                        (prFrom > 0 ? prFrom : priceRangeMin) + '_' + (prTo > 0 ? prTo : priceRangeMax),
953                        redirect,
954                        $wrapper
955                    );
956                });
957            });
958        },
959
960        initFilters: function (href) {
961            let $wrapper = $('.js-collapse-filter');
962            $('#submitMobileFilters').addClass('disabled');
963            $.evo.extended().startSpinner($wrapper);
964
965            $.ajax(href, {data: {'useMobileFilters':1}})
966                .done(function(data) {
967                    $wrapper.html(data);
968                    $.evo.initPriceSlider($wrapper, false);
969                    $.evo.initItemSearch('filter');
970                })
971                .always(function() {
972                    $('#submitMobileFilters').removeClass('disabled');
973                    $.evo.extended().stopSpinner();
974                });
975        },
976
977        initFilterEvents: function() {
978            let initiallized = false;
979            $('#js-filters').on('click', function() {
980                if (!initiallized) {
981                    $.evo.initFilters(window.location.href);
982                    initiallized = true;
983                }
984            });
985        },
986
987        redirectToNewPriceRange: function (priceRange, redirect, $wrapper) {
988            let currentURL  = window.location.href;
989            if (!redirect) {
990                currentURL  = $wrapper.find('[data-id="js-price-range-url"]').val();
991            }
992            let redirectURL = $.evo.updateURLParameter(
993                currentURL,
994                'pf',
995                priceRange
996            );
997            if (redirect) {
998                window.location.href = redirectURL;
999            } else {
1000                $.evo.initFilters(redirectURL);
1001            }
1002        },
1003
1004        updateURLParameter: function (url, param, paramVal) {
1005            let newAdditionalURL = '',
1006                tempArray        = url.split('?'),
1007                baseURL          = tempArray[0],
1008                additionalURL    = tempArray[1],
1009                temp             = '';
1010            if (additionalURL) {
1011                tempArray = additionalURL.split('&');
1012                for (let i=0; i<tempArray.length; i++){
1013                    if(tempArray[i].split('=')[0] != param){
1014                        newAdditionalURL += temp + tempArray[i];
1015                        temp = '&';
1016                    }
1017                }
1018            }
1019
1020            return baseURL + '?' + newAdditionalURL + temp + param + '=' + paramVal;
1021        },
1022
1023        updateReviewHelpful: function(item) {
1024            let formData = $.evo.io().getFormValues('reviews-list');
1025            formData[item.prop('name')] = '';
1026            formData['reviewID'] = item.data('review-id');
1027
1028            $.evo.io().call(
1029                'updateReviewHelpful',
1030                [formData],
1031                $(this) , function(error, data) {
1032                    if (error) {
1033                        return;
1034                    }
1035                    let review = data.response.review;
1036
1037                    $('[data-review-id="' + review.kBewertung + '"]').removeClass('on-list');
1038                    item.addClass('on-list');
1039                    $('[data-review-count-id="hilfreich_' + review.kBewertung + '"]').html(review.nHilfreich);
1040                    $('[data-review-count-id="nichthilfreich_' + review.kBewertung + '"]').html(review.nNichtHilfreich);
1041                });
1042        },
1043
1044        initReviewHelpful: function() {
1045            $('.js-helpful').on('click', function (e) {
1046                e.preventDefault();
1047                $.evo.extended().updateReviewHelpful($(this));
1048            });
1049        },
1050
1051        initWishlist: function() {
1052            let wlFormID = '#wl-items-form';
1053            if ($(wlFormID).length) {
1054                $.evo.extended().addInactivityCheck(wlFormID, 300, true);
1055                $('.js-update-wl').on('change', function () {
1056                    $.evo.extended().updateWishlistItem($(this).closest('.productbox-inner'));
1057                });
1058                $(window).on('resize', function () {
1059                    setWishlistItemheights();
1060                });
1061                setWishlistItemheights();
1062            }
1063            function setWishlistItemheights() {
1064                $('.product-list').children().each(function() {
1065                    $(this).css('height', window.innerWidth > globals.breakpoints.xl ? $(this).height() : 'unset');
1066                });
1067            }
1068        },
1069
1070        initPaginationEvents: function() {
1071            $('.pagination-wrapper select').on('change', function () {
1072                this.form.submit();
1073            });
1074        },
1075
1076        initItemSearch: function(context) {
1077            let searchWrapper  = '.' + context + '-search-wrapper',
1078                searchInput    = '.' + context + '-search',
1079                itemValue      = '.' + context + '-item-value',
1080                item           = '.' + context + '-item',
1081                clear          = '.form-clear',
1082                inputSelected  = 'input-group-selected',
1083                $searchWrapper = $(searchWrapper);
1084
1085            if ($searchWrapper.length === 0) {
1086                return;
1087            }
1088            $searchWrapper.each((i, itemWrapper) => {
1089                $(itemWrapper).find(searchInput).on('input', function () {
1090                    filterSearch($(itemWrapper));
1091                    $(itemWrapper).find('.collapse').collapse('show');
1092                }).on('keydown', e => {
1093                    if (e.key === 'Escape') {
1094                        e.stopPropagation();
1095                    }
1096                });
1097            });
1098            $(searchWrapper + ' ' + clear).on('click', function() {
1099                $(this).prev().val('');
1100                $(this).addClass('d-none');
1101                filterSearch($(this).closest(searchWrapper));
1102            });
1103            $(searchInput).on('focusin', function() {
1104                $(this).closest(searchWrapper).addClass(inputSelected);
1105            }).on('focusout', function() {
1106                $(this).closest(searchWrapper).removeClass(inputSelected);
1107            });
1108
1109            function filterSearch (itemWrapper) {
1110                let searchTerm = itemWrapper.find(searchInput).val().toLowerCase();
1111                itemWrapper.find(itemValue).each((i, itemTMP) => {
1112                    itemTMP = $(itemTMP);
1113                    let text = itemTMP.text().toLowerCase();
1114                    if (text.indexOf(searchTerm) === -1) {
1115                        itemTMP.closest(item).hide();
1116                    } else {
1117                        itemTMP.closest(item).show();
1118                    }
1119                    if (searchTerm.length === 0) {
1120                        itemWrapper.find(clear).addClass('d-none');
1121                    } else {
1122                        itemWrapper.find(clear).removeClass('d-none');
1123                    }
1124                });
1125            }
1126        },
1127
1128        initSliders: function() {
1129            let wrapper  = '.js-slider-wrapper',
1130                buttonF  = '.js-btn-slider-sf',
1131                buttonB  = '.js-btn-slider-sb',
1132                items    = '.js-slider-items';
1133
1134            $(wrapper).each(function (e) {
1135                let $buttonF   = $(this).find(buttonF),
1136                    $buttonB   = $(this).find(buttonB),
1137                    $items     = $(this).find(items);
1138
1139                $buttonF.on('click', function () {
1140                    $items.animate(
1141                        { scrollLeft: $items.scrollLeft() + $items.width() },
1142                        300,
1143                        'swing',
1144                        function () {
1145                            checkButtonDisable($buttonB, $buttonF, $items);
1146                        });
1147                });
1148                $buttonB.on('click', function () {
1149                    $items.animate(
1150                        { scrollLeft: $items.scrollLeft() - $items.width() },
1151                        300,
1152                        'swing',
1153                        function () {
1154                            checkButtonDisable($buttonB, $buttonF, $items);
1155                        });
1156                });
1157                $items.on('touchend', function (e) {
1158                    checkButtonDisable($buttonB, $buttonF, $items);
1159                });
1160            });
1161
1162            function checkButtonDisable($buttonB, $buttonF, $items) {
1163                let currentScroll = $items.scrollLeft();
1164                if (currentScroll <= 1) {
1165                    $buttonB.prop('disabled', true);
1166                } else {
1167                    $buttonB.prop('disabled', false);
1168                }
1169                if (currentScroll >= $items[0].scrollWidth - $items.width()) {
1170                    $buttonF.prop('disabled', true);
1171                } else {
1172                    $buttonF.prop('disabled', false);
1173                }
1174            }
1175        },
1176
1177        initSwatchFocus: function($wrapper) {
1178            $('.swatches-image>input, .swatches-text>input', $wrapper).on('focusin', function () {
1179                $(this).parent('label').addClass('focus');
1180            }).on('focusout', function () {
1181                $(this).parent('label').removeClass('focus');
1182            });
1183        },
1184
1185        registerImageHover: function($wrapper) {
1186            $(window).on("load resize", function() {
1187                let productWrapper = $('.product-wrapper');
1188                $.each(productWrapper, function() {
1189                    // Skip if element is inside a closed collapse.
1190                    let collapse = $(this).closest('.collapse');
1191                    if (collapse.length === 0 || collapse.hasClass('show')) {
1192                        let boxHeight = $(this).height()
1193                        $(this).height(boxHeight);
1194                    }
1195                })
1196            })
1197        },
1198
1199        /**
1200         * $.evo.extended() is deprecated, please use $.evo instead
1201         */
1202        extended: function() {
1203            return $.evo;
1204        },
1205
1206        register: function() {
1207            this.productTabsPriceFlow();
1208            this.generateSlickSlider();
1209            setTimeout(() => {
1210                $('.nav-tabs').tabdrop();
1211            }, 200);
1212            this.tooltips();
1213            this.popupDep();
1214            this.popover();
1215            this.addCartBtnAnimation();
1216            this.checkout();
1217            if ($('body').data('page') == 3) {
1218                this.addInactivityCheck('#cart-form',500,true);
1219            }
1220            this.fixStickyElements();
1221            this.setWishlistVisibilitySwitches();
1222            this.setDeliveryAdressDefaultSwitches();
1223            this.initEModals();
1224            $.evo.article().initConfigListeners();
1225            this.initScrollEvents();
1226            this.initSkipToScroll();
1227            this.initReviewHelpful();
1228            this.initWishlist();
1229            this.initPaginationEvents();
1230            this.initFilterEvents();
1231            this.initItemSearch('filter');
1232            this.initSliders();
1233            this.initSwatchFocus();
1234            //this.registerImageHover(); SALEPIX EDIT
1235            this.wireUpPRGLinks();
1236        },
1237
1238        wireUpPRGLinks()
1239        {
1240            for (const prgLink of document.querySelectorAll('[data-prg-href]')) {
1241                prgLink.addEventListener('click', e => {
1242                    e.preventDefault();
1243                    let targetUrl = atob(prgLink.dataset.prgHref);
1244                    let urlInput = document.createElement('input');
1245                    let virtualForm = document.createElement('form');
1246                    document.body.append(virtualForm);
1247                    urlInput.name = 'prgTargetUrl';
1248                    urlInput.value = targetUrl;
1249                    virtualForm.action = window.jtlShopBaseUrl + '/prg';
1250                    virtualForm.method = 'post';
1251                    virtualForm.append(urlInput);
1252                    virtualForm.submit();
1253                });
1254            }
1255        },
1256    };
1257
1258    $(document).ready(function () {
1259        $.evo.register();
1260    });
1261
1262    // PLUGIN DEFINITION
1263    // =================
1264    $.evo = new EvoClass();
1265})(jQuery);
1266
1267function g_recaptcha_callback() {
1268    $.evo.renderCaptcha();
1269}

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.