PageSourceSearch

https://fangoorn.de/templates/NOVA/js/global.js?v=1.7.1

js fangoorn.de collected 2026-10-01 14:24:36 UTC 29,243 bytes, 820 lines download raw bytes

1'use strict';
2
3$('body').on('click', '.option li', function (e) {
4    var i = $(this).parents('.select').attr('id'),
5        v = $(this).children().text(),
6        o = $(this).attr('id');
7    $('#' + i + ' .selected').attr('id', o).text(v);
8});
9
10// prevent multiple form submit on client side
11$('.submit_once').closest('form').on('submit', function() {
12    $(this).find('.submit_once').prop('disabled', 'true');
13    return true;
14});
15
16/**
17 *  Format file size
18 */
19function formatSize(size) {
20    var fileSize = Math.round(size / 1024),
21        suffix = 'KB',
22        fileSizeParts;
23
24    if (fileSize > 1000) {
25        fileSize = Math.round(fileSize / 1000);
26        suffix = 'MB';
27    }
28
29    fileSizeParts = fileSize.toString().split('.');
30    fileSize = fileSizeParts[0];
31
32    if (fileSizeParts.length > 1) {
33        fileSize += '.' + fileSizeParts[1].substr(0, 2);
34    }
35    fileSize += suffix;
36
37    return fileSize;
38}
39
40function getCategoryMenu(categoryId, success) {
41    var xx = {};
42    var io = $.evo.io();
43
44    io.call('getCategoryMenu', [categoryId], xx, function (error, data) {
45        if (error) {
46            console.error(data);
47        } else if (typeof success === 'function') {
48            success(xx.response);
49        }
50    });
51
52    return true;
53}
54
55function categoryMenu(rootcategory) {
56    if (typeof rootcategory === 'undefined') {
57        rootcategory = $('.sidebar-offcanvas .navbar-categories').html();
58    }
59
60    $('.sidebar-offcanvas li a.nav-sub').on('click', function(e) {
61        var navbar = $('.sidebar-offcanvas .navbar-categories'),
62            ref = $(this).data('ref');
63
64        if (ref === 0) {
65            $(navbar).html(rootcategory);
66            categoryMenu(rootcategory);
67        }
68        else {
69            getCategoryMenu(ref, function(data) {
70                $(navbar).html(data);
71                categoryMenu(rootcategory);
72            });
73        }
74
75        return false;
76    });
77}
78
79function compatibility() {
80    var __enforceFocus = $.fn.modal.Constructor.prototype.enforceFocus;
81    $.fn.modal.Constructor.prototype.enforceFocus = function () {
82        if ($('.modal-body .g-recaptcha').length === 0) {
83            __enforceFocus.apply(this, arguments);
84        }
85    };
86}
87function regionsToState(){
88    $('.js-country-select').on('change', function() {
89
90        var result = {};
91        var io = $.evo.io();
92        var country = $(this).find(':selected').val();
93        country = (country !== null && country !== undefined) ? country : '';
94        var connection_id = $(this).attr('id').toString().replace("-country","");
95
96        io.call('getRegionsByCountry', [country], result, function (error, data) {
97            if (error) {
98                console.error(data);
99            } else {
100                var state_id = connection_id+'-state';
101                var state = $('#'+state_id);
102                var state_data = state.data();
103
104                if (typeof(result.response) === 'undefined' || state.length === 0) {
105                    return;
106                }
107                var title = state_data.defaultoption;
108                var stateIsRequired = result.response.required;
109                var data = result.response.states;
110                var def = $('#'+state_id).val();
111                if(typeof(data)!=='undefined'){
112                    if (data !== null && data.length > 0) {
113                        if (stateIsRequired){
114                            var state = $('<select />').attr({ id: state_id, name: state.attr('name'), class: 'custom-select required form-control js-state-select', required: 'required'});
115                        } else {
116                            var state = $('<select />').attr({ id: state_id, name: state.attr('name'), class: 'custom-select form-control js-state-select'});
117                        }
118
119                        Object.keys(state_data).forEach(function(key,index) {
120                            state.data(key,state_data[key]);
121                        });
122
123                        state.append('<option value="">' + title + '</option>');
124                        $(data).each(function(idx, item) {
125                            state.append(
126                                $('<option></option>').val(item.iso).html(item.name)
127                                    .attr('selected', item.iso == def || item.name == def ? 'selected' : false)
128                            );
129                        });
130                        $('#'+state_id).replaceWith(state);
131                    } else {
132                        if (stateIsRequired) {
133                            var state = $('<input />').attr({ type: 'text', id: state_id, name: state.attr('name'),  class: 'required form-control js-state-select', placeholder: title, required: 'required' });
134                        } else {
135                            var state = $('<input />').attr({ type: 'text', id: state_id, name: state.attr('name'),  class: 'form-control js-state-select', placeholder: title });
136                        }
137                        Object.keys(state_data).forEach(function(key,index) {
138                            state.data(key,state_data[key]);
139                        });
140                        $('#'+state_id).replaceWith(state);
141                    }
142                    if (stateIsRequired){
143                        state.parent().find('.state-optional').addClass('d-none');
144                    } else {
145                        state.parent().find('.state-optional').removeClass('d-none');
146                    }
147                }
148            }
149        });
150        return false;
151    }).trigger('change');
152}
153
154function loadContent(url, setCustomAnchorScrolling)
155{
156    $.evo.extended().loadContent(url, function() {
157        $.evo.extended().register();
158
159        if (typeof $.evo.article === 'function') {
160            $.evo.article().onLoad();
161            $.evo.article().register();
162            addValidationListener();
163        }
164
165        let topbarHeight      = $('#header-top-bar').outerHeight() || 0,
166            wrapperHeight     = $('#jtl-nav-wrapper').outerHeight() || 0,
167            productListHeight = $('#product-list').offset().top || 0,
168            pageNavHeight     = $('.productlist-page-nav').outerHeight() || 0;
169
170        if (setCustomAnchorScrolling instanceof Function) {
171            setCustomAnchorScrolling();
172        }
173
174        $('html,body').animate({
175            scrollTop: productListHeight - wrapperHeight - topbarHeight - pageNavHeight - 20
176        }, 100);
177    });
178}
179
180function sanitizeOutput(val) {
181    return val.replace(/\&/g, '&amp;')
182        .replace(/\</g, '&lt;')
183        .replace(/\>/g, '&gt;')
184        .replace(/\"/g, '&quot;')
185        .replace(/\'/g, '&#x27;')
186        .replace(/\//g, '&#x2F;');
187}
188
189function addValidationListener() {
190    var forms      = $('form.jtl-validate'),
191        inputs     = $('form.jtl-validate input, form.jtl-validate textarea').not('[type="radio"],[type="checkbox"]'),
192        selects    = $('form.jtl-validate select'),
193        checkables = $('form.jtl-validate input[type="radio"], form.jtl-validate input[type="checkbox"]'),
194        $body      = $('body');
195
196    for (var i = 0; i < forms.length; i++) {
197        forms[i].addEventListener('invalid', function (event) {
198            event.preventDefault();
199            $(event.target).closest('.form-group').find('div.form-error-msg').remove();
200            $(event.target).closest('.form-group')
201                .addClass('has-error')
202                .append('<div class="form-error-msg w-100">' + sanitizeOutput(event.target.validationMessage) + '</div>');
203
204            if (!$body.data('doScrolling')) {
205                var $firstError = $(event.target).closest('.form-group.has-error');
206                if ($firstError.length > 0) {
207                    $body.data('doScrolling', true);
208                    var $nav        = $('#jtl-nav-wrapper.sticky-top'),
209                        fixedOffset = $nav.length > 0 ? $nav.outerHeight() : 0,
210                        vpHeight    = $(window).height(),
211                        scrollTop   = $(window).scrollTop();
212                    if ($firstError.offset().top > (scrollTop + vpHeight) || $firstError.offset().top < scrollTop) {
213                        $('html, body').animate(
214                            {
215                                scrollTop: $firstError.offset().top - fixedOffset - parseInt($firstError.css('margin-top'))
216                            },
217                            {
218                                done: function () {
219                                    $body.data('doScrolling', false);
220                                }
221                            }, 300
222                        );
223                    }
224                }
225            }
226        }, true);
227    }
228
229    for (var i = 0; i < inputs.length; i++) {
230        inputs[i].addEventListener('blur', function (event) {
231            checkInputError(event);
232        }, true);
233    }
234    for (var i = 0; i < checkables.length; i++) {
235        checkables[i].addEventListener('click', function (event) {
236            checkInputError(event);
237        }, true);
238    }
239    for (var i = 0; i < selects.length; i++) {
240        selects[i].addEventListener('change', function (event) {
241            checkInputError(event);
242        }, true);
243    }
244}
245
246const customAnchorScrollingListener = function customAnchorScrollingListener(event) {
247    const target = event.target.closest('a');
248    if (target && (
249            target.getAttribute('data-toggle') === 'tab'
250            || target.getAttribute('data-toggle') === 'pill'
251            || target.closest('.nav-tabs')
252            || target.closest('.nav-pills')
253            || target.closest('.tab-navigation')
254        )) {
255        return;
256    }
257
258    event.preventDefault();
259    const href = event.target.getAttribute('href');
260    if (href === null) {
261        return false;
262    }
263    $.evo.smoothScrollToAnchor(href);
264};
265
266const setCustomAnchorScrolling = function setCustomAnchorScrolling() {
267    const links = Array.prototype.slice.call(
268        document.querySelectorAll('a'),
269        0
270    );
271    links.filter(el => (el.getAttribute('href') || '').match(/^#/)).forEach(el => {
272        let targetID = el.getAttribute('href').replace(/^#/, '');
273        if (targetID === '') {
274            return false;
275        }
276
277        const scrollTo = document.getElementById(targetID);
278        if (scrollTo) {
279            el.removeEventListener('click', customAnchorScrollingListener);
280            el.addEventListener('click', customAnchorScrollingListener);
281        }
282    });
283};
284
285function checkInputError(event)
286{
287    var $target = $(event.target);
288    if ($target.parents('.cfg-group') != undefined) {
289        $target.parents('.cfg-group').find('div.form-error-msg').remove();
290    }
291    $target.parents('.form-group').find('div.form-error-msg').remove();
292
293    if ($target.data('must-equal-to') !== undefined) {
294        var $equalsTo = $($target.data('must-equal-to'));
295        if ($equalsTo.length === 1) {
296            var theOther = $equalsTo[0];
297            if (theOther.value !== '' && theOther.value !== event.target.value && event.target.value !== '') {
298                event.target.setCustomValidity($target.data('custom-message') !== undefined ? $target.data('custom-message') : sanitizeOutput(event.target.validationMessage));
299            } else {
300                event.target.setCustomValidity('');
301            }
302        }
303    }
304
305    if (event.target.validity.valid) {
306        $target.closest('.form-group').removeClass('has-error');
307    } else {
308        $target.closest('.form-group').addClass('has-error').append('<div class="form-error-msg">' + sanitizeOutput(event.target.validationMessage) + '</div>');
309    }
310}
311
312function captcha_filled() {
313    $('.g-recaptcha').closest('.form-group').find('div.form-error-msg').remove();
314}
315
316function isTouchCapable() {
317    return 'ontouchstart' in window || (window.DocumentTouch && document instanceof window.DocumentTouch);
318}
319
320function initWow()
321{
322    new WOW().init();
323}
324/*
325$(window).load(function(){
326    navigation();
327});*/
328
329$(document).ready(function () {
330    $('.collapse-non-validate')
331        .on('hidden.bs.collapse', function(e) {
332            $(e.target)
333                .addClass('hidden')
334                .find('fieldset, .form-control')
335                .attr('disabled', true);
336            e.stopPropagation();
337        })
338        .on('show.bs.collapse', function(e) {
339            $(e.target)
340                .removeClass('hidden')
341                .attr('disabled', false);
342            e.stopPropagation();
343        }).on('shown.bs.collapse', function(e) {
344            $(e.target)
345                .find('fieldset, .form-control')
346                .filter(function (i, e) {
347                    return $(e).closest('.collapse-non-validate.collapse').hasClass('show');
348                })
349                .attr('disabled', false);
350            e.stopPropagation();
351        });
352    $('.collapse-non-validate.collapse.show')
353        .removeClass('hidden')
354        .find('fieldset, .form-control')
355        .attr('disabled', false);
356    $('.collapse-non-validate.collapse:not(.show)')
357        .addClass('hidden')
358        .find('fieldset, .form-control')
359        .attr('disabled', true);
360
361    $('.collapse.collapse-with-button')
362        .on('show.bs.collapse', function (e) {
363            let btn = $('a[data-toggle="collapse"][href="#' + $(e.target).attr("id") + '"][data-label-show][data-label-hide]');
364            btn.html(btn.data('labelHide'));
365        })
366        .on('hidden.bs.collapse', function (e) {
367            let btn = $('a[data-toggle="collapse"][href="#' + $(e.target).attr("id") + '"][data-label-show][data-label-hide]');
368            btn.html(btn.data('labelShow'));
369        });
370    $('.collapse.collapse-with-clip')
371        .on('shown.bs.collapse', function (e) {
372            $('#clip-text-' + $(e.target).attr("id")).hide();
373        })
374        .on('hide.bs.collapse', function (e) {
375            $('#clip-text-' + $(e.target).attr("id")).show();
376        });
377
378    $('#complete-order-button').on('click', function () {
379        var commentField = $('#comment'),
380            commentFieldHidden = $('#comment-hidden');
381        if (commentField && commentFieldHidden) {
382            commentFieldHidden.val(commentField.val());
383        }
384    });
385
386    $(document).on('click', '.footnote-vat a, .versand, .popup', function(e) {
387        let url     = e.currentTarget.href,
388            classes = $(this).data('modal-classes') || '';
389        url += (url.indexOf('?') === -1) ? '?isAjax=true' : '&isAjax=true';
390        eModal.ajax({
391            size: 'xl ' + classes,
392            url: url,
393            title: typeof e.currentTarget.title !== 'undefined' ? e.currentTarget.title : '',
394            keyboard: true,
395            tabindex: -1,
396            buttons: false
397        });
398        e.stopPropagation();
399        return false;
400    });
401
402    $(document).on('click', '.pagination-ajax a:not(.active), .js-pagination-ajax:not(.active)', function(e) {
403        let url = $(this).attr('href');
404        history.pushState(null, null, url);
405        loadContent(url, setCustomAnchorScrolling);
406        return e.preventDefault();
407    });
408
409    if ($('.js-pagination-ajax').length > 0) {
410        window.addEventListener('popstate', () => {
411            loadContent(document.location.href, setCustomAnchorScrolling);
412        }, false);
413    }
414
415    setCustomAnchorScrolling();
416
417    $('.dropdown .dropdown-menu.keepopen').on('click touchstart', function(e) {
418        e.stopPropagation();
419    },{passive: true});
420
421    if (typeof $.fn.jtl_search === 'undefined') {
422        var productSearch = new Bloodhound({
423            datumTokenizer: Bloodhound.tokenizers.obj.whitespace('keyword'),
424            queryTokenizer: Bloodhound.tokenizers.whitespace,
425            remote:         {
426                url:      $.evo.io().options.ioUrl + '?io={"name":"suggestions", "params":["%QUERY"]}',
427                wildcard: '%QUERY'
428            }
429        });
430
431        let $searchInput = $('input[name="qs"]');
432        $searchInput.typeahead(
433            {
434                highlight: true
435            },
436            {
437                name:      'product-search',
438                display:   'keyword',
439                source:    productSearch,
440                templates: {
441                    suggestion: function (e) {
442                        return e.suggestion;
443                    }
444                }
445            }
446        );
447        $searchInput.on('keydown keyup blur', function () {
448            if ($(this).val().length === 0) {
449                $(this).closest('form').find('.form-clear').addClass('d-none');
450            } else {
451                $(this).closest('form').find('.form-clear').removeClass('d-none');
452            }
453        });
454        $('.search-wrapper .form-clear').on('click', function() {
455            $searchInput.typeahead('val', '');
456            $(this).addClass('d-none');
457        });
458    }
459
460    let citySuggestion = new Bloodhound({
461        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('keyword'),
462        queryTokenizer: Bloodhound.tokenizers.whitespace,
463        remote:         {
464            url:      $.evo.io().options.ioUrl + '?io={"name":"getCitiesByZip", "params":["%QUERY", "'
465                + $(this).closest('fieldset').find('.country-input').val() + '", "'
466                + $(this).closest('fieldset').find('.postcode_input').val() + '"]}',
467            wildcard: '%QUERY'
468        },
469        dataType: "json"
470    });
471
472    let postCodeSuggestion = new Bloodhound({
473        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('keyword'),
474        queryTokenizer: Bloodhound.tokenizers.whitespace,
475        remote:         {
476            url:      $.evo.io().options.ioUrl + '?io={"name":"getZips", "params":["%QUERY", "'
477                + $(this).closest('fieldset').find('.country-input').val() + '", "'
478                + $(this).closest('fieldset').find('.city_input.tt-input').val() + '"]}',
479            wildcard: '%QUERY'
480        },
481        dataType: "json"
482    });
483
484    $('.city_input').on('focusin change', function () {
485        citySuggestion.remote.url = $.evo.io().options.ioUrl + '?io={"name":"getCitiesByZip", "params":["%QUERY", "'
486            + $(this).closest('fieldset').find('.country-input').val() + '", "'
487            + $(this).closest('fieldset').find('.postcode_input.tt-input').val() + '"]}';
488
489        postCodeSuggestion.remote.url = $.evo.io().options.ioUrl + '?io={"name":"getZips", "params":["%QUERY", "'
490            + $(this).closest('fieldset').find('.country-input').val() + '", "'
491            + $(this).val() + '"]}';
492        
493        const oldVal = $(this).closest('fieldset').find('.city_input.tt-input').val();
494        $(this).closest('fieldset').find('.city_input').parent().siblings('label').addClass('focused');
495        $(this).closest('fieldset').find('.city_input')
496            .typeahead('val', '.')
497            .typeahead('val', oldVal);
498    });
499
500    $('.city_input').on('focusout', function () {
501        if ($(this).closest('fieldset').find('.city_input.tt-input').val() == ''){
502            $(this).closest('fieldset').find('.city_input').parent().siblings('label').removeClass('focused');
503        }
504    });
505
506    $('.postcode_input').on('focusin change', function () {
507        postCodeSuggestion.remote.url = $.evo.io().options.ioUrl + '?io={"name":"getZips", "params":["%QUERY", "'
508            + $(this).closest('fieldset').find('.country-input').val() + '", "'
509            + $(this).closest('fieldset').find('.city_input.tt-input').val() + '"]}';
510
511        citySuggestion.remote.url = $.evo.io().options.ioUrl + '?io={"name":"getCitiesByZip", "params":["%QUERY", "'
512            + $(this).closest('fieldset').find('.country-input').val() + '", "'
513            + $(this).val() + '"]}';
514
515        const oldVal = $(this).closest('fieldset').find('.postcode_input.tt-input').val();
516        $(this).closest('fieldset').find('.postcode_input').parent().siblings('label').addClass('focused');
517        $(this).closest('fieldset').find('.postcode_input')
518            .typeahead('val', '.')
519            .typeahead('val', oldVal);
520    });
521
522    $('.postcode_input').on('focusout', function () {
523        if ($(this).closest('fieldset').find('.postcode_input.tt-input').val() == ''){
524            $(this).closest('fieldset').find('.postcode_input').parent().siblings('label').removeClass('focused');
525        }
526    });
527
528    $('.country-input').on('change', function () {
529        citySuggestion.remote.url = $.evo.io().options.ioUrl + '?io={"name":"getCitiesByZip", "params":["%QUERY", "'
530            + $(this).val() + '", "'
531            + $(this).closest('fieldset').find('.postcode_input.tt-input').val() + '"]}';
532
533        postCodeSuggestion.remote.url = $.evo.io().options.ioUrl + '?io={"name":"getZips", "params":["%QUERY", "'
534            + $(this).val() + '", "'
535            + $(this).closest('fieldset').find('.city_input.tt-input').val() + '"]}';
536    });
537
538    $('.postcode_input').typeahead(
539        {
540            hint: true,
541            highlight: true,
542            minLength: 1
543        },
544        {
545            limit:  20,
546            name:   'zipcodes',
547            source: postCodeSuggestion
548        }
549    ).bind('typeahead:select', function() {
550        let cityInput = $(this).closest('fieldset').find('.city_input');
551        if (cityInput.val() === '') {
552            cityInput.trigger('focusin');
553
554            setTimeout(function() {
555                if (cityInput.val() === '') {
556                    let hints = cityInput.typeahead('getHints');
557                    if (hints.length === 1 && hints[0].innerHTML.length > 1) {
558                        cityInput.typeahead('val', hints[0].innerHTML);
559                        cityInput.typeahead('close');
560                        cityInput.trigger('change');
561                    }
562                }
563            }, 1000);
564        }
565    });
566    $('.postcode_input').each(function() {
567        if ($(this).val() !== '') {
568            $(this).trigger('focusin');
569        }
570    });
571
572    $('.city_input').typeahead(
573        {
574            hint: true,
575            highlight: true,
576            minLength: 1
577        },
578        {
579            limit:  20,
580            name:   'cities',
581            source: citySuggestion
582        }
583    );
584    $('.city_input').each(function() {
585        if ($(this).val() !== '') {
586            $(this).trigger('focusin');
587        }
588    });
589
590    $('.btn-offcanvas').on('click', function() {
591        $('body').trigger('click');
592    });
593
594    if ("ontouchstart" in document.documentElement) {
595        $('.variations .swatches .variation').on('mouseover', function() {
596            $(this).trigger('click');
597        });
598    }
599
600    /*
601     * show subcategory on caret click
602     */
603    $('section.box-categories .nav-panel li a').on('click', function(e) {
604        if ($(e.target).hasClass("nav-toggle")) {
605            $(e.delegateTarget)
606                .parent('li')
607                .find('> ul.nav').toggle();
608            return false;
609        }
610    });
611
612    /*
613     * show linkgroup on caret click
614     */
615    $('section.box-linkgroup .nav-panel li a').on('click', function(e) {
616        if ($(e.target).hasClass("nav-toggle")) {
617            $(e.delegateTarget)
618                .parent('li')
619                .find('> ul.nav').toggle();
620            return false;
621        }
622    });
623
624    /*
625     * Banner
626     */
627    var bannerLink = $('.banner > a:not(.empty-popover)');
628    bannerLink.popover({
629        html:      true,
630        placement: 'bottom',
631        trigger:   'hover focus',
632        container: 'body',
633        sanitize: false,
634        template:  	'<div class="popover popover-min-width" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>',
635        content:   function () {
636            return this.nextElementSibling.innerHTML
637        }
638    });
639
640    bannerLink.on('mouseenter focus', function () {
641        $(this).animate({
642            borderWidth: 2,
643            opacity:     0.5
644        }, 300);
645    });
646
647    bannerLink.on('mouseleave blur', function () {
648        $(this).animate({
649            borderWidth: 0,
650            opacity:     1
651        }, 300);
652    });
653
654    $('.banner').on('mouseenter focus', function () {
655        $(this).children('a').animate({
656            borderWidth: 8,
657            opacity:     0
658        }, 900, function () {
659            $(this).css({opacity: 1, borderWidth: 0});
660        });
661    });
662
663    $('.banner > a[href=""]').on('click', function () {
664        return false;
665    });
666
667    /*
668     * alert actions
669     */
670    $('.alert .close').on('click', function (){
671        $(this).parent().fadeOut(1000);
672    });
673
674    $('.alert').each(function(){
675        if ($(this).data('fade-out') > 0) {
676            $(this).fadeOut($(this).data('fade-out'));
677        }
678    });
679
680    /*
681     * margin to last filter-box
682     */
683    $('aside .box[class*=box-filter-]').last().addClass('mb-5');
684
685    /*
686     * set bootstrap viewport
687     */
688    (function($, document, window, viewport){
689        var $body = $('body');
690
691        $(window).on('resize',
692            viewport.changed(function() {
693                $body.attr('data-viewport', viewport.current());
694            })
695        );
696        $body.attr('data-viewport', viewport.current());
697        $body.attr('data-touchcapable', isTouchCapable() ? 'true' : 'false');
698    })(jQuery, document, window, ResponsiveBootstrapToolkit);
699
700
701    $('.onchangeSubmit').on('change', function(){
702        this.form.submit();
703    });
704
705    $('#mobile-search-dropdown').on('click', function() {
706        setTimeout(function(){
707            $('#search-header-desktop').focus();
708        },100);
709    });
710
711    categoryMenu();
712    regionsToState();
713    compatibility();
714    addValidationListener();
715    initWow();
716    setClickableRow();
717
718    document.addEventListener('lazybeforesizes', function(e){
719        //use width of parent node instead of the image width itself
720        var parent = e.target.parentNode;
721
722        if(parent.nodeName == 'PICTURE'){
723            parent = parent.parentNode;
724        }
725        e.detail.width = parent.offsetWidth || e.detail.width;
726    });
727
728    // init auto expand for textareas
729    $('textarea.auto-expand').on('input click', function (event) {
730        autoExpand(event.target);
731    });
732
733    $('input[maxlength][data-chars-left-msg]').on('input', function (event) {
734        let maxLength = $(this).attr('maxlength'),
735            limit     = .1 * maxLength,
736            remaining  = maxLength - $(this).val().length;
737
738        $(this).closest('.form-group').find('.char-left').remove();
739
740        if (remaining <= limit) {
741            $(this).closest('.form-group').append(
742                '<div class="text-warning char-left"><b>' + remaining + '</b> ' + $(this).data('chars-left-msg') + '</div>'
743            );
744        }
745    });
746
747    $('.video-transcript').each(function() {
748        let container = $(this);
749        container.find('[data-toggle="collapse"]').on('click', function() {
750            $(this).attr('aria-expanded', function(i, attr) {
751                return attr === 'true' ? 'false' : 'true'
752            });
753            container.find('.collapse').collapse('toggle');
754        }).on('focus', function() {
755            $(this).parent('.video-transcript').toggleClass('focus');
756        })
757    });
758
759    $('[data-video-transcript]').each(function() {
760        let transcriptElement = $(this);
761
762        transcriptElement.on('click', function (e) {
763            e.preventDefault();
764            let content = transcriptElement.data('video-transcript');
765            if (content !== '') {
766                let popup = window.open(
767                    '',
768                    'TranscriptWindow',
769                    'width=600, height=400, scrollbars=yes'
770                );
771                $(popup.document.body).html(content);
772            }
773        });
774    });
775
776    $('.cart-icon-dropdown').on('show.bs.dropdown', function() {
777        const $topBar = $('#header-top-bar');
778        let maxMiniCartHeight = $(window).height()
779            - ($('header').outerHeight() || 0)
780            - 12;
781        if ($topBar.length && $topBar.isInViewport()) {
782            maxMiniCartHeight -= $topBar.outerHeight();
783        }
784        $(this).find('.dropdown-menu').css({maxHeight: maxMiniCartHeight});
785    });
786});
787
788function setClickableRow()
789{
790    $('.clickable-row').off().on('click', function() {
791        window.location = $(this).data('href');
792    });
793}
794
795function isMobileByBodyClass() {
796    return $('body').hasClass('is-mobile');
797}
798
799function autoExpand(field) {
800    field.style.height = 'inherit';
801
802    let computed = window.getComputedStyle(field),
803        height = parseInt(computed.getPropertyValue('border-top-width'), 10)
804            + parseInt(computed.getPropertyValue('padding-top'), 10)
805            + field.scrollHeight
806            + parseInt(computed.getPropertyValue('padding-bottom'), 10)
807            + parseInt(computed.getPropertyValue('border-bottom-width'), 10);
808
809    field.style.height = height + 'px';
810}
811
812$.fn.isInViewport = function() {
813    let elementTop = $(this).offset().top;
814    let elementBottom = elementTop + $(this).outerHeight();
815
816    let viewportTop = $(window).scrollTop();
817    let viewportBottom = viewportTop + $(window).height();
818
819    return elementBottom > viewportTop && elementTop < viewportBottom;
820};

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.