HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/honger7.komma.pro/wwwroot/js/site/app.js
var FadeTransition = Barba.BaseTransition.extend({
    start: function() {
        /**
         * This function is automatically called as soon the Transition starts
         * this.newContainerLoading is a Promise for the loading of the new container
         * (Barba.js also comes with an handy Promise polyfill!)
         */

        // As soon the loading is finished and the old page is faded out, let's fade the new page
        Promise
            .all([this.newContainerLoading, this.fadeOut()])
            .then(this.fadeIn.bind(this));
    },

    fadeOut: function() {
        /**
         * this.oldContainer is the HTMLElement of the old Container
         */
        return $(this.oldContainer).animate({ opacity: 0 },function(){
            // Tell Barba we can't see the old page anymore
            Barba.Dispatcher.trigger('updatePage');
        }).promise();
    },

    fadeIn: function() {
        /**
         * this.newContainer is the HTMLElement of the new Container
         * At this stage newContainer is on the DOM (inside our #barba-container and with visibility: hidden)
         * Please note, newContainer is available just after newContainerLoading is resolved!
         */

        var _this = this;
        var $el = $(this.newContainer);

        $(this.oldContainer).hide();

        $el.css({
            visibility : 'visible',
            opacity : 0
        });

        $el.animate({ opacity: 1 }, 400, function() {
            /**
             * Do not forget to call .done() as soon your transition is finished!
             * .done() will automatically remove from the DOM the old Container
             */
            _this.done();
        });
    }
});
/* ==========================================================================
 The drip transition between every page

 Some links that may come in handy:
 BarbaJs Transition: http://barbajs.org/transition.html
 GSAP LagSmoothing: https://greensock.com/gsap-1-12-0sa

 ========================================================================== */


var DT = Barba.BaseTransition.extend({

    transition : null,

    start: function() {

        DT.transition = this;

        // //When newContainerLoading is done, call the drip method
        Promise
            .all([this.newContainerLoading])
            .then(this.initDripGrid.bind(this));
    },

    initDripGrid: function()
    {
        // Initialise the grid
        DT.DripGrid.init();
    },

    /* Grid section
     ========================================================================== */

    /**
     * We call all the drips next to each other the DripGrid
     */
    DripGrid : {

        // Number of drips we need to draw
        numDrips : null,
        // Number of drips we have drawn so far
        count : 0,
        // Width of one column
        singleColumnWidth : null,
        // Drips done animating
        dripsDropped : 0,
        // Container
        container : $('#drip-transition-container'),

        /**
         * Setup properties
         */
        init : function ()
        {
            // Assume we always have a grid-row on a page
            DT.DripGrid.singleColumnWidth = DT.Drip.tailHeight = DT.DripGrid.calculateSingleColumnWidth();
            // Define number of drips we need
            DT.DripGrid.numDrips = Math.ceil($(window).width() / DT.DripGrid.singleColumnWidth);
            // Draw the Drips
            DT.DripGrid.draw();
            // Animate
            setTimeout(function() { DT.dropDrips('in') } ,200);
        },

        /**
         * Calculate the right
         * @returns {number}
         */
        calculateSingleColumnWidth : function()
        {
            var minDripWidth = 60;
            var columns = 12;
            var gridWidth = $('#drip-transition-grid-width').outerWidth();

            // Default drip width
            var width = gridWidth / columns;
            // Make sure width is larger then minGridWidth
            while(width < minDripWidth)
            {
                // Divide trough less columns
                columns--;
                width = gridWidth / columns;
            }

            return width;
        },

        /**
         * Draw the grid
         */
        draw: function ()
        {
            // Draw the drips on the grid
            for(var i = 0; i < DT.DripGrid.numDrips; i++)
            {
                DT.Drip.draw();
                DT.DripGrid.count++;
            }
        }
    },

    /* Single drip section
     ========================================================================== */

    /**
     * Drip stands for one single drip column
     */
    Drip : {

        // The tail is a square so the height of the tail should be the width of one column
        tailHeight : 0,

        /**
         * Draw the random drip on the dripContainer
         */
        draw : function()
        {
            // Create Drip jquery object
            var $drip = $('<div>',{
                class: 'drip',
                id: 'transition-drip-' + DT.DripGrid.count
            });

            // Append inner HTML to drip
            if( ! DT.Drip.isReversed())
            {
                $drip.append(DT.Drip.normalDripHTML());
            }
            else{
                $drip.append(DT.Drip.reversedDripHTML());
            }

            // Give some random sizes to our drip
            $drip = DT.Drip.setSize($drip);

            // Append HTML to container
            DT.DripGrid.container.append($drip);
        },

        /**
         * Return a normal drip with the border-radius at the bottom
         *
         * @returns {string}
         */
        normalDripHTML : function()
        {
            return '<div class="drip-tail"></div>' +
                   '<div class="drip-body"></div>';
        },

        /**
         * Return a reversed drip with the inverted circle at the bottom
         * In the reversed drip the body comes first, then the tail
         *
         * @returns {string}
         */
        reversedDripHTML : function()
        {
            return '<div class="drip-body"></div>' +
                   '<div class="drip-tail"></div>';
        },

        /**
         * Set the size of each drip
         *
         * @param $drip
         * @returns {*}
         */
        setSize : function($drip)
        {
            $drip.css({ width: DT.DripGrid.singleColumnWidth + 'px' });

            // Set the height of the drip-body
            var bodyHeight = parseInt($(window).height()) + DT.Drip.tailHeight * 1.5;
            $drip.children('.drip-body').css({ height: bodyHeight + 'px' });

            // Position the drip right out of the viewport at the top
            var dripPosition = (bodyHeight + DT.Drip.tailHeight) * -1;
            // Set reversed items half a tailHeight higher
            if(DT.Drip.isReversed()) dripPosition -= DT.Drip.tailHeight / 2;
            // Set position
            $drip.css({ transform : 'translateY(' + dripPosition + 'px)' });
            return $drip;
        },

        /**
         * Return whether a drip is reversed
         *
         * @returns {boolean}
         */
        isReversed : function()
        {
            return DT.DripGrid.count % 2 != 0;
        },

        /**
         * Animate drip to a color
         */
        animateToColor : function($drip, color)
        {
            // Add force3D:true to tell the browser to render our element using the GPU (graphics card) instead of using the CPU.
            var options = {
                backgroundColor: color,
                ease: Power0.easeOut
            };

            // Tween
            TweenLite.to($drip.find('div.drip-body'), .7, options);
            TweenLite.to($drip.find('div.drip-tail'), .7, options);
        }
    },

    /* Animation section
     ========================================================================== */

    /**
     * Drop all the drips with some random delay
     */
    dropDrips: function(phase)
    {
        var i;
        var $drip;
        var delay;
        // First we drop all the even drips
        for(i=0;i<DT.DripGrid.numDrips;i+=2)
        {
            $drip = $('#transition-drip-' + i);
            delay = Math.random() * .5;
            if(phase == 'in') DT.dropDripIn($drip,delay,0);
            if(phase == 'out') DT.dropDripOut($drip,delay,0);

            // Add delay to the data attribute
            $drip.attr('data-delay-' + phase, delay);
        }

        // Then the "in between" odd (reversed) drips
        for(i=1;i<DT.DripGrid.numDrips;i+=2)
        {
            // Define drip objects
            $drip = $('#transition-drip-' + i);
            var $rightDrip = $('#transition-drip-'+(i+1));
            var $leftDrip = $('#transition-drip-'+(i-1));

            // The delay should'nt be smaller then the drip on the left or right
            // Get delay of drip on the left
            var leftDripDelay = $leftDrip.data('delay-' + phase);
            // Get right delay or set to zero if there is no right drip
            var rightDripDelay = 0;
            if($rightDrip.length) rightDripDelay = $rightDrip.data('delay-' + phase);
            // Check whether the left or the right drip has the largest delay
            var largestDelay = leftDripDelay;
            if(rightDripDelay > leftDripDelay) largestDelay = rightDripDelay;
            // Add some randomness
            delay = largestDelay + Math.random() * .15;

            // Let's drip!
            if(phase == 'in') DT.dropDripIn($drip,delay,1);
            if(phase == 'out') DT.dropDripOut($drip,delay,1);
        }
    },

    /**
     * Drop a drip into the screen
     */
    dropDripIn : function($drip,delay,reversed)
    {
        // Disable lag smoothing
        TweenLite.lagSmoothing(0);

        // Animate the colors
        DT.Drip.animateToColor($drip,'#0000ff');

        // Define targetY
        var targetY = DT.Drip.tailHeight * -1;
        if(reversed) targetY = DT.Drip.tailHeight * -1.5;

        // Animate the size
        TweenLite.to($drip, .3, {
            y: targetY+'px',
            ease: Sine.easeIn,
            delay: delay,
            force3D: true,
            onComplete: function () {
                // todo: figure out if this can be done with a Promise
                DT.whenAllDripsDropped(function()
                {
                    // Tell Barba we can't see the old page anymore
                    Barba.Dispatcher.trigger('updatePage');

                    // Ready to load new container
                    $(window).scrollTop(0);

                    DT.transition.done();

                    // Drop all drips to the bottom
                    DT.dropDrips('out');
                });
            }
        });
    },

    /**
     * Drop a drip out of screen
     */
    dropDripOut : function($drip,delay,reversed)
    {
        // Disable lag smoothing
        TweenLite.lagSmoothing(0);

        // Animate the colors
        DT.Drip.animateToColor($drip,'#00c7ff');

        // Define targetY
        var windowHeight = $(window).height();
        targetY = windowHeight + DT.Drip.tailHeight / 2;
        if(reversed) targetY = windowHeight;

        // Animate the size
        TweenLite.to($drip, .4, {
            y: targetY+'px',
            ease: Sine.easeIn,
            delay: delay,
            force3D: true,
            onComplete: function () {
                DT.whenAllDripsDropped(function()
                {
                    // Reset some data
                    DT.DripGrid.count = 0;
                    DT.DripGrid.container.html('');
                });
            }
        });
    },

    /**
     * Check if all drips are dropped
     */
    whenAllDripsDropped : function(callback)
    {
        // Increase drips dropped by one
        DT.DripGrid.dripsDropped++;
        // Check if all drips are dropped
        if(DT.DripGrid.dripsDropped == DT.DripGrid.numDrips)
        {
            // Reset drips dropped
            DT.DripGrid.dripsDropped = 0;
            // Run callback
            callback();
        }
    }
});
/* ==========================================================================
 Initialize BarbaJS when DomContentLoaded
 ========================================================================== */

document.addEventListener("DOMContentLoaded", function() {
    var lastElementClicked;

    // Refine wrapper
    Barba.Pjax.Dom.wrapperId = 'hungry-wrapper';
    Barba.Pjax.Dom.containerClass = 'hungry-container';

    // Initialize Pjax
    Barba.Pjax.init();

    // Update lastElementClicked on click
    Barba.Dispatcher.on('linkClicked', function(el) {
        lastElementClicked = el;
    });

    // Since there is no transition on page reload, trigger the updatePage
    Barba.Dispatcher.trigger('updatePage');


    /* Setup transition
     ========================================================================== */

    Barba.Pjax.getTransition = function()
    {
        // Switch name
        switch(lastElementClicked.dataset.name)
        {
            // Optional: custom animations for specific pages
            // case 'case':
            //     // Custom animation
            //     return FadeTransition;
            //     break;
            default:
                return DT;
        }
    };
});


/* Setup Event listeners
 ========================================================================== */

// When a new page is ready
Barba.Dispatcher.on('newPageReady', function(currentStatus, oldStatus, container) {

    // Fade in all images when loaded
    ImagePreloader.init();

    // Reset navigation open
    $('body').removeClass("navigation-is-open");
});

// When the old page is no longer visible
// You can only update elements outside the hungry container here
Barba.Dispatcher.on('updatePage',function(){

    // Define previous and current status
    var currentStatus = Barba.HistoryManager.currentStatus();
    var prevStatus = Barba.HistoryManager.prevStatus();

    // Make sure the body always has a class with the name of the page
    var $body = $('body');
    // Remove previous state from body class
    if( isset(prevStatus)) $body.removeClass(prevStatus.namespace);
    // Add current state to body class
    $body.addClass(currentStatus.namespace);

    // Update Google Analytics
    // Edit: this is done in tag manager
    // if (typeof ga === 'function') ga('send', 'pageview', location.pathname);
    // Update Komma Leads
    // if( window._gaq ) _gaq.push(['_trackPageview', window.location.href]);
});

// After a page transition is completed:
// All actions that have affect on elements inside the hungry-container should go here.
Barba.Dispatcher.on('transitionCompleted', function(currentStatus,prevStatus) {

    // Initialize handler for every page
    AnimationHandler.init();
    BrowserHandler.init();
    Navigation.init();
    ScrollHandler.init();
    ViewportHandler.init();
    FeaturedCaseHandler.init();

    // Paint the navigation drip
    if(currentStatus.namespace == 'cases') NavigationDripPainter.init();
    if(currentStatus.namespace.substr(0,5) == 'case ')
    {
        ScrollableWebsite.init();
        CaseProgress.init();
    }
    if(currentStatus.namespace == 'process') ProcessHandler.init();
    if(currentStatus.namespace == 'testimonials') TestimonialHandler.init();
    if(currentStatus.namespace == 'home') YoutubeHandler.init();
    if(currentStatus.namespace == 'contact') MapsHandler.init();
});
/*
 * Simple isset method for this does not exist in javascript
 */
var isset = function(obj)
{
    return typeof obj !== 'undefined' && obj !== null;
};

/**
 * With this method you can call a function with it's string name
 * This will also work with namespaced functions
 * executeFunctionByName("My.Namespace.functionName", window, arguments);
 *
 * @param functionName
 * @param context
 * @returns {*}
 */
function executeFunctionByName(functionName, context /*, args */) {
    var args = [].slice.call(arguments).splice(2);
    // Split function name on .
    var namespaces = functionName.split(".");
    // Return last element of array and remove it
    var func = namespaces.pop();
    // Loop through every namespace
    for(var i = 0; i < namespaces.length; i++) {
        // Overwrite context with the namespace
        // We go one level deeper every time
        context = context[namespaces[i]];
    }
    // Finally call the function in the current context
    return context[func].apply(context, args);
}
/* ==========================================================================
 Image related javascript
 ========================================================================== */

/**
 * Preload images
 */
var ImagePreloader = {

    // Init preloader
    init : function()
    {
        $('img.preload').one('load',function()
        {
            // Once loaded remove the preload class
            // Our CSS will take care of the fade in
            $(this).removeClass('preload');
        })
        .each(function()
        {
            if(this.complete) $(this).load();
        });
    }
};
/**
 * Google Maps API
 * https://developers.google.com/maps/documentation/javascript/adding-a-google-map
 */
var MapsHandler = {

    /**
     * 
     */
    init : function()
    {
        // See if maps variable exists
        if (typeof(google) == 'undefined' || typeof(google.maps) == 'undefined') {
            // Load external script
            $.getScript('https://maps.googleapis.com/maps/api/js?key=AIzaSyCVGPUmRmQRxXvzzWu3Xyu77XebQxQ-f4Y')
                .done(function( script, textStatus ) {
                    MapsHandler.drawMap();
            });
        } else {
            MapsHandler.drawMap()
        }
    },

    drawMap : function()
    {
        // Define location
        var location = {lat: 51.261828, lng: 5.598753};

        // Create a map
        var map = new google.maps.Map(document.getElementById('map'), {
            zoom: 11,
            center: location,
            disableDefaultUI: true
        });
        // Add a marker
        var marker = new google.maps.Marker({
            position: location,
            map: map
        });
    }
};
/* ==========================================================================
 Navigation handler
 ========================================================================== */

/**
 * Main navigation
 */
var Navigation = {

    // Initialize click event
    init : function()
    {
        var nav = this;

        // Bind clicks to burger button and overlay
        $('.burger-button, .navigation-overlay-container').bind('click',function()
        {
            nav.toggle();
        });

        $('#close-navigation').bind('click',nav.close)
    },

    // Toggle navigation
    toggle : function()
    {
        var nav = this;

        if( ! $('body.navigation-is-open').length) {
            nav.open();
        }
        else
        {
            nav.close();
        }
    },

    // Open navigation
    open : function()
    {
        $('body').addClass('navigation-is-open');
        // Slide in navigation
        TweenLite.to($('nav.main'), .8, { x:0,y:0,z:0, ease:Power4.easeOut });
        // Drop overlay
        TweenLite.to($('.navigation-overlay-container .drip'), .5, {top:'0', ease:Power4.easeOut});
    },

    // Close navigation
    close : function()
    {
        $('body').removeClass('navigation-is-open');
        // GSAP uses a matrix so we can't use percentage, calculate absolute width
        var newX = parseInt($('nav.main').outerWidth());
        // Slide out navigation
        TweenLite.to($('nav.main'), 1, { x: newX ,y:0,z:0, ease:Power3.easeOut });
        // Drop overlay
        TweenLite.to($('.navigation-overlay-container .drip'), .5, {top:'-100vh', ease:Power4.easeOut});
    }
};

var YoutubeHandler = {

    elementId : '',
    youtubeId : '',

    /**
     * 
     */
    init : function()
    {
        YoutubeHandler.elementId = 'ytplayer';
        YoutubeHandler.youtubeId = 'Qm0FitSetD0';

        YoutubeHandler.playVideo()
    },
    
    /**
     * Check if external script is loaded
     * 
     */
    playVideo: function() {
        // See if YT variable exists
        if (typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') {
            // Setup API ready function
            window.onYouTubePlayerAPIReady = function() {
                YoutubeHandler.loadPlayer();
            };
            // Load external script
            $.getScript('https://www.youtube.com/iframe_api');
        // If YT already exists load player
        } else {
            YoutubeHandler.loadPlayer();
        }
    },

    /**
     * Load Youtube player with parameters
     *
     */
    loadPlayer: function() {
        // Load player
        window.player = new YT.Player(YoutubeHandler.elementId,{
            height: 200,
            width: 200,
            videoId: YoutubeHandler.youtubeId,
            host: 'https://www.youtube-nocookie.com',
            playerVars: {
                modestbranding: 0,
                showinfo: 0,
                rel: 0,
                controls: 0,
                disablekb: 1
            },
            events: {
                'onReady': YoutubeHandler.onReady,
                'onStateChange': YoutubeHandler.onStateChange
            }
        });
    },

    /**
     * When player is ready to play
     */
    onReady : function() {

        // Show video
        setTimeout(function(){ $('#' + YoutubeHandler.elementId).stop().animate({ opacity: 1 },1000) },800);

        // If not on tablet or mobile, play on high quality
        window.player.mute();
        window.player.playVideo();
        window.player.setPlaybackQuality('hd1080');
    },

    /**
     * Listener for Youtube state change
     *
     * @param state
     */
    onStateChange : function(state) {
        // Loop video
        if (state.data === YT.PlayerState.ENDED ) {
            window.player.playVideo();
        }
    }
};

var BrowserHandler = {

    userAgent : '',

    init : function()
    {
        BrowserHandler.userAgent = window.navigator.userAgent;
        BrowserHandler.handleIE();
    },

    handleIE : function()
    {
        // Detect versions below ie11
        var msie = BrowserHandler.userAgent.indexOf("MSIE ");
        var ielt11 = msie > 0;

        // Detect ie11
        var ie11 = !!navigator.userAgent.match(/Trident.*rv\:11\./);

        // If Internet Explorer
        if (ielt11 || ie11)
        {
            // Default version
            var version = '11';

            // Way to detect version < 11
            if(ielt11) version = parseInt(BrowserHandler.userAgent.substring(
                msie+5,
                BrowserHandler.userAgent.indexOf(".", msie )
                ));

            // Append classes to HTML
            $('html').addClass('ie v' + version);
        }
    }
};
var AnimationHandler = {

    init : function()
    {
        AnimationHandler.headerSideDrips();
    },

    /**
     * Left and right drips in the header
     */
    headerSideDrips : function()
    {
        if( ! $('#left-side-drip').length) return false;

        // Left and right both go to a random number between 150% and 200%
        var leftEnd = Math.random() * 40 + 120;
        var rightEnd = Math.random() * 20 + 110; // A little lower

        // Left and right both have a random speed
        var leftSpeed = Math.random() * 10 + 5;
        var rightSpeed = Math.random() * 10 + 5;

        // Animate left
        TweenLite.to($('#left-side-drip'), leftSpeed, {
            height: leftEnd+'%',
            ease: Power4.easeOut,
            delay: 1
            }
        );
        // Animate right
        TweenLite.to($('#right-side-drip'), rightSpeed, {
            height: rightEnd+'%',
            ease: Power4.easeOut,
            delay: 2
            }
        );
    }


};
/* ==========================================================================
    All scroll related javascript
 ========================================================================== */

var ScrollHandler = {

    init : function(){

        $('.scroll-to-target').bind('click',function()
        {
            ScrollHandler.scrollToTarget($(this))
        });
    },

    /**
     * Handles click on the mouse with the arrow
     *
     * @param $el
     */
    scrollToTarget : function($el){
        // Set the target
        var target = $el.data('target');
        // Scroll to the target
        TweenLite.to(window, .8, {scrollTo:"#"+target});
    }

};
/* ==========================================================================
   Scrollable website component on case-detail
   ========================================================================== */

var ScrollableWebsite = {

    init : function(){

        // Define scroller
        var $scroller = $('.sw-scroller');
        // Maximum scrollable distance
        var max = $scroller.height() - $scroller.parent().height();
        // Scroll ease (https://greensock.com/customease)
        CustomEase.create("ScrollEase", "M0,0,C0.11,0.494,0.144,0.661,0.222,0.822,0.296,0.974,0.504,1,1,1");

        // Scrolling animation Todo: customizable scroll-points
        var tl = new TimelineLite();
        tl.from($scroller, 2, { y:0 },"+=.5");
        tl.to($scroller, 2, {ease: "ScrollEase", y:'-' + (max*.4)});
        tl.to($scroller, 2, {ease: "ScrollEase", y:'-' + (max*.5)});
        tl.to($scroller, 2, {ease: "ScrollEase", y:'-' + (max*.85)});
        tl.to($scroller, 2, {ease: "ScrollEase", y:'-' + max},"+=0.3");
        tl.to($scroller, 3, {ease: "ScrollEase", y:0, onComplete: function()
        {
            // Restart after last tween
            tl.restart()
        }});
    },
};
/* ==========================================================================
 Handles elements that need animation when entering the viewport
 ========================================================================== */

var ViewportHandler = {

    init : function()
    {
        // Fire once on init
        this.handle();
        // Handle on scroll
        $(window).on('scroll', this.handle);
    },

    handle : function()
    {
        // For every element with data-in-viewport with haven't got a class show
        $('*[data-in-viewport]:not(.show)').each(function()
        {
            if(ViewportHandler.isInViewport($(this),1))
            {
                // Execute the function written in 'data-in-viewport'
                executeFunctionByName($(this).data('in-viewport'), window, $(this));
            }
        })
    },

    /**
     * Return if the element is in the viewport
     *
     * @param el
     * @param partial
     * @returns {boolean}
     */
    isInViewport : function(el, partial) {

        // For jQuery we need to get the first key
        el = el[0];

        // Get bounding rectangle
        var rect = el.getBoundingClientRect();
        var parentRect = {top: 0, left: 0, bottom: $(window).height(), right: $(window).width()};

        // Partially in viewport
        if (partial) {
            return (
                rect.left >= parentRect.left &&
                rect.right <= parentRect.right &&
                (
                    (rect.top >= parentRect.top && rect.top <= parentRect.bottom) ||
                    (rect.bottom >= parentRect.top && rect.bottom <= parentRect.bottom)
                )
            );
        }
        // Fully in viewport
        else {
            return (
                rect.top >= parentRect.top &&
                rect.left >= parentRect.left &&
                rect.bottom <= parentRect.bottom &&
                rect.right <= parentRect.right
            );
        }
    }
};
/* ==========================================================================
 Contains all viewport animations
 ========================================================================== */


var ViewportAnimations = {

    /* Team members on about page
     ========================================================================== */

    Team : {

        delay : 0,

        /**
         * Fade in members from the bottom
         *
         * @param $el
         */
        show : function($el)
        {
            // Animate translateY to 0 with some delay
            TweenLite.to($el.children('.portrait').children('img'), 2,{
                y : 0,
                ease: Power2.easeOut,
                opacity: 1 }
            ).delay(this.delay);
            // Add some delay
            this.delay += .2;
            // Add a show class so data-in-viewport will ignore this once visible
            $el.addClass('show');
        }
    },

    Process : {
        /**
         * Animate text
         */
        show : function($el)
        {
            if( ! $el.hasClass('shown'))
            {
                $el.addClass('shown');
                var delay = .5;
                $el.children().each(function(){
                    // Animate translateY to 0 with some delay
                    TweenLite.to($(this), .8,{
                        y : 0,
                        ease: Power4.easeOut,
                        opacity: 1 }
                    ).delay(delay);
                    // Add some delay
                    delay += .2
                });
            }
        }
    }
};
/* ==========================================================================
 Case specific javascript
 ========================================================================== */

/* Background gradient on navigation drip
 ========================================================================== */

var NavigationDripPainter = {

    drip : '',

    init : function()
    {
        // Set drip for when returning on this page trough Pjax
        this.drip = $('#navigation-drip');
        // Color when entering the page
        NavigationDripPainter.paint();
        // Handle scroll
        $(window).on('scroll', NavigationDripPainter.paint);
    },

    /*
     * Check for every case if the drip touches the case
     */
    paint : function()
    {
        var colors = [];
        var gradientLine = 100;

        $('.case-layout').each(function(){

            // Define drip bottom
            var dripBottom = NavigationDripPainter.drip.height();

            // Get rectangle
            var rect = $(this)[0].getBoundingClientRect();

            // Check if element is behind the navigation drip
            if(rect.bottom > 0 && rect.top < dripBottom)
            {
                // Is the bottom of the element behind the drip?
                // Calculate bottom position in percentage
                var bottomPosition = rect.bottom * 100 / dripBottom;
                // We need a gradient if the percentage is lower then 100 percent
                if(bottomPosition < 100) gradientLine = bottomPosition;
                // Add color to array
                colors.push($(this).data('navigation-color'));
            }
        });

        // Check if we need gradient
        if(colors.length > 1)
        {
            NavigationDripPainter.gradient(gradientLine, colors);
        }
        else
        {
            NavigationDripPainter.drip.css({ background: colors[0] });
        }
    },

    /**
     * Draw calculated gradient
     */
    gradient : function(gradientLine, colors){
        var margin = 30;
        var line1, line2;

        // On enter next case
        if(gradientLine > (100 - margin)) {
            line1 = gradientLine - (100 - gradientLine);
            line2 = 100;
        }
        // On leaving case
        else if(gradientLine < margin){
            line1 = 0;
            line2 = gradientLine * 2;
        }
        // Default
        else{
            line1 = gradientLine - margin;
            line2 = gradientLine + margin;
        }
        // Update gradient
        this.drip.css({ background: 'linear-gradient(to bottom, ' + colors[0] + ',' + colors[0] + ' ' + line1 + '%,' + colors[1] + ' ' + line2 + '%,' + colors[1] + ')' });

    }
};

var CaseProgress = {

    currentPosition : 'top',

    init : function()
    {
        CaseProgress.setPosition();
        $(window).scroll(function(){
            CaseProgress.setPosition();
            CaseProgress.scaleProgress();
        });
    },

    /**
     * Update the transform Y on scroll
     */
    setPosition : function()
    {
        // Find bounding rectangle of aside progress container
        var $progressContainer = $('#progress-container');
        if( ! $progressContainer.length) return false;
        var rect = $($progressContainer)[0].getBoundingClientRect();

        // When top of the element reaches the viewport top,
        // Till the bottom of the element reaches the viewport bottom
        var fixedCondition = (rect.top < 0 && rect.top > ($progressContainer.height()-$(window).height()) * -1);
        var sunkCondition = (rect.bottom < $(window).height());
        if(fixedCondition && CaseProgress.currentPosition != 'fixed')
        {
            CaseProgress.currentPosition = 'fixed';
            $progressContainer.find('#fixable').attr('class','fixable fixed');
        }
        else if(sunkCondition && CaseProgress.currentPosition != 'sunk'){
            CaseProgress.currentPosition = 'sunk';
            $progressContainer.find('#fixable').attr('class','fixable sunk');
        }
        else if( ! fixedCondition && ! sunkCondition && CaseProgress.currentPosition != 'top'){
            CaseProgress.currentPosition = 'top';
            $progressContainer.find('#fixable').attr('class','fixable');
        }
    },

    /**
     * Scale the progress bar
     */
    scaleProgress : function ()
    {
        $('#dynamic-content').children('section').each(function()
        {
            var $section = $(this);
            // Get bounding rectangle
            var rect = $section[0].getBoundingClientRect();
            // Do the math
            var scale = ((rect.top - $(window).height()/2 ) *-1) / $section.height();
            // Scale bar
            $('#progress-bar-' + $section.attr('id') ).css({ transform: 'scaleX(' + scale + ')'});
        });
    }
};

var FeaturedCaseHandler = {

    aniOverlay : [],
    aniTitle : [],
    aniTags : [],
    aniArrow : [],

    init : function(){

        // Set hover on featured case
        $('.featured-case').hover(function()
        {
            FeaturedCaseHandler.mouseIn($(this));
        }, function(){
            FeaturedCaseHandler.mouseOut($(this));
        })

    },

    /**
     * On mouse in: show blue square with white text
     */
    mouseIn : function($el) {

        // Color overlay variables
        var posX = 50;
        var posY = 50;
        var w = $el.width() - posX;
        var h = $el.height() - posY;

        // Animate the overlay from edges a little to the inside
        FeaturedCaseHandler.aniOverlay[$el] = TweenLite.to($('.color-overlay',$el), .6, {
            opacity: .95,
            width: w,
            height: h,
            x: posX / 2,
            y: posY / 2,
            ease: Power4.easeOut
        });

        // Pop up title
        FeaturedCaseHandler.aniTitle[$el] = TweenLite.to($('.title',$el), .3, {
            y: 0,
            opacity: 1
        });

        // Fade in tags
        FeaturedCaseHandler.aniTags[$el] = TweenLite.to($('.tags',$el), .3, {
            opacity: 1,
            delay: .2
        });

        // Slide in arrow
        FeaturedCaseHandler.aniArrow[$el] = TweenLite.to($('.arrow',$el), .3, {
            x: 0,
            opacity: 1,
            delay: .3
        });
    },

    /**
     * On mouse out: hide square and text
     */
    mouseOut : function($el)
    {
        FeaturedCaseHandler.aniOverlay[$el].kill();
        FeaturedCaseHandler.aniTitle[$el].kill();
        FeaturedCaseHandler.aniTags[$el].kill();
        FeaturedCaseHandler.aniArrow[$el].kill();

        // Color overlay variables
        var w = $el.width();
        var h = $el.height();

        // Animate the overlay back to edges
        TweenLite.to($('.color-overlay',$el), .6, {
            opacity: 0,
            width: w,
            height: h,
            x: 0,
            y: 0,
            ease: Power4.easeOut
        });

        // Drop down title
        TweenLite.to($('.title',$el), .3, {
            y: 20,
            opacity: 0
        });

        TweenLite.to($('.tags',$el), .1, {
            opacity: 0
        });

        if($el.hasClass('prev'))
        {
            // Slide out arrow
            TweenLite.to($('.arrow',$el), .3, {
                x: 10,
                opacity: 0
            });
        }
        else
        {
            // Slide out arrow
            TweenLite.to($('.arrow',$el), .3, {
                x: -10,
                opacity: 0
            });
        }
    }

};
/* ==========================================================================
 Process specific javascript
 ========================================================================== */

var ProcessHandler = {

    init : function()
    {
        $('.next-step').bind('click',this.nextStep)
    },

    /**
     * Handle next step click event
     *
     * @param evt
     */
    nextStep : function(evt)
    {
        // Get clicked item as jquery object
        var $button = $(evt.target);

        // Get target
        var $target = $('#step-' + $button.attr('data-target'));

        // Get target offset top
        var offsetTop = $target.offset().top;

        // Animate scroll top
        TweenLite.to(window, 2, {
            ease: Power4.easeOut,
            scrollTo: offsetTop
        });
    }
};
/* ==========================================================================
 Testimonial specific javascript
 ========================================================================== */

var TestimonialHandler = {

    init : function()
    {
        $('#plus').bind('click',this.toggleOpen)
    },

    /**
     * Toggle client mask
     *
     * @param evt
     */
    toggleOpen : function(evt)
    {
        $('.client-mask').toggleClass('open');
    }
};