/*!
 * Cube Portfolio - Responsive jQuery Grid Plugin
 *
 * version: 3.2.1 (14 October, 2015)
 * require: jQuery v1.7+
 *
 * Copyright 2013-2015, Mihai Buricea (http://scriptpie.com/cubeportfolio/live-preview/)
 * Licensed under CodeCanyon License (http://codecanyon.net/licenses)
 *
 */
(function($, window, document, undefined) {
    'use strict';
    function CubePortfolio(obj, options, callback) {
        /*jshint validthis: true */
        var t = this,
            initialCls = 'cbp',
            children;
        if ($.data(obj, 'cubeportfolio')) {
            throw new Error('cubeportfolio is already initialized. Destroy it before initialize again!');
        }
        // attached this instance to obj
        $.data(obj, 'cubeportfolio', t);
        // extend options
        t.options = $.extend({}, $.fn.cubeportfolio.options, options);
        // store the state of the animation used for filters
        t.isAnimating = true;
        // default filter for plugin
        t.defaultFilter = t.options.defaultFilter;
        // registered events (observator & publisher pattern)
        t.registeredEvents = [];
        // queue for this plugin
        t.queue = [];
        // has wrapper
        t.addedWrapp = false;
        // register callback function
        if ($.isFunction(callback)) {
            t.registerEvent('initFinish', callback, true);
        }
        // js element
        t.obj = obj;
        // jquery element
        t.$obj = $(obj);
        // when there are no .cbp-item
        children = t.$obj.children();
        // if caption is active
        if (t.options.caption) {
            if (t.options.caption !== 'expand' && !CubePortfolio.Private.modernBrowser) {
                t.options.caption = 'minimal';
            }
            // .cbp-caption-active is used only for css
            // so it will not generate a big css from sass if a caption is set
            initialCls += ' cbp-caption-active cbp-caption-' + t.options.caption;
        }
        t.$obj.addClass(initialCls);
        if (children.length === 0 || children.first().hasClass('cbp-item')) {
            t.wrapInner(t.obj, 'cbp-wrapper');
            t.addedWrapp = true;
        }
        // jquery wrapper element
        t.$ul = t.$obj.children().addClass('cbp-wrapper');
        // wrap the $ul in a outside wrapper
        t.wrapInner(t.obj, 'cbp-wrapper-outer');
        t.wrapper = t.$obj.children('.cbp-wrapper-outer');
        t.blocks = t.$ul.children('.cbp-item');
        t.blocksOn = t.blocks;
        // wrap .cbp-item-wrap div inside .cbp-item
        t.wrapInner(t.blocks, 'cbp-item-wrapper');
        // plugins
        t.plugins = $.map(CubePortfolio.Plugins, function(pluginName) {
            return pluginName(t);
        });
        // wait to load all images and then go further
        t.loadImages(t.$obj, t.display);
    }
    $.extend(CubePortfolio.prototype, {
        storeData: function(blocks, indexStart) {
            var t = this;
            indexStart = indexStart || 0; // used by loadMore
            blocks.each(function(index, el) {
                var item = $(el),
                    width = item.width(),
                    height = item.height();
                item.data('cbp', {
                    index: indexStart + index, // used when I sort the items and I need them to revert that sorting
                    wrapper: item.children('.cbp-item-wrapper'),
                    widthInitial: width,
                    heightInitial: height,
                    width: width, // used by drag & drop wp @todo - maybe I will use widthAndGap
                    height: height,
                    widthAndGap: width + t.options.gapVertical,
                    heightAndGap: height + t.options.gapHorizontal,
                    left: null,
                    leftNew: null,
                    top: null,
                    topNew: null,
                    pack: false,
                });
            });
        },
        // http://bit.ly/pure-js-wrap
        wrapInner: function(items, classAttr) {
            var t = this,
                item, i, div;
            classAttr = classAttr || '';
            if (items.length && items.length < 1) {
                return; // there are no .cbp-item
            } else if (items.length === undefined) {
                items = [items];
            }
            for (i = items.length - 1; i >= 0; i--) {
                item = items[i];
                div = document.createElement('div');
                div.setAttribute('class', classAttr);
                while (item.childNodes.length) {
                    div.appendChild(item.childNodes[0]);
                }
                item.appendChild(div);
            }
        },
        /**
         * Wait to load all images
         */
        loadImages: function(elems, callback) {
            var t = this;
            // wait a frame (Safari bug)
            requestAnimationFrame(function() {
                var src = elems.find('img').map(function(index, el) {
                    return t.checkSrc(el.src);
                });
                var srcLength = src.length;
                if (srcLength === 0) {
                    callback.call(t);
                    return;
                }
                $.each(src, function(i, el) {
                    $('![]() ').on('load.cbp error.cbp', function() {
                        srcLength--;
                        if (srcLength === 0) {
                            callback.call(t);
                        }
                    }).attr('src', el); // for ie8
                });
            });
        },
        checkSrc: function(src) {
            if (src === '') {
                return null;
            }
            var img = new Image();
            img.src = src;
            if (img.complete && img.naturalWidth !== undefined && img.naturalWidth !== 0) {
                return null;
            }
            return src;
        },
        /**
         * Show the plugin
         */
        display: function() {
            var t = this;
            // store main container width
            t.width = t.$obj.outerWidth();
            // store to data some values of t.blocks
            t.storeData(t.blocks);
            t.triggerEvent('initStartRead');
            t.triggerEvent('initStartWrite');
            // create mark-up for slider layout
            if (t.options.layoutMode === 'slider') {
                t.registerEvent('gridAdjust', function() {
                    t.sliderMarkup();
                }, true);
            }
            // make layout
            t.layoutAndAdjustment();
            t.triggerEvent('initEndRead');
            t.triggerEvent('initEndWrite');
            // plugin is ready to show and interact
            t.$obj.addClass('cbp-ready');
            t.runQueue('delayFrame', t.delayFrame);
        },
        delayFrame: function() {
            var t = this;
            requestAnimationFrame(function() {
                t.resizeEvent();
                t.triggerEvent('initFinish');
                // animating is now false
                t.isAnimating = false;
                // trigger public event initComplete
                t.$obj.trigger('initComplete.cbp');
            });
        },
        /**
         * Add resize event when browser width changes
         */
        resizeEvent: function() {
            var t = this,
                gridWidth;
            CubePortfolio.Private.initResizeEvent({
                instance: t,
                fn: function() {
                    var tt = this;
                    // used by wp fullWidth force option
                    tt.triggerEvent('beforeResizeGrid');
                    gridWidth = tt.$obj.outerWidth();
                    if (tt.width !== gridWidth) {
                        if (tt.options.gridAdjustment === 'alignCenter') {
                            tt.wrapper[0].style.maxWidth = '';
                        }
                        // update the current grid width
                        tt.width = gridWidth;
                        // reposition the blocks with gridAdjustment set to true
                        tt.layoutAndAdjustment();
                        if (tt.options.layoutMode === 'slider') {
                            tt.updateSlider();
                        }
                        tt.triggerEvent('resizeGrid');
                    }
                    tt.triggerEvent('resizeWindow');
                }
            });
        },
        gridAdjust: function() {
            var t = this;
            // if responsive
            if (t.options.gridAdjustment === 'responsive') {
                t.responsiveLayout();
            } else {
                // reset the style attribute for all blocks so I can read a new width & height
                // for the current grid width. This is usefull for the styles defined in css
                // to create a custom responsive system.
                // Note: reset height if it was set for addHeightToBlocks
                t.blocks.removeAttr('style');
                t.blocks.each(function(index, el) {
                    var data = $(el).data('cbp'),
                        bound = el.getBoundingClientRect(),
                        width = t.columnWidthTruncate(bound.right - bound.left),
                        height = Math.round(bound.bottom - bound.top);
                    data.height = height;
                    data.heightAndGap = height + t.options.gapHorizontal;
                    data.width = width;
                    data.widthAndGap = width + t.options.gapVertical;
                });
                t.widthAvailable = t.width + t.options.gapVertical;
            }
            // used by slider layoutMode
            t.triggerEvent('gridAdjust');
        },
        layoutAndAdjustment: function() {
            var t = this;
            t.gridAdjust();
            t.layout();
        },
        /**
         * Build the layout
         */
        layout: function() {
            var t = this;
            t.computeBlocks(t.filterConcat(t.defaultFilter));
            if (t.options.layoutMode === 'slider') {
                t.sliderLayoutReset();
                t.sliderLayout();
            } else {
                t.mosaicLayoutReset();
                t.mosaicLayout();
            }
            // positionate the blocks
            t.positionateItems();
            // resize main container height
            t.resizeMainContainer();
        },
        computeFilter: function(expression) {
            var t = this;
            t.computeBlocks(expression);
            t.mosaicLayoutReset();
            t.mosaicLayout();
            // filter call layout
            t.filterLayout();
        },
        /**
         *  Default filter layout if nothing overrides
         */
        filterLayout: function() {
            var t = this;
            t.blocksOff.addClass('cbp-item-off');
            t.blocksOn.removeClass('cbp-item-off')
                .each(function(index, el) {
                    var data = $(el).data('cbp');
                    data.left = data.leftNew;
                    data.top = data.topNew;
                    el.style.left = data.left + 'px';
                    el.style.top = data.top + 'px';
                });
            // resize main container height
            t.resizeMainContainer();
            t.filterFinish();
        },
        /**
         *  Trigger when a filter is finished
         */
        filterFinish: function() {
            var t = this;
            // if blocks are sorted (the index ascending is broken) revert
            // this state so the index is ascending again
            if (t.blocksAreSorted) {
                t.sortBlocks(t.blocks, 'index');
            }
            t.isAnimating = false;
            t.$obj.trigger('filterComplete.cbp');
            t.triggerEvent('filterFinish');
        },
        computeBlocks: function(expression) {
            var t = this;
            // blocks that are visible before applying the filter
            t.blocksOnInitial = t.blocksOn;
            // blocks visible after applying the filter
            t.blocksOn = t.blocks.filter(expression);
            // blocks off after applying the filter
            t.blocksOff = t.blocks.not(expression);
            t.triggerEvent('computeBlocksFinish', expression);
        },
        /**
         * Make this plugin responsive
         */
        responsiveLayout: function() {
            var t = this;
            // calculate numbers of cols
            t.cols = t[($.isArray(t.options.mediaQueries) ? 'getColumnsBreakpoints' : 'getColumnsAuto')]();
            t.columnWidth = t.columnWidthTruncate((t.width + t.options.gapVertical) / t.cols);
            t.widthAvailable = t.columnWidth * t.cols;
            if (t.options.layoutMode === 'mosaic') {
                t.getMosaicWidthReference();
            }
            t.blocks.each(function(index, el) {
                var data = $(el).data('cbp'),
                    cols = 1, // grid & slider layoutMode must be 1
                    width;
                if (t.options.layoutMode === 'mosaic') {
                    cols = t.getColsMosaic(data.widthInitial);
                }
                width = t.columnWidth * cols - t.options.gapVertical;
                el.style.width = width + 'px';
                data.width = width;
                data.widthAndGap = width + t.options.gapVertical;
                // reset height if it was set for addHeightToBlocks
                el.style.height = '';
            });
            t.blocks.each(function(index, el) {
                var data = $(el).data('cbp'),
                    bound = el.getBoundingClientRect(),
                    height = Math.round(bound.bottom - bound.top);
                data.height = height;
                data.heightAndGap = height + t.options.gapHorizontal;
            });
        },
        getMosaicWidthReference: function() {
            var t = this,
                arrWidth = [];
            t.blocks.each(function(index, el) {
                var data = $(el).data('cbp');
                arrWidth.push(data.widthInitial);
            });
            arrWidth.sort(function(a, b) {
                return a - b;
            });
            if (arrWidth[0]) {
                t.mosaicWidthReference = arrWidth[0];
            } else {
                t.mosaicWidthReference = t.columnWidth;
            }
        },
        getColsMosaic: function(widthInitial) {
            var t = this;
            if (widthInitial === t.width) {
                return t.cols;
            }
            var ratio = widthInitial / t.mosaicWidthReference;
            if (ratio % 1 >= 0.79) {
                ratio = Math.ceil(ratio);
            } else {
                ratio = Math.floor(ratio);
            }
            return Math.min(Math.max(ratio, 1), t.cols);
        },
        /**
         * Get numbers of columns when t.options.mediaQueries is not an array
         */
        getColumnsAuto: function() {
            var t = this;
            if (t.blocks.length === 0) {
                return 1;
            }
            var columnWidth = t.blocks.first().data('cbp').widthInitial + t.options.gapVertical;
            return Math.max(Math.round(t.width / columnWidth), 1);
        },
        /**
         * Get numbers of columns if t.options.mediaQueries is an array
         */
        getColumnsBreakpoints: function() {
            var t = this,
                gridWidth = t.width,
                columns;
            $.each(t.options.mediaQueries, function(index, val) {
                if (gridWidth >= val.width) {
                    columns = val.cols;
                    return false;
                }
            });
            if (columns === undefined) {
                columns = t.options.mediaQueries[t.options.mediaQueries.length - 1].cols;
            }
            return columns;
        },
        /**
         *  Defines how the columns dimension & position (width, left) will be truncated
         *
         *  If you use `Math.*` there could be some issues with the items on the right side
         *  that can have some pixels hidden(1 or 2, depends on the number of columns)
         *  but this is a known limitation.
         *
         *  If you don't use the built-in captions effects (overlay at hover over an item) returning
         *  the possibly floated values may be a solution for the pixels hidden on the right side.
         *
         *  The column width must be an integer because browsers have some visual issues
         *  with transform properties for caption effects.
         *
         *  The initial behaviour was return Math.floor
         *
         */
        columnWidthTruncate: function(value) {
            return Math.floor(value);
        },
        positionateItems: function() {
            var t = this,
                data;
            t.blocksOn.removeClass('cbp-item-off')
                .each(function(index, el) {
                    data = $(el).data('cbp');
                    data.left = data.leftNew;
                    data.top = data.topNew;
                    el.style.left = data.left + 'px';
                    el.style.top = data.top + 'px';
                });
            t.blocksOff.addClass('cbp-item-off');
            // if blocks are sorted (the index ascending is broken) revert
            // this state so the index is ascending again
            if (t.blocksAreSorted) {
                t.sortBlocks(t.blocks, 'index');
            }
        },
        /**
         * Resize main container vertically
         */
        resizeMainContainer: function() {
            var t = this,
                height = Math.max(t.freeSpaces.slice(-1)[0].topStart - t.options.gapHorizontal, 0),
                maxWidth;
            // set max-width to center the grid if I need to
            if (t.options.gridAdjustment === 'alignCenter') {
                maxWidth = 0;
                t.blocksOn.each(function(index, el) {
                    var data = $(el).data('cbp'),
                        rightEdge = data.left + data.width;
                    if (rightEdge > maxWidth) {
                        maxWidth = rightEdge;
                    }
                });
                t.wrapper[0].style.maxWidth = maxWidth + 'px';
            }
            // set container height for `overflow: hidden` to be applied
            if (height === t.height) {
                return;
            }
            t.obj.style.height = height + 'px';
            // if resizeMainContainer is called for the first time skip this event trigger
            if (t.height !== undefined) {
                if (CubePortfolio.Private.modernBrowser) {
                    t.$obj.one(CubePortfolio.Private.transitionend, function() {
                        t.$obj.trigger('pluginResize.cbp');
                    });
                } else {
                    t.$obj.trigger('pluginResize.cbp');
                }
            }
            t.height = height;
            t.triggerEvent('resizeMainContainer');
        },
        filterConcat: function(filter) {
            return filter.replace(/\|/gi, '');
        },
        pushQueue: function(name, deferred) {
            var t = this;
            t.queue[name] = t.queue[name] || [];
            t.queue[name].push(deferred);
        },
        runQueue: function(name, fn) {
            var t = this,
                queue = t.queue[name] || [];
            $.when.apply($, queue).then($.proxy(fn, t));
        },
        clearQueue: function(name) {
            var t = this;
            t.queue[name] = [];
        },
        /**
         *  Register event
         */
        registerEvent: function(name, callbackFunction, oneTime) {
            var t = this;
            if (!t.registeredEvents[name]) {
                t.registeredEvents[name] = [];
            }
            t.registeredEvents[name].push({
                func: callbackFunction,
                oneTime: oneTime || false
            });
        },
        /**
         *  Trigger event
         */
        triggerEvent: function(name, param) {
            var t = this,
                i, len;
            if (t.registeredEvents[name]) {
                for (i = 0, len = t.registeredEvents[name].length; i < len; i++) {
                    t.registeredEvents[name][i].func.call(t, param);
                    if (t.registeredEvents[name][i].oneTime) {
                        t.registeredEvents[name].splice(i, 1);
                        // function splice change the t.registeredEvents[name] array
                        // if event is one time you must set the i to the same value
                        // next time and set the length lower
                        i--;
                        len--;
                    }
                }
            }
        },
        addItems: function(items, callback) {
            var t = this;
            // wrap .cbp-item-wrap div inside .cbp-item
            t.wrapInner(items, 'cbp-item-wrapper');
            items.addClass('cbp-item-loading').css({
                top: '100%',
                left: 0
            }).appendTo(t.$ul);
            if (CubePortfolio.Private.modernBrowser) {
                items.last().one(CubePortfolio.Private.animationend, function() {
                    t.addItemsFinish(items, callback);
                });
            } else {
                t.addItemsFinish(items, callback); // @todo - on ie8 & ie9 callback trigger to early
            }
            t.loadImages(items, function() {
                t.$obj.addClass('cbp-addItems');
                // push to data values of items
                t.storeData(items, t.blocks.length);
                // push the new items to t.blocks
                $.merge(t.blocks, items);
                t.triggerEvent('addItemsToDOM', items);
                t.layoutAndAdjustment();
                if (t.options.layoutMode === 'slider') {
                    t.updateSlider();
                }
                // if show count was actived, call show count function again
                if (t.elems) {
                    CubePortfolio.Public.showCounter.call(t.obj, t.elems);
                }
            });
        },
        addItemsFinish: function(items, callback) {
            var t = this;
            t.isAnimating = false;
            t.$obj.removeClass('cbp-addItems');
            items.removeClass('cbp-item-loading');
            if ($.isFunction(callback)) {
                callback.call(t);
            }
        }
    });
    /**
     * jQuery plugin initializer
     */
    $.fn.cubeportfolio = function(method, options, callback) {
        return this.each(function() {
            if (typeof method === 'object' || !method) {
                return CubePortfolio.Public.init.call(this, method, options);
            } else if (CubePortfolio.Public[method]) {
                return CubePortfolio.Public[method].call(this, options, callback);
            }
            throw new Error('Method ' + method + ' does not exist on jquery.cubeportfolio.js');
        });
    };
    CubePortfolio.Plugins = {};
    $.fn.cubeportfolio.Constructor = CubePortfolio;
})(jQuery, window, document);
(function($, window, document, undefined) {
    'use strict';
    var CubePortfolio = $.fn.cubeportfolio.Constructor;
    function Filters(parent) {
        var t = this;
        t.parent = parent;
        t.filters = $(parent.options.filters);
        t.filterData = [];
        // set default filter if it's present in url
        t.filterFromUrl();
        t.registerFilter();
    }
    Filters.prototype.registerFilter = function() {
        var t = this,
            parent = t.parent,
            filtersCallback,
            arr = parent.defaultFilter.split('|');
        t.wrap = t.filters.find('.cbp-l-filters-dropdownWrap')
            .on({
                'mouseover.cbp': function() {
                    $(this).addClass('cbp-l-filters-dropdownWrap-open');
                },
                'mouseleave.cbp': function() {
                    $(this).removeClass('cbp-l-filters-dropdownWrap-open');
                }
            });
        t.filters.each(function(index, el) {
            var filter = $(el),
                filterName = '*',
                items = filter.find('.cbp-filter-item'),
                dropdown = {};
            if (filter.hasClass('cbp-l-filters-dropdown')) {
                dropdown.wrap = filter.find('.cbp-l-filters-dropdownWrap');
                dropdown.header = filter.find('.cbp-l-filters-dropdownHeader');
                dropdown.headerText = dropdown.header.text();
            }
            // activate counter for filters
            parent.$obj.cubeportfolio('showCounter', items);
            $.each(arr, function(index, val) {
                if (items.filter('[data-filter="' + val + '"]').length) {
                    filterName = val;
                    arr.splice(index, 1);
                    return false;
                }
            });
            $.data(el, 'filterName', filterName);
            t.filterData.push(el);
            t.filtersCallback(dropdown, items.filter('[data-filter="' + filterName + '"]'));
            items.on('click.cbp', function() {
                var item = $(this);
                if (item.hasClass('cbp-filter-item-active') || parent.isAnimating) {
                    return;
                }
                t.filtersCallback(dropdown, item);
                $.data(el, 'filterName', item.data('filter'));
                var name = $.map(t.filterData, function(el, index) {
                    var f = $.data(el, 'filterName');
                    return (f !== "" && f !== '*') ? f : null;
                });
                if (name.length < 1) {
                    name = ['*'];
                }
                var filterJoin = name.join('|');
                if (parent.defaultFilter !== filterJoin) {
                    // filter the items
                    parent.$obj.cubeportfolio('filter', filterJoin);
                }
            });
        });
    };
    Filters.prototype.filtersCallback = function(dropdown, item) {
        if (!$.isEmptyObject(dropdown)) {
            dropdown.wrap.trigger('mouseleave.cbp');
            if (dropdown.headerText) {
                dropdown.headerText = '';
            } else {
                dropdown.header.text(item.text());
            }
        }
        item.addClass('cbp-filter-item-active').siblings().removeClass('cbp-filter-item-active');
    };
    /**
     * Check if filters is present in url
     */
    Filters.prototype.filterFromUrl = function() {
        var match = /#cbpf=(.*?)([#\?&]|$)/gi.exec(location.href);
        if (match !== null) {
            this.parent.defaultFilter = decodeURIComponent(match[1]);
        }
    };
    Filters.prototype.destroy = function() {
        var t = this;
        t.filters.find('.cbp-filter-item').off('.cbp');
        t.wrap.off('.cbp');
    };
    CubePortfolio.Plugins.Filters = function(parent) {
        if (parent.options.filters === '') {
            return null;
        }
        return new Filters(parent);
    };
})(jQuery, window, document);
(function($, window, document, undefined) {
    'use strict';
    var CubePortfolio = $.fn.cubeportfolio.Constructor;
    function LoadMore(parent) {
        var t = this;
        t.parent = parent;
        t.loadMore = $(parent.options.loadMore).find('.cbp-l-loadMore-link');
        // load click or auto action
        if (parent.options.loadMoreAction.length) {
            t[parent.options.loadMoreAction]();
        }
    }
    LoadMore.prototype.click = function() {
        var t = this,
            numberOfClicks = 0;
        t.loadMore.on('click.cbp', function(e) {
            var item = $(this);
            e.preventDefault();
            if (t.parent.isAnimating || item.hasClass('cbp-l-loadMore-stop')) {
                return;
            }
            // set loading status
            item.addClass('cbp-l-loadMore-loading');
            numberOfClicks++;
            // perform ajax request
            $.ajax({
                url: t.loadMore.attr('href'),
                type: 'GET',
                dataType: 'HTML'
            }).done(function(result) {
                var items, itemsNext;
                // find current container
                items = $(result).filter(function() {
                    return $(this).is('div' + '.cbp-loadMore-block' + numberOfClicks);
                });
                t.parent.$obj.cubeportfolio('appendItems', items.children(), function() {
                    // put the original message back
                    item.removeClass('cbp-l-loadMore-loading');
                    // check if we have more works
                    itemsNext = $(result).filter(function() {
                        return $(this).is('div' + '.cbp-loadMore-block' + (numberOfClicks + 1));
                    });
                    if (itemsNext.length === 0) {
                        item.addClass('cbp-l-loadMore-stop');
                    }
                });
            }).fail(function() {
                // error
            });
        });
    };
    LoadMore.prototype.auto = function() {
        var t = this;
        t.parent.$obj.on('initComplete.cbp', function() {
            Object.create({
                init: function() {
                    var self = this;
                    // the job inactive
                    self.isActive = false;
                    self.numberOfClicks = 0;
                    // set loading status
                    t.loadMore.addClass('cbp-l-loadMore-loading');
                    // cache window selector
                    self.window = $(window);
                    // add events for scroll
                    self.addEvents();
                    // trigger method on init
                    self.getNewItems();
                },
                addEvents: function() {
                    var self = this,
                        timeout;
                    t.loadMore.on('click.cbp', function(e) {
                        e.preventDefault();
                    });
                    self.window.on('scroll.loadMoreObject', function() {
                        clearTimeout(timeout);
                        timeout = setTimeout(function() {
                            if (!t.parent.isAnimating) {
                                // get new items on scroll
                                self.getNewItems();
                            }
                        }, 80);
                    });
                    // when the filter is completed
                    t.parent.$obj.on('filterComplete.cbp', function() {
                        self.getNewItems();
                    });
                },
                getNewItems: function() {
                    var self = this,
                        topLoadMore, topWindow;
                    if (self.isActive || t.loadMore.hasClass('cbp-l-loadMore-stop')) {
                        return;
                    }
                    topLoadMore = t.loadMore.offset().top;
                    topWindow = self.window.scrollTop() + self.window.height();
                    if (topLoadMore > topWindow) {
                        return;
                    }
                    // this job is now busy
                    self.isActive = true;
                    // increment number of clicks
                    self.numberOfClicks++;
                    // perform ajax request
                    $.ajax({
                            url: t.loadMore.attr('href'),
                            type: 'GET',
                            dataType: 'HTML',
                            cache: true
                        })
                        .done(function(result) {
                            var items, itemsNext;
                            // find current container
                            items = $(result).filter(function() {
                                return $(this).is('div' + '.cbp-loadMore-block' + self.numberOfClicks);
                            });
                            t.parent.$obj.cubeportfolio('appendItems', items.html(), function() {
                                // check if we have more works
                                itemsNext = $(result).filter(function() {
                                    return $(this).is('div' + '.cbp-loadMore-block' + (self.numberOfClicks + 1));
                                });
                                if (itemsNext.length === 0) {
                                    t.loadMore.addClass('cbp-l-loadMore-stop');
                                    // remove events
                                    self.window.off('scroll.loadMoreObject');
                                    t.parent.$obj.off('filterComplete.cbp');
                                } else {
                                    // make the job inactive
                                    self.isActive = false;
                                    self.window.trigger('scroll.loadMoreObject');
                                }
                            });
                        })
                        .fail(function() {
                            // make the job inactive
                            self.isActive = false;
                        });
                }
            }).init();
        });
    };
    LoadMore.prototype.destroy = function() {
        var t = this;
        t.loadMore.off('.cbp');
        $(window).off('scroll.loadMoreObject');
    };
    CubePortfolio.Plugins.LoadMore = function(parent) {
        if (parent.options.loadMore === '') {
            return null;
        }
        return new LoadMore(parent);
    };
})(jQuery, window, document);
// Plugin default options
jQuery.fn.cubeportfolio.options = {
    /**
     *  Define the wrapper for filters
     *  Values: strings that represent the elements in the document (DOM selector).
     */
    filters: '',
    /**
     *  Define the wrapper for loadMore
     *  Values: strings that represent the elements in the document (DOM selector).
     */
    loadMore: '',
    /**
     *  How the loadMore functionality should behave. Load on click on the button or
     *  automatically when you scroll the page
     *  Values: - click
     *          - auto
     */
    loadMoreAction: 'click',
    /**
     *  Define the search input element
     *  Values: strings that represent the element in the document (DOM selector).
     */
    search: '',
    /**
     *  Layout Mode for this instance
     *  Values: 'grid', 'mosaic' or 'slider'
     */
    layoutMode: 'grid',
    /**
     *  Sort the items (bigger to smallest) if there are gaps in grid
     *  Option available only for `layoutMode: 'mosaic'`
     *  Values: true or false
     */
    sortToPreventGaps: false,
    /**
     *  Mouse and touch drag support
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    drag: true,
    /**
     *  Autoplay the slider
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    auto: false,
    /**
     *  Autoplay interval timeout. Time is set in milisecconds
     *  1000 milliseconds equals 1 second.
     *  Option available only for `layoutMode: 'slider'`
     *  Values: only integers (ex: 1000, 2000, 5000)
     */
    autoTimeout: 5000,
    /**
     *  Stops autoplay when user hover the slider
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    autoPauseOnHover: true,
    /**
     *  Show `next` and `prev` buttons for slider
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    showNavigation: true,
    /**
     *  Show pagination for slider
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    showPagination: true,
    /**
     *  Enable slide to first item (last item)
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    rewindNav: true,
    /**
     *  Scroll by page and not by item. This option affect next/prev buttons and drag support
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    scrollByPage: false,
    /**
     *  Default filter for plugin
     *  Option available only for `layoutMode: 'grid'`
     *  Values: strings that represent the filter name(ex: *, .logo, .web-design, .design)
     */
    defaultFilter: '*',
    /**
     *  Enable / disable the deeplinking feature when you click on filters
     *  Option available only for `layoutMode: 'grid'`
     *  Values: true or false
     */
    filterDeeplinking: false,
    /**
     *  Defines which animation to use for items that will be shown or hidden after a filter has been activated.
     *  Option available only for `layoutMode: 'grid'`
     *  The plugin use the best browser features available (css3 transitions and transform, GPU acceleration).
     *  Values: - fadeOut
     *          - quicksand
     *          - bounceLeft
     *          - bounceTop
     *          - bounceBottom
     *          - moveLeft
     *          - slideLeft
     *          - fadeOutTop
     *          - sequentially
     *          - skew
     *          - slideDelay
     *          - rotateSides
     *          - flipOutDelay
     *          - flipOut
     *          - unfold
     *          - foldLeft
     *          - scaleDown
     *          - scaleSides
     *          - frontRow
     *          - flipBottom
     *          - rotateRoom
     */
    animationType: 'fadeOut',
    /**
     *  Adjust the layout grid
     *  Values: - default (no adjustment applied)
     *          - alignCenter (align the grid on center of the page)
     *          - responsive (use a fluid algorithm to resize the grid)
     */
    gridAdjustment: 'responsive',
    /**
     * Define `media queries` for columns layout.
     * Format: [{width: a, cols: d}, {width: b, cols: e}, {width: c, cols: f}],
     * where a, b, c are the grid width and d, e, f are the columns displayed.
     * e.g. [{width: 1100, cols: 4}, {width: 800, cols: 3}, {width: 480, cols: 2}] means
     * if (gridWidth >= 1100) => show 4 columns,
     * if (gridWidth >= 800 && gridWidth < 1100) => show 3 columns,
     * if (gridWidth >= 480 && gridWidth < 800) => show 2 columns,
     * if (gridWidth < 480) => show 2 columns
     * Keep in mind that a > b > c
     * This option is available only when `gridAdjustment: 'responsive'`
     * Values:  - array of objects of format: [{width: a, cols: d}, {width: b, cols: e}]
     *          - you can define as many objects as you want
     *          - if this option is `false` Cube Portfolio will adjust the items
     *            width automatically (default option for backward compatibility)
     */
    mediaQueries: false,
    /**
     *  Horizontal gap between items
     *  Values: only integers (ex: 1, 5, 10)
     */
    gapHorizontal: 10,
    /**
     *  Vertical gap between items
     *  Values: only integers (ex: 1, 5, 10)
     */
    gapVertical: 10,
    /**
     *  Caption - the overlay that is shown when you put the mouse over an item
     *  NOTE: If you don't want to have captions set this option to an empty string ( caption: '')
     *  Values: - pushTop
     *          - pushDown
     *          - revealBottom
     *          - revealTop
     *          - revealLeft
     *          - moveRight
     *          - overlayBottom
     *          - overlayBottomPush
     *          - overlayBottomReveal
     *          - overlayBottomAlong
     *          - overlayRightAlong
     *          - minimal
     *          - fadeIn
     *          - zoom
     *          - opacity
     *          - ''
     */
    caption: 'pushTop',
    /**
     *  The plugin will display his content based on the following values.
     *  Values: - default (the content will be displayed as soon as possible)
     *          - lazyLoading (the plugin will fully preload the images before displaying the items with a fadeIn effect)
     *          - fadeInToTop (the plugin will fully preload the images before displaying the items with a fadeIn effect from bottom to top)
     *          - sequentially (the plugin will fully preload the images before displaying the items with a sequentially effect)
     *          - bottomToTop (the plugin will fully preload the images before displaying the items with an animation from bottom to top)
     */
    displayType: 'lazyLoading',
    /**
     *  Defines the speed of displaying the items (when `displayType == default` this option will have no effect)
     *  Values: only integers, values in ms (ex: 200, 300, 500)
     */
    displayTypeSpeed: 400,
    /**
     *  This is used to define any clickable elements you wish to use to trigger lightbox popup on click.
     *  Values: strings that represent the elements in the document (DOM selector)
     */
    lightboxDelegate: '.cbp-lightbox',
    /**
     *  Enable / disable gallery mode
     *  Values: true or false
     */
    lightboxGallery: true,
    /**
     *  Attribute of the delegate item that contains caption for lightbox
     *  Values: html atributte
     */
    lightboxTitleSrc: 'data-title',
    /**
     *  Markup of the lightbox counter
     *  Values: html markup
     */
    lightboxCounter: '
').on('load.cbp error.cbp', function() {
                        srcLength--;
                        if (srcLength === 0) {
                            callback.call(t);
                        }
                    }).attr('src', el); // for ie8
                });
            });
        },
        checkSrc: function(src) {
            if (src === '') {
                return null;
            }
            var img = new Image();
            img.src = src;
            if (img.complete && img.naturalWidth !== undefined && img.naturalWidth !== 0) {
                return null;
            }
            return src;
        },
        /**
         * Show the plugin
         */
        display: function() {
            var t = this;
            // store main container width
            t.width = t.$obj.outerWidth();
            // store to data some values of t.blocks
            t.storeData(t.blocks);
            t.triggerEvent('initStartRead');
            t.triggerEvent('initStartWrite');
            // create mark-up for slider layout
            if (t.options.layoutMode === 'slider') {
                t.registerEvent('gridAdjust', function() {
                    t.sliderMarkup();
                }, true);
            }
            // make layout
            t.layoutAndAdjustment();
            t.triggerEvent('initEndRead');
            t.triggerEvent('initEndWrite');
            // plugin is ready to show and interact
            t.$obj.addClass('cbp-ready');
            t.runQueue('delayFrame', t.delayFrame);
        },
        delayFrame: function() {
            var t = this;
            requestAnimationFrame(function() {
                t.resizeEvent();
                t.triggerEvent('initFinish');
                // animating is now false
                t.isAnimating = false;
                // trigger public event initComplete
                t.$obj.trigger('initComplete.cbp');
            });
        },
        /**
         * Add resize event when browser width changes
         */
        resizeEvent: function() {
            var t = this,
                gridWidth;
            CubePortfolio.Private.initResizeEvent({
                instance: t,
                fn: function() {
                    var tt = this;
                    // used by wp fullWidth force option
                    tt.triggerEvent('beforeResizeGrid');
                    gridWidth = tt.$obj.outerWidth();
                    if (tt.width !== gridWidth) {
                        if (tt.options.gridAdjustment === 'alignCenter') {
                            tt.wrapper[0].style.maxWidth = '';
                        }
                        // update the current grid width
                        tt.width = gridWidth;
                        // reposition the blocks with gridAdjustment set to true
                        tt.layoutAndAdjustment();
                        if (tt.options.layoutMode === 'slider') {
                            tt.updateSlider();
                        }
                        tt.triggerEvent('resizeGrid');
                    }
                    tt.triggerEvent('resizeWindow');
                }
            });
        },
        gridAdjust: function() {
            var t = this;
            // if responsive
            if (t.options.gridAdjustment === 'responsive') {
                t.responsiveLayout();
            } else {
                // reset the style attribute for all blocks so I can read a new width & height
                // for the current grid width. This is usefull for the styles defined in css
                // to create a custom responsive system.
                // Note: reset height if it was set for addHeightToBlocks
                t.blocks.removeAttr('style');
                t.blocks.each(function(index, el) {
                    var data = $(el).data('cbp'),
                        bound = el.getBoundingClientRect(),
                        width = t.columnWidthTruncate(bound.right - bound.left),
                        height = Math.round(bound.bottom - bound.top);
                    data.height = height;
                    data.heightAndGap = height + t.options.gapHorizontal;
                    data.width = width;
                    data.widthAndGap = width + t.options.gapVertical;
                });
                t.widthAvailable = t.width + t.options.gapVertical;
            }
            // used by slider layoutMode
            t.triggerEvent('gridAdjust');
        },
        layoutAndAdjustment: function() {
            var t = this;
            t.gridAdjust();
            t.layout();
        },
        /**
         * Build the layout
         */
        layout: function() {
            var t = this;
            t.computeBlocks(t.filterConcat(t.defaultFilter));
            if (t.options.layoutMode === 'slider') {
                t.sliderLayoutReset();
                t.sliderLayout();
            } else {
                t.mosaicLayoutReset();
                t.mosaicLayout();
            }
            // positionate the blocks
            t.positionateItems();
            // resize main container height
            t.resizeMainContainer();
        },
        computeFilter: function(expression) {
            var t = this;
            t.computeBlocks(expression);
            t.mosaicLayoutReset();
            t.mosaicLayout();
            // filter call layout
            t.filterLayout();
        },
        /**
         *  Default filter layout if nothing overrides
         */
        filterLayout: function() {
            var t = this;
            t.blocksOff.addClass('cbp-item-off');
            t.blocksOn.removeClass('cbp-item-off')
                .each(function(index, el) {
                    var data = $(el).data('cbp');
                    data.left = data.leftNew;
                    data.top = data.topNew;
                    el.style.left = data.left + 'px';
                    el.style.top = data.top + 'px';
                });
            // resize main container height
            t.resizeMainContainer();
            t.filterFinish();
        },
        /**
         *  Trigger when a filter is finished
         */
        filterFinish: function() {
            var t = this;
            // if blocks are sorted (the index ascending is broken) revert
            // this state so the index is ascending again
            if (t.blocksAreSorted) {
                t.sortBlocks(t.blocks, 'index');
            }
            t.isAnimating = false;
            t.$obj.trigger('filterComplete.cbp');
            t.triggerEvent('filterFinish');
        },
        computeBlocks: function(expression) {
            var t = this;
            // blocks that are visible before applying the filter
            t.blocksOnInitial = t.blocksOn;
            // blocks visible after applying the filter
            t.blocksOn = t.blocks.filter(expression);
            // blocks off after applying the filter
            t.blocksOff = t.blocks.not(expression);
            t.triggerEvent('computeBlocksFinish', expression);
        },
        /**
         * Make this plugin responsive
         */
        responsiveLayout: function() {
            var t = this;
            // calculate numbers of cols
            t.cols = t[($.isArray(t.options.mediaQueries) ? 'getColumnsBreakpoints' : 'getColumnsAuto')]();
            t.columnWidth = t.columnWidthTruncate((t.width + t.options.gapVertical) / t.cols);
            t.widthAvailable = t.columnWidth * t.cols;
            if (t.options.layoutMode === 'mosaic') {
                t.getMosaicWidthReference();
            }
            t.blocks.each(function(index, el) {
                var data = $(el).data('cbp'),
                    cols = 1, // grid & slider layoutMode must be 1
                    width;
                if (t.options.layoutMode === 'mosaic') {
                    cols = t.getColsMosaic(data.widthInitial);
                }
                width = t.columnWidth * cols - t.options.gapVertical;
                el.style.width = width + 'px';
                data.width = width;
                data.widthAndGap = width + t.options.gapVertical;
                // reset height if it was set for addHeightToBlocks
                el.style.height = '';
            });
            t.blocks.each(function(index, el) {
                var data = $(el).data('cbp'),
                    bound = el.getBoundingClientRect(),
                    height = Math.round(bound.bottom - bound.top);
                data.height = height;
                data.heightAndGap = height + t.options.gapHorizontal;
            });
        },
        getMosaicWidthReference: function() {
            var t = this,
                arrWidth = [];
            t.blocks.each(function(index, el) {
                var data = $(el).data('cbp');
                arrWidth.push(data.widthInitial);
            });
            arrWidth.sort(function(a, b) {
                return a - b;
            });
            if (arrWidth[0]) {
                t.mosaicWidthReference = arrWidth[0];
            } else {
                t.mosaicWidthReference = t.columnWidth;
            }
        },
        getColsMosaic: function(widthInitial) {
            var t = this;
            if (widthInitial === t.width) {
                return t.cols;
            }
            var ratio = widthInitial / t.mosaicWidthReference;
            if (ratio % 1 >= 0.79) {
                ratio = Math.ceil(ratio);
            } else {
                ratio = Math.floor(ratio);
            }
            return Math.min(Math.max(ratio, 1), t.cols);
        },
        /**
         * Get numbers of columns when t.options.mediaQueries is not an array
         */
        getColumnsAuto: function() {
            var t = this;
            if (t.blocks.length === 0) {
                return 1;
            }
            var columnWidth = t.blocks.first().data('cbp').widthInitial + t.options.gapVertical;
            return Math.max(Math.round(t.width / columnWidth), 1);
        },
        /**
         * Get numbers of columns if t.options.mediaQueries is an array
         */
        getColumnsBreakpoints: function() {
            var t = this,
                gridWidth = t.width,
                columns;
            $.each(t.options.mediaQueries, function(index, val) {
                if (gridWidth >= val.width) {
                    columns = val.cols;
                    return false;
                }
            });
            if (columns === undefined) {
                columns = t.options.mediaQueries[t.options.mediaQueries.length - 1].cols;
            }
            return columns;
        },
        /**
         *  Defines how the columns dimension & position (width, left) will be truncated
         *
         *  If you use `Math.*` there could be some issues with the items on the right side
         *  that can have some pixels hidden(1 or 2, depends on the number of columns)
         *  but this is a known limitation.
         *
         *  If you don't use the built-in captions effects (overlay at hover over an item) returning
         *  the possibly floated values may be a solution for the pixels hidden on the right side.
         *
         *  The column width must be an integer because browsers have some visual issues
         *  with transform properties for caption effects.
         *
         *  The initial behaviour was return Math.floor
         *
         */
        columnWidthTruncate: function(value) {
            return Math.floor(value);
        },
        positionateItems: function() {
            var t = this,
                data;
            t.blocksOn.removeClass('cbp-item-off')
                .each(function(index, el) {
                    data = $(el).data('cbp');
                    data.left = data.leftNew;
                    data.top = data.topNew;
                    el.style.left = data.left + 'px';
                    el.style.top = data.top + 'px';
                });
            t.blocksOff.addClass('cbp-item-off');
            // if blocks are sorted (the index ascending is broken) revert
            // this state so the index is ascending again
            if (t.blocksAreSorted) {
                t.sortBlocks(t.blocks, 'index');
            }
        },
        /**
         * Resize main container vertically
         */
        resizeMainContainer: function() {
            var t = this,
                height = Math.max(t.freeSpaces.slice(-1)[0].topStart - t.options.gapHorizontal, 0),
                maxWidth;
            // set max-width to center the grid if I need to
            if (t.options.gridAdjustment === 'alignCenter') {
                maxWidth = 0;
                t.blocksOn.each(function(index, el) {
                    var data = $(el).data('cbp'),
                        rightEdge = data.left + data.width;
                    if (rightEdge > maxWidth) {
                        maxWidth = rightEdge;
                    }
                });
                t.wrapper[0].style.maxWidth = maxWidth + 'px';
            }
            // set container height for `overflow: hidden` to be applied
            if (height === t.height) {
                return;
            }
            t.obj.style.height = height + 'px';
            // if resizeMainContainer is called for the first time skip this event trigger
            if (t.height !== undefined) {
                if (CubePortfolio.Private.modernBrowser) {
                    t.$obj.one(CubePortfolio.Private.transitionend, function() {
                        t.$obj.trigger('pluginResize.cbp');
                    });
                } else {
                    t.$obj.trigger('pluginResize.cbp');
                }
            }
            t.height = height;
            t.triggerEvent('resizeMainContainer');
        },
        filterConcat: function(filter) {
            return filter.replace(/\|/gi, '');
        },
        pushQueue: function(name, deferred) {
            var t = this;
            t.queue[name] = t.queue[name] || [];
            t.queue[name].push(deferred);
        },
        runQueue: function(name, fn) {
            var t = this,
                queue = t.queue[name] || [];
            $.when.apply($, queue).then($.proxy(fn, t));
        },
        clearQueue: function(name) {
            var t = this;
            t.queue[name] = [];
        },
        /**
         *  Register event
         */
        registerEvent: function(name, callbackFunction, oneTime) {
            var t = this;
            if (!t.registeredEvents[name]) {
                t.registeredEvents[name] = [];
            }
            t.registeredEvents[name].push({
                func: callbackFunction,
                oneTime: oneTime || false
            });
        },
        /**
         *  Trigger event
         */
        triggerEvent: function(name, param) {
            var t = this,
                i, len;
            if (t.registeredEvents[name]) {
                for (i = 0, len = t.registeredEvents[name].length; i < len; i++) {
                    t.registeredEvents[name][i].func.call(t, param);
                    if (t.registeredEvents[name][i].oneTime) {
                        t.registeredEvents[name].splice(i, 1);
                        // function splice change the t.registeredEvents[name] array
                        // if event is one time you must set the i to the same value
                        // next time and set the length lower
                        i--;
                        len--;
                    }
                }
            }
        },
        addItems: function(items, callback) {
            var t = this;
            // wrap .cbp-item-wrap div inside .cbp-item
            t.wrapInner(items, 'cbp-item-wrapper');
            items.addClass('cbp-item-loading').css({
                top: '100%',
                left: 0
            }).appendTo(t.$ul);
            if (CubePortfolio.Private.modernBrowser) {
                items.last().one(CubePortfolio.Private.animationend, function() {
                    t.addItemsFinish(items, callback);
                });
            } else {
                t.addItemsFinish(items, callback); // @todo - on ie8 & ie9 callback trigger to early
            }
            t.loadImages(items, function() {
                t.$obj.addClass('cbp-addItems');
                // push to data values of items
                t.storeData(items, t.blocks.length);
                // push the new items to t.blocks
                $.merge(t.blocks, items);
                t.triggerEvent('addItemsToDOM', items);
                t.layoutAndAdjustment();
                if (t.options.layoutMode === 'slider') {
                    t.updateSlider();
                }
                // if show count was actived, call show count function again
                if (t.elems) {
                    CubePortfolio.Public.showCounter.call(t.obj, t.elems);
                }
            });
        },
        addItemsFinish: function(items, callback) {
            var t = this;
            t.isAnimating = false;
            t.$obj.removeClass('cbp-addItems');
            items.removeClass('cbp-item-loading');
            if ($.isFunction(callback)) {
                callback.call(t);
            }
        }
    });
    /**
     * jQuery plugin initializer
     */
    $.fn.cubeportfolio = function(method, options, callback) {
        return this.each(function() {
            if (typeof method === 'object' || !method) {
                return CubePortfolio.Public.init.call(this, method, options);
            } else if (CubePortfolio.Public[method]) {
                return CubePortfolio.Public[method].call(this, options, callback);
            }
            throw new Error('Method ' + method + ' does not exist on jquery.cubeportfolio.js');
        });
    };
    CubePortfolio.Plugins = {};
    $.fn.cubeportfolio.Constructor = CubePortfolio;
})(jQuery, window, document);
(function($, window, document, undefined) {
    'use strict';
    var CubePortfolio = $.fn.cubeportfolio.Constructor;
    function Filters(parent) {
        var t = this;
        t.parent = parent;
        t.filters = $(parent.options.filters);
        t.filterData = [];
        // set default filter if it's present in url
        t.filterFromUrl();
        t.registerFilter();
    }
    Filters.prototype.registerFilter = function() {
        var t = this,
            parent = t.parent,
            filtersCallback,
            arr = parent.defaultFilter.split('|');
        t.wrap = t.filters.find('.cbp-l-filters-dropdownWrap')
            .on({
                'mouseover.cbp': function() {
                    $(this).addClass('cbp-l-filters-dropdownWrap-open');
                },
                'mouseleave.cbp': function() {
                    $(this).removeClass('cbp-l-filters-dropdownWrap-open');
                }
            });
        t.filters.each(function(index, el) {
            var filter = $(el),
                filterName = '*',
                items = filter.find('.cbp-filter-item'),
                dropdown = {};
            if (filter.hasClass('cbp-l-filters-dropdown')) {
                dropdown.wrap = filter.find('.cbp-l-filters-dropdownWrap');
                dropdown.header = filter.find('.cbp-l-filters-dropdownHeader');
                dropdown.headerText = dropdown.header.text();
            }
            // activate counter for filters
            parent.$obj.cubeportfolio('showCounter', items);
            $.each(arr, function(index, val) {
                if (items.filter('[data-filter="' + val + '"]').length) {
                    filterName = val;
                    arr.splice(index, 1);
                    return false;
                }
            });
            $.data(el, 'filterName', filterName);
            t.filterData.push(el);
            t.filtersCallback(dropdown, items.filter('[data-filter="' + filterName + '"]'));
            items.on('click.cbp', function() {
                var item = $(this);
                if (item.hasClass('cbp-filter-item-active') || parent.isAnimating) {
                    return;
                }
                t.filtersCallback(dropdown, item);
                $.data(el, 'filterName', item.data('filter'));
                var name = $.map(t.filterData, function(el, index) {
                    var f = $.data(el, 'filterName');
                    return (f !== "" && f !== '*') ? f : null;
                });
                if (name.length < 1) {
                    name = ['*'];
                }
                var filterJoin = name.join('|');
                if (parent.defaultFilter !== filterJoin) {
                    // filter the items
                    parent.$obj.cubeportfolio('filter', filterJoin);
                }
            });
        });
    };
    Filters.prototype.filtersCallback = function(dropdown, item) {
        if (!$.isEmptyObject(dropdown)) {
            dropdown.wrap.trigger('mouseleave.cbp');
            if (dropdown.headerText) {
                dropdown.headerText = '';
            } else {
                dropdown.header.text(item.text());
            }
        }
        item.addClass('cbp-filter-item-active').siblings().removeClass('cbp-filter-item-active');
    };
    /**
     * Check if filters is present in url
     */
    Filters.prototype.filterFromUrl = function() {
        var match = /#cbpf=(.*?)([#\?&]|$)/gi.exec(location.href);
        if (match !== null) {
            this.parent.defaultFilter = decodeURIComponent(match[1]);
        }
    };
    Filters.prototype.destroy = function() {
        var t = this;
        t.filters.find('.cbp-filter-item').off('.cbp');
        t.wrap.off('.cbp');
    };
    CubePortfolio.Plugins.Filters = function(parent) {
        if (parent.options.filters === '') {
            return null;
        }
        return new Filters(parent);
    };
})(jQuery, window, document);
(function($, window, document, undefined) {
    'use strict';
    var CubePortfolio = $.fn.cubeportfolio.Constructor;
    function LoadMore(parent) {
        var t = this;
        t.parent = parent;
        t.loadMore = $(parent.options.loadMore).find('.cbp-l-loadMore-link');
        // load click or auto action
        if (parent.options.loadMoreAction.length) {
            t[parent.options.loadMoreAction]();
        }
    }
    LoadMore.prototype.click = function() {
        var t = this,
            numberOfClicks = 0;
        t.loadMore.on('click.cbp', function(e) {
            var item = $(this);
            e.preventDefault();
            if (t.parent.isAnimating || item.hasClass('cbp-l-loadMore-stop')) {
                return;
            }
            // set loading status
            item.addClass('cbp-l-loadMore-loading');
            numberOfClicks++;
            // perform ajax request
            $.ajax({
                url: t.loadMore.attr('href'),
                type: 'GET',
                dataType: 'HTML'
            }).done(function(result) {
                var items, itemsNext;
                // find current container
                items = $(result).filter(function() {
                    return $(this).is('div' + '.cbp-loadMore-block' + numberOfClicks);
                });
                t.parent.$obj.cubeportfolio('appendItems', items.children(), function() {
                    // put the original message back
                    item.removeClass('cbp-l-loadMore-loading');
                    // check if we have more works
                    itemsNext = $(result).filter(function() {
                        return $(this).is('div' + '.cbp-loadMore-block' + (numberOfClicks + 1));
                    });
                    if (itemsNext.length === 0) {
                        item.addClass('cbp-l-loadMore-stop');
                    }
                });
            }).fail(function() {
                // error
            });
        });
    };
    LoadMore.prototype.auto = function() {
        var t = this;
        t.parent.$obj.on('initComplete.cbp', function() {
            Object.create({
                init: function() {
                    var self = this;
                    // the job inactive
                    self.isActive = false;
                    self.numberOfClicks = 0;
                    // set loading status
                    t.loadMore.addClass('cbp-l-loadMore-loading');
                    // cache window selector
                    self.window = $(window);
                    // add events for scroll
                    self.addEvents();
                    // trigger method on init
                    self.getNewItems();
                },
                addEvents: function() {
                    var self = this,
                        timeout;
                    t.loadMore.on('click.cbp', function(e) {
                        e.preventDefault();
                    });
                    self.window.on('scroll.loadMoreObject', function() {
                        clearTimeout(timeout);
                        timeout = setTimeout(function() {
                            if (!t.parent.isAnimating) {
                                // get new items on scroll
                                self.getNewItems();
                            }
                        }, 80);
                    });
                    // when the filter is completed
                    t.parent.$obj.on('filterComplete.cbp', function() {
                        self.getNewItems();
                    });
                },
                getNewItems: function() {
                    var self = this,
                        topLoadMore, topWindow;
                    if (self.isActive || t.loadMore.hasClass('cbp-l-loadMore-stop')) {
                        return;
                    }
                    topLoadMore = t.loadMore.offset().top;
                    topWindow = self.window.scrollTop() + self.window.height();
                    if (topLoadMore > topWindow) {
                        return;
                    }
                    // this job is now busy
                    self.isActive = true;
                    // increment number of clicks
                    self.numberOfClicks++;
                    // perform ajax request
                    $.ajax({
                            url: t.loadMore.attr('href'),
                            type: 'GET',
                            dataType: 'HTML',
                            cache: true
                        })
                        .done(function(result) {
                            var items, itemsNext;
                            // find current container
                            items = $(result).filter(function() {
                                return $(this).is('div' + '.cbp-loadMore-block' + self.numberOfClicks);
                            });
                            t.parent.$obj.cubeportfolio('appendItems', items.html(), function() {
                                // check if we have more works
                                itemsNext = $(result).filter(function() {
                                    return $(this).is('div' + '.cbp-loadMore-block' + (self.numberOfClicks + 1));
                                });
                                if (itemsNext.length === 0) {
                                    t.loadMore.addClass('cbp-l-loadMore-stop');
                                    // remove events
                                    self.window.off('scroll.loadMoreObject');
                                    t.parent.$obj.off('filterComplete.cbp');
                                } else {
                                    // make the job inactive
                                    self.isActive = false;
                                    self.window.trigger('scroll.loadMoreObject');
                                }
                            });
                        })
                        .fail(function() {
                            // make the job inactive
                            self.isActive = false;
                        });
                }
            }).init();
        });
    };
    LoadMore.prototype.destroy = function() {
        var t = this;
        t.loadMore.off('.cbp');
        $(window).off('scroll.loadMoreObject');
    };
    CubePortfolio.Plugins.LoadMore = function(parent) {
        if (parent.options.loadMore === '') {
            return null;
        }
        return new LoadMore(parent);
    };
})(jQuery, window, document);
// Plugin default options
jQuery.fn.cubeportfolio.options = {
    /**
     *  Define the wrapper for filters
     *  Values: strings that represent the elements in the document (DOM selector).
     */
    filters: '',
    /**
     *  Define the wrapper for loadMore
     *  Values: strings that represent the elements in the document (DOM selector).
     */
    loadMore: '',
    /**
     *  How the loadMore functionality should behave. Load on click on the button or
     *  automatically when you scroll the page
     *  Values: - click
     *          - auto
     */
    loadMoreAction: 'click',
    /**
     *  Define the search input element
     *  Values: strings that represent the element in the document (DOM selector).
     */
    search: '',
    /**
     *  Layout Mode for this instance
     *  Values: 'grid', 'mosaic' or 'slider'
     */
    layoutMode: 'grid',
    /**
     *  Sort the items (bigger to smallest) if there are gaps in grid
     *  Option available only for `layoutMode: 'mosaic'`
     *  Values: true or false
     */
    sortToPreventGaps: false,
    /**
     *  Mouse and touch drag support
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    drag: true,
    /**
     *  Autoplay the slider
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    auto: false,
    /**
     *  Autoplay interval timeout. Time is set in milisecconds
     *  1000 milliseconds equals 1 second.
     *  Option available only for `layoutMode: 'slider'`
     *  Values: only integers (ex: 1000, 2000, 5000)
     */
    autoTimeout: 5000,
    /**
     *  Stops autoplay when user hover the slider
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    autoPauseOnHover: true,
    /**
     *  Show `next` and `prev` buttons for slider
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    showNavigation: true,
    /**
     *  Show pagination for slider
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    showPagination: true,
    /**
     *  Enable slide to first item (last item)
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    rewindNav: true,
    /**
     *  Scroll by page and not by item. This option affect next/prev buttons and drag support
     *  Option available only for `layoutMode: 'slider'`
     *  Values: true or false
     */
    scrollByPage: false,
    /**
     *  Default filter for plugin
     *  Option available only for `layoutMode: 'grid'`
     *  Values: strings that represent the filter name(ex: *, .logo, .web-design, .design)
     */
    defaultFilter: '*',
    /**
     *  Enable / disable the deeplinking feature when you click on filters
     *  Option available only for `layoutMode: 'grid'`
     *  Values: true or false
     */
    filterDeeplinking: false,
    /**
     *  Defines which animation to use for items that will be shown or hidden after a filter has been activated.
     *  Option available only for `layoutMode: 'grid'`
     *  The plugin use the best browser features available (css3 transitions and transform, GPU acceleration).
     *  Values: - fadeOut
     *          - quicksand
     *          - bounceLeft
     *          - bounceTop
     *          - bounceBottom
     *          - moveLeft
     *          - slideLeft
     *          - fadeOutTop
     *          - sequentially
     *          - skew
     *          - slideDelay
     *          - rotateSides
     *          - flipOutDelay
     *          - flipOut
     *          - unfold
     *          - foldLeft
     *          - scaleDown
     *          - scaleSides
     *          - frontRow
     *          - flipBottom
     *          - rotateRoom
     */
    animationType: 'fadeOut',
    /**
     *  Adjust the layout grid
     *  Values: - default (no adjustment applied)
     *          - alignCenter (align the grid on center of the page)
     *          - responsive (use a fluid algorithm to resize the grid)
     */
    gridAdjustment: 'responsive',
    /**
     * Define `media queries` for columns layout.
     * Format: [{width: a, cols: d}, {width: b, cols: e}, {width: c, cols: f}],
     * where a, b, c are the grid width and d, e, f are the columns displayed.
     * e.g. [{width: 1100, cols: 4}, {width: 800, cols: 3}, {width: 480, cols: 2}] means
     * if (gridWidth >= 1100) => show 4 columns,
     * if (gridWidth >= 800 && gridWidth < 1100) => show 3 columns,
     * if (gridWidth >= 480 && gridWidth < 800) => show 2 columns,
     * if (gridWidth < 480) => show 2 columns
     * Keep in mind that a > b > c
     * This option is available only when `gridAdjustment: 'responsive'`
     * Values:  - array of objects of format: [{width: a, cols: d}, {width: b, cols: e}]
     *          - you can define as many objects as you want
     *          - if this option is `false` Cube Portfolio will adjust the items
     *            width automatically (default option for backward compatibility)
     */
    mediaQueries: false,
    /**
     *  Horizontal gap between items
     *  Values: only integers (ex: 1, 5, 10)
     */
    gapHorizontal: 10,
    /**
     *  Vertical gap between items
     *  Values: only integers (ex: 1, 5, 10)
     */
    gapVertical: 10,
    /**
     *  Caption - the overlay that is shown when you put the mouse over an item
     *  NOTE: If you don't want to have captions set this option to an empty string ( caption: '')
     *  Values: - pushTop
     *          - pushDown
     *          - revealBottom
     *          - revealTop
     *          - revealLeft
     *          - moveRight
     *          - overlayBottom
     *          - overlayBottomPush
     *          - overlayBottomReveal
     *          - overlayBottomAlong
     *          - overlayRightAlong
     *          - minimal
     *          - fadeIn
     *          - zoom
     *          - opacity
     *          - ''
     */
    caption: 'pushTop',
    /**
     *  The plugin will display his content based on the following values.
     *  Values: - default (the content will be displayed as soon as possible)
     *          - lazyLoading (the plugin will fully preload the images before displaying the items with a fadeIn effect)
     *          - fadeInToTop (the plugin will fully preload the images before displaying the items with a fadeIn effect from bottom to top)
     *          - sequentially (the plugin will fully preload the images before displaying the items with a sequentially effect)
     *          - bottomToTop (the plugin will fully preload the images before displaying the items with an animation from bottom to top)
     */
    displayType: 'lazyLoading',
    /**
     *  Defines the speed of displaying the items (when `displayType == default` this option will have no effect)
     *  Values: only integers, values in ms (ex: 200, 300, 500)
     */
    displayTypeSpeed: 400,
    /**
     *  This is used to define any clickable elements you wish to use to trigger lightbox popup on click.
     *  Values: strings that represent the elements in the document (DOM selector)
     */
    lightboxDelegate: '.cbp-lightbox',
    /**
     *  Enable / disable gallery mode
     *  Values: true or false
     */
    lightboxGallery: true,
    /**
     *  Attribute of the delegate item that contains caption for lightbox
     *  Values: html atributte
     */
    lightboxTitleSrc: 'data-title',
    /**
     *  Markup of the lightbox counter
     *  Values: html markup
     */
    lightboxCounter: '
',
    /**
     *  This is used to define any clickable elements you wish to use to trigger singlePage popup on click.
     *  Values: strings that represent the elements in the document (DOM selector)
     */
    singlePageDelegate: '.cbp-singlePage',
    /**
     *  Enable / disable the deeplinking feature for singlePage popup
     *  Values: true or false
     */
    singlePageDeeplinking: true,
    /**
     *  Enable / disable the sticky navigation for singlePage popup
     *  Values: true or false
     */
    singlePageStickyNavigation: true,
    /**
     *  Markup of the singlePage counter
     *  Values: html markup
     */
    singlePageCounter: '',
    /**
     *  Defines which animation to use when singlePage appear
     *  Values: - left
     *          - fade
     *          - right
     */
    singlePageAnimation: 'left',
    /**
     *  Use this callback to update singlePage content.
     *  The callback will trigger after the singlePage popup will open.
     *  @param url = the href attribute of the item clicked
     *  @param element = the item clicked
     *  Values: function
     */
    singlePageCallback: function(url, element) {
        // to update singlePage content use the following method: this.updateSinglePage(yourContent)
    },
    /**
     *  This is used to define any clickable elements you wish to use to trigger singlePage Inline on click.
     *  Values: strings that represent the elements in the document (DOM selector)
     */
    singlePageInlineDelegate: '.cbp-singlePageInline',
    /**
     *  This is used to define the position of singlePage Inline block
     *  Values: - above ( above current element )
     *          - below ( below current elemnet)
     *          - top ( positon top )
     *          - bottom ( positon bottom )
     */
    singlePageInlinePosition: 'top',
    /**
     *  Push the open panel in focus and at close go back to the former stage
     *  Values: true or false
     */
    singlePageInlineInFocus: true,
    /**
     *  Use this callback to update singlePage Inline content.
     *  The callback will trigger after the singlePage Inline will open.
     *  @param url = the href attribute of the item clicked
     *  @param element = the item clicked
     *  Values: function
     */
    singlePageInlineCallback: function(url, element) {
        // to update singlePage Inline content use the following method: this.updateSinglePageInline(yourContent)
    },
};
(function($, window, document, undefined) {
    'use strict';
    var CubePortfolio = $.fn.cubeportfolio.Constructor;
    var popup = {
        /**
         * init function for popup
         * @param cubeportfolio = cubeportfolio instance
         * @param type =  'lightbox' or 'singlePage'
         */
        init: function(cubeportfolio, type) {
            var t = this,
                currentBlock;
            // remember cubeportfolio instance
            t.cubeportfolio = cubeportfolio;
            // remember if this instance is for lightbox or for singlePage
            t.type = type;
            // remember if the popup is open or not
            t.isOpen = false;
            t.options = t.cubeportfolio.options;
            if (type === 'lightbox') {
                t.cubeportfolio.registerEvent('resizeWindow', function() {
                    t.resizeImage();
                });
            }
            if (type === 'singlePageInline') {
                t.startInline = -1;
                t.height = 0;
                // create markup, css and add events for SinglePageInline
                t.createMarkupSinglePageInline();
                t.cubeportfolio.registerEvent('resizeGrid', function() {
                    if (t.isOpen) {
                        // @todo must add support for this features in the future
                        t.close(); // workaround
                    }
                });
                return;
            }
            // create markup, css and add events for lightbox and singlePage
            t.createMarkup();
            if (type === 'singlePage') {
                t.cubeportfolio.registerEvent('resizeWindow', function() {
                    if (t.options.singlePageStickyNavigation) {
                        var width = t.wrap[0].clientWidth;
                        if (width > 0) {
                            t.navigationWrap.width(width);
                            // set navigation width='window width' to center the divs
                            t.navigation.width(width);
                        }
                    }
                });
                if (t.options.singlePageDeeplinking) {
                    t.url = location.href;
                    if (t.url.slice(-1) === '#') {
                        t.url = t.url.slice(0, -1);
                    }
                    var links = t.url.split('#cbp=');
                    var url = links.shift(); // remove first item
                    $.each(links, function(index, link) {
                        t.cubeportfolio.blocksOn.each(function(index1, el) {
                            var singlePage = $(el).find(t.options.singlePageDelegate + '[href="' + link + '"]');
                            if (singlePage.length) {
                                currentBlock = singlePage;
                                return false;
                            }
                        });
                        if (currentBlock) {
                            return false;
                        }
                    });
                    if (currentBlock) {
                        t.url = url;
                        var self = currentBlock,
                            gallery = self.attr('data-cbp-singlePage'),
                            blocks = [];
                        if (gallery) {
                            blocks = self.closest($('.cbp-item')).find('[data-cbp-singlePage="' + gallery + '"]');
                        } else {
                            t.cubeportfolio.blocksOn.each(function(index, el) {
                                var item = $(el);
                                if (item.not('.cbp-item-off')) {
                                    item.find(t.options.singlePageDelegate).each(function(index2, el2) {
                                        if (!$(el2).attr('data-cbp-singlePage')) {
                                            blocks.push(el2);
                                        }
                                    });
                                }
                            });
                        }
                        t.openSinglePage(blocks, currentBlock[0]);
                    } else if (links.length) { // @todo - hack to load items from loadMore
                        var fakeLink = document.createElement('a');
                        fakeLink.setAttribute('href', links[0]);
                        t.openSinglePage([fakeLink], fakeLink);
                    }
                }
            }
        },
        /**
         * Create markup, css and add events
         */
        createMarkup: function() {
            var t = this,
                animationCls = '';
            if (t.type === 'singlePage') {
                if (t.options.singlePageAnimation !== 'left') {
                    animationCls = ' cbp-popup-singlePage-' + t.options.singlePageAnimation;
                }
            }
            // wrap element
            t.wrap = $('', {
                'class': 'cbp-popup-wrap cbp-popup-' + t.type + animationCls,
                'data-action': (t.type === 'lightbox') ? 'close' : ''
            }).on('click.cbp', function(e) {
                if (t.stopEvents) {
                    return;
                }
                var action = $(e.target).attr('data-action');
                if (t[action]) {
                    t[action]();
                    e.preventDefault();
                }
            });
            // content element
            t.content = $('', {
                'class': 'cbp-popup-content'
            }).appendTo(t.wrap);
            // append loading div
            $('', {
                'class': 'cbp-popup-loadingBox'
            }).appendTo(t.wrap);
            // add background only for ie8
            if (CubePortfolio.Private.browser === 'ie8') {
                t.bg = $('', {
                    'class': 'cbp-popup-ie8bg',
                    'data-action': (t.type === 'lightbox') ? 'close' : ''
                }).appendTo(t.wrap);
            }
            // create navigation wrap
            t.navigationWrap = $('', {
                'class': 'cbp-popup-navigation-wrap'
            }).appendTo(t.wrap);
            // create navigation block
            t.navigation = $('', {
                'class': 'cbp-popup-navigation'
            }).appendTo(t.navigationWrap);
            // close
            t.closeButton = $('', {
                'class': 'cbp-popup-close',
                'title': 'Close (Esc arrow key)',
                'data-action': 'close'
            }).appendTo(t.navigation);
            // next
            t.nextButton = $('', {
                'class': 'cbp-popup-next',
                'title': 'Next (Right arrow key)',
                'data-action': 'next'
            }).appendTo(t.navigation);
            // prev
            t.prevButton = $('', {
                'class': 'cbp-popup-prev',
                'title': 'Previous (Left arrow key)',
                'data-action': 'prev'
            }).appendTo(t.navigation);
            if (t.type === 'singlePage') {
                if (t.options.singlePageCounter) {
                    // counter for singlePage
                    t.counter = $(t.options.singlePageCounter).appendTo(t.navigation);
                    t.counter.text('');
                }
                t.content.on('click.cbp', t.options.singlePageDelegate, function(e) {
                    e.preventDefault();
                    var i,
                        len = t.dataArray.length,
                        href = this.getAttribute('href');
                    for (i = 0; i < len; i++) {
                        if (t.dataArray[i].url === href) {
                            break;
                        }
                    }
                    t.singlePageJumpTo(i - t.current);
                });
                // if there are some events than overrides the default scroll behaviour don't go to them
                t.wrap.on('mousewheel.cbp' + ' DOMMouseScroll.cbp', function(e) {
                    e.stopImmediatePropagation();
                });
            }
            $(document).on('keydown.cbp', function(e) {
                // if is not open => return
                if (!t.isOpen) {
                    return;
                }
                // if all events are stopped => return
                if (t.stopEvents) {
                    return;
                }
                if (e.keyCode === 37) { // prev key
                    t.prev();
                } else if (e.keyCode === 39) { // next key
                    t.next();
                } else if (e.keyCode === 27) { //esc key
                    t.close();
                }
            });
        },
        createMarkupSinglePageInline: function() {
            var t = this;
            // wrap element
            t.wrap = $('', {
                'class': 'cbp-popup-singlePageInline'
            }).on('click.cbp', function(e) {
                if (t.stopEvents) {
                    return;
                }
                var action = $(e.target).attr('data-action');
                if (action && t[action]) {
                    t[action]();
                    e.preventDefault();
                }
            });
            // content element
            t.content = $('', {
                'class': 'cbp-popup-content'
            }).appendTo(t.wrap);
            // append loading div
            // $('', {
            //     'class': 'cbp-popup-loadingBox'
            // }).appendTo(t.wrap);
            // create navigation block
            t.navigation = $('', {
                'class': 'cbp-popup-navigation'
            }).appendTo(t.wrap);
            // close
            t.closeButton = $('', {
                'class': 'cbp-popup-close',
                'title': 'Close (Esc arrow key)',
                'data-action': 'close'
            }).appendTo(t.navigation);
        },
        destroy: function() {
            var t = this,
                body = $('body');
            // remove off key down
            $(document).off('keydown.cbp');
            // external lightbox and singlePageInline
            body.off('click.cbp', t.options.lightboxDelegate);
            body.off('click.cbp', t.options.singlePageDelegate);
            t.content.off('click.cbp', t.options.singlePageDelegate);
            t.cubeportfolio.$obj.off('click.cbp', t.options.singlePageInlineDelegate);
            t.cubeportfolio.$obj.off('click.cbp', t.options.lightboxDelegate);
            t.cubeportfolio.$obj.off('click.cbp', t.options.singlePageDelegate);
            t.cubeportfolio.$obj.removeClass('cbp-popup-isOpening');
            t.cubeportfolio.$obj.find('.cbp-item').removeClass('cbp-singlePageInline-active');
            t.wrap.remove();
        },
        openLightbox: function(blocks, currentBlock) {
            var t = this,
                i = 0,
                currentBlockHref, tempHref = [],
                element;
            if (t.isOpen) {
                return;
            }
            // remember that the lightbox is open now
            t.isOpen = true;
            // remember to stop all events after the lightbox has been shown
            t.stopEvents = false;
            // array with elements
            t.dataArray = [];
            // reset current
            t.current = null;
            currentBlockHref = currentBlock.getAttribute('href');
            if (currentBlockHref === null) {
                throw new Error('HEI! Your clicked element doesn\'t have a href attribute.');
            }
            $.each(blocks, function(index, item) {
                var href = item.getAttribute('href'),
                    src = href, // default if element is image
                    type = 'isImage', // default if element is image
                    videoLink;
                if ($.inArray(href, tempHref) === -1) {
                    if (currentBlockHref === href) {
                        t.current = i;
                    } else if (!t.options.lightboxGallery) {
                        return;
                    }
                    if (/youtube/i.test(href)) {
                        videoLink = href.substring(href.lastIndexOf('v=') + 2);
                        if (!(/autoplay=/i.test(videoLink))) {
                            videoLink += '&autoplay=1';
                        }
                        videoLink = videoLink.replace(/\?|&/, '?');
                        // create new href
                        src = '//www.youtube.com/embed/' + videoLink;
                        type = 'isYoutube';
                    } else if (/vimeo\.com/i.test(href)) {
                        videoLink = href.substring(href.lastIndexOf('/') + 1);
                        if (!(/autoplay=/i.test(videoLink))) {
                            videoLink += '&autoplay=1';
                        }
                        videoLink = videoLink.replace(/\?|&/, '?');
                        // create new href
                        src = '//player.vimeo.com/video/' + videoLink;
                        type = 'isVimeo';
                    } else if (/www\.ted\.com/i.test(href)) {
                        // create new href
                        src = 'http://embed.ted.com/talks/' + href.substring(href.lastIndexOf('/') + 1) + '.html';
                        type = 'isTed';
                    } else if (/soundcloud\.com/i.test(href)) {
                        // create new href
                        src = href;
                        type = 'isSoundCloud';
                    } else if (/(\.mp4)|(\.ogg)|(\.ogv)|(\.webm)/i.test(href)) {
                        if (href.indexOf('|') !== -1) {
                            // create new href
                            src = href.split('|');
                        } else {
                            // create new href
                            src = href.split('%7C');
                        }
                        type = 'isSelfHostedVideo';
                    } else if (/\.mp3$/i.test(href)) {
                        src = href;
                        type = 'isSelfHostedAudio';
                    }
                    t.dataArray.push({
                        src: src,
                        title: item.getAttribute(t.options.lightboxTitleSrc),
                        type: type
                    });
                    i++;
                }
                tempHref.push(href);
            });
            // total numbers of elements
            t.counterTotal = t.dataArray.length;
            if (t.counterTotal === 1) {
                t.nextButton.hide();
                t.prevButton.hide();
                t.dataActionImg = '';
            } else {
                t.nextButton.show();
                t.prevButton.show();
                t.dataActionImg = 'data-action="next"';
            }
            // append to body
            t.wrap.appendTo(document.body);
            t.scrollTop = $(window).scrollTop();
            t.originalStyle = $('html').attr('style');
            $('html').css({
                overflow: 'hidden',
                paddingRight: window.innerWidth - $(document).width()
            });
            // show the wrapper (lightbox box)
            t.wrap.show();
            // get the current element
            element = t.dataArray[t.current];
            // call function if current element is image or video (iframe)
            t[element.type](element);
        },
        openSinglePage: function(blocks, currentBlock) {
            var t = this,
                i = 0,
                currentBlockHref, tempHref = [];
            if (t.isOpen) {
                return;
            }
            // check singlePageInline and close it
            if (t.cubeportfolio.singlePageInline && t.cubeportfolio.singlePageInline.isOpen) {
                t.cubeportfolio.singlePageInline.close();
            }
            // remember that the lightbox is open now
            t.isOpen = true;
            // remember to stop all events after the popup has been showing
            t.stopEvents = false;
            // array with elements
            t.dataArray = [];
            // reset current
            t.current = null;
            currentBlockHref = currentBlock.getAttribute('href');
            if (currentBlockHref === null) {
                throw new Error('HEI! Your clicked element doesn\'t have a href attribute.');
            }
            $.each(blocks, function(index, item) {
                var href = item.getAttribute('href');
                if ($.inArray(href, tempHref) === -1) {
                    if (currentBlockHref === href) {
                        t.current = i;
                    }
                    t.dataArray.push({
                        url: href,
                        element: item
                    });
                    i++;
                }
                tempHref.push(href);
            });
            // total numbers of elements
            t.counterTotal = t.dataArray.length;
            if (t.counterTotal === 1) {
                t.nextButton.hide();
                t.prevButton.hide();
            } else {
                t.nextButton.show();
                t.prevButton.show();
            }
            // append to body
            t.wrap.appendTo(document.body);
            t.scrollTop = $(window).scrollTop();
            $('html').css({
                overflow: 'hidden',
                paddingRight: window.innerWidth - $(document).width()
            });
            // go to top of the page (reset scroll)
            t.wrap.scrollTop(0);
            // show the wrapper
            t.wrap.show();
            // finish the open animation
            t.finishOpen = 2;
            // if transitionend is not fulfilled
            t.navigationMobile = $();
            t.wrap.one(CubePortfolio.Private.transitionend, function() {
                var width;
                // make the navigation sticky
                if (t.options.singlePageStickyNavigation) {
                    t.wrap.addClass('cbp-popup-singlePage-sticky');
                    width = t.wrap[0].clientWidth;
                    t.navigationWrap.width(width);
                    if (CubePortfolio.Private.browser === 'android' || CubePortfolio.Private.browser === 'ios') {
                        // wrap element
                        t.navigationMobile = $('', {
                            'class': 'cbp-popup-singlePage cbp-popup-singlePage-sticky',
                            'id': t.wrap.attr('id')
                        }).on('click.cbp', function(e) {
                            if (t.stopEvents) {
                                return;
                            }
                            var action = $(e.target).attr('data-action');
                            if (t[action]) {
                                t[action]();
                                e.preventDefault();
                            }
                        });
                        t.navigationMobile.appendTo(document.body).append(t.navigationWrap);
                    }
                }
                t.finishOpen--;
                if (t.finishOpen <= 0) {
                    t.updateSinglePageIsOpen.call(t);
                }
            });
            if (CubePortfolio.Private.browser === 'ie8' || CubePortfolio.Private.browser === 'ie9') {
                // make the navigation sticky
                if (t.options.singlePageStickyNavigation) {
                    var width = t.wrap[0].clientWidth;
                    t.navigationWrap.width(width);
                    setTimeout(function() {
                        t.wrap.addClass('cbp-popup-singlePage-sticky');
                    }, 1000);
                }
                t.finishOpen--;
            }
            t.wrap.addClass('cbp-popup-loading');
            // force reflow and then add class
            t.wrap.offset();
            t.wrap.addClass('cbp-popup-singlePage-open');
            // change link
            if (t.options.singlePageDeeplinking) {
                // ignore old #cbp from href
                t.url = t.url.split('#cbp=')[0];
                location.href = t.url + '#cbp=' + t.dataArray[t.current].url;
            }
            // run callback function
            if ($.isFunction(t.options.singlePageCallback)) {
                t.options.singlePageCallback.call(t, t.dataArray[t.current].url, t.dataArray[t.current].element);
            }
        },
        openSinglePageInline: function(blocks, currentBlock, fromOpen) {
            var t = this,
                start = 0,
                currentBlockHref,
                tempCurrent,
                cbpitem,
                parentElement;
            fromOpen = fromOpen || false;
            t.fromOpen = fromOpen;
            t.storeBlocks = blocks;
            t.storeCurrentBlock = currentBlock;
            // check singlePageInline and close it
            if (t.isOpen) {
                tempCurrent = $(currentBlock).closest('.cbp-item').index();
                if ((t.dataArray[t.current].url !== currentBlock.getAttribute('href')) || (t.current !== tempCurrent)) {
                    t.cubeportfolio.singlePageInline.close('open', {
                        blocks: blocks,
                        currentBlock: currentBlock,
                        fromOpen: true
                    });
                } else {
                    t.close();
                }
                return;
            }
            // remember that the lightbox is open now
            t.isOpen = true;
            // remember to stop all events after the popup has been showing
            t.stopEvents = false;
            // array with elements
            t.dataArray = [];
            // reset current
            t.current = null;
            currentBlockHref = currentBlock.getAttribute('href');
            if (currentBlockHref === null) {
                throw new Error('HEI! Your clicked element doesn\'t have a href attribute.');
            }
            cbpitem = $(currentBlock).closest('.cbp-item')[0];
            blocks.each(function(index, el) {
                if (cbpitem === el) {
                    t.current = index;
                }
            });
            t.dataArray[t.current] = {
                url: currentBlockHref,
                element: currentBlock
            };
            parentElement = $(t.dataArray[t.current].element).parents('.cbp-item').addClass('cbp-singlePageInline-active');
            // total numbers of elements
            t.counterTotal = blocks.length;
            t.wrap.insertBefore(t.cubeportfolio.wrapper);
            if (t.options.singlePageInlinePosition === 'top') {
                t.startInline = 0;
                t.top = 0;
                t.firstRow = true;
                t.lastRow = false;
            } else if (t.options.singlePageInlinePosition === 'bottom') {
                t.startInline = t.counterTotal;
                t.top = t.cubeportfolio.height;
                t.firstRow = false;
                t.lastRow = true;
            } else if (t.options.singlePageInlinePosition === 'above') {
                t.startInline = t.cubeportfolio.cols * Math.floor(t.current / t.cubeportfolio.cols);
                t.top = $(blocks[t.current]).data('cbp').top;
                if (t.startInline === 0) {
                    t.firstRow = true;
                } else {
                    t.top -= t.options.gapHorizontal;
                    t.firstRow = false;
                }
                t.lastRow = false;
            } else { // below
                t.top = $(blocks[t.current]).data('cbp').top + $(blocks[t.current]).data('cbp').height;
                t.startInline = Math.min(t.cubeportfolio.cols *
                    (Math.floor(t.current / t.cubeportfolio.cols) + 1),
                    t.counterTotal);
                t.firstRow = false;
                t.lastRow = (t.startInline === t.counterTotal) ? true : false;
            }
            t.wrap[0].style.height = t.wrap.outerHeight(true) + 'px';
            // debouncer for inline content
            t.deferredInline = $.Deferred();
            if (t.options.singlePageInlineInFocus) {
                t.scrollTop = $(window).scrollTop();
                var goToScroll = t.cubeportfolio.$obj.offset().top + t.top - 100;
                if (t.scrollTop !== goToScroll) {
                    $('html,body').animate({
                            scrollTop: goToScroll
                        }, 350)
                        .promise()
                        .then(function() {
                            t.resizeSinglePageInline();
                            t.deferredInline.resolve();
                        });
                } else {
                    t.resizeSinglePageInline();
                    t.deferredInline.resolve();
                }
            } else {
                t.resizeSinglePageInline();
                t.deferredInline.resolve();
            }
            t.cubeportfolio.$obj.addClass('cbp-popup-singlePageInline-open');
            t.wrap.css({
                top: t.top
            });
            // register callback function
            if ($.isFunction(t.options.singlePageInlineCallback)) {
                t.options.singlePageInlineCallback.call(t, t.dataArray[t.current].url, t.dataArray[t.current].element);
            }
        },
        resizeSinglePageInline: function() {
            var t = this;
            t.height = (t.firstRow || t.lastRow) ? t.wrap.outerHeight(true) : t.wrap.outerHeight(true) - t.options.gapHorizontal;
            t.storeBlocks.each(function(index, el) {
                if (index < t.startInline) {
                    if (CubePortfolio.Private.modernBrowser) {
                        el.style[CubePortfolio.Private.transform] = '';
                    } else {
                        el.style.marginTop = '';
                    }
                } else {
                    if (CubePortfolio.Private.modernBrowser) {
                        el.style[CubePortfolio.Private.transform] = 'translate3d(0px, ' + t.height + 'px, 0)';
                    } else {
                        el.style.marginTop = t.height + 'px';
                    }
                }
            });
            t.cubeportfolio.obj.style.height = t.cubeportfolio.height + t.height + 'px';
        },
        revertResizeSinglePageInline: function() {
            var t = this;
            // reset deferred object
            t.deferredInline = $.Deferred();
            t.storeBlocks.each(function(index, el) {
                if (CubePortfolio.Private.modernBrowser) {
                    el.style[CubePortfolio.Private.transform] = '';
                } else {
                    el.style.marginTop = '';
                }
            });
            t.cubeportfolio.obj.style.height = t.cubeportfolio.height + 'px';
        },
        appendScriptsToWrap: function(scripts) {
            var t = this,
                index = 0,
                loadScripts = function(item) {
                    var script = document.createElement('script'),
                        src = item.src;
                    script.type = 'text/javascript';
                    if (script.readyState) { // ie
                        script.onreadystatechange = function() {
                            if (script.readyState == 'loaded' || script.readyState == 'complete') {
                                script.onreadystatechange = null;
                                index++;
                                if (scripts[index]) {
                                    loadScripts(scripts[index]);
                                }
                            }
                        };
                    } else {
                        script.onload = function() {
                            index++;
                            if (scripts[index]) {
                                loadScripts(scripts[index]);
                            }
                        };
                    }
                    if (src) {
                        script.src = src;
                    } else {
                        script.text = item.text;
                    }
                    t.content[0].appendChild(script);
                };
            loadScripts(scripts[0]);
        },
        updateSinglePage: function(html, scripts, isWrap) {
            var t = this,
                counterMarkup,
                animationFinish;
            t.content.addClass('cbp-popup-content').removeClass('cbp-popup-content-basic');
            if (isWrap === false) {
                t.content.removeClass('cbp-popup-content').addClass('cbp-popup-content-basic');
            }
            // update counter navigation
            if (t.counter) {
                counterMarkup = $(t.getCounterMarkup(t.options.singlePageCounter, t.current + 1, t.counterTotal));
                t.counter.text(counterMarkup.text());
            }
            t.content.html(html);
            if (scripts) {
                t.appendScriptsToWrap(scripts);
            }
            // trigger public event
            t.cubeportfolio.$obj.trigger('updateSinglePageStart.cbp');
            t.finishOpen--;
            if (t.finishOpen <= 0) {
                t.updateSinglePageIsOpen.call(t);
            }
        },
        updateSinglePageIsOpen: function() {
            var t = this,
                selectorSlider;
            t.wrap.addClass('cbp-popup-ready');
            t.wrap.removeClass('cbp-popup-loading');
            // instantiate slider if exists
            selectorSlider = t.content.find('.cbp-slider');
            if (selectorSlider) {
                selectorSlider.find('.cbp-slider-item').addClass('cbp-item');
                t.slider = selectorSlider.cubeportfolio({
                    layoutMode: 'slider',
                    mediaQueries: [{
                        width: 1,
                        cols: 1
                    }],
                    gapHorizontal: 0,
                    gapVertical: 0,
                    caption: '',
                    coverRatio: '', // wp version only
                });
            } else {
                t.slider = null;
            }
            // scroll bug on android and ios
            if (CubePortfolio.Private.browser === 'android' || CubePortfolio.Private.browser === 'ios') {
                $('html').css({
                    position: 'fixed'
                });
            }
            // trigger public event
            t.cubeportfolio.$obj.trigger('updateSinglePageComplete.cbp');
        },
        updateSinglePageInline: function(html, scripts) {
            var t = this;
            t.content.html(html);
            if (scripts) {
                t.appendScriptsToWrap(scripts);
            }
            // trigger public event
            t.cubeportfolio.$obj.trigger('updateSinglePageInlineStart.cbp');
            t.singlePageInlineIsOpen.call(t);
        },
        singlePageInlineIsOpen: function() {
            var t = this;
            function finishLoading() {
                t.wrap.addClass('cbp-popup-singlePageInline-ready');
                t.wrap[0].style.height = '';
                t.resizeSinglePageInline();
                // trigger public event
                t.cubeportfolio.$obj.trigger('updateSinglePageInlineComplete.cbp');
            }
            // wait to load all images
            t.cubeportfolio.loadImages(t.wrap, function() {
                // instantiate slider if exists
                var selectorSlider = t.content.find('.cbp-slider');
                if (selectorSlider.length) {
                    selectorSlider.find('.cbp-slider-item').addClass('cbp-item');
                    selectorSlider.one('initComplete.cbp', function() {
                        t.deferredInline.done(finishLoading);
                    });
                    selectorSlider.on('pluginResize.cbp', function() {
                        t.deferredInline.done(finishLoading);
                    });
                    t.slider = selectorSlider.cubeportfolio({
                        layoutMode: 'slider',
                        displayType: 'default',
                        mediaQueries: [{
                            width: 1,
                            cols: 1
                        }],
                        gapHorizontal: 0,
                        gapVertical: 0,
                        caption: '',
                        coverRatio: '', // wp version only
                    });
                } else {
                    t.slider = null;
                    t.deferredInline.done(finishLoading);
                }
            });
        },
        isImage: function(el) {
            var t = this,
                img = new Image();
            t.tooggleLoading(true);
            t.cubeportfolio.loadImages($('