PageSourceSearch

https://fulcosystem.com/static/js/scripts.js?t=1791444335

js fulcosystem.com collected 2026-10-08 07:26:10 UTC 59,455 bytes, 1,849 lines download raw bytes

1var body,
2    debugMode = false,
3    windowWidth = 0,
4    windowHeight = 0,
5    desktopWidth = 1139, /* Desktop powyżej podanej wielkosci */
6    tabletWidth = 639, /* Tablet powyżej podanej wielkości */
7    mobileSize, /* Przedział poniżej tabletu, nie definiowany */
8    devbar_pages = [];
9
10$(function () {
11    body = $('body');
12    windowSize();
13    $(window).bind('resize load', function () {
14        windowSize(); // musi byc przed debugView
15        debugView();
16        stickyFooter();
17    });
18
19    labelLinkFix();
20    stickyHeader();
21    rwdMenuHandler();
22    langsMenuHandler();
23    initFooterNavSlider();
24    initTooltips();
25    initSelect2();
26    initiCheck();
27    footerToggleHandler();
28    rwdMenuActions();
29    initMovingElements();
30
31    // Bind header top-box elements
32    $('.top-box-container').each(function () {
33        DelayedHoverHandler.add($(this), {
34            leaveDelay: 120,
35        });
36    });
37
38    DelayedHoverHandler.add($('#main-menu > ul > li'), {
39        enterDelay: 150,
40        leaveDelay: 200,
41    });
42
43    // fillView();
44    /*
45    initFancybox();
46    initMatchHeight();
47    initLazyLoad();
48    menuHover();
49    */
50
51    initSavedProducts();
52
53    ElementsMovingHandler.add({
54        element: $('.footer-col-4'),
55        resolution: 1280,
56        from: {
57            element: $('.footer-cols'),
58            method: 'appendTo',
59        },
60        to: {
61            element: $('.footer-col-3'),
62            method: 'appendTo',
63        }
64    });
65
66    if ($('header .langs-menu').length) {
67        ElementsMovingHandler.add({
68            element: $('header .langs-menu'),
69            resolution: 1140,
70            from: {
71                element: $('header'),
72                method: 'prependTo',
73            },
74            to: {
75                element: $('header > .container'),
76                method: 'appendTo',
77            }
78        });
79    }
80
81    /* Handle grayscale when hovering parent */
82    $('.gray-hover').bind('hover', function () {
83        $(this).addBack().find('.gray-target, .grayscale').toggleClass('grayscale-off');
84    });
85
86
87    /* Handle lines animation when in viewport */
88    $('.static-lines.static-lines-corner').uAnimate({
89        timeout: 400,
90    });
91
92
93    // $('.footer-col-1 img').uAnimate({
94    //     classToAdd: 'opacityToLeft',
95    //     timeout: 0,
96    // });
97
98
99    /* Initialize sliders */
100    var fullsliders = [];
101    $('.section-fullslider').each(function (i, el) {
102        var fullslider = new Fullslider($(el));
103        fullsliders.push(fullslider);
104        fullslider.init();
105    });
106
107    $('.page-col > .heading, .page-col .page-col-title').matchHeight({property: 'min-height'});
108
109    /* Initialize product sliders */
110    $('.productsSlider-container').not('.no-slider .productsSlider-container').each(function () {
111        var $this = $(this);
112        $this.find('.product-list').slick({
113            infinite: true,
114            slidesToShow: 6,
115            slidesToScroll: 1,
116            fade: false,
117            autoplay: true,
118            autoplaySpeed: 5000,
119            dots: false,
120            arrows: true,
121            prevArrow: $this.find('.slider-prev'),
122            nextArrow: $this.find('.slider-next'),
123            waitForAnimate: false,
124            responsive: [
125                {
126                    breakpoint: 1281,
127                    settings: {
128                        slidesToShow: 5,
129                    }
130                },
131                {
132                    breakpoint: 1025,
133                    settings: {
134                        slidesToShow: 4,
135                    }
136                },
137                {
138                    breakpoint: 768,
139                    settings: {
140                        slidesToShow: 3,
141                    }
142                },
143                {
144                    breakpoint: 580,
145                    settings: {
146                        slidesToShow: 2,
147                    }
148                },
149                {
150                    breakpoint: 380,
151                    settings: {
152                        slidesToShow: 1,
153                    }
154                },
155            ]
156        })
157    });
158
159    /* Initialize article sliders */
160    $('.articlesSlider-container').not('.no-slider .articlesSlider-container').each(function () {
161        var $this = $(this);
162        $this.find('.articlebox-list').slick({
163            infinite: true,
164            slidesToShow: 4,
165            slidesToScroll: 1,
166            fade: false,
167            autoplay: true,
168            autoplaySpeed: 5000,
169            dots: false,
170            arrows: true,
171            prevArrow: $this.find('.slider-prev'),
172            nextArrow: $this.find('.slider-next'),
173            waitForAnimate: false,
174            responsive: [
175                {
176                    breakpoint: 1441,
177                    settings: {
178                        slidesToShow: 3
179                    }
180                },
181                {
182                    breakpoint: 1140,
183                    settings: {
184                        slidesToShow: 2
185                    }
186                },
187                {
188                    breakpoint: 640,
189                    settings: {
190                        slidesToShow: 1
191                    }
192                }
193            ]
194        });
195    });
196
197    /* When hovering on product list with category tiles - add helper class */
198    var $productLists = $('.product-list');
199    if ($productLists.length) {
200        $('.product-list-category-item').bind('mouseenter', function () {
201            var $this = $(this);
202            var $list = $this.closest('.product-list');
203            $list.addClass('hovering-category');
204        }).bind('mouseleave', function () {
205            var $this = $(this);
206            var $list = $this.closest('.product-list');
207            $list.removeClass('hovering-category');
208        });
209    }
210});
211
212function initTooltips() {
213    // Init standard tooltips
214    $('.tooltipable').tooltip();
215
216    // Init tooltips with title and text
217    // data-title="tytuł"
218    // data-text="lorem ipsum lorem ipsum lorem ipsum"
219    $('.tooltipable-badge').each(function () {
220        var $this = $(this),
221            content = "";
222        if ($this.data('title')) {
223            content += '<div class="tooltip-title">' + $this.data('title') + '</div>';
224        }
225        if ($this.data('text')) {
226            content += '<div class="tooltip-text">' + $this.data('text') + '</div>';
227        }
228        if (content) {
229            content = '<div class="tooltip-content">' + content + '</div>';
230        }
231        $this.tooltip({
232            html: true,
233            placement: 'auto top',
234            title: content,
235        });
236    });
237}
238
239/**
240 * jQuery Fancybox
241 */
242function initFancybox() {
243    try {
244        $('a.fancy').fancybox({});
245    }
246    catch (err) {
247        console.log('Library jQuery Fancybox doesn`t exsist');
248    }
249}
250
251/**
252 * jQuery iCheck
253 */
254function initiCheck() {
255    try {
256        $('input[type="radio"], input[type="checkbox"]').iCheck({
257            checkboxClass: 'icheckbox_minimal-custom',
258            radioClass: 'iradio_minimal-custom',
259            increaseArea: '20%'
260        });
261    }
262    catch (err) {
263        console.log('Library jQuery iCheck doesn`t exsist');
264    }
265}
266
267/**
268 * jQuery Select 2
269 */
270function initSelect2() {
271    try {
272        $('.select2 select').each(function () {
273            var $this = $(this);
274            $this.select2({
275                dropdownParent: $this.parent(),
276                minimumResultsForSearch: Infinity,
277            });
278        });
279
280        // Fancybox
281        // $('.savedProducts-select2 select').each(function() {
282        //     var $this = $(this);
283        //     $this.select2({
284        //         dropdownParent: $this.parent(),
285        //         minimumResultsForSearch: Infinity,
286        //     });
287        // });
288    }
289    catch (err) {
290        console.log('Library jQuery Select2 doesn`t exsist');
291    }
292}
293
294/**
295 * jQuery MatchHeight
296 */
297function initMatchHeight() {
298    try {
299        $('.match').matchHeight();
300    }
301    catch (err) {
302        console.log('Library jQuery matchHeight doesn`t exsist');
303    }
304}
305
306/**
307 * jQuery LazyLoad
308 */
309function initLazyLoad() {
310    try {
311        $(".lazyload").lazyload({
312            threshold: 200
313        });
314    }
315    catch (err) {
316        console.log('Library jQuery lazyload doesn`t exsist');
317    }
318}
319
320
321/**
322 * RWD menu
323 */
324function rwdMenuHandler() {
325    var $header = $('header');
326    var $rwdMenuWraper = $('.rwd-menu-wrapper');
327
328    $(".nav-toggle").bind('click touch', function () {
329        $('.rwd-menu').css('padding-top', $('#container-page').offset().top);
330        $rwdMenuWraper.css('margin-top', $header.height());
331        $rwdMenuWraper.css('padding-bottom', $header.height());
332
333        if ($(this).hasClass('active')) {
334            rwdMenuHide();
335        } else {
336            rwdMenuShow();
337        }
338        return false;
339    });
340}
341
342function rwdMenuShow() {
343    langsMenuHide();
344
345    $(".nav-toggle").addClass('active');
346    body.addClass('body-block');
347    $('.rwd-menu').slideDown();
348}
349
350function rwdMenuHide() {
351    $(".nav-toggle").removeClass('active');
352    body.removeClass('body-block');
353    if (windowWidth >= 1140) {
354        $('.rwd-menu').css('display', 'none');
355    } else {
356        $('.rwd-menu').slideUp();
357    }
358}
359
360/**
361 * Languages menu
362 */
363function langsMenuHandler() {
364    $('.lang-button').bind('click touch', function () {
365        var $header = $('header');
366        var $rwdLangWrapper = $('.rwd-lang-wrapper');
367
368        $('.rwd-lang').css('padding-top', $('#container-page').offset().top);
369        $rwdLangWrapper.css('margin-top', $header.height());
370        $rwdLangWrapper.css('padding-bottom', $header.height());
371
372        if ($('.langs-menu').hasClass('active')) {
373            langsMenuHide();
374        } else {
375            langsMenuShow();
376        }
377        return false;
378    });
379}
380
381function langsMenuShow() {
382    rwdMenuHide();
383
384    $('.langs-menu').addClass('active');
385    $('.langs-menu > ul').slideDown();
386    $('.rwd-lang').slideDown();
387    body.addClass('body-block');
388}
389
390function langsMenuHide() {
391    $('.langs-menu').removeClass('active');
392    $('.langs-menu > ul').slideUp();
393    if (windowWidth >= 1140) {
394        $('.rwd-lang').css('display', 'none');
395    } else {
396        $('.rwd-lang').slideUp();
397    }
398    body.removeClass('body-block');
399}
400
401function rwdMenuActions() {
402    $('.rwd-menu ul li a').bind('click touch', function () {
403        var $this = $(this),
404            li = $(this).closest('li'),
405            child = li.find('ul:first');
406
407        if ($this.attr('href') != undefined) {
408            return true;
409        }
410
411        if (child.length) {
412            if (li.hasClass('active')) {
413                child.slideUp();
414                li.removeClass('active');
415            } else {
416                child.slideDown();
417                li.addClass('active');
418            }
419            return false;
420        }
421    });
422    $('.rwd-menu ul li .pull-right').bind('click', function () {
423        var $this = $(this).parent(),
424            li = $(this).closest('li'),
425            child = li.find('ul:first'),
426
427            ul = $(this).closest('ul');
428
429        ul.find('li.active').not(li).find('ul:first').slideUp('slow', function () {
430            $(this).parent().removeClass('active')
431        });
432
433
434        if (child.length) {
435            if (li.hasClass('active')) {
436                child.slideUp();
437                li.removeClass('active');
438            } else {
439                child.slideDown();
440                li.addClass('active');
441            }
442            return false;
443        }
444    });
445}
446
447/**
448 * Sticky footer
449 */
450function stickyFooter() {
451    var $height = $("#container-page > footer").outerHeight();
452    $("body.sticky-footer #page").css({
453        marginBottom: -$height + "px",
454        paddingBottom: $height + "px"
455    });
456}
457
458function fillView() {
459    var $fillview = $('.fillview'),
460        $header = $('header'),
461        $footer = $('footer');
462    if ($fillview.length) {
463        $(window).bind('resize load', function () {
464            $fillview.css({
465                'min-height': windowHeight - $header.outerHeight() - $footer.outerHeight(),
466            });
467        });
468    }
469}
470
471/**
472 * Przyklejenie menu do góry strony.
473 */
474function stickyHeader() {
475    var fireAfterResize,
476        $fromTop = 0,
477        $underSlider = true,
478        $rwdRun = true;
479
480    $(window).bind('resize load', function () {
481        clearTimeout(fireAfterResize);
482        fireAfterResize = setTimeout(function () {
483            headerStickyBase($fromTop, $underSlider, $rwdRun);
484        }, 500);
485    });
486
487    $(window).bind("scroll", function () {
488        headerStickyBase($fromTop, $underSlider, $rwdRun);
489    });
490}
491
492/**
493 * Opóźnienie zamknięcia submenu nawigacji po zjechaniu myszką
494 * Aby poprawnie użyć nalezy ostylować klasę "hovered"
495 */
496function menuHover() {
497    var timeout;
498
499    $('#main-menu ul li')
500        .mouseenter(function () {
501            var $this = $(this);
502            var $submenu = $this.find('ul');
503            if (!$submenu.length) return;
504            clearTimeout(timeout);
505            $('#main-menu ul li ul').removeClass('hovered');
506            $submenu.addClass('hovered');
507        })
508        .mouseleave(function () {
509            var $this = $(this);
510            var $submenu = $this.find('ul');
511            if (!$submenu.length) return;
512            timeout = setTimeout(function () {
513                $submenu.removeClass('hovered');
514            }, 300);
515        });
516}
517
518
519function labelLinkFix() {
520    $('label a').each(function () {
521        var $this = $(this), span;
522        $this.attr('target', '_blank');
523        $this.attr('rel', 'noopener');
524
525        span = $('<span onclick="event.stopPropagation();"></span>');
526        span.html($(this).clone());
527        $this.replaceWith(span);
528    });
529}
530
531
532function initFooterNavSlider() {
533    // $('.footer-nav-slider .footer-nav-item').each(function(i, el) {
534    //     var $this = $(el);
535    //     $this.css('width', $this.outerWidth());
536    // });
537    // $('.footer-nav-slider').slick({
538    //     dots: false,
539    //     arrows: true,
540    //     infinite: false,
541    //     speed: 800,
542    //     centerMode: false,
543    //     variableWidth: true
544    // });
545}
546
547function initSavedProducts() {
548    $('.savedProducts-open').on('click touch', function (e) {
549        var $this = $(this),
550            productId = $this.data("id"),
551            materialId = [];
552        e.preventDefault();
553
554        $.ajax({
555            url: "/inquiry/add",
556            data: {ajax: 1, product_id: productId, materials: materialId},
557            method: "POST",
558            success: function (resp) {
559                $("#savedProducts .productSmall-list").html(resp.content);
560
561                var $headerList = $('.headerlink-list');
562                if ($headerList.hasClass('compact')) {
563                    window.savedProductsOpenedBefore = true;
564                } else {
565                    $headerList.addClass('compact');
566                    window.savedProductsOpenedBefore = false;
567                }
568
569                $.fancybox.open($('#savedProducts'), {
570                    touch: false,
571                    baseClass: "savedProducts-popup",
572                    beforeShow: function () {
573                        if (!window.savedProductsOpenedBefore) {
574                            $('.headerlink .savedProducts-open').addClass('savedProducts-is-opened');
575                        }
576                    },
577                    afterClose: function () {
578                        $('.headerlink .savedProducts-open').removeClass('savedProducts-is-opened');
579                        window.savedProductsOpenedBefore = true;
580                    }
581                });
582            }
583        });
584
585        e.preventDefault();
586        return false;
587    });
588
589    $('.savedProducts-close').on('click touch', function (e) {
590        $.fancybox.close();
591        e.preventDefault();
592        return false;
593    });
594
595    $('.savedProducts-ask').on('click touch', function (e) {
596        var $this = $(this);
597        $this.closest('#savedProducts').find('.savedProducts-form').slideToggle();
598
599        e.preventDefault();
600        return false;
601    });
602}
603
604/**
605 * Handles fullscreen realizations viewing - slider, next/prev relization, related products slider
606 * @param GROUP {String} - Name for a group of realizations that should be grouped together
607 * @constructor
608 *
609 * [Element that opens up popup should contain:]
610 * data-fsv-group="{String}" - Name of the realizations group
611 * href="{String}" - Unique ID of the target popup element
612 *
613 * [Element that contains the popup structure for given single realization should contain:]
614 * class="fsv-popup"
615 * data-fsv-group="{String}" - Name of the realizations group
616 * data-fsv-id="{String}" - Unique ID
617 */
618function FullscreenViewer(GROUP) {
619    var that = this,
620        isOpened = false,
621        isPanelOpened = false,
622        $opened = $();
623
624    if (typeof GROUP !== "string") {
625        console.error('FullscreenViewer constructor: argument "group" must not be empty and must be a string');
626        return;
627    }
628
629    /* Bind elements that open up popup of given group's realization (ALSO BINDS FUTURE ELEMENTS) */
630    body.on('click touch', '.fsv-open[data-fsv-group="' + GROUP + '"], [data-fsv-group="' + GROUP + '"] .fsv-open', onClickOpen);
631
632    /* Bind close buttons */
633    body.on('click touch', '[data-fsv-group="' + GROUP + '"] .fsv-close', onClickClose);
634
635    /* Bind panel toggle buttons */
636    body.on('click touch', '.fsv-popup[data-fsv-group="' + GROUP + '"] .fsv-panel-toggle', function () {
637        that.togglePanel($(this).closest('.fsv-popup'));
638    });
639    body.on('touchmove', '.fsv-popup[data-fsv-group="' + GROUP + '"] .fsv-panel-bar', function () {
640        if (windowWidth < 1140) {
641            that.togglePanel($(this).closest('.fsv-popup'));
642        }
643    });
644
645    $(document).bind('keydown', function (e) {
646        if (isOpened) {
647            //ESCAPE
648            if (e.which === 27) {
649                that.close();
650            }
651            //ARROW UP
652            else if (e.which === 38) {
653                that.togglePanel($opened, true);
654            }
655            //ARROW DOWN
656            else if (e.which === 40) {
657                that.togglePanel($opened, false);
658            }
659            //ENTER / SPACE
660            else if (e.which === 13 || e.which === 32) {
661                that.togglePanel($opened);
662            }
663            //ARROW LEFT
664            else if (e.which === 37) {
665                if (isPanelOpened) {
666                    $opened.find('.fsv-panel .product-list').slick('slickPrev');
667                } else {
668                    $opened.find('.fsv-slider').slick('slickPrev');
669                }
670            }
671            //ARROW RIGHT
672            else if (e.which === 39) {
673                if (isPanelOpened) {
674                    $opened.find('.fsv-panel .product-list').slick('slickNext');
675                } else {
676                    $opened.find('.fsv-slider').slick('slickNext');
677                }
678            }
679        }
680    });
681
682    function init() {
683        if (location.hash) {
684            openFromHash();
685        }
686    }
687
688    /***************************************************************************************************************/
689    /**
690     * Handles click on element that opens up FullscreenViewer
691     * @param e {Event} - Click event
692     */
693    function onClickOpen(e) {
694        var $this = $(this),
695            targetId = $this.attr('href');
696
697        if (!targetId) {
698            console.error('FullscreenViewer, onClickOpen(): Clicked element doesnt contain href!');
699            return;
700        }
701
702        that.open(targetId);
703
704        e.preventDefault();
705        return false;
706    }
707
708    /**
709     * Handles click on element that closes FullscreenViewer
710     * @param e {Event} - Click event
711     */
712    function onClickClose(e) {
713        console.log('Closing');
714        that.close();
715    }
716
717    /**
718     * Opens viewer with realization of given id
719     * @param targetId {String}
720     */
721    this.open = function (targetId) {
722        var $target = $('[data-fsv-id="' + targetId + '"]');
723
724        if (!$target.length) {
725            /*
726            console.error('FullscreenViewer, open(): Cannot find target with data-fsv-id of', targetId);
727            return;
728            */
729
730            var tab = targetId.split('#');
731            getAjaxData(tab[0], tab[1]);
732            targetId = '#' + tab[1];
733            $target = $('[data-fsv-id="' + targetId + '"]');
734        }
735
736        this.close();
737
738        location.hash = targetId;
739
740        $opened = $target;
741
742        // body.addClass('fsv-opened');
743
744        initPopup($target);
745
746        $opened.addClass('active');
747
748        isOpened = true;
749    };
750
751    /**
752     * Closes this FullscreenViewer (if opened)
753     */
754    this.close = function () {
755        $opened.removeClass('active');
756        body.removeClass('fsv-opened');
757        isOpened = false;
758        isPanelOpened = false;
759        $opened = $();
760        location.hash = "";
761    };
762
763    /**
764     * Opens bottom panel in given popup
765     * @param {jQuery} $popup - $('.fsv-popup')
766     * @param {boolean} [forcedState]  - force state instead od toggling
767     */
768    this.togglePanel = function ($popup, forcedState) {
769        if (typeof forcedState === "boolean") {
770            if (forcedState) {
771                $popup.find('.fsv-panel').addClass('active');
772                isPanelOpened = true;
773            } else {
774                $popup.find('.fsv-panel').removeClass('active');
775                isPanelOpened = false;
776            }
777        } else {
778            $popup.find('.fsv-panel').toggleClass('active');
779            isPanelOpened = !isPanelOpened;
780        }
781    };
782
783    /**
784     * Initializes popup that hasn't been opened before
785     * Starts sliders etc
786     * @param $popup {jQuery} - $('.fsv-popup')
787     */
788    function initPopup($popup) {
789        if ($popup.hasClass('initialized')) {
790            $popup.find('.fsv-slider').slick('slickGoTo', 0, true);
791        } else {
792            // Main slider
793            $popup.find('.fsv-slider').slick({
794                infinite: false,
795                slidesToShow: 1,
796                slidesToScroll: 1,
797                fade: true,
798                autoplay: false,
799                autoplaySpeed: 6000,
800                speed: 1500,
801                dots: false,
802                arrows: true,
803                accesibility: false,
804                waitForAnimate: false,
805            })
806                .on('init beforeChange reInit', function (event, slick, currentSlide, nextSlide) {
807                    if (nextSlide === undefined) {
808                        nextSlide = 0;
809                    }
810                    updateSliderIndicator($popup, nextSlide);
811
812                    var totalSlides = getTotalSlides($popup);
813                    var showPrevGoto = (nextSlide === 0);
814                    var showNextGoto = (nextSlide === totalSlides - 1);
815
816                    if (showPrevGoto || showNextGoto) {
817                        updateGotos($popup, showPrevGoto, showNextGoto);
818                    } else {
819                        updateGotos($popup, false, false, true);
820                    }
821                });
822
823            updateSliderIndicator($popup, 0);
824
825            if (getTotalSlides($popup) <= 1) {
826                updateGotos($popup, true, true);
827            } else {
828                updateGotos($popup, true, false);
829            }
830
831            // Product slider
832            $popup.find('.product-list').slick({
833                infinite: true,
834                slidesToShow: 6,
835                slidesToScroll: 1,
836                fade: false,
837                autoplay: false,
838                autoplaySpeed: 3000,
839                dots: false,
840                arrows: true,
841                prevArrow: $popup.find('.fsv-panel .productsSlider-container .slider-prev'),
842                nextArrow: $popup.find('.fsv-panel .productsSlider-container .slider-next'),
843                accesibility: false,
844                waitForAnimate: false,
845                responsive: [
846                    {
847                        breakpoint: 1281,
848                        settings: {
849                            slidesToShow: 5,
850                        }
851                    },
852                    {
853                        breakpoint: 901,
854                        settings: {
855                            slidesToShow: 4,
856                        }
857                    },
858                    {
859                        breakpoint: 768,
860                        settings: {
861                            slidesToShow: 3,
862                        }
863                    },
864                    {
865                        breakpoint: 560,
866                        settings: {
867                            slidesToShow: 2,
868                        }
869                    },
870                ],
871            });
872
873            $popup.addClass('initialized');
874        }
875    }
876
877    function openFromHash() {
878        var $target = $('[data-fsv-id="' + location.hash + '"][data-fsv-group="' + GROUP + '"]');
879        if ($target.length) {
880            that.open(location.hash);
881        }
882    }
883
884    /**
885     * Update slider's indicator based on given index of a slide
886     * Calculates its width and position
887     * @param $popup {jQuery} - $('.fsv-popup')
888     * @param index {number} - index of slide
889     */
890    function updateSliderIndicator($popup, index) {
891        var totalSlides = getTotalSlides($popup);
892        $popup.find('.fsv-indicator > span').css({
893            width: (100 / totalSlides) + "%",
894            left: (index / totalSlides * 100) + "%",
895        });
896    }
897
898    /**
899     * Update prev/next realization squares based on .fsv-group-item order AN
899D/OR show/hide gotos
900     * .fsv-group-item class is used to figure out order of realizations
901     * @param {jQuery} $popup - $('.fsv-popup')
902     * @param {boolean} [showPrev] - optional flag for hiding/showing prev goto
903     * @param {boolean} [showNext] - optional flag for hiding/showing next goto
904     * @param {boolean} [dontUpdate] - optional flag for skipping update of gotos' content
905     */
906    function updateGotos($popup, showPrev, showNext, dontUpdate) {
907        dontUpdate = true;
908
909        //Get all realization items
910        var $groupItems = $('.fsv-group-item[data-fsv-group="' + GROUP + '"]');
911        //Get current realization ID
912        var id = $popup.data('fsv-id');
913        //Find the index of current realization in items collection
914        var itemIndex = $groupItems.index('[href="' + id + '"]');
915        //Get previous and next realization item
916        var $prev = $groupItems.eq(itemIndex - 1);
917        var $next = $groupItems.eq(itemIndex + 1);
918
919        if ($prev.is($groupItems.eq(itemIndex))) $prev = $();
920        if ($next.is($groupItems.eq(itemIndex))) $next = $();
921
922        var $gotoPrev = $popup.find('.fsv-goto-prev');
923        var $gotoNext = $popup.find('.fsv-goto-next');
924
925        var imgUrl;
926
927        if (!dontUpdate && $prev.length) {
928            imgUrl = $prev.find('img').attr('src');
929            $gotoPrev.find('.fsv-goto-img').css({
930                'background-image': 'url(' + imgUrl + ')',
931            });
932            $gotoPrev.attr('href', $prev.attr('href'));
933        }
934        if (typeof showPrev === "boolean") {
935            if (showPrev && $prev.length) {
936                $gotoPrev.addClass('active');
937            } else {
938                $gotoPrev.removeClass('active');
939            }
940        } else if ($prev.length === 0) {
941            $gotoPrev.removeClass('active');
942        }
943
944        if (!dontUpdate && $next.length) {
945            imgUrl = $next.find('img').attr('src');
946            $gotoNext.find('.fsv-goto-img').css({
947                'background-image': 'url(' + imgUrl + ')',
948            });
949            $gotoNext.attr('href', $next.attr('href'));
950        }
951        if (typeof showNext === "boolean") {
952            if (showNext && $next.length) {
953                $gotoNext.addClass('active');
954            } else {
955                $gotoNext.removeClass('active');
956            }
957        } else if ($next.length === 0) {
958            $gotoNext.removeClass('active');
959        }
960    }
961
962    /**
963     * Returns a total number of slides in the popup
964     * @param {jQuery} $popup - $('.fsv-popup')
965     * @returns {Number}
966     */
967    function getTotalSlides($popup) {
968        return $popup.find('.fsv-slide').not('.slick-cloned').length;
969    }
970
971    /**
972     * Returns group of this FullscreenViewer
973     * @returns {string}
974     */
975    this.getGroup = function () {
976        return GROUP;
977    };
978
979    function getAjaxData(href, hash) {
980        if (popups.indexOf(hash) == -1) {
981            $.ajax({
982                url: href,
983                data: {ajax: 1, popup: 1, slug: hash},
984                method: "POST",
985                dataType: "json",
986                success: function (resp) {
987                    $(".page-realizations").append(resp.content);
988                    that.open('#' + hash);
989                    popups.push(hash);
990                }
991            });
992        }
993    }
994
995    init();
996}
997
998function Fullslider($slidersection) {
999    if (typeof $slidersection !== "object") {
1000        console.error('Fullslider constructor: property $slidersection must be a jQuery element');
1001        return;
1002    }
1003    if ($slidersection.length === 0) {
1004        console.error('Fullslider constructor: $slidersection must not be empty');
1005        return;
1006    }
1007    if ($slidersection.length > 1) {
1008        console.error('Fullslider constructor: $slidersection must contain only ONE element');
1009        return;
1010    }
1011
1012    var that = this;
1013
1014    this.$element = $slidersection;
1015    var $bar = this.$element.find('.fullslider-bar');
1016    this.$indicator = $slidersection.find('.fullslider-indicator > span');
1017    this.slideCount = $slidersection.find('.fullslider-slide').length;
1018
1019    this.init = function () {
1020        var $that = this;
1021        $slidersection.find('.fullslider-slide').each(function () {
1022            var $this = $(this),
1023                href = $this.data('href');
1024
1025            if (href) {
1026                $this.bind('click touch', function () {
1027                    if ($bar.find('.fullslider-btn').length) {
1028                        $bar.find('.fullslider-btn')[0].click();
1029                    }
1030                });
1031            }
1032        });
1033
1034        $slidersection.find('.fullslider').slick({
1035            infinite: true,
1036            slidesToShow: 1,
1037            slidesToScroll: 1,
1038            fade: true,
1039            autoplay: true,
1040            autoplaySpeed: 5000,
1041            speed: 1600,
1042            dots: false,
1043            arrows: true,
1044            waitForAnimate: false,
1045        })
1046            .on('init beforeChange reInit', function (event, slick, currentSlide, nextSlide) {
1047                if (nextSlide === undefined) {
1048                    nextSlide = 0;
1049                }
1050                that.updateIndicator(nextSlide);
1051                that.updateBarData(nextSlide);
1052            });
1053
1054        this.updateBarData(0);
1055        this.updateIndicator(0);
1056
1057        $slidersection.data('scrollTo', false);
1058        $slidersection.find('.slick-arrow').bind('click touch', function () {
1059            if (windowWidth >= 1140) {
1060                if ($slidersection.data('scrollTo') == true) return;
1061                $slidersection.data('scrollTo', true);
1062                $(window).scrollTo($slidersection, {
1063                    duration: 400,
1064                    onAfter: function () {
1065                        $slidersection.data('scrollTo', false);
1066                    }
1067                });
1068            }
1069        });
1070
1071        $slidersection.find('.fullslider-content .content-wrapper').bind('mouseenter', function () {
1072            if (windowWidth >= 1140) {
1073                $bar.addClass('hovered');
1074            }
1075        }).bind('mouseleave', function () {
1076            if (windowWidth >= 1140) {
1077                $bar.removeClass('hovered');
1078            }
1079        });
1080    };
1081
1082    this.updateIndicator = function (nextSlide) {
1083        that.$indicator.css({
1084            width: (100 / that.slideCount) + "%",
1085            left: (nextSlide / that.slideCount * 100) + "%",
1086        });
1087    };
1088
1089    this.updateBarData = function (nextSlide) {
1090        var $btn = $slidersection.find('.fullslider-slide[data-slideid="' + nextSlide + '"]').eq(0).find('.fullslider-bar-data').clone();
1091        var $leftBar = $slidersection.find('.fullslider-bar-left');
1092        $leftBar.empty();
1093        if ($btn.length) {
1094            $leftBar.append($btn);
1095        }
1096    };
1097}
1098
1099/**
1100 * Handles text numeric animation
1101 * @param $elements - {jQuery} elements to animate text
1102 * data-value="float" - {"float", default: integer} Number type, can be float (21.37), defaults to integer
1103 * data-value-type="" - {number} value to animate to
1104 * data-timeout="600" - {number - miliseconds} of lag before animation start
1105 * data-duration="3000" - {number - miliseconds} of animation length
1106 * data-value-prefix="Value: " - {string} to put before each number in animation
1107 * data-value-suffix=" PLN" - {string} to put after each number in animation
1108 * @param options - extra options
1109 * {
1110 *   callback - {function} to call on animation finish
1111 * }
1112 */
1113function animateCountUp($elements, options) {
1114    if (typeof options !== 'object') options = {};
1115
1116    function animateCount($element) {
1117        var value,
1118            $this = $element,
1119            type = $this.attr('data-value-type'),
1120            value_prefix = $this.attr('data-value-prefix'),
1121            value_suffix = $this.attr('data-value-suffix'),
1122            timeout = Number($this.attr('data-timeout')),
1123            duration = Number($this.attr('data-duration'));
1124
1125        if (isNaN(Number($this.attr('data-value')))) {
1126            console.warn('CountUp: element with class "countup" must have a data-value attribute with a number value');
1127            return;
1128        }
1129
1130        // DEFAULTS
1131        timeout = isNaN(timeout) ? 0 : timeout;
1132        duration = isNaN(duration) ? 2500 : duration;
1133
1134        if (value_prefix) {
1135            value_prefix = value_prefix + " ";
1136        } else {
1137            value_prefix = "";
1138        }
1139        if (value_suffix) {
1140            value_suffix = " " + value_suffix;
1141        } else {
1142            value_suffix = "";
1143        }
1144
1145        setTimeout(function () {
1146            if (type === "float") {
1147                value = parseFloat($this.attr('data-value'), 10);
1148                $({countNum: 0.00}).animate(
1149                    {countNum: value},
1150                    {
1151                        duration: duration,
1152                        easing: 'swing',
1153                        step: function () {
1154                            $this.text(value_prefix + this.countNum.toLocaleString(undefined, {
1155                                minimumFractionDigits: 2,
1156                                maximumFractionDigits: 2
1157                            }) + value_suffix);
1158                        },
1159                        complete: function () {
1160                            $this.text(value_prefix + this.countNum.toLocaleString(undefined, {
1161                                minimumFractionDigits: 2,
1162                                maximumFractionDigits: 2
1163                            }) + value_suffix);
1164                            if (typeof options.callback === 'function') {
1165                                options.callback();
1166                            }
1167                            $this.addClass('countup-ended');
1168                        }
1169                    }
1170                );
1171            } else {
1172                value = parseInt($this.attr('data-value'), 10);
1173                $({countNum: 0}).animate(
1174                    {countNum: value},
1175                    {
1176                        duration: duration,
1177                        easing: 'swing',
1178                        step: function () {
1179                            $this.text(value_prefix + Math.round(this.countNum) + value_suffix);
1180                        },
1181                        complete: function () {
1182                            $this.text(value_prefix + this.countNum + value_suffix);
1183                            if (typeof options.callback === 'function') {
1184                                options.callback();
1185                            }
1186                            $this.addClass('countup-ended');
1187                        }
1188                    }
1189                );
1190            }
1191            $this.addClass('countup-started');
1192        }, timeout);
1193    }
1194
1195    $elements.each(function () {
1196        var $this = $(this);
1197        var delay = parseInt($this.attr('data-delay'));
1198        delay = isNaN(delay) ? 0 : delay;
1199        setTimeout(function () {
1200            animateCount($this);
1201        }, delay);
1202    });
1203}
1204
1205
1206/**
1207 * Initializes a horizontally scrollable map
1208 * @param $el - container with all necessary elements
1209 * @param options
1210 * @constructor
1211 */
1212function ImageMap($el, options) {
1213    var that = this;
1214    if (typeof options !== 'object') options = {};
1215
1216    var $inside = $el.find('.imageMap-inside'),
1217        $viewport = $el.find('.imageMap-viewport'),
1218        $view = $el.find('.imageMap-view'),
1219        $arrowLeft = $el.find('.imageMap-arrow-left'),
1220        $arrowRight = $el.find('.imageMap-arrow-right');
1221
1222    if ($viewport.length === 0) {
1223        console.error('ImageMap: cannot find viewport');
1224        return;
1225    }
1226    if ($view.length === 0) {
1227        console.error('ImageMap: cannot find view');
1228        return;
1229    }
1230
1231    /**
1232     * Bind mouse events for dragging
1233     */
1234    var drag, startx, diffx, dragTimeout;
1235    $viewport.bind({
1236        'mousedown': function (e) {
1237            if (e.which !== 1) return;
1238            if (!e) {
1239                e = window.event;
1240            }
1241            if (e.target && e.target.className === 'imageMap-area') {
1242                e.preventDefault();
1243                return false;
1244            }
1245            startx = e.clientX + $viewport[0].scrollLeft;
1246            diffx = 0;
1247            drag = true;
1248        },
1249        'mouseup mouseleave': function (e) {
1250            if (!e) {
1251                e = window.event;
1252            }
1253            drag = false;
1254        },
1255        'mousemove': function (e) {
1256            if (drag === true) {
1257                if (!e) {
1258                    e = window.event;
1259                }
1260                diffx = (startx - (e.clientX + $viewport[0].scrollLeft));
1261                $viewport[0].scrollLeft += diffx;
1262                clearTimeout(dragTimeout);
1263                dragTimeout = setTimeout(that.updateOverflowing, 100)
1264            }
1265        },
1266    });
1267
1268    /**
1269     * Bind window changes for updating
1270     */
1271    var viewportScrollWidth, viewportWidth, viewportScrollMax;
1272    $(window).bind('resize load', function () {
1273        that.update();
1274    });
1275
1276    /**
1277     * Arrows functionality - scrolling animation
1278     */
1279    var FPS = 60, // How fast {frames per second}
1280        SCROLL_SPEED = 10; // How much {pixels} per frame
1281    /** Do NOT change : **/
1282    var fpsInterval = 1000 / FPS,
1283        scrollAnimationRight, scrollAnimationLeft,
1284        animLeftStart, animLeftThen,
1285        animRightStart, animRightThen;
1286    /** ************* **/
1287    $arrowLeft.bind({
1288        'mousedown': function (e) {
1289            if (e.which !== 1) return;
1290            animRightThen = Date.now();
1291            animRightStart = animRightThen;
1292            requestAnimationFrame(scrollToRight);
1293            scrollAnimationRight = true;
1294        },
1295        'mouseup mouseleave': function () {
1296            scrollAnimationRight = false;
1297        },
1298    });
1299    $arrowRight.bind({
1300        'mousedown': function (e) {
1301            if (e.which !== 1) return;
1302            animLeftThen = Date.now();
1303            animLeftStart = animLeftThen;
1304            requestAnimationFrame(scrollToLeft);
1305            scrollAnimationLeft = true;
1306        },
1307        'mouseup mouseleave': function () {
1308            scrollAnimationLeft = false;
1309        },
1310    });
1311
1312    // Scroll left animation loop
1313    function scrollToLeft() {
1314        if (!scrollAnimationLeft) return;
1315
1316        var now = Date.now(),
1317            elapsed = now - animLeftThen;
1318
1319        // FPS lock
1320        if (elapsed > fpsInterval) {
1321            that.incScroll(SCROLL_SPEED);
1322        }
1323
1324        requestAnimationFrame(scrollToLeft);
1325    }
1326
1327    // Scroll right animation loop
1328    function scrollToRight() {
1329        if (!scrollAnimationRight) return;
1330
1331        var now = Date.now(),
1332            elapsed = now - animRightThen;
1333
1334        // FPS lock
1335        if (elapsed > fpsInterval) {
1336            that.incScroll(-SCROLL_SPEED);
1337        }
1338
1339        requestAnimationFrame(scrollToRight);
1340    }
1341
1342    /**
1343     *  Bind mouse hover to pause autoplay
1344     */
1345    var autoplayRequest,
1346        autoplayThen = Date.now(),
1347        autoplay = true,
1348        autoplayPerFrame = 1,
1349        autoplayDirection = 1; // -1/1
1350    $inside.bind({
1351        'mouseenter': function () {
1352            console.dir(1);
1353            autoplay = false;
1354            stopAutoplay();
1355        },
1356        'mouseleave': function () {
1357            console.dir(2);
1358            stopAutoplay();
1359            autoplay = true;
1360            doAutoplay()
1361        },
1362    });
1363
1364    function doAutoplay() {
1365        if (!autoplay) return;
1366
1367        var now = Date.now(),
1368            elapsed = now - autoplayThen,
1369            upToAnEdge = false;
1370
1371        // FPS lock
1372        if (elapsed > fpsInterval * 2) {
1373            upToAnEdge = that.incScroll(autoplayDirection * autoplayPerFrame);
1374            console.dir(upToAnEdge);
1375            autoplayThen = Date.now();
1376        }
1377
1378        if (upToAnEdge) autoplayDirection *= -1;
1379
1380        autoplayRequest = requestAnimationFrame(doAutoplay);
1381    }
1382
1383    function stopAutoplay() {
1384        console.dir('stop');
1385        autoplay = false;
1386        cancelAnimationFrame(autoplayRequest);
1387    }
1388
1389    /**
1390     * Updates
1391     */
1392    this.update = function () {
1393        that.updateOverflowing();
1394    };
1395
1396    /**
1397     * Updates classes that determine whether map is overflowing on the left or/and right
1398     * Returns boolean - whenever any edge is not overflowing = true
1399     */
1400    var overflowLeft = false,
1401        overflowRight = false;
1402    this.updateOverflowing = function () {
1403        var result = false;
1404
1405        viewportScrollWidth = $viewport[0].scrollWidth;
1406        viewportWidth = $viewport.outerWidth();
1407        viewportScrollMax = viewportScrollWidth - viewportWidth;
1408
1409        if ($viewport.scrollLeft() > 0) {
1410            $el.addClass('imageMap--overflowLeft');
1411            overflowLeft = true;
1412        } else if ($viewport.scrollLeft() === 0) {
1413            $el.removeClass('imageMap--overflowLeft');
1414            overflowLeft = false;
1415            result = true;
1416        }
1417
1418        if ($viewport.scrollLeft() < viewportScrollMax) {
1419            $el.addClass('imageMap--overflowRight');
1420            overflowRight = true;
1421        } else if ($viewport.scrollLeft() === viewportScrollMax) {
1422            $el.removeClass('imageMap--overflowRight');
1423            overflowRight = false;
1424            result = true;
1425        }
1426
1427        return result;
1428    };
1429
1430    /**
1431     * Scroll by this much pixels
1432     * @param px {number}
1433     */
1434    this.incScroll = function (px) {
1435        $viewport.scrollLeft($viewport.scrollLeft() + px);
1436        return that.updateOverflowing();
1437    };
1438    /**
1439     * Set scroll to this position
1440     * @param px {number}
1441     */
1442    this.setScroll = function (px) {
1443        $viewport.scrollLeft(px);
1444        return that.updateOverflowing();
1445    };
1446
1447    /**
1448     * Set scroll based on mousemove event
1449     * @param e {Event}
1450     */
1451    this.setScrollByEvent = function (e) {
1452        // Show dragging cursor
1453        if (!isCursorScroll) {
1454            $viewport.css('cursor', 'e-resize');
1455            isCursorScroll = true;
1456        }
1457        var x = parseInt(e.clientX) - parseInt($view[0].getBoundingClientRect().left);
1458
1459        var diff = lastX - x;
1460
1461        $viewport[0].scrollLeft = $viewport[0].scrollLeft + diff;
1462
1463        lastX = x;
1464
1465        that.updateOverflowing();
1466    };
1467
1468    /**
1469     * Set starting scroll position
1470     */
1471    if (options.startingOffset) this.setScroll(options.startingOffset);
1472}
1473
1474var AffixHandler = {
1475    _binds: [],
1476    _initialized: false,
1477    /**
1478     * Add affix to keep track of
1479     * @param $target {jQuery} - element to affix
1480     * @param $column {jQuery} - container element as a track for affixed element
1481     * @param rwdBreakpoint {number} - OPTIONAL - stop affixing on and below this breakpoint
1482     * @returns {boolean}
1483     */
1484    add: function ($target, $column, rwdBreakpoint, callback) {
1485        // Inner vars
1486        var affixState = 0;
1487
1488        //Validation
1489        if (!($target instanceof jQuery)) {
1490            console.error('AffixController: required parameter "$target" must be a jQuery object: ', $target);
1491            return false;
1492        }
1493        if ($target.length !== 1) {
1494            console.error('AffixController: required parameter "$target" must be a jQuery set of only ONE element: ', $target);
1495            return false;
1496        }
1497        if (!($column instanceof jQuery)) {
1498            console.error('AffixController: required parameter "$column" must be a jQuery object: ', $column);
1499            return false;
1500        }
1501        if ($column.length !== 1) {
1502            console.error('AffixController: required parameter "$column" must be a jQuery set of only ONE element: ', $column);
1503            return false;
1504        }
1505        if (rwdBreakpoint !== undefined && rwdBreakpoint !== null) {
1506            if (typeof rwdBreakpoint !== 'number') {
1507                console.error('AffixController: optional parameter "rwdBreakpoint" must be a number: ', rwdBreakpoint);
1508                return false;
1509            }
1510        } else {
1511            rwdBreakpoint = 0;
1512        }
1513        if (callback !== undefined && callback !== null) {
1514            if (typeof callback !== 'function') {
1515                console.error('AffixController: optional parameter "callback" must be a function: ', callback);
1516                return false;
1517            }
1518        } else {
1519            callback = null;
1520        }
1521
1522        //Push to binds
1523        this._binds.push({
1524            $target: $target,
1525            $column: $column,
1526            rwdBreakpoint: rwdBreakpoint,
1527            //Internal state:
1528            affixState: 0,
1529            callback: callback,
1530        });
1531
1532        //Initialize handler
1533        this._initialize();
1534
1535        return true;
1536    },
1537    _initialize: function () {
1538        if (!this._initialized) {
1539            //Utility vars
1540            var $window = $(window),
1541                that = this;
1542
1543            $(window).on('load resize scroll', function () {
1544                for (var i = 0; i < that._binds.length; i++) {
1545                    var current = that._binds[i],
1546                        $this = current.$target,
1547                        $column = current.$column,
1548                        rwdBreakpoint = current.rwdBreakpoint,
1549                        callback = current.callback;
1550
1551                    $this.css('width', $column.outerWidth());
1552                    $this.css('width', $column.width());
1553
1554                    //var $height = $this.outerHeight();
1555                    //$column.css('min-height', $height);
1556
1557                    if (windowWidth <= rwdBreakpoint) {
1558                        $this.removeClass('affix affix-top affix-bottom');
1559                        return;
1560                    }
1561
1562                    // var windowTopOffset = parseInt(windowHeight / 2 - $this.outerHeight() / 2);
1563                    var windowTopOffset = $('header').outerHeight() + 15;
1564
1565                    if ($window.scrollTop() > ($column.offset().top - windowTopOffset)) {
1566                        // If overflows bottom
1567                        if ($column.offset().top + $column.outerHeight() < windowTopOffset + $this.outerHeight() + $window.scrollTop()) {
1568                            if (current.affixState === 1) return;
1569                            current.affixState = 1;
1570                            $this.removeClass('affix-top affix').addClass('affix-bottom');
1571                            $this.css('top', '');
1572                        }
1573                        // If in the middle
1574                        else {
1575                            if (current.affixState !== 2) {
1576                                $this.removeClass('affix-top affix-bottom').addClass('affix');
1577                            }
1578                            current.affixState = 2;
1579                            $this.css('top', windowTopOffset);
1580                        }
1581                    }
1582                    // If overflows top
1583                    else {
1584                        if (current.affixState === 3) return;
1585                        current.affixState = 3;
1586                        $this.removeClass('affix-bottom affix').addClass('affix-top');
1587                        $this.css('top', '');
1588                    }
1589
1590                    if (callback) {
1591                        (callback.bind($this))();
1592                    }
1593                }
1594            });
1595            this._initialized = true;
1596        }
1597    },
1598};
1599
1600/**
1601 * Usage example:
1602 DelayedHoverHandler.add($('#main-menu li'), {
1603            enterDelay: 300,
1604            leaveDelay: 100,
1605            enterCallback: function () {},
1606            leaveCallback: function () {},
1607   });
1608
1609 * Adds .hovered class on hovered targets
1610 * Can set delay for hover and unhover
1611 *
1612 * options {
1613 *     [BASIC:]
1614 *     enterDelay {number} - miliseconds to delay hover
1615 *     leaveDelay {number} - miliseconds to delay unhover
1616 *
1617 *     [EXTRA:]
1618 *     keepHover {boolean} - doesn't remove hover - does only move it to a different hovered sibling
1619 *     instantHoverSwitch {boolean} - ignores enterDelay and leaveDelay when already initialized on one of the elements and user starts to hover different element
1620 *          true - leaveDelay doesn't work, enterDelay works only for first hovered element and then works instantly for next ones
1621 *          false - always use provided delays for entering and leaving
1622 *
1623 *     [CALLBACKS:]
1624 *     enterCallback - call provided function on hover (jQuery element is binded as 'this')
1625 *     leaveCallback - call provided function on unhover (jQuery element is binded as 'this')
1626 * }
1627 */
1628var DelayedHoverHandler = {
1629    // Do NOT change (use options instead):
1630    Defaults: {
1631        ENTER_DELAY: 0, // ms
1632        LEAVE_DELAY: 0, // ms
1633        KEEP_HOVER: false,
1634        INSTANT_HOVER_SWITCH: false,
1635    },
1636    add: function ($targets, options) {
1637        if (!($targets instanceof jQuery)) {
1638            console.error('DelayedHoverHandler: required parameter "$targets" must be a jQuery object: ', $targets);
1639            return false;
1640        }
1641        if (typeof options !== "undefined") {
1642            if (typeof options !== "object") {
1643                console.error('DelayedHoverHandler: optional parameter "options" must be an object: ', options);
1644                return false;
1645            }
1646            if (options.hasOwnProperty('enterCallback') && typeof options['enterCallback'] !== 'function') {
1647                console.error('DelayedHoverHandler: optional option "enterCallback" must be a function: ', options['enterCallback']);
1648                return false;
1649            }
1650            if (options.hasOwnProperty('leaveCallback') && typeof options['leaveCallback'] !== 'function') {
1651                console.error('DelayedHoverHandler: optional option "leaveCallback" must be a function: ', options['leaveCallback']);
1652                return false;
1653            }
1654        }
1655
1656        var enterDelay = this.Defaults.ENTER_DELAY,
1657            leaveDelay = this.Defaults.LEAVE_DELAY,
1658            keepHover = this.Defaults.KEEP_HOVER,
1659            instantHoverSwitch = this.Defaults.INSTANT_HOVER_SWITCH;
1660
1661        if (options) {
1662            if (options.hasOwnProperty('enterDelay') && !isNaN(options['enterDelay'])) {
1663                enterDelay = parseInt(options.enterDelay);
1664            }
1665            if (options.hasOwnProperty('leaveDelay') && !isNaN(options['leaveDelay'])) {
1666                leaveDelay = parseInt(options.leaveDelay);
1667            }
1668            if (options.hasOwnProperty('keepHover')) {
1669                keepHover = options.keepHover;
1670            }
1671            if (options.hasOwnProperty('instantHoverSwitch')) {
1672                instantHoverSwitch = options.instantHoverSwitch;
1673            }
1674        }
1675
1676        var timer = null;
1677
1678        $targets.bind('mouseenter', function () {
1679            var $this = $(this);
1680
1681            clearTimeout(timer);
1682
1683            if ($targets.filter('.hovered').length && instantHoverSwitch) {
1684                var $hovered = $targets.filter('.hovered');
1685                $hovered.removeClass('hovered');
1686                $hovered.each(function () {
1687                    var $this = $(this);
1688                    if ($this[0]._leaveCallback) $this[0]._leaveCallback();
1689                });
1690                $this.addClass('hovered');
1691            } else {
1692                timer = setTimeout(function () {
1693                    var $hovered = $targets.filter('.hovered');
1694                    $hovered.removeClass('hovered');
1695                    $hovered.each(function () {
1696                        var $this = $(this);
1697                        if ($this[0]._leaveCallback) $this[0]._leaveCallback();
1698                    });
1699                    $this.addClass('hovered');
1700                    if (options['enterCallback']) (options['enterCallback'].bind($this))();
1701                }, enterDelay);
1702            }
1703        });
1704        $targets.bind('mouseleave', function () {
1705            clearTimeout(timer);
1706            var $this = $(this);
1707
1708            if (options['leaveCallback']) {
1709                $this[0]._leaveCallback = function () {
1710                    (options['leaveCallback'].bind($this))()
1711                };
1712            }
1713
1714            if (!keepHover) {
1715                timer = setTimeout(function () {
1716                    var $hovered = $targets.filter('.hovered');
1717                    $hovered.removeClass('hovered');
1718                    if ($this[0]._leaveCallback) $this[0]._leaveCallback();
1719                }, leaveDelay);
1720            } else {
1721                if ($this[0]._leaveCallback) $this[0]._leaveCallback();
1722            }
1723        });
1724
1725        return true;
1726    }
1727};
1728
1729/*
1730 [settings] {
1731    element: $,
1732    resolution: 1139,
1733    from: {
1734        element: $,
1735        method: one of ['appendTo', 'prependTo', 'insertAfter', 'insertBefore'],
1736    },
1737    to: {
1738        element: $,
1739        method: one of ['appendTo', 'prependTo', 'insertAfter', 'insertBefore'],
1740    },
1741 }
1742 */
1743var ElementsMovingHandler = {
1744    _elements: [],
1745    _started: false,
1746    _methods: ['appendTo', 'prependTo', 'insertAfter', 'insertBefore'],
1747    add: function (settings) {
1748        if (typeof settings !== 'object') return console.error('bindElementMove: settings must be an object');
1749        if (typeof settings.from !== 'object') return console.error('bindElementMove: settings.from must be an object');
1750        if (typeof settings.to !== 'object') return console.error('bindElementMove: settings.to must be an object');
1751        if (!settings.element.length) {
1752            console.warn('bindElementMove: Element not found', settings.element);
1753            return;
1754        }
1755        if (settings.element.length > 1) return console.error('bindElementsOrder: More than one element found: ' + settings.element.selector);
1756        if (!settings.from.element.length) return console.error('bindElementsOrder: Cant find [from] element: ' + settings.from.element.selector);
1757        if (settings.from.element.length > 1) return console.error('bindElementsOrder: More than one [from] element found: ' + settings.from.element.selector);
1758        if (!settings.to.element.length) return console.error('bindElementsOrder: Cant find [to] element: ' + settings.to.element.selector);
1759        if (settings.to.element.length > 1) return console.error('bindElementsOrder: More than one [to] element found: ' + settings.to.element.selector);
1760        if (this._methods.indexOf(settings.from.method) === -1) return console.error('bindElementsOrder: Unknown "to" method "' + settings.from.method + '". Alowed: ' + this._methods.join(', '));
1761        if (this._methods.indexOf(settings.to.method) === -1) return console.error('bindElementsOrder: Unknown "from" method "' + settings.to.method + '". Alowed: ' + this._methods.join(', '));
1762        if (typeof settings.resolution !== 'number') return console.error('bindElementsOrder: "resolution" must be a number');
1763        if (settings.resolutionMin !== undefined && typeof settings.resolutionMin !== 'number') return console.error('bindElementsOrder: "resolutionMin" must be a number');
1764
1765        if (!this._started) {
1766            this._init();
1767        }
1768
1769        this._elements.push(settings);
1770    },
1771    _init: function () {
1772        this._started = true;
1773        var that = this;
1774        $(window).bind('resize load', function () {
1775            for (var i = 0; i < that._elements.length; i++) {
1776                that._moveElement(that._elements[i]);
1777                if (typeof that._elements[i].callback === 'function') {
1778                    that._elements[i].callback();
1779                }
1780            }
1781        });
1782    },
1783    _moveElement: function (o) {
1784        if (windowWidth > o.resolution || (o.resolutionMin !== undefined && windowWidth <= o.resolutionMin)) {
1785            if (o.element[0].hasAttribute('data-moved')) {
1786                o.element[0].removeAttribute('data-moved');
1787                o.element[o.from.method](o.from.element);
1788            }
1789        } else {
1790            if (!o.element[0].hasAttribute('data-moved')) {
1791                o.element[0].setAttribute('data-moved', true);
1792                o.element[o.to.method](o.to.element);
1793            }
1794        }
1795    },
1796};
1797
1798function footerToggleHandler() {
1799    var $footerBoxes = $(".footer-col-2, .footer-col-3");
1800    var $footerBoxesTitle = $footerBoxes.find('.footer-col-title');
1801    var $footerBoxesContent = $footerBoxes.find('.footer-col-content');
1802    $footerBoxesTitle.bind("click touch", function () {
1803        var $this = $(this);
1804        var $toggled = $this.closest(".footer-col").find(".footer-col-content");
1805        if (windowWidth <= 480) {
1806            if ($this.hasClass("active")) {
1807                $this.removeClass("active");
1808                $toggled.slideUp();
1809            } else {
1810                $footerBoxesContent.slideUp();
1811                $footerBoxesTitle.removeClass("active");
1812                $this.addClass("active");
1813                $toggled.slideDown();
1814            }
1815        }
1816    });
1817}
1818
1819function displaySelectedCount (select) {
1820    var $select = select.parent();
1821    var selectedCount = $select.find(".select2-selection__choice").length;
1822    var total = $select.find("option").length;
1823    var text = "Wybrano " + selectedCount + " z " + total;
1824
1825    if (selectedCount === 0) return;
1826
1827    var setText = function () {
1828        $select.find(".select2-selection__rendered").html(
1829            "<span class=\"select2-selection__count\">" + text + "</span>"
1830        );
1831    };
1832    setText();
1833    window.setTimeout(setText, 25);
1834}
1835
1836function initMovingElements() {
1837    ElementsMovingHandler.add({
1838        element: $('.basket-box.top-box-container'),
1839        resolution: 1140,
1840        from: {
1841            element: $('.headerlink-list'),
1842            method: 'prependTo',
1843        },
1844        to: {
1845            element: $('.rwd-menu-wrapper'),
1846            method: 'appendTo',
1847        }
1848    });
1849}

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.