PageSourceSearch

https://russianhighways.ru/app/js/common.js?v=2

js russianhighways.ru collected 2026-09-24 18:57:45 UTC 83,850 bytes, 2,300 lines download raw bytes

1$(document).ready(function() {
2
3    try {
4        svg4everybody();
5    } catch (e) {
6        console.log(e);
7    }
8
9    /* Anchor link scroll */
10    (function() {
11        var anchorLink = $('.js-anchor-link');
12
13        anchorLink.on('click', function(e){
14            e.preventDefault();
15
16            var it = $(this),
17                target = it.attr('href'),
18                targetOffset = $(target).offset().top,
19                scrollPosition,
20                headerHeight = $('.header-main').height()
21
22            if($(target).length){
23                scrollPosition = targetOffset - headerHeight;
24                $('html,body').animate({ scrollTop: scrollPosition }, 1000);
25            }
26        });
27    })();
28    /* !Anchor link scroll */
29
30    /* Header banner fixed */
31    (function() {
32        var banner = document.querySelector('.js-header-banner');
33        if(typeof(banner) !== 'undefined' && banner !== null){
34            function bannerFixed(e) {
35                if (window.pageYOffset >= 100) {
36                    banner.classList.add('fixed');
37                } else {
38                    banner.classList.remove('fixed');
39                }
40            }
41            bannerFixed();
42            window.addEventListener('scroll', bannerFixed);
43        }
44    })();
45    /* !Header banner fixed */
46
47    //Mask
48    var maskType = {
49        inn: {
50            mask: "9{10,12}",
51            placeholder: "____________"
52        },
53        kpp: {
54            mask: "9{9}",
55            placeholder: "_________"
56        },
57        orgn: {
58            mask: "9{13}",
59            placeholder: "_____________"
60        }
61    };
62
63    var maskList = $('.js-mask');
64    $.each(maskList, function(maskIndex, maskValue){
65        var it = $(maskValue),
66            type = it.data('mask-type');
67
68        it.inputmask({
69            "mask": maskType[type]['mask'],
70            "placeholder": maskType[type]['placeholder'],
71            "autoUnmask": false,
72            "removeMaskOnSubmit": false,
73            "disablePredictiveText": true
74        });
75    });
76
77
78    $('.js-mask-phone').inputmask({
79        "mask": "+9 (999) 999-99-99",
80        "placeholder": "+_ (___) ___ __ __",
81        "autoUnmask": false,
82        "removeMaskOnSubmit": false,
83        "disablePredictiveText": true
84    });
85
86
87    //Mobile menu
88    var mobileTog = $('.js-menu-tog');
89    mobileTog.on('click', function(e){
90        e.preventDefault();
91
92        $('.js-layout').toggleClass('layout--fixed');
93        $('.js-menu-mob').toggleClass('active');
94    });
95
96    //Tabs
97    var initTabs = function(tabsWrap){
98
99        $(tabsWrap).each(function(index, elem) {
100            var tabs = $(elem),
101                tabsNav = tabs.find('.js-tabs-nav'),
102                navItems = tabsNav.find('.js-tabs-nav-item'),
103                tabsContent = tabs.find('.js-tabs-content');
104
105            $.each(navItems, function(navIndex, navItem){
106                var item = $(navItem),
107                    itemIndex = item.data('tab-content');
108
109                item.on('click', function(e){
110                    e.preventDefault();
111
112                    var it = $(this);
113
114                    if(!it.hasClass('active')){
115                        navItems.removeClass('active');
116                        item.addClass('active');
117
118                        tabsContent.find('.js-tabs-item').addClass('d-none');
119                        tabsContent.find('.js-tabs-item[data-tab="'+itemIndex+'"]').removeClass('d-none');
120                    }
121                });
122            });
123        });
124
125    };
126
127 	var inno_initTabs = function(tabsWrap){
128
129        $(tabsWrap).each(function(index, elem) {
130            var tabs = $(elem),
131                tabsNav = tabs.find('.js-tabs-nav-inno'),
132                navItems = tabsNav.find('.js-tabs-nav-item'),
133                tabsContent = tabs.find('.js-tabs-content');
134
135            $.each(navItems, function(navIndex, navItem){
136                var item = $(navItem),
137                    itemIndex = item.data('tab-content');
138
139                item.on('click', function(e){
140                    e.preventDefault();
141					location.reload();
142
143                    var it = $(this);
144
145                    if(!it.hasClass('active')){
146                        navItems.removeClass('active');
147                        item.addClass('active');
148
149                        tabsContent.find('.js-tabs-item').addClass('d-none');
150                        tabsContent.find('.js-tabs-item[data-tab="'+itemIndex+'"]').removeClass('d-none');
151                    }
152                });
153            });
154        });
155
156    };
157	/*Innovations*/
158
159        inno_initTabs('.js-left-nav-wrapper-inno');
160	/* !Innovations*/
161
162    initTabs('.js-tabs-inv');
163
164    initTabs('.js-tabs-real');
165    
166    $('.js-press-date-trigger').click(function() {
167        var it = $(this),
168            dateParent = it.parents('.js-press-date-wrap'),
169            dateCurrent = it.parents('.js-press-date-item'),
170            dateCurrentContent = dateCurrent.find('.js-press-date-content');
171
172        dateCurrent.addClass('active').siblings('.js-press-date-item').removeClass('active');
173        dateCurrent.siblings('.js-press-date-item').find('.js-press-date-content').removeClass('active');
174        dateCurrentContent.addClass('active');
175        return false;
176    });
177
178    //Right menu mobile
179    var rightMenuTog = $('.js-press-date-tog');
180    rightMenuTog.on('click', function(e){
181        e.preventDefault();
182
183        var rightMenu = $('.js-press-date-wrap'),
184            rightMenuBg = $('.js-press-date-tog');
185
186        rightMenu.toggleClass('active');
187        rightMenuBg.toggleClass('active');
188    });
189
190    /* Youtube video */
191    var initYTVideo = (function() {
192        var isScriptLoaded = false;
193
194        return init;
195
196        function init($wrappers) {
197            if(!isScriptLoaded) loadScript();
198            window.onYouTubeIframeAPIReady = function() {
199                $wrappers.each(function(i, wrapper) {
200                    var $wrapper = $(wrapper),
201                        $placeholder = $wrapper.find('.js-video-frame'),
202                        elId = $placeholder.attr('id'),
203                        vidId = $placeholder.data('id');
204                    if(!elId || !vidId) return;
205                    var player = new YT.Player(elId, {
206                        videoId: vidId,
207                        playerVars: {'playsinline': '1'},
208                        events: {
209                            'onReady': function(event) {
210                                $wrapper.addClass('ready');
211                                $wrapper.on('click', function() {
212                                    player.playVideo();
213                                });
214                            },
215                            'onStateChange': function (event) {
216                                $wrapper.removeClass('play');
217                                if(event.data === 1 || event.data === 3) {
218                                    $wrapper.addClass('play');
219                                }
220                            }
221                        }
222                    });
223                });
224            };
225        }
226
227        function loadScript() {
228            var tag = document.createElement('script');
229            tag.src = "https://www.youtube.com/iframe_api";
230            var firstScriptTag = document.getElementsByTagName('script')[0];
231            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
232            isScriptLoaded = true;
233        }
234    })();
235    /* !Youtube video */
236
237    //Slider main
238    var initSlider = function(sliderWrap){
239
240        var instances = [];
241
242        $.each(sliderWrap, function(index, value) {
243
244            var sliderWrapElement = $(value).find('.js-slider-container'),
245                sliderThumbs = $(value).find('.js-slider-thumbs'),
246                sliderType = $(value).data('slider-type') || "default",
247                sliderCount = sliderWrapElement.find('.swiper-slide').length,
248                sliderPagination = $(value).find('.js-slider-pagination'),
249                sliderNav = sliderWrapElement.find('.js-slider-nav'),
250                sliderPrev = $(value).find('.js-slider-prev'),
251                sliderNext = $(value).find('.js-slider-next');
252
253            var sliderOptions; 
254
255            switch(sliderType) {
256                case "history":
257                    sliderOptions = {
258                        autoHeight: $(value).data('slider-height') || false,
259                        loop: true,
260                        slidesPerView: $(value).data('slide-count') || "auto",
261                        spaceBetween: $(value).data('slide-space') || 0,
262                        centeredSlides: true,
263                        effect: $(value).data('slider-effect') || "slide",
264                        autoplay: false,
265                        pagination: false,
266                        navigation: {
267                            prevEl: '.swiper-button-prev.h-slider-prev.js-h-slider-prev-0',
268                            nextEl: '.swiper-button-next.h-slider-next.js-h-slider-next-0'
269                        },
270                        breakpoints: {
271                            1024: {
272                                slidesPerView: 1
273                            },
274                            576: {
275                                slidesPerView: 1
276                            }
277                        }
278                    };
279                    break;
280                case "attractions":
281                    sliderOptions = {
282                        autoHeight: $(value).data('slider-height') || false,
283                        loop: sliderCount > 2 || false,
284                        slidesPerView: $(value).data('slide-count') || "auto",
285                        // slideClass: '.swiper-slide.slider-group.mr30',
286                        spaceBetween: $(value).data('slide-space') || 0,
287                        centeredSlides: false,
288                        effect: $(value).data('slider-effect') || "slide",
289                        autoplay: false,
290                        pagination: false,
291                        navigation: {
292                            nextEl: sliderNext,
293                            prevEl: sliderPrev
294                        },
295                        breakpoints: {
296                            768: {
297                                //slidesPerView: 4.1
298                            },
299                            480: {
300                                //slidesPerView: 1
301                            }
302                        }
303                    };
304                    if ($(this).hasClass('all-roads')) {
305                        sliderOptions.initialSlide = 3;
306                    }
307                    break;
308                case "news":
309                    sliderOptions = {
310                        autoHeight: $(value).data('slider-height') || false,
311                        loop: true,
312                        slidesPerView: $(value).data('slide-count') || "auto",
313                        spaceBetween: $(value).data('slide-space') || 0,
314                        centeredSlides: true,
315                        effect: $(value).data('slider-effect') || "slide",
316                        autoplay: false,
317                        pagination: false,
318                        loopAdditionalSlides: 1,
319                        navigation: {
320                            nextEl: sliderNext,
321                            prevEl: sliderPrev
322                        },
323                        breakpoints: {
324                            1024: {
325                                slidesPerView: 1.2
326                            },
327                            576: {
328                                slidesPerView: 1.1
329                            }
330                        }
331                    };
332                    break;
333                case "drivers":
334                    sliderOptions = {
335                        autoHeight: $(value).data('slider-height') || false,
336                        loop: $(value).data('slider-loop') || false,
337                        slidesPerView: 4,
338                        spaceBetween: $(value).data('slide-space') || 0,
339                        centeredSlides: false,
340                        effect: $(value).data('slider-effect') || "slide",
341                        autoplay: false,
342                        pagination: false,
343                        navigation: {
344                            nextEl: sliderNext,
345                            prevEl: sliderPrev
346                        },
347                        breakpoints: {
348                            1024: {
349                                slidesPerView: 3
350                            },
351                            576: {
352                                slidesPerView: 1.2
353                            }
354                        }
355                    };
356                    break;
357				case "inno":
358                    sliderOptions = {
359                        autoHeight: $(value).data('slider-height') || false,
360                        loop: true,
361                        slidesPerView: 1,
362                        spaceBetween: $(value).data('slide-space') || 0,
363                        centeredSlides: false,
364                        effect: $(value).data('slider-effect') || "slide",
365                        autoplay: true,
366						speed: 800,
367                        pagination: false,
368                        navigation: {
369                            nextEl: sliderNext,
370                            prevEl: sliderPrev
371                        },
372
373                    };
374                    break;
375                default:
376                    sliderOptions = {
377                        autoHeight: $(value).data('slider-height') || false,
378                        loop: $(value).data('slider-loop') || false,
379                        slidesPerView: $(value).data('slide-count') || "auto",
380                        spaceBetween: $(value).data('slide-space') || 0,
381                        centeredSlides: false,
382                        effect: $(value).data('slider-effect') || "slide",
383                        autoplay: false,
384                        pagination: false,
385                        navigation: {
386                            nextEl: sliderNext,
387                            prevEl: sliderPrev
388                        },
389                        breakpoints: {
390                            768: {
391                                //slidesPerView: 4.1
392                            },
393                            480: {
394                                //slidesPerView: 1
395                            }
396                        },
397                        on: {
398                            init: function() {
399                                var el = this.$el[0],
400                                    $videoFrameWrappers = $(el).find('.js-video-frame-wrapper');
401                                if($videoFrameWrappers.length) {
402                                    initYTVideo($videoFrameWrappers);
403                                }
404                            }
405                        }
406                    };
407                    if ($(value).data('has-pagination')) {
408                        if ($(value).hasClass('main-bottom-slider') && screen.width < 768) {
409                            sliderOptions.pagination = {
410                                el: '.swiper-pagination',
411                                type: 'bullets'
412                            };
413                        }
414                    }
415            }
416
417            if(sliderThumbs.length > 0){
418                switch(sliderType) {
419                    case "history":
420                        if(window.matchMedia('(min-width: 1024px)').matches) {
421                            sliderOptions.thumbs = {
422                                swiper: {
423                                    el: sliderThumbs.find('.swiper-container')[0],
424                                    slidesPerView: 9,
425                                    slideToClickedSlide: true,
426                                    breakpoints: {
427                                        768: {
428                                            slidesPerView: 3
429                                        },
430                                        480: {
431                                            //slidesPerView: 1
432                                        }
433                                    }
434                                }
435                            };
436                        }
437                        break;
438                    case "news":
439                        if(window.matchMedia('(min-width: 1024px)').matches) {
440                            sliderOptions.thumbs = {
441                                swiper: {
442                                    el: sliderThumbs.find('.swiper-container')[0],
443                                    slidesPerView: 9,
444                                    slideToClickedSlide: true,
445                                    breakpoints: {
446                                        768: {
447                                            slidesPerView: 3
448                                        },
449                                        480: {
450                                            //slidesPerView: 1
451                                        }
452                                    }
453                                }
454                            };
455                        }
456                        break;
457                    default:
458                        sliderOptions.thumbs = {
459                            swiper: {
460                                el: sliderThumbs.find('.swiper-container')[0],
461                                slidesPerView: 4,
462                                slideToClickedSlide: true,
463                                breakpoints: {
464                                    768: {
465                                        slidesPerView: 3
466                                    },
467                                    480: {
468                                        //slidesPerView: 1
469                                    }
470                                }
471                            }
472                        };
473                }
474            }
475
476            var resistanceRatio = $(value).data('resistance-ratio'),
477                initBreakpoint = $(value).data('init-breakpoint'),
478                hasNavigation = $(value).data('has-navigation');
479
480            if(typeof resistanceRatio !== 'undefined') {
481                sliderOptions.resistanceRatio = parseFloat(resistanceRatio);
482            }
483
484            if(hasNavigation === true) {
485                if ($(value).hasClass('main-bottom-slider') && screen.width < 768) {
486                    sliderOptions.navigation = {
487                        nextEl: '.swiper-button-next',
488                        prevEl: '.swiper-button-prev'
489                    };
490                } else {
491                    sliderOptions.navigation = {
492                        nextEl: $(value).find('.js-slider-nav-arrow-next')[0],
493                        prevEl: $(value).find('.js-slider-nav-arrow-prev')[0]
494                    };
495                }
496            }
497
498/*            var swiperInstance;
499                        if(typeof initBreakpoint !== 'undefined') {
500                if(window.matchMedia('(max-width: ' + initBreakpoint + 'px)').matches) {
501                    swiperInstance = new Swiper(sliderWrapElement[0], sliderOptions);
502                    instances.push(swiperInstance);
503                }
504            } else {
505                swiperInstance = new Swiper(sliderWrapElement[0], sliderOptions);
506                instances.push(swiperInstance);
507            }*/
508
509            var swiperInstance = new Swiper(sliderWrapElement[0], sliderOptions);
510            instances.push(swiperInstance);
511        });
512        return instances;
513    };
514
515    var sliderWrap = $('.js-slider-wrap');
516    initSlider(sliderWrap);
517
518
519    /* Tab slider */
520    var initTabSlider = function($sliderWrap, callback) {
521        if(!$sliderWrap.length) return;
522        var $root = $sliderWrap,
523            $sliderWrapElement = $root.find('.js-tab-slider-container'),
524            $sliderPrev = $root.find('.js-tab-slider-prev'),
525            $sliderNext = $root.find('.js-tab-slider-next'),
526            slidesPerView = $root.data('slides-per-view') || 2,
527            breakpoints = {};
528
529        if($root.data('breakpoints')) {
530            breakpoints = $root.data('breakpoints');
531        }
532
533        var sliderOptions = {
534            autoHeight: false,
535            loop: false,
536            slidesPerView: slidesPerView,
537            spaceBetween: 0,
538            centeredSlides: false,
539            effect: "slide",
540            autoplay: false,
541            pagination: false,
542            breakpoints: breakpoints,
543            on: {
544                init: onInit
545            }
546        };
547
548        var queryObject = null;
549
550        var swiper = new Swiper($sliderWrapElement[0], sliderOptions),
551            slides, $slides;
552
553        $sliderPrev.on('click', function() {
554            if($(this).hasClass('.swiper-button-disabled')) return;
555            var activeIndex = $slides.filter('.swiper-slide-thumb-active').index();
556            $slides[activeIndex - 1].click();
557        });
558
559        $sliderNext.on('click', function() {
560            if($(this).hasClass('.swiper-button-disabled')) return;
561            var activeIndex = $slides.filter('.swiper-slide-thumb-active').index();
562            $slides[activeIndex + 1].click();
563        });
564
565        function onInit() {
566            var swiper = this;
567            slides = this.slides;
568            $slides = $(slides);
569            if($slides.filter('[data-href]').length) { //if there are tabs with urls
570                queryObject = searchToObject();
571            }
572            $slides.on('click', function() {
573                var $clickedTab = $(this),
574                    url = $clickedTab.data('href') || null,
575                    currentIndex = $clickedTab.index(),
576                    $ajaxContentOuter = $('.js-tab-slider-content-outer'),
577                    $ajaxContentWrapper = $('.js-tab-slider-content-wrapper');
578
579                swiper.slideTo(currentIndex);
580
581                $slides.removeClass('swiper-slide-thumb-active');
582                $clickedTab.addClass('swiper-slide-thumb-active');
583
584                $sliderPrev.removeClass('swiper-button-disabled');
585                $sliderNext.removeClass('swiper-button-disabled');
586                if(currentIndex === 0) {
587                    $sliderPrev.addClass('swiper-button-disabled');
588                } else if(currentIndex === $slides.length - 1) {
589                    $sliderNext.addClass('swiper-button-disabled');
590                }
591
592                if(url) {
593                    addPreloader($ajaxContentOuter);
594                    $.get(url).done(function(content) {
595                        try {
596                            handleContent($ajaxContentWrapper, content);
597                            handleUrl($clickedTab, queryObject);
598                            if(typeof callback === 'function') {
599                                callback($ajaxContentWrapper, $clickedTab); //additional initializations
600                            }
601                        } catch(err) {
602                            if(err.message === "Internal Error") {
603                                console.log(err);
604                            } else {
605                                throw err;
606                            }
607                        } finally {
608                            removePreloader($ajaxContentOuter);
609                        }
610                    });
611                } else if(typeof callback === 'function') {
612                    callback(null, $clickedTab);
613                }
614
615            });
616
617            if(queryObject) {
618                firstLoad($slides, queryObject);
619            }
620        }
621
622        function handleUrl($tab, queryObject) {
623            if(!$tab.length) {
624                throw new Error('Internal Error');
625            }
626            var tabIndex = $tab.index();
627            var path = window.location.pathname + '?' + (function makeQuery(queryObject) {
628                queryObject.tab = tabIndex + 1;
629                var queryArr = [];
630                for(var key in queryObject) {
631                    if(!queryObject.hasOwnProperty(key)) continue;
632                    queryArr.push(key + '=' + queryObject[key]);
633                }
634                return queryArr.join('&');
635            })(queryObject);
636            window.history.pushState(null, null, path);
637        }
638
639        function handleContent($wrapper, content) {
640            if(!$wrapper.length || !content) {
641                throw new Error('Internal Error');
642            }
643            $wrapper.html(content);
644        }
645
646        function firstLoad($tabs, queryObject) {
647            var tabIndexFromQuery = +queryObject.tab,
648                tabIndex = 1;
649            if(typeof tabIndexFromQuery === 'number'
650                && tabIndexFromQuery === tabIndexFromQuery) { // check if not NaN
651                tabIndex = tabIndexFromQuery;
652            }
653            $tabs[tabIndex - 1].click();
654        }
655
656        function addPreloader($outer) {
657            try {
658                modulePreloader.init({
659                    element: $outer,
660                    position: 'append'
661                });
662            } catch (e) {
663                //no preloader
664            }
665        }
666
667        function removePreloader($outer) {
668            try {
669                modulePreloader.destroy({
670                    element: $outer,
671                    preloader: $outer.find('.preloader-module__wrapper')
672                });
673            } catch (e) {
674                //no preloader
675            }
676        }
677
678        function searchToObject() {
679            var pairs = window.location.search.substring(1).split("&"),
680                obj = {},
681                pair,
682                i;
683
684            for ( i in pairs ) {
685                if ( pairs[i] === "" ) continue;
686
687                pair = pairs[i].split("=");
688                obj[ decodeURIComponent( pair[0] ) ] = decodeURIComponent( pair[1] );
689            }
690
691            return obj;
692        }
693
694        return swiper;
695    };
696
697    initTabSlider($('.js-tab-slider-wrapper'));
698    /* !Tab slider */
699
700
701    /* Form field toggle */
702    var initFieldToggle = function(element){
703        element = $(element);
704
705        if(!element.length) return;
706
707        element.on('click', function(){
708            var it = $(this),
709                checkType = it.data('check-type'),
710                checkTarget = it.data('check-target').split(','),
711                toggleType = it.data('toggle-type'),
712                toggleTarget = it.data('toggle-target') || false;
713
714            $.each(checkTarget, function(checkIndex, checkItem){
715                var checkElement = $('.js-check-item[name="'+checkItem.trim()+'"]'),
716                    checkElementWrap = checkElement.parents('.js-check-item-wrap');
717
718                if(checkElement.length > 0){
719                    if(checkType === "show"){
720                        checkElement.prop('disabled', false);
721                        checkElementWrap.removeClass('d-none');
722                    }else{
723                        checkElement.prop('disabled', true);
724                        checkElementWrap.addClass('d-none');
725                    }
726                }
727            });
728
729            if(toggleTarget){
730                var toggleElement = $('.js-toggle-item[name="' + toggleTarget.trim() + '"]'),
731                    toggleCondition = it.data('toggle-condition') || false;
732                if(toggleElement.length > 0){
733                    if(toggleType === "enable" && !toggleElement.hasClass('not-required')){
734                        toggleElement.attr({
735                            'data-required': 'true',
736                            'placeholder': function(i, val) {
737                                if(val.indexOf("*") === -1){
738                                    return val + "*";
739                                }
740                            }
741                        });
742                    }else{
743                        var toggleConditionElement = $(toggleCondition['elem']),
744                            toggleConditionResult = toggleCondition['res'];
745
746                        if(toggleConditionElement.length > 0 && toggleConditionElement.is(':'+toggleConditionResult)){
747                            toggleElement.attr({
748                                'data-required': 'false',
749                                'placeholder': function(i, val) {
750                                    if(val.indexOf("*") > 0){
751                                        return val.slice(0, -1);
752                                    }
753                                }
754                            });
755                        }
756                    }
757                }
758            }
759        });
760    };
761
762    initFieldToggle('.js-check-field');
763    /* !Form field toggle */
764
765    /* Form captcha */
766    var initFormCaptcha = function(captchaWrap){
767        captchaWrap = $(captchaWrap);
768
769        if(!captchaWrap.length) return;
770
771        var verifyCallback = function(){
772            $('.js-form-captcha-submit').prop('disabled', false);
773        };
774
775        var initCaptcha = function(){
776            if (typeof grecaptcha === 'undefined') {
777                return;
778            }
779
780            grecaptcha.render(captchaWrap[0], {
781                'sitekey': '6LfJQBMaAAAAAN1SX3q1ILaXS5sg5IBQhbRpwCHC',
782                'callback' : verifyCallback
783            });
784        };
785
786        setTimeout(function(){
787            initCaptcha();
788        },1500);
789    };
790
791    initFormCaptcha('.js-form-captcha');
792    /* !Form captcha */
793
794    /* FIle upload */
795    var fileuploadItem = $('.js-file-upload');
796    if(fileuploadItem.length){
797        moduleFile.initDropzone(fileuploadItem);
798    }
799    /* !FIle upload */
800
801    /* Form Appeal */
802    var formAppeal = $('.js-form-appeal');
803    if(formAppeal.length){
804        moduleAppeal.initFormAppeal(formAppeal);
805    }
806	//appeal for TY
807	var formAppeal = $('.js-form-appeal-tu');
808    if(formAppeal.length){
809        moduleAppealTU.initFormAppeal(formAppeal);
810    }
811    /* !Form Appeal */
812
813    /* Page Affiliates */
814    var affiliatesList = $('.js-affiliates-list');
815
816	var getNextSibling = function (elem, selector) {
817
818		var sibling = elem.next();
819		var i = 1;
820		if (sibling.hasClass(selector)) return sibling;
821
822		while (sibling && i<20) {  
823			if (sibling.hasClass(selector)) return sibling;
824			sibling = sibling.next(); i++;
825		}
826		return;
827	};
828
829	var setAffiliatesTree = function(list){
830        var listWrap = $(list),
831            itemList = listWrap.find('.affiliate-item--sub');
832
833        var setAffiliateItemLine = function(item){
834			var itemMiddle = 0;
835			var newHeight = 0;
836			var affiItem = $(item);
837
838				var next = getNextSibling(affiItem, 'affiliate-item--sub');
839				if(next){
840					var rect = next[0].getBoundingClientRect();
841					itemMiddle = (rect.top + 0.5 * (rect.bottom - rect.top)).toFixed(0);   
842					newHeight = (itemMiddle - affiItem[0].getBoundingClientRect().bottom + 40).toFixed(0) + 'px';
843					affiItem.removeClass(function (index, css) {
844						return (css.match (/\baffiliate-item-extra\S+/g) || []).join(' '); 
845					});
846					affiItem.addClass("affiliate-item-extra" + itemMiddle);
847					var styleElem = document.head.appendChild(document.createElement("style"));
848	
849					styleElem.innerHTML = ".affiliate-item-extra" + itemMiddle + ':before {content: "";position: absolute; width: 1px;background: #dd9046; z-index: 1;top: -16px; height: calc(' + newHeight + " + 70%);}";
850					
851				}
852
853		}
854		
855		$.each(itemList, function(index, val){
856            setAffiliateItemLine(val);
857        });
858		
859	}
860
861    var initAffiliates = function(list){
862        var listWrap = $(list),
863            itemList = listWrap.find('.js-affiliate-item');
864
865        var initAffiliateItem = function(item){
866
867            var affiItem = $(item),
868                //parent = affiItem.parents('.js-affiliate-wrap'),
869                //tog = parent.find('.js-affiliate-tog'),
870                //info = parent.find('.js-affiliate-info'),
871                //sub = parent.find('.js-affiliate-sub-list');
872				info = affiItem.find('.js-affiliate-info'),
873				tog = affiItem.find('.js-affiliate-tog'),
874				sub = getNextSibling(affiItem, 'js-affiliate-sub-list');
875
876            affiItem.on('click', function(e){
877
878                var clickTarget = e.target,
879                    clickTargetTog = $(clickTarget).data('tog') || $(clickTarget).closest('[data-tog]').length !== 0 || false;
880
881                if (clickTarget === this || clickTargetTog === true){
882                    affiItem.toggleClass('active');
883                    info.toggleClass('active');
884                    sub.toggleClass('active');
885                }
886				var affiliatesList = $('.js-affiliates-list');
887				setTimeout(function () {setAffiliatesTree(affiliatesList)}, 10); 
888            });
889        };
890
891        $.each(itemList, function(index, val){
892            initAffiliateItem(val);
893        });
894    };
895
896    if(affiliatesList.length){
897        initAffiliates(affiliatesList);
898		setAffiliatesTree(affiliatesList);
899    }
900    /* !Page Affiliates */
901
902    /* About: Map */
903    (function () {
904        if (!$("#about-map").length) return;
905
906        var initialCoords = [55.767610, 37.608625];
907
908        ymaps.ready(init);
909
910        function init() {
911            var map = new ymaps.Map("about-map", {
912                center: initialCoords,
913                zoom: 16,
914                controls: []
915            });
916            var placemark = new ymaps.Placemark(initialCoords, {
917                iconContent: '',
918                balloonContent: 'Страстной бульвар, 9',
919                hintContent: 'Страстной бульвар, 9'
920            }, {
921                iconLayout: 'default#image',
922                iconImageHref: '/i/map-marker.svg',
923                iconImageSize: [45, 70],
924                iconImageOffset: [-32.5, -90],
925                zIndex: 999
926            });
927            map.geoObjects.add(placemark);
928        }
929    })();
930    /* !About: Map */
931
932
933    /* Toggler */
934    var initToggler = function($root) {
935        $root = $root || $(document);
936        var $togglers = $root.find('.js-toggler');
937        if(!$togglers.length) return;
938        $togglers.each(function(_, toggler) {
939            var $root = $(toggler),
940                $trigger = $root.find('.js-toggler__trigger'),
941                $triggerText = $trigger.find('.js-toggler__trigger-text'),
942                $triggerDefault = $triggerText.html() || false,
943                $triggerCollapsed = $triggerText.data('collapsed') || false;
944            $trigger.on('click', function(e) {
945                e.preventDefault();
946
947                var it = $(this),
948                    active = it.parents($root).hasClass('open');
949                if(!active){
950                    $root.addClass('open');
951                    if($triggerText.length){
952                        $triggerText.html($triggerCollapsed);
953                    }
954                }else{
955                    $root.removeClass('open');
956                    if($triggerText.length){
957                        $triggerText.html($triggerDefault);
958                    }
959                }
960            });
961        });
962    };
963    initToggler();
964    /* !Toggler */
965
966
967    /* Calculator init */
968    (function () {
969        if(!$('.js-calculator-form').length) return;
970        var url = '/i/_static/roads.json',
971            lang = 'ru';
972        if(window.location.pathname.indexOf('/en/') !== -1) {
973            url = '/i/_static/roads-eng.json';
974            lang = 'en';
975        }
976        $.get(url, function(data) {
977            moduleCalculator.init(data, lang, false);
978        });
979    })();
980    /* !Calculator init */
981
982
983    /* Drivers page */
984    (function() {
985        var $pageNavWrapper = $('.js-drivers-page-nav');
986
987        //road list page
988        if($pageNavWrapper.length) {
989            initTabSlider($pageNavWrapper, function ($wrapper, $tab) {
990                var roadId = $tab.data('road-id');
991                initMap(roadId);
992                initSlider($wrapper.find('.js-slider-wrap'));
993                initToggler($wrapper);
994            });
995        }
996
997        //road detail page
998        var detailMap = $('.js-driver-map-detail');
999        if(detailMap.length){
1000            initMap(detailMap.data('id'));
1001        }
1002
1003        function initMap(roadId) {
1004            console.log("roadId:", roadId)
1005            var $mapContainer = $('#drivers-map');
1006            if (!$mapContainer.length) return;
1007
1008            var initialCoords = [55.767585, 37.6063982];
1009
1010            ymaps.ready(init);
1011
1012            function init () {
1013                var lang = window.location.pathname.indexOf('/en/') !== -1 ? 's2' : 's1';
1014                adjustContainerMapBounds($mapContainer);
1015
1016                try {
1017                    moduleResize.width({
1018                        userFunction: adjustContainerMapBounds.bind(null, $mapContainer)
1019                    });
1020                } catch (e) {
1021                    //module is not defined
1022                }
1023
1024                // Создаем карту с добавленными на нее кнопками.
1025                var myMap = new ymaps.Map('drivers-map', {
1026                    center: initialCoords,
1027                    zoom: 6,
1028                    controls: []
1029                }, {
1030                    buttonMaxWidth: 300
1031                });
1032                console.log("myMap:", myMap)
1033                $.get('/ajax/getlayout.php?track=' + roadId + '&site=' + lang)
1034                    .done(function(filePaths) {
1035                        var paths;
1036                        try {
1037                            paths = JSON.parse(filePaths)[0];
1038                        } catch (e) {
1039                            console.log(e);
1040                            return;
1041                        }
1042                        //console.log(paths);
1043                        if(!paths || !paths[0]) return;
1044                        ymaps.vow.all(
1045                            paths.map(function(path) {
1046                                return ymaps.geoXml.load(path);
1047                            })
1048                        ).then(function(results) {
1049                            var geoCollection = new ymaps.GeoObjectCollection();
1050                            results.forEach(function(res) {
1051                                geoCollection.add(res.geoObjects);
1052                            });
1053                            myMap.geoObjects.add(geoCollection);
1054                            myMap.setBounds(geoCollection.getBounds(), {checkZoomRange:true});
1055                        });
1056                    })
1057                    .fail(function(err) {
1058                        //debugger;
1059                    });
1060            }
1061        }
1062
1063        function adjustContainerMapBounds($element) { //many browsers include scrollbar width while calculating width in vw
1064            var $mapContainer = $element,
1065                el = document.createElement('div'),
1066                factor = $mapContainer.width() / $(document).width(),
1067                scrollbarWidth, offset;
1068            el.style.width = 'calc(100vw - 100%)'; //100% is the width without scrollbar
1069            el.style.visibility = 'hidden';
1070            $('body').append(el);
1071            scrollbarWidth = $(el).width();
1072            $(el).remove();
1073            offset = scrollbarWidth * factor;
1074            if(offset === offset) {
1075                $mapContainer.css('padding-right', offset + 'px');
1076            }
1077        }
1078    })();
1079    /* !Drivers page */
1080
1081
1082    /* Switch */
1083    (function () {
1084        var $switchBlocks = $('.js__switch');
1085        if(!$switchBlocks.length) return;
1086        $switchBlocks.each(function(_, block) {
1087            init(block);
1088        });
1089
1090        function init(block) {
1091            var $root = $(block),
1092                $contents = $root.find('.js__switch--contents'),
1093                $buttons = $root.find('.js__switch--btn'),
1094                hash = window.location.hash;
1095
1096            $buttons.on('click', function(e) {
1097                e.preventDefault();
1098                var $btn = $(this),
1099                    id = $btn.attr('data-id'),
1100                    href = $btn.attr('href');
1101                $contents.addClass('switch-hidden')
1102                    .filter('[data-id=' + id + ']')
1103                    .removeClass('switch-hidden');
1104                $buttons.removeClass('active')
1105                    .filter(this)
1106                    .addClass('active');
1107                if(href && href.indexOf('#') === 0 && href !== '#') {
1108                    window.location.hash = href;
1109                }
1110            });
1111
1112            if(hash) {
1113                $buttons.filter('[href="' + hash + '"]').trigger('click');
1114            }
1115        }
1116    })();
1117    /* !Switch */
1118
1119
1120    /* Styled selects */
1121    var styledSelects = (function() {
1122
1123        var PATH_TO_SPRITE = '/i/icons/select/sprite.svg#';
1124
1125        return {
1126            init: init
1127        };
1128
1129        function init($root) {
1130            $root = $root || $(document);
1131            var $selects = $root.find('.js-select-styled');
1132
1133            if(!$selects.length) return;
1134
1135            $selects.each(function(_, select) {
1136                var $select = $(select),
1137                    $state, $text, $icon, useElement, currentIconId = null;
1138                $select.select2({
1139                    width: '100%',
1140                    minimumResultsForSearch: -1,
1141                    containerCssClass: 'select-styled',
1142                    placeholder: function(){
1143                        $(this).data('placeholder');
1144                    },
1145                    templateSelection: function(state) {
1146                        var iconIdFromOption = $(state.element).data('ico'),
1147                            iconId = iconIdFromOption || $select.data('ico');
1148                        //first initialization
1149                        if(!$state) {
1150                            $state = $(
1151                                '<span class="select-styled-state select-styled__option-holder">' +
1152                                '<span class="select-styled__option-ico-wrapper">' +
1153                                '<svg class="ico select-styled__option-ico" width="19" height="22">\n' +
1154                                '<use xlink:href="' + PATH_TO_SPRITE + iconId + '"></use>\n' +
1155                                '</svg>' +
1156                                '</span>' +
1157                                '<span class="select-styled__option-text"></span>' +
1158                                '</span>'
1159                            );
1160                            $text = $state.find('.select-styled__option-text');
1161                            $icon = $state.find('.select-styled__option-ico');
1162                            useElement = $state.find('use')[0];
1163                            currentIconId = iconId;
1164                        }
1165
1166                        $text.text(state.text);
1167
1168                        if(iconId !== currentIconId) {
1169                            useElement.setAttributeNS(
1170                                'http://www.w3.org/1999/xlink',
1171                                'xlink:href',
1172                                PATH_TO_SPRITE + iconId);
1173                            currentIconId = iconId;
1174                        }
1175
1176                        iconIdFromOption
1177                            ? $icon.removeClass('disabled')
1178                            : $icon.addClass('disabled');
1179
1180                        iconId
1181                            ? $icon.parent().removeClass('d-none')
1182                            : $icon.parent().addClass('d-none');
1183
1184                        return $state;
1185                    }
1186                });
1187            });
1188        }
1189    })();
1190
1191    styledSelects.init();  		
1192    /* !Styled selects */
1193
1194
1195    /* Sharing */
1196    var initShares = function ($element, options) {
1197        var $shares = $element;
1198        if(!$shares.length) return;
1199        var $shareItems = $shares.find('.js-shares__item');
1200        $.each($shareItems, function(socialIndex, socialObject){
1201            $(socialObject).on('click', function share(e){
1202                e.preventDefault();
1203                return JSShare.go(this, options);
1204            });
1205        });
1206    };
1207
1208    (function () {
1209        var $shares = $('.js-shares');
1210        if(!$shares.length) return;
1211        initShares($shares, {
1212            //if we don't specify options they would be overwritten by ajax loaded content
1213            url: window.location.href,
1214            title: document.title
1215        });
1216    })();
1217    /* !Sharing */
1218
1219
1220    var adjustFontSize = function($container) {
1221        $container = $container || $(document);
1222        var $titles = $container.find('.js-title');
1223        if(!$titles.length) return;
1224        $titles.each(function(_, title) {
1225            var $title = $(title),
1226                length = $title.data('length') || 80;
1227            if($title.text().length > length) {
1228                $title.addClass('sm');
1229            }
1230        });
1231    };
1232    adjustFontSize();
1233
1234
1235    /* News infinite scroll */
1236    (function() {
1237        var $root = $('.js-news-more');
1238        if(!$root.length) return;
1239
1240        var $container = $root.find('.js-news-more__container'),
1241            limitEl = $root.find('.js-news-more__limit')[0],
1242            requestUrl = $root.data('url');
1243
1244        //validation
1245        var isConfigurationValid = false;
1246        if(!$container.length) {
1247            console.error('NewsInfiniteScroll: No container is specified');
1248        } else if(!limitEl) {
1249            console.error('NewsInfiniteScroll: No limit element is specified');
1250        } else if(!requestUrl) {
1251            console.error('NewsInfiniteScroll: No request url is specified');
1252        } else if(!$root.attr('data-offset')) {
1253            console.error('NewsInfiniteScroll: No offset is specified');
1254        } else {
1255            isConfigurationValid = true;
1256        }
1257        if(!isConfigurationValid) {
1258            return;
1259        }
1260        //!validation
1261
1262        if($('.news-one-outer').eq(0).length) {
1263            observeNewsItem(
1264                $('.news-one-outer').eq(0),
1265                updatePageMeta.bind(null, window.location.pathname, document.title)
1266            );
1267        }
1268
1269        var options = {
1270            root: null, //observe on document
1271            threshold: 1.0
1272        };
1273        var isAllLoaded = false;
1274        var callback = function (entries) {
1275            if($root.hasClass('loading') || isAllLoaded) return;
1276            var entry = entries[0],
1277                offset = parseInt($root.attr('data-offset')),
1278                id = $root.data('id') || 0;
1279            if(entry.isIntersecting) {
1280                $root.addClass('loading');
1281                try {
1282                    modulePreloader.init({
1283                        element: $root,
1284                        position: 'append'
1285                    });
1286                } catch (e) {
1287                    //no preloader
1288                }
1289                $.get(requestUrl + '?offset=' + offset + '&id=' + id).done(function(response) {
1290                        try {
1291                            modulePreloader.destroy({
1292                                element: $root,
1293                                preloader: $root.find('.preloader-module__wrapper')
1294                            });
1295                        } catch(e) {
1296                            //no preloader
1297                        }
1298                    if(response === 'false') {
1299                        isAllLoaded = true;
1300                    }
1301                    var $content = $(response),
1302                        $shares = $content.find('.js-shares'),
1303                        newUrl = $content.data('url'),
1304                        newTitle = $content.find('.js-news-single__title').text(),
1305                        update = updatePageMeta.bind(null, newUrl, newTitle);
1306                    //update();
1307                    if($shares.length && (!newUrl || !newTitle)) {
1308                        $shares.remove(); //no url or title specified
1309                    } else {
1310                        initShares($shares, {
1311                            url: window.location.origin + newUrl, //url should be absolute
1312                            title: newTitle
1313                        });
1314                    }
1315                    adjustFontSize($content);
1316                    $container.append($content);
1317                    initSlider($container.find('.js-slider-wrap'));
1318                    $root.attr('data-offset', offset + 1);
1319                    $root.removeClass('loading');
1320
1321                    //change url and title when news item appears on viewport
1322                    observeNewsItem($content, update);
1323                });
1324            }
1325        };
1326
1327        var observer = new IntersectionObserver(callback, options);
1328        observer.observe(limitEl);
1329
1330        function updatePageMeta(url, title) {
1331            if(url) {
1332                window.history.pushState(null, null, url);
1333                if (title) {
1334                    document.title = title;
1335                }
1336            }
1337        }
1338
1339        function observeNewsItem($element, updateCb) {
1340            var winH = $(window).height(),
1341                contentH = $element.outerHeight(),
1342                CORRECTION_FACTOR = 10;
1343            new IntersectionObserver(function (entries) {
1344                var entry = entries[0];
1345                if(entry.isIntersecting) {
1346                    updateCb();
1347                }
1348            }, {
1349                root: null, //observe on document
1350                threshold: winH > contentH
1351                    ? 1
1352                    : winH / (contentH + CORRECTION_FACTOR)
1353            }).observe($element[0]);
1354        }
1355    })();
1356    /* !News infinite scroll */
1357
1358
1359    /* Form calc */
1360    (function() {
1361        var $form = $('.js-form-calc');
1362        if(!$form.length) return;
1363        $form.on('submit', function(e) {
1364            e.preventDefault();
1365            var data = $(this).serialize(),
1366                type = $(this).attr('data-type'),
1367                url = $form.attr('action');
1368
1369            $.post({
1370                url: url,
1371                data: data
1372            }).done(function(response) {
1373                var data, num, rest, from, to;
1374
1375                try {
1376                    data = JSON.parse(response);
1377                    num = data.cost;
1378                    rest = data.rest || "00";
1379                    from = data.locationFrom;
1380                    to = data.locationTo;
1381                } catch(e) {
1382                    console.log(e);
1383                    return;
1384                }
1385
1386                if(type === "drivers") {
1387                    (function() {
1388                        var $popupWrapper = $('#resolve-result'),
1389                            $num = $popupWrapper.find('.js-form-calc__num'),
1390                            $rest = $popupWrapper.find('.js-form-calc__rest'),
1391                            $route = $popupWrapper.find('.js-form-calc__route'),
1392                            $from = $popupWrapper.find('.js-form-calc__from'),
1393                            $to = $popupWrapper.find('.js-form-calc__to');
1394                        $num.text(num);
1395                        $rest.text(rest);
1396                        if(from && to) {
1397                            $route.removeClass('d-none');
1398                            $from.text(from);
1399                            $to.text(to);
1400                        } else {
1401                            $route.addClass('d-none');
1402                            console.error('В ответе от сервера отсутсвуют поля "пункт отправления" и "пункт прибытия"')
1403                        }
1404
1405                        $.fancybox.open({
1406                            src: '#resolve-result',
1407                            type: 'inline'
1408                        });
1409                    })();
1410                } else {
1411                    (function() {
1412                        var $num = $form.find('.js-form-calc__num'),
1413                            $rest = $form.find('.js-form-calc__rest'),
1414                            $resultWrapper = $form.find('.js-form-calc__result-show');
1415                        $num.text(num);
1416                        $rest.text(rest);
1417                        $resultWrapper.removeClass('d-none');
1418                    })();
1419                }
1420            });
1421        });
1422    })();
1423    /* !Form calc */
1424
1425    /* Custom Scroll */
1426    var initCustomScroll = function($el) {
1427      $el.mCustomScrollbar();
1428    };
1429
1430    (function() {
1431        var $scrollBlock = $('.js-custom-scroll');
1432        if(!$scrollBlock.length) return;
1433        initCustomScroll($scrollBlock);
1434    })();
1435    /* !Custom Scroll */
1436
1437
1438    /* Counter */
1439    var initCounter = function($container) {
1440        $container = $container || $(document);
1441        var $el = $container.find('.js-counter');
1442        if(!$el.length) {
1443            console.error('initCounter: root elements not found');
1444            return;
1445        }
1446        $el.each(function (_, el) {
1447            var $root = $(el),
1448                dateStr = $root.data('countdown'),
1449                $items = $root.find('.js-counter-item'),
1450                type = $root.data('countdown-type'),
1451                scenarioIndex;
1452
1453            var cases = {
1454                    months: ['Месяц', 'Месяца', 'Месяцев'],
1455                    daysToMonth: ['День', 'Дня', 'Дней'],
1456                    hours: ['Час', 'Часа', 'Часов'],
1457                    minutes: ['Минута', 'Минуты', 'Минут'],
1458                    seconds: ['Секунда', 'Секунды', 'Секунд']
1459                },
1460                scenaries = [
1461                    ['months', 'daysToMonth', 'hours'], //months
1462                    ['daysToMonth', 'hours', 'minutes'], //days
1463                    ['hours', 'minutes', 'seconds'] //hours
1464                ];
1465
1466            var templateEnded1 = '<div class="tender-skew tender-ended-block">\n' +
1467                '                                        <div class="tender-skew-compensate">\n' +
1468                '                                            Прием заявок закрыт \n' +
1469                '                                        </div>\n' +
1470                '                                    </div>',
1471                templateEnded2 = '<div class="renders-one-side-block renders-one-side-block--gray h-100">\n' +
1472                    '                                            <div class="renders-one-side-block__title">Прием заявок <br class="d-none d-xl-block">закрыт</div>\n' +
1473                    '                                        </div>';
1474
1475            $root.countdown(dateStr, {})
1476                .on('update.countdown', function(e) {
1477                    if(!scenarioIndex) {
1478                        scenarioIndex = resolveScenario(e.offset);
1479                    }
1480                    scenaries[scenarioIndex].forEach(function(item, index) {
1481                        var value = e.offset[item],
1482                            $item = $items.eq(index),
1483                            $value = $item.children('.js-counter-num');
1484                        if(parseInt($value.text()) !== value) {
1485                            $value.text(value);
1486                            $item.children('.js-counter-label').text(
1487                                cases[item][getCase(value)]
1488                            );
1489                        }
1490                    })
1491                })
1492                .on('finish.countdown', function() {
1493                    if(type === 1) {
1494                        $root.replaceWith(templateEnded1);
1495                    } else if(type === 2) {
1496                        $root.closest('.js-counter-parent').replaceWith(templateEnded2);
1497                        $('.js-tenders-apply-btn').remove();
1498                    }
1499                });
1500        });
1501
1502        function resolveScenario(dateObj) {
1503            if(dateObj.months !== 0) return 0; //months
1504            else if(dateObj.daysToMonth !==0) return 1; //days
1505            else return 2; //hours
1506        }
1507
1508        function getCase(n) {
1509            n = Math.abs(n) % 100; var n1 = n % 10;
1510            if (n > 10 && n < 20) return 2;
1511            if (n1 > 1 && n1 < 5) return 1;
1512            if (n1 === 1) return 0;
1513            return 2;
1514        }
1515    };
1516
1517    (function() {
1518       var $counters = $('.js-counter');
1519       if(!$counters.length) return;
1520       initCounter();
1521    })();
1522    /* !Counter */
1523
1524
1525    /* Sticky block */
1526    var initStickyBlock = function($container) {
1527        $container = $container || $(document);
1528        var $items = $container.find('.js-sticky-block');
1529        if(!$items.length) return;
1530
1531        $items.each(function(_, item) {
1532           var $item = $(item),
1533               breakpointInit = parseInt($item.data('breakpoint-init')) || null,
1534               breakpointDestroy = parseInt($item.data('breakpoint-destroy')) - 1 || null,
1535               isInitialized = false,
1536               parent = $item.closest('.js-sticky-block-parent') || $item.parent(),
1537               offsetHeight = $(window).height()-$item.height();
1538
1539                process();
1540
1541                if(moduleResize) {
1542                    moduleResize.width({
1543                        userFunction: process
1544                    });
1545                }
1546
1547                function process() {
1548                    if(!isInitialized && isMatch(breakpointInit, breakpointDestroy)) {
1549                        if ($item.hasClass('sticky-btn')) {
1550                            $item.stick_in_parent({offset_top: offsetHeight}); //Button on mobile
1551                        } else {
1552                            $item.stick_in_parent({offset_top: 128, parent: parent}); //Block on desktop and tablet
1553                        }
1554                        isInitialized = true;
1555                    } else if(isInitialized && !isMatch(breakpointInit, breakpointDestroy)) {
1556                        $item.trigger('sticky_kit:detach');
1557                        isInitialized = false;
1558                    }
1559                }
1560        });
1561
1562        function isMatch(breakpointInit, breakpointDestroy) {
1563            var queryString = '';
1564            if (breakpointInit && breakpointDestroy) {
1565                queryString = '(min-width: {brInit}px) and (max-width: {brDestroy}px)';
1566            } else if (breakpointInit) {
1567                queryString = '(min-width: {brInit}px)';
1568            } else if(breakpointDestroy) {
1569                queryString = '(min-width: {brDestroy}px)';
1570            } else {
1571                return true;
1572            }
1573            queryString = queryString
1574                .replace('{brInit}', breakpointInit)
1575                .replace('{brDestroy}', breakpointDestroy);
1576            return window.matchMedia(queryString).matches;
1577        }
1578    };
1579
1580    initStickyBlock();
1581    /* !Sticky block */
1582
1583
1584    /* Datepicker */
1585    var datetimepicker = (function() {
1586        var monthLocale = {
1587                en: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
1588                ru: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь']
1589            },
1590            dayLocale = {
1591                en: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
1592                ru: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб']
1593            },
1594            firstDayLocale = {
1595                en: 0,
1596                ru: 1
1597            };
1598
1599        var options = {
1600            monthNames: monthLocale['ru'],
1601            dayNamesMin: dayLocale['ru'],
1602            firstDay: firstDayLocale['ru'],
1603            dateFormat: "dd.mm.yy",
1604        };
1605
1606        return {
1607            init: init
1608        };
1609
1610        function init($container) {
1611            $container = $container || $(document);
1612            var $elements = $container.find('.js-datepicker');
1613
1614            if(!$elements.length) return;
1615
1616            $elements.each(function(_, element) {
1617               var $element = $(element),
1618                   $master = $('#' + $element.data('entangled-id')),
1619                   isSub = $master.data('sub') || false;
1620               $element.datepicker(options);
1621
1622               if($master.length) {
1623                   $element.on("change", function() {
1624                       var $this = $(this),
1625                           thisVal = $this.datepicker('getDate'),
1626                           masterVal = $master.datepicker('getDate');
1627                       if(new Date(thisVal) < new Date(masterVal)) {
1628                           $this.datepicker('setDate', masterVal);
1629                       }
1630                   });
1631                   if(isSub){
1632                       $master.on("change", function() {
1633                           $element.datepicker("option", "minDate", $(this).datepicker('getDate'));
1634                       });
1635                   }
1636               }
1637            });
1638        }
1639    })();
1640
1641    datetimepicker.init();
1642    /* !Datepicker */
1643
1644/*innovations*/
1645    /* Timepicker */
1646    var timepicker = (function() {
1647        var monthLocale = {
1648                en: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
1649                ru: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь']
1650            },
1651            dayLocale = {
1652                en: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
1653                ru: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб']
1654            },
1655            firstDayLocale = {
1656                en: 0,
1657                ru: 1
1658            };
1659
1660        var options = {
1661            showSecond: 0,
1662            showMillisec: 0,
1663            showMicrosec: 0,
1664            showTimezone: 0,
1665        };
1666
1667        return {
1668            init: init
1669        };
1670
1671        function init($container) {
1672            $container = $container || $(document);
1673            var $elements = $container.find('.js-timepicker');
1674
1675            if(!$elements.length) return;
1676
1677			$.timepicker.regional['ru'] = {
1678				timeOnlyTitle: 'Выберите время',
1679				timeText: 'Время',
1680				hourText: 'Часы',
1681				minuteText: 'Минуты',
1682				secondText: 'Секунды',
1683				millisecText: 'Миллисекунды',
1684				timezoneText: 'Часовой пояс',
1685				currentText: 'Сейчас',
1686				closeText: 'Закрыть',
1687				timeFormat: 'HH:mm',
1688				amNames: ['AM', 'A'],
1689				pmNames: ['PM', 'P'],
1690				isRTL: false
1691			};
1692			$.timepicker.setDefaults($.timepicker.regional['ru']);
1693	
1694			$elements.each(function(_, element) {
1695               var $element = $(element),
1696                   $master = $('#' + $element.data('entangled-id')),
1697                   isSub = $master.data('sub') || false;
1698				$element.timepicker( {	showSecond: false,
1699										showMillisec: false,
1700										showMicrosec: false,
1701									  	showTimezone: false});
1702
1703               if($master.length) {
1704                   $element.on("change", function() {
1705                       var $this = $(this),
1706                           thisVal = $this.timepicker('getTime'),
1707                           masterVal = $master.timepicker('getTime');
1708                       if(new Time(thisVal) < new Time(masterVal)) {
1709                           $this.timepicker('setTime', masterVal);
1710                       }
1711                   });
1712                   if(isSub){
1713                       $master.on("change", function() {
1714                           $element.timepicker("option", "minTimee", $(this).timepicker('getTime'));
1715                       });
1716                   }
1717               }
1718           });
1719        }
1720    })();
1721
1722    timepicker.init();
1723   /* innovations!Timepicker */
1724
1725    /* Price input */
1726    var initPriceInput = (function () {
1727
1728        return init;
1729
1730        function init($outer) {
1731            if(typeof $outer === 'undefined') {
1732                $outer = $(window);
1733            } else if(!$outer.length) {
1734                console.error('outer element not found');
1735                return;
1736            }
1737            var $root = $outer.find('.js-price-input-wrapper');
1738            if(!$root.length) return;
1739            $root.each(function(_, root) {
1740                var $root = $(root),
1741                    $input = $root.find('.js-price-input'),
1742                    $placeholder = $root.find('.js-price-input-placeholder'),
1743                    $value = $root.find('.js-price-input-placeholder-value');
1744
1745                $input.on('blur', function() {
1746                    var $this = $(this),
1747                        value = $this.val();
1748                    $root.removeClass('focus');
1749                    if(value.length) {
1750                        value = numberWithSpaces(value);
1751                        $value.text(value);
1752                        $root.removeClass('empty');
1753                    } else {
1754                        $value.text('');
1755                        $root.addClass('empty');
1756                    }
1757                });
1758
1759                $input.on('focus', function() {
1760                    $root.addClass('focus');
1761                });
1762
1763                $placeholder.on('click', function() {
1764                    $root.addClass('focus');
1765                    $input.trigger('focus');
1766                });
1767            });
1768        }
1769
1770        //utility
1771        function numberWithSpaces(x) {
1772            return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
1773        }
1774    })();
1775    /* !Price input */
1776
1777
1778    /* Activity page */
1779    (function() {
1780        var vSliderContainer = document.querySelector('.js-v-slider'),
1781            $hSliderContainer = $('.js-h-slider');
1782        if(!!vSliderContainer) {
1783            new Swiper(vSliderContainer, {
1784                direction: 'vertical',
1785                loop: false,
1786                mousewheel: {
1787                    eventsTarget: document.body,
1788                    releaseOnEdges: true,
1789                },
1790                noSwiping: true,
1791                touchReleaseOnEdges: true,
1792                pagination: {
1793                    el: '.js-v-slider-pagination',
1794                    clickable: true,
1795                    renderBullet: function(index, className) {
1796                        var current = index + 1,
1797                            monthString = (current < 10) ? '0' + current : current;
1798                        return '<div class="v-slider-progress-item ' + className + '">\n' +
1799                            '       <div class="v-slider-progress-item__num">' + monthString + '</div>\n' +
1800                            '       <div class="v-slider-progress-item__decor"></div>\n' +
1801                            '   </div>'
1802                    }
1803                },
1804                breakpoints: {
1805                    1350: {
1806                        noSwiping: false
1807                    }
1808                },
1809                on: {
1810                    init: function() {
1811                        setTimeout(function() {
1812                            $('html, body').scrollTop(0);
1813                        }, 500);
1814                        var prevRatio = null,
1815                            enableSliderScroll = function() {
1816                                this.mousewheel.enable();
1817                                this.allowTouchMove = true;
1818                            }.bind(this),
1819                            disableSliderScroll = function() {
1820                                this.mousewheel.disable();
1821                                this.allowTouchMove = false;
1822                            }.bind(this);
1823                        new IntersectionObserver(function(entries) {
1824                            var entry = entries[0],
1825                                ratio = entry.intersectionRatio;
1826                            ratio > prevRatio ? enableSliderScroll() : disableSliderScroll();
1827                            prevRatio = ratio;
1828                        }, {
1829                           root: null,
1830                           threshold: 0.9
1831                        }).observe(vSliderContainer);
1832                    },
1833                    slidePrevTransitionStart: function() {
1834                        $(window).scrollTop(0);
1835                    }
1836                }
1837            });
1838        }
1839        if($hSliderContainer.length) {
1840            $hSliderContainer.each(function(i, container) {
1841                new Swiper(container, {
1842                    direction: 'horizontal',
1843                    loop: true,
1844                    nested: true,
1845                    effect: 'fade',
1846                    noSwiping: true,
1847                    navigation: {
1848                        nextEl: '.js-h-slider-next-' + i,
1849                        prevEl: '.js-h-slider-prev-' + i
1850                    },
1851                    pagination: {
1852                        el: '.js-h-slider-pagination-' + i,
1853                        clickable: true
1854                    },
1855                });
1856            });
1857        }
1858    })();
1859    /* !Activity page */
1860
1861
1862    /* Tenders page */
1863    (function() {
1864        var $pageNavWrapper = $('.js-tenders-page-nav');
1865
1866        if($pageNavWrapper.length) {
1867            initTabSlider($pageNavWrapper, function ($wrapper, $tab) {
1868                initToggler($wrapper);
1869                datetimepicker.init($wrapper);
1870                initCounter($wrapper);
1871                initClearFilter();
1872                initFilterTrigger();
1873                initPriceInput($wrapper);
1874            });
1875        }
1876    })();
1877    /* !Tenders page */
1878
1879
1880    /* Msp page */
1881    (function() {
1882        var $pageNavWrapper = $('.js-msp-page-nav');
1883
1884        if($pageNavWrapper.length) {
1885            initTabSlider($pageNavWrapper, function ($wrapper, $tab) {
1886                initSlider($wrapper.find('.js-slider-wrap'));
1887            });
1888        }
1889    })();
1890    /* !Msp page */
1891
1892
1893    /* Investors page */
1894    (function() {
1895       var $tabSliderEl = $('.js-investors-tab-slider'),
1896           $tabsWrapper = $('.js-left-nav-wrapper');
1897       if($tabSliderEl.length && $tabsWrapper.length) {
1898           $tabSliderEl.each(function(_, slider) {
1899               var $slider = $(slider),
1900                   $tabs = $tabsWrapper.filter('[data-index="' + $slider.data('index') + '"]');
1901               if($tabs.length) {
1902                   initTabSlider($slider, function(_, $tab) {
1903                       var index = $tab.index(),
1904                           relatedTab = $tabs.find('.js-tabs-nav-item')[index];
1905                       if(!!relatedTab) {
1906                           relatedTab.click();
1907                       }
1908                   });
1909               }
1910           })
1911       }
1912       if($tabsWrapper.length) {
1913           initTabs($tabsWrapper);
1914       }
1915    })();
1916    /* !Investors page */
1917
1918
1919
1920    /* Detail project */
1921    (function() {
1922        var $pageNavWrapper = $('.js-detail-project-page-nav');
1923
1924        if($pageNavWrapper.length) {
1925            initTabSlider($pageNavWrapper, function ($wrapper, $tab) {
1926                initSlider($wrapper.find('.js-slider-wrap'));
1927                initScrollBar();
1928            });
1929        }
1930    })();
1931    /* !Detail project */
1932
1933
1934    /* Investors chart */
1935    (function() {
1936        var $root = $('.js-chart-wrapper');
1937        if(!$root.length) return;
1938
1939        var constants = { //constants
1940            $root: $root,
1941            $titles: $root.find('.js-chart-title'),
1942            points: $root.data('points'),
1943            breakpoints: {
1944                xl: 1024,
1945                md: 768
1946            },
1947        };
1948
1949        var state = { //state
1950            chart: null,
1951            observer: null,
1952            isInitialized: false
1953        };
1954
1955        CanvasJS.addColorSet('lgColorSet', [
1956            '#C4C4C4',
1957            '#DF6F4C'
1958        ]);
1959
1960        CanvasJS.addColorSet('mdColorSet', [
1961            '#E8B550',
1962            '#DD9046'
1963        ]);
1964
1965        if (cookieModule.get('spec') && cookieModule.get('spec') === 'spec_On'){
1966            CanvasJS.addColorSet('lgColorSet', [
1967                '#686868',
1968                '#000000'
1969            ]);
1970
1971            CanvasJS.addColorSet('mdColorSet', [
1972                '#686868',
1973                '#686868'
1974            ]);
1975        }
1976
1977        //initial CanvasJS options
1978        var options = (function setInitials() {
1979            var options = {
1980                animationEnabled: true,
1981                colorSet: "lgColorSet",
1982                backgroundColor: 'rgba(0, 0, 0, 0)',
1983                toolTip:{
1984                    enabled: false,
1985                },
1986                data: [{
1987                    type: "doughnut",
1988                    startAngle: 0,
1989                    indexLabelFontSize: 12,
1990                    innerRadius: '70%',
1991                    dataPoints: [],
1992                    mouseout: function() {
1993                        constants.$titles
1994                            .addClass('chart-title--hidden')
1995                            .eq(constants.$titles.length - 1).removeClass('chart-title--hidden');
1996                    }
1997                }]
1998            };
1999            if($.isArray(constants.points)) { //add sectors to chart
2000                constants.points.forEach(function(point) {
2001                    point.indexLabelFontColor = 'rgba(73, 70, 70, 0.7)';
2002                    point.mouseover = function(e) {
2003                        var index = e.dataPointIndex,
2004                            $title = constants.$titles.eq(index);
2005                        constants.$titles.addClass('chart-title--hidden');
2006                        $title.removeClass('chart-title--hidden');
2007                    };
2008                    options.data[0].dataPoints.push(point);
2009                });
2010            }
2011            return options;
2012        })();
2013
2014        var extendOptions = function(options) { // modify options depending on screen width
2015            var extendedOptions = $.extend({}, options);
2016            if(window.matchMedia('(max-width: ' + constants.breakpoints.xl + 'px)').matches) {
2017                extendedOptions.colorSet = 'mdColorSet';
2018                extendedOptions.animationEnabled = false;
2019            }
2020            if(window.matchMedia('(max-width: ' + constants.breakpoints.md + 'px)').matches) {
2021                extendedOptions.data[0].innerRadius = '80%';
2022            }
2023            return extendedOptions;
2024        };
2025
2026        var init = function(options) {
2027            var extendedOptions = extendOptions(options);
2028            state.chart = new CanvasJS.Chart('chart-container', extendedOptions);
2029            if(window.matchMedia('(max-width: ' + constants.breakpoints.xl + 'px)').matches) {
2030                //don't need to use IntersectionObserver
2031                state.chart.render();
2032                state.isInitialized = true;
2033                constants.$root.addClass('initialized');
2034            } else {
2035                state.observer = new IntersectionObserver(function(entries) {
2036                    var entry = entries[0];
2037                    if(entry.isIntersecting) {
2038                        state.chart.render();
2039                        state.isInitialized = true;
2040                        constants.$root.addClass('initialized');
2041                    }
2042                }, {
2043                    root: null,
2044                    threshold: 1.0
2045                });
2046                state.observer.observe(state.chart.container);
2047            }
2048        };
2049
2050        init(options);
2051    })();
2052
2053    /*Hover on center chart*/
2054    $('.chart-title-hover').on('mouseover', function () {
2055        $(this).removeClass('chart-hidden');
2056        $('.chart-title').each(function(ind, elem) {
2057            $(elem).addClass('chart-hidden');
2058        });
2059    });
2060    $('.chart-title-hover').on('mouseout', function () {
2061        $(this).addClass('chart-hidden');
2062        $('.chart-title').each(function(ind, elem) {
2063            $(elem).removeClass('chart-hidden');
2064        });
2065    });
2066    /* !Investors chart */
2067
2068    $('.js-view-change-trigger').on('click', function(e) {
2069        e.preventDefault();
2070        if($(this).hasClass('active')) return;
2071        $('.js-view-change-trigger').removeClass('active');
2072        $('.js-view-change-view').toggleClass('view-table');
2073        $(this).addClass('active');
2074    });
2075
2076
2077    (function () {
2078        var $accordeons = $('.js-accordeon-trigger');
2079        if(!$accordeons.length) return;
2080        $accordeons.on('click', function() {
2081            $(this).toggleClass('active');
2082        });
2083    })();
2084
2085    (function () {
2086        var $triggers = $('.js-accordeon-trigger');
2087        if(!$triggers.length) return;
2088        $triggers.on('click', function() {
2089            $(this).closest('.js-accordeon').toggleClass('active');
2090        });
2091    })();
2092
2093    $('.js-stop-propagation--click').on('click', function(e) {
2094        e.stopPropagation();
2095    });
2096
2097    $('.js-program-trigger').on('click', function() {
2098        var $newActive = $(this).closest('.js-program-item');
2099        $('.js-program-item').removeClass('active');
2100        $newActive.toggleClass('active');
2101        setTimeout(function() {
2102            $('html, body').animate({
2103                scrollTop: $newActive.offset().top - 70
2104            }, 600);
2105        }, 0);
2106    });
2107
2108    function initScrollBar(offsetLeft) {
2109        var $scrollX = $('.js-custom-scroll-h');
2110        if(!$scrollX.length) return;
2111        if(typeof $scrollX.data('offset') !== 'undefined') {
2112            offsetLeft = $scrollX.data('offset');
2113        }
2114        if(window.matchMedia('(max-width: 767px)').matches) {
2115            $scrollX.each(function(index, element) {
2116                $(element).mCustomScrollbar({
2117                    axis: "x",
2118                    setLeft: offsetLeft
2119                });
2120            });
2121        }
2122    }
2123    initScrollBar("85px");
2124
2125
2126    //Spec version
2127    var specTog = $('.js_adapt');
2128    specTog.on('click', function (e) {
2129        e.preventDefault();
2130        var it = $(this),
2131            act = it.hasClass('active');
2132
2133        if (!act) it.addClass('active');
2134        else it.removeClass('active');
2135    });
2136    try {
2137        specTog.vmspec({
2138            activated: function () {
2139            },
2140            deactivated: function () {
2141            }
2142        });
2143    } catch(e) {
2144        console.log(e);
2145    }
2146
2147    function initFilterTrigger() {
2148        var $filterTrigger = $('.js-side-filter-trigger'),
2149            $filterSlide = $('.js-side-filter');
2150            $filterTrigger.each(function(index, element) {
2151                $(element).on('click', function () {
2152                    $filterSlide.toggleClass('open');
2153                });
2154            });
2155    }
2156    initFilterTrigger();
2157
2158    (function() {
2159        var $calendar = $('.js-side-filter-calendar'),
2160            $calendarResult = $('.js-side-filter-calendar-result');
2161        if(!$calendar.length || !$calendarResult.length) return;
2162        var $inputs = $calendar.find('input');
2163        $inputs.on('change', function() {
2164           var year, month;
2165            $inputs.filter(':checked').each(function(_, input) {
2166                var val = $(input).parent().find('label').text(),
2167                    valNumber = parseInt(val);
2168                if(valNumber === valNumber) year = val; //if not NaN
2169                else month = val;
2170            });
2171            if(year && month) {
2172                $calendarResult.text(month + ' ' + year);
2173            }
2174        });
2175    })();
2176
2177    $.fancybox.defaults.backFocus = false;
2178    /**/
2179    $('.show-more').on('click', function() {
2180        $.ajax({
2181            data: $(this).attr('data-offset'),
2182            type: 'POST',
2183            url: "/ajax/getnewsone_adaptive.php",
2184            success: function () {
2185                console.log('Успех');
2186                }
2187        });
2188    });
2189
2190     var initClearFilter = function() {
2191         var $filter = $('.js-clear-filter');
2192         if ($filter.length) {
2193             $filter.each(function(index, element) {
2194                 $(element).on('click', function () {
2195                     var $form = $(element).closest('form'),
2196                         $inputs = $form.find('input.form-control');
2197                     $inputs.each(function(ind, elem) {
2198                         $(elem).val('');
2199                     });
2200                     $form.submit();
2201                 });
2202             });
2203         }
2204    };
2205    initClearFilter();
2206
2207     //Change title btn submit on filter regulatory information
2208     if (screen.width >= 768 && screen.width < 1024) {
2209         $('.reg-doc-section .btn.resolve-form__submit').val('Поиск');
2210     }
2211
2212     /* Disabled button submit in filter on detail page "Regulatory information" */
2213    var disabledBtnSubmit = function(btnSubmit) {
2214        if (btnSubmit.length) {
2215            var form = $(btnSubmit).closest('form'),
2216                massFields = $(form).find('input:not([type="submit"])'),
2217                checkFields = function() {
2218                    var massResult = $.map(massFields, function (element, index) {
2219                        return Boolean($(element).val());
2220                    });
2221                    if (massResult.includes(true)) {
2222                        $(btnSubmit).removeAttr('disabled');
2223                    } else {
2224                        $(btnSubmit).attr('disabled', 'disabled');
2225                    }
2226                };
2227            checkFields();
2228
2229            $(massFields).each(function (index, element) {
2230                $(element).on('keyup change', function () {
2231                    checkFields();
2232                });
2233            });
2234        }
2235    };
2236    disabledBtnSubmit($('.reg-doc-outer .resolve-form__submit'));
2237
2238    /* Limiting name of documents on a page "For investors" */
2239    var limitFileName = function () {
2240        var heightLines, screenWidth = screen.width;
2241        heightLines = 75;
2242        if (screenWidth < 768) {
2243            heightLines = 100;
2244        }
2245        if (screenWidth >= 1024 && screenWidth < 1230) {
2246            heightLines = 50;
2247        }
2248
2249        var dotElement = $('.file-block__name');
2250        if(dotElement.length){
2251            dotElement.dotdotdot({
2252                ellipsis: "\u2026 ",
2253                height: heightLines,
2254                truncate: "word",
2255            });
2256        }
2257    };
2258    limitFileName();
2259
2260    /* Limiting text in option in select on a page "For drivers" */
2261    var limitOptionText = function () {
2262            var $form = $('.js-calculator-form');
2263            if ($form.length) {
2264                var $field = $form.find('.select2[data-select2-id=5]'),
2265                    $parent = $field.closest('.resolve-form-item'),
2266                    $select = $parent.find('select');
2267                $select.on('select2:select', function () {
2268                    var $option = $field.find('.select-styled__option-text'),
2269                        $ico = $field.find('.select-styled__option-ico-wrapper'),
2270                        $arrow = $field.find('.select2-selection__arrow'),
2271                        $result = $field.width() - $ico.width() - $arrow.width();
2272                    if ($option.width() > $result) {
2273                        $option.width($result);
2274                        $option.css('overflow', 'hidden');
2275                        $option.css('text-overflow', 'ellipsis');
2276                    }
2277                });
2278            }
2279    };
2280    limitOptionText();
2281
2282
2283    (function () {
2284        var $form = $('.js-form-autosubmit'),
2285            $xlEnabled = $form.find('.js-xl-enabled'),
2286            $xlDisabled = $form.find('.js-xl-disabled');
2287        $form.on('change', function() {
2288            if(window.matchMedia('(min-width: 1024px)').matches) {
2289                $xlEnabled.removeAttr('disabled');
2290                $xlDisabled.attr('disabled', '');
2291            } else {
2292                $xlDisabled.removeAttr('disabled');
2293                $xlEnabled.attr('disabled', '');
2294            }
2295            this.submit();
2296        });
2297    })();
2298
2299});
2300

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.