<?php 
    // prevent direct file access
	if( !defined( 'ABSPATH' ) ) exit;
    
    // core component
    function pixe_main_scripts(){
?>
// core size
window.pixeDisplay = 'desktop';
window.pixeTabletWidth = <?php echo esc_js(pixe_device_width('tablet')); ?>;
window.pixeMobileWidth = <?php echo esc_js(pixe_device_width('mobile')); ?>;
// core functions
$.pixeGetDisplaySize = function(){
    if( typeof(window.matchMedia) == 'function' ){
        if( window.matchMedia('(max-width: ' + pixeMobileWidth + 'px)').matches ){
            window.pixeDisplay = 'mobile'
        }else if( window.matchMedia('(max-width: ' + pixeTabletWidth + 'px)').matches ){
            window.pixeDisplay = 'tablet'
        }else{
            window.pixeDisplay = 'desktop';
        }
    }else{
        if( window.innerWidth <= pixeMobileWidth ){
            window.pixeDisplay = 'mobile'
        }else if( window.innerWidth <= pixeTabletWidth ){
            window.pixeDisplay = 'tablet'
        }else{
            window.pixeDisplay = 'desktop';
        }
    }
}
$.pixeGetDisplaySize();
$(document).ready(function(){ $.pixeGetDisplaySize(); });
$(window).on('resize', function(){ $.pixeGetDisplaySize(); });

// throttling
$.pixeThrottling = function(func, threshold = 7, funcAlways){
    var timeout;

    return function throttled(){
        var obj = this, args = arguments;
        
        if( funcAlways ){
            funcAlways.apply(obj, args);
        }
        function delayed(){
            func.apply(obj, args);
            timeout = null;
        };

        if( !timeout ){
            timeout = setTimeout(delayed, threshold);
        }
    };
}

// debounce function
$.pixeDebounce = function(func, threshold = 800, execAsap = false){
    if( !threshold ) return func;
    
    var timeout;

    return function debounced(){
        var obj = this, args = arguments;

        if( timeout ){
            clearTimeout(timeout);
        }else if( execAsap ){
            func.apply(obj, args);
        }

        timeout = setTimeout(function(){
            if( !execAsap ){
                func.apply(obj, args);
            }
            timeout = null;
        }, threshold);
    };
}

// get ajax content
$.pixeGetAjaxContent = function(settings, options){
    options = $.extend({
        onSuccess: function(html){ 
            if( options && options.container ){
                if( html ){
                    options.container.empty();
                    options.container.append(html);

                    if( typeof(options.onUpdate) == 'function' ){
                        options.onUpdate(options.container);
                    }
                    
                    if( window.pixeEditor && $.pixeEditorEvents.visualchange ){
                        window.pixeEditor.trigger('visualchange');
                    }
                }else{
                    if( typeof(options.onEmpty) == 'function' ){
                        options.onEmpty(options.container);
                    }
                }
            }
        }
    }, options);

    // prepare data
    var data = {
        action: 'pixe_render_item',
        settings: settings
    }
    
    // merge data
    if( options && options.data ){
        data = $.extend(data, options.data);
    }

    // add nonce for admin area
    if( !data.security && $.pixeGetAjaxData ){
        data = $.pixeGetAjaxData(data);
    }

    // set ajax editor type
    if( $.pixeEditor ){
        data['is-admin'] = true;
        data['type'] = pixeData.type;
        data['part'] = pixeData.part;
        data['id'] = pixeData.id;
        data['site'] = pixeData.site;
    }

    // ajax call
    $.ajax({
        type: 'POST',
        url: pixeData.ajaxUrl,
        data: data,
        dataType: 'html',
        error: function(jqXHR, textStatus, errorThrown){
            console.log(jqXHR, textStatus, errorThrown);
        },
        success: options.onSuccess
    });
}

// on image ready
$.pixeOnImageReady = function(container, callback){
    var images = container.find('img');
    var count = images.length;

    images.each(function(){
        if( $(this).attr('src') && this.complete ){
            count--;
        }
    });

    if( count == 0 ){  callback();  return; }
    images.on('load', function(){
        count--;

        if( count == 0 ){  callback(); }
    });
}

// format number
$.pixeFormatNumber = function(number, decimalPoints = 2, thousandSeparator = ',', decimalSeparator = '.'){
    if(typeof number !== 'number') return '-';
    
    // Ensure the number is a float
    const parts = parseFloat(number).toFixed(decimalPoints).split('.');
        
    // Add the thousand separators to the integer part
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator);

    // Join integer and decimal part with the custom decimal separator
    return parts.join(decimalSeparator);
}

$.fn.pixeTriggerLocation = function(settings){
    settings = $.extend({
        onSuccess: undefined
    }, settings);

    var item = $(this);
    var location = $(this).data('trigger-location');

    function animate(){
        var l = 1;

        if( location ){
            switch(window.pixeDisplay){
                case 'mobile':
                    if( location && location.m ){ l = location.m; break; }
                case 'tablet':
                    if( location && location.t ){ l = location.t; break; }
                case 'desktop':
                    if( location && location.d ){ l = location.d; break; }
            }
        }

        // no trigger location
        if( l == -1 ){
            if( settings.onSuccess ){
                settings.onSuccess();
                $(window).off('scroll', animate);
            }
        }else{
            var scrollPos = window.scrollY + (window.innerHeight * l);
            if( scrollPos >= item.offset().top ){
                settings.onSuccess();
                $(window).off('scroll', animate);
            }
        }

    }

    $(window).on('scroll', animate);
    animate();
}

$.pixeSequenceAnimation = function(items, options){
    options = $.extend({
        delay: 150
    }, options);

    var timeout = options.delay;

    items.addClass('pixe-seq-anim');
    items.each(function(){
        var item = $(this);
        setTimeout(function(){
            item.addClass('pixe-animated')
        }, timeout);
        timeout += options.delay;
    });
}

$.pixeSetCookie = function(cname, cvalue, expires){
    if( typeof(expires) != 'undefined' ){
        if( expires == 0 ){ expires = 86400; }

        var now = new Date();
        var new_time  = now.getTime() + (parseInt(expires) * 1000);
        now.setTime(new_time);

        expires = now.toGMTString();
    }

    document.cookie = cname + "=" + encodeURIComponent(cvalue) + "; expires=" + expires + "; path=/";
}

$.fn.pixeOnSwipe = function(settings){

    // default parameter
    settings = $.extend({
        mouseEvent: true,
        swipeThreshold: 150,
        allowedTime: 300
    }, settings);

    var swipeArea = $(this);
    var startX = 0;
    var startTime = 0;
    var startEvent = settings.mouseEvent? 'mousedown touchstart' : 'touchstart';
    var endEvent = settings.mouseEvent? 'mouseup touchend' : 'touchend';

    swipeArea.on(startEvent, function(e){
        var evt = (e.type === 'touchstart') ? e.originalEvent.touches[0] : e;

        startX    = evt.clientX;
        startTime = new Date().getTime();
    });
    swipeArea.on(endEvent, function(e){
        let evt = (e.type === 'touchend') ? e.originalEvent.changedTouches[0] : e;

        var swipeDistance = evt.clientX - startX;
        var elapsedTime = new Date().getTime() - startTime;

        if( elapsedTime <= settings.allowedTime && Math.abs(swipeDistance) > settings.swipeThreshold ){
            if( swipeDistance > 0 ){
                swipeArea.trigger('swiperight');
            }else{
                swipeArea.trigger('swipeleft');
            }
        }
    });

    // prevent dragitem
    if( settings.mouseEvent ){
        swipeArea.on('dragstart', function(e){
            e.preventDefault();
        });
    }
}
// end core functions
<?php
    }

    // lightbox script
    function pixe_lightbox_script(){
?>
$.pixeLightGallery = function(container){
    var lgPlugins = [];
    if( typeof(lgVideo) != 'undefined' ){ lgPlugins.push(lgVideo); }
    if( typeof(lgShare) != 'undefined' ){ lgPlugins.push(lgShare); }
    if( typeof(lgZoom) != 'undefined' ){ lgPlugins.push(lgZoom); }
    if( typeof(lgThumbnail) != 'undefined' ){ lgPlugins.push(lgThumbnail); }
    
    var groups = [];
    container.find('.pixe-lightbox').each(function(){
        if( $(this).attr('data-lg-id') ) return; 
        
        // convert video file data
        var href = $(this).attr('href');
        if( href && href.endsWith('.mp4') ){
            $(this).attr('data-video', JSON.stringify({
                source: [{src: href, type: "video/mp4"}],
                attributes: {preload: false, playsinline: true, controls: true, muted: false}
            }));
            $(this).removeAttr('href');
        }

        var groupSlug = $(this).attr('data-lightbox-group');

        // group images
        if( groupSlug ){
            if( groups.indexOf(groupSlug) == -1 ){
                groups.push(groupSlug);
            }

        // individual image
        }else{
            lightGallery($(this).get(0), {
                selector: 'this',
                plugins: lgPlugins,
                zoomFromOrigin: false,
                download: false,
                mobileSettings: {
                    showCloseIcon: true
                }
            });
        }
    });

    // group images
    for( var i in groups ){
        lightGallery(container.get(0), {
            selector: '.pixe-lightbox[data-lightbox-group="' + groups[i] + '"]',
            plugins: lgPlugins,
            zoomFromOrigin: false,
            mobileSettings: {
                showCloseIcon: true
            }
        });
    }
}
$.pixeGLightbox = function(container){
    var groups = [];

    container.find('.pixe-lightbox').each(function() {
        if( $(this).hasClass('pixe-lb-init') ) return;

        var groupSlug = $(this).attr('data-lightbox-group');

        if( groupSlug ){
            if( groups.indexOf(groupSlug) == -1 ){
                groups.push(groupSlug);
            }
        }else{
            $(this).on('click', function(){
                GLightbox({
                    elements: [{ href: this.href }],
                    touchNavigation: true,
                    loop: false
                }).open();

                return false;
            });
        }
        $(this).addClass('pixe-lb-init');
    });
    
    // group images
    for( var i in groups ){
        GLightbox({
            selector: '.pixe-lightbox[data-lightbox-group="' + groups[i] + '"]',
            touchNavigation: true,
            loop: true,
            zoomable: true
        });
    }
}
$.pixeLightbox = function(container){
    if( typeof(lightGallery) != 'undefined' ){
        $.pixeLightGallery(container);
    }else if( typeof(GLightbox) != 'undefined' ){
        $.pixeGLightbox(container);
    }
}
$(document).ready(function(){
    $.pixeLightbox($(document.body));
});
<?php
    }
    Pixe_Dependency::get()->register_script('lightbox', 'pixe_lightbox_script');

    // background parallax script
    function pixe_bg_parallax_core_script(){
?>
// parallax background
$.fn.pixeParallaxBackground = function(){
    
    $(this).find('.pixe-bg-image[data-parallax]').each(function(){
        var bg = $(this);
        var wrap = $(this).parent('.pixe-bg-style');
        var speed = parseInt($(this).attr('data-parallax')) / 100;
        if( speed == 0 ) return;

        function setHeight(){
            var newHeight = wrap.outerHeight();
            var screenHeight = window.innerHeight;

            if( speed > 0 ){
                newHeight += (screenHeight - newHeight) * speed;
            }else if( speed < 0){
                newHeight += (screenHeight + newHeight) * Math.abs(speed);
            }
            bg.css({height: newHeight});
        }
        function setPosition(){
            var wrapTopPos = wrap.offset().top;
            var wrapBottomPos = wrapTopPos + wrap.outerHeight();
            var scrollPos = window.scrollY;
            var screenHeight = window.innerHeight;

            if( scrollPos + screenHeight > wrapTopPos && scrollPos < wrapBottomPos ){
                if( speed > 0 ){
                    bg.css({'transform': 'translate(0px, ' + ((scrollPos - wrapTopPos) * speed) + 'px)'});
                }else if( speed < 0 ){
                    bg.css({'transform': 'translate(0px, ' + ((scrollPos + screenHeight - wrapTopPos) * speed) + 'px)'});
                }
            }
        }

        setHeight();
        setPosition();
        $(window).on('load resize', function(){
            setHeight();
            setPosition();
        });
        $(window).on('scroll', $.pixeThrottling(function(){
            setPosition();
        }));

    });

}
<?php
    }
    function pixe_bg_parallax_script(){
?>
$(document).ready(function(){ $(document.body).pixeParallaxBackground(); });
<?php
    }
    Pixe_Dependency::get()->register_core_script('bg-parallax', 'pixe_bg_parallax_core_script');
    Pixe_Dependency::get()->register_script('bg-parallax', 'pixe_bg_parallax_script');

    // background video script
    function pixe_video_core_script(){
?>
// video bg
$.pixeVideo = {
    vimeoJs: false,
    youtubeJs: false,
    youtubeIframeReady: false,
    mediaFrameId: 0,
    
    resizePortrait: function(item){
        if( item.outerWidth() == 0 ) return;

        function setVideoSize(){
            var fvideo = $(this);
            var iframe = fvideo.children('iframe');
            var container = fvideo.parent('.pixe-fvideo-wrap');
            if( !iframe.length || !container.length ) return;

            var ratio = parseInt(iframe.attr('height')) / parseInt(iframe.attr('width'));
            if( isNaN(ratio) ){ ratio = 0.5625; } // 9:16 for default ratio

            // only apply ratio when height is too long
            var containerRatio = container.outerHeight() / container.outerWidth();
            if( containerRatio > ratio ){
                fvideo.css({
                    width: container.outerHeight() / ratio,
                    height: container.outerHeight()
                });
            }else{
                fvideo.css({width: '', height: ''});
            }
        }

        item.find('.pixe-fvideo').each(setVideoSize);
        item.filter('.pixe-fvideo').each(setVideoSize);
    },

    initVimeo: function(){
        var t = this;
        if( !t.vimeoJs ){
            t.vimeoJs = true;
            var tag = document.createElement('script');
            tag.src = "https://player.vimeo.com/api/player.js";

            var firstScriptTag = document.getElementsByTagName('script')[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
        }
    },

    initYoutube: function(){
        var t = this;
        if( !t.youtubeJs ){
            t.youtubeJs = true;
            var tag = document.createElement('script');
            tag.src = "https://www.youtube.com/iframe_api";

            var firstScriptTag = document.getElementsByTagName('script')[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

            window.onYouTubeIframeAPIReady = function(){
                t.youtubeIframeReady = true;
            }
        }
    },

    initMedia: function(container){
        var t = this;
        container.find('[data-js-api]').each(function(){
            var api = $(this).attr('data-js-api');

            if( api == 'youtube' ){
                t.initYoutubeMedia($(this));
            }else if( api == 'vimeo' ){
                t.initVimeoMedia($(this));
            }else if( api == 'html5'){
                t.setHtml5Video($(this));
            }
        });
    },

    initVimeoMedia: function(iframe){
        var t = this;
        t.initVimeo();

        // set id if not exists
        var id = iframe.attr('id');
        if( !id ){
            t.mediaFrameId++;
            id = 'pixe-iframe-media-' + t.mediaFrameId;
            iframe.attr('id', id);
        } 

        if( typeof(Vimeo) != 'undefined' && Vimeo.Player && iframe.closest(document.body).length ){
            t.setVimeoMedia(iframe);
        }
        var i = setInterval(function(){
            if( typeof(Vimeo) != 'undefined' && Vimeo.Player && iframe.closest(document.body).length ){
                t.setVimeoMedia(iframe);
                clearInterval(i);
            }
        }, 500);
    },

    setVimeoMedia: function(iframe){

        var startTime = iframe.attr('data-start-time') || 0;
        var endTime = iframe.attr('data-end-time') || 0;
        var isBackground = iframe.attr('data-background');
        var isLoop = iframe.attr('data-loop');
        var isMuted = iframe.attr('data-muted');
        var isAutoplay = iframe.attr('data-autoplay');

        // video atts
        var videoAtts = {
            id: iframe.attr('data-video-id'),
            isLoop: isLoop? 1: 0
        };
        if( isBackground ){
            videoAtts.background = true;
        }

        // player
        var id = iframe.attr('id');
        var fvideo = iframe.parent('.pixe-fvideo').attr('id', id);
        iframe.remove();

        var player = new Vimeo.Player(iframe.attr('id'), videoAtts);
        fvideo.data('player', player);
        fvideo.attr('data-js-api', 'vimeo');

        player.on('loaded', function(){
            $.pixeVideo.resizePortrait(fvideo);
        });

        // action
        if( startTime ){
            player.setCurrentTime(startTime);
        }
        if( endTime ){
            player.addCuePoint(endTime);
            player.on('cuepoint', function(e){
                if( e.time == endTime ){
                    if( isLoop ){
                        player.setCurrentTime(startTime);
                    }else{
                        player.pause();
                    }
                }
            });
        }

        if( isBackground ){
            player.setVolume(0);
            player.play();
        }else{
            if( isMuted ){
                player.setVolume(0);
            }
            if( isAutoplay ){
                player.play();
            } 
        }

    },

    initYoutubeMedia: function(iframe){
        var t = this;
        t.initYoutube();

        // set id if not exists
        var id = iframe.attr('id');
        if( !id ){
            t.mediaFrameId++;
            id = 'pixe-iframe-media-' + t.mediaFrameId;
            iframe.attr('id', id);
        } 
        
        if( t.youtubeIframeReady && iframe.closest(document.body).length ){
            t.setYoutubeMedia(iframe);
        }else{
            var i = setInterval(function(){
                if( t.youtubeIframeReady && iframe.closest(document.body).length ){
                    t.setYoutubeMedia(iframe);
                    clearInterval(i);
                }
            }, 500);
        }
        
    },

    setYoutubeMedia: function(iframe){
        var t = this;
        var startTime = iframe.attr('data-start-time') || 0;
        var endTime = iframe.attr('data-end-time') || 0;
        var isBackground = iframe.attr('data-background');
        var isLoop = iframe.attr('data-loop');
        var isMuted = iframe.attr('data-muted');
        var isAutoplay = iframe.attr('data-autoplay');

        // video atts
        var videoAtts = {
            videoId: iframe.attr('data-video-id'),
            events: {
                'onReady': function (event){
                    if( isBackground ){
                        event.target.mute();
                        event.target.playVideo();
                    }else{
                        if( isMuted ){
                            event.target.mute();
                        }
                        if( isAutoplay ){
                            event.target.playVideo();
                        }
                    }
                    
                },
                'onStateChange': function(event){
                    if( event.data == 0 && event.target && event.target.seekTo ){
                        if( isLoop ){
                            event.target.seekTo(startTime);
                        }else{
                            event.target.pauseVideo();
                        }
                        
                    }
                }
            }
        }
        if( iframe.attr('data-background') ){
            videoAtts.playerVars = {
                'autoplay': 1, 
                'controls': 0,
                'rel': 0,
                'start': startTime,
                'end': endTime,
            };
        }else{
            videoAtts.playerVars = {
                'start': startTime,
                'end': endTime
            }
        }
        
        // init
        new YT.Player(iframe.attr('id'), videoAtts);

        // resize video
        $('#' + iframe.attr('id')).each(function(){
            t.resizePortrait($(this).parent('.pixe-fvideo'));
        });
    },

    setHtml5Video: function(video){
        var loop = video.prop('loop');
        var autoplay = video.prop('autoplay');
        var startTime = video.attr('data-start-time');
        var endTime = video.attr('data-end-time');
        
        if( startTime ){
            video.on('loadedmetadata', function(){
                this.currentTime = startTime
            });
        }
        if( loop ){
            video.on('timeupdate', function(){
                if( (endTime && this.currentTime > endTime) || this.ended ){
                    this.currentTime = startTime? startTime: 0;
                    this.play();
                }
            });
        }
        
        var videoObject = video.get(0);
        if( autoplay && videoObject.paused ){
            videoObject.currentTime = startTime? startTime: 0;
            videoObject.muted = true; 
            videoObject.play();
        }
    },

    playVideo: function(iframe){
        if( iframe.attr('data-js-api') == 'youtube' ){
            var player = YT.get(iframe.attr('id'));
            player.playVideo();
        }else if( iframe.closest('.pixe-fvideo').attr('data-js-api') == 'vimeo' ){
            var player = iframe.closest('.pixe-fvideo').data('player');
            if( player ){
                player.play();
            }
        }
    },
};
<?php
    }
    function pixe_bg_video_script(){
?>
$(document).ready(function(){ 
    $.pixeVideo.resizePortrait($(document.body)); 
    $.pixeVideo.initMedia($(document.body)); 
});
<?php
    }
    Pixe_Dependency::get()->register_core_script('video-js', 'pixe_video_core_script');
    Pixe_Dependency::get()->register_script('video-js', 'pixe_bg_video_script');

    // animation script
    function pixe_animation_script(){
?>
// animation script
$(document).ready(function(){
    $('[data-anim-location]').each(function(){
        var item = $(this);
        var location = $(this).data('anim-location');
        var repeat = location && location.repeat;
        var startHidden = (item.css('opacity') == 0);
        var observer;
        
        // add animation class
        item.on('animationstart', function(){
            $(this).addClass('pixe-animating');
        });
        item.on('animationend animationcancel', function(){
            $(this).removeClass('pixe-animating');
        });

        // add animated class in trigger location
        function animate(){
            if( item.hasClass('pixe-animating') ) return;
            var l = 1;

            switch(window.pixeDisplay){
                case 'mobile':
                    if( location && location.m ){ l = location.m; break; }
                case 'tablet':
                    if( location && location.t ){ l = location.t; break; }
                case 'desktop':
                    if( location && location.d ){ l = location.d; break; }
            }
            
            // no trigger location
            if( l == -1 ){
                item.addClass('pixe-animated');
                $(window).off('scroll', animate);
                observer.disconnect();
                
            }else{
                var scrollPos = window.scrollY + (window.innerHeight * l);
                if( scrollPos >= item.offset().top ){
                    if( !item.hasClass('pixe-animated') ){
                        item.addClass('pixe-animated');
                        if( !repeat ){
                            $(window).off('scroll', animate);
                            observer.disconnect();
                        }
                    }
                }else{
                    if( item.hasClass('pixe-animated') ){
                        if( startHidden ){
                            item.animate({opacity: 0}, 150, function(){
                                item.css({opacity: ''});
                            });
                        }
                        item.removeClass('pixe-animated');
                    }
                }
            }

        } // animate

        // observer to reduce work load
        observer = new IntersectionObserver(function(entries){
            entries.forEach(function(entry){
                if( entry.isIntersecting ){
                    $(window).on('scroll', animate);
                }else{
                    $(window).off('scroll', animate);
                }
            });
        });
        observer.observe(item[0]);

        $(window).on('scroll', animate);
        animate();
    });
});
<?php
    }
    Pixe_Dependency::get()->register_script('animation', 'pixe_animation_script');

    // justified script
    function pixe_justified_script(){
?>
$.pixeJustified = function(container){
    var t = this;
    t.container = container;
    t.containerWidth = 0;
    t.init();
}
$.pixeJustified.prototype = {
    init: function(){
        var t = this;
        t.container.data('justified', this);
        t.getSettings();
        t.animate(t.items);

        t.onResize = $.pixeDebounce(function(e){
            if( !t.container.data('justified') || t.container.data('justified') != t ){
                $(window).off('resize', t.onResize);
                return;
            }

            var containerWidth = t.container.width();
            if( containerWidth != t.containerWidth || e.type == 'changeheight' ){
                t.animate(t.items);
            }
        });

        if( $.pixeEditor ){
            t.container.on('changeheight', t.onResize);
        }
            
        $(window).on('resize', t.onResize);
    },

    getSettings: function(){
        var t = this;
        t.settings = { delay: 150, imageThreshold: 200 };
        t.items = t.container.children('.pixe-grid-item');
    },

    isRowFull: function(row){
        var t = this;
        var endPos = row.offset().left + row.outerWidth();
        var lastChild = row.children().last();
        if( !lastChild.length ) return false;

        var lastChildEndPos = lastChild.offset().left + lastChild.outerWidth();
        return (endPos - lastChildEndPos < t.settings.imageThreshold);
    },

    addToRow: function(item){
        var t = this;

        if( !t.row ){ 
            t.row = $('<div class="pixe-justified-row" ></div>'); 
            t.row.appendTo(t.container);
        }

        item.appendTo(t.row);

        var isRowFull = t.isRowFull(t.row);
        if( isRowFull ){
            t.row.addClass('pixe-stretch');
            delete t.row;
        }
        
    },

    // replace or append item
    update: function(items, replace = true){
        var t = this;
        var queue = [];

        if( replace ){
            t.items = items;
            t.animate(items);
        }else{
            t.items.add(items, false);
        }
    },

    animate: function(items, replace = true){
        var t = this;
        if( replace ){
            t.container.empty();
        }

        t.containerWidth = t.container.width();
        items.removeClass('pixe-init');

        var queue = [];
        items.each(function(){ 
            t.addToRow($(this));
            queue.push($(this));
        });

        // animate opacity
        setInterval(function(){
            if( queue.length ){
                var target = queue.shift();
                target.addClass('pixe-init');
            }else{
                clearInterval(t.interval);
                delete t.interval;
            }
        }, t.settings.delay);
    }
}
<?php
    }
    Pixe_Dependency::get()->register_core_script('justified', 'pixe_justified_script');

    // masonry script
    function pixe_masonry_script(){
?>
$.pixeMasonry = function(container, settings){
    var t = this;
    t.settings = $.extend({
        delay: 150,
        itemSelector: '.pixe-grid-item'
    }, settings);

    t.container = container;
    t.init();
}
$.pixeMasonry.prototype = {
    
    init: function(){
        var t = this;
        t.container.addClass('pixe-masonry');
        t.container.data('masonry', this);
        t.getSettings();
        t.animate();
        
        t.onResize = $.pixeDebounce(function(e){ 
            if( !t.container.data('masonry') || t.container.data('masonry') != t ){
                $(window).off('resize', t.onResize);
                return;
            }
            t.animate(); 
        });

        $(window).on('resize', t.onResize);
    },

    getSettings: function(){
        var t = this;
        t.settings.column = t.container.attr('data-col');
        t.settings.tColumn = t.container.attr('data-tablet-col');
        t.settings.mColumn = t.container.attr('data-mobile-col');

        t.items = t.container.children(t.settings.itemSelector);
        t.items.addClass('pixe-masonry-item');
    },

    reset: function(){
        var t = this;

        t.currentCol = '';
        t.container.empty();
        t.items.removeClass('pixe-init');
    },

    // replace or append item
    update: function(items, replace = true){
        var t = this;

        items.addClass('pixe-masonry-item');
        if( replace ){
            t.currentCol = '';
            t.items = items;
            t.reset();
            t.animate();
        }else{
            t.items.add(items);
            items.each(function(){
                t.addItem($(this));
            });
        }
    },

    animate: function(){
        var t = this;

        // get column
        var col = 4; // default column

        switch(window.pixeDisplay){
            case 'mobile':
                if( t.settings.mColumn ){
                    col = t.settings.mColumn;
                    break;
                }
            case 'tablet':
                if( t.settings.tColumn ){
                    col = t.settings.tColumn;
                    break;
                }
            case 'desktop':
                if( t.settings.column ){
                    col = t.settings.column;
                    break;
                }
        }

        // animate only when there're changes to column
        if( t.currentCol != col ){
            t.reset();
            t.currentCol = col;
            
            // create new column
            t.columns = [];
            t.queue = [];
            for( var i = 0; i < col; i++ ){
                var column = $('<div class="pixe-masonry-column" ></div>');
                t.container.append(column);
                t.columns.push(column);
            }
            
            // add each item to the layout
            t.items.each(function(){
                t.addItem($(this));
            });
        }
    },

    getShortestColumn: function(){
        var t = this;
        var minHeight = Number.MAX_VALUE;
        var column;

        for( var i = 0; i < t.columns.length; i++ ){
            var height = t.columns[i].outerHeight();
            if( height < minHeight ){
                minHeight = height;
                column = t.columns[i];
            }
        }

        return column;
    },

    addItem: function(item){
        var t = this;
        t.queue.push(item);

        var column = t.getShortestColumn();
        column.append(item);

        // animate opacity
        if( !t.interval ){
            t.interval = setInterval(function(){
                if( t.queue.length ){
                    var target = t.queue.shift();
                    target.addClass('pixe-init');
                }else{
                    clearInterval(t.interval);
                    delete t.interval;
                }
            }, t.settings.delay);
        }
    },
}
<?php
    }
    Pixe_Dependency::get()->register_core_script('masonry', 'pixe_masonry_script');

    // filter bar script
    function pixe_filter_bar_script(){
?>
$.pixeFilterBar = function(filter){
    var hasFilterBar = filter.is('[data-filter-bar]');
    var filterBarType = filter.attr('data-filter-bar');
    var filterBar = filter.find('.pixe-filter-bar');
    
    if( hasFilterBar && filterBarType != 'border' ){
        function targetCss(target){
            if( !target.length ) return {};

            return {
                top: target.position().top + target.outerHeight(),
                left: target.position().left,
                width: target.outerWidth()
            };
        }

        if( !filterBar.length ){
            filterBar = $('<div class="pixe-filter-bar"><span></span></div>');
            filterBar.appendTo(filter);

            // initial position
            filterBar.css(targetCss(filter.children('.pixe-active')));
            
            // event
            filter.on('mouseenter', '[data-filter]', function(e){
                if( !filterBar.parent().length ){ filter.off(e); return; }

                filterBar.animate(targetCss($(this)), {duration: 150, queue: false});
            });
            filter.on('mouseleave', '[data-filter]', function(e){
                if( !filterBar.parent().length ){ filter.off(e); return; }

                if( $(this).hasClass('pixe-active') ){
                    filterBar.animate(targetCss($(this)), {duration: 150, queue: false});
                }else{
                    var target = $(this).siblings('.pixe-active');
                    filterBar.animate(targetCss(target), {duration: 150, queue: false});
                }
            });

            // on resize event
            $(window).on('resize', function(e){
                if( !filterBar.closest(document.body).length ){ $(this).off(e); }
                filterBar.css(targetCss(filter.children('.pixe-active')));
            });
        }else{
            // init position again
            filterBar.css(targetCss(filter.children('.pixe-active')));
        }
    }else{
        filterBar.remove();
    }
}
<?php
    }
    Pixe_Dependency::get()->register_core_script('filter-bar', 'pixe_filter_bar_script');

    // collection slider
    function pixe_collection_script(){
?>
$.pixeCollectionSlider = function(slider){
    var t = this;

    t.slider = slider;
    t.content = t.slider.children('.pixe-collection-content');
    t.slides = t.content.children('.pixe-wrapper').not('.pixe-is-overlay');
    t.settings = t.slider.data('slider')? t.slider.data('slider'): {};

    // init data
    t.pauseSlide = false;
    t.currentIndex = 0;
    t.currentSlide = undefined;
    t.nextSlide = t.slides.eq(t.currentIndex);
    t.slideDuration = t.settings['slide-duration']? t.settings['slide-duration']: 7000;
    t.animInDuration = t.settings['in-duration']? t.settings['in-duration']: 500;

    t.slideTimeout = 0;
    t.slideEndTime = 0;
    t.init();
}
$.pixeCollectionSlider.prototype = {

    init: function(){
        var t = this;
        t.animateSlide();
        t.bulletInit();
        t.navigationInit();
        t.bindSwipe();

        // pause on hover events
        var slideDiffTime = 0;
        if( t.settings['autoplay'] && t.settings['pause-on-hover'] ){
            t.slider.on('mouseenter', function(){
                t.pauseSlide = true;
                if( t.slideTimeout ){
                    clearTimeout(t.slideTimeout);
                    t.slideDiffTime = t.slideEndTime - parseFloat(new Date().getTime());
                    t.slideDiffTime = t.slideDiffTime > 0? t.slideDiffTime: undefined;
                }else{
                    t.slideDiffTime = undefined;
                }
            });
            t.slider.on('mouseleave', function(){
                t.pauseSlide = false;
                t.autoplaySlide(t.slideDiffTime);
            });
        }
    },

    // swipe
    bindSwipe: function(){
        var t = this;

        t.content.pixeOnSwipe();
        t.content.on('swipeleft swiperight', function(e){
            if( e.type == 'swipeleft' ){
                t.toNextSlide();
            }else if( e.type == 'swiperight' ){
                t.toPrevSlide();
            }
        });
    },

    // animate slide
    animateSlideIn: function(){
        var t = this;

        // clear old slides
        var nextSlide = t.nextSlide;
        if( nextSlide.data('timeout') ){
            clearTimeout(nextSlide.data('timeout'));
            nextSlide.removeClass('pixe-anim-in pixe-anim-out pixe-active-slide');
            nextSlide.removeData('timeout');
        }

        // slide in
        nextSlide.addClass('pixe-active-slide');
        setTimeout(function(){
            nextSlide.addClass('pixe-anim-in');
        }, 20);

        // timer for autoplay
        if( t.slideTimeout ){
            clearTimeout(t.slideTimeout);
        }
        
        // autoplay next slide
        if( t.settings.autoplay ){
            t.autoplaySlide();
        }
    },
    animateSlideOut: function(){
        var t = this;

        var activeSlide = t.currentSlide;
        if( activeSlide && activeSlide.length ){
            activeSlide.addClass('pixe-anim-out');

            var timeout = setTimeout(function(){
                activeSlide.removeClass('pixe-anim-in pixe-anim-out pixe-active-slide');
                activeSlide.removeData('timeout');
            }, t.animInDuration);
            activeSlide.data('timeout', timeout);
        }
    },
    animateSlide: function(){
        var t = this;
        
        t.animateSlideOut();
        t.animateSlideIn();

        // animate bullet
        if( t.bullets ){
            t.bullets.eq(t.currentIndex).addClass('pixe-active').siblings().removeClass('pixe-active')
        }
    },

    // go to next slide
    toNextSlide: function(){
        var t = this;
        t.currentIndex++;
        if( t.currentIndex >= t.slides.length ){
            t.currentIndex = 0;
        }

        t.currentSlide = t.nextSlide;
        t.nextSlide = t.slides.eq(t.currentIndex);
        t.animateSlide();
    },

    // go to prev slide
    toPrevSlide: function(){
        var t = this;
        t.currentIndex--;
        if( t.currentIndex < 0 ){
            t.currentIndex = t.slides.length - 1;
        }

        t.currentSlide = t.nextSlide;
        t.nextSlide = t.slides.eq(t.currentIndex);
        t.animateSlide();
    },
    
    autoplaySlide: function(slideTime){
        var t = this;
        if( t.pauseSlide ) return;

        // find the slide time
        if( !slideTime ){
            var slideTime = t.slideDuration;
            if( t.nextSlide.attr('data-slide-duration') ){
                slideTime = parseFloat(t.nextSlide.attr('data-slide-duration'));
            }
            if( !slideTime ){
                slideTime = t.slideDuration;
            }
        }
        
        // animate
        t.slideEndTime = parseFloat(new Date().getTime()) + parseFloat(slideTime);
        t.slideTimeout = setTimeout(function(){
            t.toNextSlide();
        }, slideTime);
    },

    bulletInit: function(){
        var t = this;
        t.bullet = t.slider.children('.pixe-bullet');
        t.bullet.addClass('pixe-init');
        if( t.bullet.length ){
            t.bullet.empty();
            for( var i = 0; i < t.slides.length; i++ ){
                t.bullet.append('<span ' + (i == t.currentIndex? 'class="pixe-active"': '') + ' ></span>');
            }   
            t.bullets = t.bullet.children();
            t.bullets.on('click', function(){
                if( $(this).index() == t.currentIndex ) return;

                t.currentIndex = $(this).index();
                t.currentSlide = t.nextSlide;
                t.nextSlide = t.slides.eq(t.currentIndex);
                t.animateSlide();
            });
        }else{
            delete t.bullet;
            delete t.bullets;
        }
    },

    navigationInit: function(){
        var t = this;
        var nav = t.slider.children('.pixe-navigation');
        nav.addClass('pixe-init');
        nav.on('click', '.pixe-prev, .pixe-next', function(){
            if( $(this).hasClass('pixe-prev') ){
                t.toPrevSlide();
            }else if( $(this).hasClass('pixe-next') ){
                t.toNextSlide();
            }
        });
    }

}
$(document).ready(function(){
    $('.pixe-collection-slider').each(function(){
        new $.pixeCollectionSlider($(this));
    });
});
<?php
    }
    Pixe_Dependency::get()->register_script('collection_slider', 'pixe_collection_script');

    // collection carousel
    function pixe_collection_carousel(){
?>
$(document).ready(function(){
    $('.pixe-collection-carousel').each(function(){
        new $.pixeCarousel($(this), {
            slideSelector: '.pixe-collection-content',
            gridSelector: '.pixe-column',
            controlsArea: 'children',
            syncNavPosition: false
        });
    });
});
<?php
    }
    Pixe_Dependency::get()->register_script('collection_carousel', 'pixe_collection_carousel');

    // carousel script
    function pixe_carousel_script(){
?>
$.pixeCarousel = function(container, settings){
    var t = this;
    t.settings = $.extend({
        slideSelector: '.pixe-slides',
        gridSelector: '.pixe-grid-item',
        controlsArea: 'siblings',
        syncNavPosition: true,
        loop: container.attr('data-loop')? false: true, // duplicate image to loop as carousel
        start: container.attr('data-start')? parseInt(container.attr('data-start')) - 1: 0,
        move: container.attr('data-move')? parseInt(container.attr('data-move')): 1,
        autoplay: container.attr('data-autoplay'),
        activeClass: container.attr('data-active-class')? true: false,
        animationTime: container.attr('data-speed')? parseInt(container.attr('data-speed')): 500,
        animationDelay: container.attr('data-delay')? parseInt(container.attr('data-delay')): 7000,
        pauseOnHover: container.attr('data-poh')? true: false
    }, settings);

    if( !container.children(t.settings.slideSelector).length ) return;
    if( container.hasClass('pixe-carousel') ) return; 

    t.container = container;
    t.slides = container.children(t.settings.slideSelector);
    t.images = t.slides.children(t.settings.gridSelector);
    t.steps = t.images.length;
    t.pause = false;
    
    t.overflow = t.slides.css('overflow');

    t.init();
}
$.pixeCarousel.prototype = {

    init: function(isUpdate = false){
        var t = this;
        t.container.addClass('pixe-carousel');
        t.container.data('carousel', this);

        // double the image amount for carousel animaation
        if( t.settings.loop ){
            var cWidth = t.slides.outerWidth();
            var iWidth = 0;
            t.images.each(function(){ iWidth += $(this).outerWidth(); });
            
            t.dupeBefore = t.getDupe(t.images.filter(function(i){ return i >= t.steps - 3; }));
            t.dupeAfter = t.getDupe(t.images);

            // duplicate twice if width is short
            if( iWidth < cWidth ){
                t.dupeAfter = t.dupeAfter.add(t.getDupe(t.images))
            } 

            t.slides.prepend(t.dupeBefore);
            t.slides.append(t.dupeAfter);
        }

        // init variable
        t.firstSlide = t.slides.children().first();
        t.currentStep = t.settings.start;
        if( t.currentStep < 0 || t.currentStep >= t.steps ){
            t.currentStep = 0;
        }
        if( t.settings.move <= 0 ){
            t.settings.move = 1;
        }
        
        // init position
        t.currentPos = -($(t.images.get(t.currentStep)).position().left);
        t.setPos(t.currentPos);

        t.setLastSlide();
        t.navInit();
        t.touchNavInit();
        t.bulletInit();
        t.bulletThumbnailInit();
        t.bindSwipe();

        t.initActiveClass();
        t.setActiveClass();
        
        if( !isUpdate ){
            t.startInterval();
            
            // pause on hover
            if( t.settings.pauseOnHover ){
                t.container.on('mouseover', function(){
                    t.pause = true;
                });
                t.container.on('mouseout', function(){
                    t.pause = false;
                });
            }

            // resize window
            $(window).on('resize', $.pixeDebounce(function(){
                t.initActiveClass();
                t.setActiveClass();
                if( t.settings.autoplay != 'cont' ){
                    t.animate(t.currentStep);
                }
                
                t.setLastSlide();
                t.bulletInit();
            }));
        }
    },

    update: function(elements){
        var t = this;
        t.slides.empty().append(elements);
        t.images = t.slides.children(t.settings.gridSelector);
        t.steps = t.images.length;

        if( t.interval ){ clearInterval(t.interval); }
        if( elements.length ){ 
            t.init(); 
        }else{
            t.bulletInit(); // reset bullet
        }
    },

    setPos: function(position){
        var t = this;

        if( t.overflow == 'hidden' ){
            t.firstSlide.css({'margin-left': position});
        }else{
            t.slides.css({'transform': 'translateX(' + position + 'px)'});
        }
    },

    // duplicate element and manage lightbox events
    getDupe: function(elements){
        var dupe = $();

        elements.each(function(){
            var elem = $(this);
            var clone = elem.clone().addClass('pixe-dupe');

            // manage lightbox
            if( clone.children('.pixe-lightbox').length ){
                clone.children('.pixe-lightbox').removeClass('pixe-lightbox').removeAttr('data-lightbox-group');
                clone.on('click', function(){
                    elem.find('img').trigger('click');
                    return false;
                });
            }

            dupe = dupe.add(clone);
        });

        return dupe;
    },

    // use to set last slide/step when carousel is not looped
    // set first and last post of animate 'cont'
    setLastSlide: function(){
        var t = this;

        // cont animation
        if( t.settings.autoplay == 'cont' ){
            t.startPos = -t.images.first().position().left;
            t.endPos = -t.dupeAfter.first().position().left;

        // no loop
        }else if( !t.settings.loop ){
            if( t.settings.loop ) return true;

            var containerWidth = t.slides.outerWidth();
            var lastItem = t.images.last();
            var endPos = lastItem.position().left + lastItem.outerWidth();
            var startPos = endPos - containerWidth - 5; // start pos for last slide ( threshold 5px )

            t.images.each(function(){
                var itemStart = $(this).position().left;
                if( itemStart >= startPos ){
                    t.steps = $(this).index() + 1;
                    return false;
                }
            });
        }
        
    },

    // adding active class to item within container area
    initActiveClass: function(){
        var t = this;
        if( !t.settings.activeClass ) return;

        t.slides.children().each(function(){
            $(this).data('mpos', $(this).position().left + ($(this).outerWidth() / 2));
        });
    },
    setActiveClass: function(){
        var t = this;
        if( !t.settings.activeClass ) return;

        var containerWidth = t.slides.outerWidth();
        t.slides.children().each(function(){
            var itemPos = t.currentPos + $(this).data('mpos');
            if( itemPos > 0 && itemPos < containerWidth ){
                $(this).addClass('pixe-active-slide').removeClass('pixe-inactive-slide');
            }else{
                $(this).removeClass('pixe-active-slide').addClass('pixe-inactive-slide');
            }
        });
    },

    startInterval: function(){
        var t = this;
        if( t.settings.autoplay == 'no' ) return;

        // continuous slide
        if( t.settings.autoplay == 'cont' ){
            t.animateCont();
        }else{
            t.interval = setInterval(function(){
                if( t.pause ) return;
                
                t.next();

                // stop interval for editor
                if( $.pixeEditor && !t.container.closest(document.body).length ){
                    clearInterval(t.interval);
                }
            }, t.settings.animationDelay);
        }
    },
    
    next: function(resetTimer = false){
        var t = this;
        if( t.currentStep + t.settings.move < t.steps ){
            t.animate(t.currentStep + t.settings.move);
        }else if( t.currentStep != t.steps - 1 ){
            t.animate(t.steps - 1);
        }else{
            t.animate(0);
        }

        if( resetTimer && t.interval ){
            clearInterval(t.interval);
            t.startInterval();
        }
    },

    prev: function(resetTimer = false){
        var t = this;
        if( t.currentStep == 0 ){
            t.animate(t.steps - 1);
        }else if( t.currentStep < t.settings.move ){
            t.animate(0)
        }else{
            t.animate(t.currentStep - t.settings.move);
        }
        
        if( resetTimer && t.interval ){
            clearInterval(t.interval);
            t.startInterval();
        }
    },

    setContActiveBullet: function(){
        var t = this;
        if( !t.bullets || !t.bullets.length || !t.dupeAfter || !t.dupeAfter.length ) return;

        var firstPos = t.images.first().position().left;
        var cycleWidth = t.dupeAfter.first().position().left - firstPos;
        if( cycleWidth <= 0 ) return;

        var offset = (-t.currentPos) - firstPos;
        offset = ((offset % cycleWidth) + cycleWidth) % cycleWidth;

        var activeStep = 0;
        t.images.each(function(i){
            if( $(this).position().left - firstPos <= offset + 1 ){
                activeStep = i;
            }else{
                return false;
            }
        });

        if( activeStep != t.currentStep ){
            t.currentStep = activeStep;
            $(t.bullets.get(activeStep)).addClass('pixe-active').siblings().removeClass('pixe-active');
        }
    },

    animateCont: function(){
        var t = this;
        if( t.contAnimationFrame ) return;

        t.currentPos = t.startPos;
        t.setPos(t.currentPos);
        t.setContActiveBullet();
        var lastTime = performance.now();
        
        // get speed & direction
        var speed = parseInt(t.container.attr('data-speed'));
        var direction = (t.container.attr('data-direction') == 'right')? 1: -1;
        if( !speed ) speed = 50; 
        speed = speed * direction;

        function animate(){
            var time = performance.now();
            var deltaTime = (time - lastTime) / 1000;
            lastTime = time;

            var deltaPos = speed * deltaTime;

            if( !t.pause && !t.isAnimated ){
                t.currentPos += deltaPos;
                if( deltaPos > 0 && t.currentPos >= t.startPos ){
                    t.currentPos = t.endPos;
                }else if( deltaPos < 0 && t.currentPos <= t.endPos ){
                    t.currentPos = t.startPos;
                }

                t.setPos(t.currentPos);
                t.setContActiveBullet();
            }
            
            // stop interval for editor
            if( $.pixeEditor && !t.container.closest(document.body).length ){
                delete t.contAnimationFrame;
                return;
            }

            // continue to next frame
            t.contAnimationFrame = requestAnimationFrame(animate);
        }

        t.contAnimationFrame = requestAnimationFrame(animate);
    },

    animate: function(nextStep){
        var t = this;
        var initialPos = t.currentPos;
        var target = $(t.images.get(nextStep));
        if( !target.length ) return;

        var targetPos = - (target.position().left);
        var offset = 0;
        if( t.overflow == 'hidden' ){
            if( target.is(t.firstSlide) ){
                targetPos = 0;
            }else{
                offset = t.currentPos;
                targetPos += t.currentPos;
            }
        }

        // position the slide to loop the carousel
        if( t.settings.autoplay != 'cont' && !t.isAnimated && t.settings.loop){
            var jump = false;

            if( t.currentStep == t.steps - 1 && nextStep == 0 ){ 
                jump = true;
                initialPos = offset - (t.dupeBefore.last().position().left);
                t.setPos(initialPos);
            }else if( t.currentStep == 0 && nextStep == t.steps - 1 ){ 
                jump = true;
                initialPos = offset - (t.dupeAfter.first().position().left);
                t.setPos(initialPos);
            }

            // fix loop jump animation
            if( jump && t.settings.activeClass ){
                t.currentPos = initialPos;

                var children = t.slides.children();
                children.addClass('pixe-no-transition');
                t.setActiveClass();
                setTimeout(function(){ 
                    children.removeClass('pixe-no-transition'); 
                }, 0);
            }
        }
        
        // animate distance
        t.isAnimated = true;
        $({targetPos: initialPos}).animate({targetPos: targetPos}, {
            step: function(now, fx){
                t.currentPos = now;
                t.setPos(now, false);
            },
            duration: t.settings.animationTime, 
            queue: false,
            complete: function(){ 
                t.isAnimated = false; 
            }
        });

        // animate bullet
        if( t.bullets && t.bullets.length ){
            $(t.bullets.get(nextStep)).addClass('pixe-active').siblings().removeClass('pixe-active');
        }

        // bullet thumbnail
        t.animateBulletThumbnail(nextStep);
        
        // update state
        t.currentStep = nextStep;
        
        setTimeout(function(){
            t.currentPos = targetPos;
            t.setActiveClass();
        }, 0);
    },
    
    bindSwipe: function(){
        var t = this;

        t.container.pixeOnSwipe();
        t.container.on('swipeleft swiperight', function(e){
            if( e.type == 'swipeleft' ){
                t.next(true);
            }else if( e.type == 'swiperight' ){
                t.prev(true);
            }
        });
    },

    touchNavInit: function(){
        var t = this;
        var nav;
        if( t.settings.controlsArea == 'siblings' ){
            nav = t.container.siblings('.pixe-touch-navigation');
        }else{
            nav = t.container.children('.pixe-touch-navigation');
        }

        if( !nav.length || $.pixeEditor ) return;

        var animationUpdate = false;
        var mouseX, mouseY;
        function setPosition(){
            nav.css({ top: mouseY, left: mouseX });
            animationUpdate = false;
        }
        
        var touch = false;
        t.container.on('touchstart', function(){
            touch = true;
            setTimeout(function(){
                touch = false;
            }, 100);
        });
        t.container.on('mouseenter mouseleave mousemove', function(e){
            if( touch ) return;
            
            if( e.type == 'mouseenter' ){
                nav.addClass('pixe-active');
            }else if( e.type == 'mouseleave' ){
                nav.removeClass('pixe-active');
            }else if( e.type == 'mousemove' ){
                mouseX = e.clientX;
                mouseY = e.clientY;
                if( !animationUpdate ){
                    requestAnimationFrame(setPosition);
                    animationUpdate = true;
                }
                
            }
        });
    },

    navInit: function(){
        var t = this;
        var nav;
        if( t.settings.controlsArea == 'siblings' ){
            nav = t.container.siblings('.pixe-navigation');
        }else{
            nav = t.container.children('.pixe-navigation');
        }
        nav.addClass('pixe-init');

        nav.off().on('click', '.pixe-prev, .pixe-next', function(){
            if( $(this).hasClass('pixe-prev') ){
                t.prev(true);
            }else if( $(this).hasClass('pixe-next') ){
                t.next(true);
            }
        }); 
        
        if( !t.settings.syncNavPosition ) return;
        var position = nav.attr('data-position');
        if( position == 'top' ){
            nav.insertBefore(t.slides);
        }else if( position == 'inner' || position == 'outer' ){

            function setNavPosition(e){

                // unbind set position if removed
                if( e && nav.closest(document.body).length == 0 ){
                    $(window).off(e);
                }

                // set position
                if( position == 'outer' ){
                    nav.css({
                        'top': t.container.position().top,
                        'left': - t.container.offset().left,
                        'width': $(document.body).outerWidth(),
                        'height': t.slides.outerHeight()
                    });
                }else if( position == 'inner' ){
                    nav.css({
                        'top': t.container.position().top,
                        'left': t.container.position().left,
                        'width': t.container.outerWidth(),
                        'height': t.slides.outerHeight()
                    });
                }
            }

            setNavPosition();
            $(window).on('resize', setNavPosition);
        }
    },

    bulletInit: function(){
        var t = this;
        
        if( t.settings.controlsArea == 'siblings' ){
            t.bullet = t.container.siblings('.pixe-bullet');
        }else{
            t.bullet = t.container.children('.pixe-bullet');
        }
        t.bullet.addClass('pixe-init');

        if( t.bullet.length ){
            t.bullet.off().empty();
            for( var i = 0; i < t.steps; i++ ){
                t.bullet.append('<span ' + (i == t.currentStep? 'class="pixe-active"': '') + ' ></span>');
            }   
            t.bullets = t.bullet.children();

            // bullet event
            t.bullet.on('click', 'span', function(){
                t.animate($(this).index());

                // reset
                clearInterval(t.interval);
                t.startInterval();
            });
        }else{
            delete t.bullet;
            delete t.bullets;
        }
    },

    bulletThumbnailInit: function(){
        var t = this;
        t.bulletThumbnail = t.container.siblings('.pixe-bullet-thumbnail');
        t.bulletThumbnail.addClass('pixe-init');
        t.bulletSlides = t.bulletThumbnail.children('.pixe-slides');
        if( t.bulletThumbnail.length ){
            t.bulletThumbnails = t.bulletSlides.children();
            t.bulletThumbnails.on('click', function(){
                var index = $(this).index();
                t.animate(index);

                // reset
                clearInterval(t.interval);
                t.startInterval();
            });
            t.animateBulletThumbnail(t.currentStep);
        }else{
            delete t.bulletThumbnail;
            delete t.bulletThumbnails;
        }
    },

    animateBulletThumbnail: function(index){
        var t = this;
        if( !t.bulletThumbnails ) return;

        // active state
        var activeBullet = $(t.bulletThumbnails.get(index));
        activeBullet.addClass('pixe-active').siblings().removeClass('pixe-active');

        // check position ( start = 0, end = endPos - width )
        var containerWidth = t.bulletThumbnail.width();
        var lastItem = t.bulletThumbnails.last();
        var endPos = lastItem.position().left + lastItem.outerWidth();
        
        // move the thumbnail
        if( containerWidth < endPos ){
            t.bulletSlides.removeClass('pixe-static');
            t.bulletSlides.css('transform', '');

            var currentItem = $(t.bulletThumbnails.get(index));
            var centerPos = (containerWidth / 2) - (currentItem.position().left + (currentItem.outerWidth() / 2));
            var lastPos = containerWidth - endPos;

            if( centerPos > 0 ){
                centerPos = 0;
            }else if( centerPos < lastPos ){
                centerPos = lastPos;
            }

            t.bulletSlides.animate({targetPos: centerPos}, {
                step: function(now, fx){
                    t.bulletSlides.css({'transform': 'translateX(' + now + 'px)'});
                },
                duration: t.settings.animationTime, 
                queue: false
            });

        // center and do not move
        }else{
            t.bulletSlides.addClass('pixe-static');
        }
    }
}
<?php
    }
    Pixe_Dependency::get()->register_core_script('carousel', 'pixe_carousel_script');

    // input number
    function pixe_input_number_script(){
?>
$.fn.pixeInputNumber = function(){
    $(this).each(function(){
        if( !$(this).val() ){
            $(this).val('0');
        }

        if( !$(this).parent().hasClass('pixe-input-number') ){
            $(this).wrap('<div class="pixe-input-number" ></div>');

            var wrap = $(this).parent('.pixe-input-number');
            wrap.append('<span class="pixe-plus" ><svg viewBox="0 0 12 11" ><path d="M5.41667 10.75V6.08333H0.75V4.91667H5.41667V0.25H6.58333V4.91667H11.25V6.08333H6.58333V10.75H5.41667Z" /></svg></span>');
            wrap.append('<span class="pixe-minus" ><svg viewBox="0 0 10 3" ><path d="M0.915527 2.08561V0.918945H9.0822V2.08561H0.915527Z" /></svg></span>');

            wrap.on('mousedown touchstart', '.pixe-plus, .pixe-minus', function(e){
                var input = $(this).siblings('input[type="number"]');
                var value = parseInt(input.val()) || 0;
                var step;

                if( $(this).hasClass('pixe-plus') ){
                    step = 1;

                    var max = parseInt(input.attr("max"));
                    if( !max || value + 1 <= max ){
                        input.val(value + 1).trigger("change");
                    }
                }else{

                    var min = parseInt(input.attr("min"));
                    min = min? min: 0;
                    if( value - 1 >= min ){
                        input.val(value - 1).trigger("change");
                    }
                }

                e.preventDefault();

                return false;
            });
        }
    });
}
<?php
    }
    Pixe_Dependency::get()->register_core_script('input-number', 'pixe_input_number_script');

    // select-box
    function pixe_select_box_script(){
?>
$.fn.pixeSelectBox = function(){
    $(this).each(function(){
        var select = $(this);
        if( select.is('[multiple]') ) return;

        console.log($(this), $(this).val());
        function setPlaceholder(){
            if( !select.val() ){
                select.addClass('pixe-empty');
            }else{
                select.removeClass('pixe-empty');
            }
        }

        if( !select.parent().hasClass('pixe-select-box') ){
            select.wrap('<div class="pixe-select-box" ></div>');

            var wrap = select.parent('.pixe-select-box');
            wrap.append('<span class="pixe-icon" ><svg width="9" height="6" viewBox="0 0 9 6" ><path d="M1.42259 0.24405L4.41078 3.23222L7.39895 0.24405C7.72437 -0.08135 8.25195 -0.08135 8.57745 0.24405C8.61812 0.2848 8.6537 0.328634 8.6842 0.3748C8.89778 0.6983 8.8622 1.13788 8.57745 1.42263L5.00003 5.00005C4.8437 5.1563 4.63178 5.24405 4.41078 5.24405C4.1897 5.24405 3.97778 5.1563 3.82153 5.00005L0.244075 1.42263C-0.0813583 1.09713 -0.0813583 0.56955 0.244075 0.24405C0.284758 0.203408 0.3286 0.167817 0.374808 0.137308C0.698267 -0.0762583 1.13783 -0.0406667 1.42259 0.24405Z" /></svg></span>');
        
            setPlaceholder();
            select.on('change', function(){
                setPlaceholder();
            })
        }
    });
}
<?php
    }
    Pixe_Dependency::get()->register_core_script('select-box', 'pixe_select_box_script');

    // footer script
    function pixe_fixed_footer_script(){
?>
$(document).ready(function(){
    var footerSpace;
    var fixedFooter = $('.pixe-fixed-footer-container');
    
    function setFixedFooter(){
        fixedFooter.each(function(){
            if( $(this).css('display') == 'none' ) return;

            var container = $(this);
            var footer = $(this).children('footer');

            // add footer space
            footerSpace = container.siblings('.pixe-footer-space');
            if( !footerSpace.length ){
                footerSpace = $('<div class="pixe-footer-space" ></div>');
                footerSpace.insertBefore(container);
            }

            // additional spaces
            if( footer.hasClass('pixe-style-locked') || footer.hasClass('pixe-style-parallax-locked') ){
                footerSpace.css('height', Math.floor(footer.outerHeight()));
            }
        });
    }
    setFixedFooter();
    $(window).on('load resize', setFixedFooter);

    // scroll footer
    fixedFooter.each(function(){
        var container = $(this);
        var footer = $(this).children('footer');

        if( footer.hasClass('pixe-style-parallax-locked') ){

            // init position
            footer.css('transform', 'translateY(50%)');

            // on scroll
            $(window).on('scroll', function(){
                if( container.css('display') == 'none' ) return;

                var bottomPos = window.scrollY + window.innerHeight;
                var spacePos = footerSpace.offset().top;
                var spaceHeight = footerSpace.outerHeight();

                // 0% -> translateY 50%
                // 100 -> translateY 0
                if( bottomPos > spacePos ){
                    var percent = (bottomPos - spacePos) * 100 / spaceHeight;
                    var translate = 50 - (percent / 2);
                    if( translate < 0 ){
                        footer.css('transform', 'translateY(0%)');
                    }else{
                        footer.css('transform', 'translateY(' + translate + '%)');
                    }
                }
            });
        }
    });

});
<?php
    }
    Pixe_Dependency::get()->register_script('fixed-footer', 'pixe_fixed_footer_script');

    // header script
    function pixe_sticky_header_script(){
?>
$(document).ready(function(){
    $('.pixe-header').each(function(){
        if( !$(this).hasClass('pixe-style-floating') && !$(this).hasClass('pixe-style-sticky') ) return;

        var header = $(this);
        var floatHeader = $('<div class="pixe-float-header" ></div>');
        floatHeader.appendTo(document.body);

        // header substitute area
        var headerSub = $('<div class="pixe-header-sub" ></div>');
        if( header.css('position') == 'absolute' ){
            headerSub.css({'position': 'absolute'});
        }

        // float header
        if( $(this).hasClass('pixe-style-floating') ){
            floatHeader.addClass('pixe-style-floating');

            $(window).on('scroll', function(){
                if( header.css('display') == 'none' ) return;

                var scrollPos = floatHeader.offset().top;
                var threshold = 100;

                // normal state - display float header
                if( !floatHeader.hasClass('pixe-active') ){
                    if( header.offset().top + header.outerHeight() < scrollPos - threshold ){
                        headerSub.css('height', header.outerHeight());
                        headerSub.insertAfter(header);

                        floatHeader.append(header);
                        floatHeader.addClass('pixe-active');
                        floatHeader.css({'display': 'none'});
                        floatHeader.slideDown(150);
                    }

                // float state - return to normal header
                }else{
                    if( headerSub.offset().top + headerSub.outerHeight() > scrollPos - threshold ){
                        header.insertBefore(headerSub);

                        headerSub.css('height', 'auto');
                        headerSub.detach();

                        // animation
                        var headerClone = header.clone(false);
                        floatHeader.removeClass('pixe-active');
                        floatHeader.append(headerClone);
                        floatHeader.slideUp(150, function(){
                            headerClone.remove();
                            floatHeader.css({'display': 'block'});
                        });
                    }
                }

            });
            
        // sticky header
        }else if( $(this).hasClass('pixe-style-sticky') ){
            floatHeader.addClass('pixe-style-sticky');

            var stickyElem = header.children().not('.pixe-sticky-hidden').first();
            var stickyPos = 0;
            if( !stickyElem.length ) return;

            $(window).on('scroll', function(){
                if( header.css('display') == 'none' ) return;
                
                var scrollPos = floatHeader.offset().top;

                // normal state - display float header
                if( !floatHeader.hasClass('pixe-active') ){
                    if( stickyElem.offset().top - parseInt(stickyElem.css('margin-top')) < scrollPos ){
                        stickyPos = stickyElem.offset().top - parseInt(stickyElem.css('margin-top'));
                        headerSub.css('height', header.outerHeight());
                        headerSub.insertAfter(header);

                        floatHeader.append(header);
                        floatHeader.addClass('pixe-active');
                    }

                // float state - return to normal header
                }else{
                    if( stickyPos >= scrollPos ){
                        header.insertBefore(headerSub);

                        headerSub.css('height', 'auto');
                        headerSub.detach();

                        floatHeader.removeClass('pixe-active');
                    }
                }
            });

        }
    });
});
<?php
    }
    Pixe_Dependency::get()->register_script('sticky-header', 'pixe_sticky_header_script');

    // side header script
    function pixe_side_header_script(){
?>
$(document).ready(function(){
    $('.pixe-side-header').each(function(){
        var sideHeader = $(this);
        var templateContent = sideHeader.closest('.pixe-template-content');
        var templateContainer = sideHeader.closest('.pixe-template-container');

        var state, prevScroll;
        var htmlTopMargin, templateTopPadding, templateBottomPadding;
        var windowHeight, contentHeight, sideHeaderHeight;

        function sideHeaderReset(){
            sideHeader.css({'min-height': '0', position: '', top: '', left: '', bottom: '', width: ''});
            templateContent.css({'min-height': ''});
            $(window).off('scroll pixescroll', sideHeaderScroll);
        }
        function sideHeaderInit(){
            state = 'absolute-top';
            prevScroll = window.scrollY;
            htmlTopMargin = parseFloat($('html').css('margin-top'));
            templateTopPadding = parseFloat(templateContainer.css('padding-top'));
            templateBottomPadding = parseFloat(templateContainer.css('padding-bottom'));

            windowHeight = window.innerHeight;
            contentHeight = templateContent.outerHeight();
            sideHeaderHeight = sideHeader.outerHeight();
        }
        function setState(value){
            if( state == value ) return;

            state = value;
            switch(state){
                case 'fixed-bottom': 
                    var leftOffset = sideHeader.offset().left;
                    sideHeader.css({ position: 'fixed', top: 'auto', bottom: 0, left: leftOffset, width: sideHeader.outerWidth() });
                    break;
                case 'fixed-top':
                    var leftOffset = sideHeader.offset().left;
                    sideHeader.css({ position: 'fixed', top: htmlTopMargin, bottom: 'auto', left: leftOffset, width: sideHeader.outerWidth() });
                    break;
                case 'absolute-bottom':
                    sideHeader.css({ position: '', top: 'auto', bottom: 0, left: '', width: '' });
                    break;
                case 'absolute-top':
                    sideHeader.css({ position: '', top: '', bottom: '', left: '', width: '' });
                    break;
                case 'absolute-middle':
                    var topOffset = sideHeader.offset().top - templateTopPadding - htmlTopMargin;
                    sideHeader.css({ position: '', top: topOffset, bottom: 'auto', left: '', width: '' });
                    break;
            }
        }
        function sideHeaderScroll(){
            var scrollPos = window.scrollY;
            var contentTop = templateContent.offset().top;
            var windowBottom = scrollPos + windowHeight;
            var contentBottom = templateContent.offset().top + templateContent.outerHeight();

            // absolute top
            if( scrollPos + htmlTopMargin <= contentTop ){
                setState('absolute-top');

            // absolute bottom
            }else if( windowBottom >= contentBottom ){
                setState('absolute-bottom');

            // scroll down
            }else if( prevScroll <= scrollPos ){
                var sideHeaderBottom = sideHeader.offset().top + sideHeaderHeight;
                if( windowBottom >= sideHeaderBottom ){
                    setState('fixed-bottom');
                }else if( state == 'fixed-top' && sideHeaderBottom > windowBottom ){
                    setState('absolute-middle');
                }

            // scroll up    
            }else{
                var sideHeaderTop = sideHeader.offset().top;
                if( scrollPos + htmlTopMargin <= sideHeaderTop ){
                    setState('fixed-top');
                }else if( state == 'fixed-bottom' && sideHeaderTop < scrollPos + htmlTopMargin ){
                    setState('absolute-middle');
                }
            }

            // update scroll position
            prevScroll = scrollPos;
        }
        function sideHeaderSet(){
            var contentFrameHeight = windowHeight - htmlTopMargin - templateTopPadding - templateBottomPadding;
 
            // side header smaller than window height
            if( sideHeaderHeight <= contentFrameHeight ){
                sideHeader.css({
                    'min-height': contentFrameHeight
                });
                setState('fixed-top');
            
            // side header longer than content
            }else if( sideHeaderHeight >= contentHeight ){
                templateContent.css({
                    'min-height': sideHeaderHeight
                });

            // side header larger than window height && content longer than sideheader
            }else{
                sideHeader.css({
                    'min-height': windowHeight - htmlTopMargin
                });

                $(window).on('scroll pixescroll', sideHeaderScroll);
            }
        }

        sideHeaderInit();
        sideHeaderSet();

        $(window).trigger('pixescroll');
        $(window).on('load resize initsideheader', function(){
            sideHeaderReset();
            sideHeaderInit();
            sideHeaderSet();
            $(window).trigger('pixescroll');
        });

    });
    
});
<?php
    }
    Pixe_Dependency::get()->register_script('side-header', 'pixe_side_header_script');

    // bottom header script
    function pixe_bottom_header_script(){
?>
$(document).ready(function(){
    var header = $('header.pixe-bottom-header');
    
    function setSpace(){
        $(document.body).css({'padding-bottom': header.outerHeight()});
    }

    if( header.length ){
        setSpace();
        $(window).on('load resize', setSpace);
    }
});
<?php
    }
    Pixe_Dependency::get()->register_script('bottom-header', 'pixe_bottom_header_script');
