PageSourceSearch

https://www.festivalofbritisheventing.com/wp-content/themes/jupite…/js/core-scripts.6.1.1.js?ver=1593079140

js festivalofbritisheventing.com collected 2026-10-05 07:07:00 UTC 452,228 bytes, 13,587 lines download raw bytes

1(function($) {// v5 namespace 
2var MK = {
3	api 		: {},
4	ui 			: {},
5	component 	: {},
6};
7
8// Global 
9window.MK = MK;
10'use strict';
11
12
13console.log( 23423 );
14/**
15 * Copyright Marc J. Schmidt. See the LICENSE file at the top-level
16 * directory of this distribution and at
17 * https://github.com/marcj/css-element-queries/blob/master/LICENSE.
18 */
19(function (root, factory) {
20    if (typeof define === "function" && define.amd) {
21        define(factory);
22    } else if (typeof exports === "object") {
23        module.exports = factory();
24    } else {
25        root.ResizeSensor = factory();
26    }
27}(typeof window !== 'undefined' ? window : this, function () {
28
29    // Make sure it does not throw in a SSR (Server Side Rendering) situation
30    if (typeof window === "undefined") {
31        return null;
32    }
33    // Only used for the dirty checking, so the event callback count is limited to max 1 call per fps per sensor.
34    // In combination with the event based resize sensor this saves cpu time, because the sensor is too fast and
35    // would generate too many unnecessary events.
36    var requestAnimationFrame = window.requestAnimationFrame ||
37        window.mozRequestAnimationFrame ||
38        window.webkitRequestAnimationFrame ||
39        function (fn) {
40            return window.setTimeout(fn, 20);
41        };
42
43    /**
44     * Iterate over each of the provided element(s).
45     *
46     * @param {HTMLElement|HTMLElement[]} elements
47     * @param {Function}                  callback
48     */
49    function forEachElement(elements, callback){
50        var elementsType = Object.prototype.toString.call(elements);
51        var isCollectionTyped = ('[object Array]' === elementsType
52            || ('[object NodeList]' === elementsType)
53            || ('[object HTMLCollection]' === elementsType)
54            || ('[object Object]' === elementsType)
55            || ('undefined' !== typeof jQuery && elements instanceof jQuery) //jquery
56            || ('undefined' !== typeof Elements && elements instanceof Elements) //mootools
57        );
58        var i = 0, j = elements.length;
59        if (isCollectionTyped) {
60            for (; i < j; i++) {
61                callback(elements[i]);
62            }
63        } else {
64            callback(elements);
65        }
66    }
67
68    /**
69    * Get element size
70    * @param {HTMLElement} element
71    * @returns {Object} {width, height}
72    */
73    function getElementSize(element) {
74        if (!element.getBoundingClientRect) {
75            return {
76                width: element.offsetWidth,
77                height: element.offsetHeight
78            }
79        }
80
81        var rect = element.getBoundingClientRect();
82        return {
83            width: Math.round(rect.width),
84            height: Math.round(rect.height)
85        }
86    }
87
88    /**
89     * Class for dimension change detection.
90     *
91     * @param {Element|Element[]|Elements|jQuery} element
92     * @param {Function} callback
93     *
94     * @constructor
95     */
96    var ResizeSensor = function(element, callback) {
97        /**
98         *
99         * @constructor
100         */
101        function EventQueue() {
102            var q = [];
103            this.add = function(ev) {
104                q.push(ev);
105            };
106
107            var i, j;
108            this.call = function() {
109                for (i = 0, j = q.length; i < j; i++) {
110                    q[i].call();
111                }
112            };
113
114            this.remove = function(ev) {
115                var newQueue = [];
116                for(i = 0, j = q.length; i < j; i++) {
117                    if(q[i] !== ev) newQueue.push(q[i]);
118                }
119                q = newQueue;
120            };
121
122            this.length = function() {
123                return q.length;
124            }
125        }
126
127        /**
128         *
129         * @param {HTMLElement} element
130         * @param {Function}    resized
131         */
132        function attachResizeEvent(element, resized) {
133            if (!element) return;
134            if (element.resizedAttached) {
135                element.resizedAttached.add(resized);
136                return;
137            }
138
139            element.resizedAttached = new EventQueue();
140            element.resizedAttached.add(resized);
141
142            element.resizeSensor = document.createElement('div');
143            element.resizeSensor.dir = 'ltr';
144            element.resizeSensor.className = 'resize-sensor';
145            var style = 'position: absolute; left: -10px; top: -10px; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;';
146            var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;';
147
148            element.resizeSensor.style.cssText = style;
149            element.resizeSensor.innerHTML =
150                '<div class="resize-sensor-expand" style="' + style + '">' +
151                    '<div style="' + styleChild + '"></div>' +
152                '</div>' +
153                '<div class="resize-sensor-shrink" style="' + style + '">' +
154                    '<div style="' + styleChild + ' width: 200%; height: 200%"></div>' +
155                '</div>';
156            element.appendChild(element.resizeSensor);
157
158            var position = window.getComputedStyle(element).getPropertyPriority('position');
159            if ('absolute' !== position && 'relative' !== position && 'fixed' !== position) {
160                element.style.position = 'relative';
161            }
162
163            var expand = element.resizeSensor.childNodes[0];
164            var expandChild = expand.childNodes[0];
165            var shrink = element.resizeSensor.childNodes[1];
166            var dirty, rafId, newWidth, newHeight;
167            var size = getElementSize(element);
168            var lastWidth = size.width;
169            var lastHeight = size.height;
170
171            var reset = function() {
172                //set display to block, necessary otherwise hidden elements won't ever work
173                var invisible = element.offsetWidth === 0 && element.offsetHeight === 0;
174
175                if (invisible) {
176                    var saveDisplay = element.style.display;
177                    element.style.display = 'block';
178                }
179
180                expandChild.style.width = '100000px';
181                expandChild.style.height = '100000px';
182
183                expand.scrollLeft = 100000;
184                expand.scrollTop = 100000;
185
186                shrink.scrollLeft = 100000;
187                shrink.scrollTop = 100000;
188
189                if (invisible) {
190                    element.style.display = saveDisplay;
191                }
192            };
193            element.resizeSensor.resetSensor = reset;
194
195            var onResized = function() {
196                rafId = 0;
197
198                if (!dirty) return;
199
200                lastWidth = newWidth;
201                lastHeight = newHeight;
202
203                if (element.resizedAttached) {
204                    element.resizedAttached.call();
205                }
206            };
207
208            var onScroll = function() {
209                var size = getElementSize(element);
210                var newWidth = size.width;
211                var newHeight = size.height;
212                dirty = newWidth != lastWidth || newHeight != lastHeight;
213
214                if (dirty && !rafId) {
215                    rafId = requestAnimationFrame(onResized);
216                }
217
218                reset();
219            };
220
221            var addEvent = function(el, name, cb) {
222                if (el.attachEvent) {
223                    el.attachEvent('on' + name, cb);
224                } else {
225                    el.addEventListener(name, cb);
226                }
227            };
228
229            addEvent(expand, 'scroll', onScroll);
230            addEvent(shrink, 'scroll', onScroll);
231
232			// Fix for custom Elements
233			requestAnimationFrame(reset);
234        }
235
236        forEachElement(element, function(elem){
237            attachResizeEvent(elem, callback);
238        });
239
240        this.detach = function(ev) {
241            ResizeSensor.detach(element, ev);
242        };
243
244        this.reset = function() {
245            element.resizeSensor.resetSensor();
246        };
247    };
248
249    ResizeSensor.reset = function(element, ev) {
250        forEachElement(element, function(elem){
251            elem.resizeSensor.resetSensor();
252        });
253    };
254
255    ResizeSensor.detach = function(element, ev) {
256        forEachElement(element, function(elem){
257            if (!elem) return;
258            if(elem.resizedAttached && typeof ev === "function"){
259                elem.resizedAttached.remove(ev);
260                if(elem.resizedAttached.length()) return;
261            }
262            if (elem.resizeSensor) {
263                if (elem.contains(elem.resizeSensor)) {
264                    elem.removeChild(elem.resizeSensor);
265                }
266                delete elem.resizeSensor;
267                delete elem.resizedAttached;
268            }
269        });
270    };
271
272    return ResizeSensor;
273
274}));
275
276'use strict';
277
278/**
279 * Copyright Marc J. Schmidt. See the LICENSE file at the top-level
280 * directory of this distribution and at
281 * https://github.com/marcj/css-element-queries/blob/master/LICENSE.
282 */
283(function (root, factory) {
284    if (typeof define === "function" && define.amd) {
285        define(['./ResizeSensor.js'], factory);
286    } else if (typeof exports === "object") {
287        module.exports = factory(require('./ResizeSensor.js'));
288    } else {
289        root.ElementQueries = factory(root.ResizeSensor);
290        root.ElementQueries.listen();
291    }
292}(typeof window !== 'undefined' ? window : this, function (ResizeSensor) {
293
294    /**
295     *
296     * @type {Function}
297     * @constructor
298     */
299    var ElementQueries = function () {
300        //<style> element with our dynamically created styles
301        var cssStyleElement;
302
303        //all rules found for element queries
304        var allQueries = {};
305
306        //association map to identify which selector belongs to a element from the animationstart event.
307        var idToSelectorMapping = [];
308
309        /**
310         *
311         * @param element
312         * @returns {Number}
313         */
314        function getEmSize(element) {
315            if (!element) {
316                element = document.documentElement;
317            }
318            var fontSize = window.getComputedStyle(element, null).fontSize;
319            return parseFloat(fontSize) || 16;
320        }
321
322        /**
323         * Get element size
324         * @param {HTMLElement} element
325         * @returns {Object} {width, height}
326         */
327        function getElementSize(element) {
328            if (!element.getBoundingClientRect) {
329                return {
330                    width: element.offsetWidth,
331                    height: element.offsetHeight
332                }
333            }
334
335            var rect = element.getBoundingClientRect();
336            return {
337                width: Math.round(rect.width),
338                height: Math.round(rect.height)
339            }
340        }
341
342        /**
343         *
344         * @copyright https://github.com/Mr0grog/element-query/blob/master/LICENSE
345         *
346         * @param {HTMLElement} element
347         * @param {*} value
348         * @returns {*}
349         */
350        function convertToPx(element, value) {
351            var numbers = value.split(/\d/);
352            var units = numbers[numbers.length - 1];
353            value = parseFloat(value);
354            switch (units) {
355                case "px":
356                    return value;
357                case "em":
358                    return value * getEmSize(element);
359                case "rem":
360                    return value * getEmSize();
361                // Viewport units!
362                // According to http://quirksmode.org/mobile/tableViewport.html
363                // documentElement.clientWidth/Height gets us the most reliable info
364                case "vw":
365                    return value * document.documentElement.clientWidth / 100;
366                case "vh":
367                    return value * document.documentElement.clientHeight / 100;
368                case "vmin":
369                case "vmax":
370                    var vw = document.documentElement.clientWidth / 100;
371                    var vh = document.documentElement.clientHeight / 100;
372                    var chooser = Math[units === "vmin" ? "min" : "max"];
373                    return value * chooser(vw, vh);
374                default:
375                    return value;
376                // for now, not supporting physical units (since they are just a set number of px)
377                // or ex/ch (getting accurate measurements is hard)
378            }
379        }
380
381        /**
382         *
383         * @param {HTMLElement} element
384         * @param {String} id
385         * @constructor
386         */
387        function SetupInformation(element, id) {
388            this.element = element;
389            var key, option, elementSize, value, actualValue, attrValues, attrValue, attrName;
390
391            var attributes = ['min-width', 'min-height', 'max-width', 'max-height'];
392
393            /**
394             * Extracts the computed width/height and sets to min/max- attribute.
395             */
396            this.call = function () {
397                // extract current dimensions
398                elementSize = getElementSize(this.element);
399
400                attrValues = {};
401
402                for (key in allQueries[id]) {
403                    if (!allQueries[id].hasOwnProperty(key)) {
404                        continue;
405                    }
406                    option = allQueries[id][key];
407
408                    value = convertToPx(this.element, option.value);
409
410                    actualValue = option.property === 'width' ? elementSize.width : elementSize.height;
411                    attrName = option.mode + '-' + option.property;
412                    attrValue = '';
413
414                    if (option.mode === 'min' && actualValue >= value) {
415                        attrValue += option.value;
416                    }
417
418                    if (option.mode === 'max' && actualValue <= value) {
419                        attrValue += option.value;
420                    }
421
422                    if (!attrValues[attrName]) attrValues[attrName] = '';
423                    if (attrValue && -1 === (' ' + attrValues[attrName] + ' ').indexOf(' ' + attrValue + ' ')) {
424                        attrValues[attrName] += ' ' + attrValue;
425                    }
426                }
427
428                for (var k in attributes) {
429                    if (!attributes.hasOwnProperty(k)) continue;
430
431                    if (attrValues[attributes[k]]) {
432                        this.element.setAttribute(attributes[k], attrValues[attributes[k]].substr(1));
433                    } else {
434                        this.element.removeAttribute(attributes[k]);
435                    }
436                }
437            };
438        }
439
440        /**
441         * @param {HTMLElement} element
442         * @param {Object}      id
443         */
444        function setupElement(element, id) {
445            if (!element.elementQueriesSetupInformation) {
446                element.elementQueriesSetupInformation = new SetupInformation(element, id);
447            }
448            if (!element.elementQueriesSensor) {
449                element.elementQueriesSensor = new ResizeSensor(element, function () {
450                    element.elementQueriesSetupInformation.call();
451                });
452            }
453
454            element.elementQueriesSetupInformation.call();
455        }
456
457        /**
458         * Stores rules to the selector that should be applied once resized.
459         *
460         * @param {String} selector
461         * @param {String} mode min|max
462         * @param {String} property width|height
463         * @param {String} value
464         */
465        function queueQuery(selector, mode, property, value) {
466            if (typeof(allQueries[selector]) === 'undefined') {
467                allQueries[selector] = [];
468                // add animation to trigger animationstart event, so we know exactly when a element appears in the DOM
469
470                var id = idToSelectorMapping.length;
471                cssStyleElement.innerHTML += '\n' + selector + ' {animation: 0.1s element-queries;}';
472                cssStyleElement.innerHTML += '\n' + selector + ' > .resize-sensor {min-width: '+id+'px;}';
473                idToSelectorMapping.push(selector);
474            }
475
476            allQueries[selector].push({
477                mode: mode,
478                property: property,
479                value: value
480            });
481        }
482
483        function getQuery(container) {
484            var query;
485            if (document.querySelectorAll) query = (container) ? container.querySelectorAll.bind(container) : document.querySelectorAll.bind(document);
486            if (!query && 'undefined' !== typeof $$) query = $$;
487            if (!query && 'undefined' !== typeof jQuery) query = jQuery;
488
489            if (!query) {
490                throw 'No document.querySelectorAll, jQuery or Mootools\'s $$ found.';
491            }
492
493            return query;
494        }
495
496        /**
497         * If animationStart didn't catch a new element in the DOM, we can manually search for it
498         */
499        function findElementQueriesElements(container) {
500            var query = getQuery(container);
501
502            for (var selector in allQueries) if (allQueries.hasOwnProperty(mode)) {
503                // find all elements based on the extract query selector from the element query rule
504                var elements = query(selector, container);
505
506                for (var i = 0, j = elements.length; i < j; i++) {
507                    setupElement(elements[i], selector);
508                }
509            }
510        }
511
512        /**
513         *
514         * @param {HTMLElement} element
515         */
516        function attachResponsiveImage(element) {
517            var children = [];
518            var rules = [];
519            var sources = [];
520            var defaultImageId = 0;
521            var lastActiveImage = -1;
522            var loadedImages = [];
523
524            for (var i in element.children) {
525                if (!element.children.hasOwnProperty(i)) continue;
526
527                if (element.children[i].tagName && element.children[i].tagName.toLowerCase() === 'img') {
528                    children.push(element.children[i]);
529
530                    var minWidth = element.children[i].getAttribute('min-width') || element.children[i].getAttribute('data-min-width');
531                    //var minHeight = element.children[i].getAttribute('min-height') || element.children[i].getAttribute('data-min-height');
532                    var src = element.children[i].getAttribute('data-src') || element.children[i].getAttribute('url');
533
534                    sources.push(src);
535
536                    var rule = {
537                        minWidth: minWidth
538                    };
539
540                    rules.push(rule);
541
542                    if (!minWidth) {
543                        defaultImageId = children.length - 1;
544                        element.children[i].style.display = 'block';
545                    } else {
546                        element.children[i].style.display = 'none';
547                    }
548                }
549            }
550
551            lastActiveImage = defaultImageId;
552
553            function check() {
554                var imageToDisplay = false, i;
555
556                for (i in children) {
557                    if (!children.hasOwnProperty(i)) continue;
558
559                    if (rules[i].minWidth) {
560                        if (element.offsetWidth > rules[i].minWidth) {
561                            imageToDisplay = i;
562                        }
563                    }
564                }
565
566                if (!imageToDisplay) {
567                    //no rule matched, show default
568                    imageToDisplay = defaultImageId;
569                }
570
571                if (lastActiveImage !== imageToDisplay) {
572                    //image change
573
574                    if (!loadedImages[imageToDisplay]) {
575                        //image has not been loaded yet, we need to load the image first in memory to prevent flash of
576                        //no content
577
578                        var image = new Image();
579                        image.onload = function () {
580                            children[imageToDisplay].src = sources[imageToDisplay];
581
582                            children[lastActiveImage].style.display = 'none';
583                            children[imageToDisplay].style.display = 'block';
584
585                            loadedImages[imageToDisplay] = true;
586
587                            lastActiveImage = imageToDisplay;
588                        };
589
590                        image.src = sources[imageToDisplay];
591                    } else {
592                        children[lastActiveImage].style.display = 'none';
593                        children[imageToDisplay].style.display = 'block';
594                        lastActiveImage = imageToDisplay;
595                    }
596                } else {
597                    //make sure for initial check call the .src is set correctly
598                    children[imageToDisplay].src = sources[imageToDisplay];
599                }
600            }
601
602            element.resizeSensor = new ResizeSensor(element, check);
603            check();
604        }
605
606        function findResponsiveImages() {
607            var query = getQuery();
608
609            var elements = query('[data-responsive-image],[responsive-image]');
610            for (var i = 0, j = elements.length; i < j; i++) {
611                attachResponsiveImage(elements[i]);
612            }
613        }
614
615        var regex = /,?[\s\t]*([^,\n]*?)((?:\[[\s\t]*?(?:min|max)-(?:width|height)[\s\t]*?[~$\^]?=[\s\t]*?"[^"]*?"[\s\t]*?])+)([^,\n\s\{]*)/mg
615i;
616        var attrRegex = /\[[\s\t]*?(min|max)-(width|height)[\s\t]*?[~$\^]?=[\s\t]*?"([^"]*?)"[\s\t]*?]/mgi;
617
618        /**
619         * @param {String} css
620         */
621        function extractQuery(css) {
622            var match, smatch, attrs, attrMatch;
623
624            css = css.replace(/'/g, '"');
625            while (null !== (match = regex.exec(css))) {
626                smatch = match[1] + match[3];
627                attrs = match[2];
628
629                while (null !== (attrMatch = attrRegex.exec(attrs))) {
630                    queueQuery(smatch, attrMatch[1], attrMatch[2], attrMatch[3]);
631                }
632            }
633        }
634
635        /**
636         * @param {CssRule[]|String} rules
637         */
638        function readRules(rules) {
639            var selector = '';
640
641            if (!rules) {
642                return;
643            }
644
645            if ('string' === typeof rules) {
646                rules = rules.toLowerCase();
647                if (-1 !== rules.indexOf('min-width') || -1 !== rules.indexOf('max-width')) {
648                    extractQuery(rules);
649                }
650            } else {
651                for (var i = 0, j = rules.length; i < j; i++) {
652                    if (1 === rules[i].type) {
653                        selector = rules[i].selectorText || rules[i].cssText;
654                        if (-1 !== selector.indexOf('min-height') || -1 !== selector.indexOf('max-height')) {
655                            extractQuery(selector);
656                        } else if (-1 !== selector.indexOf('min-width') || -1 !== selector.indexOf('max-width')) {
657                            extractQuery(selector);
658                        }
659                    } else if (4 === rules[i].type) {
660                        readRules(rules[i].cssRules || rules[i].rules);
661                    } else if (3 === rules[i].type) {
662                        readRules(rules[i].styleSheet.cssRules);
663                    }
664                }
665            }
666        }
667
668        var defaultCssInjected = false;
669
670        /**
671         * Searches all css rules and setups the event listener to all elements with element query rules..
672         */
673        this.init = function () {
674            var animationStart = 'animationstart';
675            if (typeof document.documentElement.style['webkitAnimationName'] !== 'undefined') {
676                animationStart = 'webkitAnimationStart';
677            } else if (typeof document.documentElement.style['MozAnimationName'] !== 'undefined') {
678                animationStart = 'mozanimationstart';
679            } else if (typeof document.documentElement.style['OAnimationName'] !== 'undefined') {
680                animationStart = 'oanimationstart';
681            }
682
683            document.body.addEventListener(animationStart, function (e) {
684                var element = e.target;
685                var styles = window.getComputedStyle(element, null);
686
687                if (-1 !== styles.getPropertyValue('animation-name').indexOf('element-queries')) {
688                    element.elementQueriesSensor = new ResizeSensor(element, function () {
689                        if (element.elementQueriesSetupInformation) {
690                            element.elementQueriesSetupInformation.call();
691                        }
692                    });
693
694                    var sensorStyles = window.getComputedStyle(element.resizeSensor, null);
695                    var id = sensorStyles.getPropertyValue('min-width');
696                    id = parseInt(id.replace('px', ''));
697                    setupElement(e.target, idToSelectorMapping[id]);
698                }
699            });
700
701            if (!defaultCssInjected) {
702                cssStyleElement = document.createElement('style');
703                cssStyleElement.type = 'text/css';
704                cssStyleElement.innerHTML = '[responsive-image] > img, [data-responsive-image] {overflow: hidden; padding: 0; } [responsive-image] > img, [data-responsive-image] > img {width: 100%;}';
705
706                //safari wants at least one rule in keyframes to start working
707                cssStyleElement.innerHTML += '\n@keyframes element-queries { 0% { visibility: inherit; } }';
708                document.getElementsByTagName('head')[0].appendChild(cssStyleElement);
709                defaultCssInjected = true;
710            }
711
712            for (var i = 0, j = document.styleSheets.length; i < j; i++) {
713                try {
714                    if (document.styleSheets[i].href && 0 === document.styleSheets[i].href.indexOf('file://')) {
715                        console.log("CssElementQueries: unable to parse local css files, " + document.styleSheets[i].href);
716                    }
717
718                    readRules(document.styleSheets[i].cssRules || document.styleSheets[i].rules || document.styleSheets[i].cssText);
719                } catch (e) {
720                }
721            }
722
723            // findElementQueriesElements();
724            findResponsiveImages();
725        };
726
727        /**
728         * Go through all collected rules (readRules()) and attach the resize-listener.
729         * Not necessary to call it manually, since we detect automatically when new elements
730         * are available in the DOM. However, sometimes handy for dirty DOM modifications.
731         *
732         * @param {HTMLElement} container only elements of the container are considered (document.body if not set)
733         */
734        this.findElementQueriesElements = function (container) {
735            findElementQueriesElements(container);
736        };
737
738        this.update = function () {
739            this.init();
740        };
741    };
742
743    ElementQueries.update = function () {
744        ElementQueries.instance.update();
745    };
746
747    /**
748     * Removes all sensor and elementquery information from the element.
749     *
750     * @param {HTMLElement} element
751     */
752    ElementQueries.detach = function (element) {
753        if (element.elementQueriesSetupInformation) {
754            //element queries
755            element.elementQueriesSensor.detach();
756            delete element.elementQueriesSetupInformation;
757            delete element.elementQueriesSensor;
758
759        } else if (element.resizeSensor) {
760            //responsive image
761
762            element.resizeSensor.detach();
763            delete element.resizeSensor;
764        }
765    };
766
767    ElementQueries.init = function () {
768        if (!ElementQueries.instance) {
769            ElementQueries.instance = new ElementQueries();
770        }
771
772        ElementQueries.instance.init();
773    };
774
775    var domLoaded = function (callback) {
776        /* Mozilla, Chrome, Opera */
777        if (document.addEventListener) {
778            document.addEventListener('DOMContentLoaded', callback, false);
779        }
780        /* Safari, iCab, Konqueror */
781        else if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
782            var DOMLoadTimer = setInterval(function () {
783                if (/loaded|complete/i.test(document.readyState)) {
784                    callback();
785                    clearInterval(DOMLoadTimer);
786                }
787            }, 10);
788        }
789        /* Other web browsers */
790        else window.onload = callback;
791    };
792
793    ElementQueries.findElementQueriesElements = function (container) {
794        ElementQueries.instance.findElementQueriesElements(container);
795    };
796
797    ElementQueries.listen = function () {
798        domLoaded(ElementQueries.init);
799    };
800
801    return ElementQueries;
802
803}));
804
805(function($) {
806	'use strict';
807
808	$.exists = function(selector) {
809	    return ($(selector).length > 0);
810	};
811
812	/**
813	 * Helper to enable caching async scripts
814	 * https://api.jquery.com/jquery.getscript/
815	 * http://www.vrdmn.com/2013/07/overriding-jquerygetscript-to-include.html
816	 * 
817	 * @param  {String}   script url
818	 * @param  {Function} callback     
819	 */
820	$.getCachedScript = function( url ) {
821		var options = {
822			dataType: "script",
823			cache: true,
824			url: url
825		};
826	 
827	    // Use $.ajax() since it is more flexible than $.getScript
828	    // Return the jqXHR object so we can chain callbacks
829	  	return $.ajax( options );
830	};
831
832
833
834	// Fn to allow an event to fire after all images are loaded
835	// usage:
836	// $.ajax({
837	//     cache: false,
838	//     url: 'ajax/content.php',
839	//     success: function(data) {
840	//         $('#divajax').html(data).imagesLoaded().then(function(){
841	//             // do stuff after images are loaded here
842	//         });
843	//     }
844	// });
845	$.fn.mk_imagesLoaded = function () {
846
847	    // Edit: in strict mode, the var keyword is needed
848	    var $imgs = this.find('img[src!=""]');
849	    // if there's no images, just return an already resolved promise
850	    if (!$imgs.length) {return $.Deferred().resolve().promise();}
851
852	    // for each image, add a deferred object to the array which resolves when the image is loaded (or if loading fails)
853	    var dfds = [];  
854	    $imgs.each(function(){
855	        var dfd = $.Deferred();
856	        dfds.push(dfd);
857	        var img = new Image();
858	        img.onload = function(){dfd.resolve();};
859	        img.onerror = function(){dfd.resolve();};
860	        img.src = this.src;
861	    });
862
863	    // return a master promise object which will resolve when all the deferred objects have resolved
864	    // IE - when all the images are loaded
865	    return $.when.apply($,dfds);
866
867	};
868
869}(jQuery));
870/**
871* Detect Element Resize
872*
873* https://github.com/sdecima/javascript-detect-element-resize
874* Sebastian Decima
875*
876* version: 0.5.3
877**/
878
879(function () {
880	var attachEvent = document.attachEvent,
881		stylesCreated = false;
882	
883	if (!attachEvent) {
884		var requestFrame = (function(){
885			var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
886								function(fn){ return window.setTimeout(fn, 20); };
887			return function(fn){ return raf(fn); };
888		})();
889		
890		var cancelFrame = (function(){
891			var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
892								   window.clearTimeout;
893		  return function(id){ return cancel(id); };
894		})();
895
896		function resetTriggers(element){
897			var triggers = element.__resizeTriggers__,
898				expand = triggers.firstElementChild,
899				contract = triggers.lastElementChild,
900				expandChild = expand.firstElementChild;
901			contract.scrollLeft = contract.scrollWidth;
902			contract.scrollTop = contract.scrollHeight;
903			expandChild.style.width = expand.offsetWidth + 1 + 'px';
904			expandChild.style.height = expand.offsetHeight + 1 + 'px';
905			expand.scrollLeft = expand.scrollWidth;
906			expand.scrollTop = expand.scrollHeight;
907		};
908
909		function checkTriggers(element){
910			return element.offsetWidth != element.__resizeLast__.width ||
911						 element.offsetHeight != element.__resizeLast__.height;
912		}
913		
914		function scrollListener(e){
915			var element = this;
916			resetTriggers(this);
917			if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);
918			this.__resizeRAF__ = requestFrame(function(){
919				if (checkTriggers(element)) {
920					element.__resizeLast__.width = element.offsetWidth;
921					element.__resizeLast__.height = element.offsetHeight;
922					element.__resizeListeners__.forEach(function(fn){
923						fn.call(element, e);
924					});
925				}
926			});
927		};
928		
929		/* Detect CSS Animations support to detect element display/re-attach */
930		var animation = false,
931			animationstring = 'animation',
932			keyframeprefix = '',
933			animationstartevent = 'animationstart',
934			domPrefixes = 'Webkit Moz O ms'.split(' '),
935			startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '),
936			pfx  = '';
937		{
938			var elm = document.createElement('fakeelement');
939			if( elm.style.animationName !== undefined ) { animation = true; }    
940			
941			if( animation === false ) {
942				for( var i = 0; i < domPrefixes.length; i++ ) {
943					if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
944						pfx = domPrefixes[ i ];
945						animationstring = pfx + 'Animation';
946						keyframeprefix = '-' + pfx.toLowerCase() + '-';
947						animationstartevent = startEvents[ i ];
948						animation = true;
949						break;
950					}
951				}
952			}
953		}
954		
955		var animationName = 'resizeanim';
956		var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
957		var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
958	}
959	
960	function createStyles() {
961		if (!stylesCreated) {
962			//opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360
963			var css = (animationKeyframes ? animationKeyframes : '') +
964					'.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' +
965					'.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }',
966				head = document.head || document.getElementsByTagName('head')[0],
967				style = document.createElement('style');
968			
969			style.type = 'text/css';
970			if (style.styleSheet) {
971				style.styleSheet.cssText = css;
972			} else {
973				style.appendChild(document.createTextNode(css));
974			}
975
976			head.appendChild(style);
977			stylesCreated = true;
978		}
979	}
980	
981	window.addResizeListener = function(element, fn){
982		if (attachEvent) element.attachEvent('onresize', fn);
983		else {
984			if (!element.__resizeTriggers__) {
985				if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
986				createStyles();
987				element.__resizeLast__ = {};
988				element.__resizeListeners__ = [];
989				(element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers';
990				element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' +
991																						'<div class="contract-trigger"></div>';
992				element.appendChild(element.__resizeTriggers__);
993				resetTriggers(element);
994				element.addEventListener('scroll', scrollListener, true);
995				
996				/* Listen for a css animation to detect element display/re-attach */
997				animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) {
998					if(e.animationName == animationName)
999						resetTriggers(element);
1000				});
1001			}
1002			element.__resizeListeners__.push(fn);
1003		}
1004	};
1005	
1006	window.removeResizeListener = function(element, fn){
1007		if (attachEvent) element.detachEvent('onresize', fn);
1008		else {
1009			element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
1010			if (!element.__resizeListeners__.length) {
1011					element.removeEventListener('scroll', scrollListener);
1012					element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);
1013			}
1014		}
1015	}
1016})();
1017/**
1018* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
1019*/
1020;(function(window, document) {
1021/*jshint evil:true */
1022  /** version */
1023  var version = '3.7.3';
1024
1025  /** Preset options */
1026  var options = window.html5 || {};
1027
1028  /** Used to skip problem elements */
1029  var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
1030
1031  /** Not all elements can be cloned in IE **/
1032  var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
1033
1034  /** Detect whether the browser supports default html5 styles */
1035  var supportsHtml5Styles;
1036
1037  /** Name of the expando, to work with multiple documents or to re-shiv one document */
1038  var expando = '_html5shiv';
1039
1040  /** The id for the the documents expando */
1041  var expanID = 0;
1042
1043  /** Cached data for each document */
1044  var expandoData = {};
1045
1046  /** Detect whether the browser supports unknown elements */
1047  var supportsUnknownElements;
1048
1049  (function() {
1050    try {
1051        var a = document.createElement('a');
1052        a.innerHTML = '<xyz></xyz>';
1053        //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
1054        supportsHtml5Styles = ('hidden' in a);
1055
1056        supportsUnknownElements = a.childNodes.length == 1 || (function() {
1057          // assign a false positive if unable to shiv
1058          (document.createElement)('a');
1059          var frag = document.createDocumentFragment();
1060          return (
1061            typeof frag.cloneNode == 'undefined' ||
1062            typeof frag.createDocumentFragment == 'undefined' ||
1063            typeof frag.createElement == 'undefined'
1064          );
1065        }());
1066    } catch(e) {
1067      // assign a false positive if detection fails => unable to shiv
1068      supportsHtml5Styles = true;
1069      supportsUnknownElements = true;
1070    }
1071
1072  }());
1073
1074  /*--------------------------------------------------------------------------*/
1075
1076  /**
1077   * Creates a style sheet with the given CSS text and adds it to the document.
1078   * @private
1079   * @param {Document} ownerDocument The document.
1080   * @param {String} cssText The CSS text.
1081   * @returns {StyleSheet} The style element.
1082   */
1083  function addStyleSheet(ownerDocument, cssText) {
1084    var p = ownerDocument.createElement('p'),
1085        parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
1086
1087    p.innerHTML = 'x<style>' + cssText + '</style>';
1088    return parent.insertBefore(p.lastChild, parent.firstChild);
1089  }
1090
1091  /**
1092   * Returns the value of `html5.elements` as an array.
1093   * @private
1094   * @returns {Array} An array of shived element node names.
1095   */
1096  function getElements() {
1097    var elements = html5.elements;
1098    return typeof elements == 'string' ? elements.split(' ') : elements;
1099  }
1100
1101  /**
1102   * Extends the built-in list of html5 elements
1103   * @memberOf html5
1104   * @param {String|Array} newElements whitespace separated list or array of new element names to shiv
1105   * @param {Document} ownerDocument The context document.
1106   */
1107  function addElements(newElements, ownerDocument) {
1108    var elements = html5.elements;
1109    if(typeof elements != 'string'){
1110      elements = elements.join(' ');
1111    }
1112    if(typeof newElements != 'string'){
1113      newElements = newElements.join(' ');
1114    }
1115    html5.elements = elements +' '+ newElements;
1116    shivDocument(ownerDocument);
1117  }
1118
1119   /**
1120   * Returns the data associated to the given document
1121   * @private
1122   * @param {Document} ownerDocument The document.
1123   * @returns {Object} An object of data.
1124   */
1125  function getExpandoData(ownerDocument) {
1126    var data = expandoData[ownerDocument[expando]];
1127    if (!data) {
1128        data = {};
1129        expanID++;
1130        ownerDocument[expando] = expanID;
1131        expandoData[expanID] = data;
1132    }
1133    return data;
1134  }
1135
1136  /**
1137   * returns a shived element for the given nodeName and document
1138   * @memberOf html5
1139   * @param {String} nodeName name of the element
1140   * @param {Document|DocumentFrag
vendor: 6,335 bytes, lines 1140-1342
1140ment} ownerDocument The context document.
1141   * @returns {Object} The shived element.
1142   */
1143  function createElement(nodeName, ownerDocument, data){
1144    if (!ownerDocument) {
1145        ownerDocument = document;
1146    }
1147    if(supportsUnknownElements){
1148        return ownerDocument.createElement(nodeName);
1149    }
1150    if (!data) {
1151        data = getExpandoData(ownerDocument);
1152    }
1153    var node;
1154
1155    if (data.cache[nodeName]) {
1156        node = data.cache[nodeName].cloneNode();
1157    } else if (saveClones.test(nodeName)) {
1158        node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
1159    } else {
1160        node = data.createElem(nodeName);
1161    }
1162
1163    // Avoid adding some elements to fragments in IE < 9 because
1164    // * Attributes like `name` or `type` cannot be set/changed once an element
1165    //   is inserted into a document/fragment
1166    // * Link elements with `src` attributes that are inaccessible, as with
1167    //   a 403 response, will cause the tab/window to crash
1168    // * Script elements appended to fragments will execute when their `src`
1169    //   or `text` property is set
1170    return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
1171  }
1172
1173  /**
1174   * returns a shived DocumentFragment for the given document
1175   * @memberOf html5
1176   * @param {Document} ownerDocument The context document.
1177   * @returns {Object} The shived DocumentFragment.
1178   */
1179  function createDocumentFragment(ownerDocument, data){
1180    if (!ownerDocument) {
1181        ownerDocument = document;
1182    }
1183    if(supportsUnknownElements){
1184        return ownerDocument.createDocumentFragment();
1185    }
1186    data = data || getExpandoData(ownerDocument);
1187    var clone = data.frag.cloneNode(),
1188        i = 0,
1189        elems = getElements(),
1190        l = elems.length;
1191    for(;i<l;i++){
1192        clone.createElement(elems[i]);
1193    }
1194    return clone;
1195  }
1196
1197  /**
1198   * Shivs the `createElement` and `createDocumentFragment` methods of the document.
1199   * @private
1200   * @param {Document|DocumentFragment} ownerDocument The document.
1201   * @param {Object} data of the document.
1202   */
1203  function shivMethods(ownerDocument, data) {
1204    if (!data.cache) {
1205        data.cache = {};
1206        data.createElem = ownerDocument.createElement;
1207        data.createFrag = ownerDocument.createDocumentFragment;
1208        data.frag = data.createFrag();
1209    }
1210
1211
1212    ownerDocument.createElement = function(nodeName) {
1213      //abort shiv
1214      if (!html5.shivMethods) {
1215          return data.createElem(nodeName);
1216      }
1217      return createElement(nodeName, ownerDocument, data);
1218    };
1219
1220    ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
1221      'var n=f.cloneNode(),c=n.createElement;' +
1222      'h.shivMethods&&(' +
1223        // unroll the `createElement` calls
1224        getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
1225          data.createElem(nodeName);
1226          data.frag.createElement(nodeName);
1227          return 'c("' + nodeName + '")';
1228        }) +
1229      ');return n}'
1230    )(html5, data.frag);
1231  }
1232
1233  /*--------------------------------------------------------------------------*/
1234
1235  /**
1236   * Shivs the given document.
1237   * @memberOf html5
1238   * @param {Document} ownerDocument The document to shiv.
1239   * @returns {Document} The shived document.
1240   */
1241  function shivDocument(ownerDocument) {
1242    if (!ownerDocument) {
1243        ownerDocument = document;
1244    }
1245    var data = getExpandoData(ownerDocument);
1246
1247    if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
1248      data.hasCSS = !!addStyleSheet(ownerDocument,
1249        // corrects block display not defined in IE6/7/8/9
1250        'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
1251        // adds styling not present in IE6/7/8/9
1252        'mark{background:#FF0;color:#000}' +
1253        // hides non-rendered elements
1254        'template{display:none}'
1255      );
1256    }
1257    if (!supportsUnknownElements) {
1258      shivMethods(ownerDocument, data);
1259    }
1260    return ownerDocument;
1261  }
1262
1263  /*--------------------------------------------------------------------------*/
1264
1265  /**
1266   * The `html5` object is exposed so that more elements can be shived and
1267   * existing shiving can be detected on iframes.
1268   * @type Object
1269   * @example
1270   *
1271   * // options can be changed before the script is included
1272   * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
1273   */
1274  var html5 = {
1275
1276    /**
1277     * An array or space separated string of node names of the elements to shiv.
1278     * @memberOf html5
1279     * @type Array|String
1280     */
1281    'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video',
1282
1283    /**
1284     * current version of html5shiv
1285     */
1286    'version': version,
1287
1288    /**
1289     * A flag to indicate that the HTML5 style sheet should be inserted.
1290     * @memberOf html5
1291     * @type Boolean
1292     */
1293    'shivCSS': (options.shivCSS !== false),
1294
1295    /**
1296     * Is equal to true if a browser supports creating unknown/HTML5 elements
1297     * @memberOf html5
1298     * @type boolean
1299     */
1300    'supportsUnknownElements': supportsUnknownElements,
1301
1302    /**
1303     * A flag to indicate that the document's `createElement` and `createDocumentFragment`
1304     * methods should be overwritten.
1305     * @memberOf html5
1306     * @type Boolean
1307     */
1308    'shivMethods': (options.shivMethods !== false),
1309
1310    /**
1311     * A string to describe the type of `html5` object ("default" or "default print").
1312     * @memberOf html5
1313     * @type String
1314     */
1315    'type': 'default',
1316
1317    // shivs the document according to the specified `html5` object options
1318    'shivDocument': shivDocument,
1319
1320    //creates a shived element
1321    createElement: createElement,
1322
1323    //creates a shived documentFragment
1324    createDocumentFragment: createDocumentFragment,
1325
1326    //extends list of elements
1327    addElements: addElements
1328  };
1329
1330  /*--------------------------------------------------------------------------*/
1331
1332  // expose html5
1333  window.html5 = html5;
1334
1335  // shiv the document
1336  shivDocument(document);
1337
1338  if(typeof module == 'object' && module.exports){
1339    module.exports = html5;
1340  }
1341
1342}(typeof window !== "undefined" ? window : this, document));
1343/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */
1344
1345window.matchMedia || (window.matchMedia = function() {
1346    "use strict";
1347
1348    // For browsers that support matchMedium api such as IE 9 and webkit
1349    var styleMedia = (window.styleMedia || window.media);
1350
1351    // For those that don't support matchMedium
1352    if (!styleMedia) {
1353        var style       = document.createElement('style'),
1354            script      = document.getElementsByTagName('script')[0],
1355            info        = null;
1356
1357        style.type  = 'text/css';
1358        style.id    = 'matchmediajs-test';
1359
1360        script.parentNode.insertBefore(style, script);
1361
1362        // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
1363        info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;
1364
1365        styleMedia = {
1366            matchMedium: function(media) {
1367                var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';
1368
1369                // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
1370                if (style.styleSheet) {
1371                    style.styleSheet.cssText = text;
1372                } else {
1373                    style.textContent = text;
1374                }
1375
1376                // Test if media query is true or false
1377                return info.width === '1px';
1378            }
1379        };
1380    }
1381
1382    return function(media) {
1383        return {
1384            matches: styleMedia.matchMedium(media || 'all'),
1385            media: media || 'all'
1386        };
1387    };
1388}());
1389
1390/*!
1391 * The MIT License
1392 *
1393 * Copyright (c) 2012 James Allardice
1394 *
1395 * Permission is hereby granted, free of charge, to any person obtaining a copy
1396 * of this software and associated documentation files (the "Software"), to
1397 * deal in the Software without restriction, including without limitation the
1398 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
1399 * sell copies of the Software, and to permit persons to whom the Software is
1400 * furnished to do so, subject to the following conditions:
1401 *
1402 * The above copyright notice and this permission notice shall be included in
1403 * all copies or substantial portions of the Software.
1404 *
1405 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1406 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1407 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1408 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1409 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1410 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
1411 * IN THE SOFTWARE.
1412 */
1413
1414( function ( global ) {
1415
1416  'use strict';
1417
1418  //
1419  // Test for support. We do this as early as possible to optimise for browsers
1420  // that have native support for the attribute.
1421  //
1422
1423  var test = document.createElement('input');
1424  var nativeSupport = test.placeholder !== void 0;
1425
1426  global.Placeholders = {
1427    nativeSupport: nativeSupport,
1428    disable: nativeSupport ? noop : disablePlaceholders,
1429    enable: nativeSupport ? noop : enablePlaceholders
1430  };
1431
1432  if ( nativeSupport ) {
1433    return;
1434  }
1435
1436  //
1437  // If we reach this point then the browser does not have native support for
1438  // the attribute.
1439  //
1440
1441  // The list of input element types that support the placeholder attribute.
1442  var validTypes = [
1443    'text',
1444    'search',
1445    'url',
1446    'tel',
1447    'email',
1448    'password',
1449    'number',
1450    'textarea'
1451  ];
1452
1453  // The list of keycodes that are not allowed when the polyfill is configured
1454  // to hide-on-input.
1455  var badKeys = [
1456
1457    // The following keys all cause the caret to jump to the end of the input
1458    // value.
1459
1460    27, // Escape
1461    33, // Page up
1462    34, // Page down
1463    35, // End
1464    36, // Home
1465
1466    // Arrow keys allow you to move the caret manually, which should be
1467    // prevented when the placeholder is visible.
1468
1469    37, // Left
1470    38, // Up
1471    39, // Right
1472    40, // Down
1473
1474    // The following keys allow you to modify the placeholder text by removing
1475    // characters, which should be prevented when the placeholder is visible.
1476
1477    8, // Backspace
1478    46 // Delete
1479  ];
1480
1481  // Styling variables.
1482  var placeholderStyleColor = '#ccc';
1483  var placeholderClassName = 'placeholdersjs';
1484  var classNameRegExp = new RegExp('(?:^|\\s)' + placeholderClassName + '(?!\\S)');
1485
1486  // The various data-* attributes used by the polyfill.
1487  var ATTR_CURRENT_VAL = 'data-placeholder-value';
1488  var ATTR_ACTIVE = 'data-placeholder-active';
1489  var ATTR_INPUT_TYPE = 'data-placeholder-type';
1490  var ATTR_FORM_HANDLED = 'data-placeholder-submit';
1491  var ATTR_EVENTS_BOUND = 'data-placeholder-bound';
1492  var ATTR_OPTION_FOCUS = 'data-placeholder-focus';
1493  var ATTR_OPTION_LIVE = 'data-placeholder-live';
1494  var ATTR_MAXLENGTH = 'data-placeholder-maxlength';
1495
1496  // Various other variables used throughout the rest of the script.
1497  var UPDATE_INTERVAL = 100;
1498  var head = document.getElementsByTagName('head')[ 0 ];
1499  var root = document.documentElement;
1500  var Placeholders = global.Placeholders;
1501  var keydownVal;
1502
1503  // Get references to all the input and textarea elements currently in the DOM
1504  // (live NodeList objects to we only need to do this once).
1505  var inputs = document.getElementsByTagName('input');
1506  var textareas = document.getElementsByTagName('textarea');
1507
1508  // Get any settings declared as data-* attributes on the root element.
1509  // Currently the only options are whether to hide the placeholder on focus
1510  // or input and whether to auto-update.
1511  var hideOnInput = root.getAttribute(ATTR_OPTION_FOCUS) === 'false';
1512  var liveUpdates = root.getAttribute(ATTR_OPTION_LIVE) !== 'false';
1513
1514  // Create style element for placeholder styles (instead of directly setting
1515  // style properties on elements - allows for better flexibility alongside
1516  // user-defined styles).
1517  var styleElem = document.createElement('style');
1518  styleElem.type = 'text/css';
1519
1520  // Create style rules as text node.
1521  var styleRules = document.createTextNode(
1522    '.' + placeholderClassName + ' {' +
1523      'color:' + placeholderStyleColor + ';' +
1524    '}'
1525  );
1526
1527  // Append style rules to newly created stylesheet.
1528  if ( styleElem.styleSheet ) {
1529    styleElem.styleSheet.cssText = styleRules.nodeValue;
1530  } else {
1531    styleElem.appendChild(styleRules);
1532  }
1533
1534  // Prepend new style element to the head (before any existing stylesheets,
1535  // so user-defined rules take precedence).
1536  head.insertBefore(styleElem, head.firstChild);
1537
1538  // Set up the placeholders.
1539  var placeholder;
1540  var elem;
1541
1542  for ( var i = 0, len = inputs.length + textareas.length; i < len; i++ ) {
1543
1544    // Find the next element. If we've already done all the inputs we move on
1545    // to the textareas.
1546    elem = i < inputs.length ? inputs[ i ] : textareas[ i - inputs.length ];
1547
1548    // Get the value of the placeholder attribute, if any. IE10 emulating IE7
1549    // fails with getAttribute, hence the use of the attributes node.
1550    placeholder = elem.attributes.placeholder;
1551
1552    // If the element has a placeholder attribute we need to modify it.
1553    if ( placeholder ) {
1554
1555      // IE returns an empty object instead of undefined if the attribute is
1556      // not present.
1557      placeholder = placeholder.nodeValue;
1558
1559      // Only apply the polyfill if this element is of a type that supports
1560      // placeholders and has a placeholder attribute with a non-empty value.
1561      if ( placeholder && inArray(validTypes, elem.type) ) {
1562        newElement(elem);
1563      }
1564    }
1565  }
1566
1567  // If enabled, the polyfill will repeatedly check for changed/added elements
1568  // and apply to those as well.
1569  var timer = setInterval(function () {
1570    for ( var i = 0, len = inputs.length + textareas.length; i < len; i++ ) {
1571      elem = i < inputs.length ? inputs[ i ] : textareas[ i - inputs.length ];
1572
1573      // Only apply the polyfill if this element is of a type that supports
1574      // placeholders, and has a placeholder attribute with a non-empty value.
1575      placeholder = elem.attributes.placeholder;
1576
1577      if ( placeholder ) {
1578
1579        placeholder = placeholder.nodeValue;
1580
1581        if ( placeholder && inArray(validTypes, elem.type) ) {
1582
1583          // If the element hasn't had event handlers bound to it then add
1584          // them.
1585          if ( !elem.getAttribute(ATTR_EVENTS_BOUND) ) {
1586            newElement(elem);
1587          }
1588
1589          // If the placeholder value has changed or not been initialised yet
1590          // we need to update the display.
1591          if (
1592            placeholder !== elem.getAttribute(ATTR_CURRENT_VAL) ||
1593            ( elem.type === 'password' && !elem.getAttribute(ATTR_INPUT_TYPE) )
1594          ) {
1595
1596            // Attempt to change the type of password inputs (fails in IE < 9).
1597            if (
1598              elem.type === 'password' &&
1599              !elem.getAttribute(ATTR_INPUT_TYPE) &&
1600              changeType(elem, 'text')
1601            ) {
1602              elem.setAttribute(ATTR_INPUT_TYPE, 'password');
1603            }
1604
1605            // If the placeholder value has changed and the placeholder is
1606            // currently on display we need to change it.
1607            if ( elem.value === elem.getAttribute(ATTR_CURRENT_VAL) ) {
1608              elem.value = placeholder;
1609            }
1610
1611            // Keep a reference to the current placeholder value in case it
1612            // changes via another script.
1613            elem.setAttribute(ATTR_CURRENT_VAL, placeholder);
1614          }
1615        }
1616      } else if ( elem.getAttribute(ATTR_ACTIVE) ) {
1617        hidePlaceholder(elem);
1618        elem.removeAttribute(ATTR_CURRENT_VAL);
1619      }
1620    }
1621
1622    // If live updates are not enabled cancel the timer.
1623    if ( !liveUpdates ) {
1624      clearInterval(timer);
1625    }
1626  }, UPDATE_INTERVAL);
1627
1628  // Disabling placeholders before unloading the page prevents flash of
1629  // unstyled placeholders on load if the page was refreshed.
1630  addEventListener(global, 'beforeunload', function () {
1631    Placeholders.disable();
1632  });
1633
1634  //
1635  // Utility functions
1636  //
1637
1638  // No-op (used in place of public methods when native support is detected).
1639  function noop() {}
1640
1641  // Avoid IE9 activeElement of death when an iframe is used.
1642  //
1643  // More info:
1644  //  - http://bugs.jquery.com/ticket/13393
1645  //  - https://github.com/jquery/jquery/commit/85fc5878b3c6af73f42d61eedf73013e7faae408
1646  function safeActiveElement() {
1647    try {
1648      return document.activeElement;
1649    } catch ( err ) {}
1650  }
1651
1652  // Check whether an item is in an array. We don't use Array.prototype.indexOf
1653  // so we don't clobber any existing polyfills. This is a really simple
1654  // alternative.
1655  function inArray( arr, item ) {
1656    for ( var i = 0, len = arr.length; i < len; i++ ) {
1657      if ( arr[ i ] === item ) {
1658        return true;
1659      }
1660    }
1661    return false;
1662  }
1663
1664  // Cross-browser DOM event binding
1665  function addEventListener( elem, event, fn ) {
1666    if ( elem.addEventListener ) {
1667      return elem.addEventListener(event, fn, false);
1668    }
1669    if ( elem.attachEvent ) {
1670      return elem.attachEvent('on' + event, fn);
1671    }
1672  }
1673
1674  // Move the caret to the index position specified. Assumes that the element
1675  // has focus.
1676  function moveCaret( elem, index ) {
1677    var range;
1678    if ( elem.createTextRange ) {
1679      range = elem.createTextRange();
1680      range.move('character', index);
1681      range.select();
1682    } else if ( elem.selectionStart ) {
1683      elem.focus();
1684      elem.setSelectionRange(index, index);
1685    }
1686  }
1687
1688  // Attempt to change the type property of an input element.
1689  function changeType( elem, type ) {
1690    try {
1691      elem.type = type;
1692      return true;
1693    } catch ( e ) {
1694      // You can't change input type in IE8 and below.
1695      return false;
1696    }
1697  }
1698
1699  function handleElem( node, callback ) {
1700
1701    // Check if the passed in node is an input/textarea (in which case it can't
1702    // have any affected descendants).
1703    if ( node && node.getAttribute(ATTR_CURRENT_VAL) ) {
1704      callback(node);
1705    } else {
1706
1707      // If an element was passed in, get all affected descendants. Otherwise,
1708      // get all affected elements in document.
1709      var handleInputs = node ? node.getElementsByTagName('input') : input
1709s;
1710      var handleTextareas = node ? node.getElementsByTagName('textarea') : textareas;
1711
1712      var handleInputsLength = handleInputs ? handleInputs.length : 0;
1713      var handleTextareasLength = handleTextareas ? handleTextareas.length : 0;
1714
1715      // Run the callback for each element.
1716      var len = handleInputsLength + handleTextareasLength;
1717      var elem;
1718      for ( var i = 0; i < len; i++ ) {
1719
1720        elem = i < handleInputsLength ?
1721          handleInputs[ i ] :
1722          handleTextareas[ i - handleInputsLength ];
1723
1724        callback(elem);
1725      }
1726    }
1727  }
1728
1729  // Return all affected elements to their normal state (remove placeholder
1730  // value if present).
1731  function disablePlaceholders( node ) {
1732    handleElem(node, hidePlaceholder);
1733  }
1734
1735  // Show the placeholder value on all appropriate elements.
1736  function enablePlaceholders( node ) {
1737    handleElem(node, showPlaceholder);
1738  }
1739
1740  // Hide the placeholder value on a single element. Returns true if the
1741  // placeholder was hidden and false if it was not (because it wasn't visible
1742  // in the first place).
1743  function hidePlaceholder( elem, keydownValue ) {
1744
1745    var valueChanged = !!keydownValue && elem.value !== keydownValue;
1746    var isPlaceholderValue = elem.value === elem.getAttribute(ATTR_CURRENT_VAL);
1747
1748    if (
1749      ( valueChanged || isPlaceholderValue ) &&
1750      elem.getAttribute(ATTR_ACTIVE) === 'true'
1751    ) {
1752
1753      elem.removeAttribute(ATTR_ACTIVE);
1754      elem.value = elem.value.replace(elem.getAttribute(ATTR_CURRENT_VAL), '');
1755      elem.className = elem.className.replace(classNameRegExp, '');
1756
1757      // Restore the maxlength value. Old FF returns -1 if attribute not set.
1758      // See GH-56.
1759      var maxLength = elem.getAttribute(ATTR_MAXLENGTH);
1760      if ( parseInt(maxLength, 10) >= 0 ) {
1761        elem.setAttribute('maxLength', maxLength);
1762        elem.removeAttribute(ATTR_MAXLENGTH);
1763      }
1764
1765      // If the polyfill has changed the type of the element we need to change
1766      // it back.
1767      var type = elem.getAttribute(ATTR_INPUT_TYPE);
1768      if ( type ) {
1769        elem.type = type;
1770      }
1771
1772      return true;
1773    }
1774
1775    return false;
1776  }
1777
1778  // Show the placeholder value on a single element. Returns true if the
1779  // placeholder was shown and false if it was not (because it was already
1780  // visible).
1781  function showPlaceholder( elem ) {
1782
1783    var val = elem.getAttribute(ATTR_CURRENT_VAL);
1784
1785    if ( elem.value === '' && val ) {
1786
1787      elem.setAttribute(ATTR_ACTIVE, 'true');
1788      elem.value = val;
1789      elem.className += ' ' + placeholderClassName;
1790
1791      // Store and remove the maxlength value.
1792      var maxLength = elem.getAttribute(ATTR_MAXLENGTH);
1793      if ( !maxLength ) {
1794        elem.setAttribute(ATTR_MAXLENGTH, elem.maxLength);
1795        elem.removeAttribute('maxLength');
1796      }
1797
1798      // If the type of element needs to change, change it (e.g. password
1799      // inputs).
1800      var type = elem.getAttribute(ATTR_INPUT_TYPE);
1801      if ( type ) {
1802        elem.type = 'text';
1803      } else if ( elem.type === 'password' && changeType(elem, 'text') ) {
1804        elem.setAttribute(ATTR_INPUT_TYPE, 'password');
1805      }
1806
1807      return true;
1808    }
1809
1810    return false;
1811  }
1812
1813  // Returns a function that is used as a focus event handler.
1814  function makeFocusHandler( elem ) {
1815    return function () {
1816
1817      // Only hide the placeholder value if the (default) hide-on-focus
1818      // behaviour is enabled.
1819      if (
1820        hideOnInput &&
1821        elem.value === elem.getAttribute(ATTR_CURRENT_VAL) &&
1822        elem.getAttribute(ATTR_ACTIVE) === 'true'
1823      ) {
1824
1825        // Move the caret to the start of the input (this mimics the behaviour
1826        // of all browsers that do not hide the placeholder on focus).
1827        moveCaret(elem, 0);
1828      } else {
1829
1830        // Remove the placeholder.
1831        hidePlaceholder(elem);
1832      }
1833    };
1834  }
1835
1836  // Returns a function that is used as a blur event handler.
1837  function makeBlurHandler( elem ) {
1838    return function () {
1839      showPlaceholder(elem);
1840    };
1841  }
1842
1843  // Returns a function that is used as a submit event handler on form elements
1844  // that have children affected by this polyfill.
1845  function makeSubmitHandler( form ) {
1846    return function () {
1847
1848        // Turn off placeholders on all appropriate descendant elements.
1849        disablePlaceholders(form);
1850    };
1851  }
1852
1853  // Functions that are used as a event handlers when the hide-on-input
1854  // behaviour has been activated - very basic implementation of the 'input'
1855  // event.
1856  function makeKeydownHandler( elem ) {
1857    return function ( e ) {
1858      keydownVal = elem.value;
1859
1860      // Prevent the use of the arrow keys (try to keep the cursor before the
1861      // placeholder).
1862      if (
1863        elem.getAttribute(ATTR_ACTIVE) === 'true' &&
1864        keydownVal === elem.getAttribute(ATTR_CURRENT_VAL) &&
1865        inArray(badKeys, e.keyCode)
1866      ) {
1867        if ( e.preventDefault ) {
1868            e.preventDefault();
1869        }
1870        return false;
1871      }
1872    };
1873  }
1874
1875  function makeKeyupHandler(elem) {
1876    return function () {
1877      hidePlaceholder(elem, keydownVal);
1878
1879      // If the element is now empty we need to show the placeholder
1880      if ( elem.value === '' ) {
1881        elem.blur();
1882        moveCaret(elem, 0);
1883      }
1884    };
1885  }
1886
1887  function makeClickHandler(elem) {
1888    return function () {
1889      if (
1890        elem === safeActiveElement() &&
1891        elem.value === elem.getAttribute(ATTR_CURRENT_VAL) &&
1892        elem.getAttribute(ATTR_ACTIVE) === 'true'
1893      ) {
1894        moveCaret(elem, 0);
1895      }
1896    };
1897  }
1898
1899  // Bind event handlers to an element that we need to affect with the
1900  // polyfill.
1901  function newElement( elem ) {
1902
1903    // If the element is part of a form, make sure the placeholder string is
1904    // not submitted as a value.
1905    var form = elem.form;
1906    if ( form && typeof form === 'string' ) {
1907
1908      // Get the real form.
1909      form = document.getElementById(form);
1910
1911      // Set a flag on the form so we know it's been handled (forms can contain
1912      // multiple inputs).
1913      if ( !form.getAttribute(ATTR_FORM_HANDLED) ) {
1914        addEventListener(form, 'submit', makeSubmitHandler(form));
1915        form.setAttribute(ATTR_FORM_HANDLED, 'true');
1916      }
1917    }
1918
1919    // Bind event handlers to the element so we can hide/show the placeholder
1920    // as appropriate.
1921    addEventListener(elem, 'focus', makeFocusHandler(elem));
1922    addEventListener(elem, 'blur', makeBlurHandler(elem));
1923
1924    // If the placeholder should hide on input rather than on focus we need
1925    // additional event handlers
1926    if (hideOnInput) {
1927      addEventListener(elem, 'keydown', makeKeydownHandler(elem));
1928      addEventListener(elem, 'keyup', makeKeyupHandler(elem));
1929      addEventListener(elem, 'click', makeClickHandler(elem));
1930    }
1931
1932    // Remember that we've bound event handlers to this element.
1933    elem.setAttribute(ATTR_EVENTS_BOUND, 'true');
1934    elem.setAttribute(ATTR_CURRENT_VAL, placeholder);
1935
1936    // If the element doesn't have a value and is not focussed, set it to the
1937    // placeholder string.
1938    if ( hideOnInput || elem !== safeActiveElement() ) {
1939      showPlaceholder(elem);
1940    }
1941  }
1942
1943}(this) );
1944// IE spupport comes in IE10
1945(function rAFPolyfill() {
1946    var lastTime, vendors, x;
1947    lastTime = 0;
1948    vendors = ["webkit", "moz"];
1949    x = 0;
1950    while (x < vendors.length && !window.requestAnimationFrame) {
1951      window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"];
1952      window.cancelAnimationFrame = window[vendors[x] + "CancelAnimationFrame"] || window[vendors[x] + "CancelRequestAnimationFrame"];
1953      ++x;
1954    }
1955    if (!window.requestAnimationFrame) {
1956      window.requestAnimationFrame = function(callback, element) {
1957        var currTime, id, timeToCall;
1958        currTime = new Date().getTime();
1959        timeToCall = Math.max(0, 16 - (currTime - lastTime));
1960        id = window.setTimeout(function() {
1961          callback(currTime + timeToCall);
1962        }, timeToCall);
1963        lastTime = currTime + timeToCall;
1964        return id;
1965      };
1966    }
1967    if (!window.cancelAnimationFrame) {
1968      window.cancelAnimationFrame = function(id) {
1969        clearTimeout(id);
1970      };
1971    }
1972})();
1973
1974
1975
1976(function($) {
1977	'use strict';
1978
1979	var MK = window.MK || {};
1980
1981	/**
1982	 * MK.core holds most important methods that bootstraps whole application
1983	 * 
1984	 * @type {Object}
1985	 */
1986	MK.core = {};
1987
1988
1989
1990	/**
1991	 * State for referance of already loaded script files
1992	 * @type {Array}
1993	 */
1994	var _loadedDependencies = [];
1995
1996	/**
1997	 * State of queue represented as pairs of script ref => callback
1998	 * @type {Object}
1999	 */
2000	var _inQueue = {};
2001	
2002	/**
2003	 * Initializes all components in given scope (object or DOM reference) based on data attribute and 'pointer' css class '.js-el'.
2004	 * DOM work is reduced by single traversing for pointer class and later filtering through cached object. It expects init() method
2005	 * on every component. Component itself should be defined in MK.component namespace and assign to DOM element via data-mk-component.
2006	 * Use it once on DOM ready with document as a scope. For partial initialization after aja
2006x operations pass as a scope element
2007	 * where new DOM was inserted.
2008	 * 
2009	 * @param  {string|object}
2010	 */
2011	MK.core.initAll = function( scope ) {
2012		var $el = $( scope ).find( '.js-el' ), // single traversing
2013			$components = $el.filter( '[data-mk-component]' ),
2014			component = null;
2015
2016
2017		// initialize  component
2018		var init = function init(name, el) {
2019			var $el = $(el);
2020
2021			if ( $el.data('init-' + name) ) return; // do not initialize the same module twice
2022
2023			if ( typeof MK.component[ name ] !== 'function' ) console.log('Component init error: ', name);
2024			else {
2025				component = new MK.component[ name ]( el );
2026				component.init();
2027				$el.data('init-' + name, true); // mark as initialised
2028				// TODO add name
2029				MK.utils.eventManager.publish('component-inited');
2030			}
2031		};
2032
2033		$components.each( function() {
2034			var self = this,
2035				$this = $( this ),
2036				names = $this.data( 'mk-component' );
2037
2038			if( typeof names === 'string' ) {
2039				var name = names; // containes only single name. Keep it transparent.
2040				init(name, self);
2041			} else {
2042				names.forEach( function( name ) {
2043					init(name, self);
2044				});
2045			} 
2046		}); 
2047	};
2048
2049	/**
2050	 * Async loader for 3rd party plugins available from within theme or external CDNs / APIs.
2051	 * Take one argument as callback which is run when loading is finished. Also keeps track of already loaded scripts 
2052	 * and prevent duplication. Holds in queue multiple callbacks that where defined in different places but depend on the 
2053	 * same plugin.
2054	 *
2055	 * TODO: heavy test for multiple dependencies and crosssharing one dependency and different one dependency in queue, 
2056	 * bulletproof with single dependency
2057	 *
2058	 * @example MK.core.loadDependencies([MK.core.path.plugins + 'plugin.js'], function() {
2059	 *          	// do something when plugin is loaded
2060	 * 			})
2061	 * 
2062	 * @param  {array}
2063	 * @param  {function}
2064	 */
2065	MK.core.loadDependencies = function( dependencies, callback ) {
2066		var _callback = callback || function() {};
2067
2068        if( !dependencies ) {
2069        	// If no dependencies defined then run _callback imidietelly
2070        	_callback(); 
2071        	return;
2072        }
2073
2074		// Check for new dependencies
2075        var newDeps = dependencies.map( function( dep ) {
2076            if( _loadedDependencies.indexOf( dep ) === -1 ) {
2077            	 if( typeof _inQueue[ dep ] === 'undefined' ) {
2078        			// console.log( dep );
2079                	return dep;
2080                } else {
2081                	_inQueue[ dep ].push( _callback );
2082                	return true;
2083                }
2084            } else {
2085            	return false;
2086            }
2087        });
2088
2089        // The dependency is not new but it's not resolved yet
2090        // Callback is added to queue that will be run after the script is loaded
2091        // Don't run callback just yet.
2092        if( newDeps[0] === true ) {
2093        	// console.log('Waiting for ' + dependencies[0]);
2094        	return;
2095        }
2096
2097        // Dependency was loaded previously. We can run callback safely
2098        if( newDeps[0] === false ) {
2099        	_callback();
2100        	return;
2101        }
2102
2103        // Create queue and relationship script -> callback array to track
2104        // all callbacks that waits for ths script
2105        var queue = newDeps.map( function( script ) {
2106        	// console.log( script );
2107        	_inQueue[ script ] = [ _callback ];
2108            return $.getCachedScript( script );
2109        });
2110
2111        // Callbacks invoking
2112        var onLoad = function onLoad() {
2113        	var index;
2114        	newDeps.map( function( loaded ) {
2115        		_inQueue[ loaded ].forEach( function( callback ) {
2116        			callback();
2117        		});
2118        		delete _inQueue[ loaded ];
2119                _loadedDependencies.push( loaded );
2120        	});
2121        };
2122
2123        // Run callbacks when promise is resolved
2124        $.when.apply( null, queue ).done( onLoad );
2125	};
2126
2127	/**
2128	 * Single namespace for all paths recuired in application.
2129	 * @type {Object}
2130	 */
2131	MK.core.path = {
2132		theme   : mk_theme_dir,
2133		plugins : mk_theme_js_path + '/plugins/async/min/',
2134		ajaxUrl : window.PHP.ajax
2135	};
2136
2137
2138})(jQuery);
2139(function($) {
2140	'use strict';
2141
2142    var MK = window.MK || {};
2143	MK.utils = window.MK.utils || {};
2144
2145    /**
2146     * Enables to evaluate common methods through DOM JSON references by invoking from object with bracket notation MK.utils[var][var]
2147     * @type {Object}
2148     */
2149    MK.utils.actions = {};
2150
2151    MK.utils.actions.activate = function (el) {
2152        $(el).addClass('is-active');
2153    };
2154        
2155    MK.utils.actions.deactivate = function (el) {
2156        $(el).removeClass('is-active');
2157    };
2158
2159}(jQuery));
2160(function($) {
2161	'use strict';
2162
2163    var MK = window.MK || {};
2164	MK.utils = window.MK.utils || {};
2165
2166    /**
2167     * Gets user browser and its version
2168     * @return {Object} => {name, version}
2169     */
2170	MK.utils.browser = (function() {
2171        var dataBrowser = [
2172            {string: navigator.userAgent, subString: "Edge", identity: "Edge"},
2173            {string: navigator.userAgent, subString: "Chrome", identity: "Chrome"},
2174            {string: navigator.userAgent, subString: "MSIE", identity: "IE"},
2175            {string: navigator.userAgent, subString: "Trident", identity: "IE"},
2176            {string: navigator.userAgent, subString: "Firefox", identity: "Firefox"},
2177            {string: navigator.userAgent, subString: "Safari", identity: "Safari"},
2178            {string: navigator.userAgent, subString: "Opera", identity: "Opera"}
2179        ];
2180
2181		var versionSearchString = null;
2182        var searchString = function (data) {
2183            for (var i = 0; i < data.length; i++) {
2184                var dataString = data[i].string;
2185                versionSearchString = data[i].subString;
2186
2187                if (dataString.indexOf(data[i].subString) !== -1) {
2188                    return data[i].identity;
2189                }
2190            }
2191        };
2192        
2193        var searchVersion = function (dataString) {
2194            var index = dataString.indexOf(versionSearchString);
2195            if (index === -1) {
2196                return;
2197            }
2198
2199            var rv = dataString.indexOf("rv:");
2200            if (versionSearchString === "Trident" && rv !== -1) {
2201                return parseFloat(dataString.substring(rv + 3));
2202            } else {
2203                return parseFloat(dataString.substring(index + versionSearchString.length + 1));
2204            }
2205        };
2206
2207        var name = searchString(dataBrowser) || "Other";
2208        var version = searchVersion(navigator.userAgent) || searchVersion(navigator.appVersion) || "Unknown";
2209
2210        // Expose for css
2211        $('html').addClass(name).addClass(name + version);
2212
2213
2214        return {
2215        	name : name,
2216        	version : version
2217        };
2218        
2219	})();
2220
2221    /**
2222     * Gets user operating system
2223     * @return {String}
2224     */
2225	MK.utils.OS = (function() {
2226		if (navigator.appVersion.indexOf("Win")!=-1) return "Windows";
2227		if (navigator.appVersion.indexOf("Mac")!=-1) return "OSX";
2228		if (navigator.appVersion.indexOf("X11")!=-1) return "UNIX";
2229		if (navigator.appVersion.indexOf("Linux")!=-1) return "Linux";
2230	})();
2231	
2232    /**
2233     * Check if mobile device.
2234     * @return {Boolean}
2235     */
2236	MK.utils.isMobile = function() {
2237        // Problems with bigger tablets as users raport differences with behaviour. Switch to navigator sniffing
2238		// return ('ontouchstart' in document.documentElement) && matchMedia( '(max-width: 1024px)' ).matches;
2239     
2240        // http://www.abeautifulsite.net/detecting-mobile-devices-with-javascript/
2241        // if it still brings problem try to move to more sophisticated solution like
2242        // apachemobilefilter.org
2243        // detectright.com
2244        // web.wurfl.io
2245        // 
2246        // Seems as best solution here:
2247        // hgoebl.github.io/mobile-detect.js
2248
2249        function android() {
2250            return navigator.userAgent.match(/Android/i);
2251        }
2252
2253        function blackBerry() {
2254            return navigator.userAgent.match(/BlackBerry/i);
2255        }
2256
2257        function iOS() {
2258            return navigator.userAgent.match(/iPhone|iPad|iPod/i);
2259        }
2260
2261        function opera() {
2262            return navigator.userAgent.match(/Opera Mini/i);
2263        }
2264
2265        function windows() {
2266            return navigator.userAgent.match(/IEMobile/i);
2267        }
2268
2269        return (android() || blackBerry() || iOS() || opera() || windows() || matchMedia( '(max-width: 1024px)' ).matches); 
2270            
2271	};
2272
2273    /**
2274     * Check if menu is switched to responsive state based on user width settings
2275     * @return {Boolean} 
2276     */
2277    MK.utils.isResponsiveMenuState = function() {
2278        return window.matchMedia( '(max-width: '+ mk_responsive_nav_width +'px)').matches;
2279    };
2280
2281
2282
2283    MK.utils.getUrlParameter = function getUrlParameter(sParam) {
2284        var sPageURL = decodeURIComponent(window.location.search.substring(1)),
2285            sURLVariables = sPageURL.split('&'),
2286            sParameterName,
2287            i;
2288
2289        for (i = 0; i < sURLVariables.length; i++) {
2290            sParameterName = sURLVariables[i].split('=');
2291
2292            if (sParameterName[0] === sParam) {
2293                return sParameterName[1] === undefined ? true : sParameterName[1];
2294            }
2295        }
2296    };
2297
2298
2299    MK.utils.isSmoothScroll = (function() {
2300        var isUserChoice = (mk_smooth_scroll === 'true');
2301
2302        // We notify our app about smooth scroll option when user choose it from admin panel.
2303        return isUserChoice;
2304    }());
2305
2306}(jQuery));
2307(function($) {
2308	'use strict';
2309
2310    var MK = window.MK || {};
2311	MK.utils = window.MK.utils || {};
2312
2313	/**
2314	 * Basic implementation of pub / sub pattern to avoid tight coupling with direct module communication
2315	 * @type {Object}
2316	 */
2317	MK.utils.eventManager = {};
2318
2319	/**
2320	 * Subscribe to custom event and run callbacks
2321	 * @param  {String}
2322	 * @param  {Function}
2323	 *
2324	 * @usage MK.utils.eventManager.subscribe('event', function(e, params) {} )
2325	 */
2326	MK.utils.eventManager.subscribe = function(evt, func) {
2327		$(this).on(evt, func);
2328	};
2329
2330	/**
2331	 * Unsubscribe from custom event
2332	 * @param  {String}
2333	 * @param  {Function}
2334	 */
2335	MK.utils.eventManager.unsubscribe = function(evt, func) {
2336		$(this).off(evt, func);
2337	};
2338
2339	/**
2340	 * Publish custom event to notify appliaction about state change
2341	 * @param  {String}
2342	 * 
2343	 * @usage MK.utils.eventManager.publish('event', {
2344	 *        	param: val
2345	 *        })
2346	 */
2347	MK.utils.eventManager.publish = function(evt, params) {
2348		$(this).trigger(evt, [params]);
2349	};
2350
2351}(jQuery));
2352(function($) {
2353	'use strict';
2354
2355    var MK = window.MK || {};
2356	MK.utils = window.MK.utils || {};
2357
2358	/**
2359	 * Control browser fullscreen mode
2360	 * @type {Object}
2361	 */
2362	MK.utils.fullscreen = {};
2363
2364	// TODO: move to namespace
2365	MK.utils.launchIntoFullscreen = function ( element ) {
2366	    if(element.requestFullscreen) {
2367	     	element.requestFullscreen();
2368	  	} else if(element.mozRequestFullScreen) {
2369	    	element.mozRequestFullScreen();
2370	  	} else if(element.webkitRequestFullscreen) {
2371	    	element.webkitRequestFullscreen();
2372	  	} else if(element.msRequestFullscreen) {
2373	    	element.msRequestFullscreen();
2374	  	}
2375	};
2376
2377	MK.utils.exitFullscreen = function () {
2378	  	if(document.exitFullscreen) {
2379	    	document.exitFullscreen();
2380	  	} else if(document.mozCancelFullScreen) {
2381	    	document.mozCancelFullScreen();
2382	  	} else if(document.webkitExitFullscreen) {
2383	    	document.webkitExitFullscreen();
2384	  	}
2385	};
2386
2387}(jQuery));
2388(function($) {
2389	'use strict';
2390
2391    var MK = window.MK || {};
2392	MK.utils = window.MK.utils || {};
2393
2394	MK.utils.misc = {};
2395	// TODO: move to namespace
2396
2397	/**
2398	 * Get all top offsets from jQuery collection
2399	 * 
2400	 * @param  {$Objects}
2401	 * @return {Aray}
2402	 */
2403	MK.utils.offsets = function( $els ) {
2404		return $.map( $els, function( el ) {
2405			return $( el ).offset().top;
2406		});
2407	};
2408
2409	/**
2410	 * Retrive from array of numbers first number that is higher than given parameter
2411	 * 
2412	 * @param  {Number}
2413	 * @param  {Array}
2414	 * @return {Number}
2415	 */
2416	MK.utils.nextHigherVal = function( val, arr ) {
2417		var i = 0,
2418			higher = null;
2419
2420		var check = function() {
2421			if( val > arr[ i ]) {
2422				i += 1;
2423				check();
2424			} else {
2425				higher = arr[ i ];
2426			}
2427		};
2428		check();
2429
2430		return higher;
2431	};
2432
2433
2434    MK.utils.throttle = function( delay, fn ) {
2435        var last;
2436        var deferTimer;
2437
2438        return function() {
2439            var context = this;
2440            var args = arguments;
2441            var now = +new Date;
2442            if( last && now < last + delay ) {
2443            	clearTimeout( deferTimer );
2444            	deferTimer = setTimeout( function() { 
2445            		last = now; fn.apply( context, args ); 
2446            	}, delay );
2447          	} else {
2448            	last = now;
2449            	fn.apply( context, args );
2450          	}
2451        };
2452    };
2453
2454    MK.utils.isElementInViewport = function( el ) {
2455        var elemTop = el.getBoundingClientRect().top;
2456	    var isVisible = (elemTop < window.innerHeight);
2457	    return isVisible;
2458    };
2459
2460})(jQuery); 
2461(function($) {
2462	'use strict';
2463
2464    var MK = window.MK || {};
2465	MK.utils = window.MK.utils || {};
2466
2467	/**
2468	 * Scrolls page to static pixel offset
2469	 * @param  {Number}
2470	 */
2471	MK.utils.scrollTo = function( offset ) {
2472		$('html, body').stop().animate({
2473			scrollTop: offset
2474			}, {
2475	  		duration: 1200,
2476	  		easing: "easeInOutExpo"
2477		});
2478	};
2479
2480	/**
2481	 * Scrolls to element passed in as object or DOM reference
2482	 * @param  {String|Object}
2483	 */
2484	MK.utils.scrollToAnchor = function( hash ) {
2485		// Escape meta-chars from hash name only.
2486		hash = hash.substring(1).replace(/[!"#$%&'()*+,./:;<=>?@[\]^`{|}~]/g, "\\$&");
2487		hash = "#" + hash;
2488		var $target = $( hash );
2489		// console.log( hash );
2490
2491		if( ! $target.length ) return;
2492
2493		var offset  = $target.offset().top;
2494		offset = offset - MK.val.offsetHeaderHeight( offset );
2495
2496		if( hash === '#top-of-page' ) window.history.replaceState( undefined, undefined, ' ' );
2497		else window.history.replaceState( undefined, undefined, hash );
2498
2499		MK.utils.scrollTo( offset );
2500	};
2501
2502	/**
2503	 * Controls native scroll behaviour
2504	 * @return {Object} => {disable, enable}
2505	 */
2506	MK.utils.scroll = (function() {
2507        // 37 - left arror, 38 - up arrow, 39 right arrow, 40 down arrow
2508	    var keys = [38, 40];
2509
2510        function preventDefault(e) {
2511          e = e || window.event;
2512          e.preventDefault();
2513          e.returnValue = false;  
2514        }
2515
2516        function wheel(e) {
2517          preventDefault(e);
2518        }
2519
2520        function keydown(e) {
2521            for (var i = keys.length; i--;) {
2522                if (e.keyCode === keys[i]) {
2523                    preventDefault(e);
2524                    return;
2525                }
2526            }
2527        }
2528
2529        function disableScroll() {
2530            if (window.addEventListener) {
2531                window.addEventListener('DOMMouseScroll', wheel, false);
2532            }
2533          	window.onmousewheel = document.onmousewheel = wheel;
2534          	document.onkeydown = keydown;
2535        }
2536
2537        function enableScroll() {            
2538          	if (window.removeEventListener) {
2539                window.removeEventListener('DOMMouseScroll', wheel, false);
2540            }
2541            window.onmousewheel = document.onmousewheel = document.onkeydown = null; 
2542        }	
2543
2544        return {
2545        	disable : disableScroll,
2546        	enable  : enableScroll
2547        };
2548
2549	})();
2550
2551	/**
2552	 * Checks if passed link element has anchor inside current page. Returns string like '#anchor' if so or false
2553	 * @param  {String|Object}
2554	 * @return {String|Boolean}
2555	 */
2556	MK.utils.detectAnchor = function( el ) {
2557		var $this = $( el ),
2558			loc = window.location,
2559			currentPage = loc.origin + loc.pathname,
2560			href = $this.attr( 'href' ),
2561			linkSplit = (href) ? href.split( '#' ) : '',
2562			hrefPage  = linkSplit[0] ? linkSplit[0] : '', 
2563			hrefHash  = linkSplit[1] ? linkSplit[1] : '';
2564
2565		if( typeof hrefHash !== 'undefined' && hrefHash !== '' ) {
2566			return '#' + hrefHash;
2567		} else {
2568			return false;
2569		}
2570	};
2571
2572	/**
2573	 * This should be invoked only on page load. 
2574	 * Scrolls to anchor from  address bar
2575	 */
2576	MK.utils.scrollToURLHash = function() {
2577		var loc = window.location,
2578			hash = loc.hash;
2579
2580		if ( hash.length && hash.substring(1).length ) {
2581			// !loading is added early after DOM is ready to prevent native jump to anchor
2582			hash = hash.replace( '!loading', '' );
2583
2584			// Wait for one second before animating 
2585			// Most of UI animations should be done by then and async operations complited
2586			setTimeout( function() {
2587				MK.utils.scrollToAnchor( hash );
2588			}, 1000 ); 
2589
2590			// Right after reset back address bar
2591			setTimeout( function() {
2592				window.history.replaceState(undefined, undefined, hash);
2593			}, 1001);
2594		}
2595	};
2596
2597	/**
2598	 * Scroll Spy implementation. Spy dynamic offsets of elements or static pixel offset
2599	 * @param  {Number|Element}
2600	 * @param  {Object} => callback object {before, active, after}
2601	 */
2602	MK.utils.scrollSpy = function( toSpy, config ) {
2603		var $window   = $( window ),
2604	        container = document.getElementById( 'mk-theme-container' ),
2605	        isObj     = ( typeof toSpy === 'object' ),
2606	        offset    = (isObj) ? MK.val.dynamicOffset( toSpy, config.position, config.threshold ) : function() { return toSpy; },
2607	        height    = (isObj) ? MK.val.dynamicHeight( toSpy ) : function() { return 0; },
2608	        cacheVals = {},
2609	        _p 		  = 'before'; // current position
2610
2611		var checkPosition = function() {
2612	    	var s = MK.val.scroll(), 
2613	    		o = offset(),
2614	    		h = height();
2615
2616	        if( s < o && _p !== 'before' ) {
2617	        	// console.log( toSpy, 'before' );
2618	        	if( config.before ) config.before();
2619	        	_p = 'before';
2620	        } 
2621	        else if( s >= o && s <= o + h && _p !== 'active' ) {
2622	        	// console.log( toSpy, 'active' );
2623	        	if( config.active ) config.active( o );
2624	        	_p = 'active';
2625	        }
2626	        else if( s > o + h && _p !== 'after' ) {
2627	        	// console.log( toSpy, 'after' );
2628	        	if( config.after) config.after( o + h );
2629	        	_p = 'after';
2630	        }
2631		};
2632
2633		var rAF = function() {
2634			window.requestAnimationFrame( checkPosition );
2635		};
2636
2637		var exportVals = function() {
2638			return cacheVals;    
2639		};
2640
2641		var updateCache = function() {
2642	    	var o = offset(),
2643	    		h = height();
2644	    		
2645	        cacheVals = {
2646	        	before : o - $window.height(),
2647	        	active : o,
2648	        	after : o + h
2649	        };
2650		};
2651
2652		if( config.cache ) {
2653			config.cache( exportVals );
2654		}
2655
2656	    checkPosition();
2657	    $window.on( 'load', checkPosition );
2658	    $window.on( 'resize', checkPosition );
2659	    $window.on( 'mouseup', checkPosition );
2660   		window.addResizeListener( container, checkPosition );
2661
2662	    $window.on( 'scroll', rAF ); 
2663
2664   		updateCache();
2665	    $window.on( 'load', updateCache );
2666	    $window.on( 'resize', updateCache );
2667   		window.addResizeListener( container, updateCache );
2668	};
2669
2670}(jQuery));
2671(function($) {
2672    'use strict';
2673
2674    // Create delagation event handler to behave as "live" listener. We may provide new elements with ajax etc later
2675    // Just add js-taphover class whatever element you'd like to immidietely bring hover on touch devices
2676    $("body").on("click touchend", '.js-taphover', function (e) {
2677        var $link = $(e.currentTarget); // grab target
2678        var $target = $(e.target);
2679
2680        // Rather than ":hover" state we operate on ".hover" class which gives us more control and chance to emulate it on click
2681        // yet it is easy to reason about in our CSS
2682        if ($link.hasClass('hover')) {
2683            return true;
2684        } else if ( MK.utils.isMobile() ) {
2685            if ( ($target.hasClass('hover-icon') || $target.closest('.hover-icon').length) && !$target.closest('.js-taphover').hasClass('hover') ) {
2686                e.preventDefault();
2687            }
2688            $link.addClass('hover');
2689            $('.js-taphover').not(e.currentTarget).removeClass('hover'); // remove it from previous element
2690            e.stopPropagation(); // do not leak to document root if expected element was touched
2691        }
2692    });
2693
2694    // Whenever click leaks to the root romve all hover classes
2695    $(document).on("click", function(e) {
2696        $('.js-taphover').removeClass('hover');
2697    });
2698
2699}(jQuery));
2700// (function() {
2701//     'use strict';
2702
2703//     // Make sure the video behaves like background-size: cover
2704//     window.videoCover = function( holderSelector, videoSelector ) {
2705//         var videos = document.querySelectorAll( videoSelector ),
2706//             holder = document.querySelectorAll( holderSelector )[0];
2707
2708//         [].forEach.call(videos, function(video) {
2709
2710//             var videoAspectRatio;
2711
2712//             resizeBackground(); 
2713
2714//             video.onloadedmetadata = function() {
2715//                 // get images aspect ratio
2716//                 videoAspectRatio = this.height / this.width;
2717//                 // attach resize event and fire it once
2718//                 window.onresize = resizeBackground;
2719//                 resizeBackground();
2720//             };
2721
2722//             function resizeBackground() {
2723//                 // get window size and aspect ratio
2724//                 var holderWidth = holder.innerWidth,
2725//                     holderHeight = holder.innerHeight,
2726//                     holderAspectRatio = holderHeight / holderWidth;
2727
2728//                 //compare holder ratio to image ratio so you know which way the image should fill
2729//                 if ( holderAspectRatio < videoAspectRatio ) {
2730//                     // we are fill width
2731//                     video.style.width = holderWidth + "px";
2732//                     // and applying the correct aspect to the height now
2733//                     video.style.height = (holderWidth * videoAspectRatio) + "px"; // this can be margin if your element is not positioned relatively, absolutely or fixed
2734//                     // make sure image is always centered
2735//                     video.style.left = "0px";
2736//                     video.style.top = (holderHeight - (holderWidth * videoAspectRatio)) / 2 + "px";
2737//                 } else { // same thing as above but filling height instead
2738//                     video.style.height = holderHeight + "px";
2739//                     video.style.width = (holderHeight / videoAspectRatio) + "px";
2740//                     video.style.left = (holderWidth - (holderHeight / videoAspectRatio)) / 2 + "px";
2741//                     video.style.top = "0px";
2742//                 }
2743//             }
2744
2745//         });
2746//     };
2747
2748// }());
2749// 
2750// 
2751// 
2752// TODO it is temp only. make it as a plugin
2753
2754(function($) {
2755    'use strict';
2756
2757    var $videoHolder = $('.mk-center-video'),
2758        $wrapper = $videoHolder.parent(),
2759        baseAspectRatio = 56.25;
2760
2761    var wrapperHeight,
2762        wrapperWidth,
2763        wrapperAspectRatio;
2764
2765    function calc() {
2766        wrapperHeight = $wrapper.height();
2767        wrapperWidth = $wrapper.width();
2768        wrapperAspectRatio = (wrapperHeight / wrapperWidth) * 100;
2769    } 
2770
2771    function apply() {        
2772        var width = (wrapperAspectRatio / baseAspectRatio) * 100,
2773            widthOverflow = (width - 100);
2774
2775        $videoHolder.css({
2776            'padding-top': wrapperAspectRatio + '%',
2777            'width': width + '%',
2778            'left': -(widthOverflow / 2) + '%'
2779        }); 
2780    }
2781
2782    function reset() {
2783        $videoHolder.css({
2784            'padding-top': baseAspectRatio + '%',
2785            'width': 100 + '%',
2786            'left': 0
2787        });
2788    }
2789
2790    function setCover() {
2791        reset();
2792        calc();
2793        if(wrapperAspectRatio > baseAspectRatio) apply();
2794    }
2795
2796    $(window).on('load', setCover);
2797    $(window).on('resize', setCover);
2798
2799
2800}(jQuery));
2801(function($) {
2802	'use strict';
2803
2804	var MK = window.MK || {};
2805
2806	/**
2807	* 	MK.val is collection of Lambdas responsible for returning up to date values of method type like scrollY or el offset.
2808	* 	The Lambda is responsible for keeping track of value of a particular property, usually takes as argument an object
2809	* 	(or DOM reference) and internally creates and updates data that is returned as primitive value - through variable reference.
2810	*
2811	*  Benefits of this approach:
2812	*  - reduced DOM reads
2813	*  - auto-updating values without need for additional logic where methods are called
2814	*  - updating values when needed to be updated not read
2815	*
2816	*  Downsides:
2817	*  - Memory overhead with closures and keeping state in memory ( still beter than read state from DOM, but use wisely -
2818	*    do not use it when you really need static value on runtime )
2819	*/
2820	MK.val = {};
2821
2822	/**
2823	* Current window offsetY position
2824	*
2825	* @uses   MK.val.scroll()
2826	* @return {number}
2827	*/
2828	MK.val.scroll = (function() {
2829		var offset = 0,
2830		$window = $(window),
2831		hasPageYOffset = (window.pageYOffset !== undefined),
2832		body = (document.documentElement || document.body.parentNode || document.body); // cross browser handling
2833
2834		var update = function() {
2835			offset = hasPageYOffset ? window.pageYOffset : body.scrollTop;
2836		};
2837
2838		var rAF = function() {
2839			window.requestAnimationFrame(update);
2840		};
2841
2842		update();
2843		$window.on('load', update);
2844		$window.on('resize', update);
2845		$window.on('scroll', rAF);
2846
2847		return function() {
2848			return offset;
2849		};
2850	})();
2851
2852
2853	/**
2854	* Changes number of percent to pixels based on viewport height
2855	*
2856	* @uses   MK.val.viewportPercentHeight({percent val})
2857	* @param  {number}
2858	* @return {number}
2859	*/
2860	MK.val.viewportPercentHeight = function(percent) {
2861		return $(window).height() * (percent / 100);
2862	};
2863
2864
2865	/**
2866	* Wordpress adminbar height based on wp media queries
2867	* @return {Number}
2868	*/
2869	MK.val.adminbarHeight = function() {
2870		if (php.hasAdminbar) {
2871			// apply WP native media-query and sizes
2872			return (window.matchMedia('( max-width: 782px )').matches) ? 46 : 32;
2873		} else {
2874			return 0;
2875		}
2876	};
2877
2878
2879	/**
2880	* Offset when header becomes sticky. Evaluates viewport % and header height to pixels for according options
2881	* @return {Number}
2882	*/
2883	MK.val.stickyOffset = (function() {
2884		var $header = $('.mk-header').not('.js-header-shortcode').first();
2885
2886		// We need to have returning function even when header is disabled
2887		if (!$header.length) {
2888			return function() {
2889				return 0;
2890			};
2891		}
2892
2893
2894
2895		var $toolbar = $header.find('.mk-header-toolbar'),
2896		config = $header.data(),
2897		hasToolbar = $toolbar.length,
2898		toolbarHeight = (hasToolbar) ? $toolbar.height() : 0,
2899		isVertical = (config.headerStyle === 4),
2900		headerHeight = (isVertical) ? 0 : config.height;
2901
2902		var type = ((typeof config.stickyOffset === 'number') ? 'number' : false) ||
2903		((config.stickyOffset === 'header') ? 'header' : false) ||
2904		'percent';
2905
2906		var stickyOffset = 0;
2907		var setOffset = function() {
2908
2909			//we calculate toolbar height for When the device is changed Size
2910			//Toolbar height in responsive state is 0
2911			toolbarHeight = (hasToolbar) ? $toolbar.height() : 0;
2912
2913			if (MK.utils.isResponsiveMenuState()) {
2914				headerHeight = config.responsiveHeight;
2915
2916				if (hasToolbar) {
2917					if ($toolbar.is(':hidden')) {
2918						toolbarHeight = 0;
2919					}
2920				}
2921			}
2922
2923			if (type === 'number') {
2924				stickyOffset = config.stickyOffset;
2925			} else if (type === 'header') {
2926
2927				stickyOffset = headerHeight + toolbarHeight + MK.val.adminbarHeight(); // add all header components here, make them 0 if needed
2928
2929			} else if (type === 'percent') {
2930				stickyOffset = MK.val.viewportPercentHeight(parseInt(config.stickyOffset));
2931			}
2932		};
2933
2934		setOffset();
2935		$(window).on('resize', setOffset);
2936
2937		return function() {
2938			return stickyOffset;
2939		};
2940	}());
2941
2942
2943
2944	/**
2945	* Gets header height on particular offsetY position. Use to determine logic for fullHeight, smooth scroll etc.
2946	* Takes one parameter which is offset position we're interested in.
2947	*
2948	* @uses   MK.val.offsetHeaderHeight({offset val})
2949	* @param  {number}
2950	* @return {number}
2951	*/
2952	MK.val.offsetHeaderHeight = (function() { // Closure avoids multiple DOM reads. We need to fetch header config only once.
2953		var $header = $('.mk-header').not('.js-header-shortcode').first();
2954
2955		// We need to have returning function even when header is disabled
2956		if (!$header.length) {
2957			return function() {
2958				return 0;
2959			};
2960		}
2961
2962		var $toolbar = $header.find('.mk-header-toolbar'),
2963		config = $header.data(),
2964		stickyHeight = config.stickyHeight,
2965		desktopHeight = config.height,
2966		mobileHeight = config.responsiveHeight,
2967		isTransparent = $header.hasClass('transparent-header'),
2968		isSticky = config.stickyStyle.length,
2969		isStickyLazy = config.stickyStyle === 'lazy',
2970		isVertical = config.headerStyle === 4,
2971		hasToolbar = $toolbar.length,
2972		toolbarHeight = hasToolbar ? $toolbar.height() : 0,
2973		bufor = 5;
2974
2975		/**
2976		 * The sticky section of header style 2 has fixed height.
2977		 * The stickey height option does not affect this header style.
2978		 */
2979		if ( config.headerStyle === 2 ) {
2980			stickyHeight = $header.find( '.mk-header-nav-container' ).outerHeight();
2981		}
2982
2983		// if header has border bottom we can calculate that (for responsive state)
2984		var $innerHeader = $header.find('.mk-header-inner');
2985		var hasInnerHeader = $innerHeader.length;
2986
2987		var headerHeight = function(offset) {
2988
2989			toolbarHeight = hasToolbar ? $toolbar.height() : 0
2990			var stickyOffset = MK.val.stickyOffset();
2991
2992
2993			if (MK.utils.isResponsiveMenuState()) { //  Header avaible only on top for mobile
2994
2995				if (hasToolbar && $toolbar.is(':hidden')) {
2996					toolbarHeight = 0;
2997				}
2998
2999				//in responsive state , .mk-header-holder position's changed to "relative"
3000				//and header's border affected to offset,so borders must be calculated
3001				var headerBorder = 0;
3002				headerBorder = parseInt($innerHeader.css('border-bottom-width'));
3003
3004				var totalHeight = mobileHeight + MK.val.adminbarHeight() + toolbarHeight + headerBorder;
3005
3006				if (offset <= totalHeight) return totalHeight;
3007				else return MK.val.adminbarHeight();
3008			} else {
3009				if (offset <= stickyOffset) {
3010					if (isVertical) {
3011						if (hasToolbar) {
3012							return toolbarHeight + MK.val.adminbarHeight();
3013						} else {
3014							return MK.val.adminbarHeight();
3015						}
3016					} else if (isTransparent) {
3017						return MK.val.adminbarHeight();
3018					} else {
3019						return desktopHeight + toolbarHeight + MK.val.adminbarHeight();
3020					} // For any other return regular desktop height
3021				} else if (offset > stickyOffset) {
3022					if (isVertical) {
3023						return MK.val.adminbarHeight();
3024					} else if (!isSticky) {
3025						return MK.val.adminbarHeight();
3026					} else if (isStickyLazy) {
3027						return MK.val.adminbarHeight();
3028					} else if (isSticky) {
3029						return stickyHeight + MK.val.adminbarHeight();
3030					}
3031				}
3032			}
3033			// default to 0 to prevent errors ( need to return number )
3034			// Anyway make sure all scenarios are covered in IFs
3035			return 0;
3036		};
3037
3038		return function(offset) {
3039			return headerHeight(offset - MK.val.adminbarHeight());
3040		};
3041	})();
3042
3043
3044	/**
3045	* Gets current offset of given element (passed as object or DOM reference) from top or bottom (default to top)
3046	* of screen  with possible threshold (default to 0)
3047	*
3048	* @uses   MK.val.dynamicOffset({obj reference}, {'top'|'bottom'}, {threshold val})
3049	* @param  {string|object}
3050	* @param  {string}
3051	* @param  {number}
3052	* @return {number}
3053	*/
3054	MK.val.dynamicOffset = function(el, position, threshold) {
3055		var $window = $(window),
3056		$el = $(el),
3057		pos = position || 'top',
3058		thr = threshold || 0,
3059		container = document.getElementById('mk-theme-container'),
3060		currentPos = 0;
3061
3062		var offset = 0,
3063		winH = 0,
3064		rect = 0,
3065		x = 0;
3066
3067		var update = function() {
3068			winH = $window.height();
3069			rect = $el[0].getBoundingClientRect();
3070			offset = (rect.top + MK.val.scroll());
3071			x = (pos === 'top') ? MK.val.offsetHeaderHeight(offset) : winH + (rect.height - thr);
3072			currentPos = offset - x - 1;
3073		};
3074
3075		update();
3076		$window.on('load', update);
3077		$window.on('resize', update);
3078		window.addResizeListener(container, update);
3079
3080		return function() {
3081			return currentPos;
3082		};
3083	};
3084
3085	/**
3086	* Gets current height of given element (passed as object or DOM reference)
3087	*
3088	* @uses   MK.val.dynamicHeight({obj reference})
3089	* @param  {string|object}
3090	* @return {number}
3091	*/
3092	MK.val.dynamicHeight = function(el) {
3093		var $window = $(window),
3094		$el = $(el),
3095		container = document.getElementById('mk-theme-container'),
3096		currentHeight = 0;
3097
3098		var update = function() {
3099			currentHeight = $el.outerHeight();
3100		};
3101
3102		update();
3103		$window.on('load', update);
3104		$window.on('resize', update);
3105		window.addResizeListener(container, update);
3106
3107		return function() {
3108			return currentHeight;
3109		};
3110	};
3111
3112})(jQuery);
3113
3114/*
3115 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
3116 *
3117 */
3118jQuery.easing["jswing"] = jQuery.easing["swing"];
3119jQuery.extend(jQuery.easing, {
3120        def: "easeOutQuad",
3121        swing: function (a, b, c, d, e) {
3122                return jQuery.easing[jQuery.easing.def](a, b, c, d, e)
3123        },
3124        easeInQuad: function (a, b, c, d, e) {
3125                return d * (b /= e) * b + c
3126        },
3127        easeOutQuad: function (a, b, c, d, e) {
3128                return -d * (b /= e) * (b - 2) + c
3129        },
3130        easeInOutQuad: function (a, b, c, d, e) {
3131                if ((b /= e / 2) < 1) return d / 2 * b * b + c;
3132                return -d / 2 * (--b * (b - 2) - 1) + c
3133        },
3134        easeInCubic: function (a, b, c, d, e) {
3135                return d * (b /= e) * b * b + c
3136        },
3137        easeOutCubic: function (a, b, c, d, e) {
3138                return d * ((b = b / e - 1) * b * b + 1) + c
3139        },
3140        easeInOutCubic: function (a, b, c, d, e) {
3141                if ((b /= e / 2) < 1) return d / 2 * b * b * b + c;
3142                return d / 2 * ((b -= 2) * b * b + 2) + c
3143        },
3144        easeInQuart: function (a, b, c, d, e) {
3145                return d * (b /= e) * b * b * b + c
3146        },
3147        easeOutQuart: function (a, b, c, d, e) {
3148                return -d * ((b = b / e - 1) * b * b * b - 1) + c
3149        },
3150        easeInOutQuart: function (a, b, c, d, e) {
3151                if ((b /= e / 2) < 1) return d / 2 * b * b * b * b + c;
3152                return -d / 2 * ((b -= 2) * b * b * b - 2) + c
3153        },
3154        easeInQuint: function (a, b, c, d, e) {
3155                return d * (b /= e) * b * b * b * b + c
3156        },
3157        easeOutQuint: function (a, b, c, d, e) {
3158                return d * ((b = b / e - 1) * b * b * b * b + 1) + c
3159        },
3160        easeInOutQuint: function (a, b, c, d, e) {
3161                if ((b /= e / 2) < 1) return d / 2 * b * b * b * b * b + c;
3162                return d / 2 * ((b -= 2) * b * b * b * b + 2) + c
3163        },
3164        easeInSine: function (a, b, c, d, e) {
3165                return -d * Math.cos(b / e * (Math.PI / 2)) + d + c
3166        },
3167        easeOutSine: function (a, b, c, d, e) {
3168                return d * Math.sin(b / e * (Math.PI / 2)) + c
3169        },
3170        easeInOutSine: function (a, b, c, d, e) {
3171                return -d / 2 * (Math.cos(Math.PI * b / e) - 1) + c
3172        },
3173        easeInExpo: function (a, b, c, d, e) {
3174                return b == 0 ? c : d * Math.pow(2, 10 * (b / e - 1)) + c
3175        },
3176        easeOutExpo: function (a, b, c, d, e) {
3177                return b == e ? c + d : d * (-Math.pow(2, -10 * b / e) + 1) + c
3178        },
3179        easeInOutExpo: function (a, b, c, d, e) {
3180                if (b == 0) return c;
3181                if (b == e) return c + d;
3182                if ((b /= e / 2) < 1) return d / 2 * Math.pow(2, 10 * (b - 1)) + c;
3183                return d / 2 * (-Math.pow(2, -10 * --b) + 2) + c
3184        },
3185        easeInCirc: function (a, b, c, d, e) {
3186                return -d * (Math.sqrt(1 - (b /= e) * b) - 1) + c
3187        },
3188        easeOutCirc: function (a, b, c, d, e) {
3189                return d * Math.sqrt(1 - (b = b / e - 1) * b) + c
3190        },
3191        easeInOutCirc: function (a, b, c, d, e) {
3192                if ((b /= e / 2) < 1) return -d / 2 * (Math.sqrt(1 - b * b) - 1) + c;
3193                return d / 2 * (Math.sqrt(1 - (b -= 2) * b) + 1) + c
3194        },
3195        easeInElastic: function (a, b, c, d, e) {
3196                var f = 1.70158;
3197                var g = 0;
3198                var h = d;
3199                if (b == 0) return c;
3200                if ((b /= e) == 1) return c + d;
3201                if (!g) g = e * .3;
3202                if (h < Math.abs(d)) {
3203                        h = d;
3204                        var f = g / 4
3205                } else var f = g / (2 * Math.PI) * Math.asin(d / h);
3206                return -(h * Math.pow(2, 10 * (b -= 1)) * Math.sin((b * e - f) * 2 * Math.PI / g)) + c
3207        },
3208        easeOutElastic: function (a, b, c, d, e) {
3209                var f = 1.70158;
3210                var g = 0;
3211                var h = d;
3212                if (b == 0) return c;
3213                if ((b /= e) == 1) return c + d;
3214                if (!g) g = e * .3;
3215                if (h < Math.abs(d)) {
3216                        h = d;
3217                        var f = g / 4
3218                } else var f = g / (2 * Math.PI) * Math.asin(d / h);
3219                return h * Math.pow(2, -10 * b) * Math.sin((b * e - f) * 2 * Math.PI / g) + d + c
3220        },
3221        easeInOutElastic: function (a, b, c, d, e) {
3222                var f = 1.70158;
3223                var g = 0;
3224                var h = d;
3225                if (b == 0) return c;
3226                if ((b /= e / 2) == 2) return c + d;
3227                if (!g) g = e * .3 * 1.5;
3228                if (h < Math.abs(d)) {
3229                        h = d;
3230                        var f = g / 4
3231                } else var f = g / (2 * Math.PI) * Math.asin(d / h);
3232                if (b < 1) return -.5 * h * Math.pow(2, 10 * (b -= 1)) * Math.sin((b * e - f) * 2 * Math.PI / g) + c;
3233                return h * Math.pow(2, -10 * (b -= 1)) * Math.sin((b * e - f) * 2 * Math.PI / g) * .5 + d + c
3234        },
3235        easeInBack: function (a, b, c, d, e, f) {
3236                if (f == undefined) f = 1.70158;
3237                return d * (b /= e) * b * ((f + 1) * b - f) + c
3238        },
3239        easeOutBack: function (a, b, c, d, e, f) {
3240                if (f == undefined) f = 1.70158;
3241                return d * ((b = b / e - 1) * b * ((f + 1) * b + f) + 1) + c
3242        },
3243        easeInOutBack: function (a, b, c, d, e, f) {
3244                if (f == undefined) f = 1.70158;
3245                if ((b /= e / 2) < 1) return d / 2 * b * b * (((f *= 1.525) + 1) * b - f) + c;
3246                return d / 2 * ((b -= 2) * b * (((f *= 1.525) + 1) * b + f) + 2) + c
3247        },
3248        easeInBounce: function (a, b, c, d, e) {
3249                return d - jQuery.easing.easeOutBounce(a, e - b, 0, d, e) + c
3250        },
3251        easeOutBounce: function (a, b, c, d, e) {
3252                if ((b /= e) < 1 / 2.75) {
3253                        return d * 7.5625 * b * b + c
3254                } else if (b < 2 / 2.75) {
3255                        return d * (7.5625 * (b -= 1.5 / 2.75) * b + .75) + c
3256                } else if (b < 2.5 / 2.75) {
3257                        return d * (7.5625 * (b -= 2.25 / 2.75) * b + .9375) + c
3258                } else {
3259                        return d * (7.5625 * (b -= 2.625 / 2.75) * b + .984375) + c
3260                }
3261        },
3262        easeInOutBounce: function (a, b, c, d, e) {
3263                if (b < e / 2) return jQuery.easing.easeInBounce(a, b * 2, 0, d, e) * .5 + c;
3264                return jQuery.easing.easeOutBounce(a, b * 2 - e, 0, d, e) * .5 + d * .5 + c
3265        }
3266});
3267
3268/*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */
3269(function(s, H, f, w) {
3270    var K = f("html"),
3271        q = f(s),
3272        p = f(H),
3273        b = f.fancybox = function() {
3274            b.open.apply(this, arguments)
3275        },
3276        J = navigator.userAgent.match(/msie/i),
3277        C = null,
3278        t = H.createTouch !== w,
3279        u = function(a) {
3280            return a && a.hasOwnProperty && a instanceof f
3281        },
3282        r = function(a) {
3283            return a && "string" === f.type(a)
3284        },
3285        F = function(a) {
3286            return r(a) && 0 < a.indexOf("%")
3287        },
3288        m = function(a, d) {
3289            var e = parseInt(a, 10) || 0;
3290            d && F(a) && (e *= b.getViewport()[d] / 100);
3291            return Math.ceil(e)
3292        },
3293        x = function(a, b) {
3294            return m(a, b) + "px"
3295        };
3296    f.extend(b, {
3297        version: "2.1.5",
3298        defaults: {
3299            padding: 15,
3300            margin: 20,
3301            width: 800,
3302            height: 600,
3303            minWidth: 100,
3304            minHeight: 100,
3305            maxWidth: 9999,
3306            maxHeight: 9999,
3307            pixelRatio: 1,
3308            autoSize: !0,
3309            autoHeight: !1,
3310            autoWidth: !1,
3311            autoResize: !0,
3312            autoCenter: !t,
3313            fitToView: !0,
3314            aspectRatio: !1,
3315            topRatio: 0.5,
3316            leftRatio: 0.5,
3317            scrolling: "auto",
3318            wrapCSS: "",
3319            arrows: !0,
3320            closeBtn: !0,
3321            closeClick: !1,
3322            nextClick: !1,
3323            mouseWheel: !0,
3324            autoPlay: !1,
3325            playSpeed: 3E3,
3326            preload: 3,
3327            modal: !1,
3328            loop: !0,
3329            ajax: {
3330                dataType: "html",
3331                headers: {
3332                    "X-fancyBox": !0
3333                }
3334            },
3335            iframe: {
3336                scrolling: "auto",
3337                preload: !0
3338            },
3339            swf: {
3340                wmode: "transparent",
3341                allowfullscreen: "true",
3342                allowscriptaccess: "always"
3343            },
3344            keys: {
3345                next: {
3346                    13: "left",
3347                    34: "up",
3348                    39: "left",
3349                    40: "up"
3350                },
3351                prev: {
3352                    8: "right",
3353                    33: "down",
3354                    37: "right",
3355                    38: "down"
3356                },
3357                close: [27],
3358                play: [32],
3359                toggle: [70]
3360            },
3361            direction: {
3362                next: "left",
3363                prev: "right"
3364            },
3365            scrollOutside: !0,
3366            index: 0,
3367            type: null,
3368            href: null,
3369            content: null,
3370            title: null,
3371            tpl: {
3372                wrap: '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',
3373                image: '<img class="fancybox-image" src="{href}" alt="" />',
3374                iframe: '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' +
3375                    (J ? ' allowtransparency="true"' : "") + "></iframe>",
3376                error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
3377                closeBtn: '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',
3378                next: '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',
3379                prev: '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>'
3380            },
3381            openEffect: "fade",
3382            openSpeed: 250,
3383            openEasing: "swing",
3384            openOpacity: !0,
3385            openMethod: "zoomIn",
3386            closeEffect: "fade",
3387            closeSpeed: 250,
3388            closeEasing: "swing",
3389            closeOpacity: !0,
3390            closeMethod: "zoomOut",
3391            nextEffect: "elastic",
3392            nextSpeed: 250,
3393            nextEasing: "swing",
3394            nextMethod: "changeIn",
3395            prevEffect: "elastic",
3396            prevSpeed: 250,
3397            prevEasing: "swing",
3398            prevMethod: "changeOut",
3399            helpers: {
3400                overlay: !0,
3401                title: !0
3402            },
3403            onCancel: f.noop,
3404            beforeLoad: f.noop,
3405            afterLoad: f.noop,
3406            beforeShow: f.noop,
3407            afterShow: f.noop,
3408            beforeChange: f.noop,
3409            beforeClose: f.noop,
3410            afterClose: f.noop
3411        },
3412        group: {},
3413        opts: {},
3414        previous: null,
3415        coming: null,
3416        current: null,
3417        isActive: !1,
3418        isOpen: !1,
3419        isOpened: !1,
3420        wrap: null,
3421        skin: null,
3422        outer: null,
3423        inner: null,
3424        player: {
3425            timer: null,
3426            isActive: !1
3427        },
3428        ajaxLoad: null,
3429        imgPreload: null,
3430        transitions: {},
3431        helpers: {},
3432        open: function(a, d) {
3433            if (a && (f.isPlainObject(d) || (d = {}), !1 !== b.close(!0))) return f.isArray(a) || (a = u(a) ? f(a).get() : [a]), f.each(a, function(e, 
vendor: 34,462 bytes, lines 3433-4183
3433c) {
3434                var l = {},
3435                    g, h, k, n, m;
3436                "object" === f.type(c) && (c.nodeType && (c = f(c)), u(c) ? (l = {
3437                        href: c.data("fancybox-href") || c.attr("href"),
3438                        title: f("<div/>").text(c.data("fancybox-title") || c.attr("title")).html(),
3439                        isDom: !0,
3440                        element: c
3441                    },
3442                    f.metadata && f.extend(!0, l, c.metadata())) : l = c);
3443                g = d.href || l.href || (r(c) ? c : null);
3444                h = d.title !== w ? d.title : l.title || "";
3445                n = (k = d.content || l.content) ? "html" : d.type || l.type;
3446                !n && l.isDom && (n = c.data("fancybox-type"), n || (n = (n = c.prop("class").match(/fancybox\.(\w+)/)) ? n[1] : null));
3447                r(g) && (n || (b.isImage(g) ? n = "image" : b.isSWF(g) ? n = "swf" : "#" === g.charAt(0) ? n = "inline" : r(c) && (n = "html", k = c)), "ajax" === n && (m = g.split(/\s+/, 2), g = m.shift(), m = m.shift()));
3448                k || ("inline" === n ? g ? k = f(r(g) ? g.replace(/.*(?=#[^\s]+$)/, "") : g) : l.isDom && (k = c) :
3449                    "html" === n ? k = g : n || g || !l.isDom || (n = "inline", k = c));
3450                f.extend(l, {
3451                    href: g,
3452                    type: n,
3453                    content: k,
3454                    title: h,
3455                    selector: m
3456                });
3457                a[e] = l
3458            }), b.opts = f.extend(!0, {}, b.defaults, d), d.keys !== w && (b.opts.keys = d.keys ? f.extend({}, b.defaults.keys, d.keys) : !1), b.group = a, b._start(b.opts.index)
3459        },
3460        cancel: function() {
3461            var a = b.coming;
3462            a && !1 === b.trigger("onCancel") || (b.hideLoading(), a && (b.ajaxLoad && b.ajaxLoad.abort(), b.ajaxLoad = null, b.imgPreload && (b.imgPreload.onload = b.imgPreload.onerror = null), a.wrap && a.wrap.stop(!0, !0).trigger("onReset").remove(),
3463                b.coming = null, b.current || b._afterZoomOut(a)))
3464        },
3465        close: function(a) {
3466            b.cancel();
3467            !1 !== b.trigger("beforeClose") && (b.unbindEvents(), b.isActive && (b.isOpen && !0 !== a ? (b.isOpen = b.isOpened = !1, b.isClosing = !0, f(".fancybox-item, .fancybox-nav").remove(), b.wrap.stop(!0, !0).removeClass("fancybox-opened"), b.transitions[b.current.closeMethod]()) : (f(".fancybox-wrap").stop(!0).trigger("onReset").remove(), b._afterZoomOut())))
3468        },
3469        play: function(a) {
3470            var d = function() {
3471                    clearTimeout(b.player.timer)
3472                },
3473                e = function() {
3474                    d();
3475                    b.current && b.player.isActive &&
3476                        (b.player.timer = setTimeout(b.next, b.current.playSpeed))
3477                },
3478                c = function() {
3479                    d();
3480                    p.unbind(".player");
3481                    b.player.isActive = !1;
3482                    b.trigger("onPlayEnd")
3483                };
3484            !0 === a || !b.player.isActive && !1 !== a ? b.current && (b.current.loop || b.current.index < b.group.length - 1) && (b.player.isActive = !0, p.bind({
3485                "onCancel.player beforeClose.player": c,
3486                "onUpdate.player": e,
3487                "beforeLoad.player": d
3488            }), e(), b.trigger("onPlayStart")) : c()
3489        },
3490        next: function(a) {
3491            var d = b.current;
3492            d && (r(a) || (a = d.direction.next), b.jumpto(d.index + 1, a, "next"))
3493        },
3494        prev: function(a) {
3495            var d =
3496                b.current;
3497            d && (r(a) || (a = d.direction.prev), b.jumpto(d.index - 1, a, "prev"))
3498        },
3499        jumpto: function(a, d, e) {
3500            var c = b.current;
3501            c && (a = m(a), b.direction = d || c.direction[a >= c.index ? "next" : "prev"], b.router = e || "jumpto", c.loop && (0 > a && (a = c.group.length + a % c.group.length), a %= c.group.length), c.group[a] !== w && (b.cancel(), b._start(a)))
3502        },
3503        reposition: function(a, d) {
3504            var e = b.current,
3505                c = e ? e.wrap : null,
3506                l;
3507            c && (l = b._getPosition(d), a && "scroll" === a.type ? (delete l.position, c.stop(!0, !0).animate(l, 200)) : (c.css(l), e.pos = f.extend({}, e.dim, l)))
3508        },
3509        update: function(a) {
3510            var d = a && a.originalEvent && a.originalEvent.type,
3511                e = !d || "orientationchange" === d;
3512            e && (clearTimeout(C), C = null);
3513            b.isOpen && !C && (C = setTimeout(function() {
3514                var c = b.current;
3515                c && !b.isClosing && (b.wrap.removeClass("fancybox-tmp"), (e || "load" === d || "resize" === d && c.autoResize) && b._setDimension(), "scroll" === d && c.canShrink || b.reposition(a), b.trigger("onUpdate"), C = null)
3516            }, e && !t ? 0 : 300))
3517        },
3518        toggle: function(a) {
3519            b.isOpen && (b.current.fitToView = "boolean" === f.type(a) ? a : !b.current.fitToView, t && (b.wrap.removeAttr("style").addClass("fancybox-tmp"),
3520                b.trigger("onUpdate")), b.update())
3521        },
3522        hideLoading: function() {
3523            p.unbind(".loading");
3524            f("#fancybox-loading").remove()
3525        },
3526        showLoading: function() {
3527            var a, d;
3528            b.hideLoading();
3529            a = f('<div id="fancybox-loading"><div></div></div>').click(b.cancel).appendTo("body");
3530            p.bind("keydown.loading", function(a) {
3531                27 === (a.which || a.keyCode) && (a.preventDefault(), b.cancel())
3532            });
3533            b.defaults.fixed || (d = b.getViewport(), a.css({
3534                position: "absolute",
3535                top: 0.5 * d.h + d.y,
3536                left: 0.5 * d.w + d.x
3537            }));
3538            b.trigger("onLoading")
3539        },
3540        getViewport: function() {
3541            var a = b.current &&
3542                b.current.locked || !1,
3543                d = {
3544                    x: q.scrollLeft(),
3545                    y: q.scrollTop()
3546                };
3547            a && a.length ? (d.w = a[0].clientWidth, d.h = a[0].clientHeight) : (d.w = t && s.innerWidth ? s.innerWidth : q.width(), d.h = t && s.innerHeight ? s.innerHeight : q.height());
3548            return d
3549        },
3550        unbindEvents: function() {
3551            b.wrap && u(b.wrap) && b.wrap.unbind(".fb");
3552            p.unbind(".fb");
3553            q.unbind(".fb")
3554        },
3555        bindEvents: function() {
3556            var a = b.current,
3557                d;
3558            a && (q.bind("orientationchange.fb" + (t ? "" : " resize.fb") + (a.autoCenter && !a.locked ? " scroll.fb" : ""), b.update), (d = a.keys) && p.bind("keydown.fb", function(e) {
3559                var c =
3560                    e.which || e.keyCode,
3561                    l = e.target || e.srcElement;
3562                if (27 === c && b.coming) return !1;
3563                e.ctrlKey || e.altKey || e.shiftKey || e.metaKey || l && (l.type || f(l).is("[contenteditable]")) || f.each(d, function(d, l) {
3564                    if (1 < a.group.length && l[c] !== w) return b[d](l[c]), e.preventDefault(), !1;
3565                    if (-1 < f.inArray(c, l)) return b[d](), e.preventDefault(), !1
3566                })
3567            }), f.fn.mousewheel && a.mouseWheel && b.wrap.bind("mousewheel.fb", function(d, c, l, g) {
3568                for (var h = f(d.target || null), k = !1; h.length && !(k || h.is(".fancybox-skin") || h.is(".fancybox-wrap"));) k = h[0] && !(h[0].style.overflow &&
3569                    "hidden" === h[0].style.overflow) && (h[0].clientWidth && h[0].scrollWidth > h[0].clientWidth || h[0].clientHeight && h[0].scrollHeight > h[0].clientHeight), h = f(h).parent();
3570                0 !== c && !k && 1 < b.group.length && !a.canShrink && (0 < g || 0 < l ? b.prev(0 < g ? "down" : "left") : (0 > g || 0 > l) && b.next(0 > g ? "up" : "right"), d.preventDefault())
3571            }))
3572        },
3573        trigger: function(a, d) {
3574            var e, c = d || b.coming || b.current;
3575            if (c) {
3576                f.isFunction(c[a]) && (e = c[a].apply(c, Array.prototype.slice.call(arguments, 1)));
3577                if (!1 === e) return !1;
3578                c.helpers && f.each(c.helpers, function(d, e) {
3579                    if (e &&
3580                        b.helpers[d] && f.isFunction(b.helpers[d][a])) b.helpers[d][a](f.extend(!0, {}, b.helpers[d].defaults, e), c)
3581                })
3582            }
3583            p.trigger(a)
3584        },
3585        isImage: function(a) {
3586            return r(a) && a.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)
3587        },
3588        isSWF: function(a) {
3589            return r(a) && a.match(/\.(swf)((\?|#).*)?$/i)
3590        },
3591        _start: function(a) {
3592            var d = {},
3593                e, c;
3594            a = m(a);
3595            e = b.group[a] || null;
3596            if (!e) return !1;
3597            d = f.extend(!0, {}, b.opts, e);
3598            e = d.margin;
3599            c = d.padding;
3600            "number" === f.type(e) && (d.margin = [e, e, e, e]);
3601            "number" === f.type(c) && (d.padding = [c, c,
3602                c, c
3603            ]);
3604            d.modal && f.extend(!0, d, {
3605                closeBtn: !1,
3606                closeClick: !1,
3607                nextClick: !1,
3608                arrows: !1,
3609                mouseWheel: !1,
3610                keys: null,
3611                helpers: {
3612                    overlay: {
3613                        closeClick: !1
3614                    }
3615                }
3616            });
3617            d.autoSize && (d.autoWidth = d.autoHeight = !0);
3618            "auto" === d.width && (d.autoWidth = !0);
3619            "auto" === d.height && (d.autoHeight = !0);
3620            d.group = b.group;
3621            d.index = a;
3622            b.coming = d;
3623            if (!1 === b.trigger("beforeLoad")) b.coming = null;
3624            else {
3625                c = d.type;
3626                e = d.href;
3627                if (!c) return b.coming = null, b.current && b.router && "jumpto" !== b.router ? (b.current.index = a, b[b.router](b.direction)) : !1;
3628                b.isActive = !0;
3629                if ("image" ===
3630                    c || "swf" === c) d.autoHeight = d.autoWidth = !1, d.scrolling = "visible";
3631                "image" === c && (d.aspectRatio = !0);
3632                "iframe" === c && t && (d.scrolling = "scroll");
3633                d.wrap = f(d.tpl.wrap).addClass("fancybox-" + (t ? "mobile" : "desktop") + " fancybox-type-" + c + " fancybox-tmp " + d.wrapCSS).appendTo(d.parent || "body");
3634                f.extend(d, {
3635                    skin: f(".fancybox-skin", d.wrap),
3636                    outer: f(".fancybox-outer", d.wrap),
3637                    inner: f(".fancybox-inner", d.wrap)
3638                });
3639                f.each(["Top", "Right", "Bottom", "Left"], function(a, b) {
3640                    d.skin.css("padding" + b, x(d.padding[a]))
3641                });
3642                b.trigger("onReady");
3643                if ("inline" === c || "html" === c) {
3644                    if (!d.content || !d.content.length) return b._error("content")
3645                } else if (!e) return b._error("href");
3646                "image" === c ? b._loadImage() : "ajax" === c ? b._loadAjax() : "iframe" === c ? b._loadIframe() : b._afterLoad()
3647            }
3648        },
3649        _error: function(a) {
3650            f.extend(b.coming, {
3651                type: "html",
3652                autoWidth: !0,
3653                autoHeight: !0,
3654                minWidth: 0,
3655                minHeight: 0,
3656                scrolling: "no",
3657                hasError: a,
3658                content: b.coming.tpl.error
3659            });
3660            b._afterLoad()
3661        },
3662        _loadImage: function() {
3663            var a = b.imgPreload = new Image;
3664            a.onload = function() {
3665                this.onload = this.onerror = null;
3666                b.coming.width =
3667                    this.width / b.opts.pixelRatio;
3668                b.coming.height = this.height / b.opts.pixelRatio;
3669                b._afterLoad()
3670            };
3671            a.onerror = function() {
3672                this.onload = this.onerror = null;
3673                b._error("image")
3674            };
3675            a.src = b.coming.href;
3676            !0 !== a.complete && b.showLoading()
3677        },
3678        _loadAjax: function() {
3679            var a = b.coming;
3680            b.showLoading();
3681            b.ajaxLoad = f.ajax(f.extend({}, a.ajax, {
3682                url: a.href,
3683                error: function(a, e) {
3684                    b.coming && "abort" !== e ? b._error("ajax", a) : b.hideLoading()
3685                },
3686                success: function(d, e) {
3687                    "success" === e && (a.content = d, b._afterLoad())
3688                }
3689            }))
3690        },
3691        _loadIframe: function() {
3692            var a = b.coming,
3693                d = f(a.tpl.iframe.replace(/\{rnd\}/g, (new Date).getTime())).attr("scrolling", t ? "auto" : a.iframe.scrolling).attr("src", a.href);
3694            f(a.wrap).bind("onReset", function() {
3695                try {
3696                    f(this).find("iframe").hide().attr("src", "//about:blank").end().empty()
3697                } catch (a) {}
3698            });
3699            a.iframe.preload && (b.showLoading(), d.one("load", function() {
3700                f(this).data("ready", 1);
3701                t || f(this).bind("load.fb", b.update);
3702                f(this).parents(".fancybox-wrap").width("100%").removeClass("fancybox-tmp").show();
3703                b._afterLoad()
3704            }));
3705            a.content = d.appendTo(a.inner);
3706            a.iframe.preload ||
3707                b._afterLoad()
3708        },
3709        _preloadImages: function() {
3710            var a = b.group,
3711                d = b.current,
3712                e = a.length,
3713                c = d.preload ? Math.min(d.preload, e - 1) : 0,
3714                f, g;
3715            for (g = 1; g <= c; g += 1) f = a[(d.index + g) % e], "image" === f.type && f.href && ((new Image).src = f.href)
3716        },
3717        _afterLoad: function() {
3718            var a = b.coming,
3719                d = b.current,
3720                e, c, l, g, h;
3721            b.hideLoading();
3722            if (a && !1 !== b.isActive)
3723                if (!1 === b.trigger("afterLoad", a, d)) a.wrap.stop(!0).trigger("onReset").remove(), b.coming = null;
3724                else {
3725                    d && (b.trigger("beforeChange", d), d.wrap.stop(!0).removeClass("fancybox-opened").find(".fancybox-item, .fancybox-nav").remove());
3726                    b.unbindEvents();
3727                    e = a.content;
3728                    c = a.type;
3729                    l = a.scrolling;
3730                    f.extend(b, {
3731                        wrap: a.wrap,
3732                        skin: a.skin,
3733                        outer: a.outer,
3734                        inner: a.inner,
3735                        current: a,
3736                        previous: d
3737                    });
3738                    g = a.href;
3739                    switch (c) {
3740                        case "inline":
3741                        case "ajax":
3742                        case "html":
3743                            a.selector ? e = f("<div>").html(e).find(a.selector) : u(e) && (e.data("fancybox-placeholder") || e.data("fancybox-placeholder", f('<div class="fancybox-placeholder"></div>').insertAfter(e).hide()), e = e.show().detach(), a.wrap.bind("onReset", function() {
3744                                f(this).find(e).length && e.hide().replaceAll(e.data("fancybox-placeholder")).data("fancybox-placeholder", !1)
3745                            }));
3746                            break;
3747                        case "image":
3748                            e = a.tpl.image.replace(/\{href\}/g, g);
3749                            break;
3750                        case "swf":
3751                            e = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + g + '"></param>', h = "", f.each(a.swf, function(a, b) {
3752                                e += '<param name="' + a + '" value="' + b + '"></param>';
3753                                h += " " + a + '="' + b + '"'
3754                            }), e += '<embed src="' + g + '" type="application/x-shockwave-flash" width="100%" height="100%"' + h + "></embed></object>"
3755                    }
3756                    u(e) && e.parent().is(a.inner) || a.inner.append(e);
3757                    b.trigger("beforeShow");
3758                    a.inner.css("overflow", "yes" === l ? "scroll" : "no" === l ? "hidden" : l);
3759                    b._setDimension();
3760                    b.reposition();
3761                    b.isOpen = !1;
3762                    b.coming = null;
3763                    b.bindEvents();
3764                    if (!b.isOpened) f(".fancybox-wrap").not(a.wrap).stop(!0).trigger("onReset").remove();
3765                    else if (d.prevMethod) b.transitions[d.prevMethod]();
3766                    b.transitions[b.isOpened ? a.nextMethod : a.openMethod]();
3767                    b._preloadImages()
3768                }
3769        },
3770        _setDimension: function() {
3771            var a = b.getViewport(),
3772                d = 0,
3773                e = !1,
3774                c = !1,
3775                e = b.wrap,
3776                l = b.skin,
3777                g = b.inner,
3778                h = b.current,
3779                c = h.width,
3780                k = h.height,
3781                n = h.minWidth,
3782                v = h.minHeight,
3783                p = h.maxWidth,
3784                q = h.maxHeight,
3785                t = h.scrolling,
3786                r = h.scrollOutside ? h.scrollbarWidth : 0,
3787                y = h.margin,
3788                z = m(y[1] + y[3]),
3789                s = m(y[0] + y[2]),
3790                w, A, u, D, B, G, C, E, I;
3791            e.add(l).add(g).width("auto").height("auto").removeClass("fancybox-tmp");
3792            y = m(l.outerWidth(!0) - l.width());
3793            w = m(l.outerHeight(!0) - l.height());
3794            A = z + y;
3795            u = s + w;
3796            D = F(c) ? (a.w - A) * m(c) / 100 : c;
3797            B = F(k) ? (a.h - u) * m(k) / 100 : k;
3798            if ("iframe" === h.type) {
3799                if (I = h.content, h.autoHeight && 1 === I.data("ready")) try {
3800                    I[0].contentWindow.document.location && (g.width(D).height(9999), G = I.contents().find("body"), r && G.css("overflow-x",
3801                        "hidden"), B = G.outerHeight(!0))
3802                } catch (H) {}
3803            } else if (h.autoWidth || h.autoHeight) g.addClass("fancybox-tmp"), h.autoWidth || g.width(D), h.autoHeight || g.height(B), h.autoWidth && (D = g.width()), h.autoHeight && (B = g.height()), g.removeClass("fancybox-tmp");
3804            c = m(D);
3805            k = m(B);
3806            E = D / B;
3807            n = m(F(n) ? m(n, "w") - A : n);
3808            p = m(F(p) ? m(p, "w") - A : p);
3809            v = m(F(v) ? m(v, "h") - u : v);
3810            q = m(F(q) ? m(q, "h") - u : q);
3811            G = p;
3812            C = q;
3813            h.fitToView && (p = Math.min(a.w - A, p), q = Math.min(a.h - u, q));
3814            A = a.w - z;
3815            s = a.h - s;
3816            h.aspectRatio ? (c > p && (c = p, k = m(c / E)), k > q && (k = q, c = m(k * E)), c < n && (c = n, k = m(c /
3817                E)), k < v && (k = v, c = m(k * E))) : (c = Math.max(n, Math.min(c, p)), h.autoHeight && "iframe" !== h.type && (g.width(c), k = g.height()), k = Math.max(v, Math.min(k, q)));
3818            if (h.fitToView)
3819                if (g.width(c).height(k), e.width(c + y), a = e.width(), z = e.height(), h.aspectRatio)
3820                    for (;
3821                        (a > A || z > s) && c > n && k > v && !(19 < d++);) k = Math.max(v, Math.min(q, k - 10)), c = m(k * E), c < n && (c = n, k = m(c / E)), c > p && (c = p, k = m(c / E)), g.width(c).height(k), e.width(c + y), a = e.width(), z = e.height();
3822                else c = Math.max(n, Math.min(c, c - (a - A))), k = Math.max(v, Math.min(k, k - (z - s)));
3823            r && "auto" === t && k < B &&
3824                c + y + r < A && (c += r);
3825            g.width(c).height(k);
3826            e.width(c + y);
3827            a = e.width();
3828            z = e.height();
3829            e = (a > A || z > s) && c > n && k > v;
3830            c = h.aspectRatio ? c < G && k < C && c < D && k < B : (c < G || k < C) && (c < D || k < B);
3831            f.extend(h, {
3832                dim: {
3833                    width: x(a),
3834                    height: x(z)
3835                },
3836                origWidth: D,
3837                origHeight: B,
3838                canShrink: e,
3839                canExpand: c,
3840                wPadding: y,
3841                hPadding: w,
3842                wrapSpace: z - l.outerHeight(!0),
3843                skinSpace: l.height() - k
3844            });
3845            !I && h.autoHeight && k > v && k < q && !c && g.height("auto")
3846        },
3847        _getPosition: function(a) {
3848            var d = b.current,
3849                e = b.getViewport(),
3850                c = d.margin,
3851                f = b.wrap.width() + c[1] + c[3],
3852                g = b.wrap.height() + c[0] + c[2],
3853                c = {
3854                    position: "absolute",
3855                    top: c[0],
3856                    left: c[3]
3857                };
3858            d.autoCenter && d.fixed && !a && g <= e.h && f <= e.w ? c.position = "fixed" : d.locked || (c.top += e.y, c.left += e.x);
3859            c.top = x(Math.max(c.top, c.top + (e.h - g) * d.topRatio));
3860            c.left = x(Math.max(c.left, c.left + (e.w - f) * d.leftRatio));
3861            return c
3862        },
3863        _afterZoomIn: function() {
3864            var a = b.current;
3865            a && ((b.isOpen = b.isOpened = !0, b.wrap.css("overflow", "visible").addClass("fancybox-opened"), b.update(), (a.closeClick || a.nextClick && 1 < b.group.length) && b.inner.css("cursor", "pointer").bind("click.fb", function(d) {
3866                f(d.target).is("a") || f(d.target).parent().is("a") ||
3867                    (d.preventDefault(), b[a.closeClick ? "close" : "next"]())
3868            }), a.closeBtn && f(a.tpl.closeBtn).appendTo(b.skin).bind("click.fb", function(a) {
3869                a.preventDefault();
3870                b.close()
3871            }), a.arrows && 1 < b.group.length && ((a.loop || 0 < a.index) && f(a.tpl.prev).appendTo(b.outer).bind("click.fb", b.prev), (a.loop || a.index < b.group.length - 1) && f(a.tpl.next).appendTo(b.outer).bind("click.fb", b.next)), b.trigger("afterShow"), a.loop || a.index !== a.group.length - 1) ? b.opts.autoPlay && !b.player.isActive && (b.opts.autoPlay = !1, b.play(!0)) : b.play(!1))
3872        },
3873        _afterZoomOut: function(a) {
3874            a = a || b.current;
3875            f(".fancybox-wrap").trigger("onReset").remove();
3876            f.extend(b, {
3877                group: {},
3878                opts: {},
3879                router: !1,
3880                current: null,
3881                isActive: !1,
3882                isOpened: !1,
3883                isOpen: !1,
3884                isClosing: !1,
3885                wrap: null,
3886                skin: null,
3887                outer: null,
3888                inner: null
3889            });
3890            b.trigger("afterClose", a)
3891        }
3892    });
3893    b.transitions = {
3894        getOrigPosition: function() {
3895            var a = b.current,
3896                d = a.element,
3897                e = a.orig,
3898                c = {},
3899                f = 50,
3900                g = 50,
3901                h = a.hPadding,
3902                k = a.wPadding,
3903                n = b.getViewport();
3904            !e && a.isDom && d.is(":visible") && (e = d.find("img:first"), e.length || (e = d));
3905            u(e) ? (c = e.offset(), e.is("img") &&
3906                (f = e.outerWidth(), g = e.outerHeight())) : (c.top = n.y + (n.h - g) * a.topRatio, c.left = n.x + (n.w - f) * a.leftRatio);
3907            if ("fixed" === b.wrap.css("position") || a.locked) c.top -= n.y, c.left -= n.x;
3908            return c = {
3909                top: x(c.top - h * a.topRatio),
3910                left: x(c.left - k * a.leftRatio),
3911                width: x(f + k),
3912                height: x(g + h)
3913            }
3914        },
3915        step: function(a, d) {
3916            var e, c, f = d.prop;
3917            c = b.current;
3918            var g = c.wrapSpace,
3919                h = c.skinSpace;
3920            if ("width" === f || "height" === f) e = d.end === d.start ? 1 : (a - d.start) / (d.end - d.start), b.isClosing && (e = 1 - e), c = "width" === f ? c.wPadding : c.hPadding, c = a - c, b.skin[f](m("width" ===
3921                f ? c : c - g * e)), b.inner[f](m("width" === f ? c : c - g * e - h * e))
3922        },
3923        zoomIn: function() {
3924            var a = b.current,
3925                d = a.pos,
3926                e = a.openEffect,
3927                c = "elastic" === e,
3928                l = f.extend({
3929                    opacity: 1
3930                }, d);
3931            delete l.position;
3932            c ? (d = this.getOrigPosition(), a.openOpacity && (d.opacity = 0.1)) : "fade" === e && (d.opacity = 0.1);
3933            b.wrap.css(d).animate(l, {
3934                duration: "none" === e ? 0 : a.openSpeed,
3935                easing: a.openEasing,
3936                step: c ? this.step : null,
3937                complete: b._afterZoomIn
3938            })
3939        },
3940        zoomOut: function() {
3941            var a = b.current,
3942                d = a.closeEffect,
3943                e = "elastic" === d,
3944                c = {
3945                    opacity: 0.1
3946                };
3947            e && (c = this.getOrigPosition(), a.closeOpacity &&
3948                (c.opacity = 0.1));
3949            b.wrap.animate(c, {
3950                duration: "none" === d ? 0 : a.closeSpeed,
3951                easing: a.closeEasing,
3952                step: e ? this.step : null,
3953                complete: b._afterZoomOut
3954            })
3955        },
3956        changeIn: function() {
3957            var a = b.current,
3958                d = a.nextEffect,
3959                e = a.pos,
3960                c = {
3961                    opacity: 1
3962                },
3963                f = b.direction,
3964                g;
3965            e.opacity = 0.1;
3966            "elastic" === d && (g = "down" === f || "up" === f ? "top" : "left", "down" === f || "right" === f ? (e[g] = x(m(e[g]) - 200), c[g] = "+=200px") : (e[g] = x(m(e[g]) + 200), c[g] = "-=200px"));
3967            "none" === d ? b._afterZoomIn() : b.wrap.css(e).animate(c, {
3968                duration: a.nextSpeed,
3969                easing: a.nextEasing,
3970                complete: b._afterZoomIn
3971            })
3972        },
3973        changeOut: function() {
3974            var a = b.previous,
3975                d = a.prevEffect,
3976                e = {
3977                    opacity: 0.1
3978                },
3979                c = b.direction;
3980            "elastic" === d && (e["down" === c || "up" === c ? "top" : "left"] = ("up" === c || "left" === c ? "-" : "+") + "=200px");
3981            a.wrap.animate(e, {
3982                duration: "none" === d ? 0 : a.prevSpeed,
3983                easing: a.prevEasing,
3984                complete: function() {
3985                    f(this).trigger("onReset").remove()
3986                }
3987            })
3988        }
3989    };
3990    b.helpers.overlay = {
3991        defaults: {
3992            closeClick: !0,
3993            speedOut: 200,
3994            showEarly: !0,
3995            css: {},
3996            locked: !t,
3997            fixed: !0
3998        },
3999        overlay: null,
4000        fixed: !1,
4001        el: f("html"),
4002        create: function(a) {
4003            var d;
4004            a = f.extend({}, this.defaults, a);
4005            this.overlay &&
4006                this.close();
4007            d = b.coming ? b.coming.parent : a.parent;
4008            this.overlay = f('<div class="fancybox-overlay"></div>').appendTo(d && d.lenth ? d : "body");
4009            this.fixed = !1;
4010            a.fixed && b.defaults.fixed && (this.overlay.addClass("fancybox-overlay-fixed"), this.fixed = !0)
4011        },
4012        open: function(a) {
4013            var d = this;
4014            a = f.extend({}, this.defaults, a);
4015            this.overlay ? this.overlay.unbind(".overlay").width("auto").height("auto") : this.create(a);
4016            this.fixed || (q.bind("resize.overlay", f.proxy(this.update, this)), this.update());
4017            a.closeClick && this.overlay.bind("click.overlay",
4018                function(a) {
4019                    if (f(a.target).hasClass("fancybox-overlay")) return b.isActive ? b.close() : d.close(), !1
4020                });
4021            this.overlay.css(a.css).show()
4022        },
4023        close: function() {
4024            q.unbind("resize.overlay");
4025            this.el.hasClass("fancybox-lock") && (f(".fancybox-margin").removeClass("fancybox-margin"), this.el.removeClass("fancybox-lock"), q.scrollTop(this.scrollV).scrollLeft(this.scrollH));
4026            f(".fancybox-overlay").remove().hide();
4027            f.extend(this, {
4028                overlay: null,
4029                fixed: !1
4030            })
4031        },
4032        update: function() {
4033            var a = "100%",
4034                b;
4035            this.overlay.width(a).height("100%");
4036            J ? (b = Math.max(H.documentElement.offsetWidth, H.body.offsetWidth), p.width() > b && (a = p.width())) : p.width() > q.width() && (a = p.width());
4037            this.overlay.width(a).height(p.height())
4038        },
4039        onReady: function(a, b) {
4040            var e = this.overlay;
4041            f(".fancybox-overlay").stop(!0, !0);
4042            e || this.create(a);
4043            a.locked && this.fixed && b.fixed && (b.locked = this.overlay.append(b.wrap), b.fixed = !1);
4044            !0 === a.showEarly && this.beforeShow.apply(this, arguments)
4045        },
4046        beforeShow: function(a, b) {
4047            b.locked && !this.el.hasClass("fancybox-lock") && (!1 !== this.fixPosition && f("*").filter(function() {
4048                return "fixed" ===
4049                    f(this).css("position") && !f(this).hasClass("fancybox-overlay") && !f(this).hasClass("fancybox-wrap")
4050            }).addClass("fancybox-margin"), this.el.addClass("fancybox-margin"), this.scrollV = q.scrollTop(), this.scrollH = q.scrollLeft(), this.el.addClass("fancybox-lock"), q.scrollTop(this.scrollV).scrollLeft(this.scrollH));
4051            this.open(a)
4052        },
4053        onUpdate: function() {
4054            this.fixed || this.update()
4055        },
4056        afterClose: function(a) {
4057            this.overlay && !b.coming && this.overlay.fadeOut(a.speedOut, f.proxy(this.close, this))
4058        }
4059    };
4060    b.helpers.title = {
4061        defaults: {
4062            type: "float",
4063            position: "bottom"
4064        },
4065        beforeShow: function(a) {
4066            var d = b.current,
4067                e = d.title,
4068                c = a.type;
4069            f.isFunction(e) && (e = e.call(d.element, d));
4070            if (r(e) && "" !== f.trim(e)) {
4071                d = f('<div class="fancybox-title fancybox-title-' + c + '-wrap">' + e + "</div>");
4072                switch (c) {
4073                    case "inside":
4074                        c = b.skin;
4075                        break;
4076                    case "outside":
4077                        c = b.wrap;
4078                        break;
4079                    case "over":
4080                        c = b.inner;
4081                        break;
4082                    default:
4083                        c = b.skin, d.appendTo("body"), J && d.width(d.width()), d.wrapInner('<span class="child"></span>'), b.current.margin[2] += Math.abs(m(d.css("margin-bottom")))
4084                }
4085                d["top" === a.position ? "prependTo" :
4086                    "appendTo"](c)
4087            }
4088        }
4089    };
4090    f.fn.fancybox = function(a) {
4091        var d, e = f(this),
4092            c = this.selector || "",
4093            l = function(g) {
4094                var h = f(this).blur(),
4095                    k = d,
4096                    l, m;
4097                g.ctrlKey || g.altKey || g.shiftKey || g.metaKey || h.is(".fancybox-wrap") || (l = a.groupAttr || "data-fancybox-group", m = h.attr(l), m || (l = "rel", m = h.get(0)[l]), m && "" !== m && "nofollow" !== m && (h = c.length ? f(c) : e, h = h.filter("[" + l + '="' + m + '"]'), k = h.index(this)), a.index = k, !1 !== b.open(h, a) && g.preventDefault())
4098            };
4099        a = a || {};
4100        d = a.index || 0;
4101        c && !1 !== a.live ? p.undelegate(c, "click.fb-start").delegate(c + ":not('.fancybox-item, .fancybox-nav')",
4102            "click.fb-start", l) : e.unbind("click.fb-start").bind("click.fb-start", l);
4103        this.filter("[data-fancybox-start=1]").trigger("click");
4104        return this
4105    };
4106    p.ready(function() {
4107        var a, d;
4108        f.scrollbarWidth === w && (f.scrollbarWidth = function() {
4109            var a = f('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo("body"),
4110                b = a.children(),
4111                b = b.innerWidth() - b.height(99).innerWidth();
4112            a.remove();
4113            return b
4114        });
4115        f.support.fixedPosition === w && (f.support.fixedPosition = function() {
4116            var a = f('<div style="position:fixed;top:20px;"></div>').appendTo("body"),
4117                b = 20 === a[0].offsetTop || 15 === a[0].offsetTop;
4118            a.remove();
4119            return b
4120        }());
4121        f.extend(b.defaults, {
4122            scrollbarWidth: f.scrollbarWidth(),
4123            fixed: f.support.fixedPosition,
4124            parent: f("body")
4125        });
4126        a = f(s).width();
4127        K.addClass("fancybox-lock-test");
4128        d = f(s).width();
4129        K.removeClass("fancybox-lock-test");
4130        f("<style type='text/css'>.fancybox-margin{margin-right:" + (d - a) + "px;}</style>").appendTo("head")
4131    })
4132})(window, document, jQuery);
4133
4134
4135
4136
4137
4138
4139/*!
4140 * Media helper for fancyBox
4141 * version: 1.0.6 (Fri, 14 Jun 2013)
4142 * @requires fancyBox v2.0 or later
4143 *
4144 * Usage:
4145 *     $(".fancybox").fancybox({
4146 *         helpers : {
4147 *             media: true
4148 *         }
4149 *     });
4150 *
4151 * Set custom URL parameters:
4152 *     $(".fancybox").fancybox({
4153 *         helpers : {
4154 *             media: {
4155 *                 youtube : {
4156 *                     params : {
4157 *                         autoplay : 0
4158 *                     }
4159 *                 }
4160 *             }
4161 *         }
4162 *     });
4163 *
4164 * Or:
4165 *     $(".fancybox").fancybox({,
4166 *         helpers : {
4167 *             media: true
4168 *         },
4169 *         youtube : {
4170 *             autoplay: 0
4171 *         }
4172 *     });
4173 *
4174 *  Supports:
4175 *
4176 *      Youtube
4177 *          http://www.youtube.com/watch?v=opj24KnzrWo
4178 *          http://www.youtube.com/embed/opj24KnzrWo
4179 *          http://youtu.be/opj24KnzrWo
4180 *          http://www.youtube-nocookie.com/embed/opj24KnzrWo
4181 *      Vimeo
4182 *          http://vimeo.com/40648169
4183 *          http://vimeo.com/channels/staffpicks/38843628
vendor: 5,535 bytes, lines 4184-4332
4184 *          http://vimeo.com/groups/surrealism/videos/36516384
4185 *          http://player.vimeo.com/video/45074303
4186 *      Metacafe
4187 *          http://www.metacafe.com/watch/7635964/dr_seuss_the_lorax_movie_trailer/
4188 *          http://www.metacafe.com/watch/7635964/
4189 *      Dailymotion
4190 *          http://www.dailymotion.com/video/xoytqh_dr-seuss-the-lorax-premiere_people
4191 *      Twitvid
4192 *          http://twitvid.com/QY7MD
4193 *      Twitpic
4194 *          http://twitpic.com/7p93st
4195 *      Instagram
4196 *          http://instagr.am/p/IejkuUGxQn/
4197 *          http://instagram.com/p/IejkuUGxQn/
4198 *      Google maps
4199 *          http://maps.google.com/maps?q=Eiffel+Tower,+Avenue+Gustave+Eiffel,+Paris,+France&t=h&z=17
4200 *          http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
4201 *          http://maps.google.com/?ll=48.859463,2.292626&spn=0.000965,0.002642&t=m&z=19&layer=c&cbll=48.859524,2.292532&panoid=YJ0lq28OOy3VT2IqIuVY0g&cbp=12,151.58,,0,-15.56
4202 */
4203(function ($) {
4204    "use strict";
4205
4206    //Shortcut for fancyBox object
4207    var F = $.fancybox,
4208        format = function( url, rez, params ) {
4209            params = params || '';
4210
4211            if ( $.type( params ) === "object" ) {
4212                params = $.param(params, true);
4213            }
4214
4215            $.each(rez, function(key, value) {
4216                url = url.replace( '$' + key, value || '' );
4217            });
4218
4219            if (params.length) {
4220                url += ( url.indexOf('?') > 0 ? '&' : '?' ) + params;
4221            }
4222
4223            return url;
4224        };
4225
4226    //Add helper object
4227    F.helpers.media = {
4228        defaults : {
4229            youtube : {
4230                matcher : /(youtube\.com|youtu\.be|youtube-nocookie\.com)\/(watch\?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*)).*/i,
4231                params  : {
4232                    autoplay    : 1,
4233                    autohide    : 1,
4234                    fs          : 1,
4235                    rel         : 0,
4236                    hd          : 1,
4237                    wmode       : 'opaque',
4238                    enablejsapi : 1
4239                },
4240                type : 'iframe',
4241                url  : '//www.youtube.com/embed/$3'
4242            },
4243            vimeo : {
4244                matcher : /(?:vimeo(?:pro)?.com)\/(?:[^\d]+)?(\d+)(?:.*)/,
4245                params  : {
4246                    autoplay      : 1,
4247                    hd            : 1,
4248                    show_title    : 1,
4249                    show_byline   : 1,
4250                    show_portrait : 0,
4251                    fullscreen    : 1
4252                },
4253                type : 'iframe',
4254                url  : '//player.vimeo.com/video/$1'
4255            },
4256            metacafe : {
4257                matcher : /metacafe.com\/(?:watch|fplayer)\/([\w\-]{1,10})/,
4258                params  : {
4259                    autoPlay : 'yes'
4260                },
4261                type : 'swf',
4262                url  : function( rez, params, obj ) {
4263                    obj.swf.flashVars = 'playerVars=' + $.param( params, true );
4264
4265                    return '//www.metacafe.com/fplayer/' + rez[1] + '/.swf';
4266                }
4267            },
4268            dailymotion : {
4269                matcher : /dailymotion.com\/video\/(.*)\/?(.*)/,
4270                params  : {
4271                    additionalInfos : 0,
4272                    autoStart : 1
4273                },
4274                type : 'swf',
4275                url  : '//www.dailymotion.com/swf/video/$1'
4276            },
4277            twitvid : {
4278                matcher : /twitvid\.com\/([a-zA-Z0-9_\-\?\=]+)/i,
4279                params  : {
4280                    autoplay : 0
4281                },
4282                type : 'iframe',
4283                url  : '//www.twitvid.com/embed.php?guid=$1'
4284            },
4285            twitpic : {
4286                matcher : /twitpic\.com\/(?!(?:place|photos|events)\/)([a-zA-Z0-9\?\=\-]+)/i,
4287                type : 'image',
4288                url  : '//twitpic.com/show/full/$1/'
4289            },
4290            instagram : {
4291                matcher : /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,
4292                type : 'image',
4293                url  : '//$1/p/$2/media/?size=l'
4294            },
4295            google_maps : {
4296                matcher : /maps\.google\.([a-z]{2,3}(\.[a-z]{2})?)\/(\?ll=|maps\?)(.*)/i,
4297                type : 'iframe',
4298                url  : function( rez ) {
4299                    return '//maps.google.' + rez[1] + '/' + rez[3] + '' + rez[4] + '&output=' + (rez[4].indexOf('layer=c') > 0 ? 'svembed' : 'embed');
4300                }
4301            }
4302        },
4303
4304        beforeLoad : function(opts, obj) {
4305            var url   = obj.href || '',
4306                type  = false,
4307                what,
4308                item,
4309                rez,
4310                params;
4311
4312            for (what in opts) {
4313                if (opts.hasOwnProperty(what)) {
4314                    item = opts[ what ];
4315                    rez  = url.match( item.matcher );
4316
4317                    if (rez) {
4318                        type   = item.type;
4319                        params = $.extend(true, {}, item.params, obj[ what ] || ($.isPlainObject(opts[ what ]) ? opts[ what ].params : null));
4320
4321                        url = $.type( item.url ) === "function" ? item.url.call( this, rez, params, obj ) : format( item.url, rez, params );
4322
4323                        break;
4324                    }
4325                }
4326            }
4327
4328            if (type) {
4329                obj.href = url;
4330                obj.type = type;
4331
4332                obj.autoHeight = false;
4333            }
4334        }
4335    };
4336
4337}(jQuery));
4338;
4339(function ($, window, document, undefined) {
4340
4341  var pluginName = "MegaMenu",
4342    defaults = {
4343      propertyName: "value"
4344    };
4345
4346  // Set delay time for mouseout
4347  var delayOut = 400; // Default delay time is 200
4348
4349  // the list of menus
4350  var menus = [];
4351
4352  function CustomMenu(element, options) {
4353    this.element = element;
4354
4355    this.options = $.extend({}, defaults, options);
4356
4357    this._defaults = defaults;
4358    this._name = pluginName;
4359
4360    this.init();
4361  }
4362
4363  CustomMenu.prototype = {
4364    isOpen: false,
4365    timeout: null,
4366    init: function () {
4367
4368      var that = this;
4369
4370      $(this).each(function(index, menu) {
4371        that.node = menu.element; 
4372        that.addListeners(menu.element);
4373
4374        var $menu = $(menu.element);
4375        $menu.addClass("dropdownJavascript");
4376        menus.push(menu.element);
4377
4378        $menu.find('ul > li').each(function(index, submenu) {
4379          if ($(submenu).find('ul').length > 0 ) {
4380            $(submenu).addClass('with-menu');
4381          }
4382        });
4383      });
4384    },
4385    addListeners: function(menu) {
4386      var that = this;
4387      $(menu).mouseover(function(e) {
4388        that.handleMouseOver.call(that, e);
4389      }).mouseout(function(e) {
4390          that.handleMouseOut.call(that, e);
4391        });
4392    },
4393    handleMouseOver: function (e) {
4394      var that = this;
4395      // clear the timeout
4396      this.clearTimeout();
4397
4398      // find the parent list item
4399      //var item = ('target' in e ? e.target : e.srcElement);
4400      var item = e.target || e.srcElement;
4401      while (item.nodeName != 'LI' && item != this.node) {
4402        item = item.parentNode;
4403      }
4404
4405      // if the target is within a list item, set the timeout
4406      if (item.nodeName == 'LI') {
4407        this.toOpen = item;
4408        this.timeout = setTimeout(function() {
4409          that.open.call(that);
4410        }, this.options.delay);
4411      }
4412
4413    },
4414    handleMouseOut: function () {
4415      var that = this;
4416      // clear the timeout
4417      this.clearTimeout();
4418
4419      // Check mouseout delay overriding
4420      var _delayOut = this.options.delay;
4421      if ( delayOut ) {
4422        _delayOut = delayOut;
4423      }
4424
4425      this.timeout = setTimeout(function() {
4426        that.close.call(that);
4427      }, _delayOut );
4428
4429    },
4430    clearTimeout: function () {
4431
4432      // clear the timeout
4433      if (this.timeout) {
4434        clearTimeout(this.timeout);
4435        this.timeout = null;
4436      }
4437
4438    },
4439    open: function () {
4440
4441      var that = this;
4442      // store that the menu is open
4443      this.isOpen = true;
4444
4445      // loop over the list items with the same parent
4446      var items = $(this.toOpen).parent().children('li');
4447      $(items).each(function(index, item) {
4448        $(item).find("ul").each(function(index, submenu) {
4449          if (item != that.toOpen) {
4450            // close the submenu
4451            $(item).removeClass("dropdownOpen");
4452            that.close(item);
4453
4454          } else if (!$(item).hasClass('dropdownOpen')) {
4455
4456            // open the submenu
4457            //if ( !$(item).parents('li').hasClass('has-mega-menu') ) {
4458              $(item).addClass("dropdownOpen");
4459            //}
4460
4461
4462            // determine the location of the edges of the submenu
4463            var left = 0;
4464            var node = submenu;
4465            while (node) {
4466              //abs is because when you make menus right to left
4467              //the offsetLeft would be negative
4468              left += Math.abs(node.offsetLeft);
4469              node = node.offsetParent;
4470            }
4471            var right = left + submenu.offsetWidth;
4472
4473
4474            //We should refactor this code to execute only when menu is vertical
4475            var menuHeight = $(submenu).outerHeight();
4476            var parentTop = $(submenu).offset().top - $(window).scrollTop();
4477            var totalHeight = menuHeight + parentTop;
4478            var windowHeight = window.innerHeight;
4479
4480           /* if (totalHeight > windowHeight) {
4481              var bestTop = (windowHeight - totalHeight) - 20;
4482              $(submenu).css('margin-top', bestTop + "px");
4483            }*/
4484
4485            //remove any previous classes
4486            $(item).removeClass('dropdownRightToLeft');
4487
4488            // move the submenu to the right of the item if appropriate
4489            if (left < 0) $(item).addClass('dropdownLeftToRight');
4490
4491            // move the submenu to the left of the item if appropriate
4492            if (right > document.body.clientWidth) {
4493              $(item).addClass('dropdownRightToLeft');
4494            }
4495
4496          }
4497        });
4498      });
4499
4500    },
4501
4502
4503    close: function (node) {
4504
4505      // if no node was specified, close all menus
4506      if (!node) {
4507        this.isOpen = false;
4508        node = this.node;
4509      }
4510
4511      // loop over the items, closing their submenus
4512      $(node).find('li').each(function(index, item) {
4513        $(item).removeClass('dropdownOpen');
4514      });
4515
4516    }
4517  };
4518
4519  $.fn[pluginName] = function (options) {
4520    return this.each(function () {
4521      if (!$.data(this, "plugin_" + pluginName)) {
4522        $.data(this, "plugin_" + pluginName,
4523          new CustomMenu(this, options));
4524      }
4525    });
4526  };
4527
4528})(jQuery, window, document);
4529
4530/*!
4531 * modernizr v3.3.1
4532 * Build https://modernizr.com/download?-cssanimations-csstransitions-touchevents-domprefixes-prefixed-prefixes-setclasses-shiv-testallprops-testprop-teststyles-dontmin
4533 *
4534 * Copyright (c)
4535 *  Faruk Ates
4536 *  Paul Irish
4537 *  Alex Sexton
4538 *  Ryan Seddon
4539 *  Patrick Kettner
4540 *  Stu Cox
4541 *  Richard Herrera
4542
4543 * MIT License
4544 */
4545
4546/*
4547 * Modernizr tests which native CSS3 and HTML5 features are available in the
4548 * current UA and makes the results available to you in two ways: as properties on
4549 * a global `Modernizr` object, and as classes on the `<html>` element. This
4550 * information allows you to progressively enhance your pages with a granular level
4551 * of control over the experience.
4552*/
4553
4554;(function(window, document, undefined){
4555  var classes = [];
4556  
4557
4558  var tests = [];
4559  
4560
4561  /**
4562   *
4563   * ModernizrProto is the constructor for Modernizr
4564   *
4565   * @class
4566   * @access public
4567   */
4568
4569  var ModernizrProto = {
4570    // The current version, dummy
4571    _version: '3.3.1',
4572
4573    // Any settings that don't work as separate modules
4574    // can go in here as configuration.
4575    _config: {
4576      'classPrefix': '',
4577      'enableClasses': true,
4578      'enableJSClass': true,
4579      'usePrefixes': true
4580    },
4581
4582    // Queue of tests
4583    _q: [],
4584
4585    // Stub these for people who are listening
4586    on: function(test, cb) {
4587      // I don't really think people should do this, but we can
4588      // safe guard it a bit.
4589      // -- NOTE:: this gets WAY overridden in src/addTest for actual async tests.
4590      // This is in case people listen to synchronous tests. I would leave it out,
4591      // but the code to *disallow* sync tests in the real version of this
4592      // function is actually larger than this.
4593      var self = this;
4594      setTimeout(function() {
4595        cb(self[test]);
4596      }, 0);
4597    },
4598
4599    addTest: function(name, fn, options) {
4600      tests.push({name: name, fn: fn, options: options});
4601    },
4602
4603    addAsyncTest: function(fn) {
4604      tests.push({name: null, fn: fn});
4605    }
4606  };
4607
4608  
4609
4610  // Fake some of Object.create so we can force non test results to be non "own" properties.
4611  var Modernizr = function() {};
4612  Modernizr.prototype = ModernizrProto;
4613
4614  // Leak modernizr globally when you `require` it rather than force it here.
4615  // Overwrite name so constructor name is nicer :D
4616  Modernizr = new Modernizr();
4617
4618  
4619
4620  /**
4621   * List of property values to set for css tests. See ticket #21
4622   * http://git.io/vUGl4
4623   *
4624   * @memberof Modernizr
4625   * @name Modernizr._prefixes
4626   * @optionName Modernizr._prefixes
4627   * @optionProp prefixes
4628   * @access public
4629   * @example
4630   *
4631   * Modernizr._prefixes is the internal list of prefixes that we test against
4632   * inside of things like [prefixed](#modernizr-prefixed) and [prefixedCSS](#-code-modernizr-prefixedcss). It is simply
4633   * an array of kebab-case vendor prefixes you can use within your code.
4634   *
4635   * Some common use cases include
4636   *
4637   * Generating all possible prefixed version of a CSS property
4638   * ```js
4639   * var rule = Modernizr._prefixes.join('transform: rotate(20deg); ');
4640   *
4641   * rule === 'transform: rotate(20deg); webkit-transform: rotate(20deg); moz-transform: rotate(20deg); o-transform: rotate(20deg); ms-transform: rotate(20deg);'
4642   * ```
4643   *
4644   * Generating all possible prefixed version of a CSS value
4645   * ```js
4646   * rule = 'display:' +  Modernizr._prefixes.join('flex; display:') + 'flex';
4647   *
4648   * rule === 'display:flex; display:-webkit-flex; display:-moz-flex; display:-o-flex; display:-ms-flex; display:flex'
4649   * ```
4650   */
4651
4652  // we use ['',''] rather than an empty array in order to allow a pattern of .`join()`ing prefixes to test
4653  // values in feature detects to continue to work
4654  var prefixes = (ModernizrProto._config.usePrefixes ? ' -webkit- -moz- -o- -ms- '.split(' ') : ['','']);
4655
4656  // expose these for the plugin API. Look in the source for how to join() them against your input
4657  ModernizrProto._prefixes = prefixes;
4658
4659  
4660
4661  /**
4662   * is returns a boolean if the typeof an obj is exactly type.
4663   *
4664   * @access private
4665   * @function is
4666   * @param {*} obj - A thing we want to check the type of
4667   * @param {string} type - A string to compare the typeof against
4668   * @returns {boolean}
4669   */
4670
4671  function is(obj, type) {
4672    return typeof obj === type;
4673  }
4674  ;
4675
4676  /**
4677   * Run through all tests and detect their support in the current UA.
4678   *
4679   * @access private
4680   */
4681
4682  function testRunner() {
4683    var featureNames;
4684    var feature;
4685    var aliasIdx;
4686    var result;
4687    var nameIdx;
4688    var featureName;
4689    var featureNameSplit;
4690
4691    for (var featureIdx in tests) {
4692      if (tests.hasOwnProperty(featureIdx)) {
4693        featureNames = [];
4694        feature = tests[featureIdx];
4695        // run the test, throw the return value into the Modernizr,
4696        // then based on that boolean, define an appropriate className
4697        // and push it into an array of classes we'll join later.
4698        //
4699        // If there is no name, it's an 'async' test that is run,
4700        // but not directly added to the object. That should
4701        // be done with a post-run addTest call.
4702        if (feature.name) {
4703          featureNames.push(feature.name.toLowerCase());
4704
4705          if (feature.options && feature.options.aliases && feature.options.aliases.length) {
4706            // Add all the aliases into the names list
4707            for (aliasIdx = 0; aliasIdx < feature.options.aliases.length; aliasIdx++) {
4708              featureNames.push(feature.options.aliases[aliasIdx].toLowerCase());
4709            }
4710          }
4711        }
4712
4713        // Run the test, or use the raw value if it's not a function
4714        result = is(feature.fn, 'function') ? feature.fn() : feature.fn;
4715
4716
4717        // Set each of the names on the Modernizr object
4718        for (nameIdx = 0; nameIdx < featureNames.length; nameIdx++) {
4719          featureName = featureNames[nameIdx];
4720          // Support dot properties as sub tests. We don't do checking to make sure
4721          // that the implied parent tests have been added. You must call them in
4722          // order (either in the test, or make the parent test a dependency).
4723          //
4724          // Cap it to TWO to make the logic simple and because who needs that kind of subtesting
4725          // hashtag famous last words
4726          featureNameSplit = featureName.split('.');
4727
4728          if (featureNameSplit.length === 1) {
4729            Modernizr[featureNameSplit[0]] = result;
4730          } else {
4731            // cast to a Boolean, if not one already
4732            /* jshint -W053 */
4733            if (Modernizr[featureNameSplit[0]] && !(Modernizr[featureNameSplit[0]] instanceof Boolean)) {
4734              Modernizr[featureNameSplit[0]] = new Boolean(Modernizr[featureNameSplit[0]]);
4735            }
4736
4737            Modernizr[featureNameSplit[0]][featureNameSplit[1]] = result;
4738          }
4739
4740          classes.push((result ? '' : 'no-') + featureNameSplit.join('-'));
4741        }
4742      }
4743    }
4744  }
4745  ;
4746
4747  /**
4748   * docElement is a convenience wrapper to grab the root element of the document
4749   *
4750   * @access private
4751   * @returns {HTMLElement|SVGElement} The root element of the document
4752   */
4753
4754  var docElement = document.documentElement;
4755  
4756
4757  /**
4758   * A convenience helper to check if the document we are running in is an SVG document
4759   *
4760   * @access private
4761   * @returns {boolean}
4762   */
4763
4764  var isSVG = docElement.nodeName.toLowerCase() === 'svg';
4765  
4766
4767  /**
4768   * setClasses takes an array of class names and adds them to the root element
4769   *
4770   * @access private
4771   * @function setClasses
4772   * @param {string[]} classes - Array of class names
4773   */
4774
4775  // Pass in an and array of class names, e.g.:
4776  //  ['no-webp', 'borderradius', ...]
4777  function setClasses(classes) {
4778    var className = docElement.className;
4779    var classPrefix = Modernizr._config.classPrefix || '';
4780
4781    if (isSVG) {
4782      className = className.baseVal;
4783    }
4784
4785    // Change `no-js` to `js` (independently of the `enableClasses` option)
4786    // Handle classPrefix on this too
4787    if (Modernizr._config.enableJSClass) {
4788      var reJS = new RegExp('(^|\\s)' + classPrefix + 'no-js(\\s|$)');
4789      className = className.replace(reJS, '$1' + classPrefix + 'js$2');
4790    }
4791
4792    if (Modernizr._config.enableClasses) {
4793      // Add the new classes
4794      className += ' ' + classPrefix + classes.join(' ' + classPrefix);
4795      isSVG ? docElement.className.baseVal = className : docElement.className = className;
4796    }
4797
4798  }
4799
4800  ;
4801
4802/**
4803  * @optionName html5shiv
4804  * @optionProp html5shiv
4805  */
4806
4807  // Take the html5 variable out of the html5shiv scope so we can return it.
4808  var html5;
4809  if (!isSVG) {
4810    /**
4811     * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
4812     */
4813    ;(function(window, document) {
4814      /*jshint evil:true */
4815      /** version */
4816      var version = '3.7.3';
4817
4818      /** Preset options */
4819      var options = window.html5 || {};
4820
4821      /** Used to skip problem elements */
4822      var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
4823
4824      /** Not all elements can be cloned in IE **/
4825      var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
4826
4827      /** Detect whether the browser supports default html5 styles */
4828      var supportsHtml5Styles;
4829
4830      /** Name of the expando, to work with multiple documents or to re-shiv one document */
4831      var expando = '_html5shiv';
4832
4833      /** The id for the the documents expando */
4834      var expanID = 0;
4835
4836      /** Cached data for each document */
4837      var expandoData = {};
4838
4839      /** Detect whether the browser supports unknown elements */
4840      var supportsUnknownElements;
4841
4842      (function() {
4843        try {
4844          var a = document.createElement('a');
4845          a.innerHTML = '<xyz></xyz>';
4846          //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles
4847          supportsHtml5Styles = ('hidden' in a);
4848
4849          supportsUnknownElements = a.childNodes.length == 1 || (function() {
4850            // assign a false positive if unable to shiv
4851            (document.createElement)('a');
4852            var frag = document.createDocumentFragment();
4853            return (
4854              typeof frag.cloneNode == 'undefined' ||
4855                typeof frag.createDocumentFragment == 'undefined' ||
4856                typeof frag.createElement == 'undefined'
4857            );
4858          }());
4859        } catch(e) {
4860          // assign a false positive if detection fails => unable to shiv
4861          supportsHtml5Styles = true;
4862          supportsUnknownElements = true;
4863        }
4864
4865      }());
4866
4867      /*--------------------------------------------------------------------------*/
4868
4869      /**
4870       * Creates a style sheet with the given CSS text and adds it to the document.
4871       * @private
4872       * @param {Document} ownerDocument The document.
4873       * @param {String} cssText The CSS text.
4874       * @returns {StyleSheet} The style element.
4875       */
4876      function addStyleSheet(ownerDocument, cssText) {
4877        var p = ownerDocument.createElement('p'),
4878          parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
4879
4880        p.innerHTML = 'x<style>' + cssText + '</style>';
4881        return parent.insertBefore(p.lastChild, parent.firstChild);
4882      }
4883
4884      /**
4885       * Returns the value of `html5.elements` as an array.
4886       * @private
4887       * @returns {Array} An array of shived element node names.
4888       */
4889      function getElements() {
4890        var elements = html5.elements;
4891        return typeof elements == 'string' ? elements.split(' ') : elements;
4892      }
4893
4894      /**
4895       * Extends the built-in list of html5 elements
4896       * @memberOf html5
4897       * @param {String|Array} newElements whitespace separated list or array of new element names to shiv
4898       * @param {Document} ownerDocument The context document.
4899       */
4900      function addElements(newElements, ownerDocument) {
4901        var elements = html5.elements;
4902        if(typeof elements != 'string'){
4903          elements = elements.join(' ');
4904        }
4905        if(typeof newElements != 'string'){
4906          newElements = newElements.join(' ');
4907        }
4908        html5.elements = elements +' '+ newElements;
4909        shivDocument(ownerDocument);
4910      }
4911
4912      /**
4913       * Returns the data associated to the given document
4914       * @private
4915       * @param {Document} ownerDocument The document.
4916       * @returns {Object} An object of data.
4917       */
4918      function getExpandoData(ownerDocument) {
4919        var data = expandoData[ownerDocument[expando]];
4920        if (!data) {
4921          data = {};
4922          expanID++;
4923          ownerDocument[expando] = expanID;
4924          expandoData[expanID] = data;
4925        }
4926        return data;
4927      }
4928
4929      /**
4930       * returns a shived element for the given nodeName and document
4931       * @memberOf html5
4932       * @param {String}
vendor: 4,418 bytes, lines 4932-5043
4932 nodeName name of the element
4933       * @param {Document|DocumentFragment} ownerDocument The context document.
4934       * @returns {Object} The shived element.
4935       */
4936      function createElement(nodeName, ownerDocument, data){
4937        if (!ownerDocument) {
4938          ownerDocument = document;
4939        }
4940        if(supportsUnknownElements){
4941          return ownerDocument.createElement(nodeName);
4942        }
4943        if (!data) {
4944          data = getExpandoData(ownerDocument);
4945        }
4946        var node;
4947
4948        if (data.cache[nodeName]) {
4949          node = data.cache[nodeName].cloneNode();
4950        } else if (saveClones.test(nodeName)) {
4951          node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
4952        } else {
4953          node = data.createElem(nodeName);
4954        }
4955
4956        // Avoid adding some elements to fragments in IE < 9 because
4957        // * Attributes like `name` or `type` cannot be set/changed once an element
4958        //   is inserted into a document/fragment
4959        // * Link elements with `src` attributes that are inaccessible, as with
4960        //   a 403 response, will cause the tab/window to crash
4961        // * Script elements appended to fragments will execute when their `src`
4962        //   or `text` property is set
4963        return node.canHaveChildren && !reSkip.test(nodeName) && !node.tagUrn ? data.frag.appendChild(node) : node;
4964      }
4965
4966      /**
4967       * returns a shived DocumentFragment for the given document
4968       * @memberOf html5
4969       * @param {Document} ownerDocument The context document.
4970       * @returns {Object} The shived DocumentFragment.
4971       */
4972      function createDocumentFragment(ownerDocument, data){
4973        if (!ownerDocument) {
4974          ownerDocument = document;
4975        }
4976        if(supportsUnknownElements){
4977          return ownerDocument.createDocumentFragment();
4978        }
4979        data = data || getExpandoData(ownerDocument);
4980        var clone = data.frag.cloneNode(),
4981          i = 0,
4982          elems = getElements(),
4983          l = elems.length;
4984        for(;i<l;i++){
4985          clone.createElement(elems[i]);
4986        }
4987        return clone;
4988      }
4989
4990      /**
4991       * Shivs the `createElement` and `createDocumentFragment` methods of the document.
4992       * @private
4993       * @param {Document|DocumentFragment} ownerDocument The document.
4994       * @param {Object} data of the document.
4995       */
4996      function shivMethods(ownerDocument, data) {
4997        if (!data.cache) {
4998          data.cache = {};
4999          data.createElem = ownerDocument.createElement;
5000          data.createFrag = ownerDocument.createDocumentFragment;
5001          data.frag = data.createFrag();
5002        }
5003
5004
5005        ownerDocument.createElement = function(nodeName) {
5006          //abort shiv
5007          if (!html5.shivMethods) {
5008            return data.createElem(nodeName);
5009          }
5010          return createElement(nodeName, ownerDocument, data);
5011        };
5012
5013        ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
5014                                                        'var n=f.cloneNode(),c=n.createElement;' +
5015                                                        'h.shivMethods&&(' +
5016                                                        // unroll the `createElement` calls
5017                                                        getElements().join().replace(/[\w\-:]+/g, function(nodeName) {
5018          data.createElem(nodeName);
5019          data.frag.createElement(nodeName);
5020          return 'c("' + nodeName + '")';
5021        }) +
5022          ');return n}'
5023                                                       )(html5, data.frag);
5024      }
5025
5026      /*--------------------------------------------------------------------------*/
5027
5028      /**
5029       * Shivs the given document.
5030       * @memberOf html5
5031       * @param {Document} ownerDocument The document to shiv.
5032       * @returns {Document} The shived document.
5033       */
5034      function shivDocument(ownerDocument) {
5035        if (!ownerDocument) {
5036          ownerDocument = document;
5037        }
5038        var data = getExpandoData(ownerDocument);
5039
5040        if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
5041          data.hasCSS = !!addStyleSheet(ownerDocument,
5042                                        // corrects block display not defined in IE6/7/8/9
5043                                        'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{dis
5043play:block}' +
5044                                        // adds styling not present in IE6/7/8/9
5045                                        'mark{background:#FF0;color:#000}' +
5046                                        // hides non-rendered elements
5047                                        'template{display:none}'
5048                                       );
5049        }
5050        if (!supportsUnknownElements) {
5051          shivMethods(ownerDocument, data);
5052        }
5053        return ownerDocument;
5054      }
5055
5056      /*--------------------------------------------------------------------------*/
5057
5058      /**
5059       * The `html5` object is exposed so that more elements can be shived and
5060       * existing shiving can be detected on iframes.
5061       * @type Object
5062       * @example
5063       *
5064       * // options can be changed before the script is included
5065       * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
5066       */
5067      var html5 = {
5068
5069        /**
5070         * An array or space separated string of node names of the elements to shiv.
5071         * @memberOf html5
5072         * @type Array|String
5073         */
5074        'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video',
5075
5076        /**
5077         * current version of html5shiv
5078         */
5079        'version': version,
5080
5081        /**
5082         * A flag to indicate that the HTML5 style sheet should be inserted.
5083         * @memberOf html5
5084         * @type Boolean
5085         */
5086        'shivCSS': (options.shivCSS !== false),
5087
5088        /**
5089         * Is equal to true if a browser supports creating unknown/HTML5 elements
5090         * @memberOf html5
5091         * @type boolean
5092         */
5093        'supportsUnknownElements': supportsUnknownElements,
5094
5095        /**
5096         * A flag to indicate that the document's `createElement` and `createDocumentFragment`
5097         * methods should be overwritten.
5098         * @memberOf html5
5099         * @type Boolean
5100         */
5101        'shivMethods': (options.shivMethods !== false),
5102
5103        /**
5104         * A string to describe the type of `html5` object ("default" or "default print").
5105         * @memberOf html5
5106         * @type String
5107         */
5108        'type': 'default',
5109
5110        // shivs the document according to the specified `html5` object options
5111        'shivDocument': shivDocument,
5112
5113        //creates a shived element
5114        createElement: createElement,
5115
5116        //creates a shived documentFragment
5117        createDocumentFragment: createDocumentFragment,
5118
5119        //extends list of elements
5120        addElements: addElements
5121      };
5122
5123      /*--------------------------------------------------------------------------*/
5124
5125      // expose html5
5126      window.html5 = html5;
5127
5128      // shiv the document
5129      shivDocument(document);
5130
5131      if(typeof module == 'object' && module.exports){
5132        module.exports = html5;
5133      }
5134
5135    }(typeof window !== "undefined" ? window : this, document));
5136  }
5137;
5138
5139  /**
5140   * If the browsers follow the spec, then they would expose vendor-specific style as:
5141   *   elem.style.WebkitBorderRadius
5142   * instead of something like the following, which would be technically incorrect:
5143   *   elem.style.webkitBorderRadius
5144
5145   * Webkit ghosts their properties in lowercase but Opera & Moz do not.
5146   * Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+
5147   *   erik.eae.net/archives/2008/03/10/21.48.10/
5148
5149   * More here: github.com/Modernizr/Modernizr/issues/issue/21
5150   *
5151   * @access private
5152   * @returns {string} The string representing the vendor-specific style properties
5153   */
5154
5155  var omPrefixes = 'Moz O ms Webkit';
5156  
5157
5158  /**
5159   * List of JavaScript DOM values used for tests
5160   *
5161   * @memberof Modernizr
5162   * @name Modernizr._domPrefixes
5163   * @optionName Modernizr._domPrefixes
5164   * @optionProp domPrefixes
5165   * @access public
5166   * @example
5167   *
5168   * Modernizr._domPrefixes is exactly the same as [_prefixes](#modernizr-_prefixes), but rather
5169   * than kebab-case properties, all properties are their Capitalized variant
5170   *
5171   * ```js
5172   * Modernizr._domPrefixes === [ "Moz", "O", "ms", "Webkit" ];
5173   * ```
5174   */
5175
5176  var domPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.toLowerCase().split(' ') : []);
5177  ModernizrProto._domPrefixes = domPrefixes;
5178  
5179
5180  /**
5181   * cssToDOM takes a kebab-case string and converts it to camelCase
5182   * e.g. box-sizing -> boxSizing
5183   *
5184   * @access private
5185   * @function cssToDOM
5186   * @param {string} name - String name of kebab-case prop we want to convert
5187   * @returns {string} The camelCase version of the supplied name
5188   */
5189
5190  function cssToDOM(name) {
5191    return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) {
5192      return m1 + m2.toUpperCase();
5193    }).replace(/^-/, '');
5194  }
5195  ;
5196
5197  var cssomPrefixes = (ModernizrProto._config.usePrefixes ? omPrefixes.split(' ') : []);
5198  ModernizrProto._cssomPrefixes = cssomPrefixes;
5199  
5200
5201  /**
5202   * atRule returns a given CSS property at-rule (eg @keyframes), possibly in
5203   * some prefixed form, or false, in the case of an unsupported rule
5204   *
5205   * @memberof Modernizr
5206   * @name Modernizr.atRule
5207   * @optionName Modernizr.atRule()
5208   * @optionProp atRule
5209   * @access public
5210   * @function atRule
5211   * @param {string} prop - String name of the @-rule to test for
5212   * @returns {string|boolean} The string representing the (possibly prefixed)
5213   * valid version of the @-rule, or `false` when it is unsupported.
5214   * @example
5215   * ```js
5216   *  var keyframes = Modernizr.atRule('@keyframes');
5217   *
5218   *  if (keyframes) {
5219   *    // keyframes are supported
5220   *    // could be `@-webkit-keyframes` or `@keyframes`
5221   *  } else {
5222   *    // keyframes === `false`
5223   *  }
5224   * ```
5225   *
5226   */
5227
5228  var atRule = function(prop) {
5229    var length = prefixes.length;
5230    var cssrule = window.CSSRule;
5231    var rule;
5232
5233    if (typeof cssrule === 'undefined') {
5234      return undefined;
5235    }
5236
5237    if (!prop) {
5238      return false;
5239    }
5240
5241    // remove literal @ from beginning of provided property
5242    prop = prop.replace(/^@/, '');
5243
5244    // CSSRules use underscores instead of dashes
5245    rule = prop.replace(/-/g, '_').toUpperCase() + '_RULE';
5246
5247    if (rule in cssrule) {
5248      return '@' + prop;
5249    }
5250
5251    for (var i = 0; i < length; i++) {
5252      // prefixes gives us something like -o-, and we want O_
5253      var prefix = prefixes[i];
5254      var thisRule = prefix.toUpperCase() + '_' + rule;
5255
5256      if (thisRule in cssrule) {
5257        return '@-' + prefix.toLowerCase() + '-' + prop;
5258      }
5259    }
5260
5261    return false;
5262  };
5263
5264  ModernizrProto.atRule = atRule;
5265
5266  
5267
5268
5269  /**
5270   * contains checks to see if a string contains another string
5271   *
5272   * @access private
5273   * @function contains
5274   * @param {string} str - The string we want to check for substrings
5275   * @param {string} substr - The substring we want to search the first string for
5276   * @returns {boolean}
5277   */
5278
5279  function contains(str, substr) {
5280    return !!~('' + str).indexOf(substr);
5281  }
5282
5283  ;
5284
5285  /**
5286   * createElement is a convenience wrapper around document.createElement. Since we
5287   * use createElement all over the place, this allows for (slightly) smaller code
5288   * as well as abstracting away issues with creating elements in contexts other than
5289   * HTML documents (e.g. SVG documents).
5290   *
5291   * @access private
5292   * @function createElement
5293   * @returns {HTMLElement|SVGElement} An HTML or SVG element
5294   */
5295
5296  function createElement() {
5297    if (typeof document.createElement !== 'function') {
5298      // This is the case in IE7, where the type of createElement is "object".
5299      // For this reason, we cannot call apply() as Object is not a Function.
5300      return document.createElement(arguments[0]);
5301    } else if (isSVG) {
5302      return document.createElementNS.call(document, 'http://www.w3.org/2000/svg', arguments[0]);
5303    } else {
5304      return document.createElement.apply(document, arguments);
5305    }
5306  }
5307
5308  ;
5309
5310  /**
5311   * getBody returns the body of a document, or an element that can stand in for
5312   * the body if a real body does not exist
5313   *
5314   * @access private
5315   * @function getBody
5316   * @returns {HTMLElement|SVGElement} Returns the real body of a document, or an
5317   * artificially created element that stands in for the body
5318   */
5319
5320  function getBody() {
5321    // After page load injecting a fake body doesn't work so check if body exists
5322    var body = document.body;
5323
5324    if (!body) {
5325      // Can't use the real body create a fake one.
5326      body = createElement(isSVG ? 'svg' : 'body');
5327      body.fake = true;
5328    }
5329
5330    return body;
5331  }
5332
5333  ;
5334
5335  /**
5336   * injectElementWithStyles injects an element with style element and some CSS rules
5337   *
5338   * @access private
5339   * @function injectElementWithStyles
5340   * @param {string} rule - String representing a css rule
5341   * @param {function} callback - A function that is used to test the injected element
5342   * @param {number} [nodes] - An integer representing the number of additional nodes you want injected
5343   * @param {string[]} [testnames] - An array of strings that are used as ids for the additional nodes
5344   * @returns {boolean}
5345   */
5346
5347  function injectElementWithStyles(rule, callback, nodes, testnames) {
5348    var mod = 'modernizr';
5349    var style;
5350    var ret;
5351    var node;
5352    var docOverflow;
5353    var div = createElement('div');
5354    var body = getBody();
5355
5356    if (parseInt(nodes, 10)) {
5357      // In order not to give false positives we create a node for each test
5358      // This also allows the method to scale for unspecified uses
5359      while (nodes--) {
5360        node = createElement('div');
5361        node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
5362        div.appendChild(node);
5363      }
5364    }
5365
5366    style = createElement('style');
5367    style.type = 'text/css';
5368    style.id = 's' + mod;
5369
5370    // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody.
5371    // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270
5372    (!body.fake ? div : body).appendChild(style);
5373    body.appendChild(div);
5374
5375    if (style.styleSheet) {
5376      style.styleSheet.cssText = rule;
5377    } else {
5378      style.appendChild(document.createTextNode(rule));
5379    }
5380    div.id = mod;
5381
5382    if (body.fake) {
5383      //avoid crashing IE8, if background image is used
5384      body.style.background = '';
5385      //Safari 5.13/5.1.4 OSX stops loading if ::-webkit-scrollbar is used and scrollbars are visible
5386      body.style.overflow = 'hidden';
5387      docOverflow = docElement.style.overflow;
5388      docElement.style.overflow = 'hidden';
5389      docElement.appendChild(body);
5390    }
5391
5392    ret = callback(div, rule);
5393    // If this is done after page load we don't want to remove the body so check if body exists
5394    if (body.fake) {
5395      body.parentNode.removeChild(body);
5396      docElement.style.overflow = docOverflow;
5397      // Trigger layout so kinetic scrolling isn't disabled in iOS6+
5398      docElement.offsetHeight;
5399    } else {
5400      div.parentNode.removeChild(div);
5401    }
5402
5403    return !!ret;
5404
5405  }
5406
5407  ;
5408
5409  /**
5410   * testStyles injects an element with style element and some CSS rules
5411   *
5412   * @memberof Modernizr
5413   * @name Modernizr.testStyles
5414   * @optionName Modernizr.testStyles()
5415   * @optionProp testStyles
5416   * @access public
5417   * @function testStyles
5418   * @param {string} rule - String representing a css rule
5419   * @param {function} callback - A function that is used to test the injected element
5420   * @param {number} [nodes] - An integer representing the number of additional nodes you want injected
5421   * @param {string[]}
5421 [testnames] - An array of strings that are used as ids for the additional nodes
5422   * @returns {boolean}
5423   * @example
5424   *
5425   * `Modernizr.testStyles` takes a CSS rule and injects it onto the current page
5426   * along with (possibly multiple) DOM elements. This lets you check for features
5427   * that can not be detected by simply checking the [IDL](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Interface_development_guide/IDL_interface_rules).
5428   *
5429   * ```js
5430   * Modernizr.testStyles('#modernizr { width: 9px; color: papayawhip; }', function(elem, rule) {
5431   *   // elem is the first DOM node in the page (by default #modernizr)
5432   *   // rule is the first argument you supplied - the CSS rule in string form
5433   *
5434   *   addTest('widthworks', elem.style.width === '9px')
5435   * });
5436   * ```
5437   *
5438   * If your test requires multiple nodes, you can include a third argument
5439   * indicating how many additional div elements to include on the page. The
5440   * additional nodes are injected as children of the `elem` that is returned as
5441   * the first argument to the callback.
5442   *
5443   * ```js
5444   * Modernizr.testStyles('#modernizr {width: 1px}; #modernizr2 {width: 2px}', function(elem) {
5445   *   document.getElementById('modernizr').style.width === '1px'; // true
5446   *   document.getElementById('modernizr2').style.width === '2px'; // true
5447   *   elem.firstChild === document.getElementById('modernizr2'); // true
5448   * }, 1);
5449   * ```
5450   *
5451   * By default, all of the additional elements have an ID of `modernizr[n]`, where
5452   * `n` is its index (e.g. the first additional, second overall is `#modernizr2`,
5453   * the second additional is `#modernizr3`, etc.).
5454   * If you want to have more meaningful IDs for your function, you can provide
5455   * them as the fourth argument, as an array of strings
5456   *
5457   * ```js
5458   * Modernizr.testStyles('#foo {width: 10px}; #bar {height: 20px}', function(elem) {
5459   *   elem.firstChild === document.getElementById('foo'); // true
5460   *   elem.lastChild === document.getElementById('bar'); // true
5461   * }, 2, ['foo', 'bar']);
5462   * ```
5463   *
5464   */
5465
5466  var testStyles = ModernizrProto.testStyles = injectElementWithStyles;
5467  
5468
5469  /**
5470   * fnBind is a super small [bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) polyfill.
5471   *
5472   * @access private
5473   * @function fnBind
5474   * @param {function} fn - a function you want to change `this` reference to
5475   * @param {object} that - the `this` you want to call the function with
5476   * @returns {function} The wrapped version of the supplied function
5477   */
5478
5479  function fnBind(fn, that) {
5480    return function() {
5481      return fn.apply(that, arguments);
5482    };
5483  }
5484
5485  ;
5486
5487  /**
5488   * testDOMProps is a generic DOM property test; if a browser supports
5489   *   a certain property, it won't return undefined for it.
5490   *
5491   * @access private
5492   * @function testDOMProps
5493   * @param {array.<string>} props - An array of properties to test for
5494   * @param {object} obj - An object or Element you want to use to test the parameters again
5495   * @param {boolean|object} elem - An Element to bind the property lookup again. Use `false` to prevent the check
5496   */
5497  function testDOMProps(props, obj, elem) {
5498    var item;
5499
5500    for (var i in props) {
5501      if (props[i] in obj) {
5502
5503        // return the property name as a string
5504        if (elem === false) {
5505          return props[i];
5506        }
5507
5508        item = obj[props[i]];
5509
5510        // let's bind a function
5511        if (is(item, 'function')) {
5512          // bind to obj unless overriden
5513          return fnBind(item, elem || obj);
5514        }
5515
5516        // return the unbound function or obj or value
5517        return item;
5518      }
5519    }
5520    return false;
5521  }
5522
5523  ;
5524
5525  /**
5526   * Create our "modernizr" element that we do most feature tests on.
5527   *
5528   * @access private
5529   */
5530
5531  var modElem = {
5532    elem: createElement('modernizr')
5533  };
5534
5535  // Clean up this element
5536  Modernizr._q.push(function() {
5537    delete modElem.elem;
5538  });
5539
5540  
5541
5542  var mStyle = {
5543    style: modElem.elem.style
5544  };
5545
5546  // kill ref for gc, must happen before mod.elem is removed, so we unshift on to
5547  // the front of the queue.
5548  Modernizr._q.unshift(function() {
5549    delete mStyle.style;
5550  });
5551
5552  
5553
5554  /**
5555   * domToCSS takes a camelCase string and converts it to kebab-case
5556   * e.g. boxSizing -> box-sizing
5557   *
5558   * @access private
5559   * @function domToCSS
5560   * @param {string} name - String name of camelCase prop we want to convert
5561   * @returns {string} The kebab-case version of the supplied name
5562   */
5563
5564  function domToCSS(name) {
5565    return name.replace(/([A-Z])/g, function(str, m1) {
5566      return '-' + m1.toLowerCase();
5567    }).replace(/^ms-/, '-ms-');
5568  }
5569  ;
5570
5571  /**
5572   * nativeTestProps allows for us to use native feature detection functionality if available.
5573   * some prefixed form, or false, in the case of an unsupported rule
5574   *
5575   * @access private
5576   * @function nativeTestProps
5577   * @param {array} props - An array of property names
5578   * @param {string} value - A string representing the value we want to check via @supports
5579   * @returns {boolean|undefined} A boolean when @supports exists, undefined otherwise
5580   */
5581
5582  // Accepts a list of property names and a single value
5583  // Returns `undefined` if native detection not available
5584  function nativeTestProps(props, value) {
5585    var i = props.length;
5586    // Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface
5587    if ('CSS' in window && 'supports' in window.CSS) {
5588      // Try every prefixed variant of the property
5589      while (i--) {
5590        if (window.CSS.supports(domToCSS(props[i]), value)) {
5591          return true;
5592        }
5593      }
5594      return false;
5595    }
5596    // Otherwise fall back to at-rule (for Opera 12.x)
5597    else if ('CSSSupportsRule' in window) {
5598      // Build a condition string for every prefixed variant
5599      var conditionText = [];
5600      while (i--) {
5601        conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')');
5602      }
5603      conditionText = conditionText.join(' or ');
5604      return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function(node) {
5605        return getComputedStyle(node, null).position == 'absolute';
5606      });
5607    }
5608    return undefined;
5609  }
5610  ;
5611
5612  // testProps is a generic CSS / DOM property test.
5613
5614  // In testing support for a given CSS property, it's legit to test:
5615  //    `elem.style[styleName] !== undefined`
5616  // If the property is supported it will return an empty string,
5617  // if unsupported it will return undefined.
5618
5619  // We'll take advantage of this quick test and skip setting a style
5620  // on our modernizr element, but instead just testing undefined vs
5621  // empty string.
5622
5623  // Property names can be provided in either camelCase or kebab-case.
5624
5625  function testProps(props, prefixed, value, skipValueTest) {
5626    skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest;
5627
5628    // Try native detect first
5629    if (!is(value, 'undefined')) {
5630      var result = nativeTestProps(props, value);
5631      if (!is(result, 'undefined')) {
5632        return result;
5633      }
5634    }
5635
5636    // Otherwise do it properly
5637    var afterInit, i, propsLength, prop, before;
5638
5639    // If we don't have a style element, that means we're running async or after
5640    // the core tests, so we'll need to create our own elements to use
5641
5642    // inside of an SVG element, in certain browsers, the `style` element is only
5643    // defined for valid tags. Therefore, if `modernizr` does not have one, we
5644    // fall back to a less used element and hope for the best.
5645    // for strict XHTML browsers the hardly used samp element is used
5646    var elems = ['modernizr', 'tspan', 'samp'];
5647    while (!mStyle.style && elems.length) {
5648      afterInit = true;
5649      mStyle.modElem = createElement(elems.shift());
5650      mStyle.style = mStyle.modElem.style;
5651    }
5652
5653    // Delete the objects if we created them.
5654    function cleanElems() {
5655      if (afterInit) {
5656        delete mStyle.style;
5657        delete mStyle.modElem;
5658      }
5659    }
5660
5661    propsLength = props.length;
5662    for (i = 0; i < propsLength; i++) {
5663      prop = props[i];
5664      before = mStyle.style[prop];
5665
5666      if (contains(prop, '-')) {
5667        prop = cssToDOM(prop);
5668      }
5669
5670      if (mStyle.style[prop] !== undefined) {
5671
5672        // If value to test has been passed in, do a set-and-check test.
5673        // 0 (integer) is a valid property value, so check that `value` isn't
5674        // undefined, rather than just checking it's truthy.
5675        if (!skipValueTest && !is(value, 'undefined')) {
5676
5677          // Needs a try catch block because of old IE. This is slow, but will
5678          // be avoided in most cases because `skipValueTest` will be used.
5679          try {
5680            mStyle.style[prop] = value;
5681          } catch (e) {}
5682
5683          // If the property value has changed, we assume the value used is
5684          // supported. If `value` is empty string, it'll fail here (because
5685          // it hasn't changed), which matches how browsers have implemented
5686          // CSS.supports()
5687          if (mStyle.style[prop] != before) {
5688            cleanElems();
5689            return prefixed == 'pfx' ? prop : true;
5690          }
5691        }
5692        // Otherwise just return true, or the property name if this is a
5693        // `prefixed()` call
5694        else {
5695          cleanElems();
5696          return prefixed == 'pfx' ? prop : true;
5697        }
5698      }
5699    }
5700    cleanElems();
5701    return false;
5702  }
5703
5704  ;
5705
5706  /**
5707   * testProp() investigates whether a given style property is recognized
5708   * Property names can be provided in either camelCase or kebab-case.
5709   *
5710   * @memberof Modernizr
5711   * @name Modernizr.testProp
5712   * @access public
5713   * @optionName Modernizr.testProp()
5714   * @optionProp testProp
5715   * @function testProp
5716   * @param {string} prop - Name of the CSS property to check
5717   * @param {string} [value] - Name of the CSS value to check
5718   * @param {boolean} [useValue] - Whether or not to check the value if @supports isn't supported
5719   * @returns {boolean}
5720   * @example
5721   *
5722   * Just like [testAllProps](#modernizr-testallprops), only it does not check any vendor prefixed
5723   * version of the string.
5724   *
5725   * Note that the property name must be provided in camelCase (e.g. boxSizing not box-sizing)
5726   *
5727   * ```js
5728   * Modernizr.testProp('pointerEvents')  // true
5729   * ```
5730   *
5731   * You can also provide a value as an optional second argument to check if a
5732   * specific value is supported
5733   *
5734   * ```js
5735   * Modernizr.testProp('pointerEvents', 'none') // true
5736   * Modernizr.testProp('pointerEvents', 'penguin') // false
5737   * ```
5738   */
5739
5740  var testProp = ModernizrProto.testProp = function(prop, value, useValue) {
5741    return testProps([prop], undefined, value, useValue);
5742  };
5743  
5744
5745  /**
5746   * testPropsAll tests a list of DOM properties we want to check against.
5747   * We specify literally ALL possible (known and/or likely) properties on
5748   * the element including the non-vendor prefixed one, for forward-
5749   * compatibility.
5750   *
5751   * @access private
5752   * @function testPropsAll
5753   * @param {string} prop - A string of the property to test for
5754   * @param {string|object} [prefixed] - An object to check the prefixed properties on. Use a string to skip
5755   * @param {HTMLElement|SVGElement} [elem] - An element used to test the property and value against
5756   * @param {string} [value] - A string of a css value
5757   * @param {boolean} [skipValueTest] - An boolean representing if you want to test if value sticks when set
5758   */
5759  function testPropsAll(prop, prefixed, elem, value, skipValueTest) {
5760
5761    var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1),
5762    props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' ');
5763
5764    // did they call .prefixed('boxSizing') or are we just testing a prop?
5765    if (is(prefixed, 'string') || is(prefixed, 'undefined')) {
5766      return testProps(props, prefixed, value, skipValueTest);
5767
5768      // otherwise, they called .prefixed('requestAnimationFrame', window[, elem])
5769    } else {
5770      props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' ');
5771      return testDOMProps(props, prefixed, elem);
5772    }
5773  }
5774
5775  // Modernizr.testAllProps() investigates whether a given style property,
5776  // or any of its vendor-prefixed variants, is recognized
5777  //
5778  // Note that the property names must be provided in the camelCase variant.
5779  // Modernizr.testAllProps('boxSizing')
5780  ModernizrProto.testAllProps = testPropsAll;
5781
5782  
5783
5784  /**
5785   * prefixed returns the prefixed or nonprefixed property name variant of your input
5786   *
5787   * @memberof Modernizr
5788   * @name Modernizr.prefixed
5789   * @optionName Modernizr.prefixed()
5790   * @optionProp prefixed
5791   * @access public
5792   * @function prefixed
5793   * @param {string} prop - String name of the property to test for
5794   * @param {object} [obj] - An object to test for the prefixed properties on
5795   * @param {HTMLElement} [elem] - An element used to test specific properties against
5796   * @returns {string|false} The string representing the (possibly prefixed) valid
5797   * version of the property, or `false` when it is unsupported.
5798   * @example
5799   *
5800   * Modernizr.prefixed takes a string css value in the DOM style camelCase (as
5801   * opposed to the css style kebab-case) form and returns the (possibly prefixed)
5802   * version of that property that the browser actually supports.
5803   *
5804   * For example, in older Firefox...
5805   * ```js
5806   * prefixed('boxSizing')
5807   * ```
5808   * returns 'MozBoxSizing'
5809   *
5810   * In newer Firefox, as well as any other browser that support the unprefixed
5811   * version would simply return `boxSizing`. Any browser that does not support
5812   * the property at all, it will return `false`.
5813   *
5814   * By default, prefixed is checked against a DOM element. If you want to check
5815   * for a property on another object, just pass it as a second argument
5816   *
5817   * ```js
5818   * var rAF = prefixed('requestAnimationFrame', window);
5819   *
5820   * raf(function() {
5821   *  renderFunction();
5822   * })
5823   * ```
5824   *
5825   * Note that this will return _the actual function_ - not the name of the function.
5826   * If you need the actual name of the property, pass in `false` as a third argument
5827   *
5828   * ```js
5829   * var rAFProp = prefixed('requestAnimationFrame', window, false);
5830   *
5831   * rafProp === 'WebkitRequestAnimationFrame' // in older webkit
5832   * ```
5833   *
5834   * One common use case for prefixed is if you're trying to determine which transition
5835   * end event to bind to, you might do something like...
5836   * ```js
5837   * var transEndEventNames = {
5838   *     'WebkitTransition' : 'webkitTransitionEnd', * Saf 6, Android Browser
5839   *     'MozTransition'    : 'transitionend',       * only for FF < 15
5840   *     'transition'       : 'transitionend'        * IE10, Opera, Chrome, FF 15+, Saf 7+
5841   * };
5842   *
5843   * var transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
5844   * ```
5845   *
5846   * If you want a similar lookup, but in kebab-case, you can use [prefixedCSS](#modernizr-prefixedcss).
5847   */
5848
5849  var prefixed = ModernizrProto.prefixed = function(prop, obj, elem) {
5850    if (prop.indexOf('@') === 0) {
5851      return atRule(prop);
5852    }
5853
5854    if (prop.indexOf('-') != -1) {
5855      // Convert kebab-case to camelCase
5856      prop = cssToDOM(prop);
5857    }
5858    if (!obj) {
5859      return testPropsAll(prop, 'pfx');
5860    } else {
5861      // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame'
5862      return testPropsAll(prop, obj, elem);
5863    }
5864  };
5865
5866  
5867
5868  /**
5869   * testAllProps determines whether a given CSS property is supported in the browser
5870   *
5871   * @memberof Modernizr
5872   * @name Modernizr.testAllProps
5873   * @optionName Modernizr.testAllProps()
5874   * @optionProp testAllProps
5875   * @access public
5876   * @function testAllProps
5877   * @param {string} prop - String naming the property to test (either camelCase or kebab-case)
5878   * @param {string} [value] - String of the value to test
5879   * @param {boolean} [skipValueTest=false] - Whether to skip testing that the value is supported when using non-native detection
5880   * @example
5881   *
5882   * testAllProps determines whether a given CSS property, in some prefixed form,
5883   * is supported by the browser.
5884   *
5885   * ```js
5886   * testAllProps('boxSizing')  // true
5887   * ```
5888   *
5889   * It can optionally be given a CSS value in string form to test if a property
5890   * value is valid
5891   *
5892   * ```js
5893   * testAllProps('display', 'block') // true
5894   * testAllProps('display', 'penguin') // false
5895   * ```
5896   *
5897   * A boolean can be passed as a third parameter to skip the value check when
5898   * native detection (@supports) isn't available.
5899   *
5900   * ```js
5901   * testAllProps('shapeOutside', 'content-box', true);
5902   * ```
5903   */
5904
5905  function testAllProps(prop, value, skipValueTest) {
5906    return testPropsAll(prop, undefined, undefined, value, skipValueTest);
5907  }
5908  ModernizrProto.testAllProps = testAllProps;
5909  
5910/*!
5911{
5912  "name": "CSS Animations",
5913  "property": "cssanimations",
5914  "caniuse": "css-animation",
5915  "polyfills": ["transformie", "csssandpaper"],
5916  "tags": ["css"],
5917  "warnings": ["Android < 4 will pass this test, but can only animate a single property at a time"],
5918  "notes": [{
5919    "name" : "Article: 'Dispelling the Android CSS animation myths'",
5920    "href": "https://goo.gl/OGw5Gm"
5921  }]
5922}
5923!*/
5924/* DOC
5925Detects whether or not elements can be animated using CSS
5926*/
5927
5928  Modernizr.addTest('cssanimations', testAllProps('animationName', 'a', true));
5929
5930/*!
5931{
5932  "name": "CSS Transitions",
5933  "property": "csstransitions",
5934  "caniuse": "css-transitions",
5935  "tags": ["css"]
5936}
5937!*/
5938
5939  Modernizr.addTest('csstransitions', testAllProps('transition', 'all', true));
5940
5941/*!
5942{
5943  "name": "Touch Events",
5944  "property": "touchevents",
5945  "caniuse" : "touch",
5946  "tags": ["media", "attribute"],
5947  "notes": [{
5948    "name": "Touch Events spec",
5949    "href": "https://www.w3.org/TR/2013/WD-touch-events-20130124/"
5950  }],
5951  "warnings": [
5952    "Indicates if the browser supports the Touch Events spec, and does not necessarily reflect a touchscreen device"
5953  ],
5954  "knownBugs": [
5955    "False-positive on some configurations of Nokia N900",
5956    "False-positive on some BlackBerry 6.0 builds – https://github.com/Modernizr/Modernizr/issues/372#issuecomment-3112695"
5957  ]
5958}
5959!*/
5960/* DOC
5961Indicates if the browser supports the W3C Touch Events API.
5962
5963This *does not* necessarily reflect a touchscreen device:
5964
5965* Older touchscreen devices only emulate mouse events
5966* Modern IE touch devices implement the Pointer Events API instead: use `Modernizr.pointerevents` to detect support for that
5967* Some browsers & OS setups may enable touch APIs when no touchscreen is connected
5968* Future browsers may implement other event models for touch interactions
5969
5970See this article: [You Can't Detect A Touchscreen](http://www.stucox.com/blog/you-cant-detect-a-touchscreen/).
5971
5972It's recommended to bind both mouse and touch/pointer events simultaneously – see [this HTML5 Rocks tutorial](http://www.html5rocks.com/en/mobile/touchandmouse/).
5973
5974This test will also return `true` for Firefox 4 Multitouch support.
5975*/
5976
5977  // Chrome (desktop) used to lie about its support on this, but that has since been rectified: http://crbug.com/36415
5978  Modernizr.addTest('touchevents', function() {
5979    var bool;
5980    if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
5981      bool = true;
5982    } else {
5983      // include the 'heartz' as a way to have a non matching MQ to help terminate the join
5984      // https://git.io/vznFH
5985      var query = ['@media (', prefixes.join('touch-enabled),('), 'heartz', ')', '{#modernizr{top:9px;position:absolute}}'].join('');
5986      testStyles(query, function(node) {
5987        bool = node.offsetTop === 9;
5988      });
5989    }
5990    return bool;
5991  });
5992
5993
5994  // Run each test
5995  testRunner();
5996
5997  // Remove the "no-js" class if it exists
5998  setClasses(classes);
5999
6000  delete ModernizrProto.addTest;
6001  delete ModernizrProto.addAsyncTest;
6002
6003  // Run the things that are supposed to run after the tests
6004  for (var i = 0; i < Modernizr._q.length; i++) {
6005    Modernizr._q[i]();
6006  }
6007
6008  // Leak Modernizr namespace
6009  window.Modernizr = Modernizr;
6010
6011
6012;
6013
6014})(window, document);
6015$(function() {
6016    ParallaxScroll.init();
6017});
6018
6019// Credit: https://github.com/alumbo/jquery.parallax-scroll
6020var ParallaxScroll = {
6021    /* PUBLIC VARIABLES */
6022    showLogs: false,
6023    round: 1000,
6024
6025    /* PUBLIC FUNCTIONS */
6026    init: function() {
6027        this._log("init");
6028        if (this._inited) {
6029            this._log("Already Inited");
6030            this._inited = true;
6031            return;
6032        }
6033        this._requestAnimationFrame = (function(){
6034          return  window.requestAnimationFrame       || 
6035                  window.webkitRequestAnimationFrame || 
6036                  window.mozRequestAnimationFrame    || 
6037                  window.oRequestAnimationFrame      || 
6038                  window.msRequestAnimationFrame     || 
6039                  function(/* function */ callback, /* DOMElement */ element){
6040                      window.setTimeout(callback, 1000 / 60);
6041                  };
6042        })();
6043        this._onScroll(true);
6044    },
6045
6046    /* PRIVATE VARIABLES */
6047    _inited: false,
6048    _properties: ['x', 'y', 'z', 'rotateX', 'rotateY', 'rotateZ', 'scaleX', 'scaleY', 'scaleZ', 'scale'],
6049    _requestAnimationFrame:null,
6050
6051    /* PRIVATE FUNCTIONS */
6052    _log: function(message) {
6053        if (this.showLogs) console.log("Parallax Scroll / " + message);
6054    },
6055    _onScroll: function(noSmooth) {
6056        var scroll = $(document).scrollTop();
6057        var windowHeight = $(window).height();
6058        this._log("onScroll " + scroll);
6059        $("[data-parallax]").each($.proxy(function(index, el) {
6060            var $el = $(el);
6061            var properties = [];
6062            var applyProperties = false;
6063            var style = $el.data("style");
6064            if (style == undefined) {
6065                style = $el.attr("style") || "";
6066                $el.data("style", style);
6067            }
6068            var datas = [$el.data("parallax")];
6069            var iData;
6070            for(iData = 2; ; iData++) {
6071                if($el.data("parallax"+iData)) {
6072                    datas.push($el.data("parallax-"+iData));
6073                }
6074                else {
6075                    break;
6076                }
6077            }
6078            var datasLength = datas.length;
6079            for(iData = 0; iData < datasLength; iData ++) {
6080                var data = datas[iData];
6081                var scrollFrom = data["from-scroll"];
6082                if (scrollFrom == undefined) scrollFrom = Math.max(0, $(el).offset().top - windowHeight);
6083                scrollFrom = scrollFrom | 0;
6084                var scrollDistance = data["distance"];
6085                var scrollTo = data["to-scroll"];
6086                if (scrollDistance == undefined && scrollTo == undefined) scrollDistance = windowHeight;
6087                scrollDistance = Math.max(scrollDistance | 0, 1);
6088                var easing = data["easing"];
6089                var easingReturn = data["easing-return"];
6090                if (easing == undefined || !$.easing|| !$.easing[easing]) easing = null;
6091                if (easingReturn == undefined || !$.easing|| !$.easing[easingReturn]) easingReturn = easing;
6092                if (easing) {
6093                    var totalTime = data["duration"];
6094                    if (totalTime == undefined) totalTime = scrollDistance;
6095                    totalTime = Math.max(totalTime | 0, 1);
6096                    var totalTimeReturn = data["duration-return"];
6097                    if (totalTimeReturn == undefined) totalTimeReturn = totalTime;
6098                    scrollDistance = 1;
6099                    var currentTime = $el.data("current-time");
6100                    if(currentTime == undefined) currentTime = 0;
6101                }
6102                if (scrollTo == undefined) scrollTo = scrollFrom + scrollDistance;
6103                scrollTo = scrollTo | 0;
6104                var smoothness = data["smoothness"];
6105                if (smoothness == undefined) smoothness = 30;
6106                smoothness = smoothness | 0;
6107                if (noSmooth || smoothness == 0) smoothness = 1;
6108                smoothness = smoothness | 0;
6109                var scrollCurrent = scroll;
6110                scrollCurrent = Math.max(scrollCurrent, scrollFrom);
6111                scrollCurrent = Math.min(scrollCurrent, scrollTo);
6112                if(easing) {
6113                    if($el.data("sens") == undefined) $el.data("sens", "back");
6114                    if(scrollCurrent>scrollFrom) {
6115                        if($el.data("sens") == "back") {
6116                            currentTime = 1;
6117                            $el.data("sens", "go");
6118                        }
6119                        else {
6120                            currentTime++;
6121                        }
6122                    }
6123                    if(scrollCurrent<scrollTo) {
6124                        if($el.data("sens") == "go") {
6125                            currentTime = 1;
6126                            $el.data("sens", "back");
6127                        }
6128                        else {
6129                            currentTime++;
6130                        }
6131                    }
6132                    if(noSmooth) currentTime = totalTime;
6133                    $el.data("current-time", currentTime);
6134                }
6135                this._properties.map($.proxy(function(prop) {
6136                    var defaultProp = 0;
6137                    var to = data[prop];
6138                    if (to == undefined) return;
6139                    if(prop=="scale" || prop=="scaleX" || prop=="scaleY" || prop=="scaleZ" ) {
6140                        defaultProp = 1;
6141                    }
6142                    else {
6143                        to = to | 0;
6144                    }
6145                    var prev = $el.data("_" + prop);
6146                    if (prev == undefined) prev = defaultProp;
6147                    var next = ((to-defaultProp) * ((scrollCurrent - scrollFrom) / (scrollTo - scrollFrom))) + defaultProp;
6148                    var val = prev + (next - prev) / smoothness;
6149                    if(easing && currentTime>0 && currentTime<=totalTime) {
6150                        var from = defaultProp;
6151                        if($el.data("sens") == "back") {
6152                            from = to;
6153                            to = -to;
6154                            easing = easingReturn;
6155                            totalTime = totalTimeReturn;
6156                        }
6157                        val = $.easing[easing](null, currentTime, from, to, totalTime);
6158                    }
6159                    val = Math.ceil(val * this.round) / this.round;
6160                    if(val==prev&&next==to) val = to;
6161                    if(!properties[prop]) properties[prop] = 0;
6162                    properties[prop] += val;
6163                    if (prev != properties[prop]) {
6164                        $el.data("_" + prop, properties[prop]);
6165                        applyProperties = true;
6166                    }
6167                }, this));
6168            }
6169            if (applyProperties) {
6170                if (properties["z"] != undefined) {
6171                    var perspective = data["perspective"];
6172                    if (perspective == undefined) perspective = 800;
6173                    var $parent = $el.parent();
6174                    if(!$parent.data("style")) $parent.data("style", $parent.attr("style") || "");
6175                    $parent.attr("style", "perspective:" + perspective + "px; -webkit-perspective:" + perspective + "px; "+ $parent.data("style"));
6176                }
6177                if(properties["scaleX"] == undefined) properties["scaleX"] = 1;
6178                if(properties["scaleY"] == undefined) properties["scaleY"] = 1;
6179                if(properties["scaleZ"] == undefined) properties["scaleZ"] = 1;
6180                if (properties["scale"] != undefined) {
6181                    properties["scaleX"] *= properties["scale"];
6182                    properties["scaleY"] *= properties["scale"];
6183                    properties["scaleZ"] *= properties["scale"];
6184                }
6185                var translate3d = "translate3d(" + (properties["x"] ? properties["x"] : 0) + "px, " + (properties["y"] ? properties["y"] : 0) + "px, " + (properties["z"] ? properties["z"] : 0) + "px)";
6186                var rotate3d = "rotateX(" + (properties["rotateX"] ? properties["rotateX"] : 0) + "deg) rotateY(" + (properties["rotateY"] ? properties["rotateY"] : 0) + "deg) rotateZ(" + (properties["rotateZ"] ? properties["rotateZ"] : 0) + "deg)";
6187                var scale3d = "scaleX(" + properties["scaleX"] + ") scaleY(" + properties["scaleY"] + ") scaleZ(" + properties["scaleZ"] + ")";
6188                var cssTransform = translate3d + " " + rotate3d + " " + scale3d + ";";
6189                this._log(cssTransform);
6190                $el.attr("style", "transform:" + cssTransform + " -webkit-transform:" + cssTransform + " " + style);
6191            }
6192        }, this));
6193        if(window.requestAnimationFrame) {
6194            window.requestAnimationFrame($.proxy(this._onScroll, this, false));
6195        }
6196        else {
6197            this._requestAnimationFrame($.proxy(this._onScroll, this, false));
6198        }
6199    }
6200};
6201;
6202(function($, window, undefined) {
6203
6204	'use strict';
6205
6206	// global
6207	var Modernizr = window.Modernizr,
6208		$body = $('body');
6209
6210	$.DLMenu = function(options, element) {
6211		this.$el = $(element);
6212		this._init(options);
6213	};
6214
6215	$.DLMenu.defaults = {
6216		animationClasses: {
6217			classin: 'mk-vm-animate-in-' + mk_vertical_header_anim,
6218			classout: 'mk-vm-animate-out-' + mk_vertical_header_anim
6219		},
6220		onLevelClick: function(el, name) {
6221			return false;
6222		},
6223		onLinkClick: function(el, ev) {
6224			return false;
6225		}
6226	};
6227
6228	$.DLMenu.prototype = {
6229		_init: function(options) {
6230
6231			this.options = $.extend(true, {}, $.DLMenu.defaults, options);
6232			this._config();
6233
6234			var animEndEventNames = {
6235					'WebkitAnimation': 'webkitAnimationEnd',
6236					'OAnimation': 'oAnimationEnd',
6237					'msAnimation': 'MSAnimationEnd',
6238					'animation': 'animationend'
6239				},
6240				transEndEventNames = {
6241					'WebkitTransition': 'webkitTransitionEnd',
6242					'MozTransition': 'transitionend',
6243					'OTransition': 'oTransitionEnd',
6244					'msTransition': 'MSTransitionEnd',
6245					'transition': 'transitionend'
6246				};
6247
6248			this.animEndEventName = animEndEventNames[Modernizr.prefixed('animation')] + '.dlmenu';
6249			this.transEndEventName = transEndEventNames[Modernizr.prefixed('transition')] + '.dlmenu';
6250
6251			this.animEndEventNameUnsufixed = animEndEventNames[Modernizr.prefixed('animation')];
6252			this.transEndEventNameUnsufixed = transEndEventNames[Modernizr.prefixed('transition')];
6253
6254			this.supportAnimations = Modernizr.cssanimations;
6255			this.supportTransitions = Modernizr.csstransitions;
6256
6257			this._initEvents();
6258
6259		},
6260		_config: function() {
6261			this.open = false;
6262			this.$trigger = this.$el.children('.mk-vm-trigger');
6263			this.$menu = this.$el.children('ul.mk-vm-menu');
6264			this.$menuitems = this.$menu.find('li:not(.mk-vm-back)');
6265			this.$back = this.$menu.find('li.mk-vm-back');
6266		},
6267		_initEvents: function() {
6268
6269			var self = this;
6270			
6271			$('.mk-vm-menuwrapper a').on('transitionend', function(event) {
6272				event.stopPropagation();
6273			});
6274
6275			this.$menuitems.on('click.dlmenu', 'a', function(event) {
6276
6277				// Breaks smooth scroll in vertical menu
6278				// event.stopPropagation();
6279
6280				var $item = $(event.delegateTarget),
6281					$submenu = $(event.currentTarget).siblings('ul.sub-menu');
6282
6283				if ($submenu.length > 0) {
6284					var $flyin = $submenu.clone().css('opacity', 0).insertAfter(self.$menu);
6285					var onAnimationEndFn = function() {
6286						var $parent = $item.parents('.mk-vm-subviewopen:first');
6287						self.$menu.off(self.animEndEventName).removeClass(self.options.animationClasses.classout).addClass('mk-vm-subview');
6288						$item.addClass('mk-vm-subviewopen')
6289						$parent.removeClass('mk-vm-subviewopen').addClass('mk-vm-subview');
6290						$flyin.remove();
6291
6292						// Redraw for firefox issues
6293						var $txt = $item.find('.meni-item-text');
6294						$txt.css('opacity', 0.99);
6295						setTimeout(function() { $txt.css('opacity', 1) }, 0);
6296					};
6297
6298					setTimeout(function() {
6299						$flyin.addClass(self.options.animationClasses.classin);
6300						self.$menu.addClass(self.options.animationClasses.classout);
6301						if (self.supportAnimations) {
6302							self.$menu.on(self.animEndEventName, onAnimationEndFn);
6303						} else {
6304							onAnimationEndFn.call();
6305						}
6306
6307						self.options.onLevelClick($item, $item.children('a:first').text());
6308					});
6309
6310
6311					// This caused firefox issue. Test properly if need to bring it back
6312					// if (self.open) {
6313					// 	self._closeMenu();
6314					// } else {
6315					// 	self._openMenu();
6316					// }
6317
6318					return false;
6319
6320				} else {
6321					self.options.onLinkClick($item, event);
6322				}
6323
6324			});
6325
6326
6327			// this.$trigger.on('click.dlmenu', function() {
6328
6329			// 	if (self.open) {
6330			// 		self._closeMenu();
6331			// 	} else {
6332			// 		// if( ! $(this).hasClass('menu-item-has-children') ) return false;
6333			// 		self._openMenu();
6334			// 	}
6335			// 	return false;
6336
6337			// });
6338
6339			this.$back.on('click.dlmenu', function(event) {
6340
6341				var $this = $(this),
6342					$submenu = $this.parents('ul.sub-menu:first'),
6343					$item = $submenu.parent(),
6344
6345					$flyin = $submenu.clone().insertAfter(self.$menu);
6346
6347				var onAnimationEndFn = function() {
6348					self.$menu.off(self.animEndEventName).removeClass(self.options.animationClasses.classin);
6349					$flyin.remove();
6350				};
6351
6352				setTimeout(function() {
6353					$flyin.addClass(self.options.animationClasses.classout);
6354					self.$menu.addClass(self.options.animationClasses.classin);
6355					if (self.supportAnimations) {
6356						self.$menu.on(self.animEndEventName, onAnimationEndFn);
6357					} else {
6358						onAnimationEndFn.call();
6359					}
6360
6361					$item.removeClass('mk-vm-subviewopen');
6362
6363					var $subview = $this.parents('.mk-vm-subview:first');
6364					if ($subview.is('li')) {
6365						$subview.addClass('mk-vm-subviewopen');
6366					}
6367					$subview.removeClass('mk-vm-subview');
6368				});
6369
6370				return false;
6371
6372			});
6373
6374		},
6375		closeMenu: function() {
6376			if (this.open) {
6377				this._closeMenu();
6378			}
6379		},
6380		_closeMenu: function() {
6381			var self = this,
6382				onTransitionEndFn = function() {
6383					self.$menu.off(self.transEndEventName);
6384					self._resetMenu();
6385				};
6386
6387			this.$menu.removeClass('mk-vm-menuopen');
6388			this.$menu.addClass('mk-vm-menu-toggle');
6389			this.$trigger.removeClass('mk-vm-active');
6390
6391			if (this.supportTransitions) {
6392				this.$menu.on(this.transEndEventName, onTransitionEndFn);
6393			} else {
6394				onTransitionEndFn.call();
6395			}
6396
6397			this.open = false;
6398		},
6399		openMenu: function() {
6400			if (!this.open) {
6401				this._openMenu();
6402			}
6403		},
6404		_openMenu: function() {
6405			var self = this;
6406			$body.off('click').on('click.dlmenu', function() {
6407				self._closeMenu();
6408			});
6409			this.$menu.addClass('mk-vm-menuopen mk-vm-menu-toggle').on(this.transEndEventName, function() {
6410				$(this).removeClass('mk-vm-menu-toggle');
6411			});
6412			this.$trigger.addClass('mk-vm-active');
6413			this.open = true;
6414		},
6415		_resetMenu: function() {
6416			this.$menu.removeClass('mk-vm-subview');
6417			this.$menuitems.removeClass('mk-vm-subview mk-vm-subviewopen');
6418		}
6419	};
6420
6421	var logError = function(message) {
6422		if (window.console) {
6423			window.console.error(message);
6424		}
6425	};
6426
6427	$.fn.dlmenu = function(options) {
6428		if (typeof options === 'string') {
6429			var args = Array.prototype.slice.call(arguments, 1);
6430			this.each(function() {
6431				var instance = $.data(this, 'dlmenu');
6432				if (!instance) {
6433					logError("cannot call methods on dlmenu prior to initialization; " +
6434						"attempted to call method '" + options + "'");
6435					return;
6436				}
6437				if (!$.isFunction(instance[options]) || options.charAt(0) === "_") {
6438					logError("no such method '" + options + "' for dlmenu instance");
6439					return;
6440				}
6441				instance[options].apply(instance, args);
6442			});
6443		} else {
6444			this.each(function() {
6445				var instance = $.data(this, 'dlmenu');
6446				if (instance) {
6447					instance._init();
6448				} else {
6449					instance = $.data(this, 'dlmenu', new $.DLMenu(options, this));
6450				}
6451			});
6452		}
6453		return this;
6454	};
6455
6456})(jQuery, window);
6457( function($) {
6458    'use strict';
6459
6460	/* 
6461	 * Define popup / hover states manually to prevent click for IE on touchdevices
6462	 */
6463
6464	$('.mk-main-navigation .menu-item-has-children').children('a').attr('aria-haspopup', 'true'); 
6465	$('.animated-column-item').attr('aria-haspopup', 'true');
6466
6467})( jQuery );
6468(function($) {
6469    'use strict';
6470
6471    var Accordion = function(el) { 
6472        // Private
6473        var that = this,
6474            $el = $(el),
6475            initial = $el.data('initialindex'),
6476            timeout;
6477
6478        // Public
6479        this.$el = $el;
6480        this.$single = $('.' + this.dom.single, $el);
6481        this.isExpendable = ($el.data('style') === 'toggle-action');
6482
6483        // Init 
6484        this.bindClicks();
6485        // Reveal initial tab on load event (wait for possible images inside)
6486        $(window).on('load', function() {
6487            if( initial !== -1 ) that.show(that.$single.eq(initial))
6488        });
6489        $(window).on('resize', function() {
6490            clearTimeout(timeout);
6491            timeout = setTimeout(that.bindClicks.bind(that), 500);
6492        }); 
6493    }
6494
6495    Accordion.prototype.dom = {
6496        // only class names please!
6497        single        : 'mk-accordion-single',
6498        tab           : 'mk-accordion-tab',
6499        pane          : 'mk-accordion-pane',
6500        current       : 'current',
6501        mobileToggle  : 'mobile-false',
6502        mobileBreakPoint : 767
6503    }
6504
6505    Accordion.prototype.bindClicks = function() {
6506        // Prevent multiple events binding
6507        this.$single.off('click', '.' + this.dom.tab);
6508
6509        if( !(window.matchMedia('(max-width: ' + this.dom.mobileBreakPoint +'px)').matches 
6510          && this.$el.hasClass(this.dom.mobileToggle)) ) {
6511
6512            this.$single.on('click', '.' + this.dom.tab, this.handleEvent.bind(this));
6513            // When website is loaded in mobile view and resized to desktop 'current' will 
6514            // inherit display: none from css. Repair it by calling show() on this element
6515            var $current = $('.' + this.dom.current, this.$el);
6516            if($('.' + this.dom.pane, $current).css('display') === 'none') this.show($current);
6517        }
6518    }
6519
6520    Accordion.prototype.handleEvent = function(e) {
6521        e.preventDefault();
6522        e.stopPropagation();
6523
6524        var $single = $(e.delegateTarget);
6525
6526        if(!$single.hasClass(this.dom.current)) {
6527            this.show($single);
6528        }
6529        else {
6530            if(this.isExpendable) this.hide($single);
6531        }
6532    }
6533
6534    Accordion.prototype.hide = function($single) {
6535        $single.removeClass(this.dom.current);
6536        $('.' + this.dom.pane, $single).slideUp();
6537    }
6538
6539    Accordion.prototype.show = function($single) {
6540        // hide currently opened tab
6541        if(!this.isExpendable) {
6542            var that = this;
6543            this.hide($('.' + this.dom.current, that.$el));
6544        }
6545
6546        $single.addClass(this.dom.current);
6547        $('.' + this.dom.pane, $single).slideDown();
6548    }
6549
6550
6551
6552    // ///////////////////////////////////////
6553    //
6554    // Apply to:
6555    //
6556    // ///////////////////////////////////////
6557
6558	function init() {
6559		$('.mk-accordion').each(function() {
6560			new Accordion(this);
6561		});
6562	}
6563
6564	init();
6565	$(window).on('vc_reload', init);
6566
6567})(jQuery);
6568
6569(function($) {
6570
6571    'use strict';
6572
6573    var SkillDiagram = function( el ) {
6574        this.el = el;
6575    }
6576
6577    SkillDiagram.prototype = {
6578        init : function() {
6579            this.cacheElements();
6580            this.createDiagram();
6581            this.$skills.each( this.createSkill.bind( this ) );
6582        },
6583
6584        cacheElements : function() {
6585            this.$el = $( this.el );
6586            this.$skills = this.$el.find( '.mk-meter-arch');
6587            this.config  = this.$el.data();
6588            this.config.radius = this.config.dimension / 2;
6589        },
6590
6591        random : function( l, u ) {
6592            return Math.floor( ( Math.random() * ( u - l + 1 ) ) + l );
6593        },
6594
6595        createDiagram : function() {
6596            var self = this;
6597            $(this.el).find('svg').remove();
6598            
6599            this.diagram = Raphael( this.el, this.config.dimension, this.config.dimension );
6600
6601            // Make svg scalable in different screen sizes
6602            this.diagram.setViewBox(0,0,this.config.dimension,this.config.dimension,true);
6603            this.diagram.setSize('90%', '90%');
6604
6605            this.diagram.circle( this.config.radius, this.config.radius, 80 ).attr({ 
6606                stroke: 'none', 
6607                fill: this.config.circleColor 
6608            });
6609        
6610            // Export title
6611            this.title = this.diagram.text( this.config.radius, this.config.radius, this.config.defaultText ).attr({
6612                font: "22px helvetica",
6613                fill: this.config.defaultTextColor
6614            }).toFront();
6615            
6616            this.diagram.customAttributes.arc = function(value, color, rad){
6617                var v = 3.6 * value,
6618                    alpha = v == 360 ? 359.99 : v,
6619                    r  = self.random( 91, 240 ),
6620                    a  = (r - alpha) * Math.PI/180,
6621                    b  = r * Math.PI/180,
6622                    sx = self.config.radius + rad * Math.cos(b),
6623                    sy = self.config.radius - rad * Math.sin(b),
6624                    x  = self.config.radius + rad * Math.cos(a),
6625                    y  = self.config.radius - rad * Math.sin(a),
6626                    path = [['M', sx, sy], ['A', rad, rad, 0, +(alpha > 180), 1, x, y]];
6627
6628                return { 
6629                    path: path, 
6630                    stroke: color 
6631                }
6632            }
6633        },
6634
6635        createSkill : function( id, el ) {
6636            var self   = this,
6637                $this  = $( el ),
6638                config = $this.data(),
6639                radMin = 72,
6640                radVal = 27,
6641                newRad = radMin + ( radVal * (id + 1) );
6642
6643            var $path = this.diagram.path().attr({
6644                'stroke-width': 28,
6645                arc: [config.percent, config.color, newRad]
6646            });
6647
6648            $path.mouseover( function() {
6649                self.showSkill( this, config.name, config.percent );
6650            }).mouseout( function() {
6651                self.hideSkill( this ) 
6652            });
6653        },
6654
6655        showSkill : function( self, name, percent ) {
6656            var $this = self,
6657                time = 250;
6658
6659            //solves IE problem
6660            if(Raphael.type != 'VML') $this.toFront();
6661
6662            $this.animate({ 
6663                'stroke-width': 50, 
6664                'opacity': 0.9, 
6665            }, 800, 'elastic' );
6666
6667            this.title.stop()
6668                .animate({ opacity: 0 }, time, '>', function(){
6669                    this.attr({ text: name + '\n' + percent + '%' }).animate({ opacity: 1 }, time, '<');
6670                }).toFront();
6671        },
6672
6673        hideSkill : function( self ) {
6674            var $this = self,
6675                self = this,
6676                time = 250;
6677
6678            $this.stop().animate({ 
6679                'stroke-width': 28, 
6680                opacity: 1 
6681            }, time * 4, 'elastic' );
6682
6683            self.title.stop()
6684                .animate({ opacity: 0 }, time, '>', function(){
6685                    self.title.attr({ text: self.config.defaultText })
6686                    .animate({ opacity: 1 }, time, '<');
6687                }); 
6688        }
6689    }
6690
6691    var init = function init() {
6692        if( typeof Raphael === 'undefined' ) return;
6693        $( '.mk-skill-diagram' ).each( function() {
6694            var diagram = new SkillDiagram( this );
6695                diagram.init();
6696        });
6697    }
6698
6699    init();
6700    $(window).on('vc_reload', init);
6701
6702})(jQuery);
6703/*
6704 * Tab delegation 
6705 * Action for modules when we don't have access to chidren DOM on processing templates
6706 * yet we want ass option of opening link in new tab. 
6707 * Helpful for use with external widgets like flickr
6708 */
6709
6710(function($) {
6711
6712	'use strict';
6713
6714	$( '[data-js="tab-delegation"]' ).each( tabDelegation );
6715
6716	function tabDelegation() {
6717		var $this = $( this ),
6718			data  = $this.data();
6719
6720		// Create delegation on parent element to affect async loaded children
6721		if( data.tab ) $this.on( 'click', 'a', openInTab );
6722	}
6723
6724	function openInTab( e ) {
6725		e.preventDefault(); 
6726
6727		var $this = $( this ),
6728			url = $this.attr( 'href' );
6729
6730		window.open( url, '_blank' );
6731	}
6732
6733})(jQuery);
6734(function($) {
6735    'use strict';
6736
6737    var init = function init() {
6738        var Toggle = function(el) {
6739        var that = this,
6740            $el = $(el);
6741
6742            this.$el = $el;
6743            $el.toggle(that.open.bind(that), that.close.bind(that));
6744        };
6745
6746        Toggle.prototype.dom = {
6747            pane   : 'mk-toggle-pane',
6748            active : 'active-toggle'
6749        };
6750
6751        Toggle.prototype.open = function() {
6752            var $this = this.$el;
6753            $this.addClass(this.dom.active);
6754            $this.siblings('.' + this.dom.pane).slideDown(200);
6755        };
6756
6757        Toggle.prototype.close = function() {
6758            var $this = this.$el;
6759            $this.removeClass(this.dom.active);
6760            $this.siblings('.' + this.dom.pane).slideUp(200);
6761        };
6762
6763        // Apply to.
6764        var $toggle = $('.mk-toggle-title');
6765
6766        if(!$toggle.length) return;
6767
6768        $toggle.each(function() {
6769            new Toggle(this);
6770        });
6771    }
6772    $(window).on('load vc_reload', init);
6773
6774})(jQuery);
6775//////////////////////////////////////////////////////////////////////////
6776//
6777//   Init all scripts
6778//
6779//////////////////////////////////////////////////////////////////////////
6780
6781// This is bad but we don't have other access to this scope.
6782// Ajax Portfolio  is defined as plugin and on success needs these to be reinited
6783// We'll refactor all of this.
6784window.ajaxInit = function() {
6785    mk_lightbox_init();
6786    mk_click_events();
6787    mk_social_share_global();
6788   // mk_social_share();
6789    mk_gallery();
6790    loop_audio_init();
6791};
6792
6793window.ajaxDelayedInit = function() {
6794    mk_flexslider_init();
6795    // mk_portfolio_ajax();
6796};
6797
6798$(document).ready(function() {
6799    mk_lightbox_init();
6800    mk_login_form();
6801    mk_backgrounds_parallax();
6802    mk_flexslider_init();
6803    mk_event_countdown();
6804    mk_skill_meter();
6805    mk_milestone();
6806    mk_ajax_search();
6807    mk_hover_events();
6808    mk_portfolio_ajax();
6809    mk_love_post();
6810    product_loop_add_cart();
6811  //  mk_social_share();
6812    mk_portfolio_widget();
6813    mk_contact_form();
6814    mk_blog_carousel();
6815    mk_header_searchform();
6816    mk_click_events();
6817    mk_text_typer();
6818    mk_tab_slider_func();
6819
6820    $(window).on('load', function() {
6821        mk_unfold_footer();
6822        mk_tabs();
6823        mk_accordion_toggles_tooltip();
6824        mk_gallery();
6825        mk_theatre_responsive_calculator();
6826        mk_tabs_responsive();
6827        mk_start_tour_resize();
6828        mk_header_social_resize();
6829        mk_page_section_social_video_bg();
6830        loop_audio_init();
6831        mk_one_page_scroller();
6832        mkPositionSidebar();
6833
6834        setTimeout(function() {
6835            /*
6836                Somehow the values are not correctly updated for the screens
6837                and we need to put setTimeout to fix the issue
6838            */
6839            mk_mobile_tablet_responsive_calculator();
6840        }, 300);
6841
6842        console.log("ready for rock");
6843    });
6844
6845
6846    var onDebouncedResize = function() {
6847        mk_theatre_responsive_calculator();
6848        mk_mobile_tablet_responsive_calculator();
6849        mk_tabs_responsive();
6850        mk_accordion_toggles_tooltip();
6851        mk_start_tour_resize();
6852        mk_header_social_resize();
6853
6854        setTimeout(function() {
6855            mk_unfold_footer();
6856        }, 300);
6857    };
6858
6859    var debounceResize = null;
6860    $(window).on("resize", function() {
6861        if( debounceResize !== null ) { clearTimeout( debounceResize ); }
6862        debounceResize = setTimeout( onDebouncedResize, 300 );
6863    });
6864
6865    var onDebouncedScroll = function() {
6866        mk_skill_meter();
6867        //TODO: Ask to Bart how we can call javascript component
6868        //mk_charts();
6869        mk_milestone();
6870    };
6871
6872    var debounceScroll = null;
6873    $(window).on("scroll", function() {
6874        if( debounceScroll !== null ) { clearTimeout( debounceScroll ); }
6875        debounceScroll = setTimeout( onDebouncedScroll, 100 );
6876    });
6877
6878    if (MK.utils.isMobile()) {
6879        $('body').addClass('no-transform');
6880    }
6881
6882});
6883
6884/* VC frontend editor  */
6885/* -------------------------------------------------------------------- */
6886$(window).on("vc_reload",function () {
6887    mk_flexslider_init();
6888    loop_audio_init();
6889    mk_tab_slider_func();
6890    mk_event_countdown();
6891    videoLoadState();
6892    mk_page_section_social_video_bg();
6893    mk_hover_events();
6894
6895    setTimeout(function() {
6896        mkPositionSidebar();
6897    }, 200);
6898});
6899
6900// Replace this if new event for remove found.
6901$( document ).on( 'click', '.vc_control-btn-delete', function() {
6902    $( window ).trigger( 'vc_reload' );
6903} );
6904
6905$( document ).on( 'sortupdate', '.ui-sortable', function() {
6906    $( window ).trigger( 'vc_reload' );
6907} );
6908
6909/* Typer */
6910/* -------------------------------------------------------------------- */
6911function mk_text_typer() {
6912
6913    "use strict";
6914
6915    $('[data-typer-targets]').each(function() {
6916        var that = this;
6917        MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.typed.js' ], function() {
6918            var $this = $(that),
6919                $first_string = [$this.text()],
6920                $rest_strings = $this.attr('data-typer-targets').split(','),
6921                $strings = $first_string.concat($rest_strings);
6922
6923            $this.text('');
6924
6925            $this.typed({
6926                strings: $strings,
6927                typeSpeed: 30, // typing speed
6928                backDelay: 1200, // pause before backspacing
6929                loop: true, // loop on or off (true or false)
6930                loopCount: false, // number of loops, false = infinite
6931            });
6932        });
6933    });
6934}
6935
6936
6937
6938/* Tab Slider */
6939/* -------------------------------------------------------------------- */
6940
6941function mk_tab_slider_func() {
6942
6943    "use strict";
6944
6945    $('.mk-tab-slider').each(function() {
6946        var that = this;
6947
6948        MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.swiper.js' ], function() {
6949            var $this = $(that),
6950                id = $this.data('id'),
6951                $autoplayTime = $this.data('autoplay'),
6952                $content = $('.mk-slider-content');
6953
6954            var mk_tab_slider = $this.swiper({
6955                wrapperClass: 'mk-tab-slider-wrapper',
6956                slideClass: 'mk-tab-slider-item',
6957                calculateHeight: true,
6958                speed: 500,
6959                autoplay: isTest ? false : $autoplayTime,
6960                onSlideChangeStart: function() {
6961                    $('.mk-tab-slider-nav[data-id="' + id + '"]').find(".active").removeClass('active')
6962                    $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").eq(mk_tab_slider.activeIndex).addClass('active')
6963                }
6964            });
6965
6966            // Simple repaint for firefox issue (can't handle 100% height after plugin init)
6967            function repaintFirefox() {
6968                $content.css('display','block');
6969                setTimeout(function() {
6970                    mk_tab_slider.reInit();
6971                    $content.css('display','table');
6972                },100);
6973            }
6974
6975            $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").first().addClass('active');
6976
6977            $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").on('touchstart mousedown', function(e) {
6978                e.preventDefault()
6979                $('.mk-tab-slider-nav[data-id="' + id + '"]').find(".active").removeClass('active')
6980                $(this).addClass('active')
6981                mk_tab_slider.swipeTo($(this).index())
6982            });
6983
6984            $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").click(function(e) {
6985                e.preventDefault();
6986            });
6987
6988            repaintFirefox();
6989            $(window).on('resize', repaintFirefox);
6990        });
6991
6992    });
6993
6994}
6995
6996
6997
6998/* Edge One Pager */
6999/* -------------------------------------------------------------------- */
7000function mk_one_page_scroller() {
7001
7002    "use strict";
7003
7004    $('.mk-edge-one-pager').each(function() {
7005        var self = this;
7006
7007        MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.fullpage.js' ], function() {
7008
7009            var $this = $(self),
7010                anchorArr = [];
7011
7012            $this.find('.section').each(function() {
7013                anchorArr.push($(this).attr('data-title'));
7014            });
7015
7016            var scrollable = true;
7017            $this.find('.section').each(function() {
7018                var $section = $(this),
7019                    $content = $section.find('.edge-slide-content'),
7020                    sectionHeight = $section.height(),
7021                    contentHeight = $content.innerHeight();
7022
7023                if((contentHeight + 30) > $(window).height()) {
7024                    scrollable = false;
7025                }
7026            });
7027
7028            if(!scrollable){
7029                $this.find('.section').each(function() {
7030                    var $section = $(this);
7031                    $section.addClass('active').css({
7032                        'padding-bottom': '50px'
7033                    });
7034                });
7035            }
7036
7037            if(scrollable) {
7038                $this.fullpage({
7039                    verticalCentered: false,
7040                    resize: true,
7041                    slidesColor: ['#ccc', '#fff'],
7042                    anchors: anchorArr,
7043                    scrollingSpeed: 600,
7044                    easing: 'easeInQuart',
7045                    menu: false,
7046                    navigation: true,
7047                    navigationPosition: 'right',
7048                    navigationTooltips: false,
7049                    slidesNavigation: true,
7050                    slidesNavPosition: 'bottom',
7051                    loopBottom: false,
7052                    loopTop: false,
7053                    loopHorizontal: true,
7054                    autoScrolling: true,
7055                    scrollOverflow: false,
7056                    css3: true,
7057                    paddingTop: 0,
7058                    paddingBottom: 0,
7059                    normalScrollElements: '.mk-header, .mk-responsive-wrap',
7060                    normalScrollElementTouchThreshold: 5,
7061                    keyboardScrolling: true,
7062                    touchSensitivity: 15,
7063                    continuousVertical: false,
7064                    animateAnchor: true,
7065
7066                    onLeave: function(index, nextIndex, direction) {
7067                        var currentSkin = $this.find('.one-pager-slide').eq(nextIndex - 1).attr('data-header-skin');
7068                        MK.utils.eventManager.publish( 'firstElSkinChange', currentSkin );
7069                        $('#fullPage-nav').removeClass('light-skin dark-skin').addClass(currentSkin + '-skin');
7070
7071                    },
7072                    afterRender: function() {
7073
7074                        var $nav = $('#fullPage-nav');
7075
7076                        setTimeout(function() {
7077                            var currentSkin = $this.find('.one-pager-slide').eq(0).attr('data-header-skin');
7078                            MK.utils.eventManager.publish( 'firstElSkinChange', currentSkin );
7079                            if($nav.length) $nav.removeClass('light-skin dark-skin').addClass(currentSkin + '-skin');
7080                        }, 300);
7081
7082                        var $slide = $this.find('.section'),
7083                            headerHeight = MK.val.offsetHeaderHeight(0),
7084                            windowHeight = $(window).height();
7085
7086                        $slide.height(windowHeight - headerHeight);
7087
7088                        if($nav.length) {
7089                            $nav.css({
7090                                'top': 'calc(50% + ' + (headerHeight/2) + 'px)',
7091                                'marginTop': 0
7092                            });
7093
7094                            var style = $this.attr('data-pagination');
7095                            $nav.addClass('pagination-' + style);
7096                        }
7097
7098                        setTimeout(mk_one_pager_resposnive, 1000);
7099                    },
7100                    afterResize: function() {
7101                        var $slide = $this.find('.section'),
7102                            headerHeight = MK.val.offsetHeaderHeight(0),
7103                            windowHeight = $(window).height();
7104
7105                        $slide.height(windowHeight - headerHeight);
7106
7107                        $('#fullPage-nav').css({
7108                            'top': 'calc(50% + ' + (headerHeight/2) + 'px)',
7109                            'marginTop': 0
7110                        });
7111
7112                        setTimeout(mk_one_pager_resposnive, 1000);
7113                        console.log('Reposition pager content.');
7114                    },
7115                });
7116            }
7117
7118            // Linking to slides available for desktop and mobile scenarios
7119            function swipeTo(href, e) {
7120                href = '_' + href; // ensure a char before #
7121                if (!~href.indexOf('#')) return;
7122                var section = href.split('#')[1];
7123                if (~anchorArr.indexOf(section)) {
7124                    if (typeof e !== 'undefined') e.preventDefault();
7125                    if (scrollable) $.fn.fullpage.moveTo(section);
7126                    else MK.utils.scrollToAnchor('[data-title="'+section+'"]');
7127                }
7128            }
7129
7130            // onload
7131            var loc = window.location;
7132            if(loc.hash) swipeTo(loc.hash);
7133
7134            $(document).on('click', 'a', function(e) {
7135                var $link = $(e.currentTarget);
7136                swipeTo($link.attr('href'), e);
7137            });
7138        });
7139    });
7140
7141
7142
7143}
7144
7145
7146function mk_one_pager_resposnive() {
7147    "use strict";
7148
7149    $('.mk-edge-one-pager').each(function() {
7150        var $pager = $(this),
7151            headerHeight = MK.val.offsetHeaderHeight(0),
7152            windowHeight = $(window).height() - headerHeight;
7153
7154        $pager.find('.one-pager-slide').each(function() {
7155            var $slide = $(this),
7156                $content = $slide.find('.edge-slide-content');
7157
7158            if ($slide.hasClass('left_center') || $slide.hasClass('center_center') || $slide.hasClass('right_center')) {
7159                var contentHeight  = $content.height(),
7160                    distanceFromTop = (windowHeight - contentHeight) / 2;
7161
7162                distanceFromTop  = (distanceFromTop < 50) ? 50 + headerHeight : distanceFromTop;
7163
7164                $content.css('marginTop', distanceFromTop);
7165            }
7166
7167            if ($slide.hasClass('left_bottom') || $slide.hasClass('center_bottom') || $slide.hasClass('right_bottom')) {
7168                var distanceFromTop = windowHeight - $content.height() - 90;
7169                $content.css('marginTop', (distanceFromTop));
7170            }
7171        });
7172
7173        /**
7174         * Fix AM-2853
7175         *
7176         * @since 6.0.3
7177         *
7178         * At the init of Edge One Pager (EOP), EOP will render all image
7179         * background of each sections from top to bottom. In this case,
7180         * the page height will be more than screen height and the scroll
7181         * bar will appear. At the same time, the full width row will set
7182         * the container width into 100%. But, after all Slides are set up,
7183         * EOP height will be 100% of the screen height, so the scroll bar
7184         * will be disappeared. It's caused spacing issues on the left and
7185         * right side of the EOP container. To fix this, the row width
7186         * should be resized and row position should be readjusted.
7187         */
7188        var $row = $pager.parents( '.vc_row.vc_row-fluid.mk-fullwidth-true' );
7189
7190        // Run only if the Edge One Pager is wrapped inside full width row.
7191        if ( $row.length > 0 ) {
7192            // Set the wrapper and row width.
7193            var $wrapper = $( '.mk-main-wrapper-holder' );
7194            var $grid = $row.children( '.mk-grid' );
7195            var rowWidth = $row.width();         // Original width.
7196            var wrapperWidth = $wrapper.width(); // The new width.
7197
7198            // Run only if original width is smaller than the new width.
7199            if ( rowWidth >= wrapperWidth || $grid.length > 0 ) {
7200                return;
7201            }
7202
7203            // Get the content left offset.
7204            var $content = $wrapper.find( '.theme-content' );
7205            var oriPos = $content.position();
7206            var oriPadLeft = $content.css( 'padding-left' );
7207            var oriLeft = parseInt( oriPos.left ) + parseInt( oriPadLeft );
7208
7209            // Ensure the new width and left position is more than 0.
7210            if ( wrapperWidth <= 0 || oriLeft <= 0 ) {
7211                return;
7212            }
7213
7214            // Resize the width and left position of row full width.
7215            $row.css({
7216                'width': wrapperWidth,
7217                'left': oriLeft * -1,
7218            });
7219        }
7220    });
7221}
7222
7223/* Image Gallery */
7224/* -------------------------------------------------------------------- */
7225
7226function mk_gallery() {
7227
7228    "use strict";
7229
7230    $('.mk-gallery .mk-gallery-item.hover-overlay_layer .item-holder').each(function() {
7231        var itemHolder = $(this),
7232            galleryDesc = itemHolder.find('.gallery-desc');
7233
7234        function updatePosition() {
7235            var parentHeight = itemHolder.outerHeight(),
7236                contentHeight = galleryDesc.innerHeight();
7237
7238            var paddingVal = (parentHeight - contentHeight) / 2;
7239            galleryDesc.css({
7240                'top': paddingVal,
7241                // 'padding-bottom': paddingVal
7242            });
7243
7244            // console.log(parentHeight);
7245            // console.log(contentHeight);
7246
7247
7248        }
7249        updatePosition();
7250
7251        $(window).on('resize', function() {
7252            setTimeout(function() {
7253                updatePosition();
7254            }, 1000);
7255        });
7256    });
7257    // Execute hover state for mk gallery item
7258    if ($(window).width() <= 1024) {
7259        $('.mk-gallery .mk-gallery-item').on('click', function (e) {
7260            var clicks = $(this).data('clicks');
7261            if (clicks) {
7262                // First click
7263                $(this).toggleClass('hover-state');
7264            } else {
7265                // Second click
7266                $(this).toggleClass('hover-state');
7267            }
7268            $(this).data("clicks", !clicks);
7269        });
7270    }
7271}
7272
7273/* Theatre Slider Responsive Calculator */
7274/* -------------------------------------------------------------------- */
7275
7276function mk_theatre_responsive_calculator() {
7277    var $laptopContainer = $(".laptop-theatre-slider");
7278    var $computerContainer = $(".desktop-theatre-slider");
7279    $laptopContainer.each(function() {
7280        var $this = $(this),
7281            $window = $(window),
7282            $windowWidth = $window.outerWidth(),
7283            $windowHeight = $window.outerHeight(),
7284            $width = $this.outerWidth(),
7285            $height = $this.outerHeight(),
7286            $paddingTop = 38,
7287            $paddingRight = 143,
7288            $paddingBottom = 78,
7289            $paddingLeft = 143;
7290
7291        var $player = $this.find('.player-container');
7292
7293        if ($windowWidth > $width) {
7294            $player.css({
7295                'padding-left': parseInt(($width * $paddingLeft) / 1200),
7296                'padding-right': parseInt(($width * $paddingRight) / 1200),
7297                'padding-top': parseInt(($height * $paddingTop) / 690),
7298                'padding-bottom': parseInt(($height * $paddingBottom) / 690),
7299            });
7300        }
7301
7302    });
7303
7304    $computerContainer.each(function() {
7305        var $this = $(this),
7306            $window = $(window),
7307            $windowWidth = $window.outerWidth(),
7308            $windowHeight = $window.outerHeight(),
7309            $width = $this.outerWidth(),
7310            $height = $this.outerHeight(),
7311            $paddingTop = 60,
7312            $paddingRight = 52,
7313            $paddingBottom = 290,
7314            $paddingLeft = 49;
7315
7316        var $player = $this.find('.player-container');
7317
7318        if ($windowWidth > $width) {
7319            $player.css({
7320                'padding-left': parseInt(($width * $paddingLeft) / 1200),
7321                'padding-right': parseInt(($width * $paddingRight) / 1200),
7322                'padding-top': parseInt(($height * $paddingTop) / 969),
7323                'padding-bottom': parseInt(($height * $paddingBottom) / 969),
7324            });
7325        }
7326
7327    });
7328
7329}
7330
7331/* Mobile and Tablet Slideshow Responsive Calculator */
7332/* -------------------------------------------------------------------- */
7333function mk_mobile_tablet_responsive_calculator() {
7334    var $laptopSlideshow = $(".mk-laptop-slideshow-shortcode");
7335    var $lcdSlideshow = $(".mk-lcd-slideshow");
7336
7337    if ($.exists(".mk-laptop-slideshow-shortcode")) {
7338        $laptopSlideshow.each(function() {
7339            var $this = $(this),
7340                $window = $(window),
7341                $windowWidth = $window.outerWidth(),
7342                $windowHeight = $window.outerHeight(),
7343                $width = $this.outerWidth(),
7344                $height = $this.outerHeight(),
7345                $paddingTop = 28,
7346                $paddingRight = 102,
7347                $paddingBottom = 52,
7348                $paddingLeft = 102;
7349
7350            var $player = $this.find(".slideshow-container");
7351
7352            $player.css({
7353                "padding-left": parseInt(($width * $paddingLeft) / 836),
7354                "padding-right": parseInt(($width * $paddingRight) / 836),
7355                "padding-top": parseInt(($height * $paddingTop) / 481),
7356                "padding-bottom": parseInt(($height * $paddingBottom) / 481),
7357            });
7358
7359        });
7360    }
7361
7362    if ($.exists(".mk-lcd-slideshow")) {
7363        $lcdSlideshow.each(function() {
7364            var $this = $(this),
7365                $window = $(window),
7366                $windowWidth = $window.outerWidth(),
7367                $windowHeight = $window.outerHeight(),
7368                $width = $this.outerWidth(),
7369                $height = $this.outerHeight(),
7370                $paddingTop = 35,
7371                $paddingRight = 39,
7372                $paddingBottom = 213,
7373                $paddingLeft = 36;
7374
7375            var $player = $this.find(".slideshow-container");
7376            $player.css({
7377                "padding-left": parseInt(($width * $paddingLeft) / 886),
7378                "padding-right": parseInt(($width * $paddingRight) / 886),
7379                "padding-top": parseInt(($height * $paddingTop) / 713),
7380                "padding-bottom": parseInt(($height * $paddingBottom) / 713),
7381            });
7382        });
7383    }
7384}
7385
7386
7387/* Start a tour resize function */
7388/* -------------------------------------------------------------------- */
7389function mk_start_tour_resize() {
7390
7391    $('.mk-header-start-tour').each(function() {
7392
7393        var $windowWidth = $(document).width(),
7394            $this = $(this),
7395            $linkWidth = $this.width() + 15,
7396            $padding = ($windowWidth - mk_responsive_nav_width) / 2;
7397
7398
7399
7400        function updateStartTour(){
7401            if($windowWidth < mk_responsive_nav_width){
7402                $this.removeClass('hidden');
7403                $this.addClass('show');
7404            }else{
7405                if($padding < $linkWidth){
7406                    $this.removeClass('show');
7407                    $this.addClass('hidden');
7408                }else{
7409                    $this.removeClass('hidden');
7410                    $this.addClass('show');
7411                }
7412            }
7413        }
7414
7415        setTimeout(function() {
7416            updateStartTour();
7417        }, 300);
7418    });
7419}
7420
7421/* Header social resize function */
7422/* -------------------------------------------------------------------- */
7423function mk_header_social_resize() {
7424
7425    $('.mk-header-social.header-section').each(function() {
7426
7427        var $windowWidth = $(document).width(),
7428            $this = $(this),
7429            $linkWidth = $this.width() + 15,
7430            $padding = ($windowWidth - mk_responsive_nav_width) / 2;
7431
7432
7433
7434        function updateStartTour(){
7435            if($windowWidth < mk_responsive_nav_width){
7436                $this.removeClass('hidden');
7437                $this.addClass('show');
7438            }else{
7439                if($padding < $linkWidth){
7440                    $this.removeClass('show');
7441                    $this.addClass('hidden');
7442                }else{
7443                    $this.removeClass('hidden');
7444                    $this.addClass('show');
7445                }
7446            }
7447        }
7448
7449        setTimeout(function() {
7450            updateStartTour();
7451        }, 300);
7452    });
7453}
7454
7455/* Page Section Socail Video Player Controls */
7456/* -------------------------------------------------------------------- */
7457
7458function mk_page_section_social_video_bg() {
7459    $(".mk-page-section.social-hosted").each(function() {
7460        var $container = $(this),
7461            $sound = $container.data('sound'),
7462            $source = $container.data('source'),
7463            player,
7464            timer = 1000;
7465
7466        if ( $( 'body' ).hasClass( '.compose-mode' ) ) {
7467            timer = 2000;
7468        }
7469
7470        if ($source == 'youtube') {
7471            var youtube = $container.find('iframe')[0];
7472            try {
7473                player = new YT.Player(youtube, {
7474                    events: {
7475                        'onReady': function () {
7476                           player.playVideo();
7477                           if($sound == false) {
7478                               player.mute();
7479                           }
7480                       }
7481                    }
7482                });
7483
7484                
7485            } catch (e) {
7486            	console.log( e );
7487            }
7488        }
7489        if ($source == 'vimeo') {
7490            var vimeo = $container.find('iframe')[0];
7491            player = $f(vimeo);
7492            setTimeout(function() {
7493                player.api('play');
7494                if($sound === false) {
7495                    player.api('setVolume', 0);
7496                }
7497            }, timer);
7498        }
7499
7500    });
7501}
7502
7503// Pre RequireJS hot bug fixing
7504
7505function videoLoadState() {
7506    $('.mk-section-video video').each(function() {
7507        var mkVideo = this;
7508
7509        mkVideo.play();
7510        this.onload = fire();
7511
7512        function fire() {
7513            setTimeout(function() {
7514                $(mkVideo).animate({
7515                    'opacity': 1
7516                }, 300);
7517            }, 1000);
7518        }
7519    });
7520}
7521videoLoadState();
7522
7523
7524// Gmap Widget
7525(function($) {
7526
7527    $(window).on('load vc_reload', initialize);
7528
7529    function initialize() {
7530        var $gmap = $('.gmap_widget');
7531        if($gmap.length && typeof google !== 'undefined') $gmap.each(run);
7532    }
7533
7534    function run() {
7535        var $mapHolder = $(this);
7536        var myLatlng = new google.maps.LatLng($mapHolder.data('latitude'), $mapHolder.data('longitude'));
7537        var mapOptions = $mapHolder.data('options');
7538            mapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP;
7539            mapOptions.center = myLatlng;
7540        var map = new google.maps.Map(this, mapOptions);
7541
7542        new google.maps.Marker({
7543            position: myLatlng,
7544            map: map
7545        });
7546    }
7547
7548}(jQuery));
7549
7550// Instagram Widget
7551(function($) {
7552
7553    $(window).on('load', function() {
7554        var $feeds = $('.mk-instagram-feeds');
7555        if($feeds.length) $feeds.each(run);
7556    });
7557
7558    function run() {
7559        var options = $(this).data('options');
7560            options.template = '<a class="featured-image '+options.tmp_col+'-columns" href="{{link}}" target="_'+options.tmp_target+'"><div class="item-holder"><img src="{{image}}" /><div class="image-hover-overlay"></div></div></a>';
7561        var feed = new Instafeed(options);
7562        feed.run();
7563    }
7564}(jQuery));
7565
7566
7567// Flipbox backface visibility fix for chrome
7568(function($) {
7569     $(window).on('load', function() {
7570         setTimeout( function() {
7571            $('.chrome-flipbox-backface-fix').removeClass('chrome-flipbox-backface-fix');
7572         }, 300);
7573     });
7574}(jQuery));
7575
7576
7577/* Product in VC Tab Bug Fix
7578/* -------------------------------------------------------------------- */
7579(function($) {
7580    $(window).on('load', function() {
7581        $('.vc_tta-tab a').on('click', function() {
7582            setTimeout( function() {
7583                $(window).trigger('resize');
7584            }, 100);
7585        });
7586    });
7587}(jQuery));
7588
7589
7590/* Vertical menu fix when childrens exceed screen height
7591/* -------------------------------------------------------------------- */
7592(function($) {
7593    $(window).on('load', function() {
7594        $('#mk-vm-menu .menu-item-has-children, #mk-vm-menu .mk-vm-back').on('mouseenter', function() {
7595            var $header_inner = $(this).closest('.mk-header-inner'),
7596                $header_inner_height = $header_inner.outerHeight(),
7597                $header_bg = $header_inner.find('.mk-header-bg'),
7598                total_height = 0;
7599            $header_bg.css('height', '100%');
7600            setTimeout( function() {
7601                $header_inner.children(':visible').each(function() {
7602                    total_height += $(this).outerHeight(true);
7603                });
7604                total_height -= $header_bg.height();
7605                if ( total_height < $header_inner_height ) {
7606                    $header_bg.css('height', '100%');
7607                } else {
7608                    $header_bg.css('height', total_height + 'px');
7609                }
7610            }, 600);
7611        });
7612    });
7613}(jQuery));
7614
7615
7616/* Woocommerce varitions lightbox fix
7617/* -------------------------------------------------------------------- */
7618(function($) {
7619    $(window).on('load', function() {
7620
7621        var $variations_form = $('.variations_form');
7622
7623        if ( $variations_form.length ) {
7624
7625            var $varitions_selects = $variations_form.find('.variations').find('.value').find('select');
7626            $varitions_selects.on('change', function() {
7627
7628                // Woocommerce variations lightbox with galleries
7629                var $all_img_container = $('.mk-product-image .mk-woocommerce-main-image');
7630                if ( $all_img_container.length ) {
7631                    $( $all_img_container ).each( set_lightbox_href );
7632                }
7633
7634            });
7635            $varitions_selects.trigger('change');
7636
7637        }
7638
7639    });
7640
7641    function set_lightbox_href() {
7642
7643        var $product_img = $( this ).find( 'img' ),
7644            $lightbox    = $( this ).find( '.mk-lightbox' );
7645
7646        setTimeout( function() {
7647            var image_url    = $product_img.attr( 'src' ),
7648                image_suffix = image_url.substr( image_url.lastIndexOf('.') - image_url.length ), // Get image suffix
7649                image_url    = image_url.slice( 0 , image_url.lastIndexOf('-') ); // Remove image size
7650            $lightbox.attr('href', image_url + image_suffix );
7651        }, 300);
7652    }
7653
7654}(jQuery));
7655
7656
7657/* Remove video section when on mobile */
7658/* -------------------------------------------------------------------- */
7659(function($) {
7660    if ( MK.utils.isMobile() ) {
7661      $('.mk-section-video video').remove();
7662    }
7663}(jQuery));
7664
7665
7666/* Yith AJAX Product Filter & Yith Infinite Scrolling Plugin Fix
7667/* -------------------------------------------------------------------- */
7668(function($) {
7669    $(window).on('load', function() {
7670
7671        $(document).on( 'yith-wcan-ajax-filtered yith_infs_added_elem yith-wcan-ajax-reset-filtered', function(){
7672            setTimeout( function() {
7673                MK.utils.eventManager.publish('ajaxLoaded');
7674                MK.core.initAll( document );
7675            }, 1000 );
7676        });
7677
7678        // Fixed YITH Filter plugin causes issue for dropdown sort
7679        $(document).on( 'yith-wcan-ajax-filtered yith-wcan-ajax-reset-filtered', function(){
7680            setTimeout( function() {
7681                $( '.woocommerce-ordering' ).on( 'change', 'select.orderby', function() {
7682                    $( this ).closest( 'form' ).submit();
7683                });
7684            }, 1000 );
7685        });
7686
7687    });
7688}(jQuery));
7689
7690
7691/* Toggle loading state in URL for anchor links.
7692 * - Add a filter to escape meta-chars from hash string.
7693/* -------------------------------------------------------------------- */
7694!function(e){var a=window.location,n=a.hash;if(n.length&&n.substring(1).length){var hSuf = n.substring(1).replace(/[!"#$%&'()*+,./:;<=>?@[\]^`{|}~]/g, "\\$&");var r=e(".vc_row, .mk-main-wrapper-holder, .mk-page-section, #comments"),t=r.filter("#"+hSuf);if(!t.length)return;n=n.replace("!loading","");var i=n+"!loading";a.hash=i}}(jQuery);
7695
7696
7697/* Determine the top spacing of sidebar for full-width page section & row.
7698/* -------------------------------------------------------------------- */
7699function mkPositionSidebar() {
7700	
7701	var themeContent = $( '.theme-content' ),
7702		lastFullWidthChild = themeContent.find( '.vc_row-full-width' ).last(),
7703		top,
7704		sidebar = $( '#theme-page > .mk-main-wrapper-holder > .theme-page-wrapper > #mk-sidebar' );
7705
7706	if ( ! lastFullWidthChild.length ) {
7707		sidebar.removeAttr( 'style' );
7708		return;
7709	}
7710
7711	top = lastFullWidthChild.offset().top - themeContent.offset().top;
7712	sidebar.css( 'padding-top', top );
7713}
7714
7715function mk_accordion_toggles_tooltip() {
7716
7717  "use strict";
7718
7719
7720  /* Message Boxes */
7721  /* -------------------------------------------------------------------- */
7722
7723  $('.box-close-btn').on('click', function() {
7724    $(this).parent().fadeOut(300);
7725    return false;
7726
7727  });
7728
7729}
7730
7731function mk_portfolio_ajax() {
7732  "use strict";
7733
7734  var headerHeight = 0;
7735  if ($.exists("#wpadminbar")) {
7736    headerHeight += $("#wpadminbar").height();
7737  }
7738  if (!$.exists('.mk-vm-menuwrapper')) {
7739    headerHeight += parseInt($('.mk-header').attr('data-sticky-height'));
7740  }
7741
7742  function init() {
7743    var $portfolio = $('.portfolio-grid.portfolio-ajax-enabled');
7744    if (!$portfolio.length) return; // quit if no portfolio wrappers
7745    MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.ajax.portfolio.js' ], function() {
7746      // wait for ajax response propagation and insertion
7747      setTimeout(function() {
7748        $portfolio.each( function() {
7749          $(this).ajaxPortfolio({ extraOffset: headerHeight });
7750        });
7751      }, 100);
7752    });
7753  }
7754
7755  init();
7756
7757  // Reinit when ajax loaded stuff
7758  // We have global reinit on Components. so move the ajaxPortfolio to component namespace as a standalone module to get it right.
7759  MK.utils.eventManager.subscribe('ajaxLoaded', init);
7760}
7761
7762/**
7763 * Ajax Search on header nav.
7764 */
7765function mk_ajax_search() {
7766    "use strict";
7767
7768    // Check if ajax search box enabled.
7769    if (mk_ajax_search_option !== "beside_nav") {
7770        return;
7771    }
7772
7773    // Set minimum length of text to get ajax result.
7774    var minimumLengthToSearch = 3;
7775    var $mkAjaxSearchInput = $('#mk-ajax-search-input');
7776    var security = $mkAjaxSearchInput.siblings('input[name="security"]').val();
7777    var wpHttpReferer = $mkAjaxSearchInput.siblings('input[name="_wp_http_referer"]').val();
7778    var querySpliter = (ajaxurl.indexOf('?') > -1) ? '&' : '?';
7779    var ul = document.getElementById('mk-nav-search-result');
7780    var searchTerm; // Search term
7781    var requestCounter = 0;
7782    var responseCounter = 0;
7783
7784    // Add listener for getting result quickly while user entering text, past text and etc.
7785    $mkAjaxSearchInput.on('paste input propertychange', onSearchBoxInput);
7786
7787    /**
7788     * Callback function for entering search term listener (e.g. keyup).
7789     * It will generate AJAX request to get data.
7790     *
7791     * @param e
7792     */
7793    function onSearchBoxInput(e) {
7794        var target = e.target || e.srcElement;
7795        var newValue = target.value;
7796
7797        // Check if user change the value of text box
7798        if (searchTerm !== newValue) {
7799            searchTerm = newValue;
7800            ul.innerHTML = '';
7801            if (searchTerm.length >= minimumLengthToSearch) {
7802                // Show loading icon
7803                $mkAjaxSearchInput.addClass('ajax-searching');
7804                requestCounter++;
7805                $.getJSON(ajaxurl + querySpliter + 'callback=?&action=mk_ajax_search&security=' + security + '&_wp_http_referer=' + wpHttpReferer + '&term=' + searchTerm)
7806                    .done(showSearchResult)
7807                    .fail(showErrorMessage);
7808            }
7809        }
7810    }
7811
7812    /**
7813     * Callback function for the response of the search request.
7814     *
7815     * @param data
7816     */
7817    function showSearchResult(data) {
7818        responseCounter++;
7819
7820        // Only show response of latest request.
7821        if (isCorrectResponse()) {
7822            if (data.length > 0) {
7823                // Append result to result container
7824                for (var i = 0; i < data.length; i++) {
7825                    var item = data[i];
7826                    $('<li>').append('<a href="' + item.link + '">' + item.image + '<span class="search-title">' + item.label + '</span><span class="search-date">' + item.date + '</span></a>').appendTo(ul);
7827                }
7828            } else {
7829                // Show no result message
7830                ul.innerHTML = '<li class="mk-nav-search-result-zero">No Result.</li>';
7831            }
7832
7833            // Hide loading icon
7834            $mkAjaxSearchInput.parent('form').removeClass('ajax-searching').addClass('ajax-search-complete');
7835        }
7836    }
7837
7838    /**
7839     * If any errors, we need a handler to show error message.
7840     */
7841    function showErrorMessage() {
7842        responseCounter++;
7843
7844        if (isCorrectResponse()) {
7845            ul.innerHTML = '<li class="mk-nav-search-error-message">Can not search! Please try again.</li>';
7846        }
7847    }
7848
7849    /**
7850     * Check if the response is right for the request. we show latest response only.
7851     *
7852     * @returns {boolean}
7853     */
7854    function isCorrectResponse() {
7855        return requestCounter === responseCounter;
7856    }
7857}
7858/* Background Parallax Effects */
7859/* -------------------------------------------------------------------- */
7860
7861function mk_backgrounds_parallax() {
7862
7863  "use strict";
7864
7865  if (mk_header_parallax == true) {
7866    $('.mk-header-bg').addClass('mk-parallax-enabled');
7867  }
7868  if (mk_body_parallax == true) {
7869    $('body').addClass('mk-parallax-enabled');
7870  }
7871  if (mk_banner_parallax == true) {
7872    $('.mk-header').addClass('mk-parallax-enabled');
7873  }
7874  if (mk_footer_parallax == true) {
7875    $('#mk-footer').addClass('mk-parallax-enabled');
7876  }
7877
7878  $('.mk-parallax-enabled').each(function () {
7879    var $this = $( this );
7880    if (!MK.utils.isMobile()) {
7881      MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.parallax.js' ], function() {
7882        $this.parallax("49%", 0.3);
7883      });
7884    }
7885  });
7886
7887  $('.mk-fullwidth-slideshow.parallax-slideshow').each(function () {
7888    var $this = $( this );
7889    if (!MK.utils.isMobile()) {
7890      MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.parallax.js' ], function() {
7891        var speed_factor = $this.attr('data-speedFactor');
7892        $this.parallax("49%", speed_factor);
7893      });
7894    }
7895  });
7896
7897}
7898/* Blog, Portfolio Audio */
7899/* -------------------------------------------------------------------- */
7900
7901function loop_audio_init() {
7902  if ($.exists('.jp-jplayer')) {
7903    $('.jp-jplayer.mk-blog-audio').each(function () {
7904      var $this = $( this );
7905      MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.jplayer.js' ], function() {
7906        var css_selector_ancestor = "#" + $this.siblings('.jp-audio').attr('id');
7907        var ogg_file, mp3_file, mk_theme_js_path;
7908        ogg_file = $this.attr('data-ogg');
7909        mp3_file = $this.attr('data-mp3');
7910        $this.jPlayer({
7911          ready: function () {
7912            $this.jPlayer("setMedia", {
7913              mp3: mp3_file,
7914              ogg: ogg_file
7915            });
7916          },
7917          play: function () { // To avoid both jPlayers playing together.
7918            $this.jPlayer("pauseOthers");
7919          }, 
7920          swfPath: mk_theme_js_path,
7921          supplied: "mp3, ogg",
7922          cssSelectorAncestor: css_selector_ancestor,
7923          wmode: "window"
7924        });
7925      });
7926    });
7927  }
7928}
7929
7930
7931/* Blog Loop Carousel Shortcode */
7932/* -------------------------------------------------------------------- */
7933
7934
7935function mk_blog_carousel() {
7936
7937  "use strict";
7938
7939  if (!$.exists('.mk-blog-showcase')) {
7940    return;
7941  }
7942  $('.mk-blog-showcase ul li').each(function () {
7943
7944    $(this).on('hover', function () {
7945
7946      $(this).siblings('li').removeClass('mk-blog-first-el').end().addClass('mk-blog-first-el');
7947
7948    });
7949
7950  });
7951
7952
7953}
7954
7955
7956
7957
7958/**
7959 * Contact Form
7960 *
7961 * Mostly implemented in Vanilla JS instead of jQuery.
7962 */
7963
7964function mk_contact_form() {
7965    "use strict";
7966
7967    var mkContactForms = document.getElementsByClassName('mk-contact-form');
7968
7969    if (mkContactForms.length === 0) {
7970        return;
7971    }
7972
7973    var captchaImageHolder = $('.captcha-image-holder');
7974    var activeClassName = 'is-active';
7975    var invalidClassName = 'mk-invalid';
7976
7977    for (var i = 0; i < mkContactForms.length; i++) {
7978        initializeForm(mkContactForms[i], activeClassName, invalidClassName);
7979    }
7980
7981    if(captchaImageHolder.length > 0) {
7982        $(window).on('load', initializeCaptchas);    
7983    }
7984
7985    /**
7986     * Initialize mk forms. e.g add activeClassName for inputs.
7987     *
7988     * @param form
7989     * @param activeClassName
7990     * @param invalidClassName
7991     */
7992    function initializeForm(form, activeClassName, invalidClassName) {
7993        var inputs = getFormInputs(form);
7994
7995        for (var i = 0; i < inputs.length; i++) {
7996            markActiveClass(inputs[i]);
7997        }
7998
7999        form.addEventListener('submit', function (e) {
8000            validateForm(e, invalidClassName);
8001        });
8002
8003        /**
8004         * Set activeClassName for the parent node of the inout
8005         */
8006        function setActiveClass() {
8007            addClass(this.parentNode, activeClassName);
8008        }
8009
8010        /**
8011         * Unset activeClassName from the parent node of the input.
8012         * We need to unset activeClassName only if the data was empty.
8013         * e.g. in the line style of the mk-contact-form, we set labels position based on activeClassName.
8014         */
8015        function unsetActiveClass() {
8016            if (this.value === '') {
8017                removeClass(this.parentNode, activeClassName);
8018            }
8019        }
8020
8021        /**
8022         * Add event listeners (focus,blur) for input to set and unset activeClassName.
8023         *
8024         * @param input
8025         */
8026        function markActiveClass(input) {
8027            input.addEventListener('focus', setActiveClass);
8028            input.addEventListener('blur', unsetActiveClass);
8029        }
8030    }
8031
8032    /**
8033     * Validate form when it's submitted. If everything was valid, we with post form in ajax request.
8034     *
8035     * @param e
8036     * @param invalidClassName
8037     */
8038    function validateForm(e, invalidClassName) {
8039        e.preventDefault();
8040        var form = e.target || e.srcElement;
8041        var inputs = getFormInputs(form);
8042        var isValidForm = true;
8043        var hasCaptchaField = false;
8044
8045        for (var i = 0; i < inputs.length; i++) {
8046            var input = inputs[i];
8047            input.value = String(input.value).trim();
8048            switch (input.type) {
8049                case 'hidden':
8050                    break;
8051                case 'email':
8052                    isValidForm = validateEmail(input, invalidClassName) && isValidForm;
8053                    break;
8054                case 'textarea':
8055                    isValidForm = validateText(input, invalidClassName) && isValidForm;
8056                    break;
8057                case 'text':
8058                    /**
8059                     * Some old browsers such as IE 8 and 9 detect email type as text.
8060                     * So, we need to extra check for data-type attribute
8061                     */
8062                    if (input.dataset.type === 'captcha') {
8063                        isValidForm = validateText(input, invalidClassName) && isValidForm;
8064                        hasCaptchaField = true;
8065                    } else if (input.dataset.type === 'email') {
8066                        isValidForm = validateEmail(input, invalidClassName) && isValidForm;
8067                    } else {
8068                        isValidForm = validateText(input, invalidClassName) && isValidForm;
8069                    }
8070                    break;
8071                default:
8072                    /**
8073                     * e.g. validating for radiobox, selectbox and etc.
8074                     */
8075                    console.warn('Implement validation for ' + input.name + ':' + input.type);
8076                    break;
8077            }
8078        }
8079
8080        if (isValidForm) {
8081            if (hasCaptchaField) {
8082                validateCaptcha(form, invalidClassName, sendForm);
8083            } else {
8084                sendForm(form);
8085            }
8086        }
8087    }
8088
8089    /**
8090     * Validate captcha of form. If everything was, we will execute captchaIsValidCallback which as sendForm().
8091     *
8092     * @param form
8093     * @param invalidClassName
8094     * @param captchaIsValidCallback
8095     * @returns boolean
8096     */
8097    function validateCaptcha(form, invalidClassName, captchaIsValidCallback) {
8098        var input = form.querySelectorAll('[data-type="captcha"]')[0];
8099
8100        if (input.value.length === 0) {
8101            addClass(input, invalidClassName);
8102            return false;
8103        } else {
8104            window.get.captcha(input.value).done(function (data) {
8105                loadCaptcha();
8106                input.value = '';
8107
8108                if (data !== 'ok') {
8109                    addClass(input, invalidClassName);
8110                    addClass(input, 'contact-captcha-invalid');
8111                    removeClass(input, 'contact-captcha-valid');
8112                    input.placeholder = mk_captcha_invalid_txt;
8113                } else {
8114                    removeClass(input, invalidClassName);
8115                    removeClass(input, 'contact-captcha-invalid');
8116                    addClass(input, 'contact-captcha-valid');
8117                    input.placeholder = mk_captcha_correct_txt;
8118                    captchaIsValidCallback(form);
8119                }
8120            });
8121        }
8122    }
8123
8124    /**
8125     * Send submitted form.
8126     *
8127     * @param form
8128     */
8129    function sendForm(form) {
8130        var $form = $(form);
8131        var data = getFormData(form);
8132
8133        progressButton.loader($form);
8134        $.post(ajaxurl, data, function (response) {
8135            var res = JSON.parse(response);
8136            if (res.action_Status) {
8137                progressButton.success($form);
8138                $form.find('.text-input').val('');
8139                $form.find('textarea').val('');
8140                $form.find('.contact-form-message').addClass('state-success').html(res.message);
8141            } else {
8142                progressButton.error($form);
8143                $form.find('.contact-form-message').removeClass('state-success').html(res.message);
8144            }
8145        });
8146    }
8147
8148    /**
8149     * Initialize all captcha images for first time. All captcha images is always same. e.g. if we have multiple form,
8150     * all of them will have the same image.
8151     * It will also add event listener for '.captcha-change-image' objects to reload the captcha.
8152     */
8153    function initializeCaptchas() {
8154        var captchaChangeImageButtons = document.getElementsByClassName('captcha-change-image');
8155        for (var i = 0; i < captchaChangeImageButtons.length; i++) {
8156            captchaChangeImageButtons[i].addEventListener('click', loadCaptcha);
8157        }
8158    }
8159
8160    /**
8161     * Load captcha text and append the image to captcha container.
8162     * If it used as a callback, it will prevent default behave of the event.
8163     * e.g. loading new captcha by click on <a> without changing url.
8164     */
8165    function loadCaptcha(e) {
8166        if (e) {
8167            e.preventDefault();
8168        }
8169
8170        $.post(ajaxurl, {action: 'mk_create_captcha_image'}, appendImage);
8171
8172        /**
8173         * The callback function for append or change old image src based on response. T
8174         * The captchaImageURL is the url of the captcha which is provided in ajax response of mk_create_captcha_image.
8175         * @param captchaImageURL
8176         */
8177        function appendImage(captchaImageURL) {
8178            if (captchaImageHolder.find('.captcha-image').length === 0) {
8179                captchaImageHolder.html('<img src="' + captchaImageURL + '" class="captcha-image" alt="captcha txt">');
8180            } else {
8181                captchaImageHolder.find('.captcha-image').attr("src", captchaImageURL+'?'+ new Date().getTime());
8182            }
8183        }
8184    }
8185
8186
8187    /**
8188     * Get form inputs using querySelectorAll().
8189     * It returns <input> and <textarea> tags. If you need any other tags such as <select>, please update this function.
8190     *
8191     * @param form
8192     * @returns {NodeList}
8193     */
8194    function getFormInputs(form) {
8195        return form.querySelectorAll('input,textarea');
8196    }
8197
8198
8199    /**
8200     * Get data of the form inputs and textareas as a object.
8201     *
8202     * @param form
8203     * @returns {{action: string}}
8204     */
8205    function getFormData(form) {
8206        var data = {action: 'mk_contact_form'};
8207        var inputs = getFormInputs(form);
8208        for (var i = 0; i < inputs.length; i++) {
8209            data[inputs[i].name] = inputs[i].value;
8210        }
8211        return data;
8212    }
8213}
8214
8215
8216/* Ajax Login Form */
8217/* -------------------------------------------------------------------- */
8218
8219function mk_login_form() {
8220
8221    $('form.mk-login-form').each(function () {
8222        var $this = $(this);
8223        $this.on('submit', function (e) {
8224            $('p.mk-login-status', $this).show().text(ajax_login_object.loadingmessage);
8225            $.ajax({
8226                type: 'POST',
8227                dataType: 'json',
8228                url: ajax_login_object.ajaxurl,
8229                data: {
8230                    'action': 'ajaxlogin',
8231                    'username': $('#username', $this).val(),
8232                    'password': $('#password', $this).val(),
8233                    'security': $('#security', $this).val()
8234                },
8235                success: function (data) {
8236                    $('p.mk-login-status', $this).text(data.message);
8237                    if (data.loggedin === true) {
8238                        document.location.href = ajax_login_object.redirecturl;
8239                    }
8240                }
8241            });
8242            e.preventDefault();
8243        });
8244    });
8245}
8246
8247
8248/* Progress Button */
8249/* -------------------------------------------------------------------- */
8250
8251var progressButton = {
8252    loader: function (form) {
8253        MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function () {
8254            var $form = form,
8255                progressBar = $form.find(".mk-progress-button .mk-progress-inner"),
8256                buttonText = $form.find(".mk-progress-button .mk-progress-button-content"),
8257                progressButton = new TimelineLite();
8258
8259            progressButton
8260                .to(progressBar, 0, {
8261                    width: "100%",
8262                    scaleX: 0,
8263                    scaleY: 1
8264                })
8265                .to(buttonText, .3, {
8266                    y: -5
8267                })
8268                .to(progressBar, 1.5, {
8269                    scaleX: 1,
8270                    ease: Power2.easeInOut
8271                }, "-=.1")
8272                .to(buttonText, .3, {
8273                    y: 0
8274                })
8275                .to(progressBar, .3, {
8276                    scaleY: 0
8277                });
8278        });
8279    },
8280
8281    success: function (form) {
8282        MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function () {
8283            var $form = form,
8284                buttonText = $form.find(".mk-button .mk-progress-button-content, .mk-contact-button .mk-progress-button-content"),
8285                successIcon = $form.find(".mk-progress-button .state-success"),
8286                progressButtonSuccess = new TimelineLite({
8287                    onComplete: hideSuccessMessage
8288                });
8289
8290            progressButtonSuccess
8291                .to(buttonText, .3, {
8292                    paddingRight: 20,
8293                    ease: Power2.easeInOut
8294                }, "+=1")
8295                .to(successIcon, .3, {
8296                    opacity: 1
8297                })
8298                .to(successIcon, 2, {
8299                    opacity: 1
8300                });
8301
8302            function hideSuccessMessage() {
8303                progressButtonSuccess.reverse()
8304            }
8305        });
8306    },
8307
8308    error: function (form) {
8309        MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function () {
8310            var $form = form,
8311                buttonText = $form.find(".mk-button .mk-progress-button-content, .mk-contact-button .mk-progress-button-content"),
8312                errorIcon = $form.find(".mk-progress-button .state-error"),
8313                progressButtonError = new TimelineLite({
8314                    onComplete: hideErrorMessage
8315                });
8316
8317            progressButtonError
8318                .to(buttonText, .3, {
8319                    paddingRight: 20
8320                }, "+=1")
8321                .to(errorIcon, .3, {
8322                    opacity: 1
8323                })
8324                .to(errorIcon, 2, {
8325                    opacity: 1
8326                });
8327
8328            function hideErrorMessage() {
8329                progressButtonError.reverse()
8330            }
8331        });
8332    }
8333};
8334function mk_click_events() {
8335  "use strict";
8336
8337  var eventtype = 'click'; 
8338
8339  $(".mk-header-login, .mk-header-signup, .mk-side-dashboard, .mk-quick-contact-wrapper, .mk-dashboard-trigger, .blog-share-container, .news-share-buttons, .main-nav-side-search, #mk-fullscreen-search-wrapper, #fullscreen-navigation").on(eventtype, function(event) {
8340    if (event.stopPropagation) {
8341      event.stopPropagation();
8342    } else if (window.event) {
8343      window.event.cancelBubble = true;
8344    }
8345  });
8346  $("html").on(eventtype, function() {
8347    $(".mk-login-register, .mk-header-subscribe, #mk-quick-contact, .single-share-buttons, .single-share-box, .blog-social-share, .news-share-buttons, #mk-nav-search-wrapper").fadeOut(300);
8348    $('.mk-quick-contact-link').removeClass('quick-contact-active');
8349    // Removed By Maki for repairing fullnav scroll issue. Hope it odesnt break anything
8350    // $('body').css('overflow', 'visible');
8351  });
8352
8353  $('.mk-fullscreen-search-overlay').on(eventtype,function(){
8354    $(this).removeClass('mk-fullscreen-search-overlay-show');
8355  });
8356
8357  $('.mk-forget-password').on(eventtype, function() {
8358    $('.mk-forget-panel').siblings().hide().end().show();
8359  });
8360
8361  $('.mk-create-account').on(eventtype, function() {
8362    $('#mk-register-panel').siblings().hide().end().show();
8363  });
8364
8365  $('.mk-return-login').on(eventtype, function() {
8366    $('#mk-login-panel').siblings().hide().end().show();
8367  });
8368
8369
8370  $('.mk-quick-contact-link').on(eventtype, function() {
8371    var $this = $(this),
8372        $quickContact = $('#mk-quick-contact');
8373    if (!$this.hasClass('quick-contact-active')) {
8374      $quickContact.addClass('quick-contact-anim').fadeIn(250);
8375      $this.addClass('quick-contact-active');
8376    } else {
8377      $quickContact.removeClass('quick-contact-anim').fadeOut(100);
8378      $this.removeClass('quick-contact-active');
8379    }
8380    return false;
8381  });
8382
8383}
8384
8385function mk_social_share_global() {
8386
8387  "use strict";
8388
8389  var eventtype = 'click';
8390
8391  $('.twitter-share').on(eventtype, function() {
8392    var $this = $(this),
8393        $url = $this.attr('data-url'),
8394        $title = $this.attr('data-title');
8395
8396    window.open('http://twitter.com/intent/tweet?text=' + $title + ' ' + $url, "twitterWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
8397    return false;
8398  });
8399
8400  $('.pinterest-share').on(eventtype, function() {
8401    var $this = $(this),
8402        $url = $this.attr('data-url'),
8403        $title = $this.attr('data-title'),
8404        $image = $this.attr('data-image');
8405    window.open('http://pinterest.com/pin/create/button/?url=' + $url + '&media=' + $image + '&description=' + $title, "twitterWindow", "height=320,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
8406    return false;
8407  });
8408
8409  $('.facebook-share').on(eventtype, function() {
8410    var $url = $(this).attr('data-url');
8411    window.open('https://www.facebook.com/sharer/sharer.php?u=' + $url, "facebookWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
8412    return false;
8413  });
8414
8415  $('.googleplus-share').on(eventtype, function() {
8416    var $url = $(this).attr('data-url');
8417    window.open('https://plus.google.com/share?url=' + $url, "googlePlusWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
8418    return false;
8419  });
8420
8421  $('.linkedin-share').on(eventtype, function() {
8422    var $this = $(this),
8423        $url = $this.attr('data-url'),
8424        $title = $this.attr('data-title'),
8425        $desc = $this.attr('data-desc');
8426    window.open('http://www.linkedin.com/shareArticle?mini=true&url=' + $url + '&title=' + $title + '&summary=' + $desc, "linkedInWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
8427    return false;
8428  });
8429}
8430
8431
8432/* Event Count Down */
8433/* -------------------------------------------------------------------- */
8434
8435function mk_event_countdown() {
8436  if ($.exists('.mk-event-countdown')) {
8437
8438    MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.countdown.js' ], function() {
8439
8440      $('.mk-event-countdown').each(function () {
8441        if (isTest) return;
8442        var $this = $(this),
8443          $date = $this.attr('data-date'),
8444          $offset = $this.attr('data-offset');
8445
8446        $this.downCount({
8447          date: $date,
8448          offset: $offset
8449        });
8450      });
8451      
8452    });
8453  }
8454}
8455/* Flexslider init */
8456/* -------------------------------------------------------------------- */
8457
8458function mk_flexslider_init() {
8459
8460  var $lcd = $('.mk-lcd-slideshow'),
8461      $laptop = $('.mk-laptop-slideshow-shortcode');
8462
8463  if($lcd.length) $lcd.find('.mk-lcd-image').fadeIn();
8464  if($laptop.length) $laptop.find(".mk-laptop-image").fadeIn();
8465
8466  $('.js-flexslider').each(function () {
8467
8468    if ($(this).parents('.mk-tabs').length || $(this).parents('.mk-accordion').length) {
8469      $(this).removeData("flexslider");
8470    }
8471
8472    var $this = $(this),
8473      $selector = $this.attr('data-selector'),
8474      $animation = $this.attr('data-animation'),
8475      $easing = $this.attr('data-easing'),
8476      $direction = $this.attr('data-direction'),
8477      $smoothHeight = $this.attr('data-smoothHeight') == "true" ? true : false,
8478      $slideshowSpeed = $this.attr('data-slideshowSpeed'),
8479      $animationSpeed = $this.attr('data-animationSpeed'),
8480      $controlNav = $this.attr('data-controlNav') == "true" ? true : false,
8481      $directionNav = $this.attr('data-directionNav') == "true" ? true : false,
8482      $pauseOnHover = $this.attr('data-pauseOnHover') == "true" ? true : false,
8483      $isCarousel = $this.attr('data-isCarousel') == "true" ? true : false;
8484
8485
8486    if ($selector !== undefined) {
8487      var $selector_class = $selector;
8488    } else {
8489      var $selector_class = ".mk-flex-slides > li";
8490    }
8491
8492    if ($isCarousel === true) {
8493      var $itemWidth = parseInt($this.attr('data-itemWidth')),
8494        $itemMargin = parseInt($this.attr('data-itemMargin')),
8495        $minItems = parseInt($this.attr('data-minItems')),
8496        $maxItems = parseInt($this.attr('data-maxItems')),
8497        $move = parseInt($this.attr('data-move'));
8498    } else {
8499      var $itemWidth = $itemMargin = $minItems = $maxItems = $move = 0;
8500    }
8501
8502    MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.flexslider.js' ], function() {
8503      $this.flexslider({
8504        selector: $selector_class,
8505        animation: $animation,
8506        easing: $easing,
8507        direction: $direction,
8508        smoothHeight: $smoothHeight,
8509        slideshow: !isTest, // autoplay
8510        slideshowSpeed: $slideshowSpeed,
8511        animationSpeed: $animationSpeed,
8512        controlNav: $controlNav,
8513        directionNav: $directionNav,
8514        pauseOnHover: $pauseOnHover,
8515        prevText: "",
8516        nextText: "",
8517        itemWidth: $itemWidth,
8518        itemMargin: $itemMargin,
8519        minItems: $minItems,
8520        maxItems: $maxItems,
8521        move: $move
8522      });
8523    });
8524
8525  });
8526
8527}
8528
8529/* Header Search Form */
8530/* -------------------------------------------------------------------- */
8531
8532function mk_header_searchform() {
8533
8534  $('.mk-search-trigger').click(function(){
8535    setTimeout(function() {
8536        $('#mk-ajax-search-input').focus();
8537    },500);
8538  });
8539
8540  "use strict";
8541
8542  $('.mk-header-toolbar .mk-header-searchform .text-input').on('focus', function () {
8543
8544    if ($('.mk-header-toolbar .mk-header-searchform .text-input').hasClass('on-close-state')) {
8545      $('.mk-header-toolbar .mk-header-searchform .text-input').removeClass('on-close-state').animate({
8546        'width': '200px'
8547      }, 200);
8548      return false;
8549    }
8550  });
8551
8552  $(".mk-header-toolbar .mk-header-searchform").click(function (event) {
8553    if (event.stopPropagation) {
8554      event.stopPropagation();
8555    } else if (window.event) {
8556      window.event.cancelBubble = true;
8557    }
8558  });
8559
8560
8561  $("html").click(function () {
8562    $(this).find(".mk-header-toolbar .mk-header-searchform .text-input").addClass('on-close-state').animate({
8563      'width': 90
8564    }, 300);
8565  });
8566
8567  // Fix search for edge browser
8568  if(MK.utils.browser.name === 'Edge') {
8569    $('#mk-fullscreen-search-input').on('keydown', function(e) {
8570      if (e.which == 13) {
8571        e.preventDefault();
8572        $('#mk-fullscreen-searchform').submit();
8573      }
8574    });
8575  }
8576 
8577}
8578
8579
8580
8581
8582/* Hover Events */
8583/* -------------------------------------------------------------------- */
8584
8585function mk_hover_events() {
8586
8587  "use strict";
8588
8589  $('.shopping-cart-header').hover(
8590    function() {
8591      $(this).find('.mk-shopping-cart-box').stop(true, true).fadeIn(250);
8592    },
8593    function() {
8594      $(this).find('.mk-shopping-cart-box').stop(true, true).fadeOut(250);
8595    }
8596  );
8597
8598
8599  $('.widget-sub-navigation > ul > li, .widget_nav_menu ul.menu > li, .widget_product_categories ul > .cat-item').each(function() {
8600
8601    var $this = $(this),
8602        $subLevel = $this.find('ul').first();
8603
8604    if ($this.hasClass('page_item_has_children') || $this.hasClass('menu-item-has-children') || $this.hasClass('cat-parent')) {
8605      $this.on('click', function() {
8606        if($this.hasClass('toggle-active')) {
8607            $subLevel.stop(true, true).slideUp(700);  
8608            $this.removeClass('toggle-active');
8609        } else {
8610            $subLevel.stop(true, true).slideDown(700);
8611            $this.addClass('toggle-active');
8612        }
8613      });
8614
8615      $subLevel.on('click', function(e){
8616        e.stopPropagation();
8617      });
8618    }
8619
8620  });  
8621
8622  // var eventtype = mobilecheck() ? 'touchstart' : 'click';
8623  var eventtype = 'click';
8624  
8625  $('.mk-fullscreen-trigger').on(eventtype, function(e) {
8626    $('.mk-fullscreen-search-overlay').addClass('mk-fullscreen-search-overlay-show');
8627    setTimeout(function(){
8628      $("#mk-fullscreen-search-input").focus();
8629    }, 300);
8630    e.preventDefault();
8631  });
8632
8633  $('.mk-fullscreen-close').on(eventtype, function(e) {
8634    $('.mk-fullscreen-search-overlay').removeClass('mk-fullscreen-search-overlay-show');
8635    e.preventDefault();
8636  });
8637
8638}
8639
8640function mk_unfold_footer() {
8641  var $this = $('#mk-footer'),
8642      $spacer = $('#mk-footer-unfold-spacer'),
8643      $footerHeight = $this.outerHeight();
8644
8645  // Stick with CSS media query breakpoint to target exact screen width
8646  if( !window.matchMedia("(max-width: 767px)").matches ) {
8647      if ($this.hasClass('mk-footer-unfold')) {
8648        $spacer.css('height', $footerHeight);
8649      }
8650  } else {
8651     $spacer.css('height', 0);
8652  }
8653}
8654/* jQuery fancybox lightbox */
8655/* -------------------------------------------------------------------- */
8656function mk_lightbox_init() {
8657
8658var $lightbox = $(".mk-lightbox");
8659
8660  $lightbox.fancybox({
8661            padding: 15,
8662            margin: 15, 
8663
8664            width: 800,
8665            height: 600,
8666            minWidth: 100,
8667            minHeight: 100,
8668            maxWidth: 9999,
8669            maxHeight: 9999,
8670            pixelRatio: 1, // Set to 2 for retina display support
8671
8672            autoSize: true,
8673            autoHeight: false,
8674            autoWidth: false,
8675
8676            autoResize: true,
8677            fitToView: true,
8678            aspectRatio: false,
8679            topRatio: 0.5,
8680            leftRatio: 0.5,
8681
8682            scrolling: 'auto', // 'auto', 'yes' or 'no'
8683            wrapCSS: '',
8684
8685            arrows: true,
8686            closeBtn: true,
8687            closeClick: false,
8688            nextClick: false,
8689            mouseWheel: true,
8690            autoPlay: false,
8691            playSpeed: 3000,
8692            preload: 3,
8693            modal: false,
8694            loop: true,
8695            // Properties for each animation type
8696            // Opening fancyBox
8697            openEffect: 'fade', // 'elastic', 'fade' or 'none'
8698            openSpeed: 200,
8699            openEasing: 'swing',
8700            openOpacity: true,
8701            openMethod: 'zoomIn',
8702
8703            // Closing fancyBox
8704            closeEffect: 'fade', // 'elastic', 'fade' or 'none'
8705            closeSpeed: 200,
8706            closeEasing: 'swing',
8707            closeOpacity: true,
8708            closeMethod: 'zoomOut',
8709
8710            // Changing next gallery item
8711            nextEffect: 'none', // 'elastic', 'fade' or 'none'
8712            nextSpeed: 350,
8713            nextEasing: 'swing',
8714            nextMethod: 'changeIn',
8715
8716            // Changing previous gallery item
8717            prevEffect: 'none', // 'elastic', 'fade' or 'none'
8718            prevSpeed: 350,
8719            prevEasing: 'swing',
8720            prevMethod: 'changeOut',
8721            helpers : {
8722                media : {},
8723                overlay: {
8724                  locked: true 
8725                }
8726            },
8727
8728            tpl: {
8729                wrap: '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',
8730                image: '<img class="fancybox-image" src="{href}" alt="" />',
8731                error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
8732                closeBtn: '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"><i><svg class="mk-svg-icon" svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M390.628 345.372l-45.256 45.256-89.372-89.373-89.373 89.372-45.255-45.255 89.373-89.372-89.372-89.373 45.254-45.254 89.373 89.372 89.372-89.373 45.256 45.255-89.373 89.373 89.373 89.372z"/></svg></i></a>',
8733                next: '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span><i><svg class="mk-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M144 505.6c8 0 16-3.2 22.4-8l240-225.6c6.4-6.4 9.6-14.4 9.6-22.4s-3.2-16-9.6-22.4l-240-224c-12.8-12.8-32-12.8-44.8 0s-11.2 32 1.6 44.8l214.4 201.6-216 203.2c-12.8 11.2-12.8 32 0 44.8 6.4 4.8 14.4 8 22.4 8z"/></svg></i></span></a>',
8734                prev: '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span><i><svg class="mk-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M368 505.6c-8 0-16-3.2-22.4-8l-240-225.6c-6.4-6.4-9.6-14.4-9.6-24 0-8 3.2-16 9.6-22.4l240-224c12.8-11.2 33.6-11.2 44.8 1.6 12.8 12.8 11.2 32-1.6 44.8l-214.4 201.6 216 203.2c12.8 11.2 12.8 32 0 44.8-4.8 4.8-14.4 8-22.4 8z"/></svg></i></span></a>',
8735                loading: '<div id="fancybox-loading"><div></div></div>'
8736            },
8737
8738            afterLoad: function() {
8739                $('html').addClass('fancybox-lock');
8740                $('.fancybox-wrap').appendTo('.fancybox-overlay');
8741            },
8742            beforeShow: function(){
8743                this.locked = true;
8744            },
8745            afterClose: function() {
8746                // Only for gallery shortcode.
8747                var galleryParent = this.element.parents( '.mk-gallery-item' );
8748
8749                if ( galleryParent ) {
8750                    galleryParent.removeClass('hover-state');
8751                }
8752            }
8753
8754        });
8755}
8756
8757
8758/* Love This */
8759/* -------------------------------------------------------------------- */
8760
8761function mk_love_post() {
8762
8763  "use strict";
8764
8765  $('body').on('click', '.mk-love-this', function () {
8766    var $this = $(this),
8767      $id = $this.attr('id');
8768
8769    if ($this.hasClass('item-loved')) return false;
8770
8771    if ($this.hasClass('item-inactive')) return false;
8772
8773    var $sentdata = {
8774      action: 'mk_love_post',
8775      post_id: $id
8776    }
8777
8778    $.post(ajaxurl, $sentdata, function (data) {
8779      $this.find('.mk-love-count').html(data);
8780      $this.addClass('item-loved');
8781    });
8782
8783    $this.addClass('item-inactive');
8784    return false;
8785  });
8786
8787}
8788
8789
8790
8791
8792/* Milestone Number Shortcode */
8793/* -------------------------------------------------------------------- */
8794
8795function mk_milestone() {
8796
8797  "use strict";
8798
8799  if( isTest || !$.exists('.mk-milestone') ) return;
8800
8801  $('.mk-milestone').each(function () {
8802    var $this = $(this),
8803      stop_number = $this.find('.milestone-number').attr('data-stop'),
8804      animation_speed = parseInt($this.find('.milestone-number').attr('data-speed'));
8805
8806    var build = function() {
8807      if (!$this.hasClass('scroll-animated')) {
8808        $this.addClass('scroll-animated');
8809
8810        $({
8811          countNum: $this.find('.milestone-number').text()
8812        }).animate({
8813          countNum: stop_number
8814        }, {
8815          duration: animation_speed,
8816          easing: 'linear',
8817          step: function () {
8818            $this.find('.milestone-number').text(Math.floor(this.countNum));
8819          },
8820          complete: function () {
8821            $this.find('.milestone-number').text(this.countNum);
8822          }
8823        });
8824      }
8825    };
8826
8827    if ( !MK.utils.isMobile() ) {
8828      // refactored only :in-viewport logic. rest is to-do
8829      MK.utils.scrollSpy( this, {
8830          position: 'bottom',
8831          after: build
8832      });
8833    } else {
8834      build();
8835    }
8836
8837  });
8838
8839}
8840
8841
8842
8843
8844/* Recent Works Widget */
8845/* -------------------------------------------------------------------- */
8846
8847function mk_portfolio_widget() {
8848
8849  "use strict";
8850
8851  $('.widget_recent_portfolio li').each(function () {
8852
8853    $(this).find('.portfolio-widget-thumb').hover(function () {
8854
8855      $(this).siblings('.portfolio-widget-info').animate({
8856        'opacity': 1
8857      }, 200);
8858    }, function () {
8859
8860      $(this).siblings('.portfolio-widget-info').animate({
8861        'opacity': 0
8862      }, 200);
8863    });
8864
8865  });
8866}
8867
8868
8869
8870/* Skill Meter and Charts */
8871/* -------------------------------------------------------------------- */
8872function mk_skill_meter() {
8873    "use strict";
8874    if ($.exists('.mk-skill-meter')) {
8875        if (!MK.utils.isMobile()) {
8876            $(".mk-skill-meter .progress-outer").each(function() {
8877                var $this = $(this);
8878
8879                var build = function() {
8880                    if (!$this.hasClass('scroll-animated')) {
8881                        $this.addClass('scroll-animated');
8882                        $this.animate({
8883                            width: $this.attr("data-width") + '%'
8884                        }, 2000);
8885                    }
8886                };
8887
8888                MK.utils.scrollSpy( this, {
8889                    position: 'bottom',
8890                    after: build
8891                });
8892            });
8893        } else {
8894            $(".mk-skill-meter .progress-outer").each(function() {
8895                var $this = $(this);
8896                if (!$this.hasClass('scroll-animated')) {
8897                    $this.addClass('scroll-animated');
8898                    $this.css({
8899                        width: $(this).attr("data-width") + '%'
8900                    });
8901                }
8902            });
8903        }
8904    }
8905}
8906
8907// function mk_charts() {
8908//     "use strict";
8909
8910//     if( !$.exists('.mk-chart') ) return;
8911
8912//     MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.easyPieChart.js' ], function() {
8913
8914//         $('.mk-chart').each(function() {
8915
8916//             var $this = $(this),
8917//                 $parent_width = $(this).parent().width(),
8918//                 $chart_size = parseInt($this.attr('data-barSize'));
8919
8920//             if ($parent_width < $chart_size) {
8921//                 $chart_size = $parent_width;
8922//                 $this.css('line-height', $chart_size);
8923//                 $this.find('i').css({
8924//                     'line-height': $chart_size + 'px'
8925//                 });
8926//                 $this.css({
8927//                     'line-height': $chart_size + 'px'
8928//                 });
8929//             }
8930
8931//             var build = function() {
8932//                 $this.easyPieChart({
8933//                     animate: 1300,
8934//                     lineCap: 'butt',
8935//                     lineWidth: $this.attr('data-lineWidth'),
8936//                     size: $chart_size,
8937//                     barColor: $this.attr('data-barColor'),
8938//                     trackColor: $this.attr('data-trackColor'),
8939//                     scaleColor: 'transparent',
8940//                     onStep: function(value) {
8941//                         this.$el.find('.chart-percent span').text(Math.ceil(value));
8942//                     }
8943//                 });
8944//             };
8945
8946//             // refactored only :in-viewport logic. rest is to-do
8947//             MK.utils.scrollSpy( this, {
8948//                 position: 'bottom',
8949//                 after: build
8950//             });
8951
8952
8953//         });
8954//     });
8955// }
8956/* Toolbar subscribe form */
8957/* -------------------------------------------------------------------- */
8958
8959$( "#mc-embedded-subscribe-form" ).submit(function( e ){
8960    var $this = $(this);
8961  
8962    e.preventDefault();
8963    $.ajax({
8964        url: MK.core.path.ajaxUrl,
8965        type: "POST",
8966        data: {
8967            action: "mk_ajax_subscribe",
8968            email: $this.find( ".mk-subscribe--email" ).val(),
8969            list_id: $this.find( ".mk-subscribe--list-id" ).val(),
8970            optin: $this.find( ".mk-subscribe--optin" ).val()
8971        },
8972        success: function ( res ) {
8973            $this.parent().find( ".mk-subscribe--message" ).html( $.parseJSON( res ).message );
8974        }
8975    });
8976});
8977/**
8978 * Add class to tag. It's vanilla js instead of jQuery.
8979 * @param tag
8980 * @param className
8981 */
8982function addClass(tag, className) {
8983    tag.className += ' ' + className;
8984}
8985
8986/**
8987 * Remove class from tag. It's vanilla js instead of jQuery.
8988 * Replacing should be with g for replacing all occurrence.
8989 *
8990 * @param tag
8991 * @param className
8992 */
8993function removeClass(tag, className) {
8994    tag.className = tag.className.replace(new RegExp(className, 'g'), '');
8995}
8996
8997
8998/**
8999 * If we're running under Node for testing purpose.
9000 */
9001if(typeof exports !== 'undefined') {
9002    exports.addClass = addClass;
9003    exports.removeClass = removeClass;
9004}
9005
9006/*!
9007*  javascript-debounce 1.0.0
9008*
9009*  A lightweight, dependency-free JavaScript module for debouncing functions based on David Walsh's debounce function.
9010*
9011*  Source code available at: https://github.com/jgarber623/javascript-debounce
9012*
9013*  (c) 2015-present Jason Garber (http://sixtwothree.org)
9014*
9015*  javascript-debounce may be freely distributed under the MIT license.
9016*/
9017
9018(function(root, factory) {
9019	if (typeof define === "function" && define.amd) {
9020		define([], factory);
9021	} else if (typeof exports === "object") {
9022		module.exports = factory();
9023	} else {
9024		root.debounce = factory();
9025	}
9026})(this, function() {
9027	"use strict";
9028	return function(callback, delay) {
9029		var timeout;
9030		return function() {
9031			var context = this, args = arguments;
9032			clearTimeout(timeout);
9033			timeout = setTimeout(function() {
9034				callback.apply(context, args);
9035			}, delay);
9036		};
9037	};
9038});
9039
9040/**
9041 * Validate email address.
9042 *
9043 * @param input
9044 * @param invalidClassName
9045 * @returns boolean
9046 */
9047function validateEmail(input, invalidClassName) {
9048    var value = input.value.trim();
9049    if ((input.required || value.length > 0) && !/^([a-z0-9_\.\-\+]+)@([\da-z\.\-]+)\.([a-z\.]{2,63})$/i.test(value)) {
9050        if (invalidClassName) {
9051            addClass(input, invalidClassName);
9052        }
9053        return false;
9054    } else {
9055        if (invalidClassName) {
9056            removeClass(input, invalidClassName);
9057        }
9058        return true;
9059    }
9060}
9061
9062/**
9063 * Validate text entry.
9064 *
9065 * @param input
9066 * @param invalidClassName
9067 * @returns boolean
9068 */
9069function validateText(input, invalidClassName) {
9070    var value = input.value.trim();
9071
9072    if (input.required && value.length === 0) {
9073        if (invalidClassName) {
9074            addClass(input, invalidClassName);
9075        }
9076        return false;
9077    } else {
9078        if (invalidClassName) {
9079            removeClass(input, invalidClassName);
9080        }
9081        return true;
9082    }
9083}
9084
9085
9086/**
9087 * If we're running under Node for testing purpose.
9088 */
9089if(typeof exports !== 'undefined') {
9090    exports.validateEmail = validateEmail;
9091    exports.validateText = validateText;
9092}
9093(function( $ ) {
9094	'use strict';
9095
9096    var $wrapper = $('.js-bottom-corner-btns');
9097    var $contactBtn = $wrapper.find('.js-bottom-corner-btn--contact');
9098    var $backBtn = $wrapper.find('.js-bottom-corner-btn--back');
9099    var hasContactBtn = $contactBtn.length;
9100    var hasBackBtn = $backBtn.length;
9101
9102    if(!hasBackBtn) return;
9103
9104    function deactivate() {
9105        $contactBtn.removeClass('is-active');
9106        $backBtn.removeClass('is-active');
9107    }
9108
9109    function activate() { 
9110        $contactBtn.addClass('is-active');
9111        $backBtn.addClass('is-active');
9112    }
9113
9114    MK.utils.scrollSpy( 400, {
9115        before: deactivate,
9116        after: activate
9117    });
9118
9119})( jQuery );
9120(function( $ ) {
9121	'use strict';
9122
9123	MK.ui.preloader = {
9124		dom : {
9125			overlay: '.mk-body-loader-overlay'
9126		},
9127
9128		hide : function hide() {
9129			$( this.dom.overlay ).fadeOut(600, "easeInOutExpo", function() {
9130				$('body').removeClass('loading');
9131            //$( this ).remove();
9132         });
9133		}
9134	};  
9135
9136})( jQuery ); 
9137(function($) {
9138	'use strict';
9139	
9140	$('.mk-fullscreen-nav-close, .mk-fullscreen-nav-wrapper, #fullscreen-navigation a').on('click', function(e) {
9141		
9142		// Close nav with removing classes
9143		$('.mk-fullscreen-nav').removeClass('opened');
9144		$('.mk-dashboard-trigger').removeClass('fullscreen-active');
9145		$('body').removeClass('fullscreen-nav-opened'); 
9146		
9147		var anchor = MK.utils.detectAnchor( this ),
9148		$this = $( this );
9149		
9150		// Scroll to anchor if exists
9151		if( anchor.length ) {
9152			// Moved 4 these lines after anchor check because console error. If anchor
9153			// return false, split part will throw an error because $this is not a link.
9154			// Fix AM-2027
9155			var href = $this.attr( 'href' ).split( '#' )[0];
9156			var url = window.location.href;
9157			var isSamePage = url.indexOf( href ) !== -1;
9158
9159			if ( isSamePage ) {
9160				e.preventDefault();
9161			}
9162			MK.utils.scrollToAnchor( anchor );
9163			
9164		// Or do nothing if pointless # as href
9165		// BAD  PRACTICE: it is very popular to use "#" for click elements that we listen to with js.
9166		// GOOD PRACTICE: prefer "javascript:;" as easier to handle and more readable version
9167		} else if( $this.attr( 'href' ) === '#' ) {
9168			e.preventDefault();
9169		}
9170	});
9171	
9172	$('.fullscreen-navigation-ul .menu-sub-level-arrow').on('click', function(){
9173		$(this).siblings('.sub-menu').slideToggle();
9174	});
9175	
9176}(jQuery));
9177(function($) {
9178	'use strict';
9179
9180	/**
9181     * Mega menu
9182     */
9183    var $navList = $(".main-navigation-ul");
9184    var megaMenu = function megaMenu() {
9185
9186        $navList.MegaMenu({
9187            type: "vertical",
9188            delay: 200
9189        });
9190    };
9191
9192    $(window).on('load', megaMenu);
9193
9194}(jQuery));
9195(function($) {
9196	'use strict';
9197
9198	/**
9199     * One pager menu hash update. 
9200     * Smooth scroll is appended globally whenever the click element has corresponding #el
9201     */    
9202    var onePageNavItem = function onePageNavItem() {
9203        var $this = $( this ),
9204            link = $this.find( 'a' ),
9205            anchor = MK.utils.detectAnchor( link ); // anchor on current page
9206
9207        if( !anchor.length ) return;
9208
9209        $this.removeClass( 'current-menu-item current-menu-ancestor current-menu-parent' );
9210
9211        var activeNav = function( state ) {
9212            return function() {
9213                $this[ state ? 'addClass' : 'removeClass' ]( 'current-menu-item' );
9214                window.history.replaceState( undefined, undefined, [ state ? anchor : ' ' ] );
9215            };
9216        };
9217
9218        MK.utils.scrollSpy( $( anchor )[0], {
9219            before : activeNav( false ),
9220            active : activeNav( true ),
9221            after  : activeNav( false ),
9222        });
9223    };
9224
9225    var $navItems = $('.js-main-nav').find( 'li' );
9226    
9227    $(window).on('load', function() {
9228        // Wait with spying anchors so we do not assign anchor that is browser scroll to after page load
9229        // Especially when there are anchors on top - refreshing page can cause grabbing one of them into url
9230        // and force unwanted scroll
9231        setTimeout(function() {
9232            $navItems.each( onePageNavItem );
9233        }, 1000);
9234    });
9235	
9236}(jQuery));
9237(function($) {
9238    'use strict';
9239
9240    var $window = $(window);
9241    var $body = $('body');
9242    var $resMenuWrap = $('.mk-responsive-wrap');
9243    var $post_nav = $('.mk-post-nav');
9244    var $toolbar = $('.mk-header-toolbar');
9245    var $resMenuLink = $('.mk-nav-responsive-link');
9246
9247    // Flags
9248    var hasResMenu = ($resMenuWrap.length > 0);
9249
9250    //initial window and screen height
9251    var windowHeight = $window.height();
9252    var screenHeight = screen.height;
9253
9254    // We keep this handler above hasResMenu flag.
9255    // Even if our header doesn't contain droppable responsive menu (in favor of fullscreen or side menu) 
9256    // we still transform tollbar into collapsible menu part in responsive state
9257    $('.mk-toolbar-resposnive-icon').on('click', function(e) {
9258        e.preventDefault();
9259        console.log('clicked');
9260        if ($body.hasClass('toolbar-opened')) {
9261            $body.removeClass('toolbar-opened').addClass('toolbar-closed');
9262            $toolbar.hide();
9263        } else {
9264            $body.removeClass('toolbar-closed').addClass('toolbar-opened');
9265            $toolbar.show();
9266        }
9267    });
9268
9269
9270    if ( ! hasResMenu && ! $('.vc_mk_header') ) return;
9271
9272    function toggleResMenu(e) {
9273        e.preventDefault();
9274        var $this = $(this);
9275        var $headerInner = $this.parents('header');
9276        var $resMenu = $headerInner.find('.mk-responsive-wrap');
9277        var searchBox = $('.responsive-searchform .text-input');
9278        var adminBarHeight = $('#wpadminbar').height(); /* Fix AM-1918 */
9279
9280        if ($body.hasClass('mk-opened-nav')) {
9281            $this.removeClass('is-active');
9282            $body.removeClass('mk-opened-nav').addClass('mk-closed-nav').trigger('mk-closed-nav');
9283            $resMenu.hide();
9284            $post_nav.removeClass('post-nav-backward');
9285        } else {
9286            $this.addClass('is-active');
9287            $body.removeClass('mk-closed-nav').addClass('mk-opened-nav').trigger('mk-opened-nav');
9288            $resMenu.show();
9289            $post_nav.addClass('post-nav-backward');
9290
9291        }
9292
9293        //for iPhone 5 focus bug , remove search box focused class
9294        if(searchBox.hasClass('input-focused')){
9295            searchBox.removeClass('input-focused');
9296        }
9297        
9298    }
9299
9300    $resMenuLink.each(function() {
9301        $(this).on('click', toggleResMenu);
9302    });
9303
9304    $( window ).on( 'vc_reload', function () {
9305        $('.vc_mk_header .mk-nav-responsive-link').each(function() {
9306            $(this).on('click', toggleResMenu);
9307        });
9308    } )
9309
9310    var setResMenuHeight = function() {
9311        var height = $window.height() - MK.val.offsetHeaderHeight(0);
9312        $resMenuWrap.css('max-height', height);
9313    };
9314
9315    // check if device virtual keyboard is active 
9316    var isVirtualKeyboard = function() {
9317        var currentWindowHeight = $window.height();
9318        var currentScreenHeight = screen.height;
9319        var searchBox = $('.responsive-searchform .text-input');
9320        var searchBoxIsFocused = false; 
9321
9322        //for iPhone 5 focus bug , add class for detect focus state
9323        searchBox.on('touchstart touchend', function(e) {
9324            searchBox.addClass('input-focused');
9325        });
9326
9327        searchBoxIsFocused = (searchBox.is(':focus') || searchBox.hasClass("input-focused"));
9328
9329        if ($body.hasClass('mk-opened-nav') && searchBoxIsFocused && currentScreenHeight == screenHeight && currentWindowHeight != windowHeight) {
9330            return true;
9331        } else {
9332            return false;
9333        }
9334    };
9335
9336    var hideResMenu = function hideResMenu() {
9337        if (MK.utils.isResponsiveMenuState()) {
9338
9339            //when search box in responsive menu is focused , window resize fired but at this time responsive menu should be open
9340            if (!isVirtualKeyboard()) {
9341                // hide toggled menu and its states
9342                if ($body.hasClass('mk-opened-nav')) {
9343                    $resMenuLink.filter('.is-active').trigger('click');
9344                }
9345                // hide menu wrapper
9346                $resMenuWrap.hide();
9347
9348            }
9349        }
9350    };
9351
9352    $resMenuWrap.on('click', 'a', hideResMenu);
9353
9354}(jQuery));
9355
9356(function($) {
9357    'use strict';
9358
9359    var $header = $('.mk-header');    
9360    var hasHeader = ($header.length > 0);
9361
9362    if(!hasHeader && ! $('.vc_mk_header') ) return;
9363    
9364    var $sticky_style = $header.attr('data-header-style');
9365
9366    //if ($sticky_style !== 3) return;
9367
9368    $('.sidedash-navigation-ul > li').each(function() {
9369        var $this = $(this);
9370
9371        $this.children('ul').siblings('a').after('<span class="mk-nav-arrow mk-nav-sub-closed"><svg class="mk-svg-icon" data-name="mk-moon-arrow-down" data-cacheid="2" style=" height:14px; width: 14px; " xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M512 192l-96-96-160 160-160-160-96 96 256 255.999z"></path></svg></span>');
9372    });
9373
9374    function toggleSubMenu(e) {
9375        e.preventDefault();
9376        var $this = $(this);
9377        
9378        if ($this.hasClass('mk-nav-sub-closed')) {
9379            $this.siblings('ul').slideDown(450).end().removeClass('mk-nav-sub-closed').addClass('mk-nav-sub-opened');
9380        } else {
9381            $this.siblings('ul').slideUp(450).end().removeClass('mk-nav-sub-opened').addClass('mk-nav-sub-closed');
9382        }
9383    };
9384
9385    function toggleFullMenu(e) {
9386        e.preventDefault();
9387        var $this = $(this),
9388            $body = $('body'),
9389            $fullscreen_box = $('.mk-fullscreen-nav');
9390
9391        if ($this.hasClass('dashboard-style')){
9392          if (!$this.hasClass('dashboard-active')) {
9393            $this.addClass('dashboard-active');
9394            $body.addClass('dashboard-opened');
9395          } else {
9396            $this.removeClass('dashboard-active'); 
9397            $body.removeClass('dashboard-opened');
9398          }
9399        }else if($this.hasClass('fullscreen-style')){
9400          if (!$this.hasClass('fullscreen-active')) {
9401            $this.addClass('fullscreen-active');
9402            $body.addClass('fullscreen-nav-opened');
9403            $fullscreen_box.addClass('opened');
9404            // MK.utils.scroll.disable();
9405          } else {
9406            $this.removeClass('fullscreen-active');
9407            $body.removeClass('fullscreen-nav-opened');
9408            $fullscreen_box.removeClass('opened');
9409          }
9410        }
9411    }
9412
9413    $('.mk-nav-arrow').each(function() {
9414        $(this).stop(true).on('click', toggleSubMenu);
9415    });
9416
9417    $('.mk-dashboard-trigger').each(function() {
9418        $(this).on('click', toggleFullMenu);
9419    });
9420
9421    $( window ).on( 'vc_reload', function () {
9422        $('.vc_mk_header .mk-dashboard-trigger').each(function() {
9423            $(this).on('click', toggleFullMenu);
9424        });
9425
9426        $('.vc_mk_header .mk-nav-arrow').each(function() {
9427            $(this).stop(true).on('click', toggleSubMenu);
9428       });
9429    } );
9430
9431    $('html').on('click', function() {
9432        $('body').removeClass('dashboard-opened');
9433        $('.mk-dashboard-trigger').removeClass('dashboard-active');
9434    });
9435
9436}(jQuery));
9437
9438(function($) {
9439	'use strict';
9440
9441    /**
9442     * Vertical menu
9443     */
9444    var $verticalMenu = $('#mk-vm-menu');
9445    var verticalMenu = function verticalMenu() {
9446        if(!$verticalMenu.data('vertical-menu') && !MK.utils.isResponsiveMenuState()) {
9447            $verticalMenu.dlmenu();
9448            $verticalMenu.data('vertical-menu', true);
9449        }
9450    };
9451
9452    verticalMenu();
9453    $(window).on('resize', verticalMenu);
9454	
9455}(jQuery));
9456(function($) {
9457    'use strict';
9458
9459    // WPML
9460    var $lang_item = $('.mk-main-navigation > .main-navigation-ul > .menu-item-language');
9461    $lang_item.addClass('no-mega-menu').css('visibility', 'visible');
9462    $('.mk-main-navigation .menu-item-language > a').addClass('menu-item-link');
9463
9464})(jQuery);
9465(function($) {
9466	'use strict';
9467
9468    var $header = $( '.mk-header' ).first(); // Theme header is always first, do not apply to shortcode headers.
9469    var hasHeader = ($header.length > 0);
9470
9471    if(!hasHeader) return;
9472
9473    var $window = $( window );
9474    var $document = $( document );
9475    var $headerHolder = $header.find( '.mk-header-holder' );
9476    var $paddingWrapper = $header.find('.mk-header-padding-wrapper');
9477    var config = $header.data();
9478
9479    /**
9480     * Flags
9481     * @type {Boolean}
9482     */
9483    var isStickyLazy = (config.stickyStyle === 'lazy');
9484    var isStickyFixed = (config.stickyStyle === 'fixed');
9485    var isStickySlide = (config.stickyStyle === 'slide');
9486
9487    function isSticky() { // Check for sticky compatibility
9488        //return config.headerStyle !== 4; header style 4 needs sticky state for transparent header.
9489        return true;
9490    }
9491
9492    function isColorable() { // Check for coloring compatibility
9493        // TODO make it explicit in DOM that header is transparent as this is only scenario for colorable header
9494        // Monkey patch - exclude header styles that don't fit colorable
9495        return config.headerStyle !== 4;
9496    }
9497
9498
9499    /**
9500     * Change header skin
9501     */
9502	function changeSkin( e, skin ) {
9503		$header.attr( 'data-transparent-skin', skin );
9504        // Fix for class based skining
9505        var contrast = skin === 'light' ? 'dark' : 'light';
9506        $header.addClass(skin + '-skin');
9507        $header.removeClass(contrast + '-skin');
9508	}
9509
9510    if(isColorable()) MK.utils.eventManager.subscribe( 'firstElSkinChange', changeSkin );
9511
9512
9513    // Assign sticky scenarions
9514    if (isSticky() && isStickyLazy) {
9515      if(config.headerStyle !== 2) {
9516        lazySticky();
9517      }
9518    }
9519    else if (isSticky() && isStickyFixed) fixedSticky();
9520    else if (isSticky() && isStickySlide) slideSticky();
9521
9522    /**
9523     * Sticky header behavior: Lazy
9524     */
9525    function lazySticky() {
9526        var elClassHidden = 'header--hidden';
9527        var elClassSticky = 'a-sticky';
9528        var wScrollCurrent = 0;
9529        var wScrollBefore = 0;
9530        var wScrollDiff = 0;
9531        var wHeight = 0;
9532        var dHeight = 0;
9533
9534        var setSizes = function setSizes() {
9535            dHeight = $document.height();
9536            wHeight = $window.height();
9537        };
9538
9539        var onScroll = function onScroll() {
9540            wScrollCurrent = MK.val.scroll();
9541            wScrollDiff = wScrollBefore - wScrollCurrent;
9542
9543            if( wScrollCurrent <= 0 ) { // scrolled to the very top; element sticks to the top
9544                $headerHolder.removeClass( elClassHidden );
9545                $header.removeClass( elClassSticky );
9546                $('body').trigger('mk:header-unsticky');
9547
9548            } else if( wScrollDiff > 0 && $headerHolder.hasClass( elClassHidden ) ) { // scrolled up; element slides in
9549                $headerHolder.removeClass( elClassHidden );
9550                $header.addClass( elClassSticky );
9551                $('body').trigger('mk:header-sticky');
9552
9553            } else if( wScrollDiff < 0 ) { // scrolled down
9554
9555                if( wScrollCurrent + wHeight >= dHeight && $headerHolder.hasClass( elClassHidden ) ) { // scrolled to the very bottom; element slides in
9556                    $headerHolder.removeClass( elClassHidden );
9557                    $header.addClass( elClassSticky );
9558                    $('body').trigger('mk:header-sticky');
9559                } else { // scrolled down; element slides out
9560                    $headerHolder.addClass( elClassHidden );
9561                    $header.removeClass( elClassSticky );
9562                    $('body').trigger('mk:header-unsticky');
9563                }
9564            }
9565
9566            wScrollBefore = wScrollCurrent;
9567        };
9568
9569        setSizes();
9570        onScroll();
9571        $window.on( 'resize', MK.utils.throttle( 100, setSizes ) );
9572        $window.on( 'scroll', MK.utils.throttle( 500, onScroll ) );
9573    }
9574
9575
9576    /**
9577     * Sticky header behavior: Fixed
9578     */
9579    function fixedSticky() {
9580        var sticked = false;
9581        var scrollPos;
9582
9583        var toggleState = function toggleState() {
9584            scrollPos = MK.val.scroll() + MK.val.adminbarHeight();
9585
9586            if( (scrollPos > MK.val.stickyOffset() ) && ! MK.utils.isResponsiveMenuState() ) {
9587                if(sticked) return; // stop if already sticked
9588                $header.addClass('a-sticky');
9589                sticked = true;
9590                $('body').trigger('mk:header-sticky');
9591            } else {
9592                if(!sticked) return; // stop if already unsticked
9593                $header.removeClass('a-sticky');
9594                sticked = false;
9595                $('body').trigger('mk:header-unsticky');
9596            }
9597        };
9598
9599        toggleState();
9600        $window.on( 'scroll', MK.utils.throttle( 100, toggleState) );
9601        $window.on( 'resize', MK.utils.throttle( 100, toggleState) );
9602    }
9603
9604
9605    /**
9606     * Sticky header behavior: Slide
9607     */
9608    function slideSticky() {
9609        var sticked = false;
9610        var onScroll = function onScroll() {
9611            if (MK.val.scroll() > MK.val.stickyOffset()) {
9612                if(sticked) return; // stop if already sticked
9613                $header.addClass('pre-sticky');
9614                $paddingWrapper.addClass('enable-padding');
9615                setTimeout(function() {
9616                    $header.addClass('a-sticky');
9617                    $('body').trigger('mk:header-sticky');
9618                }, 1);
9619                sticked = true;
9620            } else {
9621                if(!sticked) return; // stop if already unsticked
9622                $header.removeClass('a-sticky');
9623                $header.removeClass('pre-sticky');
9624                $paddingWrapper.removeClass('enable-padding');
9625                sticked = false;
9626                $('body').trigger('mk:header-unsticky');
9627            }
9628        };
9629
9630        onScroll();
9631        $window.on( 'scroll', MK.utils.throttle( 100, onScroll) );
9632    }
9633
9634    // TODO
9635    // var pageIntro = $('body').data('intro'); // block scrolling on page intro
9636
9637
9638})( jQuery );
9639
9640(function($){
9641	'use strict';
9642
9643	// Do not assign at all if no touch events
9644	var hasTouchscreen = ('ontouchstart' in document.documentElement);
9645	if(!hasTouchscreen) return;
9646
9647	$('.mk-main-navigation .menu-item-has-children').each( normalizeClick );
9648
9649	function normalizeClick() {
9650		$(this).on('click', handleClick);
9651	}
9652
9653	// Most reasonable way to normalize click and let hover state on first touch yet don't break experience on multiple input devices is to actually check against desired effect.
9654	// Better way would be to check against expected state but JS doesn't detect :hover so it would be nice to have it normalized globally like expecting .hover class in css
9655	function handleClick(e) {
9656		var $this = $(e.currentTarget);
9657		var $child = $this.find('> ul');
9658		var isVisible = $child.css('display') !== 'none';
9659
9660		if(!isVisible) {
9661			e.preventDefault();
9662			e.stopPropagation();
9663		}
9664	}
9665
9666}(jQuery));
9667(function($) {
9668	'use strict';
9669
9670    var _ajaxUrl = MK.core.path.ajaxUrl;
9671    var _instances = {};
9672
9673	MK.utils.ajaxLoader = function ajaxLoader(el) {
9674		// retrun a cached instance to have control over state from within multiple places
9675		// we may need for example to reset pageId when do filtering. It is really one instance that controls both filtering and pagination / load more
9676		var id = '#' + ($(el).attr('id'));
9677		if(typeof _instances[id] !== 'undefined') return _instances[id];
9678
9679		// else lets start new instance
9680		this.id = id;
9681		this.el = el;
9682		this.isLoading = false;
9683		this.xhrCounter = 0;
9684	};
9685
9686	MK.utils.ajaxLoader.prototype = { 
9687		init: function init() {
9688			// prevent double initialization of we return an instance
9689			if ( this.initialized && typeof window.vc_iframe === 'undefined' ) {
9690				return;
9691			}
9692
9693			this.createInstance();
9694			this.cacheElements();
9695
9696			this.initialized = true;
9697		},
9698
9699		cacheElements: function cacheElements() {
9700			this.$container = $(this.el);
9701			this.id = '#' + (this.$container.attr('id'));
9702	        this.categories = this.$container.data('loop-categories');
9703
9704			this.data = {};
9705			this.data.action = 'mk_load_more';
9706	        this.data.query = this.$container.data('query');
9707	        this.data.atts = this.$container.data('loop-atts');
9708	        this.data.loop_iterator = this.$container.data('loop-iterator');
9709	        this.data.author = this.$container.data('loop-author');
9710	        this.data.posts = this.$container.data('loop-posts');
9711	        this.data.safe_load_more = this.$container.siblings('#safe_load_more').val();
9712	        this.data._wp_http_referer = this.$container.siblings('input[name="_wp_http_referer"]').val();
9713	        this.data.paged = 1;
9714	        this.data.maxPages = this.$container.data('max-pages');
9715	        this.data.term = this.categories;
9716		},
9717
9718		createInstance: function() {
9719			_instances[this.id] = this;
9720		},
9721
9722		load: function load(unique) {
9723			var self = this;
9724			var seq = ++this.xhrCounter;
9725            this.isLoading = true;
9726			
9727			// If mk-ajax-loaded-posts span exists, get the post ids
9728			if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) {
9729				var loaded_posts = this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts');
9730				
9731				// Do not send looaded posts for Classic Pagination Navigation
9732				if ( this.$container.attr('data-pagination-style') != 1 ) {
9733					self.data.loaded_posts = loaded_posts.split(',');
9734				}
9735			}
9736
9737            return $.when(
9738	            $.ajax({
9739	                url 	: _ajaxUrl,
9740	                type 	: "POST",
9741	                data 	: self.data
9742	            })
9743	        ).done(function(response) {
9744	        	self.onDone(response, unique, seq);
9745	        });
9746		},
9747
9748		onDone: function(response, unique, seq) {
9749			if(seq === this.xhrCounter) {
9750				var self = this;
9751
9752				response = $.parseJSON(response);
9753				response.unique = unique;
9754				response.id = this.id;
9755				
9756				// If mk-ajax-loaded-posts span exists, update current post ids 
9757				// with new post ids from server's response
9758				if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) {
9759					this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts', response.loaded_posts);
9760				}
9761
9762	            this.setData({
9763	                maxPages: response.maxPages,
9764	                found_posts: response.found_posts,
9765	                loop_iterator: response.i
9766	            });
9767
9768				// Preload images first by creating object from returned content.
9769				// mk_imagesLoaded() method will create a promise that gets resolved when all images inside are loaded.
9770				// Our ajaxLoad is somehow more similar to window.onload event now.
9771				$(response.content).mk_imagesLoaded().then(function() {
9772					MK.utils.eventManager.publish('ajaxLoaded', response);
9773		        	self.isLoading = false;
9774		        	self.initNewComponents();
9775				});
9776
9777	        } else console.log('XHR request nr '+ seq +' aborted');
9778
9779        },
9780
9781		setData: function setData(atts) {
9782			for(var att in atts) {
9783				if(att === 'term' && atts[att] === '*') this.data.term = '';
9784				else this.data[att] = atts[att];
9785			}
9786		},
9787
9788		getData: function getData(att) {
9789			return this.data[att];
9790		},
9791
9792		initNewComponents: function initNewComponents() {
9793            // Legacy scripts reinit
9794            window.ajaxInit();
9795            setTimeout(window.ajaxDelayedInit, 1000);
9796            // New way to init apended things
9797            MK.core.initAll(this.el);
9798        }
9799	};
9800
9801}(jQuery));
9802MK.component.BackgroundImageSetter = (function ($) {
9803
9804	'use strict';
9805
9806	var module = {};
9807
9808
9809	/*---------------------------------------------------------------------------------*/
9810	/* Private Variables
9811	/*---------------------------------------------------------------------------------*/
9812
9813	/**
9814	 *	Take all elements with data-mk-img-set attribute and evaluate best image according to given device orientation and resolution,
9815	 *	sets style for backround-image on the same node element.	 * 
9816	 */
9817
9818	var $win = $(window),
9819		// $layers = $('[data-mk-img-set]'),
9820		screen = getScreenSize(),
9821		orientation = getOrientation(),
9822		device = getDevice(),
9823		lastOrientation = orientation,
9824		lastDevice = device;
9825
9826
9827	/*---------------------------------------------------------------------------------*/
9828	/* Private Methods
9829	/*---------------------------------------------------------------------------------*/
9830
9831	function run($layers) {
9832		$layers.filter( function() {
9833			return !this.hasAttribute("mk-img-loaded");
9834		}).each(applyBg);
9835	}
9836
9837	// Keep our main side effect out of calculations so they can be run once before loop of applying bg as a result
9838	function applyBg() {
9839		var $this = $(this), 
9840			imgs = $this.data('mk-img-set');
9841
9842		$this.css('background-image', 'url('+ module.getImage(imgs) +')');
9843		$this.find('.mk-adaptive-image').attr('src', module.getImage(imgs)); 
9844	}
9845
9846	// Keep track of current screen size while resizing but update device reference 
9847	// and reapply backgrounds only when we discover switch point
9848	function handleResize($layers) { 
9849		updateScreenSize();
9850		if(hasSwitched()) {
9851			updateDevice();
9852			run($layers);
9853		}
9854	}
9855
9856	function getScreenSize() {
9857		return {
9858			w: $win.width(),
9859			h: $win.height() 
9860		};
9861	}
9862
9863	// Name our device classes and add them id which simply means which one is wider
9864	function getDevice() {
9865		if     (screen.w > 1024) 	return {class: 'desktop', id: 2};
9866		else if(screen.w > 736) 	return {class: 'tablet',  id: 1};
9867		else 					 	return {class: 'mobile',  id: 0};
9868	}
9869
9870	function getOrientation() {
9871		if(screen.w > screen.h) 	return 'landscape';
9872		else 						return 'portrait';
9873	}
9874
9875	function updateScreenSize() {
9876		screen = getScreenSize();
9877	}
9878
9879	function updateDevice() {
9880		if(lastOrientation !== orientation) orientation = lastOrientation;
9881		// Switch device only if going from smaller size to bigger. 
9882		// Bigger to smaller is perfectly handled by browsers and doesn't require change and reupload
9883		if(lastDevice.id > device.id) device = lastDevice;
9884	}
9885
9886	function hasSwitched() {
9887		lastOrientation = getOrientation();
9888		lastDevice = getDevice();
9889
9890		if(lastOrientation !== orientation || lastDevice.class !== device.class) return true;
9891		else return false;
9892	}
9893
9894
9895	/*---------------------------------------------------------------------------------*/
9896	/* Public Methods
9897	/*---------------------------------------------------------------------------------*/
9898
9899	// As desired image might be not available we have to evaluate the best match.
9900	module.getImage = function (imgs) {
9901		if (imgs['responsive'] === 'false') {
9902			return (imgs['landscape']['desktop']) ? imgs['landscape']['desktop'] : (imgs['landscape']['external'] ? imgs['landscape']['external'] : '');
9903			
9904		}
9905		var hasOrientation = !!imgs[orientation];
9906		// there are only two orientations now and we may get them by string name if both are there 
9907		// or by index of 0 if only one is available. Note Objects has no lexical order so we need to grab key name by its index.
9908		// Also we may have external file for each orientation which we don't scale internaly so we grab it as it is. If nothing found return an empty string 
9909		var imgOriented = imgs[ (hasOrientation ? orientation : Object.keys(imgs)[0]) ],
9910			imgExact    = (imgOriented[device.class]) ? imgOriented[device.class] : (imgOriented['external'] ? imgOriented['external'] : '');
9911		return imgExact; 
9912	}
9913
9914	module.init = function ($layers) {
9915		
9916		// Run and bind
9917		run($layers);
9918		$layers.attr('mk-img-loaded', '');
9919	};
9920
9921	module.onResize = function ($layers) {
9922		$win.on('resize', MK.utils.throttle( 500, function() {
9923			handleResize($layers);
9924		}));
9925	};
9926
9927	return module;
9928
9929}(jQuery));
9930
9931
9932jQuery(function($) {
9933
9934	var init = function init() {
9935		// Get All Layers, Excluding Edge Slider and Page Section
9936		$allLayers = $('[data-mk-img-set]').filter(function(index) {
9937			return !$(this).hasClass('mk-section-image') && !$(this).hasClass('background-layer') && !$(this).hasClass('mk-video-section-touch');
9938		});;
9939
9940		// Handle the resize
9941		MK.component.BackgroundImageSetter.onResize($allLayers);
9942
9943		// Set all the BG Layers
9944		MK.component.BackgroundImageSetter.init($allLayers);
9945	}
9946	init();
9947
9948	$(window).on('vc_reload', init);
9949
9950});
9951
9952(function( $ ) {
9953	'use strict';
9954
9955	var val = MK.val;
9956
9957	MK.component.FullHeight = function( el ) {
9958		var $window = $( window ),
9959			$this = $( el ),
9960			config = $this.data( 'fullheight-config' ),
9961			container = document.getElementById( 'mk-theme-container' ),
9962			minH = (config && config.min) ? config.min : 0,
9963			winH = null,
9964			height = null,
9965			update_count = 0,
9966			testing = MK.utils.getUrlParameter('testing'),
9967			offset = null;
9968
9969		// We need to provide height on the same specificity level for workaround to IE bug
9970		// connect.microsoft.com/IE/feedback/details/802625/min-height-and-flexbox-flex-direction-column-dont-work-together-in-ie-10-11-preview
9971		// stackoverflow.com/questions/19371626/flexbox-not-centering-vertically-in-ie
9972		if(MK.utils.browser.name === ('IE' || 'Edge')) $this.css( 'height', '1px' );
9973
9974		var update = function() {
9975
9976			if(update_count === 0) {
9977				winH = $window.height();
9978				// for correct calculate
9979				offset = $this.offset().top - 1;
9980				height = Math.max(minH, winH - val.offsetHeaderHeight( offset ));
9981				$this.css( 'min-height', height );
9982				if(testing !== undefined )
9983				update_count++;
9984			}
9985
9986		};
9987
9988		// TODO remove scroll listener by dynamic offset reader
9989		var init = function() {
9990			update();
9991			$window.on( 'resize', update );
9992			$window.on( 'scroll', update );
9993			window.addResizeListener( container, update );
9994		};
9995
9996		return {
9997			init : init
9998		};
9999	};
10000
10001})( jQuery );
10002
10003
10004(function( $ ) {
10005	'use strict';
10006
10007	var core  = MK.core,
10008		utils = MK.utils,
10009		path  = MK.core.path;
10010
10011
10012	MK.ui.FullScreenGallery = function( element, settings ) {
10013		this.element = element;
10014		this.config = settings;
10015
10016		this.isFullScreen = false;
10017	};
10018
10019
10020	// preload slick PLUGIN TO USE THIS
10021	MK.ui.FullScreenGallery.prototype = {
10022		dom : {
10023			fullScrBtn 		: '.slick-full-screen',
10024			exitFullScrBtn 	: '.slick-minimize',
10025			playBtn 		: '.slick-play',
10026			pauseBtn 		: '.slick-pause',
10027			shareBtn 		: '.slick-share',
10028			socialShare 	: '.slick-social-share',
10029		    wrapper 		: '.slick-slider-wrapper',
10030			slider 			: '.slick-slides',
10031			slides 			: '.slick-slide',
10032			dots 			: '.slick-dot',
10033			active 			: '.slick-active',
10034			hiddenClass 	: 'is-hidden',
10035			dataId 			: 'slick-index'
10036		},
10037
10038		tpl: {
10039			dot  : '<div class="slick-dot"></div>',
10040			next : '<a href="javascript:;" class="slick-next"> <svg width="33px" height="65px"> <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points=" 0.5,0.5 32.5,32.5 0.5,64.5"/> </svg> </a>',
10041			prev : '<a href="javascript:;" class="slick-prev"> <svg  width="33px" height="65px"> <polyline fill="none" stroke="#FFFFFF" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" points=" 32.5,64.5 0.5,32.5 32.5,0.5"/> </svg> </a>'
10042		},
10043
10044		init : function() { 
10045			var self = this;
10046
10047			// core.loadDependencies([ path.plugins + 'slick.js' ], function() {
10048				self.cacheElements();
10049				self.getViewportSizes();
10050				self.updateSizes( 'window' );
10051				self.create();
10052				// update cache with elements propagated by plugin
10053				self.updateCacheElements();
10054				self.createPagination();
10055				self.bindEvents();
10056			// });
10057		},
10058
10059		create : function() {
10060			var self = this;
10061
10062			this.slick = this.$gallery.slick({
10063		        dots: true,
10064		        arrows: true,
10065				infinite: true,
10066				speed: 300,
10067				slidesToShow: 1,
10068				centerMode: true,
10069				centerPadding: '0px',
10070				variableWidth: true,
10071				autoplay: false,
10072				autoplaySpeed: 3000,
10073        		useTransform: true,
10074                prevArrow: self.tpl.prev,
10075                nextArrow: self.tpl.next,
10076                customPaging: function(slider, i) {
10077                    return self.tpl.dot;
10078                },
10079			});
10080		},
10081
10082		cacheElements : function() {
10083			this.$window = $( window );
10084			this.$gallery = $( this.element );
10085
10086			this.$fullScrBtn = $( this.dom.fullScrBtn );
10087			this.$exitFullScrBtn = $( this.dom.exitFullScrBtn );
10088			this.$playBtn = $( this.dom.playBtn );
10089			this.$pauseBtn = $( this.dom.pauseBtn );
10090			this.$shareBtn = $( this.dom.shareBtn );
10091			this.$socialShare = $( this.dom.socialShare );
10092
10093		    this.$wrapper = $( this.dom.wrapper );
10094			this.$slider = $( this.dom.slider );
10095			this.$slides = $( this.dom.slides );
10096			this.$imgs = this.$slides.find( 'img' );
10097			// store reference to initial images without slides appended by pugin
10098			// - needed for creating of pagination
10099			this.$originalImgs = this.$imgs;
10100		},
10101
10102		updateCacheElements : function() {
10103			this.$slides = $( this.dom.slides );
10104			this.$imgs = this.$slides.find( 'img' );
10105			this.$dots = $( this.dom.dots );
10106		},
10107
10108		bindEvents : function() {
10109			var self = this;
10110			this.$fullScrBtn.on( 'click', this.toFullScreen.bind( this ) );
10111			this.$exitFullScrBtn.on( 'click', this.exitFullScreen.bind( this ) );
10112			this.$playBtn.on( 'click', this.play.bind( this ) );
10113			this.$pauseBtn.on( 'click', this.pause.bind( this ) );
10114			this.$shareBtn.on( 'click', this.toggleShare.bind( this ) );
10115			this.$socialShare.on( 'click', 'a', this.socialShare.bind( this ) );
10116			this.$window.on( 'resize', this.onResize.bind( this ) );
10117			this.$window.on( 'keydown', function(e) {
10118				if(e.keyCode === 39) self.$gallery.slick('slickNext');
10119				if(e.keyCode === 37) self.$gallery.slick('slickPrev');
10120			});
10121			$( document ).on( 'fullscreenchange mozfullscreenchange webkitfullscreenchange msfullcreenchange', this.exitFullScreen.bind( this ) );
10122		},
10123
10124		getViewportSizes : function() {
10125			this.screen = {
10126				w: screen.width,
10127				h: screen.height
10128			};
10129			this.window = {
10130				w: this.$window.width(),
10131				h: this.$window.height()
10132			};
10133		},
10134
10135		updateSizes : function( viewport ) {
10136			this.$wrapper.width( this[ viewport ].w );
10137			this.$wrapper.height( '100%' );
10138			this.$imgs.height( '100%');
10139		},
10140
10141		createPagination : function() {
10142			var self = this;
10143			this.$dots.each( function( i ) {
10144				var img = self.$originalImgs.eq( i ).attr( 'src' );
10145
10146				$( this ).css({
10147					'background-image': 'url('+ img +')'
10148				});
10149			});	
10150		},
10151
10152		play : function(e) {
10153			e.preventDefault();
10154			this.$playBtn.addClass( this.dom.hiddenClass );
10155			this.$pauseBtn.removeClass( this.dom.hiddenClass );
10156			$( this.element ).slick( 'slickPlay' );
10157		},
10158
10159		pause : function(e) {
10160			e.preventDefault();
10161			this.$pauseBtn.addClass( this.dom.hiddenClass );
10162			this.$playBtn.removeClass( this.dom.hiddenClass );
10163			$( this.element ).slick( 'slickPause' );
10164		},
10165
10166		toggleShare : function(e) {
10167			e.preventDefault();
10168			this.$socialShare.toggleClass( this.dom.hiddenClass );
10169		},
10170
10171		getCurentId : function() {
10172			return this.$slides.filter( this.dom.active ).data( this.dom.dataId );
10173		},
10174
10175		toFullScreen : function() {
10176			var self = this;
10177
10178			this.$fullScrBtn.addClass( this.dom.hiddenClass );
10179			this.$exitFullScrBtn.removeClass( this.dom.hiddenClass );
10180
10181			this.$slider.hide().fadeIn( 500 );
10182			utils.launchIntoFullscreen( document.documentElement );
10183			this.updateSizes( 'screen' );
10184			$( this.element ).slick( 'slickGoTo', this.getCurentId(), true );
10185
10186			// Update state with delay so we avoid triggering exitFullScreen fn from 
10187			// fullscreenchange event
10188			setTimeout( function() {
10189				self.isFullScreen = true;
10190			}, 1000);					
10191		},
10192
10193		exitFullScreen : function() {
10194			if( this.isFullScreen ) { 
10195				this.$exitFullScrBtn.addClass( this.dom.hiddenClass );
10196				this.$fullScrBtn.removeClass( this.dom.hiddenClass );
10197
10198				utils.exitFullscreen();
10199				this.updateSizes( 'window' );
10200				$( this.element ).slick( 'slickGoTo', this.getCurentId(), true );
10201
10202				this.isFullScreen = false;
10203			}
10204
10205		},
10206
10207		onResize : function() {
10208			this.getViewportSizes();
10209			this.updateSizes( this.isFullScreen ? 'screen' : 'window' );
10210			$( this.element ).slick( 'refresh' );  
10211			$( this.element ).slick( 'slickGoTo', this.getCurentId(), true );
10212			this.updateCacheElements();
10213			this.createPagination();
10214		},
10215
10216		socialShare : function( e ) {
10217			e.preventDefault();
10218			var $this = $( e.currentTarget ),
10219				network = $this.data( 'network' ),
10220				id = this.config.id,
10221				url = this.config.url,
10222				title = this.$wrapper.find( '.slick-title' ).text(),
10223				name;
10224				var picture = this.$slides.filter( this.dom.active ).children().first().attr( 'src' );
10225			switch( network ) {
10226				case 'facebook': 
10227					url = 'https://www.facebook.com/sharer/sharer.php?picture=' + picture+'&u=' + url + '#id=' + id;
10228					name = 'Facebook Share';
10229					break;
10230				case 'twitter':
10231					url = 'http://twitter.com/intent/tweet?text=' + url + '#id=' + id;
10232					name = 'Twitter Share';
10233					break;
10234				case 'pinterest':
10235					url = 'http://pinterest.com/pin/create/bookmarklet/?media=' + picture + '&url=' + url + '&is_video=false&description=' + title;
10236					// other available link paranmeters: media, description
10237					name = 'Pinterest Share';
10238					break;
10239
10240			}
10241
10242       		window.open( url, name, "height=380 ,width=660, resizable=0, toolbar=0, menubar=0, status=0, location=0, scrollbars=0" );
10243		}
10244	};
10245
10246})( jQuery );
10247(function( $ ) {
10248	'use strict';
10249
10250	/**
10251	 * A fork from original VC function.
10252	 * The original one is adding some padding which causes extra padding
10253	 * on our templates so we customized the codes.
10254	 *
10255	 * @since 5.9.8
10256	 * @since 6.0.1 Improve logic to handle LTR responsive state.
10257	 */
10258	function MkfullWidthRow() {
10259		var $elements = $('[data-mk-full-width="true"]');
10260		var direction = $('body.rtl').length ? 'right' : 'left';
10261		var verticalHeader = $('body.vertical-header-enabled').length ? true : false;
10262		var verticalHeaderWidth = ( $( '.header-style-4 .mk-header-inner' ).outerWidth() > 270 ) ? 0 : 270;
10263		var verticalHeaderRtl = $('body.rtl').length ? -1 : 1;
10264		var verticalHeaderRtlWidth = $('body.rtl.vertical-header-enabled').length ? verticalHeaderWidth : 0;
10265		var verticalHeaderRight = $('body.vertical-header-right').length ? -1 : 1;
10266		var verticalHeaderWidthBoxed = 0;
10267		var boxed = $('body.mk-boxed-enabled').length;
10268		var boxedOffset = ( boxed ) ? ( $(window).width() - $('#theme-page').outerWidth() ) / 2 : 0;
10269		var boxedMaxWidth = ( boxed ) ? $('#theme-page').outerWidth() : 'auto';
10270
10271		if ( verticalHeader && boxed ) {
10272			verticalHeaderWidthBoxed = ( $( '.header-style-4 .mk-header-inner' ).outerWidth() > 270 ) ? 0 : verticalHeaderRtl * verticalHeaderRight * 135;
10273		}
10274		if ( $('.transparent-header').length > 0 ) {
10275			verticalHeaderWidthBoxed = 0;
10276		}
10277
10278		$.each($elements, function(key, item) {
10279			var $el = $(this);
10280			var css;
10281			$el.addClass("vc_hidden");
10282			var $el_full = $el.next(".vc_row-full-width");
10283			if ($el_full.length || ($el_full = $el.parent().next(".vc_row-full-width")), $el_full.length) {
10284				var el_margin_left = parseInt($el.css("margin-left"), 10),
10285				el_margin_right = parseInt($el.css("margin-right"), 10),
10286				offset = 0 - $el_full.offset().left - el_margin_left,
10287				width = $(window).width();
10288				if (css = {
10289					position: "relative",
10290					"box-sizing": "border-box",
10291					width: $(window).width(),
10292					maxWidth: boxedMaxWidth
10293				},
10294				css[direction] = offset + boxedOffset + verticalHeaderWidthBoxed + ( verticalHeaderRight * verticalHeaderRtlWidth ),
10295				$el.css(css), !$el.data("mkStretchContent")) {
10296					var padding = -1 * offset;
10297					0 > padding && (padding = 0);
10298					var paddingRight = width - padding - $el_full.width() + el_margin_left + el_margin_right;
10299					padding = padding - paddingRight;
10300					if ( 0 > paddingRight && (paddingRight = 0) ) {
10301						css = {};
10302						if ( 'right' === direction ) {
10303							css["padding-left"] = padding + "px";
10304							css["padding-right"] = 0;
10305						} else {
10306							css["padding-right"] = padding + "px";
10307							css["padding-left"] = 0;
10308						}
10309
10310						$el.css(css)
10311					}
10312				}
10313				$el.attr("data-mk-full-width-init", "true"), $el.removeClass("vc_hidden"), $(document).trigger("vc-full-width-row-single", {
10314					el: $el,
10315					offset: offset,
10316					marginLeft: el_margin_left,
10317					marginRight: el_margin_right,
10318					elFull: $el_full,
10319					width: width
10320				})
10321			}
10322		}
10322), $(document).trigger("mk-full-width-row", $elements)
10323	}
10324
10325	MkfullWidthRow();
10326	var debounceResize = null;
10327	$(window).on("resize", function() {
10328		if( debounceResize !== null ) { clearTimeout( debounceResize ); }
10329		debounceResize = setTimeout( MkfullWidthRow, 50 );
10330	});
10331
10332})( jQuery );
10333
10334(function($) {
10335    'use strict';
10336
10337    MK.component.Grid = function( el ) {
10338    	var $container = $(el);
10339    	var config = $container.data( 'grid-config' );
10340        var isSlideshow = $container.closest('[data-mk-component="SwipeSlideshow"]').length;
10341        var miniGridConfig = {
10342            container: el,
10343            item: config.item + ':not(.is-hidden)',
10344            gutter: 0 
10345        };
10346
10347        var init = function init(){
10348            // Flags for cancelling usage goes first :
10349            // Quit early if we discover that Grid is used inside SwipeSlideshow as it brings bug with crossoverriding positioning 
10350            // + grid is not really needed as we have single row all handled by slider.
10351            // It happens only in woocommerce carousel as of hardcoded Grid in loop-start.php
10352            if(isSlideshow) return; 
10353	        MK.core.loadDependencies([ MK.core.path.plugins + 'minigrid.js' ], create);
10354        };
10355
10356        // Remove el hidden without adding proper class
10357        var prepareForGrid = function prepareForGrid() {
10358            var $item = $(this);
10359            var isHidden = ($item.css('display') === 'none');
10360            if(isHidden) $item.addClass('is-hidden');
10361            else $item.removeClass('is-hidden');
10362        };
10363
10364        var create = function create() {
10365            var timer = null;
10366
10367	        function draw() { 
10368                // Prevent plugin breaking when feeding it with hidden elements
10369                $container.find(config.item).each( prepareForGrid );
10370	            minigrid(miniGridConfig);
10371	        }
10372
10373            function redraw() {
10374                if (timer) clearTimeout(timer);
10375                timer = setTimeout(draw, 100);
10376            }
10377
10378            // init
10379	        draw(); 
10380            // If reinitializing drop existing event handler
10381            $(window).off('resize', redraw);
10382            $(window).on('resize', redraw);
10383            MK.utils.eventManager.subscribe('item-expanded', redraw);
10384            MK.utils.eventManager.subscribe('ajaxLoaded', redraw);
10385            MK.utils.eventManager.subscribe('staticFilter', redraw);
10386        };
10387
10388        return {
10389         	init : init
10390        };
10391    };
10392
10393})(jQuery);
10394
10395
10396
10397
10398
10399
10400
10401
10402/**
10403 * ICON FACTORY @ Maki
10404 * 
10405 * Javascript part that translates css styles into link to server side manufacturer.
10406 * By passing extra args we generate icons as needed on server and send them back with ajax and attch them to DOM here.
10407 *
10408 * This is temporary solution that helps us switching from font icons to singular svgs without too match overhead. The finalized solution shoulnd be 99% server side.
10409 * Our main templating is happening there. We should have an icon_factory(name, properties) function that we can call directly in templates to serve us icons. 
10410 * Post load, js soluition should target only elements that we have no direct access to. We set it as TODO for future as part of progressive development. 
10411 * When correct factory is done we should be able to use it here and there to progressively kill overhead generated by current solution until we could totally switch it.
10412 * 
10413 * Prons:
10414 * - automated process where we can mimic old behaviour
10415 * - possible bugs are easy to patch 
10416 * - far samller download size for assets needed by theme (no font families css and fonts itself to download, which are currently blocking page load time)
10417 * - icon generation moved to server side where our main templating is already happening
10418 * - we can easily switch how our Icon should be outputed - inline, img, object, iframe. Whatever our situation requires (img for responsive icons for example)
10419 *
10420 * Cons:
10421 * - possible bugs based on different nature of svgs / fonts. Need to be manually fixed
10422 * - some manual work to straighten things - litle css refactors here and there
10423 * - as the mapping the icons happens in server side, it may cause CPU bottlenecks and should be cashed in DB for repetitve usage.
10424 *
10425 *
10426 * TODO Refactor to config obj as parameter for easier passing it. Also decouple more - especially loops
10427 */
10428(function ($) {
10429	'use strict';
10430
10431	// As long as we can manage this manually it is better like so. We avoid delay based on waiting for ajax to finish
10432 	// $.get( MK.core.path.theme + '/assets/icons/icon-families.json', createAll);
10433 	var families = [
10434		['awesome-icons' , 'mk-icon-'], // [family, prefix]
10435		['icomoon' 		 , 'mk-moon-'],
10436		['pe-line-icons' , 'mk-li-'],
10437		['theme-icons' 	 , 'mk-jupiter-icon-'] 
10438	];
10439
10440	// Our css contains this extends for particular families of fonts. For now we automate the process and extend it here as well
10441	var extend = {
10442		'awesome-icons' : [], 
10443		'icomoon' : [],
10444		'pe-line-icons' : [],
10445		'theme-icons' : []
10446	};	
10447 	
10448 	// Cache holder for quick access to repeating icons. config / svg
10449	var _cache = {};
10450	var _cacheId = 0;
10451	// Merge configs to call it with single ajax
10452	var _config = [];
10453	// Counter for all families. We merge all our families for single ajax request and countdown when to trigger the download.
10454	var _roundCount = 0;
10455	// Mapper for icons - config / array with nodes
10456	var _iconMap = {};
10457
10458
10459	// Closure to merge $icons together and to run the download when we counted down icon families to 0
10460 	var getIconsSprite = (function() {
10461 		var $icons = null;
10462 		var iterator = 0;
10463
10464 		function run(callback) {
10465	 		var config = encodeURIComponent(JSON.stringify(_config));
10466
10467			$.ajax({
10468				url : MK.core.path.ajaxUrl,
10469				// dataType: 'xml',
10470				method: 'POST',
10471				data: {action : 'mk_get_icon', iterator: iterator++, config: config},
10472				success: function(sprite) { 
10473					callback(sprite, $icons);
10474					_config = [];
10475					_iconMap = {};
10476					$icons = null;
10477				},
10478				error: function(err) { 
10479					console.log('Icon load problem');
10480				}
10481			});
10482		}
10483
10484		return function(callback, $els, count) {
10485			if(!$icons) $icons = $els;
10486			else $icons.add($els);
10487			// console.log(count);
10488			if(!count) run(callback);
10489		};
10490 	}());
10491
10492 	// Wait for DOM manipulations and run where really needed
10493 	$(window).on('load', function() { 
10494 		setTimeout(function() {
10495 			createAll(document);
10496 			if($('.mk-header').length) createAll('.mk-header');
10497 			if($('.js-flexslider, .mk-flexslider').length) createAll('.js-flexslider, .mk-flexslider');
10498 			if($('.mk-accordion').length) createAll('.mk-accordion'); 
10499 		}, 1000); 
10500 	});
10501
10502 	MK.utils.eventManager.subscribe('ajaxLoaded', function() {
10503 		// Wait for actuall DOM insertion
10504 		setTimeout(createAll, 100, '.js-loop');
10505 	});
10506
10507	MK.utils.eventManager.subscribe('ajax-preview', function() {
10508 		setTimeout(createAll, 100, '.ajax-container');
10509	});
10510
10511	MK.utils.eventManager.subscribe('photoAlbum-open', function() {
10512 		setTimeout(createAll, 100, '.gallery-share');
10513	});
10514
10515	MK.utils.eventManager.subscribe('quickViewOpen', function() {
10516 		setTimeout(createAll, 300, '.mk-modal-content');
10517	});
10518
10519 	// Our main runner that creates all icons in given scope
10520 	function createAll(scope) {
10521		// iterate through families
10522 		for(var i = 0, l = families.length; i < l; i++) {
10523 			var family = families[i][0];
10524 			var prefix = families[i][1];
10525 			var $icons = getIcons(family, prefix, scope);
10526 			if($icons.length) {
10527 				_roundCount++;
10528 				// apply arguments from current loop iteration but send createIcons to event loop so it will get trigerred in the same order as this loop finish.
10529 				// We need it to pass all $icons first so we can merge all families before ajax request.
10530 				setTimeout(createIcons, 0, $icons, family, prefix);
10531 			}
10532 		}
10533 	}
10534
10535 	// Grab all els in given scope that contains our prefix, anywhere in class attribute. Extend if needed
10536 	function getIcons(family, prefix, scope) {
10537 		var $scope = $(scope);
10538 		var $icons = $scope.find('[class*='+ prefix +']');
10539 		var extraClassNames = extend[family];
10540 		// if nothing to extend just return what we have till now
10541 		if(!extraClassNames) return $icons; 
10542 		// Extend it with our css garbish
10543 		extraClassNames.forEach(function(className) {
10544 			var $icon = $scope.find(className);
10545 			$icons = $icons.add($icon);
10546 		});
10547 		// serve all
10548 		return $icons;
10549 	}
10550
10551
10552 	function createIcons($icons, family, prefix, i, unicode) {
10553 		var id   = i || 0;
10554		var icon = $icons[id];
10555
10556		// quick check point, if no more icons break recursion
10557		if(!icon) {
10558			_roundCount--;
10559			getIconsSprite(insertIcons, $icons, _roundCount, _config);
10560			return;
10561		}
10562
10563		var css       = getComputedStyle( icon, ':before');
10564		var classAttr = icon.getAttribute('class');
10565		var name      = (classAttr) ? matchClass(classAttr.split(' '), prefix) : false;
10566		var h         = getComputedStyle(icon).fontSize;
10567		var config    = createConfig(css, name, family, unicode, h);
10568		var cache 	  = JSON.stringify(config);
10569
10570		if(!config) {
10571			// Yep, we have a mess so sometimes we try to call for an icon where it should not exist (no class match or unicode found)
10572			// As we expect empty response from server, we just skip to next icon
10573
10574		} else if(_cache[cache]) {
10575			// Use cached icon when possible
10576			// 
10577			if(typeof _iconMap[cache] === 'undefined') _iconMap[cache] = [$icons.eq(id)];
10578			else _iconMap[cache].push($icons.eq(id));
10579
10580		} else {
10581			if(typeof _iconMap[cache] === 'undefined') _iconMap[cache] = [$icons.eq(id)];
10582			else _iconMap[cache].push($icons.eq(id));
10583
10584			_cache[cache] = _cacheId.toString(); // number as string so we could do [var] key lookup after reversal
10585			config.id = _cacheId; // extend config for server only
10586			_config.push(config);
10587
10588			_cacheId++; // increment after caching
10589		}
10590
10591		createIcons($icons, family, prefix, ++id);
10592 	}
10593
10594 	function insertIcons(sprite, $icons) {
10595 		var $sprite = $(sprite);
10596 		var $svgs   = $sprite.find('svg');
10597 		var idMap   = invert(_cache);
10598
10599 		$sprite.each(function() {
10600 			var $svg = $(this);
10601 			var id   = $svg.attr('data-cacheid'); // read as string
10602 			var configKey = idMap[id];
10603
10604 			_cache[configKey] = this;
10605 			// console.log(id, this)
10606 		});
10607
10608 		// console.log('sprite',sprite)
10609 		// 
10610
10611 		Object.keys(_iconMap).forEach(function (cacheKey) {
10612		   	_iconMap[cacheKey].forEach(function($icons) {
10613		   		$icons.each(function() {
10614		   			var $svg = $(_cache[cacheKey]).clone();
10615		   			var $icon = $(this);
10616
10617		   			// console.log($icon[0], _cache[cacheKey]);  
10618		   			
10619		   			function remove() {
10620		   				// exclude problematic stuff
10621		   				if($icon.parents('.pricing-features')) return;
10622			   			$icon.not('.mk-jupiter-icon-xing') 
10623			   				 .not('.mk-jupiter-icon-square-xing')
10624			   				 .not('.mk-jupiter-icon-simple-xing')
10625			   				 .find('.mk-svg-icon') 
10626			   				 .not('[data-name="mk-moon-zoom-in"]')
10627			   				 .remove(); // and remove else to reapply styles with new loaded svg
10628		   			}
10629
10630		   			if($svg.length ) remove();
10631
10632		   			if(!$icon.find('svg').length) {
10633		   				if($icon.parents('.widget ul').length) $icon.prepend($svg);
10634		   				else $icon.append($svg);
10635					}
10636		   		});
10637		   	});
10638		});
10639
10640 		// Notify rest of app
10641		MK.utils.eventManager.publish('iconsInsert');
10642 	}
10643
10644 	// Prepare configuration for server side. We need to grab icons and manipulate them a little there
10645 	function createConfig(css, name, family, unicode, height) {
10646 		var hasGradient  = checkGradient(css);
10647 		var hasDirection = extractGradient('direction', css.background);
10648
10649 		var config = {
10650 			family: family, 
10651 			// this is mostly for Extends. Because we've been customizing singular elements and assigning content unicode manually, 
10652 			// now we don't have any proper anchor for usage with our json map
10653 			unicode: (unicode) ? unicode : decodeUnicode(css.content), 
10654 			name: name,
10655 			// fill: css.color,
10656 			gradient_type:  hasGradient ? extractGradient('type' , css.background) : false,
10657 			gradient_start: hasGradient ? extractGradient('start', css.background) : false,
10658 			gradient_stop:  hasGradient ? extractGradient('stop' , css.background) : false,
10659 			gradient_direction: hasDirection ? extractGradient('direction', css.background).replace(' ', '-') : false,
10660 			height: height
10661 		};
10662
10663 		// If there is no name or unicode the whole config is invalid
10664 		if(!config.name && !config.unicode) return false;
10665 		else return config;
10666 	}
10667
10668 	// Extract class name that represents the icon that we try to generate
10669 	function matchClass(classes, prefix) {
10670 		// var missing = '';
10671 		for(var i = 0, l = classes.length; i < l; i++) {
10672 			if(classes[i].indexOf(prefix) !== -1) return classes[i]; // return first matched class name
10673 			// else missing += ' .' + classes[i]; // collect not matching classes
10674 		}
10675 		// if we didn't returned anything within loop we output notification here. Keep it for testing only
10676 		// console.log('Possibility of missing icons for element with classes:' + missing);
10677 	}
10678
10679 	// Check if background conatains gradient declaration and return bg string if so or false 
10680 	function checkGradient(css) {
10681 		var bg = css.background;
10682 		if(bg.indexOf('radial') !== -1 || bg.indexOf('linear') !== -1) return bg;
10683 		else return false;
10684 	}
10685
10686 	// Extract background attribiutes from bg string.
10687 	// Multipurpose function which returns part we ask for
10688 	function extractGradient(attr, grad) {
10689 		// quit if gradient is falsy
10690 		// console.log(grad);
10691 		if(!grad) return false;
10692
10693 		var isRadial = grad.indexOf('radial')  !== -1;
10694 		var isLinear = grad.indexOf('linear')  !== -1;
10695 		var hasDirection = grad.indexOf('(to') !== -1;
10696 		var f, t; // from, to
10697
10698 		if(attr === 'type') {
10699 			if(isRadial) return 'radial';
10700 			if(isLinear) return 'linear';
10701
10702 		} else if(attr === 'start') {
10703 			f = getStrPosition(grad, 'rgb(', 1);
10704 			t = getStrPosition(grad, '0%'  , 1);
10705
10706 		} else if(attr === 'stop') {
10707 			f = getStrPosition(grad, 'rgb(', 2);
10708 			t = getStrPosition(grad, '100%', 1);
10709
10710 		} else if(attr === 'direction') {
10711 			if(!hasDirection) return false;
10712 			f = getStrPosition(grad, '(to', 1) + 4;
10713 			t = getStrPosition(grad, ', rgb(', 1);
10714
10715 		} else {
10716 			return false;
10717 		}
10718 		
10719 		return grad.slice(f, t);
10720 	}
10721
10722 	// Helper for getting indexOf but with lookup for instance of the string
10723 	// str - string to search
10724 	// m - what we're looking for
10725 	// i - instance, starting at 1
10726 	function getStrPosition(str, m, i) {
10727	   return str.split(m, i).join(m).length;
10728	}
10729
10730	// JS outputs unicode results rather than code representation. This helper function does the job
10731	function decodeUnicode(content) {
10732		// escape() kills \ escape signature and outputs it as %u
10733		// str replace to drop special chars
10734		// and we bring it all to lowercase to match filenames we keep on server
10735		if(content && content !== 'none') return escape(content).replace(/%22/g, '').replace('%u', '').toLowerCase();
10736		else return false; // just in case we haven't provided content to work with
10737	}
10738
10739	function invert(obj) {
10740	  	var new_obj = {};
10741	  	for (var prop in obj) {
10742	    	if(obj.hasOwnProperty(prop)) {
10743	      		new_obj[obj[prop]] = prop;
10744	    	}
10745	  	}
10746	  	return new_obj;
10747	}
10748
10749}(jQuery));
10750/*!
10751 * imagesLoaded PACKAGED v4.1.1
10752 * JavaScript is all like "You images are done yet or what?"
10753 * MIT License
10754 */
10755
10756!function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}(window,function(t,e){function i(t,e){for(var i in e)t[i]=e[i];return t}function n(t){var e=[];if(Array.isArray(t))e=t;else if("number"==typeof t.length)for(var i=0;i<t.length;i++)e.push(t[i]);else e.push(t);return e}function o(t,e,r){return this instanceof o?("string"==typeof t&&(t=document.querySelectorAll(t)),this.elements=n(t),this.options=i({},this.options),"function"==typeof e?r=e:i(this.options,e),r&&this.on("always",r),this.getImages(),h&&(this.jqDeferred=new h.Deferred),void setTimeout(function(){this.check()}.bind(this))):new o(t,e,r)}function r(t){this.img=t}function s(t,e){this.url=t,this.element=e,this.img=new Image}var h=t.jQuery,a=t.console;o.prototype=Object.create(e.prototype),o.prototype.options={},o.prototype.getImages=function(){this.images=[],this.elements.forEac
10756h(this.addElementImages,this)},o.prototype.addElementImages=function(t){"IMG"==t.nodeName&&this.addImage(t),this.options.background===!0&&this.addElementBackgroundImages(t);var e=t.nodeType;if(e&&d[e]){for(var i=t.querySelectorAll("img"),n=0;n<i.length;n++){var o=i[n];this.addImage(o)}if("string"==typeof this.options.background){var r=t.querySelectorAll(this.options.background);for(n=0;n<r.length;n++){var s=r[n];this.addElementBackgroundImages(s)}}}};var d={1:!0,9:!0,11:!0};return o.prototype.addElementBackgroundImages=function(t){var e=getComputedStyle(t);if(e)for(var i=/url\((['"])?(.*?)\1\)/gi,n=i.exec(e.backgroundImage);null!==n;){var o=n&&n[2];o&&this.addBackground(o,t),n=i.exec(e.backgroundImage)}},o.prototype.addImage=function(t){var e=new r(t);this.images.push(e)},o.prototype.addBackground=function(t,e){var i=new s(t,e);this.images.push(i)},o.prototype.check=function(){function t(t,i,n){setTimeout(function(){e.progress(t,i,n)})}var e=this;return this.progressedCount=0,this.hasAnyBroken=!1,this.images.length?void this.images.forEach(function(e){e.once("progress",t),e.check()}):void this.complete()},o.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount==this.images.length&&this.complete(),this.options.debug&&a&&a.log("progress: "+i,t,e)},o.prototype.complete=function(){var t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){var e=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[e](this)}},r.prototype=Object.create(e.prototype),r.prototype.check=function(){var t=this.getIsImageComplete();return t?void this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),void(this.proxyImage.src=this.img.src))},r.prototype.getIsImageComplete=function(){return this.img.complete&&void 0!==this.img.naturalWidth},r.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.img,e])},r.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},r.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},r.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},r.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype=Object.create(r.prototype),s.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url;var t=this.getIsImageComplete();t&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},s.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},o.makeJQueryPlugin=function(e){e=e||t.jQuery,e&&(h=e,h.fn.imagesLoaded=function(t,e){var i=new o(this,t,e);return i.jqDeferred.promise(h(this))})},o.makeJQueryPlugin(),o});
10757
10758(function($, window){
10759    'use strict';
10760
10761    var scrollY = MK.val.scroll; 
10762    var dynamicHeight = MK.val.dynamicHeight;
10763
10764    var $window = $(window);
10765    var $containers = $('.js-loop');
10766
10767    $containers.each( pagination );
10768
10769	$window.on( 'vc_reload', function() {
10770		$('.js-loop').each( pagination );
10771	} );
10772
10773    function pagination() {
10774        var unique = Date.now();
10775        var $container = $(this);
10776        var $superContainer = $container.parent(); // should contain clearing so it stretches with floating children
10777        var $loadBtn = $container.siblings('.js-loadmore-holder').find('.js-loadmore-button');
10778        var $loadScroll = $('.js-load-more-scroll');
10779        var style = $container.data('pagination-style');
10780        var maxPages = $container.data('max-pages');
10781        var id = '#' + ($container.attr('id'));
10782        var ajaxLoader = new MK.utils.ajaxLoader(id);
10783        var isLoadBtn = (style === 2);
10784        var isInfiniteScroll = (style === 3); // add flag for last container
10785        var scrollCheckPoint = null;
10786        var isHandlerBinded = false;
10787
10788        ajaxLoader.init();
10789
10790        init();
10791
10792        function init() {
10793            MK.utils.eventManager.subscribe('ajaxLoaded', onLoad);
10794            bindHandlers();
10795            if( isInfiniteScroll ) scrollCheckPoint = spyScrollCheckPoint();
10796
10797			$window.on( 'vc_reload', function() {
10798				$window.off('scroll', handleScroll);
10799			} );
10800        }
10801
10802        function bindHandlers() {
10803            if( isLoadBtn ) $loadBtn.on('click', handleClick);
10804            if( isInfiniteScroll ) $window.on('scroll', handleScroll); 
10805            isHandlerBinded = true;
10806        }
10807
10808        function unbindHandlers() {
10809            if( isLoadBtn ) $loadBtn.off('click', handleClick);
10810            if( isInfiniteScroll ) $window.off('scroll', handleScroll);
10811            isHandlerBinded = false;
10812        }
10813
10814        function handleClick(e) {
10815            e.preventDefault();
10816            if(!ajaxLoader.isLoading) loadMore();
10817        }
10818
10819        function handleScroll() {
10820            if((scrollY() > scrollCheckPoint()) && !ajaxLoader.isLoading) loadMore();
10821        }
10822
10823        function loadMore() {
10824            loadingIndicatorStart();
10825            var page = ajaxLoader.getData('paged');
10826            ajaxLoader.setData({paged: ++page});
10827            ajaxLoader.load(unique);
10828        }
10829
10830        function onLoad(e, response) {
10831            if( typeof response !== 'undefined' && response.id === id) {
10832                // Checking found posts helps to fix all pagination styles 
10833                if( ajaxLoader.getData('found_posts') <= 0 && ajaxLoader.getData('paged') >= ajaxLoader.getData('maxPages')) loadingIndicatorHide();
10834                else loadingIndicatorShow();
10835                if(response.unique === unique) $container.append(response.content);
10836                loadingIndicatorStop();
10837            }
10838        }
10839
10840        function loadingIndicatorStart() {
10841            if(isLoadBtn) $loadBtn.addClass('is-active');
10842            else if(isInfiniteScroll) MK.ui.loader.add('.js-load-more-scroll');
10843
10844        }
10845
10846        function loadingIndicatorStop() {
10847            if(isLoadBtn) $loadBtn.removeClass('is-active');
10848            else if(isInfiniteScroll) MK.ui.loader.remove('.js-load-more-scroll');
10849        }
10850
10851        function loadingIndicatorShow() {
10852            if(isHandlerBinded) return;
10853            if(isLoadBtn) $loadBtn.show();
10854            else if(isInfiniteScroll) $loadScroll.show();
10855            bindHandlers();
10856        }
10857
10858        function loadingIndicatorHide() {
10859            if(!isHandlerBinded) return;
10860            if(isLoadBtn) $loadBtn.hide();
10861            else if(isInfiniteScroll) $loadScroll.hide();
10862            unbindHandlers();
10863        }
10864
10865
10866        function spyScrollCheckPoint() {
10867            var containerO = 0;
10868            var containerH = dynamicHeight( $superContainer );
10869            var winH = dynamicHeight( window );
10870 
10871            var setVals = function() {
10872                containerO = $superContainer.offset().top;
10873            };
10874
10875            setVals();
10876            $window.on('resize', function() { requestAnimationFrame(setVals); });
10877
10878            return function() {
10879                return (containerH() + containerO) - (winH() * 2);
10880            };
10881        }
10882    }
10883
10884})(jQuery, window);
10885(function($) {
10886	'use strict';
10887
10888	// Check if it's inside hidden parent
10889	// Cannot be position: fixed
10890	function isHidden(el) {
10891	    return (el.offsetParent === null);
10892	}
10893
10894	MK.component.Masonry = function(el) {
10895		var $window = $(window);
10896		var $container = $(el);
10897		var config = $container.data( 'masonry-config' );
10898		var $masonryItems = $container.find(config.item);
10899		var cols = config.cols || 8;
10900		var $filterItems = null; // assign only when apply filter
10901		var wall = null;
10902		
10903        var init = function init() {
10904        	MK.core.loadDependencies([ MK.core.path.plugins + 'freewall.js' ], onDepLoad);
10905        };
10906
10907        var onDepLoad = function onDepLoad() {
10908        	masonry();
10909
10910        	// Events
10911	        $window.on('resize', onResize);
10912            MK.utils.eventManager.subscribe('ajaxLoaded', onPostAddition);
10913			MK.utils.eventManager.subscribe('staticFilter', resize);
10914        };
10915
10916	    var masonry = function masonry() {
10917	    	// Quit for hidden elements for now.
10918	    	if(isHidden(el)) return;
10919
10920	    	var newCols;
10921	    	if(window.matchMedia( '(max-width:600px)' ).matches) newCols = 2;
10922	    	else if(window.matchMedia( '(max-width:850px)' ).matches) newCols = 4;
10923	    	else newCols = cols;
10924
10925	    	var colW = $container.width() / newCols;
10926
10927	        wall = new Freewall( config.container );
10928
10929	        // We need to pass settings to a plugin via reset method. Strange but works fine.
10930			wall.reset({
10931				selector: config.item + ':not(.is-hidden)',
10932				gutterX: 0, // set default gutter to 0 and again - apply margins to item holders in css
10933				gutterY: 0,
10934				cellW: colW,
10935				cellH: colW
10936			});
10937
10938	        wall.fillHoles();
10939	        wall.fitWidth();
10940
10941	        $masonryItems.each(function() {
10942	        	$(this).data('loaded', true);
10943	        });
10944        };
10945
10946
10947		// Clear attributes after the plugin. It's API method dosn't handle it properly
10948		var destroyContainer = function destroyContainer() {
10949			$container.removeAttr('style')
10950				 .removeData('wall-height')
10951				 .removeData('wall-width')
10952				 .removeData('min-width')
10953				 .removeData('total-col')
10954				 .removeData('total-row')
10955				 .removeAttr('data-wall-height')
10956				 .removeAttr('data-wall-width')
10957				 .removeAttr('data-min-width')
10958				 .removeAttr('data-total-col')
10959				 .removeAttr('data-total-row');
10960		};
10961
10962		var destroyItem = function destroyItem() {
10963			var $item = $(this);
10964			$item.removeAttr('style')
10965				 .removeData('delay')
10966				 .removeData('height')
10967				 .removeData('width')
10968				 .removeData('state')
10969				 .removeAttr('data-delay')
10970				 .removeAttr('data-height')
10971				 .removeAttr('data-width')
10972				 .removeAttr('data-state'); 
10973		};
10974
10975		var destroyAll = function destroyAll() {
10976	    	if( !wall ) return;
10977    		wall.destroy(); // API destroy
10978    		destroyContainer();
10979    		$masonryItems.each( destroyItem ); // run our deeper destroy
10980		};
10981
10982		var onResize = function onResize() {
10983			requestAnimationFrame(resize);
10984		};
10985
10986        var refresh = function refresh() {
10987	    	if( !wall ) return; 
10988	    	setTimeout(wall.fitWidth.bind(wall), 5);
10989        };
10990
10991        var resize = function resize() {
10992        	destroyAll();
10993	    	masonry();
10994        };
10995
10996        var onPostAddition = function onPostAddition() {
10997        	$masonryItems = $container.find(config.item);
10998
10999        	$masonryItems.each(function() {
11000        		var $item = $(this),
11001        			isLoaded = $item.data('loaded');
11002
11003        		if(!isLoaded) $item.css('visibility', 'hidden');
11004        	});
11005
11006        	
11007        	$container.mk_imagesLoaded().then(function() {
11008        		destroyAll();
11009        		masonry();
11010        	});
11011        };
11012
11013        return {
11014         	init : init
11015        };
11016	};
11017
11018}(jQuery));
11019(function($) {
11020	'use strict';
11021
11022	MK.component.Pagination = function(el) {
11023		this.el = el;
11024	};
11025
11026	MK.component.Pagination.prototype = {
11027		init: function init() {
11028			this.cacheElements(); 
11029			this.bindEvents();
11030			this.onInitLoad();
11031		},
11032
11033		cacheElements: function cacheElements() {
11034			this.lastId = 1;
11035			this.unique = Date.now();
11036			this.$pagination = $(this.el);
11037			this.$container = this.$pagination.prev('.js-loop');
11038			this.$pageLinks = this.$pagination.find('.js-pagination-page');
11039			this.$nextLink = this.$pagination.find('.js-pagination-next');
11040			this.$prevLink = this.$pagination.find('.js-pagination-prev');
11041			this.$current = this.$pagination.find('.js-current-page');
11042			this.$maxPages = this.$pagination.find('.pagination-max-pages'); // TODO change in DOM and here to js class
11043			this.containerId = '#' + this.$container.attr('id');
11044			this.pagePathname = window.location.pathname;
11045			this.pageSearch = window.location.search;
11046			this.popState = false;
11047			this.ajaxLoader = new MK.utils.ajaxLoader('#' + this.$container.attr('id'));
11048			this.ajaxLoader.init();
11049		},
11050
11051		bindEvents: function bindEvents() {
11052			this.$pageLinks.on('click', this.pageClick.bind(this));
11053			this.$nextLink.on('click', this.nextClick.bind(this));
11054			this.$prevLink.on('click', this.prevClick.bind(this)); 
11055			MK.utils.eventManager.subscribe('ajaxLoaded', this.onLoad.bind(this));
11056		},
11057
11058		pageClick: function pageClick(e) {
11059			e.preventDefault(); 
11060			var $this = $(e.currentTarget);
11061			var id = parseFloat($this.attr('data-page-id'));
11062
11063			if(id > this.ajaxLoader.getData('maxPages') || id < 1) return;
11064			this.load(id, $this);
11065			this.updatePagedNumUrl( id );
11066		},
11067
11068		nextClick: function nextClick(e) {
11069			e.preventDefault(); 
11070			if(this.ajaxLoader.getData('paged') === this.ajaxLoader.getData('maxPages')) return;
11071			this.load(++this.lastId, $(e.currentTarget));
11072			this.updatePagedNumUrl( this.lastId );
11073		},
11074
11075		prevClick: function prevClick(e) {
11076			e.preventDefault(); 
11077			if(this.ajaxLoader.getData('paged') === 1) return;
11078			this.load(--this.lastId, $(e.currentTarget));
11079			this.updatePagedNumUrl( this.lastId );
11080		},
11081
11082		load: function load(id, $el) {
11083			this.lastId = id;
11084			this.ajaxLoader.setData({paged: id});
11085			this.ajaxLoader.load(this.unique);
11086			this.removeIndicator();
11087			MK.ui.loader.add($el);
11088		},
11089
11090		onLoad: function success(e, response) {
11091			if( typeof response !== 'undefined' && response.id === this.containerId) {
11092				this.updatePagination();
11093				this.lastId = this.ajaxLoader.getData('paged');
11094
11095				if(response.unique === this.unique) {
11096					this.removeIndicator();
11097					this.scrollPage();
11098			        this.$container.html(response.content);  
11099				}   
11100			}         
11101        },
11102
11103        updatePagination: function updatePagination() {
11104        	var self = this;
11105
11106        	// Hide / show arrows
11107        	var isFirst = (this.ajaxLoader.getData('paged') === 1);
11108        	var isLast = (this.ajaxLoader.getData('paged') === this.ajaxLoader.getData('maxPages'));
11109
11110        	if(isFirst) this.$prevLink.addClass('is-vis-hidden');
11111        	else this.$prevLink.removeClass('is-vis-hidden');
11112
11113        	if(isLast) this.$nextLink.addClass('is-vis-hidden');
11114        	else this.$nextLink.removeClass('is-vis-hidden');
11115
11116			// X of Y
11117			this.$current.html(this.ajaxLoader.getData('paged'));
11118			this.$maxPages.html(this.ajaxLoader.getData('maxPages'));
11119
11120			// Move overfloating items
11121			var displayItems = 10;
11122			var centerAt = displayItems / 2;
11123
11124			if(this.ajaxLoader.getData('maxPages') > displayItems) {
11125				this.$pageLinks.each(function(i) {
11126
11127					var id = self.lastId - centerAt;
11128						id = Math.max(id, 1);
11129						id = Math.min(id, self.ajaxLoader.getData('maxPages') - displayItems + 1);
11130						id = id + i;
11131
11132					$(this).html( id ).attr('data-page-id', id).show();
11133
11134					if(i === 0 && id > 1) $(this).html('...');
11135					if(i === displayItems - 1 && id < self.ajaxLoader.getData('maxPages')) $(this).html('...');
11136				});
11137			} else {
11138				this.$pageLinks.each(function(i) {
11139					var $link = $(this);
11140					var id = i + 1;
11141
11142					$link.html(id).attr('data-page-id', id);
11143
11144					if( self.ajaxLoader.getData('maxPages') === 1) {
11145						self.$pageLinks.hide();
11146					} else {
11147						if(i > self.ajaxLoader.getData('maxPages') - 1) $link.hide();
11148						else $link.show();						
11149					}
11150
11151				});
11152			}
11153
11154        	// Highlight current only
11155			this.$pageLinks.filter('[data-page-id="' + this.ajaxLoader.getData('paged') + '"]' ).addClass('current-page')
11156				 .siblings().removeClass('current-page');
11157
11158        },
11159
11160        scrollPage: function scrollPage() {
11161            var containerOffset = this.$container.offset().top;
11162            var offset = containerOffset - MK.val.offsetHeaderHeight( containerOffset ) - 20; 
11163            MK.utils.scrollTo( offset ); 
11164        },
11165
11166        removeIndicator: function removeIndicator() {
11167        	MK.ui.loader.remove('.js-pagination-page, .js-pagination-next, .js-pagination-prev');
11168        },
11169
11170		/**
11171		 * Set some actions when archive/category page is loaded. Actions list:
11172		 * - Select the correct paged ID on pagination list.
11173		 * - Set current paged ID on the label.
11174		 * - Add event listener onpopstate for handling prev/next button of Browser URL.
11175		 * - Set info for updatePagedNumUrl() about request comes from popstate.
11176		 *
11177		 * @since 5.9.8
11178		 */
11179		onInitLoad: function onInitLoad() {
11180			var initPagedID = this.$pagination.data( 'init-pagination' );
11181			if ( initPagedID && initPagedID > 1 ) {
11182				this.$current.html( initPagedID );
11183				this.$pageLinks.filter( '[data-page-id="' + initPagedID + '"]' ).addClass( 'current-page' ).siblings().removeClass( 'current-page' );
11184			}
11185
11186			// Run popstate only if it's supported by the browser.
11187			if ( 'onpopstate' in window ) {
11188				var thisPop = this;
11189				window.onpopstate = function( event ) {
11190					var id = 1;
11191
11192					// At start, state is always null. So, we should check it before processing.
11193					if ( typeof event.state === 'object' && event.state ) {
11194						var state = event.state;
11195
11196						// Set paged ID for updating page.
11197						if ( state.hasOwnProperty( 'MkPagination' ) ) {
11198							var currentState = state.MkPagination;
11199							if ( currentState.hasOwnProperty( 'paged' ) ) {
11200								id = parseFloat( currentState.paged );
11201							}
11202						}
11203					} else {
11204						id = parseFloat( thisPop.getURLPagedID() );
11205					}
11206
11207					// Tell updatePagedNumUrl() if request come from popstate.
11208					thisPop.popState = true;
11209					thisPop.$pageLinks.filter( '[data-page-id="' + id + '"]' ).trigger( 'click' );
11210				}
11211			}
11212		},
11213
11214		/**
11215		 * Update current pagination browser URL by adding/changing paged number. Only run if
11216		 * the browser support pushState and the request not coming from popstate.
11217		 *
11218		 * WordPress has some ways to set paged number:
11219		 * 1. page/[number], paged=[number] will be directed here.
11220		 * 2. page=[number]
11221		 * So, we should check which one the request is used here.
11222		 *
11223		 * @since 5.9.8
11224		 */
11225		updatePagedNumUrl: function updatePagedNumUrl( id ) {
11226			// Check pushState browser support and ignore if request come from popstate.
11227			if ( 'history' in window && 'pushState' in history && id && ! this.popState ) {
11228				var fullPage = this.pagePathname + this.pageSearch;
11229				var isQueryPage = false;
11230
11231				// Style 1 - /page/[number], as default value.
11232				var newPage = 'page/' + id + '/';
11233				var expPage = /page\/\d+\/?/;
11234				var result = this.pagePathname.match( /\/page\/\d+/ );
11235				var isPagedExist = ( result ) ? true : false;
11236
11237				// Style 2 - ?page=[number], only run if /page/ is not exist and URL query var exist.
11238				if ( ! isPagedExist && this.pageSearch ) {
11239					isQueryPage = this.pageSearch.match( /page\=\d+/ );
11240					if ( isQueryPage ) {
11241						newPage = 'page=' + id;
11242						expPage = /page\=\d+/;
11243					}
11244				}
11245
11246				// If page number is 1, remove paged number from URL.
11247				if ( id === 1 ) {
11248					newPage = '';
11249					if ( isQueryPage ) {
11250						expPage = ( this.pageSearch.match( /\&+/ ) ) ? /page\=\d+\&?/ : /\?page\=\d+\&?/;
11251					}
11252				}
11253
11254				// Set new pathname. Do replacement only if the new pathname contains paged number.
11255				var newURL = this.pagePathname + newPage + this.pageSearch;
11256				if ( fullPage.match( expPage ) ) {
11257					newURL = fullPage.replace( expPage, newPage );
11258				}
11259
11260				// Set history state and return popstate back to fal
11260se.
11261				var historyState = {
11262					MkPagination: {
11263						url: newURL,
11264						paged: id
11265					}
11266				}
11267				this.popState = false;
11268
11269				// Push new pathname to display/hide the paged number.
11270				window.history.pushState( historyState, null, newURL );
11271			}
11272			this.popState = false;
11273		},
11274
11275		/**
11276		 * Get current URL page ID. Notes:
11277		 * 1. page/[number], paged=[number] will be directed here.
11278		 * 2. page=[number]
11279		 *
11280		 * @return {integer} Current paged ID. Default 1.
11281		 */
11282		getURLPagedID: function getURLPagedID() {
11283			var pathname = window.location.pathname;
11284			var search = window.location.search;
11285			var pagedId = 1;
11286			var result = '';
11287			var isPagedExist = false;
11288
11289			// Search based on style 1.
11290			result = pathname.match( /\/page\/(\d+)/ );
11291			if ( result ) {
11292				isPagedExist = true;
11293				pagedId = ( result.hasOwnProperty( 1 ) ) ? result[1] : 1;
11294			}
11295
11296			// Search based on style 2.
11297			if ( ! isPagedExist && search ) {
11298				result = search.match( /page\=(\d+)/ );
11299				if ( result ) {
11300					isPagedExist = true;
11301					pagedId = ( result.hasOwnProperty( 1 ) ) ? result[1] : 1;
11302				}
11303			}
11304
11305			return pagedId;
11306		}
11307	};
11308
11309}(jQuery));
11310(function( $ ) {
11311	'use strict';
11312
11313	var val = MK.val,
11314		utils = MK.utils;
11315
11316	MK.component.Parallax = function( el ) {
11317		var self = this,
11318			$this = $( el ),
11319        	obj = $this[0],
11320			$window = $( window ),
11321		    container = document.getElementById( 'mk-theme-container' ),
11322			config = $this.data( 'parallax-config' ),
11323			$holder = $( config.holder ),
11324			headerHeight = null,
11325			offset = null,
11326			elHeight = null,
11327			ticking = false,
11328			isMobile = null;
11329
11330
11331		var clientRect = null;
11332
11333		var update = function() {
11334			// Clear styles to check for natural styles
11335			// then apply position and size
11336			obj.style.transform = null;
11337			obj.style.top = null;
11338			obj.style.bottom = null;
11339
11340			isMobile = MK.utils.isMobile();
11341
11342			if( isMobile ) {
11343        		$this.css( 'height', '' );
11344				return;
11345			}
11346
11347			clientRect = $this[ 0 ].getBoundingClientRect();
11348			offset = clientRect.top;
11349			elHeight = clientRect.height;
11350			headerHeight = val.offsetHeaderHeight( offset );
11351			offset = offset - headerHeight + val.scroll(); 
11352
11353			setPosition(); 
11354			setSize( ); 
11355		};
11356
11357
11358        var h = 0,
11359        	winH = 0,
11360        	proportion = 0,
11361        	height = 0;
11362
11363        // Position and background attachement should me moved to CSS but we repair it high specificity here as styles are not reliable currently
11364        var setSize = function() {
11365        	$this.css( 'height', '' );
11366        	winH = $window.height() - headerHeight;
11367        	h = obj.getBoundingClientRect().height; 
11368
11369        	if( config.speed <= 1 && config.speed > 0 ) {
11370        		if( offset === 0 ) {
11371	        		$this.css({
11372	        			backgroundAttachment: 'scroll',
11373	        			'will-change': 'transform'
11374	        		});
11375        		} else {
11376	        		$this.css({
11377						height : h + ( (winH - h) * config.speed ),
11378	        			backgroundAttachment: 'scroll',
11379	        			'will-change': 'transform' 
11380	        		}); 
11381	        	}
11382
11383        	} else if ( config.speed > 1 && h <= winH ) {
11384        		$this.css({
11385        			// good for full heights - 2 because it's viewable by 2 screen heights
11386        			height: ( winH  +  ( ( winH * config.speed ) - winH ) * 2 ),  
11387        			top: -( ( winH * config.speed ) - winH ),
11388        			backgroundAttachment: 'scroll',
11389        			'will-change': 'transform'
11390        		}); 
11391
11392        	} else if ( config.speed > 1 && h > winH ) {
11393        		proportion = h / winH;
11394        		height = ( winH  +  ( ( winH * config.speed ) - winH ) * (1 + proportion) );
11395 
11396        		$this.css({
11397        			height: height,
11398        			top: -( height - (winH * config.speed) ),
11399        			backgroundAttachment: 'scroll',
11400        			'will-change': 'transform'
11401        		}); 
11402
11403        	} else if ( config.speed < 0 && h >= winH ) {
11404        		height = h * (1  - config.speed);
11405        		$this.css({
11406					height: height + (height - h),
11407        			top: h - height,
11408        			backgroundAttachment: 'scroll',
11409        			'will-change': 'transform'
11410        		});   
11411
11412        	} else if ( config.speed < 0 && h < winH ) {
11413        		// candidate to change
11414        		var display = (winH + h) / winH;
11415        		height = h * -config.speed * display;
11416        		$this.css({
11417					height: h + (height * 2),
11418        			top: -height,
11419        			backgroundAttachment: 'scroll',
11420        			'will-change': 'transform'
11421        		});         		
11422        	}
11423        };
11424
11425
11426		var currentPoint = null,
11427			progressVal = null,
11428			startPoint = null,
11429			endPoint = null,
11430			$opacityLayer = config.opacity ? $this.find( config.opacity ) : null,
11431			scrollY = null;
11432
11433		var setPosition = function() {
11434			startPoint = offset - winH;
11435			endPoint = offset + elHeight + winH - headerHeight;
11436			scrollY = val.scroll();
11437
11438			if( scrollY < startPoint || scrollY > endPoint ) { 
11439				ticking = false;
11440				return; 
11441			}
11442
11443			currentPoint = (( -offset + scrollY ) * config.speed);
11444
11445            $this.css({
11446              	'-webkit-transform': 'translateY(' + currentPoint + 'px) translateZ(0)',
11447              	'-moz-transform': 'translateY(' + currentPoint + 'px) translateZ(0)',
11448              	'-ms-transform': 'translateY(' + currentPoint + 'px) translateZ(0)',
11449              	'-o-transform': 'translateY(' + currentPoint + 'px) translateZ(0)',
11450              	'transform': 'translateY(' + currentPoint + 'px) translateZ(0)'
11451            });  
11452
11453			ticking = false;
11454		};
11455
11456 
11457		var requestTick = function() {
11458			if( !ticking && !isMobile ) {
11459				ticking = true;
11460				window.requestAnimationFrame( setPosition );
11461			}
11462		};
11463
11464
11465		var init = function() { 
11466			// Disable scroll effects when smooth scroll is disabled
11467			if( !MK.utils.isSmoothScroll ) { return; }
11468
11469			update();
11470			setTimeout(update, 100);
11471			$window.on( 'load', update );
11472			$window.on( 'resize', update );
11473	        window.addResizeListener( container, update );
11474	        
11475			$window.on( 'scroll', requestTick );
11476		};
11477		
11478 
11479		return {
11480			init : init
11481		};
11482	};
11483
11484})( jQuery );
11485(function($) {
11486	'use strict';
11487
11488	MK.component.Preloader = function(el) {
11489		this.el = el;
11490	};
11491
11492	MK.component.Preloader.prototype = {
11493		init: function init() {
11494			this.cacheElements();
11495			this.bindEvents();
11496		},
11497
11498		cacheElements: function cacheElements() {
11499			this.$preloader = $(this.el);
11500		},
11501
11502		bindEvents: function bindEvents() {
11503			this.onLoad(); // all components inited on page load
11504		},
11505
11506		onLoad: function onLoad() {
11507			setTimeout(this.hidePreloader.bind(this), 300);
11508		},
11509
11510		hidePreloader: function hidePreloader() {
11511			this.$preloader.hide();
11512		}
11513	};
11514
11515}(jQuery));
11516
11517(function($) {
11518	'use strict';
11519
11520	// Image added for proportional scaling
11521	MK.ui.loader = {
11522		tpl : function() {
11523			return '<div class="mk-loading-indicator">' + 
11524						'<div class="mk-loading-indicator__inner">' +
11525							'<div class="mk-loading-indicator__icon"></div>' +
11526							'<img style="height:100%; width:auto;" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">' +
11527						'</div>' +
11528					'</div>';
11529		},
11530
11531		add : function(item) {
11532			$(item).append(this.tpl);
11533		},
11534
11535		remove : function(item) {
11536			if(item) $(item).find('.mk-loading-indicator').remove();
11537			else $('.mk-loading-indicator').remove();
11538		}
11539	};
11540
11541}(jQuery));
11542(function( $ ) {
11543	// IE / Edge fix for fixed positioned elements
11544	// MS clip path doesnt redraw properly so we expirience similar bug like with background attachement fixed on Chrome
11545	if (MK.utils.browser.name === 'Edge' || MK.utils.browser.name === 'IE') {
11546	 	var val = 1;
11547	 	var $edgeClipper = $('.mk-slider-slide'); // edge slider
11548	 	var $sectionClipper = $('.clipper-true'); // edge slider
11549	 	var $bgLayer = $('.background-layer'); // page section
11550
11551    	var onScroll = function onScroll() {
11552	    	val *= -1;
11553	    	if( $edgeClipper.length ) $edgeClipper.each( redraw );
11554	    	if( $sectionClipper.length ) $sectionClipper.each( redraw );
11555	    	if( $bgLayer.length ) $bgLayer.each( redraw );
11556    	};
11557
11558	 	var redraw = function redraw() {
11559	    	$(this).css('margin-top', val / 100);
11560	    };
11561
11562	    $(window).on("scroll", function () {	    	
11563	    	window.requestAnimationFrame(onScroll);
11564	    });
11565	 }
11566}(jQuery));
11567MK.component.ResponsiveImageSetter = (function ($) {
11568
11569	'use strict';
11570
11571	var module = {};
11572
11573
11574	/*---------------------------------------------------------------------------------*/
11575	/* Private Variables
11576	/*---------------------------------------------------------------------------------*/
11577
11578	var viewportClass = getViewportClass();
11579	var isRetina = window.devicePixelRatio >= 2;
11580
11581
11582	/*---------------------------------------------------------------------------------*/
11583	/* Private Methods
11584	/*---------------------------------------------------------------------------------*/
11585
11586	function run($imgs) {
11587		$imgs.filter( function() {
11588			return !this.hasAttribute("mk-img-src-setted");
11589		}).each(setSrcAttr);		
11590	}
11591
11592	function setSrcAttr() {
11593		var $img = $(this);
11594		var set = $img.data('mk-image-src-set');
11595		// Set src attribute to img link suitable for our logic. It will load the image.
11596		if(set['responsive'] === 'false' && isRetina && set['2x']) $img.attr('src', set['2x']);
11597		else if(set['responsive'] === 'false') $img.attr('src', set.default);
11598		else if(viewportClass === 1 && isRetina && set['2x']) $img.attr('src', set['2x']); // default x2 for retina
11599		else if(viewportClass === 0 && set.mobile) $img.attr('src', set.mobile);
11600		else $img.attr('src', set.default);
11601	}
11602
11603	function getViewportClass() {
11604		if(window.matchMedia('(max-width: 736px)').matches) return 0;
11605		else return 1; 
11606	}
11607
11608	function handleResize($imgs) {
11609		if(!$imgs.length) return;
11609 // Do not run if empty collection
11610		var currentViewportClass = getViewportClass();
11611		// We don't need to reload bigger images when screen size is decreasing as browser already performs resize operation.
11612		// Run update on for increasing screen size
11613		if( currentViewportClass > viewportClass) {
11614			viewportClass = currentViewportClass; // update for further reference
11615			run($imgs);
11616		}
11617	}
11618
11619
11620	/*---------------------------------------------------------------------------------*/
11621	/* Public Methods
11622	/*---------------------------------------------------------------------------------*/
11623
11624	module.init = function ($imgs) {
11625
11626		// Do not run if empty collection
11627		if(!$imgs.length) return; 
11628
11629		// Run and bind to events
11630		run($imgs);
11631	    $imgs.attr('mk-img-src-setted', '');
11632
11633	};
11634
11635	module.onResize = function ($imgs) {
11636		
11637		$(window).on( 'resize', MK.utils.throttle( 500, function() {
11638			handleResize($imgs);
11639		}));
11640		
11641
11642	};
11643
11644
11645	module.handleAjax = function () {
11646    	setTimeout(function ajaxDelayedCallback() { // give it a chance to insert content first
11647	    	var $newImgs = $('img[data-mk-image-src-set]').filter( function() {
11648				return !this.hasAttribute("mk-lazyload");
11649			});
11650			if(!$newImgs.length) return; 
11651	    	run($newImgs);
11652    	}, 100);
11653    }
11654
11655
11656	return module;
11657
11658}(jQuery));
11659
11660
11661jQuery(function($) {
11662
11663	var init = function init() {
11664		// Get All Responsive Images
11665		$allImages = $('img[data-mk-image-src-set]').filter(function(index) {
11666			var isNotPortfolioImage = !$(this).hasClass('portfolio-image'),
11667				isNotBlogImage = $(this).closest('.mk-blog-container').length == 0,
11668				isNotSwiperImage = !$(this).hasClass('swiper-slide-image'),
11669				isNotGalleryImage = !$(this).hasClass('mk-gallery-image');
11670			return isNotPortfolioImage && isNotBlogImage && isNotSwiperImage && isNotGalleryImage;
11671		});;
11672
11673		// Handle the resize
11674		MK.component.ResponsiveImageSetter.onResize($allImages);
11675
11676		MK.component.ResponsiveImageSetter.init($allImages);
11677
11678		MK.utils.eventManager.subscribe('ajaxLoaded', MK.component.ResponsiveImageSetter.handleAjax ); // ajax loops
11679		MK.utils.eventManager.subscribe('ajax-preview', MK.component.ResponsiveImageSetter.handleAjax ); // ajax portfolio
11680		MK.utils.eventManager.subscribe('quickViewOpen', MK.component.ResponsiveImageSetter.handleAjax ); 
11681	}
11682	init();
11683	$(window).on('vc_reload', init);
11684
11685});
11686
11687
11688
11689(function( $ ) {
11690	'use strict';
11691
11692	var utils = MK.utils;
11693	var val   = MK.val;
11694
11695	/**
11696	 * Keep track of top Level sections so we can easly skip to next one.
11697	 * We must be explicit about DOM level to nested sections.
11698	 * The list of sections is static. If you'd need to refreh it on ajax etc do it with pub/sub (not really needed now).
11699	 * We keep track for the same sections in Footer for mutating window location with '!loading' to prevent native anchor behaviour.
11700	 */
11701	var $topLevelSections = $('#theme-page > .vc_row, #theme-page > .mk-main-wrapper-holder, #theme-page > .mk-page-section');
11702
11703	$( document ).on( 'click', '.mk-skip-to-next', function() {
11704		var $this = $( this ),
11705			/**
11706			 * Static height of button + the space to the bottom of the container.
11707			 *
11708			 * @TODO Possible to calculate dynamically.
11709			 */
11710			btnHeight = $this.hasClass( 'edge-skip-slider' ) ? 150 : 76,
11711			offset = $this.offset().top + btnHeight,
11712			nextOffset = utils.nextHigherVal( utils.offsets( $topLevelSections ), [offset] );
11713
11714		utils.scrollTo( nextOffset - val.offsetHeaderHeight( nextOffset ) );
11715	});
11716
11717})( jQuery );
11718
11719(function($) {
11720	'use strict';
11721
11722	// 
11723	// Constructor
11724	// 
11725	// /////////////////////////////////////////////////////////
11726
11727	MK.ui.Slider = function( container, config ) { 
11728
11729		var defaults = {
11730				slide 				: '.mk-slider-slide',
11731	            nav 	     		: '.mk-slider-nav',
11732                effect              : 'roulete',
11733                ease 				: 'easeOutQuart', // should not be changed, remove
11734                slidesPerView       : 1,
11735                slidesToView        : 1,
11736                transitionTime      : 700,
11737                displayTime         : 3000,
11738                autoplay            : true,
11739                hasNav              : true,
11740                hasPagination       : true,
11741                paginationTpl 		: '<span></span>',
11742                paginationEl 		: '#pagination',
11743                draggable           : true,
11744                fluidHeight 		: false,
11745                pauseOnHover		: false,
11746                lazyload			: false,
11747                activeClass 		: 'is-active',
11748                edgeSlider	 		: false,
11749                spinnerTpl 			: '<div class="mk-slider-spinner-wrap"><div class="mk-slider-spinner-fallback"></div><svg class="mk-slider-spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="mk-slider-spinner-path" fill="none" stroke-width="4" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>',
11750                onInitialize 		: function() {},
11751                onAfterSlide 		: function( id ) {},
11752                onBeforeSlide 		: function( id ) {}
11753		};
11754
11755		this.state = {
11756			id 						: 0,
11757			moveForward 			: true,
11758			running   				: false,
11759            zIFlow					: null,
11760            stop 					: false,
11761		};
11762
11763		this.config = $.extend( defaults, config );
11764		this.container = container;
11765
11766		this.initPerView = this.config.slidesPerView;
11767
11768		// Timer holder
11769		this.activeTimer = null;
11770		this.autoplay = null;
11771		this.timer = null;
11772		this.timerRemaining = parseInt(this.config.displayTime);
11773
11774		// Boolean 'Em All, Making sure it's not string
11775		this.config.lazyload = JSON.parse(this.config.lazyload);
11776		this.config.edgeSlider = JSON.parse(this.config.edgeSlider);
11777
11778		// Image Loader Instance
11779		this.imageLoader = null;
11780
11781		// Add abort command to imagesLoaded, Placing it inside script makes it to work with different versions
11782		// of imagesLoaded if loaded by other Plugins
11783		imagesLoaded.prototype.abort = function() {
11784			this.progress = this.complete = function() { };
11785		};
11786	};
11787
11788	
11789
11790	// 
11791	// Shared methods
11792	// 
11793	// /////////////////////////////////////////////////////////
11794
11795	MK.ui.Slider.prototype = {
11796
11797		init : function() {
11798			this.setPerViewItems();
11799			this.cacheElements();
11800			this.getSlideSize();
11801			this.bindEvents();
11802            this.setSize();
11803			this.setPos();
11804
11805			// Hack for preparing 'prev' on first click if needed
11806			this.updateId( -1 );
11807			this.updateId( 1 );
11808
11809			this.val = this.dynamicVal();
11810			this.timeline = this.prepareTimeline( this.config.transitionTime );
11811
11812			this.timeline.build();
11813
11814			if( this.config.hasPagination ) { this.buildPagination(); }
11815			
11816			if( this.config.autoplay && document.hasFocus() ) { this.setTimer(); }
11817
11818			if( typeof this.config.onInitialize === 'function' ) {
11819				this.config.onInitialize( this.slides );
11820			}
11821
11822			if( this.config.fluidHeight === true ) {
11823				$( this.slides ).height( 'auto' );
11824				$( this.container ).css( 'transition', 'height ' + 200 + 'ms ease-out' );
11825				this.setHeight( 0 );
11826			}
11827
11828
11829			if( this.config.fluidHeight === 'toHighest' ) {
11830				this.setHeightToHighest();
11831			}
11832
11833			// Create timer per slide if required
11834			$(this.slides).each(this.createTimer);
11835
11836			// If it's Edge Slider and Lazy Load is enabled 
11837			if ( this.config.lazyload && this.config.edgeSlider ) {
11838
11839				// If It's not a Video Slide
11840				if ( $(this.slides[this.state.id]).find('video').length === 0 ) {
11841					// Set the first slide's BG image
11842					var $slideImg = $(this.slides[this.state.id]).children('[data-mk-img-set]');
11843					MK.component.BackgroundImageSetter.init( $slideImg );
11844				}
11845				$(this.config.spinnerTpl).prependTo( this.$slides );
11846
11847			} else {
11848
11849				// Set all slides's BG images
11850				MK.component.BackgroundImageSetter.init( $(this.slides).children('[data-mk-img-set]') );
11851
11852			}
11853			
11854
11855
11856		},
11857
11858
11859		cacheElements : function () {
11860			this.container = this.isNode( this.container ) ? this.container 
11861				: document.querySelectorAll( this.container )[0];
11862			this.slides = this.container.querySelectorAll( this.config.slide );
11863			this.$slides = $(this.slides);
11864
11865			if( this.config.hasNav ) { this.$nav = $( this.config.nav ); }
11866			if( this.config.hasPagination ) { this.$pagination = $( this.config.paginationEl ); }
11867		},
11868
11869
11870		bindEvents : function() {
11871			var $window = $( window );
11872
11873			if( this.config.slidesPerView > 1 ) { $window.on( 'resize', this.setPerViewItems.bind( this ) ); }
11874			if( this.config.hasNav ) { this.eventsNav(); }
11875			if( this.config.hasPagination ) { this.eventsPag(); }
11876			if( this.config.draggable ) { this.dragHandler(); }
11877			if( this.config.autoplay ) {
11878				$window.on( 'focus', this.windowActive.bind( this ) );
11879				$window.on( 'blur', this.windowInactive.bind( this ) );
11880			}
11881			if( this.config.pauseOnHover ) {
11882				$(this.container).on( 'mouseleave', this.setTimer.bind( this ) );
11883				$(this.container).on( 'mouseenter', this.unsetTimer.bind( this ) );
11884			}
11885			if( this.config.fluidHeight === 'toHighest' ) {
11886				$window.on( 'resize', this.setHeightToHighest.bind( this ) );
11887			}
11888		},
11889
11890
11891		setPerViewItems: function() {
11892			if(window.matchMedia( '(max-width: 500px)' ).matches) { this.config.slidesPerView = 1; }
11893			else if(window.matchMedia( '(max-width: 767px)' ).matches && this.initPerView >= 2 ) { this.config.slidesPerView = 2; }
11894			else if(window.matchMedia( '(max-width: 1024px)' ).matches && this.initPerView >= 3 ) { this.config.slidesPerView = 3; }
11895			else { this.config.slidesPerView = this.initPerView; }
11896			
11897        	if( typeof this.slides === 'undefined' ) return; 
11898			this.getSlideSize();
11899			this.setSize();
11900			this.setPos();
11901			this.timeline = this.prepareTimeline( this.config.transitionTime );
11902			this.timeline.build();
11903		},
11904
11905
11906		eventsNav : function() {
11907			this.$nav.on( 'click', 'a', this.handleNav.bind( this ) );
11908		},
11909
11910
11911		eventsPag : function() {
11912			this.$pagination.on( 'click', 'a', this.handlePagination.bind( this ) );
11913		},
11914
11915
11916		handleNav : function( e ) {
11917			e.preventDefault();
11918
11919			if( this.state.running ) { return; }
11920			this.state.running = true;
11921
11922			var $this = $( e.currentTarget ),
11923				moveForward = $this.data( 'direction' ) === 'next';
11924
11925
11926			if( this.config.autoplay ) { 
11927				this.unsetTimer();
11928				setTimeout( this.setTimer.bind( this ), this.config.transitionTime );
11929			}
11930
11931			this.state.moveForward = moveForward;
11932			this.timeline.build();
11933			this.timeline.play();
11934
11935			this.setActive( this.nextId( moveForward ? 1 : -1 ) );
11936			if( this.config.fluidHeight ) { this.setHeight( this.nextId( moveForward ? 1 : -1 ) ); }
11937		},
11938
11939
11940		handlePagination : function( e ) {
11941			e.preventDefault();
11942
11943			var $this = $( e.currentTarget ),
11944				id = $this.index();
11945
11946			this.goTo( id );
11947		},
11948
11949
11950		reset: function() {
11951			this.state.stop = true;
11952			this.state.id = 0;
11953			this.setPos();
11954			this.unsetTimer();
11955			this.setTimer();
11956		},
11957
11958
11959		goTo : function(id) {
11960			if( this.state.running ) { return; }
11961			this.state.running = true;
11962
11963			var lastId = this.state.id;
11964
11965			if( lastId === id ) {
11966				return;
11967			} else if( lastId < id ) {
11968				this.state.moveForward = true;
11969			} else {
11970				this.state.moveForward = false;
11971			}
11972
11973			if( this.config.autoplay ) { 
11974				this.unsetTimer();
11975				setTimeout( this.setTimer.bind( this ), this.config.transitionTime );
11976			}
11977
11978			this.timeline.build( Math.abs( lastId - id ) );
11979			this.timeline.play();
11980
11981			this.setActive( id );
11982			if( this.config.fluidHeight ) { this.setHeight( id ); } 
11983		},
11984
11985
11986		windowActive : function() {
11987			this.setTimer(false, true);
11988			$(this.container).removeClass('is-paused'); 
11989		},
11990
11991
11992		windowInactive : function() {
11993			this.unsetTimer();
11994			$(this.container).addClass('is-paused');
11995		},
11996
11997
11998		updateId : function( val ) {
11999			this.state.id = this.nextId(val);
12000		},
12001
12002		nextId : function( val ) {
12003			var len = this.slides.length,
12004				insertVal = this.state.id + val;
12005				insertVal = ( insertVal >= 0 ) ? insertVal : len + val;
12006				insertVal = ( insertVal >= len ) ? 0 : insertVal;
12007
12008			return insertVal;
12009		},
12010
12011
12012		setStyle : function( obj, style ) {
12013            var hasT = style.transform,
12014            	t = {
12015	                x       : ( hasT ) ? style.transform.translateX : null,
12016	                y       : ( hasT ) ? style.transform.translateY : null,
12017	                scale   : ( hasT ) ? style.transform.scale 		: null,
12018	                rotate  : ( hasT ) ? style.transform.rotate 	: null,
12019	                rotateX : ( hasT ) ? style.transform.rotateX 	: null,
12020	                rotateY : ( hasT ) ? style.transform.rotateY 	: null
12021           		},
12022				z  = 'translateZ(0)',
12023            	x  = (t.x) ?  'translateX(' + t.x + '%)' 		: 'translateX(0)',
12024                y  = (t.y) ?  'translateY(' + t.y + '%)' 		: 'translateY(0)',
12025                s  = (t.scale)  ?  'scale(' + t.scale + ')' 	: 'scale(1)',
12026                r  = (t.rotate) ? 'rotate(' + t.rotate + 'deg)' : 'rotate(0)',
12027                rX = (t.rotateX) ? 'rotateX(' + t.rotateX + 'deg)' : '',
12028                rY = (t.rotateY) ? 'rotateY(' + t.rotateY + 'deg)' : '',
12029
12030           		o = style.opacity,
12031           		h = style.height,
12032           		w = style.width;
12033
12034            var c = z + x + y  + s + r + rX + rY;
12035
12036            if( c.length ) {
12037	            obj.style.webkitTransform 	= c;
12038	            obj.style.msTransform 		= c;
12039	            obj.style.transform 		= c;
12040	        }
12041
12042            if( typeof o === 'number' ) { obj.style.opacity = o; }
12043            if( h ) { obj.style.height  = h + '%'; }
12044            if( w ) { obj.style.width   = w + '%'; }
12045		},
12046
12047
12048		setPos : function() {
12049        	if( typeof this.slides === 'undefined' ) return; 
12050		    var id 			= this.state.id,
12051		    	i 			= 0,
12052		    	len 		= this.slides.length,
12053		    	animation 	= this.animation[ this.config.effect ],
12054		    	axis 		= animation.axis,
12055				animNext	= animation.next,
12056				animActi 	= animation.active,
12057				animPrev 	= animation.prev,
12058                perView 	= this.config.slidesPerView,
12059                slideId 	= null,
12060                zIFlow 		= null,
12061                style 		= {};
12062
12063            style.transform = {};
12064
12065
12066            for( ; i < len; i += 1 ) {
12067                if(i < perView) {
12068                	// Position for visible slides. Apply active styles
12069                	style = animActi;
12070                    style.transform[ 'translate' + axis ] = i * 100;
12071                } else {
12072                	// Rest slides move after edge based on axis and moveForward. Apply Next / Prev styles
12073                	style = this.state.moveForward ? animNext : animPrev;
12074                    style.transform[ 'translate' + axis ] =  this.state.moveForward ? perView * 100 : -100;
12075                }
12076
12077                this.slides[ i ].style.zIndex = 0;
12078
12079                slideId = ( i + id ) % len;
12080                this.setStyle( this.slides[ slideId ], style );
12081            }
12082		},
12083
12084
12085        // When we're setting animation along Y axis we're going to set up height
12086        // otherwise width. It is shared amongst all slides
12087        setSize : function() {
12088        	if( typeof this.slides === 'undefined' ) return; 
12089        	var i = 0,
12090		    	len = this.slides.length,
12091		    	axis = this.animation[ this.config.effect ].axis,
12092                slideSize = this.slideSize,
12093        		style = {};
12094
12095            if( axis === 'Y' ) {
12096                style.height = slideSize[ axis ];
12097            } else {
12098                style.width = slideSize[ axis ];
12099            }
12100
12101            for( ; i < len; i += 1 ) {
12102                this.setStyle( this.slides[ i ], style );
12103            }
12104        },
12105
12106
12107        setHeight : function( id ) {
12108			var $slides = $( this.slides ),
12109				$activeSlide = $slides.eq( id );
12110
12111        	var currentHeight = $activeSlide.height();
12112        	$( this.container ).height( currentHeight ); 
12113        },
12114
12115
12116        setHeightToHighest : function() {
12117        	// this is becouse of alliginig woocommrece carousel. Too much DOM
12118        	// Refactor someday
12119			var $slides = $( this.slides ),
12120				height = 0;
12121
12122        	$slides.each(function() {
12123        		height = Math.max(height, $(this).find('> div').outerHeight());
12124        	});
12125
12126        	$( this.container ).height( height ); 
12127        },
12128
12129
12130        // Little utility inspired by GreenSock.
12131        // We export this to this.timeline on init. 
12132        prepareTimeline : function( time ) {
12133			var self 		= this,
12134				iteration 	= 0,
12135            	totalIter 	= time / (1000 / 60),
12136            	animLoop 	= [],
12137            	aL 			= 0, // animation length
12138            	loops 		= 1,
12139				ease 		= this.config.ease, 
12140				currentStyle, timeProg, 
12141				build, move, add, play, reverse, progress, kill;
12142
12143
12144			// Build constants, run them only once
12145			// take out possibly
12146			var len 		= this.slides.length,
12147				perView   	= this.config.slidesPerView,
12148				animation 	= this.animation[ this.config.effect ],
12149				animAxis 	= animation.axis,
12150				animNext	= animation.next,
12151				animActi 	= animation.active,
12152				animPrev 	= animation.prev,
12153				style 		= {},
12154				slideId 	= null,
12155				zIFlow 		= null;
12156
12157				style.transform = {};
12158
12159
12160			build = function( repeats ) {
12161				var currentEase = ease;
12162				loops = repeats || loops;
12163
12164				// console.log('build', loops);
12165
12166				if( !loops ) { return; }
12167				if( loops > 1 ) {
12168					currentEase = 'linearEase';
12169				}
12170
12171				// clean before running new build
12172				kill();
12173				// set new positions
12174				self.setPos();
12175
12176				var id = self.state.id,
12177					moveForward = self.state.moveForward,
12178					i = 0,
12179					axisMove = (moveForward) ? -100 : 100;
12180
12181				for( ; i <= perView; i += 1 ) {
12182					slideId = ( (moveForward) ? i + id : i + id - 1 ) % len;
12183					slideId = ( slideId < 0 ) ? len + slideId : slideId;
12184
12185					if( i === 0 ) {
12186						style = moveForward ? animPrev : animActi;
12187					} else if( i === perView ) {
12188						style = moveForward ? animActi : animNext;
12189					} else {
12190						style = animActi;
12191	            	}
12192
12193               	 	zIFlow = (self.state.moveForward) ? animNext.zIndex : animPrev.zIndex; 
12194	                if( zIFlow ) { 
12195	                	// console.log( zIFlow );
12196	                	self.slides[ slideId ].style.zIndex = (zIFlow === '+') ? i + 1 : len - i;
12197	                }
12198
12199					style.transform[ 'translate' + animAxis ] = axisMove;
12200	            	add( self.slides[ slideId ], style, currentEase );
12201				}
12202			};
12203
12204			add = function( slide, toStyles, ease ) {
12205				if( typeof slide === 'undefined' ) {
12206					throw 'Add at least one slide';
12207				}
12208
12209	            var fromStyles = slide.style,
12210					style = self.refStyle( toStyles, fromStyles );
12211
12212				animLoop.push( [slide, style, ease] );
12213				aL += 1;
12214			};
12215
12216			move = function( startProg, mode ) {
12217				if (isTest) return;
12218				var currentTotalIter = totalIter;
12219
12220				if( loops > 1 ) {
12221				 	currentTotalIter = totalIter / 5;
12222				}
12223
12224				if( !self.state.running ) { self.state.running = true; }
12225
12226				if( startProg ) {
12227					// update iteration val to cached outside var
12228					// ceil to handle properly play after mouse up / touch end
12229					iteration = Math.ceil(startProg * currentTotalIter);
12230				}
12231				
12232				timeProg = iteration / currentTotalIter;
12233				progress( timeProg );
12234
12235				// Break loop
12236				if( iteration >= currentTotalIter && mode === 'play' || 
12237					iteration <= 0 && mode === 'reverse' ) { 
12238
12239					self.state.running = false;
12240					iteration = 0;
12241					kill();
12242	            	self.updateId( self.state.moveForward ? 1 : -1 );
12243					// If we're creating multiple animation loop we trigger outside only first pass to start all game.
12244					// the rest are triggered as callback
12245					loops -= 1;
12246					if( loops > 0 ) {
12247						build();
12248						play();
12249					}
12250
12251					// if we run all loops reset back the default value
12252					if( !loops ) {
12253						loops = 1;
12254						self.timerRemaining = parseInt(self.config.displayTime);
12255						self.config.onAfterSlide( self.state.id );
12256					}
12257
12258					return; 
12259				}
12260
12261				// Run in given mode
12262				if( mode === 'play') {
12263					iteration += 1;
12264				} else {
12265					iteration -= 1;
12266				}
12267
12268				requestAnimationFrame( function() {
12269					if(self.state.stop) return;
12270					move( 0, mode );
12271				});
12272			};
12273
12274			play = function( startProg ) {
12275
12276				var $nextSlide = $(self.slides[ self.nextId(self.state.moveForward ? 1 : -1) ] );
12277
12278				// If it's Edge Slider and Lazy Load is enabled and It's not a Video Slide
12279				if ( self.config.lazyload && self.config.edgeSlider ) {
12280
12281					// Set the next slide's BG Image
12282					var $slideImg = $nextSlide.find('[data-mk-img-set]');
12283					if ( $slideImg.length ) {
12284						MK.component.BackgroundImageSetter.init( $slideImg );
12285					}
12286
12287				}
12288
12289				self.config.onBeforeSlide( self.nextId(self.state.moveForward ? 1 : -1) );
12290				var start = startProg || 0;
12291				iteration = 0;
12292				self.state.stop = false;
12293				move( start, 'play' );
12294
12295			};
12296
12297			reverse = function( startProg ) {
12298				var start = startProg || 1;
12299				move( start, 'reverse' );
12300			};
12301
12302			progress = function( progVal ) {
12303            	var aI = 0, 
12304            		currentStyle;
12305
12306				for( aI; aI < aL; aI++ ) {
12307					if( progVal !== 1 && progVal !== 0 ) {
12308						currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], animLoop[ aI ][ 2 ] );
12309					} else if( progVal === 1) {
12310						currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], 'linearEase' );
12311					} else if ( progVal === 0 ) {
12312						currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], 'linearEase' );
12313					} 
12314					self.setStyle( animLoop[ aI ][ 0 ], currentStyle );
12315				}
12316			};
12317
12318			// Clear previous loop
12319			kill = function() {
12320				animLoop = [];
12321            	aL = 0;
12322			};
12323
12324
12325			return {
12326				build 		: build,
12327				add 		: add,
12328				play 		: play,
12329				reverse 	: reverse,
12330				progress 	: progress
12331			};
12332		},
12333
12334
12335		// Build reference styles.
12336		// Return object with array containig initial style and change of its value
12337		// as required for easing functions
12338		refStyle : function( toStyles, fromStyles ) {
12339			var axis = this.animation[ this.config.effect ].axis,
12340            	style = {},
12341				initVal, changeVal, endVal, dynamicEnd, styleProp, transProp, transform;
12342
12343			for( styleProp in toStyles ) {
12344
12345				if( styleProp === 'transform' ) {
12346					transform = this.getTransforms( fromStyles );
12347					style.transform = {};
12348
12349					for( transProp in toStyles.transform ) {
12350						// don't care about z
12351						if( transProp === 'translateZ' ) { continue; }
12352
12353						initVal = transform[ transProp ] || 0; // if it is undefined it means it's 0
12354						dynamicEnd = ( transProp === 'translate' + axis ) ? initVal : 0;
12355						endVal  = toStyles.transform[ transProp ] + dynamicEnd; // it is dynamic, based on slide position in current set
12356						changeVal = endVal - initVal;
12357						style.transform[ transProp ] = [ initVal, changeVal ];
12358					}
12359				} else if( styleProp === 'zIndex' ) {
12360					// console.log( 'z' );
12361					continue;
12362				} else {
12363					initVal = parseFloat( fromStyles[ styleProp ] ) || 0; // if it is undefined it means it's 0
12364					endVal  = toStyles[ styleProp ];
12365					changeVal = endVal - initVal;
12366					style[ styleProp ] =  [ initVal, changeVal ];
12367				}
12368			}
12369
12370			return style;
12371		},
12372
12373
12374		currentStyle : function( progress, style, ease ) {
12375			var self = this,
12376				currentStyle = {},
12377            	currentVals, styleProp, transProp, prog;
12378
12379			// Redo same loop but construct currentStyle object out of cached values
12380			for( styleProp in style ) {
12381
12382				if( styleProp === 'transform' ) {
12383					currentStyle.transform = {};
12384
12385					for( transProp in style.transform ) {
12386						// remove this line. double check first if needed by logging
12387						if( transProp === 'translateZ' ) { continue; }
12388
12389						currentVals = style.transform[ transProp ];
12390						currentStyle.transform[ transProp ] = 
12391							// (currentIteration, startValue, changeInValue, totalIterations)
12392								self.ease[ ease ]( progress, currentVals[ 0 ], currentVals[ 1 ], 1 );
12393					}
12394				} else {
12395					currentVals = style[ styleProp ];
12396					currentStyle[ styleProp ] = 
12397						self.ease[ ease ]( progress, currentVals[ 0 ], currentVals[ 1 ], 1 );
12398				}
12399			}
12400
12401			return currentStyle;
12402		},
12403
12404
12405		setActive : function( id ) {
12406			var $slides = $( this.slides ),
12407				className = this.config.activeClass;
12408
12409			$slides.removeClass( className );
12410
12411			if( this.config.hasPagination ) {
12412				var $pagination = this.$pagination.find( 'a' );
12413				$pagination.removeClass( className );
12414				$pagination.eq( id ).addClass( className );
12415			}
12416
12417			if( this.activeTimer ) {
12418				clearTimeout( this.activeTimer );
12419				if ( this.imageLoader ) {
12420					this.imageLoader.abort();
12421				}
12422			} 
12423			
12424
12425			var self = this;
12426
12427			this.activeTimer = setTimeout( function() {
12428
12429				var $currentSlide = $slides.eq( id );
12430
12431				if ( self.config.lazyload && self.config.edgeSlider ) {  // If it's Edge Slider and Lazy Load is enabled
12432
12433					if ( $currentSlide.find('.mk-section-video').length && $currentSlide.children('.mk-video-section-touch').length ) {  // If it's a Video Slide and has a Preview image
12434						
12435						var imgSet = $currentSlide.children('.mk-video-section-touch').data('mk-img-set');
12436						var exactImg = MK.component.BackgroundImageSetter.getImage( imgSet );
12437						var $bgImage = $('<img>').attr('src', exactImg );
12438
12439						self.imageLoader = imagesLoaded( $bgImage[0], function( instance ) {
12440							$currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden');
12441							setTimeout( function() {
12442						 		$currentSlide.children('.mk-slider-spinner-wrap').hide();
12443						 	}, 200);
12444							$currentSlide.addClass( className );
12445					 	});
12446
12447					} else if ( $currentSlide.find('.mk-section-video').length && $currentSlide.children('.mk-video-section-touch').length === 0 ) { // If it's a Video Slide and has NOT a Preview image
12448
12449						$currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden');
12450						setTimeout( function() {
12451					 		$currentSlide.children('.mk-slider-spinner-wrap').hide();
12452					 	}, 200);
12453						$currentSlide.addClass( className );
12454						
12455					} else {  // If it's a Image Slide
12456
12457						if ( $currentSlide.children('[data-mk-img-set]').length ) {
12458							// Get the matching Image URL to start lazy loading
12459							var imgSet = $currentSlide.children('[data-mk-img-set]').data('mk-img-set');
12460							var exactImg = MK.component.BackgroundImageSetter.getImage( imgSet );
12461							var $bgImage = $('<img>').attr('src', exactImg );
12462
12463							// Prevent counting time on slide until the image loads
12464							self.unsetTimer();
12465							self.imageLoader = imagesLoaded( $bgImage[0], function( instance ) {
12466								// Hide spinner, Continue counting time on slide and show the content
12467							 	$currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden');
12468							 	setTimeout( function() {
12469							 		$currentSlide.children('.mk-slider-spinner-wrap').hide();
12470							 	}, 200);
12471								self.setTimer(false, false, $currentSlide.data('timer') || Number(self.config.displayTime) );
12472								$currentSlide.addClass( className );
12473							});
12474						} else {
12475							$currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden');
12476						 	setTimeout( function() {
12477						 		$currentSlide.children('.mk-slider-spinner-wrap').hide();
12478						 	}, 200);
12479							self.setTimer(false, false, $currentSlide.data('timer') || Number(self.config.displayTime) );
12480							$currentSlide.addClass( className );
12481						}
12482
12483					}
12484
12485				} else {
12486
12487					$currentSlide.addClass( className );
12488
12489				}
12490				
12491				
12492			}, this.config.transitionTime );
12493		},
12494
12495		createTimer : function() {
12496
12497			var $slide = $(this),
12498				video = $slide.find('video').get(0);
12499
12500			if(video) {
12501				// A hacky but reliable way to ge the video duration
12502				var interval = setInterval( function() {
12503					// If the metadata is ready
12504					if ( video.readyState > 0 ) {
12505						$slide.data('timer', (video.duration * 1000));
12506						$slide.attr('data-timer', (video.duration * 1000));
12507						clearInterval(interval);
12508					}
12509				}, 100);
12510			}
12511
12512		},
12513		
12514		setTimer : function( isFirst, isPaused, fixed_time ) {
12515			// check for custom timer
12516			var customTimer = this.$slides.eq(this.nextId(this.state.moveForward ? 1 : -1)).data('timer'),
12517				trans = parseInt( this.config.transitionTime ),
12518				interval = customTimer ? customTimer : parseInt( this.config.displayTime ),
12519				timer = interval + trans;
12520
12521			var self  = this,
12522				first = isFirst || true,
12523				fixed_time = fixed_time || 0,
12524				create, run;
12525
12526			this.timer = true;
12527			this.lastSetTimer = Date.now();
12528
12529			create = function() {	
12530
12531				if( self.autoplay ) { clearTimeout( self.autoplay ); }
12532				if( !self.timer ) {
12533					return;
12534				}
12535				self.state.moveForward = true;
12536				self.timeline.build();
12537				self.timeline.play();
12538				self.setActive( self.nextId( 1 ) );
12539				if( self.config.fluidHeight ) { self.setHeight( self.nextId( 1 ) ); }
12540				first = false;
12541				self.lastSetTimer = Date.now();
12542
12543				run();
12544			};
12545
12546			run = function(newInterval) {
12547				// check for custom timer
12548				customTimer = self.$slides.eq(self.nextId(self.state.moveForward ? 1 : -1)).data('timer');
12549				interval = customTimer ? customTimer : parseInt( self.config.displayTime );
12550				timer = interval + trans; // update timer with current val
12551
12552				var time = newInterval || timer;
12553				self.autoplay = setTimeout( create, time );
12554			};
12555
12556			if ( fixed_time ) {
12557				run( fixed_time );
12558			} else if (isPaused) {
12559				run( this.timerRemaining );
12560			} else {
12561				run();
12562			}
12563		},
12564
12565
12566		unsetTimer : function() {
12567			this.timer = false;
12568			this.lastUnsetTimer = Date.now();
12569			this.timerRemaining -= this.lastUnsetTimer - this.lastSetTimer;
12570			if( this.autoplay ) { clearTimeout( this.autoplay ); }
12571		},
12572
12573
12574		buildPagination : function() {
12575			var i   = 0,
12576				len = this.slides.length,
12577				tpl = '';
12578
12579			for( ; i < len; i += 1 ) {
12580				tpl += '<a href="javascript:;">' + this.config.paginationTpl + '</a>';
12581			}
12582
12583			this.$pagination.html( tpl );
12584			this.setActive( 0 );
12585		},
12586
12587
12588		getSlideSize : function() {
12589			this.slideSize = {
12590                X: 100 / this.config.slidesPerView,
12591                Y: 100 / this.config.slidesPerView
12592            };
12593		},
12594
12595
12596		getTransforms : function( style ) {
12597			// console.log( style );
12598		    var transform = style.transform || style.webkitTransform || style.mozTransform,
12599		    	regex = /(\w+)\(([^)]*)\)/g,
12600				match,
12601				T = {};
12602
12603			if( typeof transform !== 'string' ) {
12604				throw 'Transform prop is not a string.';
12605			}
12606
12607		    if( !transform ) { return; }
12608	
12609			// Run regex assignment
12610			while( match = regex.exec( transform ) ) {
12611				T[ match[ 1 ] ] = parseFloat( match[ 2 ] );
12612			}
12613
12614		    return T;
12615		},
12616
12617		isNode : function( o ) {
12618			return (
12619		    	typeof Node === "object" ? o instanceof Node : 
12620		   			o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string"
12621		  	);
12622		},
12623
12624
12625		dragHandler : function() {
12626			var self = this,
12627				$container = $( this.container ),
12628				prevBuild = false, 
12629				nextBuild = false,
12630				dragging = false,
12631				buffor = 5, // helpful for decoupling with click events
12632				dragStart, dragMove, dragEnd, progress;
12633
12634			progress = function( moveX ) {
12635				return moveX / self.val.viewportW();
12636			};
12637
12638			dragStart = function( moveX, startX ) {
12639				// console.log( 'start', moveX, startX );
12640			};
12641
12642			dragMove = function( moveX ) {
12643				// console.log('move');
12644				if( self.state.running ) return;
12645
12646				// Don't need to check for existance here
12647
12648				if( moveX < -buffor ) {
12649
12650					if( !nextBuild ) {
12651						self.state.moveForward = true;
12652						self.timeline.build();
12653						nextBuild = true;
12654						prevBuild = false;
12655						self.unsetTimer();
12656					} else {
12657						// turn progress into positive val
12658						self.timeline.progress( -progress( moveX ) );
12659					}
12660					dragging = true;
12661				} else if( moveX > buffor ) {
12662
12663					if( !prevBuild ) {
12664						self.state.moveForward = false;
12665						self.timeline.build();
12666						prevBuild = true;
12667						nextBuild = false;
12668						self.unsetTimer();
12669					} else {
12670						self.timeline.progress( progress( moveX ) );
12671					}
12672					dragging = true;
12673				}
12674			};
12675
12676			dragEnd = function( moveX ) {
12677				if( dragging ) {
12678					var prog = progress( moveX ),
12679						absProg = prog < 0 ? -prog : prog;
12680
12681					if( absProg > 0.1 ) {
12682						self.timeline.play( absProg );
12683						self.setActive( self.nextId( prog < 0 ? 1 : -1 ) );
12684						if( self.config.fluidHeight ) { self.setHeight( self.nextId( prog < 0 ? 1 : -1 ) ); }
12685					} else {
12686						self.timeline.reverse( absProg );
12687						// eventually move this to reverse callbacks	
12688						if(prog < 0) {
12689							self.updateId( -1 );
12690						} else {
12691							self.updateId( 1 );
12692						}
12693					}
12694
12695					prevBuild = false;
12696					nextBuild = false;
12697					dragging = false;
12698					if( self.config.autoplay ) { self.setTimer( false ); }
12699				}
12700			};
12701
12702			this.drag( $container, dragStart, dragMove, dragEnd );
12703		},
12704
12705
12706		drag : function( $el, startFn, moveFn, stopFn ) {
12707
12708		    var touchX, touchY, movX, movY, go, evt,
12709		   		prevent, start, move, stop;
12710
12711		    prevent = function( e ) {
12712		        e.preventDefault();
12713		    };
12714
12715		    start = function( e ) {
12716		        // $el.on("touchmove", prevent);
12717		        $el.on("mousemove", prevent);
12718		        $el.on("touchmove", move);
12719		        $el.on("mousemove", move);
12720
12721		        evt = (e.type === 'touchstart') ? e.originalEvent.touches[0] : e;
12722		        touchX = evt.pageX;
12723
12724		        if(typeof startFn === 'function') {
12725		        	startFn(movX, touchX);
12726		        }
12727		    };
12728
12729		    move = function( e ) {
12730		        evt = (e.type === 'touchmove') ? e.originalEvent.touches[0] : e;
12731		        movX = evt.pageX - touchX;
12732
12733	        	if(typeof moveFn === 'function') {
12734		        	moveFn(movX);
12735		        }
12736		    };
12737
12738		    stop = function( e ) {
12739		        // $el.off("touchmove", prevent);
12740		        $el.off("mousemove", prevent);
12741		        $el.off("touchmove", move);
12742		        $el.off("mousemove", move);
12743
12744		    	if(typeof stopFn === 'function') {
12745		        	stopFn(movX);
12746		        }
12747		    };
12748
12749		    $el.on("touchstart", start);
12750		    $el.on("mousedown", start);
12751		    $el.on("touchend", stop);
12752		    $el.on("touchleave", stop);
12753		    $el.on("touchcancel", stop);
12754		    $el.on("mouseup", stop);
12755		    $el.on("mouseleave", stop);
12756		},
12757
12758
12759		dynamicVal : function() {
12760			var $window = $( window ),
12761				update, 
12762				getViewportW, viewportW;
12763
12764			update = function() {
12765 				viewportW = $window.width();
12766			};
12767
12768			getViewportW = function() {
12769				return viewportW;
12770			};
12771
12772			update();
12773			$window.on( 'load', update );
12774			$window.on( 'resize', update );
12775
12776			return {
12777				viewportW : getViewportW
12778			};
12779		}
12780	};
12781
12782
12783
12784	// 
12785	// Set of default animations
12786	// 
12787	// /////////////////////////////////////////////////////////
12788
12789	MK.ui.Slider.prototype.animation = {
12790
12791        slide : {
12792        	axis : 'X', 
12793            next : { transform: {} },
12794            active : { transform: {} },
12795            prev : { transform: {} }
12796        },
12797
12798        vertical_slide : {
12799        	axis : 'Y',
12800            next : { transform: {} },
12801            active : { transform: {} },
12802            prev : { transform: {} }
12803        },
12804
12805        perspective_flip : {
12806        	axis : 'Y',
12807            next : { 
12808            	transform: {
12809            		rotateX : 80
12810            	} 
12811            },
12812            active : { 
12813            	transform: {
12814            		rotateX : 0
12815            	} 
12816            },
12817            prev : { 
12818            	transform: {
12819            		rotateX : 0
12820            	} 
12821            }
12822        },
12823
12824        zoom : {
12825			axis : 'Z',
12826            next: {
12827                opacity	: 0,
12828                transform : {
12829	                scale : 0.9
12830	            }
12831            },
12832            active: {
12833                opacity	: 1,
12834                transform : {
12835	                scale : 1
12836	            }
12837            },
12838            prev: {
12839                opacity	: 0,
12840                transform : {
12841	                scale : 1.1
12842	            }
12843            }
12844        },
12845
12846        fade : {
12847			axis : 'Z',
12848            next: {
12849                opacity	: 0,
12850                transform : {}
12851            },
12852            active: {
12853                opacity	: 1,
12854                transform : {}
12855            },
12856            prev: {
12857                opacity	: 0,
12858                transform : {}
12859            }
12860        },
12861
12862        kenburned : {
12863			axis : 'Z',
12864            next: {
12865                opacity	: 0,
12866                transform : {}
12867            },
12868            active: {
12869                opacity	: 1,
12870                transform : {}
12871            },
12872            prev: {
12873                opacity	: 0,
12874                transform : {}
12875            }
12876        },
12877
12878        zoom_out : {
12879			axis : 'Z',
12880            next: {
12881				zIndex : '+',
12882                opacity	: 1,
12883                transform : {
12884	                translateY : 100,
12885	                scale : 1
12886	            }
12887            },
12888            active: {
12889                opacity	: 1,
12890                transform : {
12891	                translateY : 0,
12892	                scale : 1
12893	            }
12894            },
12895            prev: {
12896				zIndex : '+',
12897                opacity	: 0,
12898                transform : {
12899	                translateY : 0,
12900	                scale : 0.5
12901	            }
12902            }
12903        },
12904
12905        // Problem with Z-Flow
12906        horizontal_curtain : {
12907			axis : 'Z',
12908            next: {
12909				zIndex : '+',
12910                transform : {
12911	                translateX : 100,
12912	            }
12913            },
12914            active: {
12915                transform : {
12916	                translateX : 0,
12917	            }
12918            },
12919            prev: {
12920				zIndex : '+',
12921                transform : {
12922	                translateX : -70,
12923	            }
12924            }
12925        },
12926
12927		roulete : {
12928			axis : 'X',
12929            next: {
12930                opacity	: 0.5,
12931                transform : {
12932	                scale : 0.5,
12933	                rotate : 10,
12934	                translateY : 20
12935	            }
12936            },
12937            active: {
12938                opacity	: 1,
12939                transform : {
12940	                scale : 1,
12941	                rotate : 0,
12942	                translateY : 0
12943	            }
12944            },
12945            prev: {
12946                opacity	: 0.3,
12947                transform : {
12948	                scale : 0.5,
12949	                rotate : -10,
12950	                translateY : 20
12951	            }
12952            }
12953		}
12954	};
12955
12956
12957
12958	// 
12959	// Penner's easing library
12960	// 
12961	// /////////////////////////////////////////////////////////
12962
12963	MK.ui.Slider.prototype.ease = {
12964		/*
12965		 *
12966		 * TERMS OF USE - EASING EQUATIONS
12967		 * 
12968		 * Open source under the BSD License. 
12969		 * 
12970		 * Copyright © 2001 Robert Penner
12971		 * All rights reserved.
12972		 * 
12973		 * Redistribution and use in source and binary forms, with or without modification, 
12974		 * are permitted provided that the following conditions are met:
12975		 * 
12976		 * Redistributions of source code must retain the above copyright notice, this list of 
12977		 * conditions and the following disclaimer.
12978		 * Redistributions in binary form must reproduce the above copyright notice, this list 
12979		 * of conditions and the following disclaimer in the documentation and/or other materials 
12980		 * provided with the distribution.
12981		 * 
12982		 * Neither the name of the author nor the names of contributors may be used to endorse 
12983		 * or promote products derived from this software without specific prior written permission.
12984		 * 
12985		 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
12986		 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
12987		 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
12988		 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
12989		 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
12990		 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
12991		 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
12992		 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
12993		 * OF THE POSSIBILITY OF SUCH DAMAGE. 
12994		 *
12995		 */
12996		linearEase : function(currentIteration, startValue, changeInValue, totalIterations) {
12997			return changeInValue * currentIteration / totalIterations + startValue;
12998		},
12999
13000		easeInQuad : function(currentIteration, startValue, changeInValue, totalIterations) {
13001			return changeInValue * (currentIteration /= totalIterations) * currentIteration + startValue;
13002		},
13003
13004		easeOutQuad : function(currentIteration, startValue, changeInValue, totalIterations) {
13005			return -changeInValue * (currentIteration /= totalIterations) * (currentIteration - 2) + startValue;
13006		},
13007
13008		easeInOutQuad : function(currentIteration, startValue, changeInValue, totalIterations) {
13009			if ((currentIteration /= totalIterations / 2) < 1) {
13010				return changeInValue / 2 * currentIteration * currentIteration + startValue;
13011			}
13012			return -changeInValue / 2 * ((--currentIteration) * (currentIteration - 2) - 1) + startValue;
13013		},
13014
13015		easeInCubic : function(currentIteration, startValue, changeInValue, totalIterations) {
13016			return changeInValue * Math.pow(currentIteration / totalIterations, 3) + startValue;
13017		},
13018
13019		easeOutCubic : function(currentIteration, startValue, changeInValue, totalIterations) {
13020			return changeInValue * (Math.pow(currentIteration / totalIterations - 1, 3) + 1) + startValue;
13021		},
13022
13023		easeInOutCubic : function(currentIteration, startValue, changeInValue, totalIterations) {
13024			if ((currentIteration /= totalIterations / 2) < 1) {
13025				return changeInValue / 2 * Math.pow(currentIteration, 3) + startValue;
13026			}
13027			return changeInValue / 2 * (Math.pow(currentIteration - 2, 3) + 2) + startValue;
13028		},
13029
13030		easeInQuart : function(currentIteration, startValue, changeInValue, totalIterations) {
13031			return changeInValue * Math.pow (currentIteration / totalIterations, 4) + startValue;
13032		},
13033
13034		easeOutQuart : function(currentIteration, startValue, changeInValue, totalIterations) {
13035			return -changeInValue * (Math.pow(currentIteration / totalIterations - 1, 4) - 1) + startValue;
13036		},
13037
13038		easeInOutQuart : function(currentIteration, startValue, changeInValue, totalIterations) {
13039			if ((currentIteration /= totalIterations / 2) < 1) {
13040				return changeInValue / 2 * Math.pow(currentIteration, 4) + startValue;
13041			}
13042			return -changeInValue/2 * (Math.pow(currentIteration - 2, 4) - 2) + startValue;
13043		},
13044
13045		easeInQuint : function(currentIteration, startValue, changeInValue, totalIterations) {
13046			return changeInValue * Math.pow (currentIteration / totalIterations, 5) + startValue;
13047		},
13048
13049		easeOutQuint : function(currentIteration, startValue, changeInValue, totalIterations) {
13050			return changeInValue * (Math.pow(currentIteration / totalIterations - 1, 5) + 1) + startValue;
13051		},
13052
13053		easeInOutQuint : function(currentIteration, startValue, changeInValue, totalIterations) {
13054			if ((currentIteration /= totalIterations / 2) < 1) {
13055				return changeInValue / 2 * Math.pow(currentIteration, 5) + startValue;
13056			}
13057			return changeInValue / 2 * (Math.pow(currentIteration - 2, 5) + 2) + startValue;
13058		},
13059
13060		easeInSine : function(currentIteration, startValue, changeInValue, totalIterations) {
13061			return changeInValue * (1 - Math.cos(currentIteration / totalIterations * (Math.PI / 2))) + startValue;
13062		},
13063
13064		easeOutSine : function(currentIteration, startValue, changeInValue, totalIterations) {
13065			return changeInValue * Math.sin(currentIteration / totalIterations * (Math.PI / 2)) + startValue;
13066		},
13067
13068		easeInOutSine : function(currentIteration, startValue, changeInValue, totalIterations) {
13069			return changeInValue / 2 * (1 - Math.cos(Math.PI * currentIteration / totalIterations)) + startValue;
13070		},
13071
13072		easeInExpo : function(currentIteration, startValue, changeInValue, totalIterations) {
13073			return changeInValue * Math.pow(2, 10 * (currentIteration / totalIterations - 1)) + startValue;
13074		},
13075
13076		easeOutExpo : function(currentIteration, startValue, changeInValue, totalIterations) {
13077			return changeInValue * (-Math.pow(2, -10 * currentIteration / totalIterations) + 1) + startValue;
13078		},
13079
13080		easeInOutExpo : function(currentIteration, startValue, changeInValue, totalIterations) {
13081			if ((currentIteration /= totalIterations / 2) < 1) {
13082				return changeInValue / 2 * Math.pow(2, 10 * (currentIteration - 1)) + startValue;
13083			}
13084			return changeInValue / 2 * (-Math.pow(2, -10 * --currentIteration) + 2) + startValue;
13085		},
13086
13087		easeInCirc : function(currentIteration, startValue, changeInValue, totalIterations) {
13088			return changeInValue * (1 - Math.sqrt(1 - (currentIteration /= totalIterations) * currentIteration)) + startValue;
13089		},
13090
13091		easeOutCirc : function(currentIteration, startValue, changeInValue, totalIterations) {
13092			return changeInValue * Math.sqrt(1 - (currentIteration = currentIteration / totalIterations - 1) * currentIteration) + startValue;
13093		},
13094
13095		easeInOutCirc : function(currentIteration, startValue, changeInValue, totalIterations) {
13096			if ((currentIteration /= totalIterations / 2) < 1) {
13097				return changeInValue / 2 * (1 - Math.sqrt(1 - currentIteration * currentIteration)) + startValue;
13098			}
13099			return changeInValue / 2 * (Math.sqrt(1 - (currentIteration -= 2) * currentIteration) + 1) + startValue;
13100		}
13101	};
13102
13103})(jQuery);
13104/* Social Share */
13105/* -------------------------------------------------------------------- */
13106(function($) {
13107    'use strict';
13108
13109    MK.component.SocialShare = function( el ) {
13110        var networks = {
13111			twitter : 'http://twitter.com/intent/tweet?text={title} {url}',
13112			pinterest : 'http://pinterest.com/pin/create/button/?url={url}&media={image}&description={title}',
13113			facebook : 'https://www.facebook.com/sharer/sharer.php?u={url}',
13114			googleplus : 'https://plus.google.com/share?url={url}',
13115			linkedin : 'http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}&summary={desc}',
13116			digg : 'http://digg.com/submit?url={url}&title={title}',
13117			reddit : 'http://reddit.com/submit?url={url}&title={title}',
13118        };
13119
13120        this.networks = networks;
13121        this.el = el;
13122    };
13123
13124
13125	MK.component.SocialShare.prototype = {
13126
13127        init : function() {
13128            this.cacheElements();
13129            this.bindEvents();
13130        },
13131
13132        cacheElements : function() {
13133            this.$this  = $( this.el );
13134
13135
13136        },
13137
13138        bindEvents : function() {
13139			var thisObject = this;
13140			var tempClass = "";
13141			$.each(this.networks, function( key, value ) {
13142				  thisObject.$tempClass = $('.' + key + '-share');
13143				  thisObject.$tempClass.click(thisObject.openSharingDialog.bind(self, this, key));
13144
13145			});
13146        },
13147
13148        openSharingDialog : function(url, site, args) {
13149			var urlWrapper = url;
13150			var rx = new RegExp('\{[a-z]*\}','g'), res;
13151			var match = rx.exec(url);
13152			while (match != null) {
13153				var pureAttr = match[0].replace("{", "").replace("}" , "");
13154				var attValue = $(args.currentTarget).attr('data-' + pureAttr);
13155				if (attValue === undefined || attValue === null) {
13156					attValue = "";
13157				}
13158				attValue = attValue.replace('#', '%23'); // fix for twitter description
13159				urlWrapper = urlWrapper.replace(match, attValue);
13160				match = rx.exec(url);
13161			}
13162
13163			window.open(urlWrapper, site + "Window", "height=320,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
13164
13165        },
13166
13167
13168    };
13169
13170
13171	//////////////////////////////////////////
13172    //
13173    // Apply to:
13174    //
13175    // ///////////////////////////////////////
13176
13177    var $body = $('body');
13178
13179    if(!$body.length) return;
13180
13181    $body.each(function() {
13182        var socialShare = new MK.component.SocialShare(this);
13183			socialShare.init();
13184    });
13185
13186})(jQuery);
13187
13188
13189
13190//function mk_social_share() {
13191//
13192//  "use strict";
13193//
13194//  $('.twitter-share').on('click', function () {
13195//    var $url = $(this).attr('data-url'),
13196//      $title = $(this).attr('data-title');
13197//
13198//    window.open('http://twitter.com/intent/tweet?text=' + $title + ' ' + $url, "twitterWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
13199//    return false;
13200//  });
13201//
13202//  $('.pinterest-share').on('click', function () {
13203//    var $url = $(this).attr('data-url'),
13204//      $title = $(this).attr('data-title'),
13205//      $image = $(this).attr('data-image');
13206//    window.open('http://pinterest.com/pin/create/button/?url=' + $url + '&media=' + $image + '&description=' + $title, "twitterWindow", "height=320,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
13207//    return false;
13208//  });
13209//
13210//  $('.facebook-share').on('click', function () {
13211//    var $url = $(this).attr('data-url');
13212//    window.open('https://www.facebook.com/sharer/sharer.php?u=' + $url, "facebookWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
13213//    return false;
13214//  });
13215//
13216//  $('.googleplus-share').on('click', function () {
13217//    var $url = $(this).attr('data-url');
13218//    window.open('https://plus.google.com/share?url=' + $url, "googlePlusWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
13219//    return false;
13220//  });
13221//
13222//  $('.linkedin-share').on('click', function () {
13223//    var $url = $(this).attr('data-url'),
13224//      $title = $(this).attr('data-title'),
13225//      $desc = $(this).attr('data-desc');
13226//    window.open('http://www.linkedin.com/shareArticle?mini=true&url=' + $url + '&title=' + $title + '&summary=' + $desc, "linkedInWindow", "height=380,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0");
13227//    return false;
13228//  });
13229//}
13230
13231
13232
13233
13234(function($) {
13235	'use strict';
13236
13237	MK.component.Sortable = function(el) {
13238		this.el = el; 
13239	};
13240
13241	MK.component.Sortable.prototype = {
13242		init: function init() {
13243			this.cacheElements();
13244			this.bindEvents();
13245		},
13246
13247		cacheElements: function cacheElements() {
13248			this.unique = Date.now();
13249			this.$filter = $(this.el);
13250			this.config = this.$filter.data('sortable-config');
13251
13252			this.ajaxLoader = new MK.utils.ajaxLoader(this.config.container);
13253			this.ajaxLoader.init();
13254
13255			this.$container = $( this.config.container );
13256			this.$navItems = this.$filter.find('a');
13257			this.$filterItems = this.$container.find(this.config.item);
13258		},
13259
13260		bindEvents: function bindEvents() {
13261			this.$navItems.on('click', this.handleClick.bind(this));
13262			MK.utils.eventManager.subscribe('ajaxLoaded', this.onLoad.bind(this));
13263		},
13264
13265		handleClick: function handleClick(e) {
13266			e.preventDefault();
13267
13268			var $item = $(e.currentTarget);
13269			var term = $item.data('filter');
13270
13271			this.$navItems.removeClass('current');
13272			$item.addClass('current');
13273
13274			if(this.config.mode === 'ajax') this.inDB(term, $item);
13275	        else this.inPage(term);
13276		},
13277
13278		inDB: function inDB(term, $item) { 
13279			// Add load indicator only for long requests
13280			MK.ui.loader.remove(this.$filter);
13281			MK.ui.loader.add($item);
13282			
13283			// If mk-ajax-loaded-posts span exists and one of the filter is clicked,
13284			// clear post ids
13285			if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) {		
13286				this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts', '');
13287			}
13288
13289			this.ajaxLoader.setData({
13290				paged: 1,
13291				term: term
13292			});
13293            this.ajaxLoader.load(this.unique);
13294		},
13295
13296		inPage: function inPage(term) {
13297			var $filterItems = this.$container.find(this.config.item);
13298			$filterItems.removeClass('is-hidden'); // show all first
13299			// Replace all ', ' with ', .'. It's used to add '.' as class selector of each category.
13300			var className = term.replace( /, /g, ", ." );
13301			if(term !== '*') $filterItems.not( '.' + className ).addClass('is-hidden'); // hide filtered
13302			MK.utils.eventManager.publish('staticFilter');
13303		},
13304
13305		onLoad: function onLoad(e, response) {
13306			if(this.config.mode === 'static') {
13307				this.$navItems.removeClass('current').first().addClass('current');
13308			}
13309			if( typeof response !== 'undefined' &&  response.id === this.config.container) {
13310				MK.ui.loader.remove(this.$filter);
13311				if(response.unique === this.unique) {
13312		            this.$container.html(response.content);
13313					this.ajaxLoader.setData({paged: 1});
13314				}
13315			}
13316		}
13317	};
13318
13319})(jQuery);
13320(function($) {
13321    'use strict';
13322
13323    MK.component.Tabs = function( el ) {
13324        var defaults = {
13325            activeClass : 'is-active'
13326        };
13327
13328        this.config = defaults;
13329        this.el = el;
13330    };
13331
13332    MK.component.Tabs.prototype = {
13333
13334        init : function() {
13335            this.cacheElements();
13336            this.bindEvents();
13337        },
13338
13339        cacheElements : function() {
13340            this.$this  = $( this.el );
13341            this.$tabs  = this.$this.find( '.mk-tabs-tab' );
13342            this.$panes = this.$this.find( '.mk-tabs-pane' );
13343            this.currentId = 0;
13344        },
13345
13346        bindEvents : function() {
13347            var self = this;
13348
13349            this.$tabs.on( 'click', this.switchPane.bind( this ) );
13350        },
13351
13352        switchPane : function( evt ) {
13353            evt.preventDefault();
13354
13355            var clickedId = $( evt.currentTarget ).index();
13356
13357            this.hide( this.currentId );
13358            this.show( clickedId );
13359
13360            // Update current id
13361            this.currentId = clickedId;
13362
13363            // Notify rest of the app
13364            MK.utils.eventManager.publish('item-expanded');            
13365        },
13366
13367        show : function( id ) {
13368            this.$tabs.eq( id ).addClass( this.config.activeClass );
13369            this.$panes.eq( id ).addClass( this.config.activeClass );
13370        },
13371
13372        hide : function( id ) {
13373            this.$tabs.eq( id ).removeClass( this.config.activeClass );
13374            this.$panes.eq( id ).removeClass( this.config.activeClass );
13375        }
13376    };
13377
13378})(jQuery);
13379
13380
13381/* Tabs */
13382/* -------------------------------------------------------------------- */
13383
13384function mk_tabs() {
13385
13386  // "use strict";
13387
13388  // if ($.exists('.mk-tabs, .mk-news-tab, .mk-woo-tabs')) {
13389  //   $(".mk-tabs, .mk-news-tab, .mk-woo-tabs").tabs();
13390
13391  //    $('.mk-tabs').on('click', function () {
13392  //      $('.mk-theme-loop').isotope('layout');
13393  //    });
13394
13395  //   $('.mk-tabs.vertical-style').each(function () {
13396  //     $(this).find('.mk-tabs-pane').css('minHeight', $(this).find('.mk-tabs-tabs').height() - 1);
13397  //   });
13398
13399  // }
13400}
13401
13402function mk_tabs_responsive(){
13403  // $('.mk-tabs, .mk-news-tab').each(function () {
13404  //   $this = $(this);
13405  //   if ($this.hasClass('mobile-true')) {
13406  //     if (window.matchMedia('(max-width: 767px)').matches)
13407  //     {
13408  //         $this.tabs("destroy");
13409  //     } else {
13410  //       $this.tabs();
13411  //     }
13412  //   }
13413  // });
13414  
13415}
13416
13417
13418(function($) {
13419  'use strict';
13420
13421  $(document).on('click', function(e) {
13422    $('.mk-toggle-trigger').removeClass('mk-toggle-active');
13423  });
13424
13425  function toggle(e) {
13426      e.preventDefault();
13427      e.stopPropagation();
13428      var $this = $(e.currentTarget);
13429
13430      if (!$this.hasClass('mk-toggle-active')) {
13431
13432        $('.mk-box-to-trigger').fadeOut(200);
13433        $this.parent().find('.mk-box-to-trigger').fadeIn(250);
13434        $('.mk-toggle-trigger').removeClass('mk-toggle-active');
13435        $this.addClass('mk-toggle-active');
13436
13437      } else {
13438
13439        $('.mk-box-to-trigger').fadeOut(200);
13440        $this.removeClass('mk-toggle-active');
13441
13442      }
13443  }
13444
13445  function assignToggle() {
13446    // wait for ajax response propagation and insertion
13447    setTimeout(function() {
13448      $('.mk-toggle-trigger').off('click', toggle);
13449      $('.mk-toggle-trigger').on('click', toggle);
13450    }, 100);
13451  }
13452
13453  assignToggle();
13454  MK.utils.eventManager.subscribe('ajaxLoaded', assignToggle);
13455  MK.utils.eventManager.subscribe('ajax-preview', assignToggle);
13456
13457  $(window).on('vc_reload', function(){
13458    assignToggle();
13459    MK.utils.eventManager.subscribe('ajaxLoaded', assignToggle);
13460    MK.utils.eventManager.subscribe('ajax-preview', assignToggle);
13461  });
13462
13463}(jQuery));
13464(function($) {
13465	'use strict';
13466
13467	var $iframes = $('iframe');
13468
13469	$iframes.each(function() {
13470		var $iframe = $(this);
13471		var parent = $iframe.parent().get(0);
13472		var tagName = parent.tagName;
13473
13474		if(tagName === 'P') $iframe.wrap('<div class="mk-video-container"></div>');
13475	});
13476
13477}(jQuery));
13478(function( $ ) {
13479    'use strict';
13480
13481    if( MK.utils.isMobile() ) {
13482        $('.mk-animate-element').removeClass('mk-animate-element');
13483        return;
13484    }
13485
13486    var init = function init() {
13487        var $rootLevelEls = $('.js-master-row, .widget');
13488        $rootLevelEls.each( spyViewport );
13489        $rootLevelEls.each( function rootLevelEl() {
13490            var $animateEl = $(this).find( '.mk-animate-element' );
13491            $animateEl.each( spyViewport );
13492        });   
13493    };
13494
13495    var spyViewport = function spyViewport(i) {
13496        var self = this;
13497
13498        MK.utils.scrollSpy( this, {
13499            position  : 'bottom',
13500            threshold : 200,
13501            after     : function() {
13502                animate.call(self, i);
13503            }
13504        });
13505    };
13506
13507    var animate = function animate(i) {
13508        var $this = $(this);
13509
13510        setTimeout(function() {
13511            $this.addClass( 'mk-in-viewport' );
13512        }, 100 * i);
13513    };
13514
13515
13516    $(window).on('load vc_reload', init);
13517
13518}(jQuery));
13519function product_loop_add_cart() {
13520    var $body = $('body');
13521    $body.on('click', '.add_to_cart_button', function() {
13522        var icon = '<svg class="mk-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M437.011 74.99c-46.326-46.328-110.318-74.99-181.011-74.99-109.744 0-203.345 69.064-239.749 166.094l59.938 22.477c27.302-72.773 97.503-124.571 179.811-124.571 53.02 0 101.01 21.5 135.753 56.247l-71.753 71.753h192v-192l-74.989 74.99zm-181.011 373.01c-53.02 0-101.013-21.496-135.756-56.244l71.756-71.756h-192v192l74.997-74.997c46.323 46.331 110.309 74.997 181.003 74.997 109.745 0 203.346-69.064 239.75-166.094l-59.938-22.477c-27.302 72.773-97.503 124.571-179.812 124.571z"/></svg>';
13523        var $holder = $(this).parents('.product:eq(0)');
13524        var $i = $holder.find('.product-loading-icon');
13525        $holder.addClass('adding-to-cart').removeClass('added-to-cart');
13526        $i.html(icon);
13527    });
13528    $body.bind('added_to_cart', function() {
13529        var icon = '<svg class="mk-svg-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M432 64l-240 240-112-112-80 80 192 192 320-320z"/></svg>';
13530        var $holder = $('.adding-to-cart');
13531        var $i = $holder.find('.product-loading-icon');
13532        $holder.removeClass('adding-to-cart').addClass('added-to-cart');
13533        $i.html(icon);
13534    });
13535}
13536(function($) {
13537    'use strict';
13538
13539    /**
13540     * Entry point of application. Runs all components
13541     */
13542    $( window ).on( 'load', function() {
13543        MK.core.initAll( document );
13544        MK.utils.scrollToURLHash();
13545        // TODO move preloader to components and manage it state from within
13546        setTimeout( function() { 
13547            MK.ui.preloader.hide(); // site wide 
13548            $('.mk-preloader').hide(); // components
13549            $('body').removeClass('loading');
13550        }, 150 ); 
13551    });
13552
13553    /**
13554     * VC frontend editor. Init all components.
13555     */
13556    $( window ).on( 'vc_reload', function() {
13557        setTimeout(function(){ 
13558            MK.core.initAll( document ); 
13559        }, 100);
13560    });
13561
13562    /**
13563     * Assign global click handlers
13564     */
13565    $( document ).on( 'click', '.js-smooth-scroll, .js-main-nav a', smoothScrollToAnchor);
13566    $( '.side_dashboard_menu a' ).on( 'click', smoothScrollToAnchor);
13567
13568    function smoothScrollToAnchor( evt ) {
13569        var anchor = MK.utils.detectAnchor( this );
13570        var $this = $(evt.currentTarget);
13571        var loc = window.location;
13572        var currentPage = loc.origin + loc.pathname;
13573        var href = $this.attr( 'href' );
13574        var linkSplit = (href) ? href.split( '#' ) : '';
13575        var hrefPage  = linkSplit[0] ? linkSplit[0] : ''; 
13576        var hrefHash  = linkSplit[1] ? linkSplit[1] : '';
13577
13578        if( anchor.length ) {
13579            if(hrefPage === currentPage || hrefPage === '') evt.preventDefault();
13580            MK.utils.scrollToAnchor( anchor );
13581
13582        } else if( $this.attr( 'href' ) === '#' ) {
13583            evt.preventDefault();
13584        }
13585    }
13586    
13587}(jQuery));})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.