PageSourceSearch

https://www.siblider.ru/local/templates/main/js/main.js?178542301753075

js siblider.ru collected 2026-09-30 17:48:05 UTC 53,075 bytes, 1,564 lines download raw bytes

1$(document).ready(function() {
2    // Свитчер в карточке квартиры
3
4    var $flatImg = $('.js-flat-img[data-img-for="flat"]');
5    var $flatLinks = $('.js-flat__photo-link[data-img-for="flat"]');
6    var $floorImg = $('.js-flat-img[data-img-for="floor"]');
7    var $floorLinks = $('.js-flat__photo-link[data-img-for="floor"]');
8
9    $('.js-flat-img-switcher').on('change', function() {
10        var isChecked = !!$(this).prop('checked');
11
12        if (isChecked) {
13            $flatImg.addClass('flat-img--active');
14            $flatLinks.removeClass('flat__photo-link--hidden');
15
16            $floorImg.removeClass('flat-img--active');
17            $floorLinks.addClass('flat__photo-link--hidden');
18        } else {
19            $floorImg.addClass('flat-img--active');
20            $floorLinks.removeClass('flat__photo-link--hidden');
21
22            $flatImg.removeClass('flat-img--active');
23            $flatLinks.addClass('flat__photo-link--hidden');
24        }
25    });
26
27    // Reveal elements on entering viewport. WOW.js баганный, если элемент скрыт во внутреннем диве - анимация не срабатывает
28    if (window.IntersectionObserver) {
29        var observer = new IntersectionObserver(function(entries) {
30            entries.forEach(function(entry) {
31                if (entry.isIntersecting) {
32                    var $target = $(entry.target);
33                    var animationName = $target.data('reveal-animation') || 'fadeInLeft';
34                    var delay = $target.data('reveal-delay') || '0.2';
35
36                    setTimeout(function() {
37                        $target.addClass(animationName + ' ' + 'js-reveal--completed');
38                    }, parseFloat(delay) * 1000);
39
40                    observer.unobserve(entry.target);
41                }
42            });
43        });
44
45        $('.js-reveal').each(function() {
46            observer.observe(this);
47        });
48    } else {
49        $('.js-reveal').each(function() {
50            var $target = $(this);
51            var animationName = $target.data('reveal-animation') || 'fadeInLeft';
52            $target.addClass(animationName + ' ' + 'js-reveal--completed');
53        });
54    }
55
56    $('#backBtn').click(function(){
57        window.history.back();
58        return false;
59    });
60
61    new WOW({
62        offset: 100,
63    }).init();
64
65	$('#menuOpenBtn, #mobileBurger').on('click', function() {
66		if (this.id === 'mobileBurger' && !$('#menu').hasClass('is-hidden')) {
67			$('#menuCloseBtn').trigger('click');
68			return;
69		}
70		$('#menu').removeClass('is-hidden');
71		setTimeout(function(){
72			$('#menuLeft').removeClass('animation-start');
73			$('#menuRight').removeClass('animation-start');
74		}, 50);
75	});
76
77	$('#menuCloseBtn').on('click', function() {
78		$('#menuLeft').addClass('animation-start');
79		$('#menuRight').addClass('animation-start');
80		setTimeout(function(){
81			$('#menu').addClass('is-hidden');
82		}, 500);
83	});
84
85    //закрытие меню на esc
86    $(window).keydown(function(event) {
87        if (event.which == 27) {
88            if (!$('#menu').hasClass('is-hidden')) {
89                $('#menuCloseBtn').click();
90            }
91        }
92    });
93
94    setTimeout(function(){
95        if (($('.page--main').length || $('.page--fixed').length) && $(window).width() > 1000) {
96            $('body').addClass('overflow-hidden');
97        }
98    }, 20);
99
100    $(window).resize(function(){
101        if (($('.page--main').length || $('.page--fixed').length) && $(window).width() > 1000) {
102            $('body').addClass('overflow-hidden');
103        } else if (($('.page--main').length || $('.page--fixed').length) && $(window).width() <= 1000) {
104            $('body').removeClass('overflow-hidden');
105        }
106    });
107
108    $('input').blur(function() {
109        if (this.value != '') {
110            $(this).parents('label').addClass('is-filled');
111            $(this).parents('label').removeClass('is-active');
112        } else {
113            $(this).parents('label').removeClass('is-filled');
114            $(this).parents('label').removeClass('is-active');
115        }
116    });
117    $('textarea').blur(function() {
118        if (this.value != '') {
119            $(this).parents('label').addClass('is-filled');
120            $(this).parents('label').removeClass('is-active');
121        } else {
122            $(this).parents('label').removeClass('is-filled');
123            $(this).parents('label').removeClass('is-active');
124        }
125    });
126
127    $('.input--phone').keyup(function(){
128        if($(this).val() == '+7 (8'){
129            $(this).val('+7');
130        }
131    });
132    $('.input--phone').mask('+7 (000) 000-00-00', {
133        onKeyPress: function(val, e, field, options){
134            console.log(val, e, field, options);
135        },
136    });
137
138    $('input').focus(function() {
139        $(this).parents('label').addClass('is-active');
140    });
141
142    $('textarea').focus(function() {
143        $(this).parents('label').addClass('is-active');
144    });
145
146    $('.js-inputfile').on('change',function(){
147      if($(this).get(0).files.length > 0){
148        var filesSize = 0,
149            maxSize = parseInt($(this).data('max-size'),10);
150        for (var i = 0; i < $(this).get(0).files.length; i ++) {
151            var fileSize = $(this).get(0).files[i].size;
152            filesSize += fileSize;
153        }
154
155        if (maxSize >= filesSize) {
156            $(this).prev().removeClass('is-unvalid');
157            $(this).removeClass('is-unvalid');
158        } else {
159            $(this).prev().addClass('is-unvalid');
160            $(this).addClass('is-unvalid');
161        }
162      }
163    });
164
165    $('.js-inputfile').each( function() {
166        var input = $(this),
167            label = input.parents('label'),
168            labelVal = label.html();
169
170        input.on( 'change', function(e) {
171            var fileName = '';
172            if (this.files && this.files.length > 1) {
173                fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
174            }
175            else if (e.target.value) {
176                fileName = e.target.value.split( '\\' ).pop();
177            }
178
179            if (fileName) {
180                label.find( 'div.js-file-label' ).html( fileName );
181            }
182            else {
183                label.html( labelVal );
184            }
185        });
186
187        // Firefox bug fix
188        input
189        .on( 'focus', function(){ input.addClass( 'has-focus' ); })
190        .on( 'blur', function(){ input.removeClass( 'has-focus' ); });
191    });
192
193    $(document).on('click', '.js-button-add-more', function(e) {
194        var self = $(this);
195        self.addClass('is-loading');
196        var target = self;
197        if(self.parent().hasClass('js-button-add-more-parent')){
198            target = self.parent();
199        }
200
201        var opt = {
202            url: window.location.href,
203            dataType: 'html',
204            data: {
205                PAGEN_1: self.data('page'),
206                AJAX_REQUEST: 'Y'
207            },
208            successCallback: function(response){
209                target.replaceWith(response);
210            },
211        };
212        ajaxRequest(opt);
213
214       return false;
215    });
216
217    $('.js-scroll-to-link').on('click', function(e){
218        e.preventDefault();
219        var id = $(this).attr('href'),
220            offset = $(id).offset().top - $('.page-header').height();
221        $('body, html').animate({scrollTop: offset}, 500);
222    });
223
224    $('#selectObject').change(function(){
225        var id = $(this).val();
226        var form = $('#filterForm');
227        var list = $('#tableList');
228        var building = $('#building');
229        var map = $('.map-wrapper');
230        var mapBtn = $('#fancyMap');
231        var sort = [
232            {name: 'PROPERTY_E_HOUSE', value: 'ASC'},
233            {name: 'PROPERTY_N_PRICE', value: 'ASC'},
234        ]
235        var data = {
236            house_id: id,
237            action: 'flats',
238            AJAX_REQUEST: 'Y',
239            filter: form.data('file'),
240            list: list.data('file'),
241            building: building.data('file'),
242            map: mapBtn.data('file'),
243            flats_type: $('.js-flatType').val(),
244            status_active: 'Y',
245            SORT: sort
246        };
247
248        $('#tableContent').addClass('is-changed');
249
250        var opt = {
251            url: '/local/ajax/flats.php',
252            dataType: 'json',
253            data: data,
254            successCallback: function(response){
255                if(response['map'] == false){
256                    mapBtn.hide();
257                }else{
258                    map.html(response['map']);
259                    mapBtn.show();
260                }
261
262                form.html(response['filter']);
263                list.html(response['list']);
264                building.html(response['building']);
265                $('#tableContent').removeClass('is-changed');
266                $('.js-flatCount').text(response['count']);
267                initFancyBox();
268
269                if(window.initSortTables !== undefined){
270                    window.initSortTables('[data-sort-ajax-table]');
271                }
272            },
273        };
274        ajaxRequest(opt);
275    });
276
277    $(document).on('change', '#filterForm :checkbox', function(){
278        $('#filterForm').submit();
279    });
280
281    $('#filterForm').submit(function(){
282        var id = $('#selectObject').val(),
283            form = $(this),
284            data = form.serializeArray(),
285            list = $('#tableList'),
286            building = $('#building'),
287            opt = {
288                url: '/local/ajax/flats.php',
289                dataType: 'json',
290                data: data,
291                successCallback: function(response){
292                    list.html(response['list']);
293                    building.html(response['building']);
294                    $('#tableContent').removeClass('is-changed');
295                    $('.js-flatCount').text(response['count']);
296                    initFancyBox();
297                    if(window.initSortTables !== undefined){
298                        window.initSortTables('[data-sort-ajax-table]');
299                    }
300                },
301            };
302
303        data.push({name: 'house_id', value: id});
304        data.push({name: 'action', value: 'flats'});
305        data.push({name: 'AJAX_REQUEST', value: 'Y'});
306        data.push({name: 'filter', value: form.data('file')});
307        data.push({name: 'list', value: list.data('file')});
308        data.push({name: 'building', value: building.data('file')});
309
310        $('#tableContent').addClass('is-changed');
311        ajaxRequest(opt);
312
313        return false;
314    });
315});
316
317function checkField(input){
318    checkFieldsError = 0;
319    if ($(input).val() == ''){
320        checkFieldsError = 1;
321        $(input).addClass('is-unvalid');
322    } else if (input.validity.patternMismatch) {
323        checkFieldsError = 1;
324        $(input).addClass('is-unvalid');
325    } else {
326        $(input).removeClass('is-unvalid');
327    }
328    return checkFieldsError;
329}
330
331function setPosition(container) {
332	$(container).each(function(i){
333		var imgObj = $(this),
334            yPos = 0;
335        yPos = imagesArray[i].offsetLeft - ($(window).scrollTop() + window.innerHeight) * imagesArray[i].speed;
336        if ($(window).width() < 1000) {
337            yPos = imagesArray[i].offsetLeft - ($(window).scrollTop() + window.innerHeight) * (imagesArray[i].speed / 2);
338        }
339		imgObj.css({ transform: 'translate3d(' + yPos + 'px, 0, 0)' });
340        console.log('set position func', imgObj)
341	});
342}
343function initParallax() {
344    console.log('inside init function')
345	getPosition('.js-parallax-img');
346	setPosition('.js-parallax-img');
347}
348
349function getPosition(container) {
350	imagesArray = [];
351	$(container).each(function(i, elem){
352        setWidth($(this));
353		var offsetLeft = 0,
354            offsetTop = 0,
355            speed = setSpeed($(this)),
356            box = $(this)[0].getBoundingClientRect(),
357            offsetTop = box.top,
358            offsetLeft = ($(window).scrollTop() + offsetTop) * speed;
359        if ($(window).width() < 1000) {
360            offsetLeft = ($(window).scrollTop() + offsetTop) * (speed / 2);
361        }
362		var object = {
363			image: elem,
364			offsetLeft: offsetLeft,
365			offsetTop: offsetTop,
366			speed: speed
367		};
368		imagesArray.push(object);
369	});
370}
371
372function setWidth(elem) {
373    var parentWidth = elem.parent().outerWidth(),
374        windowHeight = $(window).height();
375    if($(window).width() <= 1920){
376        elem.css('width', parentWidth + (windowHeight / 5));
377    }else{
378        elem.css('width', parentWidth + (windowHeight / 2));
379    }
380}
381
382function setSpeed(elem) {
383	var parentWidth = elem.parent().outerWidth(),
384		thisWidth = elem.outerWidth(),
385		speed = (thisWidth - parentWidth) / (parentWidth * elem.data('speed') * 0.9) * elem.data('direction');
386    if ($(window).width() <= 1280 && $(window).width() > 1000) {
387        speed = (thisWidth - parentWidth) / (parentWidth * elem.data('speed') * 1.5) * elem.data('direction');
388    }
389	return speed;
390}
391
392function filterChooseFlat() {
393	//before
394	$('#tableContent').addClass('is-changed');
395
396	//TODO: загрузка контента
397
398	//after
399    //setTimeout для демонстрации загрузки
400	setTimeout(function(){
401	    $('#tableContent').removeClass('is-changed');
402	}, 2000);
403}
404
405function filterObject() {
406	$('#objectFlats').addClass('is-changed');
407    var form = $('#filterForm_detail');
408    var data = form.serializeArray();
409
410    var target = $('.js-flatsList');
411    var opt = {
412        url: '/local/ajax/flats.php',
413        dataType: 'json',
414        data: data,
415        successCallback: function(response){
416            target.html(response.flats);
417            $('.choose-flat__counter span').text(response.items.length);
418            $('.js-flatH1').html('Цены от ' + response.price.min);
419            $('#objectFlats').removeClass('is-changed');
420            initFancyBox();
421        },
422    };
423
424    ajaxRequest(opt);
425}
426
427function filterMortgage() {
428    var cost = parseInt(document.getElementById('rangeCost').noUiSlider.get().replace(/\s/g,'')),
429        contribution = parseInt(document.getElementById('rangeContribution').noUiSlider.get().replace(/\s/g,'')),
430        time = document.getElementById('rangeTime').noUiSlider.get(),
431        age = document.getElementById('rangeAge').noUiSlider.get(),
432        credit = cost - contribution;
433
434    $('#creditAmount').text(number_format(credit, 0, '.', ' '));
435    $('#mortgageContainer').addClass('is-changed');
436
437    var target = $('#mortgageList');
438    var data = {
439        AJAX_REQUEST: 'Y',
440        CREDIT: credit,
441        TYPE: $('#selectLendingType').val(),
442        AGE: age,
443        TIME: time
444    };
445    var opt = {
446        url: window.location.href,
447        dataType: 'html',
448        data: data,
449        successCallback: function(response){
450            target.html(response);
451            $('#mortgageContainer').removeClass('is-changed');
452        },
453    };
454    ajaxRequest(opt);
455}
456
457function initSelect2(container, parent) {
458    if (parent == undefined) {
459        parent = $('body');
460    }
461    container.each(function(){
462        var placeholder = '',
463            isTags = false,
464            tagsClass = '';
465
466        if($(this).attr('data-placeholder') !== undefined){
467            placeholder = $(this).attr('data-placeholder');
468        }
469        if($(this).attr('data-tags') !== undefined && $(this).attr('data-tags') == "true"){
470            isTags = $(this).attr('data-tags');
471            tagsClass = 'is-tags';
472        }
473        $(this).select2({
474            minimumResultsForSearch: -1,
475            allowClear: false,
476            tags: isTags,
477            placeholder: placeholder,
478            disabled: false,
479            dropdownParent: parent,
480            containerCssClass: 'custom-select__select',
481            dropdownCssClass: 'custom-select__dropdown ' + tagsClass,
482        });
483    });
484}
485
486function initFancyBox(){
487    $('[data-fancybox]').fancybox({
488        overlayShow: false,
489        arrows: false,
490        infobar: false,
491        keyboard: true,
492        touch:false,
493        toolbar: false,
494        animationEffect: 'fade',
495        animationDuration: 1000,
496        transitionDuration: 1000,
497        baseClass: 'fancyBox-base',
498        slideClass: 'fancyBox-slide',
499        beforeClose: function( instance, current ) {
500            $('#successMessage').hide();
501        },
502        afterClose: function( instance, current ){
503            $(current.src).find('.modal__title').show();
504        }
505    });
506    $('[data-fancybox="image"], [data-fancybox="video"], [data-fancybox="floorPlan"]').fancybox({
507        overlayShow: false,
508        arrows: false,
509        infobar: false,
510        keyboard: true,
511        touch:false,
512        toolbar: true,
513        animationEffect: "fade",
514        animationDuration: 1000,
515        transitionDuration: 1000,
516        baseClass: 'fancyBox-base  fancyBox-base--fixed',
517        slideClass: 'fancyBox-slide',
518        buttons: [
519            "zoom",
520            "fullScreen",
521            "close"
522        ]
523    });
524    $('[data-fancybox="map"], [data-fancybox="filter"]').fancybox({
525        overlayShow: false,
526        arrows: false,
527        infobar: false,
528        keyboard: true,
529        touch:false,
530        toolbar: false,
531        animationEffect: "fade",
532        animationDuration: 1000,
533        transitionDuration: 1000,
534        baseClass: 'fancyBox-base fancyBox-base--fixed',
535        slideClass: 'fancyBox-slide'
536    });
537};
538initFancyBox();
539
540function initNoUiSliderTwoPoint(container) {
541    noUiSlider.create(container, {
542        start: [parseInt(container.getAttribute('data-min')), parseInt(container.getAttribute('data-max'))],
543        connect: false,
544        step: parseInt(container.getAttribute('data-step')),
545        range: {
546            'min': parseInt(container.getAttribute('data-min')),
547            'max': parseInt(container.getAttribute('data-max'))
548        },
549        format: wNumb({
550            decimals: 0,
551            thousand: ' '
552        })
553    });
554}
555
556function initNoUiSliderOnePoint(container) {
557    noUiSlider.create(container, {
558        start: [parseInt(container.getAttribute('data-start'))],
559        connect: false,
560        step: parseInt(container.getAttribute('data-step')),
561        range: {
562            'min': parseInt(container.getAttribute('data-min')),
563            'max': parseInt(container.getAttribute('data-max'))
564        },
565        format: wNumb({
566            decimals: 0,
567            thousand: ' '
568        })
569    });
570}
571
572function getYearSurfix(year){
573	var mod = year % 10;
574	if (year > 10 && year < 15) {return '  лет'}
575	if (mod == 1) {return '  год'}
576	if (mod > 1 && mod < 5) {return '  года'}
577	if (mod >= 5 && mod <= 9 || mod == 0) {return '  лет'}
578}
579
580function ajaxRequest(opt){
581    opt.dataType = opt.dataType ? opt.dataType : 'json';
582    opt.method = opt.method ? opt.method : 'post';
583    opt.success = opt.successCallback ? opt.successCallback : function(response){console.log(response)};
584    opt.error = function(response){console.error(response);};
585    $.ajax(opt);
586};
587
588function number_format(number, decimals, dec_point, thousands_sep){
589    var i, j, kw, kd, km;
590
591    if( isNaN(decimals = Math.abs(decimals)) ){
592        decimals = 2;
593    }
594    if( dec_point == undefined ){
595        dec_point = ",";
596    }
597    if( thousands_sep == undefined ){
598        thousands_sep = ".";
599    }
600
601    i = parseInt(number = (+number || 0).toFixed(decimals)) + "";
602
603    if( (j = i.length) > 3 ){
604        j = j % 3;
605    } else{
606        j = 0;
607    }
608
609    km = (j ? i.substr(0, j) + thousands_sep : "");
610    kw = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep);
611    kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).replace(/-/, 0).slice(2) : "");
612
613    return km + kw + kd;
614}
615
616
617
618;(function(){
619    var SortTable = function(table){
620        var API = {},
621            setting = {};
622
623        if(table == null || table == undefined){return}
624
625        function _checkOption(option, defaultValue){
626            if(defaultValue == undefined){
627                defaultValue = null;
628            };
629            return option ? option : defaultValue;
630        };
631
632        function init(){
633            setting.valueAttribute = 'data-sort-value';
634            setting.buttonAttribute = 'data-sort-button';
635            setting.sectionSelector = '[data-sort-section]';
636            setting.buttonSelector = '[' + setting.buttonAttribute + ']';
637            setting.rowSelector = '[data-sort-row]';
638
639            setting.sortDirection = 1;
640            if(table.getAttribute('data-sort-direction') !== null){
641                setting.sortDirection *= table.getAttribute('data-sort-direction');
642            }
643
644            setting.tableSections = table.querySelectorAll(setting.sectionSelector);
645            setting.tableButtons = table.querySelectorAll(setting.buttonSelector);
646
647            setEvents();
648            setButtonState();
649        };
650
651        function update(){
652            setting.tableSections = table.querySelectorAll(setting.sectionSelector);
653            setting.tableButtons = table.querySelectorAll(setting.buttonSelector);
654
655            setting.sortDirection = 1;
656        }
657
658        function getSortedRows(section, sortParam){
659            var rows = Array.from(section.querySelectorAll(setting.rowSelector)),
660                sortedRows,
661                cellSelector = '[data-sort-' + sortParam + ']'
662
663
664            sortedRows = rows.sort(function(a, b){
665                var aValue, bValue;
666
667                aValue = a.querySelector(cellSelector).getAttribute(setting.valueAttribute);
668                bValue = b.querySelector(cellSelector).getAttribute(setting.valueAttribute);
669
670                return (aValue - bValue) * setting.sortDirection;
671            });
672            return sortedRows;
673        };
674
675        function sortTable(sortParam){
676            for (var i = 0; i < setting.tableSections.length; i++) {
677                var sortedRows = getSortedRows(setting.tableSections[i], sortParam);
678
679                setting.tableSections[i].innerHTML = '';
680                setting.tableSections[i].append(...sortedRows);
681            }
682
683        };
684
685        function setButtonState(){
686            if(setting.sortDirection < 0) {
687                setting.tableButtons[0].classList.add('is-reverse')
688            }
689            else {
690                setting.tableButtons[0].classList.remove('is-reverse')
691            }
692        }
693
694        function onButtonClick(event){
695            event.preventDefault();
696            var sortParam = this.getAttribute(setting.buttonAttribute);
697
698            sortTable(sortParam);
699            setting.sortDirection *= -1;
700
701            setButtonState();
702        };
703
704        function setEvents(){
705            for (var i = 0; i < setting.tableButtons.length; i++) {
706                setting.tableButtons[i].addEventListener('click', onButtonClick);
707            }
708        };
709
710        init();
711
712        API.update = update;
713        return API;
714    }
715
716
717    function initSortTables(selector){
718        var tables,
719            tableSelector = '[data-sort-table]';
720
721        if(selector !== undefined && typeof selector === 'string'){
722            tableSelector = selector;
723        }
724
725        tables = document.querySelectorAll(tableSelector);
726
727        for (var i = 0; i < tables.length; i++) {
728            var sortTable = new SortTable(tables[i]);
729            tables[i].instance = sortTable;
730        }
731
732    }
733    initSortTables();
734
735    window.SortTable = SortTable;
736    window.initSortTables = initSortTables;
737})();
738
739
740(function(){
741    var flatContainers = document.querySelectorAll('.js-flat-slider');
742
743    flatContainers.forEach(function(flatContainer){
744        var flatSldier = new Swiper(flatContainer, {
745            slidesPerView: 3,
746            breakpoints: {
747                960: {
748                    slidesPerView: 2,
749                },
750                620: {
751                    slidesPerView: 1,
752                }
753            },
754            navigation: {
755                nextEl: flatContainer.querySelector('.js-slide-next'),
756                prevEl: flatContainer.querySelector('.js-slide-prev'),
757            },
758            pagination: {
759                el: flatContainer.querySelector('.js-slide-dots'),
760                type: 'bullets',
761                clickable: true,
762                bulletClass: 'dots__item',
763                bulletActiveClass: 'is-active',
764                renderBullet: function(index, className){
765                    return '<div class="' + className + '"></div>'
766                }
767            },
768        });
769    });
770})();
771
772document.addEventListener('DOMContentLoaded', function(event){
773    var sliderContainers = document.querySelectorAll('.js-build-gallery');
774
775    initBuildSlider(sliderContainers);
776
777    function initBuildSlider(sliderContainers){
778        sliderContainers.forEach(function(sliderContainer){
779            var currentSlideIndex = 0,
780                isDragged = false,
781                currentBullet = 0,
782                bulletStatus = 0,
783                slider,
784                sliderWrap = $(sliderContainer).find('.slider__wrap'),
785                sliderCurtain = $(sliderContainer).find('.js-slider-curtain'),
786                sliderDots = $(sliderContainer).find('.js-build-gallery-dots');
787
788            slider = new Swiper(sliderContainer, {
789                speed: 1100,
790                effect: 'fade',
791                fadeEffect: {
792                    crossFade: true
793                },
794                loop: true,
795                longSwipes: false,
796                longSwipesMs: '100ms',
797                pagination: {
798                    el: sliderDots,
799                    type: 'bullets',
800                    bulletClass: 'slider__bullet',
801                    renderBullet: function (index, className) {
802                        var bulletTitle = this.slides[index + this.loopedSlides].getAttribute('data-title');
803                        if(bulletTitle === null){
804                            bulletTitle = '';
805                        }
806                        return '<span class="' + className + '">' + bulletTitle + '</span>';
807                    },
808                    bulletActiveClass: 'is-active',
809                    clickable: true
810                },
811                on: {
812                    init: function() {
813                        var self = this;
814
815                        $(sliderContainer).find('.js-slider-prev').on('click', function(){
816                            if (!isDragged) {
817                                sliderWrap.addClass('animateCurtain-to-right');
818                                self.slidePrev(1100);
819                                setTimeout(function(){
820                                    sliderWrap.addClass('animateCurtain-hide-to-right');
821                                    setTimeout(function(){
822                                        sliderWrap.removeClass('animateCurtain-hide-to-right').removeClass('animateCurtain-to-right');
823                                        self.allowSlideNext = true;
824                                        self.allowSlidePrev = true;
825                                        self.allowTouchMove = true;
826                                        isDragged = false;
827                                    }, 500);
828                                }, 600);
829                            }
830                            if (self != undefined) {
831                                self.allowSlideNext = false;
832                                self.allowSlidePrev = false;
833                                self.allowTouchMove = false;
834                            }
835                        });
836
837                        $(sliderContainer).find('.js-slider-next').on('click', function(){
838                            if (!isDragged) {
839                                sliderWrap.addClass('animateCurtain-to-left');
840                                self.slideNext(1100);
841                                setTimeout(function(){
842                                    sliderWrap.addClass('animateCurtain-hide-to-left');
843                                    setTimeout(function(){
844                                        sliderWrap.removeClass('animateCurtain-hide-to-left').removeClass('animateCurtain-to-left');
845                                        self.allowSlideNext = true;
846                                        self.allowSlidePrev = true;
847                                        self.allowTouchMove = true;
848                                        isDragged = false;
849                                    }, 500);
850                                }, 600);
851                            }
852                            if (self != undefined) {
853                                self.allowSlideNext = false;
854                                self.allowSlidePrev = false;
855                                self.allowTouchMove = false;
856                            }
857                        });
858                    },
859                    paginationRender: function() {
860                        var self = this;
861                        $(sliderContainer).find('.slider__bullet').on('click', function(){
862                            if (currentBullet < $(this).index()) {
863                                if (!isDragged) {
864                                    sliderWrap.addClass('animateCurtain-to-left');
865                                    setTimeout(function(){
866                                        sliderWrap.addClass('animateCurtain-hide-to-left');
867                                        setTimeout(function(){
868                                            sliderWrap.removeClass('animateCurtain-hide-to-left').removeClass('animateCurtain-to-left');
869                                            self.allowSlideNext = true;
870                                            self.allowSlidePrev = true;
871                                            self.allowTouchMove = true;
872                                            isDragged = false;
873                                        }, 500);
874                                    }, 600);
875                                }
876                                bulletStatus = 1;
877                            } else {
878                                if (!isDragged) {
879                                    sliderWrap.addClass('animateCurtain-to-right');
880                                    setTimeout(function(){
881                                        sliderWrap.addClass('animateCurtain-hide-to-right');
882                                        setTimeout(function(){
883                                            sliderWrap.removeClass('animateCurtain-hide-to-right').removeClass('animateCurtain-to-right');
884                                            self.allowSlideNext = true;
885                                            self.allowSlidePrev = true;
886                                            self.allowTouchMove = true;
887                                            isDragged = false;
888                                        }, 500);
889                                    }, 600);
890                                }
891                                bulletStatus = 2;
892                            }
893
894                            currentBullet = $(this).index();
895
896                        });
897                    },
898                    touchStart: function(touchstart){
899                        isDragged = true;
900                    },
901                    touchMove: function(touchMove) {
902                        var self = this,
903                            nextCurtainXOffset,
904                            curtainWidth = sliderCurtain.width() / 2;
905
906                        if (self.touches.diff > 0) {
907                            nextCurtainXOffset = curtainWidth - self.touches.diff;
908                        }
909                        else {
910                            nextCurtainXOffset = -curtainWidth - self.touches.diff;
911                        }
912
913                        sliderCurtain.css('transform', 'translate3d(' + nextCurtainXOffset + 'px, 0, 0)');
914                    },
915                    touchEnd: function(touchEnd){
916                        var self = this;
917
918                        if (self.touches.diff > 0) {
919                            sliderCurtain.css('transform', 'translate3d(-100%, 0, 0)').css('transition', 'transform 1s cubic-bezier(.55, .13, .46, .85)');
920                        }
921                        else if (self.touches.diff < 0) {
922                            sliderCurtain.css('transform', 'translate3d(100%, 0, 0)').css('transition', 'transform 1s cubic-bezier(.55, .13, .46, .85)');
923                        }
924                        else {
925                            isDragged = false;
926                        }
927
928                        setTimeout(function(){
929                            sliderCurtain.css('transition', 'unset');
930                            isDragged = false;
931                        }, 1000);
932                    },
933                    slideChange: function(e){
934                        var offset = 0,
935                            activeBullet,
936                            activeBulletLeft,
937                            sliderDotsScrollLeft;
938
939                        activeBullet = sliderDots.find('.is-active');
940
941                        if(!activeBullet.length){return}
942
943                        activeBulletLeft = activeBullet.position().left;
944                        sliderDotsScrollLeft = sliderDots.scrollLeft();
945
946                        if (activeBullet.length) {
947                            if (bulletStatus == 1) {
948                                offset = sliderDotsScrollLeft + activeBulletLeft;
949                            }
950                            else if (bulletStatus == 2) {
951                                offset = sliderDotsScrollLeft + activeBulletLeft - sliderDots.width() + activeBullet.outerWidth();
952                            }
953                            else {
954                                offset = sliderDotsScrollLeft + activeBulletLeft;
955                            }
956                            currentBullet = activeBullet.index();
957                        }
958                        sliderDots.animate({scrollLeft: offset}, 500);
959                    },
960                }
961            });
962
963        });
964    }
965});
966/*Функция для работы с cookies*/
967  function setCookiePreference(preference) {
968      localStorage.setItem('allow_cookie', preference);
969      document.getElementById('cookieNotification').style.display = 'none';
970    }
971
972    window.onload = function() {
973      const cookiePreference = localStorage.getItem('allow_cookie');
974      if (!cookiePreference || cookiePreference === 'essential') {
975        document.getElementById('cookieNotification').style.display = 'flex';
976      }
977    };
978  function setCookiePreference(preference) {
979      localStorage.setItem('allow_cookie', preference);
980      document.getElementById('cookieNotification').style.display = 'none';
981    }
982
983    window.onload = function() {
984      const cookiePreference = localStorage.getItem('allow_cookie');
985      if (!cookiePreference || cookiePreference === 'essential') {
986        document.getElementById('cookieNotification').style.display = 'flex';
987      }
988    };
989
990/*функция для добавления отступов */
991document.addEventListener('DOMContentLoaded', () => {
992    if (document.querySelector('.aside')) {
993        document.querySelector('#breadcrumbs').style.paddingLeft = '159px';
994    }
995});
996
997
998
999
1000
1001
1002
1003
1004
1005/*Функция для добавления двух разных баннеров для десктопа и мобильного разрешения*/
1006
1007
1008document.addEventListener('DOMContentLoaded', function() {
1009  function updateBackgrounds() {
1010    document.querySelectorAll('.sliderWrapper').forEach(wrapper => {
1011      const desktop = wrapper.dataset.desktop;
1012      const mobile = wrapper.dataset.mobile;
1013      
1014      if (window.innerWidth <= 768 && mobile) {
1015        wrapper.style.backgroundImage = `url('${mobile}')`;
1016      } else if (desktop) {
1017        wrapper.style.backgroundImage = `url('${desktop}')`;
1018      }
1019    });
1020  }
1021  
1022  updateBackgrounds();
1023  window.addEventListener('resize', updateBackgrounds);
1024});
1025
1026
1027document.addEventListener('DOMContentLoaded', function() {
1028    // Проверка, что это НЕ главная страница
1029    if (window.location.pathname !== '/' && window.location.pathname !== '/index.php' && window.location.pathname !== '/index.html') {
1030        
1031        function _toConsumableArray(arr) {
1032            if (Array.isArray(arr)) return arr;
1033            if (Symbol.iterator in Object(arr)) return Array.from(arr);
1034            throw new TypeError("Invalid attempt to spread non-iterable instance.");
1035        }
1036
1037        var objectsMenu = document.querySelector(".objects");
1038        var additionallyMenu = document.querySelector(".additionally");
1039        var header = document.querySelector("header");
1040        var menuTitles = _toConsumableArray(document.querySelectorAll(".menuTitle"));
1041        var objectsArrow = document.querySelector(".objects_li img");
1042        var additionallyArrow = document.querySelector(".additionally_li img");
1043        
1044        var style = document.createElement("style");
1045        document.getElementsByTagName("head")[0].appendChild(style);
1046
1047        var closeMenus = function() {
1048            style.textContent = `
1049                header::after {
1050                    height: 0;
1051                }
1052            `;
1053            header.classList.remove("header_open");
1054            additionallyArrow.classList.remove("arrowUpAdditionally");
1055            objectsArrow.classList.remove("arrowUpObjects");
1056            
1057            if (objectsMenu.classList.contains("objects_active")) {
1058                objectsMenu.classList.remove("objects_active");
1059                objectsMenu.classList.add("objects_closed");
1060            }
1061            
1062            if (additionallyMenu.classList.contains("additionally_active")) {
1063                additionallyMenu.classList.remove("additionally_active");
1064                additionallyMenu.classList.add("additionally_closed");
1065            }
1066        };
1067
1068        menuTitles.map(function(item, index) {
1069            item.addEventListener("mouseenter", function() {
1070                switch(index) {
1071                    case 0: // "Объекты"
1072                        var objectsList = document.querySelectorAll(".baseList > li")[index].querySelector("ul");
1073                        style.textContent = `
1074                            header::after {
1075                                height: ${objectsList.offsetHeight}px;
1076                            }
1077                        `;
1078                        header.classList.add("header_open");
1079                        additionallyArrow.classList.remove("arrowUpAdditionally");
1080                        objectsArrow.classList.add("arrowUpObjects");
1081                        objectsMenu.classList.remove("objects_closed");
1082                        objectsMenu.classList.add("objects_active");
1083                        
1084                        if (additionallyMenu.classList.contains("additionally_active")) {
1085                            additionallyMenu.classList.remove("additionally_active");
1086                            additionallyMenu.classList.add("additionally_closed");
1087                        }
1088                        break;
1089                        
1090                    case 4: // "дополнительно"
1091                        var additionallyList = document.querySelectorAll(".baseList > li")[index].querySelector("ul");
1092                        style.textContent = `
1093                            header::after {
1094                                height: ${additionallyList.offsetHeight}px;
1095                            }
1096                        `;
1097                        header.classList.add("header_open");
1098                        additionallyArrow.classList.add("arrowUpAdditionally");
1099                        objectsArrow.classList.remove("arrowUpObjects");
1100                        additionallyMenu.classList.remove("additionally_closed");
1101                        additionallyMenu.classList.add("additionally_active");
1102                        
1103                        if (objectsMenu.classList.contains("objects_active")) {
1104                            objectsMenu.classList.remove("objects_active");
1105                            objectsMenu.classList.add("objects_closed");
1106                        }
1107                        break;
1108                        
1109                    default:
1110                        closeMenus();
1111                }
1112            });
1113        });
1114
1115        if (header) {
1116            header.addEventListener("mouseleave", function() {
1117                closeMenus();
1118            });
1119        }
1120    }
1121});
1122
1123function getPageData() {
1124  return {
1125    PAGE_TITLE: document.title.trim(),
1126    PAGE_URL: window.location.href,
1127    PAGE_PATH: window.location.pathname
1128  };
1129}
1130
1131function sendFeedback() {
1132  $('#form_feedback_n .btn-jk').click(function() {
1133    var form = $('#form_feedback_n');
1134
1135    var nameInput = form.find('input[name="name_feedback"]');
1136    var telInput = form.find('input[name="tel_feedback"]');
1137    var emailInput = form.find('input[name="email_feedback"]');
1138    var consentInput = form.find('input[name="terms[]"]');
1139    var consentBlock = form.find('.form-feedback__checkbox');
1140
1141    var name = nameInput.val().trim();
1142    var tel = telInput.val().trim();
1143    var email = emailInput.val().trim();
1144    var consent = consentInput.is(':checked');
1145
1146    var flag = 0;
1147
1148    // Сброс ошибок
1149    form.find('.error_input').removeClass('error_input');
1150
1151    // Валидация ИМЕНИ
1152    if (name === '') {
1153      nameInput.addClass('error_input');
1154      flag = 1;
1155    }
1156
1157    // Валидация ТЕЛЕФОНА (минимум 10 цифр)
1158    var telDigits = tel.replace(/\D/g, '');
1159    if (telDigits.length < 10) {
1160      telInput.addClass('error_input');
1161      flag = 1;
1162    }
1163
1164    // Валидация EMAIL (если заполнен)
1165    if (email !== '' && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
1166      emailInput.addClass('error_input');
1167      flag = 1;
1168    }
1169
1170    // Валидация ЧЕКБОКСА
1171    if (!consent) {
1172      consentBlock.addClass('error_input');
1173      flag = 1;
1174    }
1175
1176    // Если ошибок нет — отправляем
1177    if (flag == 0) {
1178      var submitBtn = form.find('.btn-jk');
1179      var originalText = submitBtn.text();
1180      submitBtn.text('Отправка...').css('opacity', '0.7');
1181
1182      // ← Получаем данные о странице
1183      var pageTitle = document.title.trim();
1184      var pageUrl = window.location.href;
1185
1186      $.post('/local/ajax/sendfeedback.php', {
1187        NAME: name, 
1188        TEL: tel, 
1189        EMAIL: email,
1190        CONSENT: 'Y',
1191        PAGE_TITLE: pageTitle,  // ← Заголовок страницы
1192        PAGE_URL: pageUrl       // ← URL страницы
1193      }, function(data) {
1194        if (data.success) {
1195          form.find('input').val('');
1196          form.find('.error_input').removeClass('error_input');
1197          consentInput.prop('checked', false);
1198          alert('Спасибо! Ваша заявка успешно отправлена.');
1199        } else {
1200          alert('Ошибка! Попробуйте позже.');
1201        }
1202      }, 'json')
1203      .fail(function() {
1204        alert('Ошибка соединения! Проверьте интернет.');
1205      })
1206      .always(function() {
1207        submitBtn.text(originalText).css('opacity', '1');
1208      });
1209    }
1210  });
1211
1212  // Убираем ошибку при клике на чекбокс
1213  $('#form_feedback_n input[name="terms[]"]').on('click', function() {
1214    $('.form-feedback__checkbox').removeClass('error_input');
1215  });
1216
1217  // Убираем ошибку при вводе в поля
1218  $('#form_feedback_n input[type="text"], #form_feedback_n input[type="tel"], #form_feedback_n input[type="email"]').on('input', function() {
1219    $(this).removeClass('error_input');
1220  });
1221};
1222
1223
1224$(document).ready(function() {
1225  // Применяем маску к полю телефона
1226  $('.tel-form-mask').mask('+7 (000) 000-00-00', {
1227    clearIfNotMatch: false // Не очищать поле, если не заполнено до конца
1228  });
1229
1230  // Запускаем функцию отправки формы
1231  sendFeedback();
1232  initQuestionForm();
1233});
1234
1235function initQuestionForm() {
1236  const form = $('#form_question_n');
1237  if (!form.length) return;
1238
1239  form.find('.btn-jk').click(function() {
1240    const nameInput = form.find('input[name="name_question"]');
1241    const telInput = form.find('input[name="tel_question"]');
1242    const emailInput = form.find('input[name="email_question"]');
1243    const commentInput = form.find('textarea[name="comment_question"]');
1244    const consentInput = form.find('input[name="terms[]"]');
1245    const consentBlock = form.find('.form-question__checkbox');
1246
1247    const name = nameInput.val().trim();
1248    const telRaw = telInput.val();
1249    const telDigits = telRaw.replace(/\D/g, '');
1250    const email = emailInput.val().trim();
1251    const comment = commentInput.val().trim();
1252    const consent = consentInput.is(':checked');
1253
1254    let flag = 0;
1255
1256    // Сброс ошибок
1257    form.find('.error_input').removeClass('error_input');
1258
1259    // Валидация ИМЕНИ
1260    if (name === '') {
1261      nameInput.addClass('error_input');
1262      flag = 1;
1263    }
1264
1265    // Валидация ТЕЛЕФОНА (минимум 10 цифр)
1266    if (telDigits.length < 10) {
1267      telInput.addClass('error_input');
1268      flag = 1;
1269    }
1270
1271    // Валидация EMAIL (если заполнен)
1272    if (email !== '' && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
1273      emailInput.addClass('error_input');
1274      flag = 1;
1275    }
1276
1277    // Валидация ЧЕКБОКСА
1278    if (!consent) {
1279      consentBlock.addClass('error_input');
1280      flag = 1;
1281    }
1282
1283    // Если ошибок нет — отправляем
1284    if (flag === 0) {
1285      const submitBtn = form.find('.btn-jk');
1286      const originalText = submitBtn.text();
1287      submitBtn.text('Отправка...').css('opacity', '0.7');
1288
1289      // ← Получаем данные о странице
1290      const pageTitle = document.title.trim();
1291      const pageUrl = window.location.href;
1292
1293      $.post('/local/ajax/send_question.php', {
1294        NAME: name,
1295        TEL: telRaw,
1296        EMAIL: email,
1297        COMMENT: comment,
1298        CONSENT: 'Y',
1299        PAGE_TITLE: pageTitle,  // ← Заголовок страницы
1300        PAGE_URL: pageUrl       // ← URL страницы
1301      }, function(data) {
1302        if (data.success) {
1303          form.find('input, textarea').val('');
1304          form.find('.error_input').removeClass('error_input');
1305          consentInput.prop('checked', false);
1306          alert('Спасибо! Ваш вопрос отправлен.');
1307        } else {
1308          alert('Ошибка! Попробуйте позже.');
1309        }
1310      }, 'json')
1311      .fail(function() {
1312        alert('Ошибка соединения! Проверьте интернет.');
1313      })
1314      .always(function() {
1315        submitBtn.text(originalText).css('opacity', '1');
1316      });
1317    }
1318  });
1319
1320  // Сброс ошибки при клике на чекбокс
1321  form.find('input[name="terms[]"]').on('click', function() {
1322    form.find('.form-question__checkbox').removeClass('error_input');
1323  });
1324
1325  // Сброс ошибки при вводе
1326  form.find('input[type="text"], input[type="email"], textarea').on('input', function() {
1327    $(this).removeClass('error_input');
1328  });
1329  form.find('input[name="tel_question"]').on('input', function() {
1330    $(this).removeClass('error_input');
1331  });
1332}
1333
1334
1335// Цель ЯМ переходы в соц.сети и месседжеры
1336(function () {
1337    function sendMetrikaGoal(goalName) {
1338        if (typeof window.ym === 'function') {
1339            window.ym(
1340                20863021,
1341                'reachGoal',
1342                goalName
1343            );
1344        }
1345    }
1346
1347    function hostMatches(host, domain) {
1348        return (
1349            host === domain ||
1350            host.endsWith('.' + domain)
1351        );
1352    }
1353
1354    document.addEventListener('click', function (event) {
1355        var target = event.target;
1356
1357        if (!target || !target.closest) {
1358            return;
1359        }
1360
1361        var link = target.closest('a[href]');
1362
1363        if (!link) {
1364            return;
1365        }
1366
1367        var href = (
1368            link.getAttribute('href') || ''
1369        ).toLowerCase();
1370
1371        var url;
1372
1373        try {
1374            url = new URL(
1375                link.href,
1376                window.location.href
1377            );
1378        } catch (error) {
1379            return;
1380        }
1381
1382        var host = url.hostname
1383            .toLowerCase()
1384            .replace(/^www\./, '');
1385
1386        var path = url.pathname.toLowerCase();
1387
1388
1389        /*
1390         * Мессенджеры.
1391         */
1392        var isMessenger =
1393            // Telegram
1394            hostMatches(host, 't.me') ||
1395            hostMatches(host, 'telegram.me') ||
1396            hostMatches(host, 'tlgg.ru') ||
1397            hostMatches(host, 'tele.click') ||
1398            href.indexOf('tg://') === 0 ||
1399
1400            // WhatsApp
1401            hostMatches(host, 'wa.me') ||
1402            hostMatches(host, 'api.whatsapp.com') ||
1403            hostMatches(host, 'web.whatsapp.com') ||
1404            href.indexOf('whatsapp://') === 0 ||
1405
1406            // VK Мессенджер
1407            hostMatches(host, 'vk.me') ||
1408            (
1409                (
1410                    hostMatches(host, 'vk.com') ||
1411                    hostMatches(host, 'm.vk.com')
1412                ) &&
1413                path.indexOf('/im') === 0
1414            ) ||
1415            href.indexOf('vk://') === 0 ||
1416
1417            // Viber
1418            hostMatches(host, 'partners.viber.com') ||
1419            href.indexOf('viber://') === 0 ||
1420
1421            // MAX
1422            hostMatches(host, 'max.ru') ||
1423
1424            // Facebook Messenger
1425            hostMatches(host, 'm.me') ||
1426            hostMatches(host, 'messenger.com');
1427
1428        if (isMessenger) {
1429            sendMetrikaGoal('messenger_click');
1430            return;
1431        }
1432
1433
1434        /*
1435         * Социальные сети.
1436         */
1437        var isSocialNetwork =
1438            // ВКонтакте
1439            hostMatches(host, 'vk.com') ||
1440
1441            // Одноклассники
1442            hostMatches(host, 'ok.ru') ||
1443
1444            // YouTube
1445            hostMatches(host, 'youtube.com') ||
1446            hostMatches(host, 'youtu.be') ||
1447
1448            // RUTUBE
1449            hostMatches(host, 'rutube.ru') ||
1450
1451            // Instagram
1452            hostMatches(host, 'instagram.com') ||
1453
1454            // Facebook
1455            hostMatches(host, 'facebook.com') ||
1456
1457            // X / Twitter
1458            hostMatches(host, 'x.com') ||
1459            hostMatches(host, 'twitter.com') ||
1460            hostMatches(host, 't.co') ||
1461
1462            // LinkedIn
1463            hostMatches(host, 'linkedin.com') ||
1464            hostMatches(host, 'lnkd.in') ||
1465
1466            // Pinterest
1467            hostMatches(host, 'pinterest.com') ||
1468            hostMatches(host, 'pinterest.ru') ||
1469
1470            // Мой Мир
1471            hostMatches(host, 'my.mail.ru') ||
1472
1473            // LiveJournal
1474            hostMatches(host, 'livejournal.com');
1475
1476        if (isSocialNetwork) {
1477            sendMetrikaGoal('social_click');
1478        }
1479    });
1480})();
1481
1482// ЯМ по скачиванию файла
1483(function () {
1484    var downloadExtensions = [
1485        'pdf',
1486        'doc',
1487        'docx',
1488        'xls',
1489        'xlsx',
1490        'csv',
1491        'ppt',
1492        'pptx',
1493        'txt',
1494        'rtf',
1495        'zip',
1496        'rar',
1497        '7z',
1498        'gz',
1499        'mp3',
1500        'wav',
1501        'mp4',
1502        'avi',
1503        'mov',
1504        'mkv',
1505        'apk'
1506    ];
1507
1508    document.addEventListener('click', function (event) {
1509        var target = event.target;
1510
1511        if (!target || !target.closest) {
1512            return;
1513        }
1514
1515        var link = target.closest(
1516            'a[href], .js-download'
1517        );
1518
1519        if (!link) {
1520            return;
1521        }
1522
1523        var isDownload =
1524            link.hasAttribute('download') ||
1525            link.classList.contains('js-download');
1526
1527        /*
1528         * Проверяем расширение файла в ссылке.
1529         */
1530        if (!isDownload && link.href) {
1531            try {
1532                var url = new URL(
1533                    link.href,
1534                    window.location.href
1535                );
1536
1537                var pathname =
1538                    url.pathname.toLowerCase();
1539
1540                var extension = pathname
1541                    .split('.')
1542                    .pop();
1543
1544                isDownload =
1545                    downloadExtensions.indexOf(
1546                        extension
1547                    ) !== -1;
1548            } catch (error) {
1549                isDownload = false;
1550            }
1551        }
1552
1553        if (
1554            isDownload &&
1555            typeof window.ym === 'function'
1556        ) {
1557            window.ym(
1558                20863021,
1559                'reachGoal',
1560                'file_download'
1561            );
1562        }
1563    });
1564})();

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.