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 product_loop_add_cart(); 6810 // mk_social_share(); 6811 mk_portfolio_widget(); 6812 mk_contact_form(); 6813 mk_blog_carousel(); 6814 mk_header_searchform(); 6815 mk_click_events(); 6816 mk_text_typer(); 6817 mk_tab_slider_func(); 6818 6819 $(window).on('load', function() { 6820 mk_unfold_footer(); 6821 mk_tabs(); 6822 mk_accordion_toggles_tooltip(); 6823 mk_gallery(); 6824 mk_theatre_responsive_calculator(); 6825 mk_tabs_responsive(); 6826 mk_start_tour_resize(); 6827 mk_header_social_resize(); 6828 mk_page_section_social_video_bg(); 6829 loop_audio_init(); 6830 mk_one_page_scroller(); 6831 mkPositionSidebar(); 6832 6833 setTimeout(function() { 6834 /* 6835 Somehow the values are not correctly updated for the screens 6836 and we need to put setTimeout to fix the issue 6837 */ 6838 mk_mobile_tablet_responsive_calculator(); 6839 }, 300); 6840 6841 console.log("ready for rock"); 6842 }); 6843 6844 6845 var onDebouncedResize = function() { 6846 mk_theatre_responsive_calculator(); 6847 mk_mobile_tablet_responsive_calculator(); 6848 mk_tabs_responsive(); 6849 mk_accordion_toggles_tooltip(); 6850 mk_start_tour_resize(); 6851 mk_header_social_resize(); 6852 6853 setTimeout(function() { 6854 mk_unfold_footer(); 6855 }, 300); 6856 }; 6857 6858 var debounceResize = null; 6859 $(window).on("resize", function() { 6860 if( debounceResize !== null ) { clearTimeout( debounceResize ); } 6861 debounceResize = setTimeout( onDebouncedResize, 300 ); 6862 }); 6863 6864 var onDebouncedScroll = function() { 6865 mk_skill_meter(); 6866 //TODO: Ask to Bart how we can call javascript component 6867 //mk_charts(); 6868 mk_milestone(); 6869 }; 6870 6871 var debounceScroll = null; 6872 $(window).on("scroll", function() { 6873 if( debounceScroll !== null ) { clearTimeout( debounceScroll ); } 6874 debounceScroll = setTimeout( onDebouncedScroll, 100 ); 6875 }); 6876 6877 if (MK.utils.isMobile()) { 6878 $('body').addClass('no-transform'); 6879 } 6880 6881}); 6882 6883/* VC frontend editor */ 6884/* -------------------------------------------------------------------- */ 6885$(window).on("vc_reload",function () { 6886 mk_flexslider_init(); 6887 loop_audio_init(); 6888 mk_tab_slider_func();
6889 mk_event_countdown(); 6890 videoLoadState(); 6891 mk_page_section_social_video_bg(); 6892 mk_hover_events(); 6893 6894 setTimeout(function() { 6895 mkPositionSidebar(); 6896 }, 200); 6897}); 6898 6899// Replace this if new event for remove found. 6900$( document ).on( 'click', '.vc_control-btn-delete', function() { 6901 $( window ).trigger( 'vc_reload' ); 6902} ); 6903 6904$( document ).on( 'sortupdate', '.ui-sortable', function() { 6905 $( window ).trigger( 'vc_reload' ); 6906} ); 6907 6908/* Typer */ 6909/* -------------------------------------------------------------------- */ 6910function mk_text_typer() { 6911 6912 "use strict"; 6913 6914 $('[data-typer-targets]').each(function() { 6915 var that = this; 6916 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.typed.js' ], function() { 6917 var $this = $(that), 6918 $first_string = [$this.text()], 6919 $rest_strings = $this.attr('data-typer-targets').split(','), 6920 $strings = $first_string.concat($rest_strings); 6921 6922 $this.text(''); 6923 6924 $this.typed({ 6925 strings: $strings, 6926 typeSpeed: 30, // typing speed 6927 backDelay: 1200, // pause before backspacing 6928 loop: true, // loop on or off (true or false) 6929 loopCount: false, // number of loops, false = infinite 6930 }); 6931 }); 6932 }); 6933} 6934 6935 6936 6937/* Tab Slider */ 6938/* -------------------------------------------------------------------- */ 6939 6940function mk_tab_slider_func() { 6941 6942 "use strict"; 6943 6944 $('.mk-tab-slider').each(function() { 6945 var that = this; 6946 6947 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.swiper.js' ], function() { 6948 var $this = $(that), 6949 id = $this.data('id'), 6950 $autoplayTime = $this.data('autoplay'), 6951 $content = $('.mk-slider-content'); 6952 6953 var mk_tab_slider = $this.swiper({ 6954 wrapperClass: 'mk-tab-slider-wrapper', 6955 slideClass: 'mk-tab-slider-item', 6956 calculateHeight: true, 6957 speed: 500, 6958 autoplay: isTest ? false : $autoplayTime, 6959 onSlideChangeStart: function() { 6960 $('.mk-tab-slider-nav[data-id="' + id + '"]').find(".active").removeClass('active') 6961 $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").eq(mk_tab_slider.activeIndex).addClass('active') 6962 } 6963 }); 6964 6965 // Simple repaint for firefox issue (can't handle 100% height after plugin init) 6966 function repaintFirefox() { 6967 $content.css('display','block'); 6968 setTimeout(function() { 6969 mk_tab_slider.reInit(); 6970 $content.css('display','table'); 6971 },100); 6972 } 6973 6974 $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").first().addClass('active'); 6975 6976 $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").on('touchstart mousedown', function(e) { 6977 e.preventDefault() 6978 $('.mk-tab-slider-nav[data-id="' + id + '"]').find(".active").removeClass('active') 6979 $(this).addClass('active') 6980 mk_tab_slider.swipeTo($(this).index()) 6981 }); 6982 6983 $('.mk-tab-slider-nav[data-id="' + id + '"]').find("a").click(function(e) { 6984 e.preventDefault(); 6985 }); 6986 6987 repaintFirefox(); 6988 $(window).on('resize', repaintFirefox); 6989 }); 6990 6991 }); 6992 6993} 6994 6995 6996 6997/* Edge One Pager */ 6998/* -------------------------------------------------------------------- */ 6999function mk_one_page_scroller() { 7000 7001 "use strict"; 7002 7003 $('.mk-edge-one-pager').each(function() { 7004 var self = this; 7005 7006 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.fullpage.js' ], function() { 7007 7008 var $this = $(self), 7009 anchorArr = []; 7010 7011 $this.find('.section').each(function() { 7012 anchorArr.push($(this).attr('data-title')); 7013 }); 7014 7015 var scrollable = true; 7016 $this.find('.section').each(function() { 7017 var $section = $(this), 7018 $content = $section.find('.edge-slide-content'), 7019 sectionHeight = $section.height(),
7020 contentHeight = $content.innerHeight(); 7021 7022 if((contentHeight + 30) > $(window).height()) { 7023 scrollable = false; 7024 } 7025 }); 7026 7027 if(!scrollable){ 7028 $this.find('.section').each(function() { 7029 var $section = $(this); 7030 $section.addClass('active').css({ 7031 'padding-bottom': '50px' 7032 }); 7033 }); 7034 } 7035 7036 if(scrollable) { 7037 $this.fullpage({ 7038 verticalCentered: false, 7039 resize: true, 7040 slidesColor: ['#ccc', '#fff'], 7041 anchors: anchorArr, 7042 scrollingSpeed: 600, 7043 easing: 'easeInQuart', 7044 menu: false, 7045 navigation: true, 7046 navigationPosition: 'right', 7047 navigationTooltips: false, 7048 slidesNavigation: true, 7049 slidesNavPosition: 'bottom', 7050 loopBottom: false, 7051 loopTop: false, 7052 loopHorizontal: true, 7053 autoScrolling: true, 7054 scrollOverflow: false, 7055 css3: true, 7056 paddingTop: 0, 7057 paddingBottom: 0, 7058 normalScrollElements: '.mk-header, .mk-responsive-wrap', 7059 normalScrollElementTouchThreshold: 5, 7060 keyboardScrolling: true, 7061 touchSensitivity: 15, 7062 continuousVertical: false, 7063 animateAnchor: true, 7064 7065 onLeave: function(index, nextIndex, direction) { 7066 var currentSkin = $this.find('.one-pager-slide').eq(nextIndex - 1).attr('data-header-skin'); 7067 MK.utils.eventManager.publish( 'firstElSkinChange', currentSkin ); 7068 $('#fullPage-nav').removeClass('light-skin dark-skin').addClass(currentSkin + '-skin'); 7069 7070 }, 7071 afterRender: function() { 7072 7073 var $nav = $('#fullPage-nav'); 7074 7075 setTimeout(function() { 7076 var currentSkin = $this.find('.one-pager-slide').eq(0).attr('data-header-skin'); 7077 MK.utils.eventManager.publish( 'firstElSkinChange', currentSkin ); 7078 if($nav.length) $nav.removeClass('light-skin dark-skin').addClass(currentSkin + '-skin'); 7079 }, 300); 7080 7081 var $slide = $this.find('.section'), 7082 headerHeight = MK.val.offsetHeaderHeight(0), 7083 windowHeight = $(window).height(); 7084 7085 $slide.height(windowHeight - headerHeight); 7086 7087 if($nav.length) { 7088 $nav.css({ 7089 'top': 'calc(50% + ' + (headerHeight/2) + 'px)', 7090 'marginTop': 0 7091 }); 7092 7093 var style = $this.attr('data-pagination'); 7094 $nav.addClass('pagination-' + style); 7095 } 7096 7097 setTimeout(mk_one_pager_resposnive, 1000); 7098 }, 7099 afterResize: function() { 7100 var $slide = $this.find('.section'), 7101 headerHeight = MK.val.offsetHeaderHeight(0), 7102 windowHeight = $(window).height(); 7103 7104 $slide.height(windowHeight - headerHeight); 7105 7106 $('#fullPage-nav').css({ 7107 'top': 'calc(50% + ' + (headerHeight/2) + 'px)', 7108 'marginTop': 0 7109 }); 7110 7111 setTimeout(mk_one_pager_resposnive, 1000); 7112 console.log('Reposition pager content.'); 7113 }, 7114 }); 7115 } 7116 7117 // Linking to slides available for desktop and mobile scenarios 7118 function swipeTo(href, e) { 7119 href = '_' + href; // ensure a char before # 7120 if (!~href.indexOf('#')) return; 7121 var section = href.split('#')[1]; 7122 if (~anchorArr.indexOf(section)) { 7123 if (typeof e !== 'undefined') e.preventDefault(); 7124 if (scrollable) $.fn.fullpage.moveTo(section); 7125 else MK.utils.scrollToAnchor('[data-title="'+section+'"]'); 7126 } 7127 } 7128 7129 // onload 7130 var loc = window.location; 7131 if(loc.hash) swipeTo(loc.hash); 7132 7133 $(document).on('click', 'a', function(e) { 7134 var $link = $(e.currentTarget); 7135 swipeTo($link.attr('href'), e); 7136 }); 7137 }); 7138 }); 7139 7140 7141 7142} 7143 7144 7145function mk_one_pager_resposnive() { 7146 "use strict"; 7147 7148 $('.mk-edge-one-pager').each(function() { 7149 var $pager = $(this), 7150 headerHeight = MK.val.offsetHeaderHeight(0), 7151 windowHeight = $(window).height() - headerHeight; 7152 7153 $pager.find('.one-pager-slide').each(function() { 7154 var $slide = $(this), 7155 $content = $slide.find('.edge-slide-content'); 7156 7157 if ($slide.hasClass('left_center') || $slide.hasClass('center_center') || $slide.hasClass('right_center')) { 7158 var contentHeight = $content.height(), 7159 distanceFromTop = (windowHeight - contentHeight) / 2; 7160 7161 distanceFromTop = (distanceFromTop < 50) ? 50 + headerHeight : distanceFromTop; 7162 7163 $content.css('marginTop', distanceFromTop); 7164 } 7165 7166 if ($slide.hasClass('left_bottom') || $slide.hasClass('center_bottom') || $slide.hasClass('right_bottom')) { 7167 var distanceFromTop = windowHeight - $content.height() - 90; 7168 $content.css('marginTop', (distanceFromTop)); 7169 } 7170 }); 7171 7172 /** 7173 * Fix AM-2853 7174 * 7175 * @since 6.0.3 7176 * 7177 * At the init of Edge One Pager (EOP), EOP will render all image 7178 * background of each sections from top to bottom. In this case, 7179 * the page height will be more than screen height and the scroll 7180 * bar will appear. At the same time, the full width row will set 7181 * the container width into 100%. But, after all Slides are set up, 7182 * EOP height will be 100% of the screen height, so the scroll bar 7183 * will be disappeared. It's caused spacing issues on the left and 7184 * right side of the EOP container. To fix this, the row width 7185 * should be resized and row position should be readjusted. 7186 */ 7187 var $row = $pager.parents( '.vc_row.vc_row-fluid.mk-fullwidth-true' ); 7188 7189 // Run only if the Edge One Pager is wrapped inside full width row. 7190 if ( $row.length > 0 ) { 7191 // Set the wrapper and row width. 7192 var $wrapper = $( '.mk-main-wrapper-holder' ); 7193 var $grid = $row.children( '.mk-grid' ); 7194 var rowWidth = $row.width(); // Original width.
7195 var wrapperWidth = $wrapper.width(); // The new width. 7196 7197 // Run only if original width is smaller than the new width. 7198 if ( rowWidth >= wrapperWidth || $grid.length > 0 ) { 7199 return; 7200 } 7201 7202 // Get the content left offset. 7203 var $content = $wrapper.find( '.theme-content' ); 7204 var oriPos = $content.position(); 7205 var oriPadLeft = $content.css( 'padding-left' ); 7206 var oriLeft = parseInt( oriPos.left ) + parseInt( oriPadLeft ); 7207 7208 // Ensure the new width and left position is more than 0. 7209 if ( wrapperWidth <= 0 || oriLeft <= 0 ) { 7210 return; 7211 } 7212 7213 // Resize the width and left position of row full width. 7214 $row.css({ 7215 'width': wrapperWidth, 7216 'left': oriLeft * -1, 7217 }); 7218 } 7219 }); 7220} 7221 7222/* Image Gallery */ 7223/* -------------------------------------------------------------------- */ 7224 7225function mk_gallery() { 7226 7227 "use strict"; 7228 7229 $('.mk-gallery .mk-gallery-item.hover-overlay_layer .item-holder').each(function() { 7230 var itemHolder = $(this), 7231 galleryDesc = itemHolder.find('.gallery-desc'); 7232 7233 function updatePosition() { 7234 var parentHeight = itemHolder.outerHeight(), 7235 contentHeight = galleryDesc.innerHeight(); 7236 7237 var paddingVal = (parentHeight - contentHeight) / 2; 7238 galleryDesc.css({ 7239 'top': paddingVal, 7240 // 'padding-bottom': paddingVal 7241 }); 7242 7243 // console.log(parentHeight); 7244 // console.log(contentHeight); 7245 7246 7247 } 7248 updatePosition(); 7249 7250 $(window).on('resize', function() { 7251 setTimeout(function() { 7252 updatePosition(); 7253 }, 1000); 7254 }); 7255 }); 7256 // Execute hover state for mk gallery item 7257 if ($(window).width() <= 1024) { 7258 $('.mk-gallery .mk-gallery-item').on('click', function (e) { 7259 var clicks = $(this).data('clicks'); 7260 if (clicks) { 7261 // First click 7262 $(this).toggleClass('hover-state'); 7263 } else { 7264 // Second click 7265 $(this).toggleClass('hover-state'); 7266 } 7267 $(this).data("clicks", !clicks); 7268 }); 7269 } 7270} 7271 7272/* Theatre Slider Responsive Calculator */ 7273/* -------------------------------------------------------------------- */ 7274 7275function mk_theatre_responsive_calculator() { 7276 var $laptopContainer = $(".laptop-theatre-slider"); 7277 var $computerContainer = $(".desktop-theatre-slider"); 7278 $laptopContainer.each(function() { 7279 var $this = $(this), 7280 $window = $(window), 7281 $windowWidth = $window.outerWidth(), 7282 $windowHeight = $window.outerHeight(), 7283 $width = $this.outerWidth(), 7284 $height = $this.outerHeight(), 7285 $paddingTop = 38, 7286 $paddingRight = 143, 7287 $paddingBottom = 78, 7288 $paddingLeft = 143; 7289 7290 var $player = $this.find('.player-container'); 7291 7292 if ($windowWidth > $width) { 7293 $player.css({ 7294 'padding-left': parseInt(($width * $paddingLeft) / 1200), 7295 'padding-right': parseInt(($width * $paddingRight) / 1200), 7296 'padding-top': parseInt(($height * $paddingTop) / 690), 7297 'padding-bottom': parseInt(($height * $paddingBottom) / 690), 7298 }); 7299 } 7300 7301 }); 7302 7303 $computerContainer.each(function() { 7304 var $this = $(this), 7305 $window = $(window), 7306 $windowWidth = $window.outerWidth(), 7307 $windowHeight = $window.outerHeight(), 7308 $width = $this.outerWidth(), 7309 $height = $this.outerHeight(), 7310 $paddingTop = 60, 7311 $paddingRight = 52, 7312 $paddingBottom = 290, 7313 $paddingLeft = 49; 7314 7315 var $player = $this.find('.player-container'); 7316 7317 if ($windowWidth > $width) { 7318 $player.css({ 7319 'padding-left': parseInt(($width * $paddingLeft) / 1200), 7320 'padding-right': parseInt(($width * $paddingRight) / 1200), 7321 'padding-top': parseInt(($height * $paddingTop) / 969), 7322 'padding-bottom': parseInt(($height * $paddingBottom) / 969), 7323 }); 7324 } 7325 7326 }); 7327 7328} 7329 7330/* Mobile and Tablet Slideshow Responsive Calculator */ 7331/* -------------------------------------------------------------------- */ 7332function mk_mobile_tablet_responsive_calculator() { 7333 var $laptopSlideshow = $(".mk-laptop-slideshow-shortcode"); 7334 var $lcdSlideshow = $(".mk-lcd-slideshow"); 7335 7336 if ($.exists(".mk-laptop-slideshow-shortcode")) { 7337 $laptopSlideshow.each(function() { 7338 var $this = $(this), 7339 $window = $(window), 7340 $windowWidth = $window.outerWidth(), 7341 $windowHeight = $window.outerHeight(), 7342 $width = $this.outerWidth(), 7343 $height = $this.outerHeight(), 7344 $paddingTop = 28, 7345 $paddingRight = 102, 7346 $paddingBottom = 52, 7347 $paddingLeft = 102; 7348 7349 var $player = $this.find(".slideshow-container"); 7350 7351 $player.css({ 7352 "padding-left": parseInt(($width * $paddingLeft) / 836), 7353 "padding-right": parseInt(($width * $paddingRight) / 836), 7354 "padding-top": parseInt(($height * $paddingTop) / 481), 7355 "padding-bottom": parseInt(($height * $paddingBottom) / 481), 7356 }); 7357 7358 }); 7359 } 7360 7361 if ($.exists(".mk-lcd-slideshow")) {
7362 $lcdSlideshow.each(function() { 7363 var $this = $(this), 7364 $window = $(window), 7365 $windowWidth = $window.outerWidth(), 7366 $windowHeight = $window.outerHeight(), 7367 $width = $this.outerWidth(), 7368 $height = $this.outerHeight(), 7369 $paddingTop = 35, 7370 $paddingRight = 39, 7371 $paddingBottom = 213, 7372 $paddingLeft = 36; 7373 7374 var $player = $this.find(".slideshow-container"); 7375 $player.css({ 7376 "padding-left": parseInt(($width * $paddingLeft) / 886), 7377 "padding-right": parseInt(($width * $paddingRight) / 886), 7378 "padding-top": parseInt(($height * $paddingTop) / 713), 7379 "padding-bottom": parseInt(($height * $paddingBottom) / 713), 7380 }); 7381 }); 7382 } 7383} 7384 7385 7386/* Start a tour resize function */ 7387/* -------------------------------------------------------------------- */ 7388function mk_start_tour_resize() { 7389 7390 $('.mk-header-start-tour').each(function() { 7391 7392 var $windowWidth = $(document).width(), 7393 $this = $(this), 7394 $linkWidth = $this.width() + 15, 7395 $padding = ($windowWidth - mk_responsive_nav_width) / 2; 7396 7397 7398 7399 function updateStartTour(){ 7400 if($windowWidth < mk_responsive_nav_width){ 7401 $this.removeClass('hidden'); 7402 $this.addClass('show'); 7403 }else{ 7404 if($padding < $linkWidth){ 7405 $this.removeClass('show'); 7406 $this.addClass('hidden'); 7407 }else{ 7408 $this.removeClass('hidden'); 7409 $this.addClass('show'); 7410 } 7411 } 7412 } 7413 7414 setTimeout(function() { 7415 updateStartTour(); 7416 }, 300); 7417 }); 7418} 7419 7420/* Header social resize function */ 7421/* -------------------------------------------------------------------- */ 7422function mk_header_social_resize() { 7423 7424 $('.mk-header-social.header-section').each(function() { 7425 7426 var $windowWidth = $(document).width(), 7427 $this = $(this), 7428 $linkWidth = $this.width() + 15, 7429 $padding = ($windowWidth - mk_responsive_nav_width) / 2; 7430 7431 7432 7433 function updateStartTour(){ 7434 if($windowWidth < mk_responsive_nav_width){ 7435 $this.removeClass('hidden'); 7436 $this.addClass('show'); 7437 }else{ 7438 if($padding < $linkWidth){ 7439 $this.removeClass('show'); 7440 $this.addClass('hidden'); 7441 }else{ 7442 $this.removeClass('hidden'); 7443 $this.addClass('show'); 7444 } 7445 } 7446 } 7447 7448 setTimeout(function() { 7449 updateStartTour(); 7450 }, 300); 7451 }); 7452} 7453 7454/* Page Section Socail Video Player Controls */ 7455/* -------------------------------------------------------------------- */ 7456 7457function mk_page_section_social_video_bg() { 7458 $(".mk-page-section.social-hosted").each(function() { 7459 var $container = $(this), 7460 $sound = $container.data('sound'), 7461 $source = $container.data('source'), 7462 player, 7463 timer = 1000; 7464 7465 if ( $( 'body' ).hasClass( '.compose-mode' ) ) { 7466 timer = 2000; 7467 } 7468 7469 if ($source == 'youtube') { 7470 var youtube = $container.find('iframe')[0]; 7471 try { 7472 player = new YT.Player(youtube, { 7473 events: { 7474 'onReady': function () { 7475 player.playVideo(); 7476 if($sound == false) { 7477 player.mute(); 7478 } 7479 } 7480 } 7481 }); 7482 7483 7484 } catch (e) { 7485 console.log( e ); 7486 } 7487 } 7488 if ($source == 'vimeo') { 7489 var vimeo = $container.find('iframe')[0]; 7490 player = $f(vimeo); 7491 setTimeout(function() { 7492 player.api('play'); 7493 if($sound === false) {
7494 player.api('setVolume', 0); 7495 } 7496 }, timer); 7497 } 7498 7499 }); 7500} 7501 7502// Pre RequireJS hot bug fixing 7503 7504function videoLoadState() { 7505 $('.mk-section-video video').each(function() { 7506 var mkVideo = this; 7507 7508 mkVideo.play(); 7509 this.onload = fire(); 7510 7511 function fire() { 7512 setTimeout(function() { 7513 $(mkVideo).animate({ 7514 'opacity': 1 7515 }, 300); 7516 }, 1000); 7517 } 7518 }); 7519} 7520videoLoadState(); 7521 7522 7523// Gmap Widget 7524(function($) { 7525 7526 $(window).on('load vc_reload', initialize); 7527 7528 function initialize() { 7529 var $gmap = $('.gmap_widget'); 7530 if($gmap.length && typeof google !== 'undefined') $gmap.each(run); 7531 } 7532 7533 function run() { 7534 var $mapHolder = $(this); 7535 var myLatlng = new google.maps.LatLng($mapHolder.data('latitude'), $mapHolder.data('longitude')); 7536 var mapOptions = $mapHolder.data('options'); 7537 mapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP; 7538 mapOptions.center = myLatlng; 7539 var map = new google.maps.Map(this, mapOptions); 7540 7541 new google.maps.Marker({ 7542 position: myLatlng, 7543 map: map 7544 }); 7545 } 7546 7547}(jQuery)); 7548 7549// Instagram Widget 7550(function($) { 7551 7552 $(window).on('load', function() { 7553 var $feeds = $('.mk-instagram-feeds'); 7554 if($feeds.length) $feeds.each(run); 7555 }); 7556 7557 function run() { 7558 var options = $(this).data('options'); 7559 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>'; 7560 var feed = new Instafeed(options); 7561 feed.run(); 7562 } 7563}(jQuery)); 7564 7565 7566// Flipbox backface visibility fix for chrome 7567(function($) { 7568 $(window).on('load', function() { 7569 setTimeout( function() { 7570 $('.chrome-flipbox-backface-fix').removeClass('chrome-flipbox-backface-fix'); 7571 }, 300); 7572 }); 7573}(jQuery)); 7574 7575 7576/* Product in VC Tab Bug Fix 7577/* -------------------------------------------------------------------- */ 7578(function($) { 7579 $(window).on('load', function() { 7580 $('.vc_tta-tab a').on('click', function() { 7581 setTimeout( function() { 7582 $(window).trigger('resize'); 7583 }, 100); 7584 }); 7585 }); 7586}(jQuery)); 7587 7588 7589/* Vertical menu fix when childrens exceed screen height 7590/* -------------------------------------------------------------------- */ 7591(function($) { 7592 $(window).on('load', function() { 7593 $('#mk-vm-menu .menu-item-has-children, #mk-vm-menu .mk-vm-back').on('mouseenter', function() { 7594 var $header_inner = $(this).closest('.mk-header-inner'), 7595 $header_inner_height = $header_inner.outerHeight(), 7596 $header_bg = $header_inner.find('.mk-header-bg'), 7597 total_height = 0; 7598 $header_bg.css('height', '100%'); 7599 setTimeout( function() { 7600 $header_inner.children(':visible').each(function() { 7601 total_height += $(this).outerHeight(true); 7602 }); 7603 total_height -= $header_bg.height(); 7604 if ( total_height < $header_inner_height ) { 7605 $header_bg.css('height', '100%'); 7606 } else { 7607 $header_bg.css('height', total_height + 'px'); 7608 } 7609 }, 600); 7610 }); 7611 }); 7612}(jQuery)); 7613 7614 7615/* Woocommerce varitions lightbox fix 7616/* -------------------------------------------------------------------- */ 7617(function($) { 7618 $(window).on('load', function() { 7619 7620 var $variations_form = $('.variations_form'); 7621 7622 if ( $variations_form.length ) { 7623 7624 var $varitions_selects = $variations_form.find('.variations').find('.value').find('select'); 7625 $varitions_selects.on('change', function() { 7626 7627 // Woocommerce variations lightbox with galleries 7628 var $all_img_container = $('.mk-product-image .mk-woocommerce-main-image'); 7629 if ( $all_img_container.length ) { 7630 $( $all_img_container ).each( set_lightbox_href ); 7631 } 7632 7633 }); 7634 $varitions_selects.trigger('change'); 7635 7636 } 7637 7638 }); 7639 7640 function set_lightbox_href() { 7641 7642 var $product_img = $( this ).find( 'img' ), 7643 $lightbox = $( this ).find( '.mk-lightbox' ); 7644 7645 setTimeout( function() { 7646 var image_url = $product_img.attr( 'src' ), 7647 image_suffix = image_url.substr( image_url.lastIndexOf('.') - image_url.length ), // Get image suffix 7648 image_url = image_url.slice( 0 , image_url.lastIndexOf('-') ); // Remove image size 7649 $lightbox.attr('href', image_url + image_suffix ); 7650 }, 300); 7651 } 7652 7653}(jQuery)); 7654 7655 7656/* Remove video section when on mobile */ 7657/* -------------------------------------------------------------------- */ 7658(function($) { 7659 if ( MK.utils.isMobile() ) {
7660 $('.mk-section-video video').remove(); 7661 } 7662}(jQuery)); 7663 7664 7665/* Yith AJAX Product Filter & Yith Infinite Scrolling Plugin Fix 7666/* -------------------------------------------------------------------- */ 7667(function($) { 7668 $(window).on('load', function() { 7669 7670 $(document).on( 'yith-wcan-ajax-filtered yith_infs_added_elem yith-wcan-ajax-reset-filtered', function(){ 7671 setTimeout( function() { 7672 MK.utils.eventManager.publish('ajaxLoaded'); 7673 MK.core.initAll( document ); 7674 }, 1000 ); 7675 }); 7676 7677 // Fixed YITH Filter plugin causes issue for dropdown sort 7678 $(document).on( 'yith-wcan-ajax-filtered yith-wcan-ajax-reset-filtered', function(){ 7679 setTimeout( function() { 7680 $( '.woocommerce-ordering' ).on( 'change', 'select.orderby', function() { 7681 $( this ).closest( 'form' ).submit(); 7682 }); 7683 }, 1000 ); 7684 }); 7685 7686 }); 7687}(jQuery)); 7688 7689 7690/* Toggle loading state in URL for anchor links. 7691 * - Add a filter to escape meta-chars from hash string. 7692/* -------------------------------------------------------------------- */ 7693!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); 7694 7695 7696/* Determine the top spacing of sidebar for full-width page section & row. 7697/* -------------------------------------------------------------------- */ 7698function mkPositionSidebar() { 7699 7700 var themeContent = $( '.theme-content' ), 7701 lastFullWidthChild = themeContent.find( '.vc_row-full-width' ).last(), 7702 top, 7703 sidebar = $( '#theme-page > .mk-main-wrapper-holder > .theme-page-wrapper > #mk-sidebar' ); 7704 7705 if ( ! lastFullWidthChild.length ) { 7706 sidebar.removeAttr( 'style' ); 7707 return; 7708 } 7709 7710 top = lastFullWidthChild.offset().top - themeContent.offset().top; 7711 sidebar.css( 'padding-top', top ); 7712} 7713 7714function mk_accordion_toggles_tooltip() { 7715 7716 "use strict"; 7717 7718 7719 /* Message Boxes */ 7720 /* -------------------------------------------------------------------- */ 7721 7722 $('.box-close-btn').on('click', function() { 7723 $(this).parent().fadeOut(300); 7724 return false; 7725 7726 }); 7727 7728} 7729 7730function mk_portfolio_ajax() { 7731 "use strict"; 7732 7733 var headerHeight = 0; 7734 if ($.exists("#wpadminbar")) { 7735 headerHeight += $("#wpadminbar").height(); 7736 } 7737 if (!$.exists('.mk-vm-menuwrapper')) { 7738 headerHeight += parseInt($('.mk-header').attr('data-sticky-height')); 7739 } 7740 7741 function init() { 7742 var $portfolio = $('.portfolio-grid.portfolio-ajax-enabled'); 7743 if (!$portfolio.length) return; // quit if no portfolio wrappers 7744 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.ajax.portfolio.js' ], function() { 7745 // wait for ajax response propagation and insertion 7746 setTimeout(function() { 7747 $portfolio.each( function() { 7748 $(this).ajaxPortfolio({ extraOffset: headerHeight }); 7749 }); 7750 }, 100); 7751 }); 7752 } 7753 7754 init(); 7755 7756 // Reinit when ajax loaded stuff 7757 // We have global reinit on Components. so move the ajaxPortfolio to component namespace as a standalone module to get it right. 7758 MK.utils.eventManager.subscribe('ajaxLoaded', init); 7759} 7760 7761/** 7762 * Ajax Search on header nav. 7763 */ 7764function mk_ajax_search() { 7765 "use strict"; 7766 7767 // Check if ajax search box enabled. 7768 if (mk_ajax_search_option !== "beside_nav") { 7769 return; 7770 } 7771 7772 // Set minimum length of text to get ajax result. 7773 var minimumLengthToSearch = 3; 7774 var $mkAjaxSearchInput = $('#mk-ajax-search-input'); 7775 var security = $mkAjaxSearchInput.siblings('input[name="security"]').val(); 7776 var wpHttpReferer = $mkAjaxSearchInput.siblings('input[name="_wp_http_referer"]').val(); 7777 var querySpliter = (ajaxurl.indexOf('?') > -1) ? '&' : '?'; 7778 var ul = document.getElementById('mk-nav-search-result'); 7779 var searchTerm; // Search term 7780 var requestCounter = 0; 7781 var responseCounter = 0; 7782 7783 // Add listener for getting result quickly while user entering text, past text and etc. 7784 $mkAjaxSearchInput.on('paste input propertychange', onSearchBoxInput); 7785 7786 /** 7787 * Callback function for entering search term listener (e.g. keyup). 7788 * It will generate AJAX request to get data. 7789 * 7790 * @param e 7791 */ 7792 function onSearchBoxInput(e) { 7793 var target = e.target || e.srcElement; 7794 var newValue = target.value; 7795 7796 // Check if user change the value of text box 7797 if (searchTerm !== newValue) { 7798 searchTerm = newValue; 7799 ul.innerHTML = ''; 7800 if (searchTerm.length >= minimumLengthToSearch) { 7801 // Show loading icon 7802 $mkAjaxSearchInput.addClass('ajax-searching'); 7803 requestCounter++; 7804 $.getJSON(ajaxurl + querySpliter + 'callback=?&action=mk_ajax_search&security=' + security + '&_wp_http_referer=' + wpHttpReferer + '&term=' + searchTerm) 7805 .done(showSearchResult) 7806 .fail(showErrorMessage); 7807 } 7808 } 7809 } 7810 7811 /** 7812 * Callback function for the response of the search request. 7813 * 7814 * @param data 7815 */ 7816 function showSearchResult(data) { 7817 responseCounter++; 7818 7819 // Only show response of latest request. 7820 if (isCorrectResponse()) { 7821 if (data.length > 0) { 7822 // Append result to result container 7823 for (var i = 0; i < data.length; i++) { 7824 var item = data[i]; 7825 $('<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); 7826 } 7827 } else { 7828 // Show no result message 7829 ul.innerHTML = '<li class="mk-nav-search-result-zero">No Result.</li>'; 7830 } 7831 7832 // Hide loading icon 7833 $mkAjaxSearchInput.parent('form').removeClass('ajax-searching').addClass('ajax-search-complete'); 7834 } 7835 } 7836 7837 /** 7838 * If any errors, we need a handler to show error message. 7839 */ 7840 function showErrorMessage() { 7841 responseCounter++; 7842 7843 if (isCorrectResponse()) { 7844 ul.innerHTML = '<li class="mk-nav-search-error-message">Can not search! Please try again.</li>'; 7845 } 7846 } 7847 7848 /** 7849 * Check if the response is right for the request. we show latest response only. 7850 * 7851 * @returns {boolean} 7852 */ 7853 function isCorrectResponse() { 7854 return requestCounter === responseCounter; 7855 } 7856}
7857/* Background Parallax Effects */ 7858/* -------------------------------------------------------------------- */ 7859 7860function mk_backgrounds_parallax() { 7861 7862 "use strict"; 7863 7864 if (mk_header_parallax == true) { 7865 $('.mk-header-bg').addClass('mk-parallax-enabled'); 7866 } 7867 if (mk_body_parallax == true) { 7868 $('body').addClass('mk-parallax-enabled'); 7869 } 7870 if (mk_banner_parallax == true) { 7871 $('.mk-header').addClass('mk-parallax-enabled'); 7872 } 7873 if (mk_footer_parallax == true) { 7874 $('#mk-footer').addClass('mk-parallax-enabled'); 7875 } 7876 7877 $('.mk-parallax-enabled').each(function () { 7878 var $this = $( this ); 7879 if (!MK.utils.isMobile()) { 7880 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.parallax.js' ], function() { 7881 $this.parallax("49%", 0.3); 7882 }); 7883 } 7884 }); 7885 7886 $('.mk-fullwidth-slideshow.parallax-slideshow').each(function () { 7887 var $this = $( this ); 7888 if (!MK.utils.isMobile()) { 7889 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.parallax.js' ], function() { 7890 var speed_factor = $this.attr('data-speedFactor'); 7891 $this.parallax("49%", speed_factor); 7892 }); 7893 } 7894 }); 7895 7896} 7897/* Blog, Portfolio Audio */ 7898/* -------------------------------------------------------------------- */ 7899 7900function loop_audio_init() { 7901 if ($.exists('.jp-jplayer')) { 7902 $('.jp-jplayer.mk-blog-audio').each(function () { 7903 var $this = $( this ); 7904 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.jplayer.js' ], function() { 7905 var css_selector_ancestor = "#" + $this.siblings('.jp-audio').attr('id'); 7906 var ogg_file, mp3_file, mk_theme_js_path; 7907 ogg_file = $this.attr('data-ogg'); 7908 mp3_file = $this.attr('data-mp3'); 7909 $this.jPlayer({ 7910 ready: function () { 7911 $this.jPlayer("setMedia", { 7912 mp3: mp3_file, 7913 ogg: ogg_file 7914 }); 7915 }, 7916 play: function () { // To avoid both jPlayers playing together. 7917 $this.jPlayer("pauseOthers"); 7918 }, 7919 swfPath: mk_theme_js_path, 7920 supplied: "mp3, ogg", 7921 cssSelectorAncestor: css_selector_ancestor, 7922 wmode: "window" 7923 }); 7924 }); 7925 }); 7926 } 7927} 7928 7929 7930/* Blog Loop Carousel Shortcode */ 7931/* -------------------------------------------------------------------- */ 7932 7933 7934function mk_blog_carousel() { 7935 7936 "use strict"; 7937 7938 if (!$.exists('.mk-blog-showcase')) { 7939 return; 7940 } 7941 $('.mk-blog-showcase ul li').each(function () { 7942 7943 $(this).on('hover', function () { 7944 7945 $(this).siblings('li').removeClass('mk-blog-first-el').end().addClass('mk-blog-first-el'); 7946 7947 }); 7948 7949 }); 7950 7951 7952} 7953 7954 7955 7956 7957/** 7958 * Contact Form 7959 * 7960 * Mostly implemented in Vanilla JS instead of jQuery. 7961 */ 7962function mk_contact_form() { 7963 "use strict"; 7964 var mkContactForms = document.getElementsByClassName('mk-contact-form'); 7965 if (mkContactForms.length === 0) { 7966 return; 7967 } 7968 var captchaImageHolder = $('.captcha-image-holder'); 7969 var activeClassName = 'is-active'; 7970 var invalidClassName = 'mk-invalid'; 7971 for (var i = 0; i < mkContactForms.length; i++) { 7972 initializeForm(mkContactForms[i], activeClassName, invalidClassName); 7973 } 7974 if (captchaImageHolder.length > 0) { 7975 $(window).on('load', initializeCaptchas); 7976 } 7977 /** 7978 * Initialize mk forms. e.g add activeClassName for inputs. 7979 * 7980 * @param form 7981 * @param activeClassName 7982 * @param invalidClassName 7983 */ 7984 function initializeForm(form, activeClassName, invalidClassName) { 7985 var inputs = getFormInputs(form); 7986 for (var i = 0; i < inputs.length; i++) { 7987 markActiveClass(inputs[i]); 7988 } 7989 form.addEventListener('submit', function(e) { 7990 validateForm(e, invalidClassName); 7991 }); 7992 /** 7993 * Set activeClassName for the parent node of the inout 7994 */ 7995 function setActiveClass() { 7996 addClass(this.parentNode, activeClassName); 7997 } 7998 /** 7999 * Unset activeClassName from the parent node of the input. 8000 * We need to unset activeClassName only if the data was empty. 8001 * e.g. in the line style of the mk-contact-form, we set labels position based on activeClassName. 8002 */ 8003 function unsetActiveClass() { 8004 if (this.value === '') { 8005 removeClass(this.parentNode, activeClassName); 8006 } 8007 } 8008 /** 8009 * Add event listeners (focus,blur) for input to set and unset activeClassName. 8010 * 8011 * @param input 8012 */ 8013 function markActiveClass(input) { 8014 input.addEventListener('focus', setActiveClass); 8015 input.addEventListener('blur', unsetActiveClass); 8016 } 8017 } 8018 /** 8019 * Validate form when it's submitted. If everything was valid, we with post form in ajax request. 8020 * 8021 * @param e 8022 * @param invalidClassName 8023 */ 8024 function validateForm(e, invalidClassName) { 8025 e.preventDefault(); 8026 var form = e.target || e.srcElement; 8027 var inputs = getFormInputs(form); 8028 var isValidForm = true; 8029 var hasCaptchaField = false;
8030 for (var i = 0; i < inputs.length; i++) { 8031 var input = inputs[i]; 8032 input.value = String(input.value).trim(); 8033 switch (input.type) { 8034 case 'hidden': 8035 break; 8036 case 'checkbox': 8037 isValidForm = validateCheckBox(input, invalidClassName) && isValidForm; 8038 break; 8039 case 'email': 8040 isValidForm = validateEmail(input, invalidClassName) && isValidForm; 8041 break; 8042 case 'textarea': 8043 isValidForm = validateText(input, invalidClassName) && isValidForm; 8044 break; 8045 case 'text': 8046 /** 8047 * Some old browsers such as IE 8 and 9 detect email type as text. 8048 * So, we need to extra check for data-type attribute 8049 */ 8050 if (input.dataset.type === 'captcha') { 8051 isValidForm = validateText(input, invalidClassName) && isValidForm; 8052 hasCaptchaField = true; 8053 } else if (input.dataset.type === 'email') { 8054 isValidForm = validateEmail(input, invalidClassName) && isValidForm; 8055 } else { 8056 isValidForm = validateText(input, invalidClassName) && isValidForm; 8057 } 8058 break; 8059 default: 8060 /** 8061 * e.g. validating for radiobox, selectbox and etc. 8062 */ 8063 console.warn('Implement validation for ' + input.name + ':' + input.type); 8064 break; 8065 } 8066 } 8067 if (isValidForm) { 8068 if (hasCaptchaField) { 8069 validateCaptcha(form, invalidClassName, sendForm); 8070 } else { 8071 sendForm(form); 8072 } 8073 } 8074 } 8075 /** 8076 * Validate captcha of form. If everything was, we will execute captchaIsValidCallback which as sendForm(). 8077 * 8078 * @param form 8079 * @param invalidClassName 8080 * @param captchaIsValidCallback 8081 * @returns boolean 8082 */ 8083 function validateCaptcha(form, invalidClassName, captchaIsValidCallback) { 8084 var input = form.querySelectorAll('[data-type="captcha"]')[0]; 8085 if (input.value.length === 0) { 8086 addClass(input, invalidClassName); 8087 return false; 8088 } else { 8089 window.get.captcha(input.value).done(function(data) { 8090 loadCaptcha(); 8091 input.value = ''; 8092 if (data !== 'ok') { 8093 addClass(input, invalidClassName); 8094 addClass(input, 'contact-captcha-invalid'); 8095 removeClass(input, 'contact-captcha-valid'); 8096 input.placeholder = mk_captcha_invalid_txt; 8097 } else { 8098 removeClass(input, invalidClassName); 8099 removeClass(input, 'contact-captcha-invalid'); 8100 addClass(input, 'contact-captcha-valid'); 8101 input.placeholder = mk_captcha_correct_txt; 8102 captchaIsValidCallback(form); 8103 } 8104 }); 8105 } 8106 } 8107 /** 8108 * Send submitted form. 8109 * 8110 * @param form 8111 */ 8112 function sendForm(form) { 8113 var $form = $(form); 8114 var data = getFormData(form); 8115 progressButton.loader($form); 8116 $.post(ajaxurl, data, function(response) { 8117 var res = JSON.parse(response); 8118 if (res.action_Status) { 8119 progressButton.success($form); 8120 $form.find('.text-input').val(''); 8121 $form.find('textarea').val(''); 8122 $form.find('input[type=checkbox]').attr("checked", false); 8123 $form.find('.contact-form-message').slideDown().addClass('state-success').html(res.message); 8124 setTimeout(function() { 8125 $form.find('.contact-form-message').slideUp(); 8126 }, 5000); 8127 } else { 8128 progressButton.error($form); 8129 $form.find('.contact-form-message').removeClass('state-success').html(res.message); 8130 } 8131 }); 8132 } 8133 /** 8134 * Initialize all captcha images for first time. All captcha images is always same. e.g. if we have multiple form, 8135 * all of them will have the same image. 8136 * It will also add event listener for '.captcha-change-image' objects to reload the captcha. 8137 */ 8138 function initializeCaptchas() { 8139 var captchaChangeImageButtons = document.getElementsByClassName('captcha-change-image'); 8140 for (var i = 0; i < captchaChangeImageButtons.length; i++) { 8141 captchaChangeImageButtons[i].addEventListener('click', loadCaptcha); 8142 } 8143 } 8144 /** 8145 * Load captcha text and append the image to captcha container. 8146 * If it used as a callback, it will prevent default behave of the event. 8147 * e.g. loading new captcha by click on <a> without changing url. 8148 */ 8149 function loadCaptcha(e) { 8150 if (e) { 8151 e.preventDefault(); 8152 } 8153 $.post(ajaxurl, { 8154 action: 'mk_create_captcha_image' 8155 }, appendImage); 8156 /** 8157 * The callback function for append or change old image src based on response. T 8158 * The captchaImageURL is the url of the captcha which is provided in ajax response of mk_create_captcha_image. 8159 * @param captchaImageURL 8160 */ 8161 function appendImage(captchaImageURL) { 8162 if (captchaImageHolder.find('.captcha-image').length === 0) { 8163 captchaImageHolder.html('<img src="' + captchaImageURL + '" class="captcha-image" alt="captcha txt">'); 8164 } else { 8165 captchaImageHolder.find('.captcha-image').attr("src", captchaImageURL + '?' + new Date().getTime()); 8166 } 8167 } 8168 } 8169 /** 8170 * Get form inputs using querySelectorAll(). 8171 * It returns <input> and <textarea> tags. If you need any other tags such as <select>, please update this function. 8172 * 8173 * @param form 8174 * @returns {NodeList} 8175 */ 8176 function getFormInputs(form) { 8177 return form.querySelectorAll('input,textarea'); 8178 } 8179 /** 8180 * Get data of the form inputs and textareas as a object. 8181 * 8182 * @param form 8183 * @returns {{action: string}} 8184 */ 8185 function getFormData(form) { 8186 var data = { 8187 action: 'mk_contact_form' 8188 }; 8189 var inputs = getFormInputs(form); 8190 for (var i = 0; i < inputs.length; i++) {
8191 data[inputs[i].name] = inputs[i].value; 8192 } 8193 return data; 8194 } 8195} 8196/* Ajax Login Form */ 8197/* -------------------------------------------------------------------- */ 8198function mk_login_form() { 8199 $('form.mk-login-form').each(function() { 8200 var $this = $(this); 8201 $this.on('submit', function(e) { 8202 $('p.mk-login-status', $this).show().text(ajax_login_object.loadingmessage); 8203 $.ajax({ 8204 type: 'POST', 8205 dataType: 'json', 8206 url: ajax_login_object.ajaxurl, 8207 data: { 8208 'action': 'ajaxlogin', 8209 'username': $('#username', $this).val(), 8210 'password': $('#password', $this).val(), 8211 'security': $('#security', $this).val() 8212 }, 8213 success: function(data) { 8214 $('p.mk-login-status', $this).text(data.message); 8215 if (data.loggedin === true) { 8216 document.location.href = ajax_login_object.redirecturl; 8217 } 8218 } 8219 }); 8220 e.preventDefault(); 8221 }); 8222 }); 8223} 8224/* Progress Button */ 8225/* -------------------------------------------------------------------- */ 8226var progressButton = { 8227 loader: function(form) { 8228 MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function() { 8229 var $form = form, 8230 progressBar = $form.find(".mk-progress-button .mk-progress-inner"), 8231 buttonText = $form.find(".mk-progress-button .mk-progress-button-content"), 8232 progressButton = new TimelineLite(); 8233 progressButton.to(progressBar, 0, { 8234 width: "100%", 8235 scaleX: 0, 8236 scaleY: 1 8237 }).to(buttonText, .3, { 8238 y: -5 8239 }).to(progressBar, 1.5, { 8240 scaleX: 1, 8241 ease: Power2.easeInOut 8242 }, "-=.1").to(buttonText, .3, { 8243 y: 0 8244 }).to(progressBar, .3, { 8245 scaleY: 0 8246 }); 8247 }); 8248 }, 8249 success: function(form) { 8250 MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function() { 8251 var $form = form, 8252 buttonText = $form.find(".mk-button .mk-progress-button-content, .mk-contact-button .mk-progress-button-content"), 8253 successIcon = $form.find(".mk-progress-button .state-success"), 8254 progressButtonSuccess = new TimelineLite({ 8255 onComplete: hideSuccessMessage 8256 }); 8257 progressButtonSuccess.to(buttonText, .3, { 8258 paddingRight: 20, 8259 ease: Power2.easeInOut 8260 }, "+=1").to(successIcon, .3, { 8261 opacity: 1 8262 }).to(successIcon, 2, { 8263 opacity: 1 8264 }); 8265 8266 function hideSuccessMessage() { 8267 progressButtonSuccess.reverse() 8268 } 8269 }); 8270 }, 8271 error: function(form) { 8272 MK.core.loadDependencies([MK.core.path.plugins + 'tweenmax.js'], function() { 8273 var $form = form, 8274 buttonText = $form.find(".mk-button .mk-progress-button-content, .mk-contact-button .mk-progress-button-content"), 8275 errorIcon = $form.find(".mk-progress-button .state-error"), 8276 progressButtonError = new TimelineLite({ 8277 onComplete: hideErrorMessage 8278 }); 8279 progressButtonError.to(buttonText, .3, { 8280 paddingRight: 20 8281 }, "+=1").to(errorIcon, .3, { 8282 opacity: 1 8283 }).to(errorIcon, 2, { 8284 opacity: 1 8285 }); 8286 8287 function hideErrorMessage() { 8288 progressButtonError.reverse() 8289 } 8290 }); 8291 } 8292}; 8293function mk_click_events() { 8294 "use strict"; 8295 8296 var eventtype = 'click'; 8297 8298 $(".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) { 8299 if (event.stopPropagation) { 8300 event.stopPropagation(); 8301 } else if (window.event) { 8302 window.event.cancelBubble = true; 8303 } 8304 }); 8305 $("html").on(eventtype, function() {
8306 $(".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); 8307 $('.mk-quick-contact-link').removeClass('quick-contact-active'); 8308 // Removed By Maki for repairing fullnav scroll issue. Hope it odesnt break anything 8309 // $('body').css('overflow', 'visible'); 8310 }); 8311 8312 $('.mk-fullscreen-search-overlay').on(eventtype,function(){ 8313 $(this).removeClass('mk-fullscreen-search-overlay-show'); 8314 }); 8315 8316 $('.mk-forget-password').on(eventtype, function() { 8317 $('.mk-forget-panel').siblings().hide().end().show(); 8318 }); 8319 8320 $('.mk-create-account').on(eventtype, function() { 8321 $('#mk-register-panel').siblings().hide().end().show(); 8322 }); 8323 8324 $('.mk-return-login').on(eventtype, function() { 8325 $('#mk-login-panel').siblings().hide().end().show(); 8326 }); 8327 8328 8329 $('.mk-quick-contact-link').on(eventtype, function() { 8330 var $this = $(this), 8331 $quickContact = $('#mk-quick-contact'); 8332 if (!$this.hasClass('quick-contact-active')) { 8333 $quickContact.addClass('quick-contact-anim').fadeIn(250); 8334 $this.addClass('quick-contact-active'); 8335 } else { 8336 $quickContact.removeClass('quick-contact-anim').fadeOut(100); 8337 $this.removeClass('quick-contact-active'); 8338 } 8339 return false; 8340 }); 8341 8342} 8343 8344function mk_social_share_global() { 8345 8346 "use strict"; 8347 8348 var eventtype = 'click'; 8349 8350 $('.twitter-share').on(eventtype, function() { 8351 var $this = $(this), 8352 $url = $this.attr('data-url'), 8353 $title = $this.attr('data-title'); 8354 8355 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"); 8356 return false; 8357 }); 8358 8359 $('.pinterest-share').on(eventtype, function() { 8360 var $this = $(this), 8361 $url = $this.attr('data-url'), 8362 $title = $this.attr('data-title'), 8363 $image = $this.attr('data-image'); 8364 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"); 8365 return false; 8366 }); 8367 8368 $('.facebook-share').on(eventtype, function() { 8369 var $url = $(this).attr('data-url'); 8370 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"); 8371 return false; 8372 }); 8373 8374 $('.googleplus-share').on(eventtype, function() { 8375 var $url = $(this).attr('data-url'); 8376 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"); 8377 return false; 8378 }); 8379 8380 $('.linkedin-share').on(eventtype, function() { 8381 var $this = $(this), 8382 $url = $this.attr('data-url'), 8383 $title = $this.attr('data-title'), 8384 $desc = $this.attr('data-desc'); 8385 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"); 8386 return false; 8387 }); 8388} 8389 8390 8391/* Event Count Down */ 8392/* -------------------------------------------------------------------- */ 8393 8394function mk_event_countdown() { 8395 if ($.exists('.mk-event-countdown')) { 8396 8397 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.countdown.js' ], function() { 8398 8399 $('.mk-event-countdown').each(function () { 8400 if (isTest) return; 8401 var $this = $(this), 8402 $date = $this.attr('data-date'), 8403 $offset = $this.attr('data-offset'); 8404 8405 $this.downCount({ 8406 date: $date, 8407 offset: $offset 8408 }); 8409 }); 8410 8411 }); 8412 } 8413} 8414/* Flexslider init */ 8415/* -------------------------------------------------------------------- */ 8416 8417function mk_flexslider_init() { 8418 8419 var $lcd = $('.mk-lcd-slideshow'), 8420 $laptop = $('.mk-laptop-slideshow-shortcode'); 8421 8422 if($lcd.length) $lcd.find('.mk-lcd-image').fadeIn(); 8423 if($laptop.length) $laptop.find(".mk-laptop-image").fadeIn(); 8424 8425 $('.js-flexslider').each(function () { 8426 8427 if ($(this).parents('.mk-tabs').length || $(this).parents('.mk-accordion').length) { 8428 $(this).removeData("flexslider"); 8429 } 8430 8431 var $this = $(this), 8432 $selector = $this.attr('data-selector'), 8433 $animation = $this.attr('data-animation'), 8434 $easing = $this.attr('data-easing'), 8435 $direction = $this.attr('data-direction'), 8436 $smoothHeight = $this.attr('data-smoothHeight') == "true" ? true : false,
8437 $slideshowSpeed = $this.attr('data-slideshowSpeed'), 8438 $animationSpeed = $this.attr('data-animationSpeed'), 8439 $controlNav = $this.attr('data-controlNav') == "true" ? true : false, 8440 $directionNav = $this.attr('data-directionNav') == "true" ? true : false, 8441 $pauseOnHover = $this.attr('data-pauseOnHover') == "true" ? true : false, 8442 $isCarousel = $this.attr('data-isCarousel') == "true" ? true : false; 8443 8444 8445 if ($selector !== undefined) { 8446 var $selector_class = $selector; 8447 } else { 8448 var $selector_class = ".mk-flex-slides > li"; 8449 } 8450 8451 if ($isCarousel === true) { 8452 var $itemWidth = parseInt($this.attr('data-itemWidth')), 8453 $itemMargin = parseInt($this.attr('data-itemMargin')), 8454 $minItems = parseInt($this.attr('data-minItems')), 8455 $maxItems = parseInt($this.attr('data-maxItems')), 8456 $move = parseInt($this.attr('data-move')); 8457 } else { 8458 var $itemWidth = $itemMargin = $minItems = $maxItems = $move = 0; 8459 } 8460 8461 MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.flexslider.js' ], function() { 8462 $this.flexslider({ 8463 selector: $selector_class, 8464 animation: $animation, 8465 easing: $easing, 8466 direction: $direction, 8467 smoothHeight: $smoothHeight, 8468 slideshow: !isTest, // autoplay 8469 slideshowSpeed: $slideshowSpeed, 8470 animationSpeed: $animationSpeed, 8471 controlNav: $controlNav, 8472 directionNav: $directionNav, 8473 pauseOnHover: $pauseOnHover, 8474 prevText: "", 8475 nextText: "", 8476 itemWidth: $itemWidth, 8477 itemMargin: $itemMargin, 8478 minItems: $minItems, 8479 maxItems: $maxItems, 8480 move: $move 8481 }); 8482 }); 8483 8484 }); 8485 8486} 8487 8488/* Header Search Form */ 8489/* -------------------------------------------------------------------- */ 8490 8491function mk_header_searchform() { 8492 8493 $('.mk-search-trigger').click(function(){ 8494 setTimeout(function() { 8495 $('#mk-ajax-search-input').focus(); 8496 },500); 8497 }); 8498 8499 "use strict"; 8500 8501 $('.mk-header-toolbar .mk-header-searchform .text-input').on('focus', function () { 8502 8503 if ($('.mk-header-toolbar .mk-header-searchform .text-input').hasClass('on-close-state')) { 8504 $('.mk-header-toolbar .mk-header-searchform .text-input').removeClass('on-close-state').animate({ 8505 'width': '200px' 8506 }, 200); 8507 return false; 8508 } 8509 }); 8510 8511 $(".mk-header-toolbar .mk-header-searchform").click(function (event) { 8512 if (event.stopPropagation) { 8513 event.stopPropagation(); 8514 } else if (window.event) { 8515 window.event.cancelBubble = true; 8516 } 8517 }); 8518 8519 8520 $("html").click(function () { 8521 $(this).find(".mk-header-toolbar .mk-header-searchform .text-input").addClass('on-close-state').animate({ 8522 'width': 90 8523 }, 300); 8524 }); 8525 8526 // Fix search for edge browser 8527 if(MK.utils.browser.name === 'Edge') { 8528 $('#mk-fullscreen-search-input').on('keydown', function(e) { 8529 if (e.which == 13) { 8530 e.preventDefault(); 8531 $('#mk-fullscreen-searchform').submit(); 8532 } 8533 }); 8534 } 8535 8536} 8537 8538 8539 8540 8541/* Hover Events */ 8542/* -------------------------------------------------------------------- */ 8543 8544function mk_hover_events() { 8545 8546 "use strict"; 8547 8548 $('.shopping-cart-header').hover( 8549 function() { 8550 $(this).find('.mk-shopping-cart-box').stop(true, true).fadeIn(250); 8551 }, 8552 function() { 8553 $(this).find('.mk-shopping-cart-box').stop(true, true).fadeOut(250); 8554 } 8555 ); 8556 8557 8558 $('.widget-sub-navigation > ul > li, .widget_nav_menu ul.menu > li, .widget_product_categories ul > .cat-item').each(function() { 8559 8560 var $this = $(this), 8561 $subLevel = $this.find('ul').first(); 8562 8563 if ($this.hasClass('page_item_has_children') || $this.hasClass('menu-item-has-children') || $this.hasClass('cat-parent')) { 8564 $this.on('click', function() { 8565 if($this.hasClass('toggle-active')) { 8566 $subLevel.stop(true, true).slideUp(700); 8567 $this.removeClass('toggle-active'); 8568 } else { 8569 $subLevel.stop(true, true).slideDown(700); 8570 $this.addClass('toggle-active'); 8571 } 8572 }); 8573 8574 $subLevel.on('click', function(e){ 8575 e.stopPropagation(); 8576 }); 8577 } 8578 8579 }); 8580 8581 // var eventtype = mobilecheck() ? 'touchstart' : 'click'; 8582 var eventtype = 'click'; 8583 8584 $('.mk-fullscreen-trigger').on(eventtype, function(e) { 8585 $('.mk-fullscreen-search-overlay').addClass('mk-fullscreen-search-overlay-show'); 8586 setTimeout(function(){ 8587 $("#mk-fullscreen-search-input").focus(); 8588 }, 300); 8589 e.preventDefault(); 8590 }); 8591 8592 $('.mk-fullscreen-close').on(eventtype, function(e) { 8593 $('.mk-fullscreen-search-overlay').removeClass('mk-fullscreen-search-overlay-show'); 8594 e.preventDefault(); 8595 }); 8596 8597} 8598 8599function mk_unfold_footer() { 8600 var $this = $('#mk-footer'), 8601 $spacer = $('#mk-footer-unfold-spacer'), 8602 $footerHeight = $this.outerHeight(); 8603 8604 // Stick with CSS media query breakpoint to target exact screen width 8605 if( !window.matchMedia("(max-width: 767px)").matches ) { 8606 if ($this.hasClass('mk-footer-unfold')) { 8607 $spacer.css('height', $footerHeight); 8608 } 8609 } else { 8610 $spacer.css('height', 0); 8611 } 8612} 8613/* jQuery fancybox lightbox */ 8614/* -------------------------------------------------------------------- */ 8615function mk_lightbox_init() { 8616 8617var $lightbox = $(".mk-lightbox"); 8618 8619 $lightbox.fancybox({ 8620 padding: 15, 8621 margin: 15, 8622 8623 width: 800, 8624 height: 600, 8625 minWidth: 100, 8626 minHeight: 100, 8627 maxWidth: 9999, 8628 maxHeight: 9999,
8629 pixelRatio: 1, // Set to 2 for retina display support 8630 8631 autoSize: true, 8632 autoHeight: false, 8633 autoWidth: false, 8634 8635 autoResize: true, 8636 fitToView: true, 8637 aspectRatio: false, 8638 topRatio: 0.5, 8639 leftRatio: 0.5, 8640 8641 scrolling: 'auto', // 'auto', 'yes' or 'no' 8642 wrapCSS: '', 8643 8644 arrows: true, 8645 closeBtn: true, 8646 closeClick: false, 8647 nextClick: false, 8648 mouseWheel: true, 8649 autoPlay: false, 8650 playSpeed: 3000, 8651 preload: 3, 8652 modal: false, 8653 loop: true, 8654 // Properties for each animation type 8655 // Opening fancyBox 8656 openEffect: 'fade', // 'elastic', 'fade' or 'none' 8657 openSpeed: 200, 8658 openEasing: 'swing', 8659 openOpacity: true, 8660 openMethod: 'zoomIn', 8661 8662 // Closing fancyBox 8663 closeEffect: 'fade', // 'elastic', 'fade' or 'none' 8664 closeSpeed: 200, 8665 closeEasing: 'swing', 8666 closeOpacity: true, 8667 closeMethod: 'zoomOut', 8668 8669 // Changing next gallery item 8670 nextEffect: 'none', // 'elastic', 'fade' or 'none' 8671 nextSpeed: 350, 8672 nextEasing: 'swing', 8673 nextMethod: 'changeIn', 8674 8675 // Changing previous gallery item 8676 prevEffect: 'none', // 'elastic', 'fade' or 'none' 8677 prevSpeed: 350, 8678 prevEasing: 'swing', 8679 prevMethod: 'changeOut', 8680 helpers : { 8681 media : {}, 8682 overlay: { 8683 locked: true 8684 } 8685 }, 8686 8687 tpl: { 8688 wrap: '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>', 8689 image: '<img class="fancybox-image" src="{href}" alt="" />', 8690 error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>', 8691 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>', 8692 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>', 8693 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>', 8694 loading: '<div id="fancybox-loading"><div></div></div>' 8695 }, 8696 8697 afterLoad: function() { 8698 $('html').addClass('fancybox-lock'); 8699 $('.fancybox-wrap').appendTo('.fancybox-overlay'); 8700 }, 8701 beforeShow: function(){ 8702 this.locked = true; 8703 }, 8704 afterClose: function() { 8705 // Only for gallery shortcode. 8706 var galleryParent = this.element.parents( '.mk-gallery-item' ); 8707 8708 if ( galleryParent ) { 8709 galleryParent.removeClass('hover-state'); 8710 } 8711 } 8712 8713 }); 8714} 8715 8716 8717/* Milestone Number Shortcode */ 8718/* -------------------------------------------------------------------- */ 8719 8720function mk_milestone() { 8721 8722 "use strict"; 8723 8724 if( isTest || !$.exists('.mk-milestone') ) return; 8725 8726 $('.mk-milestone').each(function () { 8727 var $this = $(this), 8728 stop_number = $this.find('.milestone-number').attr('data-stop'), 8729 animation_speed = parseInt($this.find('.milestone-number').attr('data-speed')); 8730 8731 var build = function() { 8732 if (!$this.hasClass('scroll-animated')) { 8733 $this.addClass('scroll-animated'); 8734 8735 $({ 8736 countNum: $this.find('.milestone-number').text() 8737 }).animate({ 8738 countNum: stop_number 8739 }, { 8740 duration: animation_speed, 8741 easing: 'linear', 8742 step: function () { 8743 $this.find('.milestone-number').text(Math.floor(this.countNum)); 8744 }, 8745 complete: function () { 8746 $this.find('.milestone-number').text(this.countNum); 8747 } 8748 }); 8749 } 8750 }; 8751 8752 if ( !MK.utils.isMobile() ) { 8753 // refactored only :in-viewport logic. rest is to-do 8754 MK.utils.scrollSpy( this, { 8755 position: 'bottom', 8756 after: build 8757 }); 8758 } else { 8759 build(); 8760 } 8761 8762 }); 8763 8764} 8765 8766 8767 8768 8769/* Recent Works Widget */ 8770/* -------------------------------------------------------------------- */ 8771 8772function mk_portfolio_widget() { 8773 8774 "use strict"; 8775 8776 $('.widget_recent_portfolio li').each(function () { 8777 8778 $(this).find('.portfolio-widget-thumb').hover(function () { 8779 8780 $(this).siblings('.portfolio-widget-info').animate({ 8781 'opacity': 1 8782 }, 200); 8783 }, function () { 8784 8785 $(this).siblings('.portfolio-widget-info').animate({ 8786 'opacity': 0 8787 }, 200); 8788 }); 8789 8790 }); 8791} 8792 8793 8794 8795/* Skill Meter and Charts */ 8796/* -------------------------------------------------------------------- */ 8797function mk_skill_meter() { 8798 "use strict"; 8799 if ($.exists('.mk-skill-meter')) { 8800 if (!MK.utils.isMobile()) { 8801 $(".mk-skill-meter .progress-outer").each(function() { 8802 var $this = $(this); 8803 8804 var build = function() { 8805 if (!$this.hasClass('scroll-animated')) { 8806 $this.addClass('scroll-animated'); 8807 $this.animate({ 8808 width: $this.attr("data-width") + '%' 8809 }, 2000); 8810 } 8811 }; 8812 8813 MK.utils.scrollSpy( this, { 8814 position: 'bottom', 8815 after: build 8816 }); 8817 }); 8818 } else { 8819 $(".mk-skill-meter .progress-outer").each(function() { 8820 var $this = $(this); 8821 if (!$this.hasClass('scroll-animated')) { 8822 $this.addClass('scroll-animated'); 8823 $this.css({ 8824 width: $(this).attr("data-width") + '%' 8825 }); 8826 } 8827 }); 8828 } 8829 } 8830} 8831 8832// function mk_charts() { 8833// "use strict"; 8834 8835// if( !$.exists('.mk-chart') ) return; 8836 8837// MK.core.loadDependencies([ MK.core.path.plugins + 'jquery.easyPieChart.js' ], function() { 8838 8839// $('.mk-chart').each(function() { 8840 8841// var $this = $(this), 8842// $parent_width = $(this).parent().width(), 8843// $chart_size = parseInt($this.attr('data-barSize')); 8844 8845// if ($parent_width < $chart_size) { 8846// $chart_size = $parent_width; 8847// $this.css('line-height', $chart_size); 8848// $this.find('i').css({ 8849// 'line-height': $chart_size + 'px' 8850// }); 8851// $this.css({ 8852// 'line-height': $chart_size + 'px' 8853// }); 8854// } 8855 8856// var build = function() { 8857// $this.easyPieChart({ 8858// animate: 1300, 8859// lineCap: 'butt', 8860// lineWidth: $this.attr('data-lineWidth'), 8861// size: $chart_size, 8862// barColor: $this.attr('data-barColor'), 8863// trackColor: $this.attr('data-trackColor'), 8864// scaleColor: 'transparent', 8865// onStep: function(value) {
8866// this.$el.find('.chart-percent span').text(Math.ceil(value)); 8867// } 8868// }); 8869// }; 8870 8871// // refactored only :in-viewport logic. rest is to-do 8872// MK.utils.scrollSpy( this, { 8873// position: 'bottom', 8874// after: build 8875// }); 8876 8877 8878// }); 8879// }); 8880// } 8881/* Toolbar subscribe form */ 8882/* -------------------------------------------------------------------- */ 8883 8884$( "#mc-embedded-subscribe-form" ).submit(function( e ){ 8885 var $this = $(this); 8886 8887 e.preventDefault(); 8888 $.ajax({ 8889 url: MK.core.path.ajaxUrl, 8890 type: "POST", 8891 data: { 8892 action: "mk_ajax_subscribe", 8893 email: $this.find( ".mk-subscribe--email" ).val(), 8894 list_id: $this.find( ".mk-subscribe--list-id" ).val(), 8895 optin: $this.find( ".mk-subscribe--optin" ).val() 8896 }, 8897 success: function ( res ) { 8898 $this.parent().find( ".mk-subscribe--message" ).html( $.parseJSON( res ).message ); 8899 } 8900 }); 8901}); 8902/** 8903 * Add class to tag. It's vanilla js instead of jQuery. 8904 * @param tag 8905 * @param className 8906 */ 8907function addClass(tag, className) { 8908 tag.className += ' ' + className; 8909} 8910 8911/** 8912 * Remove class from tag. It's vanilla js instead of jQuery. 8913 * Replacing should be with g for replacing all occurrence. 8914 * 8915 * @param tag 8916 * @param className 8917 */ 8918function removeClass(tag, className) { 8919 tag.className = tag.className.replace(new RegExp(className, 'g'), ''); 8920} 8921 8922 8923/** 8924 * If we're running under Node for testing purpose. 8925 */ 8926if(typeof exports !== 'undefined') { 8927 exports.addClass = addClass; 8928 exports.removeClass = removeClass; 8929} 8930 8931/*! 8932* javascript-debounce 1.0.0 8933* 8934* A lightweight, dependency-free JavaScript module for debouncing functions based on David Walsh's debounce function. 8935* 8936* Source code available at: https://github.com/jgarber623/javascript-debounce 8937* 8938* (c) 2015-present Jason Garber (http://sixtwothree.org) 8939* 8940* javascript-debounce may be freely distributed under the MIT license. 8941*/ 8942 8943(function(root, factory) { 8944 if (typeof define === "function" && define.amd) { 8945 define([], factory); 8946 } else if (typeof exports === "object") { 8947 module.exports = factory(); 8948 } else { 8949 root.debounce = factory(); 8950 } 8951})(this, function() { 8952 "use strict"; 8953 return function(callback, delay) { 8954 var timeout; 8955 return function() { 8956 var context = this, args = arguments; 8957 clearTimeout(timeout); 8958 timeout = setTimeout(function() { 8959 callback.apply(context, args); 8960 }, delay); 8961 }; 8962 }; 8963}); 8964 8965/** 8966 * Validate email address. 8967 * 8968 * @param input 8969 * @param invalidClassName 8970 * @returns boolean 8971 */ 8972function validateEmail(input, invalidClassName) { 8973 var value = input.value.trim(); 8974 if ((input.required || value.length > 0) && !/^([a-z0-9_\.\-\+]+)@([\da-z\.\-]+)\.([a-z\.]{2,63})$/i.test(value)) { 8975 if (invalidClassName) { 8976 addClass(input, invalidClassName); 8977 } 8978 return false; 8979 } else { 8980 if (invalidClassName) { 8981 removeClass(input, invalidClassName); 8982 } 8983 return true; 8984 } 8985} 8986/** 8987 * Validate text entry. 8988 * 8989 * @param input 8990 * @param invalidClassName 8991 * @returns boolean 8992 */ 8993function validateText(input, invalidClassName) { 8994 var value = input.value.trim(); 8995 if (input.required && value.length === 0) { 8996 if (invalidClassName) { 8997 addClass(input, invalidClassName); 8998 } 8999 return false; 9000 } else { 9001 if (invalidClassName) { 9002 removeClass(input, invalidClassName); 9003 } 9004 return true; 9005 } 9006} 9007/** 9008 * Validate Checkbox. 9009 * 9010 * @param input 9011 * @param invalidClassName 9012 * @returns boolean 9013 */ 9014function validateCheckBox(input, invalidClassName) { 9015 if (input.required && input.checked == false) { 9016 if (invalidClassName) { 9017 addClass(input, invalidClassName); 9018 } 9019 return false; 9020 } else { 9021 if (invalidClassName) { 9022 removeClass(input, invalidClassName); 9023 } 9024 return true; 9025 } 9026} 9027/** 9028 * If we're running under Node for testing purpose. 9029 */ 9030if (typeof exports !== 'undefined') { 9031 exports.validateEmail = validateEmail; 9032 exports.validateText = validateText; 9033} 9034(function( $ ) { 9035 'use strict'; 9036 9037 var $wrapper = $('.js-bottom-corner-btns'); 9038 var $contactBtn = $wrapper.find('.js-bottom-corner-btn--contact'); 9039 var $backBtn = $wrapper.find('.js-bottom-corner-btn--back'); 9040 var hasContactBtn = $contactBtn.length; 9041 var hasBackBtn = $backBtn.length; 9042 9043 if(!hasBackBtn) return; 9044 9045 function deactivate() { 9046 $contactBtn.removeClass('is-active'); 9047 $backBtn.removeClass('is-active'); 9048 } 9049 9050 function activate() { 9051 $contactBtn.addClass('is-active'); 9052 $backBtn.addClass('is-active'); 9053 } 9054 9055 MK.utils.scrollSpy( 400, {
9056 before: deactivate, 9057 after: activate 9058 }); 9059 9060})( jQuery ); 9061(function($) { 9062 'use strict'; 9063 9064 $('.mk-fullscreen-nav-close, .mk-fullscreen-nav-wrapper, #fullscreen-navigation a').on('click', function(e) { 9065 9066 // Close nav with removing classes 9067 $('.mk-fullscreen-nav').removeClass('opened'); 9068 $('.mk-dashboard-trigger').removeClass('fullscreen-active'); 9069 $('body').removeClass('fullscreen-nav-opened'); 9070 9071 var anchor = MK.utils.detectAnchor( this ), 9072 $this = $( this ); 9073 9074 // Scroll to anchor if exists 9075 if( anchor.length ) { 9076 // Moved 4 these lines after anchor check because console error. If anchor 9077 // return false, split part will throw an error because $this is not a link. 9078 // Fix AM-2027 9079 var href = $this.attr( 'href' ).split( '#' )[0]; 9080 var url = window.location.href; 9081 var isSamePage = url.indexOf( href ) !== -1; 9082 9083 if ( isSamePage ) { 9084 e.preventDefault(); 9085 } 9086 MK.utils.scrollToAnchor( anchor ); 9087 9088 // Or do nothing if pointless # as href 9089 // BAD PRACTICE: it is very popular to use "#" for click elements that we listen to with js. 9090 // GOOD PRACTICE: prefer "javascript:;" as easier to handle and more readable version 9091 } else if( $this.attr( 'href' ) === '#' ) { 9092 e.preventDefault(); 9093 } 9094 }); 9095 9096 $('.fullscreen-navigation-ul .menu-sub-level-arrow').on('click', function(){ 9097 $(this).siblings('.sub-menu').slideToggle(); 9098 }); 9099 9100}(jQuery)); 9101(function($) { 9102 'use strict'; 9103 9104 /** 9105 * Mega menu 9106 */ 9107 var $navList = $(".main-navigation-ul"); 9108 var megaMenu = function megaMenu() { 9109 9110 $navList.MegaMenu({ 9111 type: "vertical", 9112 delay: 200 9113 }); 9114 }; 9115 9116 $(window).on('load', megaMenu); 9117 9118}(jQuery)); 9119(function($) { 9120 'use strict'; 9121 9122 /** 9123 * One pager menu hash update. 9124 * Smooth scroll is appended globally whenever the click element has corresponding #el 9125 */ 9126 var onePageNavItem = function onePageNavItem() { 9127 var $this = $( this ), 9128 link = $this.find( 'a' ), 9129 anchor = MK.utils.detectAnchor( link ); // anchor on current page 9130 9131 if( !anchor.length ) return; 9132 9133 $this.removeClass( 'current-menu-item current-menu-ancestor current-menu-parent' ); 9134 9135 var activeNav = function( state ) { 9136 return function() { 9137 $this[ state ? 'addClass' : 'removeClass' ]( 'current-menu-item' ); 9138 window.history.replaceState( undefined, undefined, [ state ? anchor : ' ' ] ); 9139 }; 9140 }; 9141 9142 MK.utils.scrollSpy( $( anchor )[0], { 9143 before : activeNav( false ), 9144 active : activeNav( true ), 9145 after : activeNav( false ), 9146 }); 9147 }; 9148 9149 var $navItems = $('.js-main-nav').find( 'li' ); 9150 9151 $(window).on('load', function() { 9152 // Wait with spying anchors so we do not assign anchor that is browser scroll to after page load 9153 // Especially when there are anchors on top - refreshing page can cause grabbing one of them into url 9154 // and force unwanted scroll 9155 setTimeout(function() { 9156 $navItems.each( onePageNavItem ); 9157 }, 1000); 9158 }); 9159 9160}(jQuery)); 9161(function($) { 9162 'use strict'; 9163 9164 var $window = $(window); 9165 var $body = $('body'); 9166 var $resMenuWrap = $('.mk-responsive-wrap'); 9167 var $post_nav = $('.mk-post-nav'); 9168 var $toolbar = $('.mk-header-toolbar'); 9169 var $resMenuLink = $('.mk-nav-responsive-link'); 9170 9171 // Flags 9172 var hasResMenu = ($resMenuWrap.length > 0); 9173 9174 //initial window and screen height 9175 var windowHeight = $window.height(); 9176 var screenHeight = screen.height; 9177 9178 // We keep this handler above hasResMenu flag. 9179 // Even if our header doesn't contain droppable responsive menu (in favor of fullscreen or side menu) 9180 // we still transform tollbar into collapsible menu part in responsive state 9181 $('.mk-toolbar-resposnive-icon').on('click', function(e) { 9182 e.preventDefault(); 9183 console.log('clicked'); 9184 if ($body.hasClass('toolbar-opened')) { 9185 $body.removeClass('toolbar-opened').addClass('toolbar-closed'); 9186 $toolbar.hide(); 9187 } else { 9188 $body.removeClass('toolbar-closed').addClass('toolbar-opened'); 9189 $toolbar.show(); 9190 } 9191 }); 9192 9193 9194 if ( ! hasResMenu && ! $('.vc_mk_header') ) return; 9195 9196 function toggleResMenu(e) { 9197 e.preventDefault(); 9198 var $this = $(this); 9199 var $headerInner = $this.parents('header'); 9200 var $resMenu = $headerInner.find('.mk-responsive-wrap'); 9201 var searchBox = $('.responsive-searchform .text-input'); 9202 var adminBarHeight = $('#wpadminbar').height(); /* Fix AM-1918 */ 9203 9204 if ($body.hasClass('mk-opened-nav')) { 9205 $this.removeClass('is-active'); 9206 $body.removeClass('mk-opened-nav').addClass('mk-closed-nav').trigger('mk-closed-nav'); 9207 $resMenu.hide(); 9208 $post_nav.removeClass('post-nav-backward'); 9209 } else { 9210 $this.addClass('is-active'); 9211 $body.removeClass('mk-closed-nav').addClass('mk-opened-nav').trigger('mk-opened-nav'); 9212 $resMenu.show(); 9213 $post_nav.addClass('post-nav-backward'); 9214 9215 } 9216 9217 //for iPhone 5 focus bug , remove search box focused class 9218 if(searchBox.hasClass('input-focused')){ 9219 searchBox.removeClass('input-focused'); 9220 } 9221 9222 } 9223 9224 $resMenuLink.each(function() { 9225 $(this).on('click', toggleResMenu); 9226 }); 9227 9228 $( window ).on( 'vc_reload', function () { 9229 $('.vc_mk_header .mk-nav-responsive-link').each(function() { 9230 $(this).on('click', toggleResMenu); 9231 }); 9232 } ) 9233 9234 var setResMenuHeight = function() { 9235 var height = $window.height() - MK.val.offsetHeaderHeight(0); 9236 $resMenuWrap.css('max-height', height); 9237 }; 9238 9239 // check if device virtual keyboard is active 9240 var isVirtualKeyboard = function() { 9241 var currentWindowHeight = $window.height(); 9242 var currentScreenHeight = screen.height; 9243 var searchBox = $('.responsive-searchform .text-input'); 9244 var searchBoxIsFocused = false; 9245 9246 //for iPhone 5 focus bug , add class for detect focus state 9247 searchBox.on('touchstart touchend', function(e) { 9248 searchBox.addClass('input-focused'); 9249 }); 9250 9251 searchBoxIsFocused = (searchBox.is(':focus') || searchBox.hasClass("input-focused")); 9252 9253 if ($body.hasClass('mk-opened-nav') && searchBoxIsFocused && currentScreenHeight == screenHeight && currentWindowHeight != windowHeight) { 9254 return true; 9255 } else { 9256 return false;
9257 } 9258 }; 9259 9260 var hideResMenu = function hideResMenu() { 9261 if (MK.utils.isResponsiveMenuState()) { 9262 9263 //when search box in responsive menu is focused , window resize fired but at this time responsive menu should be open 9264 if (!isVirtualKeyboard()) { 9265 // hide toggled menu and its states 9266 if ($body.hasClass('mk-opened-nav')) { 9267 $resMenuLink.filter('.is-active').trigger('click'); 9268 } 9269 // hide menu wrapper 9270 $resMenuWrap.hide(); 9271 9272 } 9273 } 9274 }; 9275 9276 $resMenuWrap.on('click', 'a', hideResMenu); 9277 9278}(jQuery)); 9279 9280(function($) { 9281 'use strict'; 9282 9283 var $header = $('.mk-header'); 9284 var hasHeader = ($header.length > 0); 9285 9286 if(!hasHeader && ! $('.vc_mk_header') ) return; 9287 9288 var $sticky_style = $header.attr('data-header-style'); 9289 9290 //if ($sticky_style !== 3) return; 9291 9292 $('.sidedash-navigation-ul > li').each(function() { 9293 var $this = $(this); 9294 9295 $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>'); 9296 }); 9297 9298 function toggleSubMenu(e) { 9299 e.preventDefault(); 9300 var $this = $(this); 9301 9302 if ($this.hasClass('mk-nav-sub-closed')) { 9303 $this.siblings('ul').slideDown(450).end().removeClass('mk-nav-sub-closed').addClass('mk-nav-sub-opened'); 9304 } else { 9305 $this.siblings('ul').slideUp(450).end().removeClass('mk-nav-sub-opened').addClass('mk-nav-sub-closed'); 9306 } 9307 }; 9308 9309 function toggleFullMenu(e) { 9310 e.preventDefault(); 9311 var $this = $(this), 9312 $body = $('body'), 9313 $fullscreen_box = $('.mk-fullscreen-nav'); 9314 9315 if ($this.hasClass('dashboard-style')){ 9316 if (!$this.hasClass('dashboard-active')) { 9317 $this.addClass('dashboard-active'); 9318 $body.addClass('dashboard-opened'); 9319 } else { 9320 $this.removeClass('dashboard-active'); 9321 $body.removeClass('dashboard-opened'); 9322 } 9323 }else if($this.hasClass('fullscreen-style')){ 9324 if (!$this.hasClass('fullscreen-active')) { 9325 $this.addClass('fullscreen-active'); 9326 $body.addClass('fullscreen-nav-opened'); 9327 $fullscreen_box.addClass('opened'); 9328 // MK.utils.scroll.disable(); 9329 } else { 9330 $this.removeClass('fullscreen-active'); 9331 $body.removeClass('fullscreen-nav-opened'); 9332 $fullscreen_box.removeClass('opened'); 9333 } 9334 } 9335 } 9336 9337 $('.mk-nav-arrow').each(function() { 9338 $(this).stop(true).on('click', toggleSubMenu); 9339 }); 9340 9341 $('.mk-dashboard-trigger').each(function() { 9342 $(this).on('click', toggleFullMenu); 9343 }); 9344 9345 $( window ).on( 'vc_reload', function () { 9346 $('.vc_mk_header .mk-dashboard-trigger').each(function() { 9347 $(this).on('click', toggleFullMenu); 9348 }); 9349 9350 $('.vc_mk_header .mk-nav-arrow').each(function() { 9351 $(this).stop(true).on('click', toggleSubMenu); 9352 }); 9353 } ); 9354 9355 $('html').on('click', function() { 9356 $('body').removeClass('dashboard-opened'); 9357 $('.mk-dashboard-trigger').removeClass('dashboard-active'); 9358 }); 9359 9360}(jQuery)); 9361 9362(function($) { 9363 'use strict'; 9364 9365 /** 9366 * Vertical menu 9367 */ 9368 var $verticalMenu = $('#mk-vm-menu'); 9369 var verticalMenu = function verticalMenu() { 9370 if(!$verticalMenu.data('vertical-menu') && !MK.utils.isResponsiveMenuState()) { 9371 $verticalMenu.dlmenu(); 9372 $verticalMenu.data('vertical-menu', true); 9373 } 9374 }; 9375 9376 verticalMenu(); 9377 $(window).on('resize', verticalMenu); 9378 9379}(jQuery)); 9380(function($) { 9381 'use strict'; 9382 9383 // WPML 9384 var $lang_item = $('.mk-main-navigation > .main-navigation-ul > .menu-item-language'); 9385 $lang_item.addClass('no-mega-menu').css('visibility', 'visible'); 9386 $('.mk-main-navigation .menu-item-language > a').addClass('menu-item-link'); 9387 9388})(jQuery); 9389(function($) { 9390 'use strict'; 9391 9392 var $header = $( '.mk-header' ).first(); // Theme header is always first, do not apply to shortcode headers. 9393 var hasHeader = ($header.length > 0); 9394 9395 if(!hasHeader) return; 9396 9397 var $window = $( window ); 9398 var $document = $( document ); 9399 var $headerHolder = $header.find( '.mk-header-holder' ); 9400 var $paddingWrapper = $header.find('.mk-header-padding-wrapper'); 9401 var config = $header.data(); 9402 9403 /** 9404 * Flags 9405 * @type {Boolean} 9406 */ 9407 var isStickyLazy = (config.stickyStyle === 'lazy'); 9408 var isStickyFixed = (config.stickyStyle === 'fixed'); 9409 var isStickySlide = (config.stickyStyle === 'slide'); 9410 9411 function isSticky() { // Check for sticky compatibility 9412 //return config.headerStyle !== 4; header style 4 needs sticky state for transparent header. 9413 return true; 9414 } 9415
9416 function isColorable() { // Check for coloring compatibility 9417 // TODO make it explicit in DOM that header is transparent as this is only scenario for colorable header 9418 // Monkey patch - exclude header styles that don't fit colorable 9419 return config.headerStyle !== 4; 9420 } 9421 9422 9423 /** 9424 * Change header skin 9425 */ 9426 function changeSkin( e, skin ) { 9427 $header.attr( 'data-transparent-skin', skin ); 9428 // Fix for class based skining 9429 var contrast = skin === 'light' ? 'dark' : 'light'; 9430 $header.addClass(skin + '-skin'); 9431 $header.removeClass(contrast + '-skin'); 9432 } 9433 9434 if(isColorable()) MK.utils.eventManager.subscribe( 'firstElSkinChange', changeSkin ); 9435 9436 9437 // Assign sticky scenarions 9438 if (isSticky() && isStickyLazy) { 9439 if(config.headerStyle !== 2) { 9440 lazySticky(); 9441 } 9442 } 9443 else if (isSticky() && isStickyFixed) fixedSticky(); 9444 else if (isSticky() && isStickySlide) slideSticky(); 9445 9446 /** 9447 * Sticky header behavior: Lazy 9448 */ 9449 function lazySticky() { 9450 var elClassHidden = 'header--hidden'; 9451 var elClassSticky = 'a-sticky'; 9452 var wScrollCurrent = 0; 9453 var wScrollBefore = 0; 9454 var wScrollDiff = 0; 9455 var wHeight = 0; 9456 var dHeight = 0; 9457 9458 var setSizes = function setSizes() { 9459 dHeight = $document.height(); 9460 wHeight = $window.height(); 9461 }; 9462 9463 var onScroll = function onScroll() { 9464 wScrollCurrent = MK.val.scroll(); 9465 wScrollDiff = wScrollBefore - wScrollCurrent; 9466 9467 if( wScrollCurrent <= 0 ) { // scrolled to the very top; element sticks to the top 9468 $headerHolder.removeClass( elClassHidden ); 9469 $header.removeClass( elClassSticky ); 9470 $('body').trigger('mk:header-unsticky'); 9471 9472 } else if( wScrollDiff > 0 && $headerHolder.hasClass( elClassHidden ) ) { // scrolled up; element slides in 9473 $headerHolder.removeClass( elClassHidden ); 9474 $header.addClass( elClassSticky ); 9475 $('body').trigger('mk:header-sticky'); 9476 9477 } else if( wScrollDiff < 0 ) { // scrolled down 9478 9479 if( wScrollCurrent + wHeight >= dHeight && $headerHolder.hasClass( elClassHidden ) ) { // scrolled to the very bottom; element slides in 9480 $headerHolder.removeClass( elClassHidden ); 9481 $header.addClass( elClassSticky ); 9482 $('body').trigger('mk:header-sticky'); 9483 } else { // scrolled down; element slides out 9484 $headerHolder.addClass( elClassHidden ); 9485 $header.removeClass( elClassSticky ); 9486 $('body').trigger('mk:header-unsticky'); 9487 } 9488 } 9489 9490 wScrollBefore = wScrollCurrent; 9491 }; 9492 9493 setSizes(); 9494 onScroll(); 9495 $window.on( 'resize', MK.utils.throttle( 100, setSizes ) ); 9496 $window.on( 'scroll', MK.utils.throttle( 500, onScroll ) ); 9497 } 9498 9499 9500 /** 9501 * Sticky header behavior: Fixed 9502 */ 9503 function fixedSticky() { 9504 var sticked = false; 9505 var scrollPos; 9506 9507 var toggleState = function toggleState() { 9508 scrollPos = MK.val.scroll() + MK.val.adminbarHeight(); 9509 9510 if( (scrollPos > MK.val.stickyOffset() ) && ! MK.utils.isResponsiveMenuState() ) { 9511 if(sticked) return; // stop if already sticked 9512 $header.addClass('a-sticky'); 9513 sticked = true; 9514 $('body').trigger('mk:header-sticky'); 9515 } else { 9516 if(!sticked) return; // stop if already unsticked 9517 $header.removeClass('a-sticky'); 9518 sticked = false; 9519 $('body').trigger('mk:header-unsticky'); 9520 } 9521 }; 9522 9523 toggleState(); 9524 $window.on( 'scroll', MK.utils.throttle( 100, toggleState) ); 9525 $window.on( 'resize', MK.utils.throttle( 100, toggleState) ); 9526 } 9527 9528 9529 /** 9530 * Sticky header behavior: Slide 9531 */ 9532 function slideSticky() { 9533 var sticked = false;
9534 var onScroll = function onScroll() { 9535 if (MK.val.scroll() > MK.val.stickyOffset()) { 9536 if(sticked) return; // stop if already sticked 9537 $header.addClass('pre-sticky'); 9538 $paddingWrapper.addClass('enable-padding'); 9539 setTimeout(function() { 9540 $header.addClass('a-sticky'); 9541 $('body').trigger('mk:header-sticky'); 9542 }, 1); 9543 sticked = true; 9544 } else { 9545 if(!sticked) return; // stop if already unsticked 9546 $header.removeClass('a-sticky'); 9547 $header.removeClass('pre-sticky'); 9548 $paddingWrapper.removeClass('enable-padding'); 9549 sticked = false; 9550 $('body').trigger('mk:header-unsticky'); 9551 } 9552 }; 9553 9554 onScroll(); 9555 $window.on( 'scroll', MK.utils.throttle( 100, onScroll) ); 9556 } 9557 9558 // TODO 9559 // var pageIntro = $('body').data('intro'); // block scrolling on page intro 9560 9561 9562})( jQuery ); 9563 9564(function($){ 9565 'use strict'; 9566 9567 // Do not assign at all if no touch events 9568 var hasTouchscreen = ('ontouchstart' in document.documentElement); 9569 if(!hasTouchscreen) return; 9570 9571 $('.mk-main-navigation .menu-item-has-children').each( normalizeClick ); 9572 9573 function normalizeClick() { 9574 $(this).on('click', handleClick); 9575 } 9576 9577 // 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. 9578 // 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 9579 function handleClick(e) { 9580 var $this = $(e.currentTarget); 9581 var $child = $this.find('> ul'); 9582 var isVisible = $child.css('display') !== 'none'; 9583 9584 if(!isVisible) { 9585 e.preventDefault(); 9586 e.stopPropagation(); 9587 } 9588 } 9589 9590}(jQuery)); 9591(function( $ ) { 9592 'use strict'; 9593 9594 MK.ui.preloader = { 9595 dom : { 9596 overlay: '.mk-body-loader-overlay' 9597 }, 9598 9599 hide : function hide() { 9600 $( this.dom.overlay ).fadeOut(600, "easeInOutExpo", function() { 9601 $('body').removeClass('loading'); 9602 //$( this ).remove(); 9603 }); 9604 } 9605 }; 9606 9607})( jQuery ); 9608(function($) { 9609 'use strict'; 9610 9611 var _ajaxUrl = MK.core.path.ajaxUrl; 9612 var _instances = {}; 9613 9614 MK.utils.ajaxLoader = function ajaxLoader(el) { 9615 // retrun a cached instance to have control over state from within multiple places 9616 // we may need for example to reset pageId when do filtering. It is really one instance that controls both filtering and pagination / load more 9617 var id = '#' + ($(el).attr('id')); 9618 if(typeof _instances[id] !== 'undefined') return _instances[id]; 9619 9620 // else lets start new instance 9621 this.id = id; 9622 this.el = el; 9623 this.isLoading = false; 9624 this.xhrCounter = 0; 9625 }; 9626 9627 MK.utils.ajaxLoader.prototype = { 9628 init: function init() { 9629 // prevent double initialization of we return an instance 9630 if ( this.initialized && typeof window.vc_iframe === 'undefined' ) { 9631 return; 9632 } 9633 9634 this.createInstance(); 9635 this.cacheElements(); 9636 9637 this.initialized = true; 9638 }, 9639 9640 cacheElements: function cacheElements() { 9641 this.$container = $(this.el); 9642 this.id = '#' + (this.$container.attr('id')); 9643 this.categories = this.$container.data('loop-categories'); 9644 9645 this.data = {}; 9646 this.data.action = 'mk_load_more'; 9647 this.data.query = this.$container.data('query'); 9648 this.data.atts = this.$container.data('loop-atts'); 9649 this.data.loop_iterator = this.$container.data('loop-iterator'); 9650 this.data.author = this.$container.data('loop-author'); 9651 this.data.posts = this.$container.data('loop-posts'); 9652 this.data.safe_load_more = this.$container.siblings('#safe_load_more').val(); 9653 this.data._wp_http_referer = this.$container.siblings('input[name="_wp_http_referer"]').val(); 9654 this.data.paged = 1; 9655 this.data.maxPages = this.$container.data('max-pages'); 9656 this.data.term = this.categories; 9657 }, 9658 9659 createInstance: function() { 9660 _instances[this.id] = this; 9661 }, 9662 9663 load: function load(unique) { 9664 var self = this; 9665 var seq = ++this.xhrCounter; 9666 this.isLoading = true; 9667 9668 // If mk-ajax-loaded-posts span exists, get the post ids 9669 if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) { 9670 var loaded_posts = this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts'); 9671
9672 // Do not send looaded posts for Classic Pagination Navigation 9673 if ( this.$container.attr('data-pagination-style') != 1 ) { 9674 self.data.loaded_posts = loaded_posts.split(','); 9675 } 9676 } 9677 9678 return $.when( 9679 $.ajax({ 9680 url : _ajaxUrl, 9681 type : "POST", 9682 data : self.data 9683 }) 9684 ).done(function(response) { 9685 self.onDone(response, unique, seq); 9686 }); 9687 }, 9688 9689 onDone: function(response, unique, seq) { 9690 if(seq === this.xhrCounter) { 9691 var self = this; 9692 9693 response = $.parseJSON(response); 9694 response.unique = unique; 9695 response.id = this.id; 9696 9697 // If mk-ajax-loaded-posts span exists, update current post ids 9698 // with new post ids from server's response 9699 if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) { 9700 this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts', response.loaded_posts); 9701 } 9702 9703 this.setData({ 9704 maxPages: response.maxPages, 9705 found_posts: response.found_posts, 9706 loop_iterator: response.i 9707 }); 9708 9709 // Preload images first by creating object from returned content. 9710 // mk_imagesLoaded() method will create a promise that gets resolved when all images inside are loaded. 9711 // Our ajaxLoad is somehow more similar to window.onload event now. 9712 $(response.content).mk_imagesLoaded().then(function() { 9713 MK.utils.eventManager.publish('ajaxLoaded', response); 9714 self.isLoading = false; 9715 self.initNewComponents(); 9716 }); 9717 9718 } else console.log('XHR request nr '+ seq +' aborted'); 9719 9720 }, 9721 9722 setData: function setData(atts) { 9723 for(var att in atts) { 9724 if(att === 'term' && atts[att] === '*') this.data.term = ''; 9725 else this.data[att] = atts[att]; 9726 } 9727 }, 9728 9729 getData: function getData(att) { 9730 return this.data[att]; 9731 }, 9732 9733 initNewComponents: function initNewComponents() { 9734 // Legacy scripts reinit 9735 window.ajaxInit(); 9736 setTimeout(window.ajaxDelayedInit, 1000); 9737 // New way to init apended things 9738 MK.core.initAll(this.el); 9739 } 9740 }; 9741 9742}(jQuery)); 9743MK.component.BackgroundImageSetter = (function ($) { 9744 9745 'use strict'; 9746 9747 var module = {}; 9748 9749 9750 /*---------------------------------------------------------------------------------*/ 9751 /* Private Variables 9752 /*---------------------------------------------------------------------------------*/ 9753 9754 /** 9755 * Take all elements with data-mk-img-set attribute and evaluate best image according to given device orientation and resolution, 9756 * sets style for backround-image on the same node element. * 9757 */ 9758 9759 var $win = $(window), 9760 // $layers = $('[data-mk-img-set]'), 9761 screen = getScreenSize(), 9762 orientation = getOrientation(), 9763 device = getDevice(), 9764 lastOrientation = orientation, 9765 lastDevice = device; 9766 9767 9768 /*---------------------------------------------------------------------------------*/ 9769 /* Private Methods 9770 /*---------------------------------------------------------------------------------*/ 9771 9772 function run($layers) { 9773 $layers.filter( function() { 9774 return !this.hasAttribute("mk-img-loaded"); 9775 }).each(applyBg); 9776 } 9777 9778 // Keep our main side effect out of calculations so they can be run once before loop of applying bg as a result 9779 function applyBg() { 9780 var $this = $(this), 9781 imgs = $this.data('mk-img-set'); 9782 9783 $this.css('background-image', 'url('+ module.getImage(imgs) +')'); 9784 $this.find('.mk-adaptive-image').attr('src', module.getImage(imgs)); 9785 } 9786 9787 // Keep track of current screen size while resizing but update device reference 9788 // and reapply backgrounds only when we discover switch point 9789 function handleResize($layers) { 9790 updateScreenSize(); 9791 if(hasSwitched()) { 9792 updateDevice(); 9793 run($layers); 9794 } 9795 } 9796 9797 function getScreenSize() { 9798 return { 9799 w: $win.width(), 9800 h: $win.height() 9801 }; 9802 } 9803 9804 // Name our device classes and add them id which simply means which one is wider 9805 function getDevice() { 9806 if (screen.w > 1024) return {class: 'desktop', id: 2}; 9807 else if(screen.w > 736) return {class: 'tablet', id: 1}; 9808 else return {class: 'mobile', id: 0}; 9809 } 9810 9811 function getOrientation() { 9812 if(screen.w > screen.h) return 'landscape'; 9813 else return 'portrait'; 9814 } 9815 9816 function updateScreenSize() { 9817 screen = getScreenSize(); 9818 } 9819 9820 function updateDevice() { 9821 if(lastOrientation !== orientation) orientation = lastOrientation; 9822 // Switch device only if going from smaller size to bigger. 9823 // Bigger to smaller is perfectly handled by browsers and doesn't require change and reupload 9824 if(lastDevice.id > device.id) device = lastDevice; 9825 } 9826 9827 function hasSwitched() { 9828 lastOrientation = getOrientation(); 9829 lastDevice = getDevice(); 9830 9831 if(lastOrientation !== orientation || lastDevice.class !== device.class) return true; 9832 else return false;
9833 } 9834 9835 9836 /*---------------------------------------------------------------------------------*/ 9837 /* Public Methods 9838 /*---------------------------------------------------------------------------------*/ 9839 9840 // As desired image might be not available we have to evaluate the best match. 9841 module.getImage = function (imgs) { 9842 if (imgs['responsive'] === 'false') { 9843 return (imgs['landscape']['desktop']) ? imgs['landscape']['desktop'] : (imgs['landscape']['external'] ? imgs['landscape']['external'] : ''); 9844 9845 } 9846 var hasOrientation = !!imgs[orientation]; 9847 // there are only two orientations now and we may get them by string name if both are there 9848 // 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. 9849 // 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 9850 var imgOriented = imgs[ (hasOrientation ? orientation : Object.keys(imgs)[0]) ], 9851 imgExact = (imgOriented[device.class]) ? imgOriented[device.class] : (imgOriented['external'] ? imgOriented['external'] : ''); 9852 return imgExact; 9853 } 9854 9855 module.init = function ($layers) { 9856 9857 // Run and bind 9858 run($layers); 9859 $layers.attr('mk-img-loaded', ''); 9860 }; 9861 9862 module.onResize = function ($layers) { 9863 $win.on('resize', MK.utils.throttle( 500, function() { 9864 handleResize($layers); 9865 })); 9866 }; 9867 9868 return module; 9869 9870}(jQuery)); 9871 9872 9873jQuery(function($) { 9874 9875 var init = function init() { 9876 // Get All Layers, Excluding Edge Slider and Page Section 9877 $allLayers = $('[data-mk-img-set]').filter(function(index) { 9878 return !$(this).hasClass('mk-section-image') && !$(this).hasClass('background-layer') && !$(this).hasClass('mk-video-section-touch'); 9879 });; 9880 9881 // Handle the resize 9882 MK.component.BackgroundImageSetter.onResize($allLayers); 9883 9884 // Set all the BG Layers 9885 MK.component.BackgroundImageSetter.init($allLayers); 9886 } 9887 init(); 9888 9889 $(window).on('vc_reload', init); 9890 9891}); 9892 9893(function( $ ) { 9894 'use strict'; 9895 9896 var core = MK.core, 9897 utils = MK.utils, 9898 path = MK.core.path; 9899 9900 9901 MK.ui.FullScreenGallery = function( element, settings ) { 9902 this.element = element; 9903 this.config = settings; 9904 9905 this.isFullScreen = false; 9906 }; 9907 9908 9909 // preload slick PLUGIN TO USE THIS 9910 MK.ui.FullScreenGallery.prototype = { 9911 dom : { 9912 fullScrBtn : '.slick-full-screen', 9913 exitFullScrBtn : '.slick-minimize', 9914 playBtn : '.slick-play', 9915 pauseBtn : '.slick-pause', 9916 shareBtn : '.slick-share', 9917 socialShare : '.slick-social-share', 9918 wrapper : '.slick-slider-wrapper', 9919 slider : '.slick-slides', 9920 slides : '.slick-slide', 9921 dots : '.slick-dot', 9922 active : '.slick-active', 9923 hiddenClass : 'is-hidden', 9924 dataId : 'slick-index' 9925 }, 9926 9927 tpl: { 9928 dot : '<div class="slick-dot"></div>', 9929 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>', 9930 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>' 9931 }, 9932 9933 init : function() { 9934 var self = this; 9935 9936 // core.loadDependencies([ path.plugins + 'slick.js' ], function() { 9937 self.cacheElements(); 9938 self.getViewportSizes(); 9939 self.updateSizes( 'window' ); 9940 self.create(); 9941 // update cache with elements propagated by plugin 9942 self.updateCacheElements(); 9943 self.createPagination(); 9944 self.bindEvents(); 9945 // }); 9946 }, 9947 9948 create : function() { 9949 var self = this; 9950 9951 this.slick = this.$gallery.slick({ 9952 dots: true, 9953 arrows: true, 9954 infinite: true, 9955 speed: 300, 9956 slidesToShow: 1, 9957 centerMode: true, 9958 centerPadding: '0px', 9959 variableWidth: true, 9960 autoplay: false, 9961 autoplaySpeed: 3000, 9962 useTransform: true, 9963 prevArrow: self.tpl.prev, 9964 nextArrow: self.tpl.next, 9965 customPaging: function(slider, i) { 9966 return self.tpl.dot; 9967 }, 9968 }); 9969 }, 9970 9971 cacheElements : function() { 9972 this.$window = $( window ); 9973 this.$gallery = $( this.element ); 9974 9975 this.$fullScrBtn = $( this.dom.fullScrBtn ); 9976 this.$exitFullScrBtn = $( this.dom.exitFullScrBtn ); 9977 this.$playBtn = $( this.dom.playBtn ); 9978 this.$pauseBtn = $( this.dom.pauseBtn ); 9979 this.$shareBtn = $( this.dom.shareBtn ); 9980 this.$socialShare = $( this.dom.socialShare ); 9981 9982 this.$wrapper = $( this.dom.wrapper ); 9983 this.$slider = $( this.dom.slider ); 9984 this.$slides = $( this.dom.slides ); 9985 this.$imgs = this.$slides.find( 'img' ); 9986 // store reference to initial images without slides appended by pugin 9987 // - needed for creating of pagination 9988 this.$originalImgs = this.$imgs; 9989 }, 9990 9991 updateCacheElements : function() { 9992 this.$slides = $( this.dom.slides ); 9993 this.$imgs = this.$slides.find( 'img' ); 9994 this.$dots = $( this.dom.dots ); 9995 }, 9996 9997 bindEvents : function() { 9998 var self = this; 9999 this.$fullScrBtn.on( 'click', this.toFullScreen.bind( this ) ); 10000 this.$exitFullScrBtn.on( 'click', this.exitFullScreen.bind( this ) ); 10001 this.$playBtn.on( 'click', this.play.bind( this ) ); 10002 this.$pauseBtn.on( 'click', this.pause.bind( this ) ); 10003 this.$shareBtn.on( 'click', this.toggleShare.bind( this ) ); 10004 this.$socialShare.on( 'click', 'a', this.socialShare.bind( this ) ); 10005 this.$window.on( 'resize', this.onResize.bind( this ) ); 10006 this.$window.on( 'keydown', function(e) { 10007 if(e.keyCode === 39) self.$gallery.slick('slickNext'); 10008 if(e.keyCode === 37) self.$gallery.slick('slickPrev'); 10009 }); 10010 $( document ).on( 'fullscreenchange mozfullscreenchange webkitfullscreenchange msfullcreenchange', this.exitFullScreen.bind( this ) ); 10011 }, 10012 10013 getViewportSizes : function() { 10014 this.screen = { 10015 w: screen.width, 10016 h: screen.height 10017 }; 10018 this.window = { 10019 w: this.$window.width(), 10020 h: this.$window.height() 10021 }; 10022 }, 10023 10024 updateSizes : function( viewport ) { 10025 this.$wrapper.width( this[ viewport ].w ); 10026 this.$wrapper.height( '100%' ); 10027 this.$imgs.height( '100%'); 10028 }, 10029 10030 createPagination : function() { 10031 var self = this; 10032 this.$dots.each( function( i ) { 10033 var img = self.$originalImgs.eq( i ).attr( 'src' ); 10034 10035 $( this ).css({ 10036 'background-image': 'url('+ img +')' 10037 }); 10038 }); 10039 }, 10040 10041 play : function(e) { 10042 e.preventDefault(); 10043 this.$playBtn.addClass( this.dom.hiddenClass ); 10044 this.$pauseBtn.removeClass( this.dom.hiddenClass ); 10045 $( this.element ).slick( 'slickPlay' ); 10046 }, 10047 10048 pause : function(e) { 10049 e.preventDefault(); 10050 this.$pauseBtn.addClass( this.dom.hiddenClass ); 10051 this.$playBtn.removeClass( this.dom.hiddenClass ); 10052 $( this.element ).slick( 'slickPause' ); 10053 }, 10054 10055 toggleShare : function(e) { 10056 e.preventDefault(); 10057 this.$socialShare.toggleClass( this.dom.hiddenClass ); 10058 }, 10059 10060 getCurentId : function() { 10061 return this.$slides.filter( this.dom.active ).data( this.dom.dataId ); 10062 }, 10063 10064 toFullScreen : function() { 10065 var self = this; 10066 10067 this.$fullScrBtn.addClass( this.dom.hiddenClass ); 10068 this.$exitFullScrBtn.removeClass( this.dom.hiddenClass ); 10069 10070 this.$slider.hide().fadeIn( 500 ); 10071 utils.launchIntoFullscreen( document.documentElement ); 10072 this.updateSizes( 'screen' ); 10073 $( this.element ).slick( 'slickGoTo', this.getCurentId(), true ); 10074 10075 // Update state with delay so we avoid triggering exitFullScreen fn from 10076 // fullscreenchange event 10077 setTimeout( function() { 10078 self.isFullScreen = true; 10079 }, 1000); 10080 }, 10081 10082 exitFullScreen : function() { 10083 if( this.isFullScreen ) { 10084 this.$exitFullScrBtn.addClass( this.dom.hiddenClass ); 10085 this.$fullScrBtn.removeClass( this.dom.hiddenClass ); 10086 10087 utils.exitFullscreen(); 10088 this.updateSizes( 'window' ); 10089 $( this.element ).slick( 'slickGoTo', this.getCurentId(), true ); 10090 10091 this.isFullScreen = false;
10092 } 10093 10094 }, 10095 10096 onResize : function() { 10097 this.getViewportSizes(); 10098 this.updateSizes( this.isFullScreen ? 'screen' : 'window' ); 10099 $( this.element ).slick( 'refresh' ); 10100 $( this.element ).slick( 'slickGoTo', this.getCurentId(), true ); 10101 this.updateCacheElements(); 10102 this.createPagination(); 10103 }, 10104 10105 socialShare : function( e ) { 10106 e.preventDefault(); 10107 var $this = $( e.currentTarget ), 10108 network = $this.data( 'network' ), 10109 id = this.config.id, 10110 url = this.config.url, 10111 title = this.$wrapper.find( '.slick-title' ).text(), 10112 name; 10113 var picture = this.$slides.filter( this.dom.active ).children().first().attr( 'src' ); 10114 switch( network ) { 10115 case 'facebook': 10116 url = 'https://www.facebook.com/sharer/sharer.php?picture=' + picture+'&u=' + url + '#id=' + id; 10117 name = 'Facebook Share'; 10118 break; 10119 case 'twitter': 10120 url = 'http://twitter.com/intent/tweet?text=' + url + '#id=' + id; 10121 name = 'Twitter Share'; 10122 break; 10123 case 'pinterest': 10124 url = 'http://pinterest.com/pin/create/bookmarklet/?media=' + picture + '&url=' + url + '&is_video=false&description=' + title; 10125 // other available link paranmeters: media, description 10126 name = 'Pinterest Share'; 10127 break; 10128 10129 } 10130 10131 window.open( url, name, "height=380 ,width=660, resizable=0, toolbar=0, menubar=0, status=0, location=0, scrollbars=0" ); 10132 } 10133 }; 10134 10135})( jQuery ); 10136(function( $ ) { 10137 'use strict'; 10138 10139 var val = MK.val; 10140 10141 MK.component.FullHeight = function( el ) { 10142 var $window = $( window ), 10143 $this = $( el ), 10144 config = $this.data( 'fullheight-config' ), 10145 container = document.getElementById( 'mk-theme-container' ), 10146 minH = (config && config.min) ? config.min : 0, 10147 winH = null, 10148 height = null, 10149 update_count = 0, 10150 testing = MK.utils.getUrlParameter('testing'), 10151 offset = null; 10152 10153 // We need to provide height on the same specificity level for workaround to IE bug 10154 // connect.microsoft.com/IE/feedback/details/802625/min-height-and-flexbox-flex-direction-column-dont-work-together-in-ie-10-11-preview 10155 // stackoverflow.com/questions/19371626/flexbox-not-centering-vertically-in-ie 10156 if(MK.utils.browser.name === ('IE' || 'Edge')) $this.css( 'height', '1px' ); 10157 10158 var update = function() { 10159 10160 if(update_count === 0) { 10161 winH = $window.height(); 10162 // for correct calculate 10163 offset = $this.offset().top - 1; 10164 height = Math.max(minH, winH - val.offsetHeaderHeight( offset )); 10165 $this.css( 'min-height', height ); 10166 if(testing !== undefined ) 10167 update_count++; 10168 } 10169 10170 }; 10171 10172 // TODO remove scroll listener by dynamic offset reader 10173 var init = function() { 10174 update(); 10175 $window.on( 'resize', update ); 10176 $window.on( 'scroll', update ); 10177 window.addResizeListener( container, update ); 10178 }; 10179 10180 return { 10181 init : init 10182 }; 10183 }; 10184 10185})( jQuery ); 10186 10187 10188(function( $ ) { 10189 'use strict'; 10190 10191 /** 10192 * A fork from original VC function. 10193 * The original one is adding some padding which causes extra padding 10194 * on our templates so we customized the codes. 10195 * 10196 * @since 5.9.8 10197 * @since 6.0.1 Improve logic to handle LTR responsive state. 10198 * @since 6.0.1 Fix missing padding-left if row has its own padding-left when 10199 * Vertical Header is active. 10200 */ 10201 function MkfullWidthRow() { 10202 var $windowWidth = $(document).width(); 10203 var $elements = $('[data-mk-full-width="true"]'); 10204 var direction = $('body.rtl').length ? 'right' : 'left'; 10205 var verticalHeader = $('body.vertical-header-enabled').length ? true : false; 10206 var verticalHeaderWidth = ( $( '.header-style-4 .mk-header-inner' ).outerWidth() > 270 ) ? 0 : 270; 10207 var verticalHeaderRtl = $('body.rtl').length ? -1 : 1; 10208 var verticalHeaderRtlWidth = $('body.rtl.vertical-header-enabled').length ? verticalHeaderWidth : 0; 10209 var verticalHeaderRight = $('body.vertical-header-right').length ? -1 : 1; 10210 var verticalHeaderWidthBoxed = 0; 10211 var boxed = $('body.mk-boxed-enabled').length; 10212 var boxedOffset = ( boxed ) ? ( $(window).width() - $('#theme-page').outerWidth() ) / 2 : 0; 10213 var boxedMaxWidth = ( boxed ) ? $('#theme-page').outerWidth() : 'auto'; 10214 10215 if ( verticalHeader && boxed ) { 10216 verticalHeaderWidthBoxed = ( $( '.header-style-4 .mk-header-inner' ).outerWidth() > 270 ) ? 0 : verticalHeaderRtl * verticalHeaderRight * 135; 10217 } 10218 10219 var transparentHeader = $('.transparent-header').length; 10220 if ( transparentHeader > 0 ) { 10221 verticalHeaderWidthBoxed = 0; 10222 } 10223 10224 $.each($elements, function(key, item) { 10225 var $el = $(this); 10226 var css; 10227 $el.addClass("vc_hidden"); 10228 var $el_full = $el.next(".vc_row-full-width"); 10229 if ($el_full.length || ($el_full = $el.parent().next(".vc_row-full-width")), $el_full.length) { 10230 var el_margin_left = parseInt($el.css("margin-left"), 10), 10231 el_margin_right = parseInt($el.css("margin-right"), 10), 10232 offset = 0 - $el_full.offset().left - el_margin_left, 10233 width = $(window).width(); 10234 if (css = { 10235 position: "relative", 10236 "box-sizing": "border-box", 10237 width: $(window).width(), 10238 maxWidth: boxedMaxWidth 10239 }, 10240 css[direction] = offset + boxedOffset + verticalHeaderWidthBoxed + ( verticalHeaderRight * verticalHeaderRtlWidth ), 10241 $el.css(css), !$el.data("mkStretchContent")) { 10242 var padding = -1 * offset; 10243 0 > padding && (padding = 0); 10244 var paddingRight = width - padding - $el_full.width() + el_margin_left + el_margin_right; 10245 padding = padding - paddingRight; 10246 if ( 0 > paddingRight && (paddingRight = 0) ) { 10247 css = {}; 10248 if ( 'right' === direction ) { 10249 css["padding-left"] = padding + "px"; 10250 css["padding-right"] = 0; 10251 } else { 10252 css["padding-right"] = padding + "px"; 10253 css["padding-left"] = 0; 10254 } 10255 10256 $el.css(css) 10257 } 10258 } 10259 10260 /** 10261 * Fix AM-2974 10262 * 10263 * When user set padding-left or padding-right in the row, both of them 10264 * will be prioritized as important styles. It breaks padding-left set 10265 * by Vertical Header to make the row content fit with the content 10266 * container. We need to repopulate the padding-{side - based on Vertical 10267 * Header position} value. 10268 * 10269 * Works when: 10270 * - Vertical Header is active 10271 * - Main layout is not boxed 10272 * - Page Section is full layout 10273 * - Row is full width layout and content 10274 * - Row has its own padding-left and padding-right 10275 * - There is no additional padding added 10276 * 10277 * How it works: 10278 * Get current row padding-left and vertical header width. If both of them 10279 * are equal, it means row position is correct related to Vertical Header. 10280 * If not, we should sum both of them, then declare new padding-{side} 10281 * style attribute. 10282 * 10283 * Tested with: 10284 * - Main Layout: Full & Boxed Layout 10285 * - Page Section: Full Layout and Non Full Layout 10286 * - Row: Full Width, Full Width Content, and Non Full Width 10287 * - Header: Non vertical headers 10288 * - Transparent Header 10289 * - RTL and LTR 10290 */ 10291 if ( verticalHeader && ! boxed && ! transparentHeader && ! css.hasOwnProperty( 'padding-left' ) && ! css.hasOwnProperty( 'padding-right' )) { 10292 // Get row padding-{side} and Vertical Header width. 10293 var side = 'left'; 10294 if ( verticalHeaderRight === -1 ) { 10295 side = 'right'; 10296 } 10297 var el_padding_dir = parseInt( $el.css( 'padding-' + side ), 10 ); 10298 var header_padding_dir = $( '.header-style-4 .mk-header-inner' ).outerWidth(); 10299 // Compare both of row and vertical header padding-{side}. 10300 if ( el_padding_dir != header_padding_dir) { 10301 if($windowWidth > mk_responsive_nav_width) { 10302 $el[0].style.setProperty( 'padding-' + side, header_padding_dir + 'px', 'important' ); 10303 } else { 10304 $el[0].style.removeProperty( 'padding-' + side); 10305 } 10306 10307 10308 // Reset padding-{side} for page section. 10309 var $el_page_section = $el.find( '.mk-page-section.full_layout' ); 10310 if ( $el_page_section.length > 0 ) { 10311 $el_page_section[0].style.setProperty( 'padding-' + side, 'unset', 'important' ); 10312 } 10313 } 10314 } 10315 10316 $el.attr("data-mk-full-width-init", "true"), $el.removeClass("vc_hidden"), $(document).trigger("vc-full-width-row-single", { 10317 el: $el, 10318 offset: offset, 10319 marginLeft: el_margin_left, 10320 marginRight: el_margin_right, 10321 elFull: $el_full, 10322 width: width 10323 }) 10324 } 10325 }
10325), $(document).trigger("mk-full-width-row", $elements); 10326 } 10327 10328 MkfullWidthRow(); 10329 var debounceResize = null; 10330 $(window).on("resize", function() { 10331 if( debounceResize !== null ) { clearTimeout( debounceResize ); } 10332 debounceResize = setTimeout( MkfullWidthRow, 100 ); 10333 }); 10334 10335})( jQuery ); 10336 10337(function($) { 10338 'use strict'; 10339 10340 MK.component.Grid = function( el ) { 10341 var $container = $(el); 10342 var config = $container.data( 'grid-config' ); 10343 var isSlideshow = $container.closest('[data-mk-component="SwipeSlideshow"]').length; 10344 var miniGridConfig = { 10345 container: el, 10346 item: config.item + ':not(.is-hidden)', 10347 gutter: 0 10348 }; 10349 10350 var init = function init(){ 10351 // Flags for cancelling usage goes first : 10352 // Quit early if we discover that Grid is used inside SwipeSlideshow as it brings bug with crossoverriding positioning 10353 // + grid is not really needed as we have single row all handled by slider. 10354 // It happens only in woocommerce carousel as of hardcoded Grid in loop-start.php 10355 if(isSlideshow) return; 10356 MK.core.loadDependencies([ MK.core.path.plugins + 'minigrid.js' ], create); 10357 }; 10358 10359 // Remove el hidden without adding proper class 10360 var prepareForGrid = function prepareForGrid() { 10361 var $item = $(this); 10362 var isHidden = ($item.css('display') === 'none'); 10363 if(isHidden) $item.addClass('is-hidden'); 10364 else $item.removeClass('is-hidden'); 10365 }; 10366 10367 var create = function create() { 10368 var timer = null; 10369 10370 function draw() { 10371 // Prevent plugin breaking when feeding it with hidden elements 10372 $container.find(config.item).each( prepareForGrid ); 10373 minigrid(miniGridConfig); 10374 } 10375 10376 function redraw() { 10377 if (timer) clearTimeout(timer); 10378 timer = setTimeout(draw, 100); 10379 } 10380 10381 // init 10382 draw(); 10383 // If reinitializing drop existing event handler 10384 $(window).off('resize', redraw); 10385 $(window).on('resize', redraw); 10386 MK.utils.eventManager.subscribe('item-expanded', redraw); 10387 MK.utils.eventManager.subscribe('ajaxLoaded', redraw); 10388 MK.utils.eventManager.subscribe('staticFilter', redraw); 10389 }; 10390 10391 return { 10392 init : init 10393 }; 10394 }; 10395 10396})(jQuery); 10397 10398 10399 10400 10401 10402 10403 10404 10405/** 10406 * ICON FACTORY @ Maki 10407 * 10408 * Javascript part that translates css styles into link to server side manufacturer. 10409 * By passing extra args we generate icons as needed on server and send them back with ajax and attch them to DOM here. 10410 * 10411 * 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. 10412 * 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. 10413 * 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. 10414 * 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. 10415 * 10416 * Prons: 10417 * - automated process where we can mimic old behaviour 10418 * - possible bugs are easy to patch 10419 * - 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) 10420 * - icon generation moved to server side where our main templating is already happening 10421 * - we can easily switch how our Icon should be outputed - inline, img, object, iframe. Whatever our situation requires (img for responsive icons for example) 10422 * 10423 * Cons: 10424 * - possible bugs based on different nature of svgs / fonts. Need to be manually fixed 10425 * - some manual work to straighten things - litle css refactors here and there 10426 * - as the mapping the icons happens in server side, it may cause CPU bottlenecks and should be cashed in DB for repetitve usage. 10427 * 10428 * 10429 * TODO Refactor to config obj as parameter for easier passing it. Also decouple more - especially loops 10430 */ 10431(function ($) { 10432 'use strict'; 10433 10434 // As long as we can manage this manually it is better like so. We avoid delay based on waiting for ajax to finish 10435 // $.get( MK.core.path.theme + '/assets/icons/icon-families.json', createAll); 10436 var families = [ 10437 ['awesome-icons' , 'mk-icon-'], // [family, prefix] 10438 ['icomoon' , 'mk-moon-'], 10439 ['pe-line-icons' , 'mk-li-'], 10440 ['theme-icons' , 'mk-jupiter-icon-'] 10441 ]; 10442 10443 // Our css contains this extends for particular families of fonts. For now we automate the process and extend it here as well 10444 var extend = { 10445 'awesome-icons' : [], 10446 'icomoon' : [], 10447 'pe-line-icons' : [], 10448 'theme-icons' : [] 10449 }; 10450 10451 // Cache holder for quick access to repeating icons. config / svg 10452 var _cache = {}; 10453 var _cacheId = 0;
10454 // Merge configs to call it with single ajax 10455 var _config = []; 10456 // Counter for all families. We merge all our families for single ajax request and countdown when to trigger the download. 10457 var _roundCount = 0; 10458 // Mapper for icons - config / array with nodes 10459 var _iconMap = {}; 10460 10461 10462 // Closure to merge $icons together and to run the download when we counted down icon families to 0 10463 var getIconsSprite = (function() { 10464 var $icons = null; 10465 var iterator = 0; 10466 10467 function run(callback) { 10468 var config = encodeURIComponent(JSON.stringify(_config)); 10469 10470 $.ajax({ 10471 url : MK.core.path.ajaxUrl, 10472 // dataType: 'xml', 10473 method: 'POST', 10474 data: {action : 'mk_get_icon', iterator: iterator++, config: config}, 10475 success: function(sprite) { 10476 callback(sprite, $icons); 10477 _config = []; 10478 _iconMap = {}; 10479 $icons = null; 10480 }, 10481 error: function(err) { 10482 console.log('Icon load problem'); 10483 } 10484 }); 10485 } 10486 10487 return function(callback, $els, count) { 10488 if(!$icons) $icons = $els; 10489 else $icons.add($els); 10490 // console.log(count); 10491 if(!count) run(callback); 10492 }; 10493 }()); 10494 10495 // Wait for DOM manipulations and run where really needed 10496 $(window).on('load', function() { 10497 setTimeout(function() { 10498 createAll(document); 10499 if($('.mk-header').length) createAll('.mk-header'); 10500 if($('.js-flexslider, .mk-flexslider').length) createAll('.js-flexslider, .mk-flexslider'); 10501 if($('.mk-accordion').length) createAll('.mk-accordion'); 10502 }, 1000); 10503 }); 10504 10505 MK.utils.eventManager.subscribe('ajaxLoaded', function() { 10506 // Wait for actuall DOM insertion 10507 setTimeout(createAll, 100, '.js-loop'); 10508 }); 10509 10510 MK.utils.eventManager.subscribe('ajax-preview', function() { 10511 setTimeout(createAll, 100, '.ajax-container'); 10512 }); 10513 10514 MK.utils.eventManager.subscribe('photoAlbum-open', function() { 10515 setTimeout(createAll, 100, '.gallery-share'); 10516 }); 10517 10518 MK.utils.eventManager.subscribe('quickViewOpen', function() { 10519 setTimeout(createAll, 300, '.mk-modal-content'); 10520 }); 10521 10522 // Our main runner that creates all icons in given scope 10523 function createAll(scope) { 10524 // iterate through families 10525 for(var i = 0, l = families.length; i < l; i++) { 10526 var family = families[i][0]; 10527 var prefix = families[i][1]; 10528 var $icons = getIcons(family, prefix, scope); 10529 if($icons.length) { 10530 _roundCount++; 10531 // 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. 10532 // We need it to pass all $icons first so we can merge all families before ajax request. 10533 setTimeout(createIcons, 0, $icons, family, prefix); 10534 } 10535 } 10536 } 10537 10538 // Grab all els in given scope that contains our prefix, anywhere in class attribute. Extend if needed 10539 function getIcons(family, prefix, scope) { 10540 var $scope = $(scope); 10541 var $icons = $scope.find('[class*='+ prefix +']'); 10542 var extraClassNames = extend[family]; 10543 // if nothing to extend just return what we have till now 10544 if(!extraClassNames) return $icons; 10545 // Extend it with our css garbish 10546 extraClassNames.forEach(function(className) { 10547 var $icon = $scope.find(className); 10548 $icons = $icons.add($icon); 10549 }); 10550 // serve all 10551 return $icons; 10552 } 10553 10554 10555 function createIcons($icons, family, prefix, i, unicode) { 10556 var id = i || 0; 10557 var icon = $icons[id]; 10558 10559 // quick check point, if no more icons break recursion 10560 if(!icon) { 10561 _roundCount--; 10562 getIconsSprite(insertIcons, $icons, _roundCount, _config); 10563 return; 10564 } 10565 10566 var css = getComputedStyle( icon, ':before'); 10567 var classAttr = icon.getAttribute('class'); 10568 var name = (classAttr) ? matchClass(classAttr.split(' '), prefix) : false; 10569 var h = getComputedStyle(icon).fontSize; 10570 var config = createConfig(css, name, family, unicode, h); 10571 var cache = JSON.stringify(config); 10572 10573 if(!config) { 10574 // 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) 10575 // As we expect empty response from server, we just skip to next icon 10576 10577 } else if(_cache[cache]) { 10578 // Use cached icon when possible 10579 // 10580 if(typeof _iconMap[cache] === 'undefined') _iconMap[cache] = [$icons.eq(id)]; 10581 else _iconMap[cache].push($icons.eq(id)); 10582 10583 } else { 10584 if(typeof _iconMap[cache] === 'undefined') _iconMap[cache] = [$icons.eq(id)]; 10585 else _iconMap[cache].push($icons.eq(id)); 10586 10587 _cache[cache] = _cacheId.toString(); // number as string so we could do [var] key lookup after reversal 10588 config.id = _cacheId; // extend config for server only 10589 _config.push(config); 10590 10591 _cacheId++; // increment after caching 10592 } 10593 10594 createIcons($icons, family, prefix, ++id); 10595 } 10596 10597 function insertIcons(sprite, $icons) { 10598 var $sprite = $(sprite); 10599 var $svgs = $sprite.find('svg'); 10600 var idMap = invert(_cache); 10601 10602 $sprite.each(function() { 10603 var $svg = $(this); 10604 var id = $svg.attr('data-cacheid'); // read as string 10605 var configKey = idMap[id]; 10606 10607 _cache[configKey] = this; 10608 // console.log(id, this) 10609 }); 10610 10611 // console.log('sprite',sprite) 10612 // 10613
10614 Object.keys(_iconMap).forEach(function (cacheKey) { 10615 _iconMap[cacheKey].forEach(function($icons) { 10616 $icons.each(function() { 10617 var $svg = $(_cache[cacheKey]).clone(); 10618 var $icon = $(this); 10619 10620 // console.log($icon[0], _cache[cacheKey]); 10621 10622 function remove() { 10623 // exclude problematic stuff 10624 if($icon.parents('.pricing-features')) return; 10625 $icon.not('.mk-jupiter-icon-xing') 10626 .not('.mk-jupiter-icon-square-xing') 10627 .not('.mk-jupiter-icon-simple-xing') 10628 .find('.mk-svg-icon') 10629 .not('[data-name="mk-moon-zoom-in"]') 10630 .remove(); // and remove else to reapply styles with new loaded svg 10631 } 10632 10633 if($svg.length ) remove(); 10634 10635 if(!$icon.find('svg').length) { 10636 if($icon.parents('.widget ul').length) $icon.prepend($svg); 10637 else $icon.append($svg); 10638 } 10639 }); 10640 }); 10641 }); 10642 10643 // Notify rest of app 10644 MK.utils.eventManager.publish('iconsInsert'); 10645 } 10646 10647 // Prepare configuration for server side. We need to grab icons and manipulate them a little there 10648 function createConfig(css, name, family, unicode, height) { 10649 var hasGradient = checkGradient(css); 10650 var hasDirection = extractGradient('direction', css.background); 10651 10652 var config = { 10653 family: family, 10654 // this is mostly for Extends. Because we've been customizing singular elements and assigning content unicode manually, 10655 // now we don't have any proper anchor for usage with our json map 10656 unicode: (unicode) ? unicode : decodeUnicode(css.content), 10657 name: name, 10658 // fill: css.color, 10659 gradient_type: hasGradient ? extractGradient('type' , css.background) : false, 10660 gradient_start: hasGradient ? extractGradient('start', css.background) : false, 10661 gradient_stop: hasGradient ? extractGradient('stop' , css.background) : false, 10662 gradient_direction: hasDirection ? extractGradient('direction', css.background).replace(' ', '-') : false, 10663 height: height 10664 }; 10665 10666 // If there is no name or unicode the whole config is invalid 10667 if(!config.name && !config.unicode) return false; 10668 else return config; 10669 } 10670 10671 // Extract class name that represents the icon that we try to generate
10672 function matchClass(classes, prefix) { 10673 // var missing = ''; 10674 for(var i = 0, l = classes.length; i < l; i++) { 10675 if(classes[i].indexOf(prefix) !== -1) return classes[i]; // return first matched class name 10676 // else missing += ' .' + classes[i]; // collect not matching classes 10677 } 10678 // if we didn't returned anything within loop we output notification here. Keep it for testing only 10679 // console.log('Possibility of missing icons for element with classes:' + missing); 10680 } 10681 10682 // Check if background conatains gradient declaration and return bg string if so or false 10683 function checkGradient(css) { 10684 var bg = css.background; 10685 if(bg.indexOf('radial') !== -1 || bg.indexOf('linear') !== -1) return bg; 10686 else return false; 10687 } 10688 10689 // Extract background attribiutes from bg string. 10690 // Multipurpose function which returns part we ask for 10691 function extractGradient(attr, grad) { 10692 // quit if gradient is falsy 10693 // console.log(grad); 10694 if(!grad) return false; 10695 10696 var isRadial = grad.indexOf('radial') !== -1; 10697 var isLinear = grad.indexOf('linear') !== -1; 10698 var hasDirection = grad.indexOf('(to') !== -1; 10699 var f, t; // from, to 10700 10701 if(attr === 'type') { 10702 if(isRadial) return 'radial'; 10703 if(isLinear) return 'linear'; 10704 10705 } else if(attr === 'start') { 10706 f = getStrPosition(grad, 'rgb(', 1); 10707 t = getStrPosition(grad, '0%' , 1); 10708 10709 } else if(attr === 'stop') { 10710 f = getStrPosition(grad, 'rgb(', 2); 10711 t = getStrPosition(grad, '100%', 1); 10712 10713 } else if(attr === 'direction') { 10714 if(!hasDirection) return false; 10715 f = getStrPosition(grad, '(to', 1) + 4; 10716 t = getStrPosition(grad, ', rgb(', 1); 10717 10718 } else { 10719 return false; 10720 } 10721 10722 return grad.slice(f, t); 10723 } 10724 10725 // Helper for getting indexOf but with lookup for instance of the string 10726 // str - string to search 10727 // m - what we're looking for 10728 // i - instance, starting at 1 10729 function getStrPosition(str, m, i) { 10730 return str.split(m, i).join(m).length; 10731 } 10732 10733 // JS outputs unicode results rather than code representation. This helper function does the job 10734 function decodeUnicode(content) { 10735 // escape() kills \ escape signature and outputs it as %u 10736 // str replace to drop special chars 10737 // and we bring it all to lowercase to match filenames we keep on server 10738 if(content && content !== 'none') return escape(content).replace(/%22/g, '').replace('%u', '').toLowerCase(); 10739 else return false; // just in case we haven't provided content to work with 10740 } 10741 10742 function invert(obj) { 10743 var new_obj = {}; 10744 for (var prop in obj) { 10745 if(obj.hasOwnProperty(prop)) { 10746 new_obj[obj[prop]] = prop; 10747 } 10748 } 10749 return new_obj; 10750 } 10751 10752}(jQuery)); 10753(function($, window){ 10754 'use strict'; 10755 10756 var scrollY = MK.val.scroll; 10757 var dynamicHeight = MK.val.dynamicHeight; 10758 10759 var $window = $(window); 10760 var $containers = $('.js-loop'); 10761 10762 $containers.each( pagination ); 10763 10764 $window.on( 'vc_reload', function() { 10765 $('.js-loop').each( pagination ); 10766 } ); 10767 10768 function pagination() { 10769 var unique = Date.now(); 10770 var $container = $(this); 10771 var $superContainer = $container.parent(); // should contain clearing so it stretches with floating children 10772 var $loadBtn = $container.siblings('.js-loadmore-holder').find('.js-loadmore-button'); 10773 var $loadScroll = $('.js-load-more-scroll'); 10774 var style = $container.data('pagination-style'); 10775 var maxPages = $container.data('max-pages'); 10776 var id = '#' + ($container.attr('id')); 10777 var ajaxLoader = new MK.utils.ajaxLoader(id); 10778 var isLoadBtn = (style === 2); 10779 var isInfiniteScroll = (style === 3); // add flag for last container 10780 var scrollCheckPoint = null; 10781 var isHandlerBinded = false; 10782 10783 ajaxLoader.init(); 10784 10785 init(); 10786 10787 function init() { 10788 MK.utils.eventManager.subscribe('ajaxLoaded', onLoad); 10789 bindHandlers(); 10790 if( isInfiniteScroll ) scrollCheckPoint = spyScrollCheckPoint(); 10791 10792 $window.on( 'vc_reload', function() { 10793 $window.off('scroll', handleScroll); 10794 } ); 10795 } 10796 10797 function bindHandlers() { 10798 if( isLoadBtn ) $loadBtn.on('click', handleClick); 10799 if( isInfiniteScroll ) $window.on('scroll', handleScroll); 10800 isHandlerBinded = true; 10801 } 10802 10803 function unbindHandlers() { 10804 if( isLoadBtn ) $loadBtn.off('click', handleClick); 10805 if( isInfiniteScroll ) $window.off('scroll', handleScroll); 10806 isHandlerBinded = false;
10807 } 10808 10809 function handleClick(e) { 10810 e.preventDefault(); 10811 if(!ajaxLoader.isLoading) loadMore(); 10812 } 10813 10814 function handleScroll() { 10815 if((scrollY() > scrollCheckPoint()) && !ajaxLoader.isLoading) loadMore(); 10816 } 10817 10818 function loadMore() { 10819 loadingIndicatorStart(); 10820 var page = ajaxLoader.getData('paged'); 10821 ajaxLoader.setData({paged: ++page}); 10822 ajaxLoader.load(unique); 10823 } 10824 10825 function onLoad(e, response) { 10826 if( typeof response !== 'undefined' && response.id === id) { 10827 // Checking found posts helps to fix all pagination styles 10828 if( ajaxLoader.getData('found_posts') <= 0 && ajaxLoader.getData('paged') >= ajaxLoader.getData('maxPages')) loadingIndicatorHide(); 10829 else loadingIndicatorShow(); 10830 if(response.unique === unique) $container.append(response.content); 10831 loadingIndicatorStop(); 10832 } 10833 } 10834 10835 function loadingIndicatorStart() { 10836 if(isLoadBtn) $loadBtn.addClass('is-active'); 10837 else if(isInfiniteScroll) MK.ui.loader.add('.js-load-more-scroll'); 10838 10839 } 10840 10841 function loadingIndicatorStop() { 10842 if(isLoadBtn) $loadBtn.removeClass('is-active'); 10843 else if(isInfiniteScroll) MK.ui.loader.remove('.js-load-more-scroll'); 10844 } 10845 10846 function loadingIndicatorShow() { 10847 if(isHandlerBinded) return; 10848 if(isLoadBtn) $loadBtn.show(); 10849 else if(isInfiniteScroll) $loadScroll.show(); 10850 bindHandlers(); 10851 } 10852 10853 function loadingIndicatorHide() { 10854 if(!isHandlerBinded) return; 10855 if(isLoadBtn) $loadBtn.hide(); 10856 else if(isInfiniteScroll) $loadScroll.hide(); 10857 unbindHandlers(); 10858 } 10859 10860 10861 function spyScrollCheckPoint() { 10862 var containerO = 0; 10863 var containerH = dynamicHeight( $superContainer ); 10864 var winH = dynamicHeight( window ); 10865 10866 var setVals = function() { 10867 containerO = $superContainer.offset().top; 10868 }; 10869 10870 setVals(); 10871 $window.on('resize', function() { requestAnimationFrame(setVals); }); 10872 10873 return function() { 10874 return (containerH() + containerO) - (winH() * 2); 10875 }; 10876 } 10877 } 10878 10879})(jQuery, window); 10880/*! 10881 * imagesLoaded PACKAGED v4.1.1 10882 * JavaScript is all like "You images are done yet or what?" 10883 * MIT License 10884 */ 10885 10886!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
10886h(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}); 10887 10888(function($) { 10889 'use strict'; 10890 10891 // Check if it's inside hidden parent 10892 // Cannot be position: fixed 10893 function isHidden(el) { 10894 return (el.offsetParent === null); 10895 } 10896 10897 MK.component.Masonry = function(el) { 10898 var $window = $(window); 10899 var $container = $(el); 10900 var config = $container.data( 'masonry-config' ); 10901 var $masonryItems = $container.find(config.item); 10902 var cols = config.cols || 8; 10903 var $filterItems = null; // assign only when apply filter 10904 var wall = null; 10905 10906 var init = function init() { 10907 MK.core.loadDependencies([ MK.core.path.plugins + 'freewall.js' ], onDepLoad); 10908 }; 10909 10910 var onDepLoad = function onDepLoad() { 10911 masonry(); 10912 10913 // Events 10914 $window.on('resize', onResize); 10915 MK.utils.eventManager.subscribe('ajaxLoaded', onPostAddition); 10916 MK.utils.eventManager.subscribe('staticFilter', resize); 10917 }; 10918 10919 var masonry = function masonry() { 10920 // Quit for hidden elements for now. 10921 if(isHidden(el)) return; 10922 10923 var newCols; 10924 if(window.matchMedia( '(max-width:600px)' ).matches) newCols = 2; 10925 else if(window.matchMedia( '(max-width:850px)' ).matches) newCols = 4; 10926 else newCols = cols; 10927 10928 var colW = $container.width() / newCols; 10929 10930 wall = new Freewall( config.container ); 10931 10932 // We need to pass settings to a plugin via reset method. Strange but works fine. 10933 wall.reset({
10934 selector: config.item + ':not(.is-hidden)', 10935 gutterX: 0, // set default gutter to 0 and again - apply margins to item holders in css 10936 gutterY: 0, 10937 cellW: colW, 10938 cellH: colW 10939 }); 10940 10941 wall.fillHoles(); 10942 wall.fitWidth(); 10943 10944 $masonryItems.each(function() { 10945 $(this).data('loaded', true); 10946 }); 10947 }; 10948 10949 10950 // Clear attributes after the plugin. It's API method dosn't handle it properly 10951 var destroyContainer = function destroyContainer() { 10952 $container.removeAttr('style') 10953 .removeData('wall-height') 10954 .removeData('wall-width') 10955 .removeData('min-width') 10956 .removeData('total-col') 10957 .removeData('total-row') 10958 .removeAttr('data-wall-height') 10959 .removeAttr('data-wall-width') 10960 .removeAttr('data-min-width') 10961 .removeAttr('data-total-col') 10962 .removeAttr('data-total-row'); 10963 }; 10964 10965 var destroyItem = function destroyItem() { 10966 var $item = $(this); 10967 $item.removeAttr('style') 10968 .removeData('delay') 10969 .removeData('height') 10970 .removeData('width') 10971 .removeData('state') 10972 .removeAttr('data-delay') 10973 .removeAttr('data-height') 10974 .removeAttr('data-width') 10975 .removeAttr('data-state'); 10976 }; 10977 10978 var destroyAll = function destroyAll() { 10979 if( !wall ) return; 10980 wall.destroy(); // API destroy 10981 destroyContainer(); 10982 $masonryItems.each( destroyItem ); // run our deeper destroy 10983 }; 10984 10985 var onResize = function onResize() { 10986 requestAnimationFrame(resize); 10987 }; 10988 10989 var refresh = function refresh() { 10990 if( !wall ) return; 10991 setTimeout(wall.fitWidth.bind(wall), 5); 10992 }; 10993 10994 var resize = function resize() { 10995 destroyAll(); 10996 masonry(); 10997 }; 10998 10999 var onPostAddition = function onPostAddition() { 11000 $masonryItems = $container.find(config.item); 11001 11002 $masonryItems.each(function() { 11003 var $item = $(this), 11004 isLoaded = $item.data('loaded'); 11005 11006 if(!isLoaded) $item.css('visibility', 'hidden'); 11007 }); 11008 11009 11010 $container.mk_imagesLoaded().then(function() { 11011 destroyAll(); 11012 masonry(); 11013 }); 11014 }; 11015 11016 return { 11017 init : init 11018 }; 11019 }; 11020 11021}(jQuery)); 11022(function($) { 11023 'use strict'; 11024 11025 MK.component.Pagination = function(el) { 11026 this.el = el; 11027 }; 11028 11029 MK.component.Pagination.prototype = { 11030 init: function init() { 11031 this.cacheElements(); 11032 this.bindEvents(); 11033 this.onInitLoad(); 11034 }, 11035 11036 cacheElements: function cacheElements() { 11037 this.lastId = 1; 11038 this.unique = Date.now(); 11039 this.$pagination = $(this.el); 11040 this.$container = this.$pagination.prev('.js-loop'); 11041 this.$pageLinks = this.$pagination.find('.js-pagination-page'); 11042 this.$nextLink = this.$pagination.find('.js-pagination-next'); 11043 this.$prevLink = this.$pagination.find('.js-pagination-prev'); 11044 this.$current = this.$pagination.find('.js-current-page'); 11045 this.$maxPages = this.$pagination.find('.pagination-max-pages'); // TODO change in DOM and here to js class 11046 this.containerId = '#' + this.$container.attr('id'); 11047 this.pagePathname = window.location.pathname; 11048 this.pageSearch = window.location.search; 11049 this.popState = false; 11050 this.ajaxLoader = new MK.utils.ajaxLoader('#' + this.$container.attr('id')); 11051 this.ajaxLoader.init(); 11052 }, 11053 11054 bindEvents: function bindEvents() { 11055 this.$pageLinks.on('click', this.pageClick.bind(this)); 11056 this.$nextLink.on('click', this.nextClick.bind(this)); 11057 this.$prevLink.on('click', this.prevClick.bind(this)); 11058 MK.utils.eventManager.subscribe('ajaxLoaded', this.onLoad.bind(this)); 11059 }, 11060 11061 pageClick: function pageClick(e) { 11062 e.preventDefault(); 11063 var $this = $(e.currentTarget); 11064 var id = parseFloat($this.attr('data-page-id')); 11065 11066 if(id > this.ajaxLoader.getData('maxPages') || id < 1) return; 11067 this.load(id, $this); 11068 this.updatePagedNumUrl( id ); 11069 }, 11070 11071 nextClick: function nextClick(e) { 11072 e.preventDefault(); 11073 if(this.ajaxLoader.getData('paged') === this.ajaxLoader.getData('maxPages')) return; 11074 this.load(++this.lastId, $(e.currentTarget)); 11075 this.updatePagedNumUrl( this.lastId ); 11076 }, 11077 11078 prevClick: function prevClick(e) { 11079 e.preventDefault(); 11080 if(this.ajaxLoader.getData('paged') === 1) return; 11081 this.load(--this.lastId, $(e.currentTarget)); 11082 this.updatePagedNumUrl( this.lastId ); 11083 }, 11084 11085 load: function load(id, $el) { 11086 this.lastId = id; 11087 this.ajaxLoader.setData({paged: id}); 11088 this.ajaxLoader.load(this.unique); 11089 this.removeIndicator(); 11090 MK.ui.loader.add($el); 11091 }, 11092 11093 onLoad: function success(e, response) { 11094 if( typeof response !== 'undefined' && response.id === this.containerId) { 11095 this.updatePagination(); 11096 this.lastId = this.ajaxLoader.getData('paged'); 11097 11098 if(response.unique === this.unique) { 11099 this.removeIndicator(); 11100 this.scrollPage(); 11101 this.$container.html(response.content); 11102 } 11103 } 11104 }, 11105 11106 updatePagination: function updatePagination() { 11107 var self = this; 11108 11109 // Hide / show arrows 11110 var isFirst = (this.ajaxLoader.getData('paged') === 1); 11111 var isLast = (this.ajaxLoader.getData('paged') === this.ajaxLoader.getData('maxPages')); 11112 11113 if(isFirst) this.$prevLink.addClass('is-vis-hidden'); 11114 else this.$prevLink.removeClass('is-vis-hidden'); 11115 11116 if(isLast) this.$nextLink.addClass('is-vis-hidden'); 11117 else this.$nextLink.removeClass('is-vis-hidden'); 11118 11119 // X of Y 11120 this.$current.html(this.ajaxLoader.getData('paged')); 11121 this.$maxPages.html(this.ajaxLoader.getData('maxPages')); 11122 11123 // Move overfloating items 11124 var displayItems = 10; 11125 var centerAt = displayItems / 2; 11126 11127 if(this.ajaxLoader.getData('maxPages') > displayItems) { 11128 this.$pageLinks.each(function(i) { 11129 11130 var id = self.lastId - centerAt; 11131 id = Math.max(id, 1); 11132 id = Math.min(id, self.ajaxLoader.getData('maxPages') - displayItems + 1); 11133 id = id + i; 11134 11135 $(this).html( id ).attr('data-page-id', id).show(); 11136 11137 if(i === 0 && id > 1) $(this).html('...'); 11138 if(i === displayItems - 1 && id < self.ajaxLoader.getData('maxPages')) $(this).html('...'); 11139 }); 11140 } else { 11141 this.$pageLinks.each(function(i) { 11142 var $link = $(this); 11143 var id = i + 1; 11144 11145 $link.html(id).attr('data-page-id', id); 11146 11147 if( self.ajaxLoader.getData('maxPages') === 1) { 11148 self.$pageLinks.hide(); 11149 } else { 11150 if(i > self.ajaxLoader.getData('maxPages') - 1) $link.hide(); 11151 else $link.show(); 11152 } 11153 11154 }); 11155 } 11156 11157 // Highlight current only 11158 this.$pageLinks.filter('[data-page-id="' + this.ajaxLoader.getData('paged') + '"]' ).addClass('current-page') 11159 .siblings().removeClass('current-page'); 11160 11161 }, 11162 11163 scrollPage: function scrollPage() { 11164 var containerOffset = this.$container.offset().top; 11165 var offset = containerOffset - MK.val.offsetHeaderHeight( containerOffset ) - 20; 11166 MK.utils.scrollTo( offset ); 11167 }, 11168 11169 removeIndicator: function removeIndicator() { 11170 MK.ui.loader.remove('.js-pagination-page, .js-pagination-next, .js-pagination-prev'); 11171 }, 11172 11173 /** 11174 * Set some actions when archive/category page is loaded. Actions list: 11175 * - Select the correct paged ID on pagination list. 11176 * - Set current paged ID on the label. 11177 * - Add event listener onpopstate for handling prev/next button of Browser URL. 11178 * - Set info for updatePagedNumUrl() about request comes from popstate. 11179 * 11180 * @since 5.9.8 11181 */ 11182 onInitLoad: function onInitLoad() { 11183 var initPagedID = this.$pagination.data( 'init-pagination' ); 11184 if ( initPagedID && initPagedID > 1 ) { 11185 this.$current.html( initPagedID ); 11186 this.$pageLinks.filter( '[data-page-id="' + initPagedID + '"]' ).addClass( 'current-page' ).siblings().removeClass( 'current-page' ); 11187 } 11188 11189 // Run popstate only if it's supported by the browser. 11190 if ( 'onpopstate' in window ) { 11191 var thisPop = this; 11192 window.onpopstate = function( event ) { 11193 var id = 1; 11194 11195 // At start, state is always null. So, we should check it before processing. 11196 if ( typeof event.state === 'object' && event.state ) { 11197 var state = event.state; 11198 11199 // Set paged ID for updating page. 11200 if ( state.hasOwnProperty( 'MkPagination' ) ) { 11201 var currentState = state.MkPagination; 11202 if ( currentState.hasOwnProperty( 'paged' ) ) { 11203 id = parseFloat( currentState.paged ); 11204 } 11205 } 11206 } else { 11207 id = parseFloat( thisPop.getURLPagedID() ); 11208 } 11209 11210 // Tell updatePagedNumUrl() if request come from popstate. 11211 thisPop.popState = true; 11212 thisPop.$pageLinks.filter( '[data-page-id="' + id + '"]' ).trigger( 'click' ); 11213 } 11214 } 11215 }, 11216 11217 /** 11218 * Update current pagination browser URL by adding/changing paged number. Only run if 11219 * the browser support pushState and the request not coming from popstate. 11220 * 11221 * WordPress has some ways to set paged number: 11222 * 1. page/[number], paged=[number] will be directed here. 11223 * 2. page=[number] 11224 * So, we should check which one the request is used here. 11225 * 11226 * @since 5.9.8 11227 */ 11228 updatePagedNumUrl: function updatePagedNumUrl( id ) { 11229 // Check pushState browser support and ignore if request come from popstate. 11230 if ( 'history' in window && 'pushState' in history && id && ! this.popState ) { 11231 var fullPage = this.pagePathname + this.pageSearch; 11232 var isQueryPage = false;
11233 11234 // Style 1 - /page/[number], as default value. 11235 var newPage = 'page/' + id + '/'; 11236 var expPage = /page\/\d+\/?/; 11237 var result = this.pagePathname.match( /\/page\/\d+/ ); 11238 var isPagedExist = ( result ) ? true : false; 11239 11240 // Style 2 - ?page=[number], only run if /page/ is not exist and URL query var exist. 11241 if ( ! isPagedExist && this.pageSearch ) { 11242 isQueryPage = this.pageSearch.match( /page\=\d+/ ); 11243 if ( isQueryPage ) { 11244 newPage = 'page=' + id; 11245 expPage = /page\=\d+/; 11246 } 11247 } 11248 11249 // If page number is 1, remove paged number from URL. 11250 if ( id === 1 ) { 11251 newPage = ''; 11252 if ( isQueryPage ) { 11253 expPage = ( this.pageSearch.match( /\&+/ ) ) ? /page\=\d+\&?/ : /\?page\=\d+\&?/; 11254 } 11255 } 11256 11257 // Set new pathname. Do replacement only if the new pathname contains paged number. 11258 var newURL = this.pagePathname + newPage + this.pageSearch; 11259 if ( fullPage.match( expPage ) ) { 11260 newURL = fullPage.replace( expPage, newPage ); 11261 } 11262 11263 // Set history state and return popstate back to fal
11263se. 11264 var historyState = { 11265 MkPagination: { 11266 url: newURL, 11267 paged: id 11268 } 11269 } 11270 this.popState = false; 11271 11272 // Push new pathname to display/hide the paged number. 11273 window.history.pushState( historyState, null, newURL ); 11274 } 11275 this.popState = false; 11276 }, 11277 11278 /** 11279 * Get current URL page ID. Notes: 11280 * 1. page/[number], paged=[number] will be directed here. 11281 * 2. page=[number] 11282 * 11283 * @return {integer} Current paged ID. Default 1. 11284 */ 11285 getURLPagedID: function getURLPagedID() { 11286 var pathname = window.location.pathname; 11287 var search = window.location.search; 11288 var pagedId = 1; 11289 var result = ''; 11290 var isPagedExist = false; 11291 11292 // Search based on style 1. 11293 result = pathname.match( /\/page\/(\d+)/ ); 11294 if ( result ) { 11295 isPagedExist = true; 11296 pagedId = ( result.hasOwnProperty( 1 ) ) ? result[1] : 1; 11297 } 11298 11299 // Search based on style 2. 11300 if ( ! isPagedExist && search ) { 11301 result = search.match( /page\=(\d+)/ ); 11302 if ( result ) { 11303 isPagedExist = true; 11304 pagedId = ( result.hasOwnProperty( 1 ) ) ? result[1] : 1; 11305 } 11306 } 11307 11308 return pagedId; 11309 } 11310 }; 11311 11312}(jQuery)); 11313(function( $ ) { 11314 'use strict'; 11315 11316 var val = MK.val, 11317 utils = MK.utils; 11318 11319 MK.component.Parallax = function( el ) { 11320 var self = this, 11321 $this = $( el ), 11322 obj = $this[0], 11323 $window = $( window ), 11324 container = document.getElementById( 'mk-theme-container' ), 11325 config = $this.data( 'parallax-config' ), 11326 $holder = $( config.holder ), 11327 headerHeight = null, 11328 offset = null, 11329 elHeight = null, 11330 ticking = false, 11331 isMobile = null; 11332 11333 11334 var clientRect = null; 11335 11336 var update = function() { 11337 // Clear styles to check for natural styles 11338 // then apply position and size 11339 obj.style.transform = null; 11340 obj.style.top = null; 11341 obj.style.bottom = null; 11342 11343 isMobile = MK.utils.isMobile(); 11344 11345 if( isMobile ) { 11346 $this.css( 'height', '' ); 11347 return; 11348 } 11349 11350 clientRect = $this[ 0 ].getBoundingClientRect(); 11351 offset = clientRect.top; 11352 elHeight = clientRect.height; 11353 headerHeight = val.offsetHeaderHeight( offset ); 11354 offset = offset - headerHeight + val.scroll(); 11355 11356 setPosition(); 11357 setSize( ); 11358 }; 11359 11360 11361 var h = 0, 11362 winH = 0, 11363 proportion = 0, 11364 height = 0; 11365 11366 // Position and background attachement should me moved to CSS but we repair it high specificity here as styles are not reliable currently 11367 var setSize = function() { 11368 $this.css( 'height', '' ); 11369 winH = $window.height() - headerHeight; 11370 h = obj.getBoundingClientRect().height; 11371 11372 if( config.speed <= 1 && config.speed > 0 ) { 11373 if( offset === 0 ) { 11374 $this.css({ 11375 backgroundAttachment: 'scroll', 11376 'will-change': 'transform' 11377 }); 11378 } else { 11379 $this.css({ 11380 height : h + ( (winH - h) * config.speed ), 11381 backgroundAttachment: 'scroll', 11382 'will-change': 'transform' 11383 }); 11384 } 11385 11386 } else if ( config.speed > 1 && h <= winH ) { 11387 $this.css({ 11388 // good for full heights - 2 because it's viewable by 2 screen heights 11389 height: ( winH + ( ( winH * config.speed ) - winH ) * 2 ), 11390 top: -( ( winH * config.speed ) - winH ), 11391 backgroundAttachment: 'scroll', 11392 'will-change': 'transform' 11393 }); 11394 11395 } else if ( config.speed > 1 && h > winH ) { 11396 proportion = h / winH; 11397 height = ( winH + ( ( winH * config.speed ) - winH ) * (1 + proportion) ); 11398 11399 $this.css({ 11400 height: height, 11401 top: -( height - (winH * config.speed) ), 11402 backgroundAttachment: 'scroll', 11403 'will-change': 'transform' 11404 }); 11405 11406 } else if ( config.speed < 0 && h >= winH ) { 11407 height = h * (1 - config.speed); 11408 $this.css({ 11409 height: height + (height - h), 11410 top: h - height, 11411 backgroundAttachment: 'scroll', 11412 'will-change': 'transform' 11413 }); 11414 11415 } else if ( config.speed < 0 && h < winH ) { 11416 // candidate to change 11417 var display = (winH + h) / winH; 11418 height = h * -config.speed * display; 11419 $this.css({ 11420 height: h + (height * 2), 11421 top: -height, 11422 backgroundAttachment: 'scroll', 11423 'will-change': 'transform' 11424 }); 11425 } 11426 }; 11427 11428 11429 var currentPoint = null, 11430 progressVal = null, 11431 startPoint = null, 11432 endPoint = null, 11433 $opacityLayer = config.opacity ? $this.find( config.opacity ) : null, 11434 scrollY = null; 11435 11436 var setPosition = function() { 11437 startPoint = offset - winH; 11438 endPoint = offset + elHeight + winH - headerHeight; 11439 scrollY = val.scroll(); 11440 11441 if( scrollY < startPoint || scrollY > endPoint ) { 11442 ticking = false;
11443 return; 11444 } 11445 11446 currentPoint = (( -offset + scrollY ) * config.speed); 11447 11448 $this.css({ 11449 '-webkit-transform': 'translateY(' + currentPoint + 'px) translateZ(0)', 11450 '-moz-transform': 'translateY(' + currentPoint + 'px) translateZ(0)', 11451 '-ms-transform': 'translateY(' + currentPoint + 'px) translateZ(0)', 11452 '-o-transform': 'translateY(' + currentPoint + 'px) translateZ(0)', 11453 'transform': 'translateY(' + currentPoint + 'px) translateZ(0)' 11454 }); 11455 11456 ticking = false; 11457 }; 11458 11459 11460 var requestTick = function() { 11461 if( !ticking && !isMobile ) { 11462 ticking = true; 11463 window.requestAnimationFrame( setPosition ); 11464 } 11465 }; 11466 11467 11468 var init = function() { 11469 // Disable scroll effects when smooth scroll is disabled 11470 if( !MK.utils.isSmoothScroll ) { return; } 11471 11472 update(); 11473 setTimeout(update, 100); 11474 $window.on( 'load', update ); 11475 $window.on( 'resize', update ); 11476 window.addResizeListener( container, update ); 11477 11478 $window.on( 'scroll', requestTick ); 11479 }; 11480 11481 11482 return { 11483 init : init 11484 }; 11485 }; 11486 11487})( jQuery ); 11488(function($) { 11489 'use strict'; 11490 11491 MK.component.Preloader = function(el) { 11492 this.el = el; 11493 }; 11494 11495 MK.component.Preloader.prototype = { 11496 init: function init() { 11497 this.cacheElements(); 11498 this.bindEvents(); 11499 }, 11500 11501 cacheElements: function cacheElements() { 11502 this.$preloader = $(this.el); 11503 }, 11504 11505 bindEvents: function bindEvents() { 11506 this.onLoad(); // all components inited on page load 11507 }, 11508 11509 onLoad: function onLoad() { 11510 setTimeout(this.hidePreloader.bind(this), 300); 11511 }, 11512 11513 hidePreloader: function hidePreloader() { 11514 this.$preloader.hide(); 11515 } 11516 }; 11517 11518}(jQuery)); 11519 11520(function($) { 11521 'use strict'; 11522 11523 // Image added for proportional scaling 11524 MK.ui.loader = { 11525 tpl : function() { 11526 return '<div class="mk-loading-indicator">' + 11527 '<div class="mk-loading-indicator__inner">' + 11528 '<div class="mk-loading-indicator__icon"></div>' + 11529 '<img style="height:100%; width:auto;" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">' + 11530 '</div>' + 11531 '</div>'; 11532 }, 11533 11534 add : function(item) { 11535 $(item).append(this.tpl); 11536 }, 11537 11538 remove : function(item) { 11539 if(item) $(item).find('.mk-loading-indicator').remove(); 11540 else $('.mk-loading-indicator').remove(); 11541 } 11542 }; 11543 11544}(jQuery)); 11545(function( $ ) { 11546 // IE / Edge fix for fixed positioned elements 11547 // MS clip path doesnt redraw properly so we expirience similar bug like with background attachement fixed on Chrome 11548 if (MK.utils.browser.name === 'Edge' || MK.utils.browser.name === 'IE') { 11549 var val = 1; 11550 var $edgeClipper = $('.mk-slider-slide'); // edge slider 11551 var $sectionClipper = $('.clipper-true'); // edge slider 11552 var $bgLayer = $('.background-layer'); // page section 11553 11554 var onScroll = function onScroll() { 11555 val *= -1; 11556 if( $edgeClipper.length ) $edgeClipper.each( redraw ); 11557 if( $sectionClipper.length ) $sectionClipper.each( redraw ); 11558 if( $bgLayer.length ) $bgLayer.each( redraw ); 11559 }; 11560 11561 var redraw = function redraw() { 11562 $(this).css('margin-top', val / 100); 11563 }; 11564 11565 $(window).on("scroll", function () { 11566 window.requestAnimationFrame(onScroll); 11567 }); 11568 } 11569}(jQuery)); 11570(function( $ ) { 11571 'use strict'; 11572 11573 var utils = MK.utils; 11574 var val = MK.val; 11575 11576 /** 11577 * Keep track of top Level sections so we can easly skip to next one. 11578 * We must be explicit about DOM level to nested sections. 11579 * 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). 11580 * We keep track for the same sections in Footer for mutating window location with '!loading' to prevent native anchor behaviour. 11581 */ 11582 var $topLevelSections = $('#theme-page > .vc_row, #theme-page > .mk-main-wrapper-holder, #theme-page > .mk-page-section'); 11583 11584 $( document ).on( 'click', '.mk-skip-to-next', function() { 11585 var $this = $( this ), 11586 /** 11587 * Static height of button + the space to the bottom of the container. 11588 * 11589 * @TODO Possible to calculate dynamically. 11590 */ 11591 btnHeight = $this.hasClass( 'edge-skip-slider' ) ? 150 : 76, 11592 offset = $this.offset().top + btnHeight,
11593 nextOffset = utils.nextHigherVal( utils.offsets( $topLevelSections ), [offset] ); 11594 11595 utils.scrollTo( nextOffset - val.offsetHeaderHeight( nextOffset ) ); 11596 }); 11597 11598})( jQuery ); 11599 11600MK.component.ResponsiveImageSetter = (function ($) { 11601 11602 'use strict'; 11603 11604 var module = {}; 11605 11606 11607 /*---------------------------------------------------------------------------------*/ 11608 /* Private Variables 11609 /*---------------------------------------------------------------------------------*/ 11610 11611 var viewportClass = getViewportClass(); 11612 var isRetina = window.devicePixelRatio >= 2; 11613 11614 11615 /*---------------------------------------------------------------------------------*/ 11616 /* Private Methods 11617 /*---------------------------------------------------------------------------------*/ 11618 11619 function run($imgs) { 11620 $imgs.filter( function() { 11621 return !this.hasAttribute("mk-img-src-setted"); 11622 }).each(setSrcAttr); 11623 } 11624 11625 function setSrcAttr() { 11626 var $img = $(this); 11627 var set = $img.data('mk-image-src-set'); 11628 // Set src attribute to img link suitable for our logic. It will load the image. 11629 if(set['responsive'] === 'false' && isRetina && set['2x']) $img.attr('src', set['2x']); 11630 else if(set['responsive'] === 'false') $img.attr('src', set.default); 11631 else if(viewportClass === 1 && isRetina && set['2x']) $img.attr('src', set['2x']); // default x2 for retina 11632 else if(viewportClass === 0 && set.mobile) $img.attr('src', set.mobile); 11633 else $img.attr('src', set.default); 11634 11635 $img.load(function() { 11636 $(window).trigger('mk-image-loaded') 11637 }) 11638 } 11639 11640 function getViewportClass() { 11641 if(window.matchMedia('(max-width: 736px)').matches) return 0; 11642 else return 1; 11643 } 11644 11645 function handleResize($imgs) { 11646 if(!$imgs.length) return; // Do not run if empty collection 11647 var currentViewportClass = getViewportClass(); 11648 // We don't need to reload bigger images when screen size is decreasing as browser already performs resize operation. 11649 // Run update on for increasing screen size 11650 if( currentViewportClass > viewportClass) { 11651 viewportClass = currentViewportClass; // update for further reference 11652 run($imgs); 11653 } 11654 } 11655 11656 11657 /*---------------------------------------------------------------------------------*/ 11658 /* Public Methods 11659 /*---------------------------------------------------------------------------------*/ 11660 11661 module.init = function ($imgs) { 11662 11663 // Do not run if empty collection 11664 if(!$imgs.length) return; 11665 11666 // Run and bind to events 11667 run($imgs); 11668 $imgs.attr('mk-img-src-setted', ''); 11669 11670 }; 11671 11672 module.onResize = function ($imgs) { 11673 11674 $(window).on( 'resize', MK.utils.throttle( 500, function() { 11675 handleResize($imgs); 11676 })); 11677 11678 11679 }; 11680 11681 11682 module.handleAjax = function () { 11683 setTimeout(function ajaxDelayedCallback() { // give it a chance to insert content first 11684 var $newImgs = $('img[data-mk-image-src-set]').filter( function() { 11685 return !this.hasAttribute("mk-lazyload"); 11686 }); 11687 if(!$newImgs.length) return; 11688 run($newImgs); 11689 }, 100); 11690 } 11691 11692 11693 return module; 11694 11695}(jQuery)); 11696 11697 11698jQuery(function($) { 11699 11700 var init = function init() { 11701 // Get All Responsive Images 11702 $allImages = $('img[data-mk-image-src-set]').filter(function(index) { 11703 var isNotPortfolioImage = !$(this).hasClass('portfolio-image'), 11704 isNotBlogImage = $(this).closest('.mk-blog-container').length == 0, 11705 isNotSwiperImage = !$(this).hasClass('swiper-slide-image'), 11706 isNotGalleryImage = !$(this).hasClass('mk-gallery-image'); 11707 return isNotPortfolioImage && isNotBlogImage && isNotSwiperImage && isNotGalleryImage; 11708 });; 11709 11710 // Handle the resize 11711 MK.component.ResponsiveImageSetter.onResize($allImages); 11712 11713 MK.component.ResponsiveImageSetter.init($allImages); 11714 11715 MK.utils.eventManager.subscribe('ajaxLoaded', MK.component.ResponsiveImageSetter.handleAjax ); // ajax loops 11716 MK.utils.eventManager.subscribe('ajax-preview', MK.component.ResponsiveImageSetter.handleAjax ); // ajax portfolio 11717 MK.utils.eventManager.subscribe('quickViewOpen', MK.component.ResponsiveImageSetter.handleAjax ); 11718 }
11719 init(); 11720 $(window).on('vc_reload', init); 11721 11722}); 11723 11724 11725 11726/* Social Share */ 11727/* -------------------------------------------------------------------- */ 11728(function($) { 11729 'use strict'; 11730 11731 MK.component.SocialShare = function( el ) { 11732 var networks = { 11733 twitter : 'http://twitter.com/intent/tweet?text={title} {url}', 11734 pinterest : 'http://pinterest.com/pin/create/button/?url={url}&media={image}&description={title}', 11735 facebook : 'https://www.facebook.com/sharer/sharer.php?u={url}', 11736 googleplus : 'https://plus.google.com/share?url={url}', 11737 linkedin : 'http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}&summary={desc}', 11738 digg : 'http://digg.com/submit?url={url}&title={title}', 11739 reddit : 'http://reddit.com/submit?url={url}&title={title}', 11740 }; 11741 11742 this.networks = networks; 11743 this.el = el; 11744 }; 11745 11746 11747 MK.component.SocialShare.prototype = { 11748 11749 init : function() { 11750 this.cacheElements(); 11751 this.bindEvents(); 11752 }, 11753 11754 cacheElements : function() { 11755 this.$this = $( this.el ); 11756 11757 11758 }, 11759 11760 bindEvents : function() { 11761 var thisObject = this; 11762 var tempClass = ""; 11763 $.each(this.networks, function( key, value ) { 11764 thisObject.$tempClass = $('.' + key + '-share'); 11765 thisObject.$tempClass.click(thisObject.openSharingDialog.bind(self, this, key)); 11766 11767 }); 11768 }, 11769 11770 openSharingDialog : function(url, site, args) { 11771 var urlWrapper = url; 11772 var rx = new RegExp('\{[a-z]*\}','g'), res; 11773 var match = rx.exec(url); 11774 while (match != null) { 11775 var pureAttr = match[0].replace("{", "").replace("}" , ""); 11776 var attValue = $(args.currentTarget).attr('data-' + pureAttr); 11777 if (attValue === undefined || attValue === null) { 11778 attValue = ""; 11779 } 11780 attValue = attValue.replace('#', '%23'); // fix for twitter description 11781 urlWrapper = urlWrapper.replace(match, attValue); 11782 match = rx.exec(url); 11783 } 11784 11785 window.open(urlWrapper, site + "Window", "height=320,width=660,resizable=0,toolbar=0,menubar=0,status=0,location=0,scrollbars=0"); 11786 11787 }, 11788 11789 11790 }; 11791 11792 11793 ////////////////////////////////////////// 11794 // 11795 // Apply to: 11796 // 11797 // /////////////////////////////////////// 11798 11799 var $body = $('body'); 11800 11801 if(!$body.length) return; 11802 11803 $body.each(function() { 11804 var socialShare = new MK.component.SocialShare(this); 11805 socialShare.init(); 11806 }); 11807 11808})(jQuery); 11809 11810 11811 11812//function mk_social_share() { 11813// 11814// "use strict";
11815// 11816// $('.twitter-share').on('click', function () { 11817// var $url = $(this).attr('data-url'), 11818// $title = $(this).attr('data-title'); 11819// 11820// 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"); 11821// return false; 11822// }); 11823// 11824// $('.pinterest-share').on('click', function () { 11825// var $url = $(this).attr('data-url'), 11826// $title = $(this).attr('data-title'), 11827// $image = $(this).attr('data-image'); 11828// 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"); 11829// return false; 11830// }); 11831// 11832// $('.facebook-share').on('click', function () { 11833// var $url = $(this).attr('data-url'); 11834// 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"); 11835// return false; 11836// }); 11837// 11838// $('.googleplus-share').on('click', function () { 11839// var $url = $(this).attr('data-url'); 11840// 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"); 11841// return false; 11842// }); 11843// 11844// $('.linkedin-share').on('click', function () { 11845// var $url = $(this).attr('data-url'), 11846// $title = $(this).attr('data-title'), 11847// $desc = $(this).attr('data-desc'); 11848// 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"); 11849// return false; 11850// }); 11851//} 11852 11853 11854 11855 11856(function($) { 11857 'use strict'; 11858 11859 // 11860 // Constructor 11861 // 11862 // ///////////////////////////////////////////////////////// 11863 11864 MK.ui.Slider = function( container, config ) { 11865 11866 var defaults = { 11867 slide : '.mk-slider-slide', 11868 nav : '.mk-slider-nav', 11869 effect : 'roulete', 11870 ease : 'easeOutQuart', // should not be changed, remove 11871 slidesPerView : 1, 11872 slidesToView : 1, 11873 transitionTime : 700, 11874 displayTime : 3000, 11875 autoplay : true, 11876 hasNav : true, 11877 hasPagination : true, 11878 paginationTpl : '<span></span>', 11879 paginationEl : '#pagination', 11880 draggable : true, 11881 fluidHeight : false, 11882 pauseOnHover : false, 11883 lazyload : false, 11884 activeClass : 'is-active', 11885 edgeSlider : false, 11886 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>', 11887 onInitialize : function() {}, 11888 onAfterSlide : function( id ) {}, 11889 onBeforeSlide : function( id ) {} 11890 }; 11891 11892 this.state = { 11893 id : 0, 11894 moveForward : true, 11895 running : false, 11896 zIFlow : null, 11897 stop : false, 11898 }; 11899 11900 this.config = $.extend( defaults, config ); 11901 this.container = container; 11902 11903 this.initPerView = this.config.slidesPerView; 11904 11905 // Timer holder 11906 this.activeTimer = null; 11907 this.autoplay = null; 11908 this.timer = null; 11909 this.timerRemaining = parseInt(this.config.displayTime); 11910 11911 // Boolean 'Em All, Making sure it's not string 11912 this.config.lazyload = JSON.parse(this.config.lazyload); 11913 this.config.edgeSlider = JSON.parse(this.config.edgeSlider); 11914 11915 // Image Loader Instance 11916 this.imageLoader = null; 11917 11918 // Add abort command to imagesLoaded, Placing it inside script makes it to work with different versions 11919 // of imagesLoaded if loaded by other Plugins 11920 imagesLoaded.prototype.abort = function() { 11921 this.progress = this.complete = function() { }; 11922 }; 11923 }; 11924 11925 11926 11927 // 11928 // Shared methods 11929 // 11930 // ///////////////////////////////////////////////////////// 11931 11932 MK.ui.Slider.prototype = { 11933 11934 init : function() { 11935 this.setPerViewItems(); 11936 this.cacheElements();
11937 this.getSlideSize(); 11938 this.bindEvents(); 11939 this.setSize(); 11940 this.setPos(); 11941 11942 // Hack for preparing 'prev' on first click if needed 11943 this.updateId( -1 ); 11944 this.updateId( 1 ); 11945 11946 this.val = this.dynamicVal(); 11947 this.timeline = this.prepareTimeline( this.config.transitionTime ); 11948 11949 this.timeline.build(); 11950 11951 if( this.config.hasPagination ) { this.buildPagination(); } 11952 11953 if( this.config.autoplay && document.hasFocus() ) { this.setTimer(); } 11954 11955 if( typeof this.config.onInitialize === 'function' ) { 11956 this.config.onInitialize( this.slides ); 11957 } 11958 11959 if( this.config.fluidHeight === true ) { 11960 $( this.slides ).height( 'auto' ); 11961 $( this.container ).css( 'transition', 'height ' + 200 + 'ms ease-out' ); 11962 this.setHeight( 0 ); 11963 } 11964 11965 11966 if( this.config.fluidHeight === 'toHighest' ) { 11967 this.setHeightToHighest(); 11968 } 11969 11970 // Create timer per slide if required 11971 $(this.slides).each(this.createTimer); 11972 11973 // If it's Edge Slider and Lazy Load is enabled 11974 if ( this.config.lazyload && this.config.edgeSlider ) { 11975 11976 // If It's not a Video Slide 11977 if ( $(this.slides[this.state.id]).find('video').length === 0 ) { 11978 // Set the first slide's BG image 11979 var $slideImg = $(this.slides[this.state.id]).children('[data-mk-img-set]'); 11980 MK.component.BackgroundImageSetter.init( $slideImg ); 11981 } 11982 $(this.config.spinnerTpl).prependTo( this.$slides ); 11983 11984 } else { 11985 11986 // Set all slides's BG images 11987 MK.component.BackgroundImageSetter.init( $(this.slides).children('[data-mk-img-set]') ); 11988 11989 } 11990 11991 11992 11993 }, 11994 11995 11996 cacheElements : function () { 11997 this.container = this.isNode( this.container ) ? this.container 11998 : document.querySelectorAll( this.container )[0]; 11999 this.slides = this.container.querySelectorAll( this.config.slide ); 12000 this.$slides = $(this.slides); 12001 12002 if( this.config.hasNav ) { this.$nav = $( this.config.nav ); } 12003 if( this.config.hasPagination ) { this.$pagination = $( this.config.paginationEl ); } 12004 }, 12005 12006 12007 bindEvents : function() { 12008 var $window = $( window ); 12009 12010 if( this.config.slidesPerView > 1 ) { $window.on( 'resize', this.setPerViewItems.bind( this ) ); } 12011 if( this.config.hasNav ) { this.eventsNav(); } 12012 if( this.config.hasPagination ) { this.eventsPag(); } 12013 if( this.config.draggable ) { this.dragHandler(); } 12014 if( this.config.autoplay ) { 12015 $window.on( 'focus', this.windowActive.bind( this ) ); 12016 $window.on( 'blur', this.windowInactive.bind( this ) ); 12017 } 12018 if( this.config.pauseOnHover ) { 12019 $(this.container).on( 'mouseleave', this.setTimer.bind( this ) ); 12020 $(this.container).on( 'mouseenter', this.unsetTimer.bind( this ) ); 12021 } 12022 if( this.config.fluidHeight === 'toHighest' ) { 12023 $window.on( 'resize', this.setHeightToHighest.bind( this ) ); 12024 } 12025 }, 12026 12027 12028 setPerViewItems: function() { 12029 if(window.matchMedia( '(max-width: 500px)' ).matches) { this.config.slidesPerView = 1; } 12030 else if(window.matchMedia( '(max-width: 767px)' ).matches && this.initPerView >= 2 ) { this.config.slidesPerView = 2; } 12031 else if(window.matchMedia( '(max-width: 1024px)' ).matches && this.initPerView >= 3 ) { this.config.slidesPerView = 3; } 12032 else { this.config.slidesPerView = this.initPerView; } 12033 12034 if( typeof this.slides === 'undefined' ) return; 12035 this.getSlideSize(); 12036 this.setSize(); 12037 this.setPos(); 12038 this.timeline = this.prepareTimeline( this.config.transitionTime ); 12039 this.timeline.build(); 12040 }, 12041 12042 12043 eventsNav : function() { 12044 this.$nav.on( 'click', 'a', this.handleNav.bind( this ) ); 12045 }, 12046 12047 12048 eventsPag : function() { 12049 this.$pagination.on( 'click', 'a', this.handlePagination.bind( this ) ); 12050 }, 12051 12052 12053 handleNav : function( e ) { 12054 e.preventDefault(); 12055 12056 if( this.state.running ) { return; } 12057 this.state.running = true; 12058 12059 var $this = $( e.currentTarget ), 12060 moveForward = $this.data( 'direction' ) === 'next'; 12061 12062 12063 if( this.config.autoplay ) { 12064 this.unsetTimer(); 12065 setTimeout( this.setTimer.bind( this ), this.config.transitionTime ); 12066 } 12067 12068 this.state.moveForward = moveForward; 12069 this.timeline.build(); 12070 this.timeline.play(); 12071 12072 this.setActive( this.nextId( moveForward ? 1 : -1 ) ); 12073 if( this.config.fluidHeight ) { this.setHeight( this.nextId( moveForward ? 1 : -1 ) ); } 12074 }, 12075 12076 12077 handlePagination : function( e ) { 12078 e.preventDefault(); 12079 12080 var $this = $( e.currentTarget ), 12081 id = $this.index(); 12082 12083 this.goTo( id ); 12084 }, 12085 12086 12087 reset: function() { 12088 this.state.stop = true; 12089 this.state.id = 0; 12090 this.setPos(); 12091 this.unsetTimer(); 12092 this.setTimer(); 12093 }, 12094 12095 12096 goTo : function(id) { 12097 if( this.state.running ) { return; } 12098 this.state.running = true; 12099 12100 var lastId = this.state.id; 12101 12102 if( lastId === id ) { 12103 return; 12104 } else if( lastId < id ) { 12105 this.state.moveForward = true; 12106 } else { 12107 this.state.moveForward = false;
12108 } 12109 12110 if( this.config.autoplay ) { 12111 this.unsetTimer(); 12112 setTimeout( this.setTimer.bind( this ), this.config.transitionTime ); 12113 } 12114 12115 this.timeline.build( Math.abs( lastId - id ) ); 12116 this.timeline.play(); 12117 12118 this.setActive( id ); 12119 if( this.config.fluidHeight ) { this.setHeight( id ); } 12120 }, 12121 12122 12123 windowActive : function() { 12124 this.setTimer(false, true); 12125 $(this.container).removeClass('is-paused'); 12126 }, 12127 12128 12129 windowInactive : function() { 12130 this.unsetTimer(); 12131 $(this.container).addClass('is-paused'); 12132 }, 12133 12134 12135 updateId : function( val ) { 12136 this.state.id = this.nextId(val); 12137 }, 12138 12139 nextId : function( val ) { 12140 var len = this.slides.length, 12141 insertVal = this.state.id + val; 12142 insertVal = ( insertVal >= 0 ) ? insertVal : len + val; 12143 insertVal = ( insertVal >= len ) ? 0 : insertVal; 12144 12145 return insertVal; 12146 }, 12147 12148 12149 setStyle : function( obj, style ) { 12150 var hasT = style.transform, 12151 t = { 12152 x : ( hasT ) ? style.transform.translateX : null, 12153 y : ( hasT ) ? style.transform.translateY : null, 12154 scale : ( hasT ) ? style.transform.scale : null, 12155 rotate : ( hasT ) ? style.transform.rotate : null, 12156 rotateX : ( hasT ) ? style.transform.rotateX : null, 12157 rotateY : ( hasT ) ? style.transform.rotateY : null 12158 }, 12159 z = 'translateZ(0)', 12160 x = (t.x) ? 'translateX(' + t.x + '%)' : 'translateX(0)', 12161 y = (t.y) ? 'translateY(' + t.y + '%)' : 'translateY(0)', 12162 s = (t.scale) ? 'scale(' + t.scale + ')' : 'scale(1)', 12163 r = (t.rotate) ? 'rotate(' + t.rotate + 'deg)' : 'rotate(0)', 12164 rX = (t.rotateX) ? 'rotateX(' + t.rotateX + 'deg)' : '', 12165 rY = (t.rotateY) ? 'rotateY(' + t.rotateY + 'deg)' : '', 12166 12167 o = style.opacity, 12168 h = style.height, 12169 w = style.width; 12170 12171 var c = z + x + y + s + r + rX + rY; 12172 12173 if( c.length ) { 12174 obj.style.webkitTransform = c; 12175 obj.style.msTransform = c; 12176 obj.style.transform = c; 12177 } 12178 12179 if( typeof o === 'number' ) { obj.style.opacity = o; } 12180 if( h ) { obj.style.height = h + '%'; } 12181 if( w ) { obj.style.width = w + '%'; } 12182 }, 12183 12184 12185 setPos : function() { 12186 if( typeof this.slides === 'undefined' ) return; 12187 var id = this.state.id, 12188 i = 0, 12189 len = this.slides.length, 12190 animation = this.animation[ this.config.effect ], 12191 axis = animation.axis, 12192 animNext = animation.next, 12193 animActi = animation.active, 12194 animPrev = animation.prev, 12195 perView = this.config.slidesPerView, 12196 slideId = null, 12197 zIFlow = null, 12198 style = {}; 12199 12200 style.transform = {}; 12201 12202 12203 for( ; i < len; i += 1 ) { 12204 if(i < perView) { 12205 // Position for visible slides. Apply active styles 12206 style = animActi; 12207 style.transform[ 'translate' + axis ] = i * 100; 12208 } else { 12209 // Rest slides move after edge based on axis and moveForward. Apply Next / Prev styles 12210 style = this.state.moveForward ? animNext : animPrev; 12211 style.transform[ 'translate' + axis ] = this.state.moveForward ? perView * 100 : -100; 12212 } 12213 12214 this.slides[ i ].style.zIndex = 0; 12215 12216 slideId = ( i + id ) % len; 12217 this.setStyle( this.slides[ slideId ], style ); 12218 } 12219 }, 12220 12221 12222 // When we're setting animation along Y axis we're going to set up height 12223 // otherwise width. It is shared amongst all slides 12224 setSize : function() { 12225 if( typeof this.slides === 'undefined' ) return; 12226 var i = 0, 12227 len = this.slides.length, 12228 axis = this.animation[ this.config.effect ].axis, 12229 slideSize = this.slideSize, 12230 style = {}; 12231 12232 if( axis === 'Y' ) { 12233 style.height = slideSize[ axis ]; 12234 } else { 12235 style.width = slideSize[ axis ]; 12236 } 12237 12238 for( ; i < len; i += 1 ) { 12239 this.setStyle( this.slides[ i ], style ); 12240 } 12241 }, 12242 12243 12244 setHeight : function( id ) { 12245 var $slides = $( this.slides ), 12246 $activeSlide = $slides.eq( id ); 12247 12248 var currentHeight = $activeSlide.height(); 12249 $( this.container ).height( currentHeight ); 12250 }, 12251 12252 12253 setHeightToHighest : function() { 12254 // this is becouse of alliginig woocommrece carousel. Too much DOM 12255 // Refactor someday 12256 var $slides = $( this.slides ), 12257 height = 0; 12258 12259 $slides.each(function() { 12260 height = Math.max(height, $(this).find('> div').outerHeight()); 12261 }); 12262 12263 $( this.container ).height( height ); 12264 }, 12265 12266 12267 // Little utility inspired by GreenSock. 12268 // We export this to this.timeline on init. 12269 prepareTimeline : function( time ) { 12270 var self = this, 12271 iteration = 0, 12272 totalIter = time / (1000 / 60), 12273 animLoop = [], 12274 aL = 0, // animation length 12275 loops = 1, 12276 ease = this.config.ease, 12277 currentStyle, timeProg, 12278 build, move, add, play, reverse, progress, kill; 12279 12280 12281 // Build constants, run them only once 12282 // take out possibly 12283 var len = this.slides.length, 12284 perView = this.config.slidesPerView, 12285 animation = this.animation[ this.config.effect ], 12286 animAxis = animation.axis, 12287 animNext = animation.next, 12288 animActi = animation.active, 12289 animPrev = animation.prev, 12290 style = {}, 12291 slideId = null, 12292 zIFlow = null; 12293 12294 style.transform = {}; 12295 12296 12297 build = function( repeats ) { 12298 var currentEase = ease; 12299 loops = repeats || loops; 12300 12301 // console.log('build', loops); 12302 12303 if( !loops ) { return; } 12304 if( loops > 1 ) { 12305 currentEase = 'linearEase'; 12306 } 12307 12308 // clean before running new build 12309 kill(); 12310 // set new positions 12311 self.setPos(); 12312 12313 var id = self.state.id, 12314 moveForward = self.state.moveForward, 12315 i = 0, 12316 axisMove = (moveForward) ? -100 : 100; 12317
12318 for( ; i <= perView; i += 1 ) { 12319 slideId = ( (moveForward) ? i + id : i + id - 1 ) % len; 12320 slideId = ( slideId < 0 ) ? len + slideId : slideId; 12321 12322 if( i === 0 ) { 12323 style = moveForward ? animPrev : animActi; 12324 } else if( i === perView ) { 12325 style = moveForward ? animActi : animNext; 12326 } else { 12327 style = animActi; 12328 } 12329 12330 zIFlow = (self.state.moveForward) ? animNext.zIndex : animPrev.zIndex; 12331 if( zIFlow ) { 12332 // console.log( zIFlow ); 12333 self.slides[ slideId ].style.zIndex = (zIFlow === '+') ? i + 1 : len - i; 12334 } 12335 12336 style.transform[ 'translate' + animAxis ] = axisMove; 12337 add( self.slides[ slideId ], style, currentEase ); 12338 } 12339 }; 12340 12341 add = function( slide, toStyles, ease ) { 12342 if( typeof slide === 'undefined' ) { 12343 throw 'Add at least one slide'; 12344 } 12345 12346 var fromStyles = slide.style, 12347 style = self.refStyle( toStyles, fromStyles ); 12348 12349 animLoop.push( [slide, style, ease] ); 12350 aL += 1; 12351 }; 12352 12353 move = function( startProg, mode ) { 12354 if (isTest) return; 12355 var currentTotalIter = totalIter; 12356 12357 if( loops > 1 ) { 12358 currentTotalIter = totalIter / 5; 12359 } 12360 12361 if( !self.state.running ) { self.state.running = true; } 12362 12363 if( startProg ) { 12364 // update iteration val to cached outside var 12365 // ceil to handle properly play after mouse up / touch end 12366 iteration = Math.ceil(startProg * currentTotalIter); 12367 } 12368 12369 timeProg = iteration / currentTotalIter; 12370 progress( timeProg ); 12371 12372 // Break loop 12373 if( iteration >= currentTotalIter && mode === 'play' || 12374 iteration <= 0 && mode === 'reverse' ) { 12375 12376 self.state.running = false; 12377 iteration = 0; 12378 kill(); 12379 self.updateId( self.state.moveForward ? 1 : -1 ); 12380 // If we're creating multiple animation loop we trigger outside only first pass to start all game. 12381 // the rest are triggered as callback 12382 loops -= 1; 12383 if( loops > 0 ) { 12384 build(); 12385 play(); 12386 } 12387 12388 // if we run all loops reset back the default value 12389 if( !loops ) { 12390 loops = 1; 12391 self.timerRemaining = parseInt(self.config.displayTime); 12392 self.config.onAfterSlide( self.state.id ); 12393 } 12394 12395 return; 12396 } 12397 12398 // Run in given mode 12399 if( mode === 'play') { 12400 iteration += 1; 12401 } else { 12402 iteration -= 1; 12403 } 12404 12405 requestAnimationFrame( function() { 12406 if(self.state.stop) return; 12407 move( 0, mode ); 12408 }); 12409 }; 12410 12411 play = function( startProg ) { 12412 12413 var $nextSlide = $(self.slides[ self.nextId(self.state.moveForward ? 1 : -1) ] ); 12414 12415 // If it's Edge Slider and Lazy Load is enabled and It's not a Video Slide 12416 if ( self.config.lazyload && self.config.edgeSlider ) { 12417 12418 // Set the next slide's BG Image 12419 var $slideImg = $nextSlide.find('[data-mk-img-set]'); 12420 if ( $slideImg.length ) { 12421 MK.component.BackgroundImageSetter.init( $slideImg ); 12422 } 12423 12424 } 12425 12426 self.config.onBeforeSlide( self.nextId(self.state.moveForward ? 1 : -1) ); 12427 var start = startProg || 0; 12428 iteration = 0; 12429 self.state.stop = false; 12430 move( start, 'play' ); 12431 12432 }; 12433 12434 reverse = function( startProg ) { 12435 var start = startProg || 1; 12436 move( start, 'reverse' ); 12437 }; 12438 12439 progress = function( progVal ) { 12440 var aI = 0, 12441 currentStyle; 12442 12443 for( aI; aI < aL; aI++ ) { 12444 if( progVal !== 1 && progVal !== 0 ) { 12445 currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], animLoop[ aI ][ 2 ] ); 12446 } else if( progVal === 1) { 12447 currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], 'linearEase' ); 12448 } else if ( progVal === 0 ) { 12449 currentStyle = self.currentStyle( progVal, animLoop[ aI ][ 1 ], 'linearEase' ); 12450 } 12451 self.setStyle( animLoop[ aI ][ 0 ], currentStyle ); 12452 } 12453 }; 12454 12455 // Clear previous loop 12456 kill = function() { 12457 animLoop = []; 12458 aL = 0; 12459 }; 12460 12461 12462 return { 12463 build : build, 12464 add : add, 12465 play : play, 12466 reverse : reverse, 12467 progress : progress 12468 }; 12469 }, 12470 12471 12472 // Build reference styles. 12473 // Return object with array containig initial style and change of its value 12474 // as required for easing functions 12475 refStyle : function( toStyles, fromStyles ) { 12476 var axis = this.animation[ this.config.effect ].axis, 12477 style = {}, 12478 initVal, changeVal, endVal, dynamicEnd, styleProp, transProp, transform; 12479 12480 for( styleProp in toStyles ) { 12481 12482 if( styleProp === 'transform' ) { 12483 transform = this.getTransforms( fromStyles ); 12484 style.transform = {}; 12485 12486 for( transProp in toStyles.transform ) { 12487 // don't care about z 12488 if( transProp === 'translateZ' ) { continue; } 12489 12490 initVal = transform[ transProp ] || 0; // if it is undefined it means it's 0 12491 dynamicEnd = ( transProp === 'translate' + axis ) ? initVal : 0; 12492 endVal = toStyles.transform[ transProp ] + dynamicEnd; // it is dynamic, based on slide position in current set 12493 changeVal = endVal - initVal; 12494 style.transform[ transProp ] = [ initVal, changeVal ]; 12495 } 12496 } else if( styleProp === 'zIndex' ) { 12497 // console.log( 'z' ); 12498 continue; 12499 } else { 12500 initVal = parseFloat( fromStyles[ styleProp ] ) || 0; // if it is undefined it means it's 0 12501 endVal = toStyles[ styleProp ]; 12502 changeVal = endVal - initVal; 12503 style[ styleProp ] = [ initVal, changeVal ]; 12504 } 12505 } 12506 12507 return style; 12508 }, 12509 12510 12511 currentStyle : function( progress, style, ease ) { 12512 var self = this, 12513 currentStyle = {}, 12514 currentVals, styleProp, transProp, prog; 12515 12516 // Redo same loop but construct currentStyle object out of cached values 12517 for( styleProp in style ) { 12518 12519 if( styleProp === 'transform' ) { 12520 currentStyle.transform = {}; 12521 12522 for( transProp in style.transform ) { 12523 // remove this line. double check first if needed by logging 12524 if( transProp === 'translateZ' ) { continue; } 12525 12526 currentVals = style.transform[ transProp ]; 12527 currentStyle.transform[ transProp ] = 12528 // (currentIteration, startValue, changeInValue, totalIterations) 12529 self.ease[ ease ]( progress, currentVals[ 0 ], currentVals[ 1 ], 1 ); 12530 } 12531 } else { 12532 currentVals = style[ styleProp ]; 12533 currentStyle[ styleProp ] = 12534 self.ease[ ease ]( progress, currentVals[ 0 ], currentVals[ 1 ], 1 ); 12535 } 12536 } 12537 12538 return currentStyle; 12539 }, 12540 12541 12542 setActive : function( id ) { 12543 var $slides = $( this.slides ), 12544 className = this.config.activeClass; 12545 12546 $slides.removeClass( className ); 12547 12548 if( this.config.hasPagination ) { 12549 var $pagination = this.$pagination.find( 'a' ); 12550 $pagination.removeClass( className ); 12551 $pagination.eq( id ).addClass( className ); 12552 } 12553 12554 if( this.activeTimer ) { 12555 clearTimeout( this.activeTimer ); 12556 if ( this.imageLoader ) { 12557 this.imageLoader.abort(); 12558 } 12559 } 12560 12561 12562 var self = this; 12563 12564 this.activeTimer = setTimeout( function() { 12565 12566 var $currentSlide = $slides.eq( id ); 12567 12568 if ( self.config.lazyload && self.config.edgeSlider ) { // If it's Edge Slider and Lazy Load is enabled 12569
12570 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 12571 12572 var imgSet = $currentSlide.children('.mk-video-section-touch').data('mk-img-set'); 12573 var exactImg = MK.component.BackgroundImageSetter.getImage( imgSet ); 12574 var $bgImage = $('<img>').attr('src', exactImg ); 12575 12576 self.imageLoader = imagesLoaded( $bgImage[0], function( instance ) { 12577 $currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden'); 12578 setTimeout( function() { 12579 $currentSlide.children('.mk-slider-spinner-wrap').hide(); 12580 }, 200); 12581 $currentSlide.addClass( className ); 12582 }); 12583 12584 } 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 12585 12586 $currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden'); 12587 setTimeout( function() { 12588 $currentSlide.children('.mk-slider-spinner-wrap').hide(); 12589 }, 200); 12590 $currentSlide.addClass( className ); 12591 12592 } else { // If it's a Image Slide 12593 12594 if ( $currentSlide.children('[data-mk-img-set]').length ) { 12595 // Get the matching Image URL to start lazy loading 12596 var imgSet = $currentSlide.children('[data-mk-img-set]').data('mk-img-set'); 12597 var exactImg = MK.component.BackgroundImageSetter.getImage( imgSet ); 12598 var $bgImage = $('<img>').attr('src', exactImg ); 12599 12600 // Prevent counting time on slide until the image loads 12601 self.unsetTimer(); 12602 self.imageLoader = imagesLoaded( $bgImage[0], function( instance ) { 12603 // Hide spinner, Continue counting time on slide and show the content 12604 $currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden'); 12605 setTimeout( function() { 12606 $currentSlide.children('.mk-slider-spinner-wrap').hide(); 12607 }, 200); 12608 self.setTimer(false, false, $currentSlide.data('timer') || Number(self.config.displayTime) ); 12609 $currentSlide.addClass( className ); 12610 }); 12611 } else { 12612 $currentSlide.children('.mk-slider-spinner-wrap').addClass('mk-slider-spinner-wrap-hidden'); 12613 setTimeout( function() { 12614 $currentSlide.children('.mk-slider-spinner-wrap').hide(); 12615 }, 200); 12616 self.setTimer(false, false, $currentSlide.data('timer') || Number(self.config.displayTime) ); 12617 $currentSlide.addClass( className ); 12618 } 12619 12620 } 12621 12622 } else { 12623 12624 $currentSlide.addClass( className ); 12625 12626 } 12627 12628 12629 }, this.config.transitionTime ); 12630 }, 12631 12632 createTimer : function() { 12633 12634 var $slide = $(this), 12635 video = $slide.find('video').get(0); 12636 12637 if(video) { 12638 // A hacky but reliable way to ge the video duration 12639 var interval = setInterval( function() { 12640 // If the metadata is ready 12641 if ( video.readyState > 0 ) { 12642 $slide.data('timer', (video.duration * 1000)); 12643 $slide.attr('data-timer', (video.duration * 1000)); 12644 clearInterval(interval); 12645 } 12646 }, 100); 12647 } 12648 12649 }, 12650 12651 setTimer : function( isFirst, isPaused, fixed_time ) { 12652 // check for custom timer 12653 var customTimer = this.$slides.eq(this.nextId(this.state.moveForward ? 1 : -1)).data('timer'), 12654 trans = parseInt( this.config.transitionTime ), 12655 interval = customTimer ? customTimer : parseInt( this.config.displayTime ), 12656 timer = interval + trans; 12657 12658 var self = this, 12659 first = isFirst || true, 12660 fixed_time = fixed_time || 0, 12661 create, run; 12662 12663 this.timer = true; 12664 this.lastSetTimer = Date.now(); 12665 12666 create = function() { 12667 12668 if( self.autoplay ) { clearTimeout( self.autoplay ); } 12669 if( !self.timer ) { 12670 return; 12671 } 12672 self.state.moveForward = true; 12673 self.timeline.build(); 12674 self.timeline.play(); 12675 self.setActive( self.nextId( 1 ) ); 12676 if( self.config.fluidHeight ) { self.setHeight( self.nextId( 1 ) ); } 12677 first = false; 12678 self.lastSetTimer = Date.now(); 12679 12680 run(); 12681 }; 12682 12683 run = function(newInterval) { 12684 // check for custom timer 12685 customTimer = self.$slides.eq(self.nextId(self.state.moveForward ? 1 : -1)).data('timer'); 12686 interval = customTimer ? customTimer : parseInt( self.config.displayTime ); 12687 timer = interval + trans; // update timer with current val 12688 12689 var time = newInterval || timer; 12690 self.autoplay = setTimeout( create, time ); 12691 }; 12692 12693 if ( fixed_time ) { 12694 run( fixed_time ); 12695 } else if (isPaused) { 12696 run( this.timerRemaining ); 12697 } else { 12698 run(); 12699 } 12700 }, 12701 12702 12703 unsetTimer : function() { 12704 this.timer = false;
12705 this.lastUnsetTimer = Date.now(); 12706 this.timerRemaining -= this.lastUnsetTimer - this.lastSetTimer; 12707 if( this.autoplay ) { clearTimeout( this.autoplay ); } 12708 }, 12709 12710 12711 buildPagination : function() { 12712 var i = 0, 12713 len = this.slides.length, 12714 tpl = ''; 12715 12716 for( ; i < len; i += 1 ) { 12717 tpl += '<a href="javascript:;">' + this.config.paginationTpl + '</a>'; 12718 } 12719 12720 this.$pagination.html( tpl ); 12721 this.setActive( 0 ); 12722 }, 12723 12724 12725 getSlideSize : function() { 12726 this.slideSize = { 12727 X: 100 / this.config.slidesPerView, 12728 Y: 100 / this.config.slidesPerView 12729 }; 12730 }, 12731 12732 12733 getTransforms : function( style ) { 12734 // console.log( style ); 12735 var transform = style.transform || style.webkitTransform || style.mozTransform, 12736 regex = /(\w+)\(([^)]*)\)/g, 12737 match, 12738 T = {}; 12739 12740 if( typeof transform !== 'string' ) { 12741 throw 'Transform prop is not a string.'; 12742 } 12743 12744 if( !transform ) { return; } 12745 12746 // Run regex assignment 12747 while( match = regex.exec( transform ) ) { 12748 T[ match[ 1 ] ] = parseFloat( match[ 2 ] ); 12749 } 12750 12751 return T; 12752 }, 12753 12754 isNode : function( o ) { 12755 return ( 12756 typeof Node === "object" ? o instanceof Node : 12757 o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string" 12758 ); 12759 }, 12760 12761 12762 dragHandler : function() { 12763 var self = this, 12764 $container = $( this.container ), 12765 prevBuild = false, 12766 nextBuild = false, 12767 dragging = false, 12768 buffor = 5, // helpful for decoupling with click events 12769 dragStart, dragMove, dragEnd, progress; 12770 12771 progress = function( moveX ) { 12772 return moveX / self.val.viewportW(); 12773 }; 12774 12775 dragStart = function( moveX, startX ) { 12776 // console.log( 'start', moveX, startX ); 12777 }; 12778 12779 dragMove = function( moveX ) { 12780 // console.log('move'); 12781 if( self.state.running ) return; 12782 12783 // Don't need to check for existance here 12784 12785 if( moveX < -buffor ) { 12786 12787 if( !nextBuild ) { 12788 self.state.moveForward = true; 12789 self.timeline.build(); 12790 nextBuild = true; 12791 prevBuild = false; 12792 self.unsetTimer(); 12793 } else { 12794 // turn progress into positive val 12795 self.timeline.progress( -progress( moveX ) ); 12796 } 12797 dragging = true; 12798 } else if( moveX > buffor ) { 12799 12800 if( !prevBuild ) { 12801 self.state.moveForward = false; 12802 self.timeline.build(); 12803 prevBuild = true; 12804 nextBuild = false; 12805 self.unsetTimer(); 12806 } else { 12807 self.timeline.progress( progress( moveX ) ); 12808 } 12809 dragging = true; 12810 } 12811 }; 12812 12813 dragEnd = function( moveX ) { 12814 if( dragging ) { 12815 var prog = progress( moveX ), 12816 absProg = prog < 0 ? -prog : prog; 12817 12818 if( absProg > 0.1 ) { 12819 self.timeline.play( absProg ); 12820 self.setActive( self.nextId( prog < 0 ? 1 : -1 ) ); 12821 if( self.config.fluidHeight ) { self.setHeight( self.nextId( prog < 0 ? 1 : -1 ) ); } 12822 } else { 12823 self.timeline.reverse( absProg ); 12824 // eventually move this to reverse callbacks 12825 if(prog < 0) { 12826 self.updateId( -1 ); 12827 } else { 12828 self.updateId( 1 ); 12829 } 12830 } 12831 12832 prevBuild = false; 12833 nextBuild = false; 12834 dragging = false; 12835 if( self.config.autoplay ) { self.setTimer( false ); } 12836 } 12837 }; 12838 12839 this.drag( $container, dragStart, dragMove, dragEnd ); 12840 }, 12841 12842 12843 drag : function( $el, startFn, moveFn, stopFn ) { 12844 12845 var touchX, touchY, movX, movY, go, evt, 12846 prevent, start, move, stop; 12847 12848 prevent = function( e ) { 12849 e.preventDefault(); 12850 }; 12851 12852 start = function( e ) { 12853 // $el.on("touchmove", prevent); 12854 $el.on("mousemove", prevent); 12855 $el.on("touchmove", move); 12856 $el.on("mousemove", move); 12857 12858 evt = (e.type === 'touchstart') ? e.originalEvent.touches[0] : e; 12859 touchX = evt.pageX; 12860 12861 if(typeof startFn === 'function') { 12862 startFn(movX, touchX); 12863 } 12864 }; 12865 12866 move = function( e ) { 12867 evt = (e.type === 'touchmove') ? e.originalEvent.touches[0] : e; 12868 movX = evt.pageX - touchX; 12869 12870 if(typeof moveFn === 'function') { 12871 moveFn(movX); 12872 } 12873 }; 12874 12875 stop = function( e ) { 12876 // $el.off("touchmove", prevent); 12877 $el.off("mousemove", prevent); 12878 $el.off("touchmove", move); 12879 $el.off("mousemove", move); 12880 12881 if(typeof stopFn === 'function') { 12882 stopFn(movX); 12883 } 12884 }; 12885 12886 $el.on("touchstart", start); 12887 $el.on("mousedown", start); 12888 $el.on("touchend", stop); 12889 $el.on("touchleave", stop); 12890 $el.on("touchcancel", stop);
12891 $el.on("mouseup", stop); 12892 $el.on("mouseleave", stop); 12893 }, 12894 12895 12896 dynamicVal : function() { 12897 var $window = $( window ), 12898 update, 12899 getViewportW, viewportW; 12900 12901 update = function() { 12902 viewportW = $window.width(); 12903 }; 12904 12905 getViewportW = function() { 12906 return viewportW; 12907 }; 12908 12909 update(); 12910 $window.on( 'load', update ); 12911 $window.on( 'resize', update ); 12912 12913 return { 12914 viewportW : getViewportW 12915 }; 12916 } 12917 }; 12918 12919 12920 12921 // 12922 // Set of default animations 12923 // 12924 // ///////////////////////////////////////////////////////// 12925 12926 MK.ui.Slider.prototype.animation = { 12927 12928 slide : { 12929 axis : 'X', 12930 next : { transform: {} }, 12931 active : { transform: {} }, 12932 prev : { transform: {} } 12933 }, 12934 12935 vertical_slide : { 12936 axis : 'Y', 12937 next : { transform: {} }, 12938 active : { transform: {} }, 12939 prev : { transform: {} } 12940 }, 12941 12942 perspective_flip : { 12943 axis : 'Y', 12944 next : { 12945 transform: { 12946 rotateX : 80 12947 } 12948 }, 12949 active : { 12950 transform: { 12951 rotateX : 0 12952 } 12953 }, 12954 prev : { 12955 transform: { 12956 rotateX : 0 12957 } 12958 } 12959 }, 12960 12961 zoom : { 12962 axis : 'Z', 12963 next: { 12964 opacity : 0, 12965 transform : { 12966 scale : 0.9 12967 } 12968 }, 12969 active: { 12970 opacity : 1, 12971 transform : { 12972 scale : 1 12973 } 12974 }, 12975 prev: { 12976 opacity : 0, 12977 transform : { 12978 scale : 1.1 12979 } 12980 } 12981 }, 12982 12983 fade : { 12984 axis : 'Z', 12985 next: { 12986 opacity : 0, 12987 transform : {} 12988 }, 12989 active: { 12990 opacity : 1, 12991 transform : {} 12992 }, 12993 prev: { 12994 opacity : 0, 12995 transform : {} 12996 } 12997 }, 12998 12999 kenburned : { 13000 axis : 'Z', 13001 next: { 13002 opacity : 0, 13003 transform : {} 13004 }, 13005 active: { 13006 opacity : 1, 13007 transform : {} 13008 }, 13009 prev: { 13010 opacity : 0, 13011 transform : {} 13012 } 13013 }, 13014 13015 zoom_out : { 13016 axis : 'Z', 13017 next: { 13018 zIndex : '+', 13019 opacity : 1, 13020 transform : { 13021 translateY : 100, 13022 scale : 1 13023 } 13024 }, 13025 active: { 13026 opacity : 1, 13027 transform : { 13028 translateY : 0, 13029 scale : 1 13030 } 13031 }, 13032 prev: { 13033 zIndex : '+', 13034 opacity : 0, 13035 transform : { 13036 translateY : 0, 13037 scale : 0.5 13038 } 13039 } 13040 }, 13041 13042 // Problem with Z-Flow 13043 horizontal_curtain : { 13044 axis : 'Z', 13045 next: { 13046 zIndex : '+', 13047 transform : { 13048 translateX : 100, 13049 } 13050 }, 13051 active: { 13052 transform : { 13053 translateX : 0, 13054 } 13055 }, 13056 prev: { 13057 zIndex : '+', 13058 transform : { 13059 translateX : -70, 13060 } 13061 } 13062 }, 13063 13064 roulete : { 13065 axis : 'X', 13066 next: { 13067 opacity : 0.5, 13068 transform : { 13069 scale : 0.5, 13070 rotate : 10, 13071 translateY : 20 13072 } 13073 }, 13074 active: { 13075 opacity : 1, 13076 transform : { 13077 scale : 1, 13078 rotate : 0, 13079 translateY : 0 13080 } 13081 }, 13082 prev: { 13083 opacity : 0.3, 13084 transform : { 13085 scale : 0.5, 13086 rotate : -10, 13087 translateY : 20 13088 } 13089 } 13090 } 13091 }; 13092 13093 13094 13095 // 13096 // Penner's easing library 13097 // 13098 // ///////////////////////////////////////////////////////// 13099 13100 MK.ui.Slider.prototype.ease = { 13101 /* 13102 *
13103 * TERMS OF USE - EASING EQUATIONS 13104 * 13105 * Open source under the BSD License. 13106 * 13107 * Copyright é 2001 Robert Penner 13108 * All rights reserved. 13109 * 13110 * Redistribution and use in source and binary forms, with or without modification, 13111 * are permitted provided that the following conditions are met: 13112 * 13113 * Redistributions of source code must retain the above copyright notice, this list of 13114 * conditions and the following disclaimer. 13115 * Redistributions in binary form must reproduce the above copyright notice, this list 13116 * of conditions and the following disclaimer in the documentation and/or other materials 13117 * provided with the distribution. 13118 * 13119 * Neither the name of the author nor the names of contributors may be used to endorse 13120 * or promote products derived from this software without specific prior written permission. 13121 * 13122 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 13123 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 13124 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 13125 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 13126 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 13127 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 13128 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 13129 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 13130 * OF THE POSSIBILITY OF SUCH DAMAGE. 13131 * 13132 */ 13133 linearEase : function(currentIteration, startValue, changeInValue, totalIterations) { 13134 return changeInValue * currentIteration / totalIterations + startValue; 13135 }, 13136 13137 easeInQuad : function(currentIteration, startValue, changeInValue, totalIterations) { 13138 return changeInValue * (currentIteration /= totalIterations) * currentIteration + startValue; 13139 }, 13140 13141 easeOutQuad : function(currentIteration, startValue, changeInValue, totalIterations) { 13142 return -changeInValue * (currentIteration /= totalIterations) * (currentIteration - 2) + startValue; 13143 }, 13144 13145 easeInOutQuad : function(currentIteration, startValue, changeInValue, totalIterations) { 13146 if ((currentIteration /= totalIterations / 2) < 1) { 13147 return changeInValue / 2 * currentIteration * currentIteration + startValue; 13148 } 13149 return -changeInValue / 2 * ((--currentIteration) * (currentIteration - 2) - 1) + startValue; 13150 }, 13151 13152 easeInCubic : function(currentIteration, startValue, changeInValue, totalIterations) { 13153 return changeInValue * Math.pow(currentIteration / totalIterations, 3) + startValue; 13154 }, 13155 13156 easeOutCubic : function(currentIteration, startValue, changeInValue, totalIterations) { 13157 return changeInValue * (Math.pow(currentIteration / totalIterations - 1, 3) + 1) + startValue; 13158 }, 13159 13160 easeInOutCubic : function(currentIteration, startValue, changeInValue, totalIterations) { 13161 if ((currentIteration /= totalIterations / 2) < 1) { 13162 return changeInValue / 2 * Math.pow(currentIteration, 3) + startValue; 13163 } 13164 return changeInValue / 2 * (Math.pow(currentIteration - 2, 3) + 2) + startValue; 13165 }, 13166 13167 easeInQuart : function(currentIteration, startValue, changeInValue, totalIterations) { 13168 return changeInValue * Math.pow (currentIteration / totalIterations, 4) + startValue; 13169 }, 13170 13171 easeOutQuart : function(currentIteration, startValue, changeInValue, totalIterations) { 13172 return -changeInValue * (Math.pow(currentIteration / totalIterations - 1, 4) - 1) + startValue; 13173 }, 13174 13175 easeInOutQuart : function(currentIteration, startValue, changeInValue, totalIterations) { 13176 if ((currentIteration /= totalIterations / 2) < 1) { 13177 return changeInValue / 2 * Math.pow(currentIteration, 4) + startValue; 13178 } 13179 return -changeInValue/2 * (Math.pow(currentIteration - 2, 4) - 2) + startValue; 13180 }, 13181 13182 easeInQuint : function(currentIteration, startValue, changeInValue, totalIterations) { 13183 return changeInValue * Math.pow (currentIteration / totalIterations, 5) + startValue; 13184 }, 13185 13186 easeOutQuint : function(currentIteration, startValue, changeInValue, totalIterations) { 13187 return changeInValue * (Math.pow(currentIteration / totalIterations - 1, 5) + 1) + startValue; 13188 }, 13189 13190 easeInOutQuint : function(currentIteration, startValue, changeInValue, totalIterations) { 13191 if ((currentIteration /= totalIterations / 2) < 1) { 13192 return changeInValue / 2 * Math.pow(currentIteration, 5) + startValue; 13193 } 13194 return changeInValue / 2 * (Math.pow(currentIteration - 2, 5) + 2) + startValue; 13195 }, 13196 13197 easeInSine : function(currentIteration, startValue, changeInValue, totalIterations) { 13198 return changeInValue * (1 - Math.cos(currentIteration / totalIterations * (Math.PI / 2))) + startValue; 13199 }, 13200 13201 easeOutSine : function(currentIteration, startValue, changeInValue, totalIterations) { 13202 return changeInValue * Math.sin(currentIteration / totalIterations * (Math.PI / 2)) + startValue; 13203 }, 13204 13205 easeInOutSine : function(currentIteration, startValue, changeInValue, totalIterations) { 13206 return changeInValue / 2 * (1 - Math.cos(Math.PI * currentIteration / totalIterations)) + startValue; 13207 }, 13208 13209 easeInExpo : function(currentIteration, startValue, changeInValue, totalIterations) { 13210 return changeInValue * Math.pow(2, 10 * (currentIteration / totalIterations - 1)) + startValue; 13211 }, 13212 13213 easeOutExpo : function(currentIteration, startValue, changeInValue, totalIterations) { 13214 return changeInValue * (-Math.pow(2, -10 * currentIteration / totalIterations) + 1) + startValue; 13215 }, 13216 13217 easeInOutExpo : function(currentIteration, startValue, changeInValue, totalIterations) { 13218 if ((currentIteration /= totalIterations / 2) < 1) { 13219 return changeInValue / 2 * Math.pow(2, 10 * (currentIteration - 1)) + startValue; 13220 } 13221 return changeInValue / 2 * (-Math.pow(2, -10 * --currentIteration) + 2) + startValue; 13222 }, 13223 13224 easeInCirc : function(currentIteration, startValue, changeInValue, totalIterations) { 13225 return changeInValue * (1 - Math.sqrt(1 - (currentIteration /= totalIterations) * currentIteration)) + startValue; 13226 }, 13227 13228 easeOutCirc : function(currentIteration, startValue, changeInValue, totalIterations) { 13229 return changeInValue * Math.sqrt(1 - (currentIteration = currentIteration / totalIterations - 1) * currentIteration) + startValue; 13230 }, 13231 13232 easeInOutCirc : function(currentIteration, startValue, changeInValue, totalIterations) { 13233 if ((currentIteration /= totalIterations / 2) < 1) { 13234 return changeInValue / 2 * (1 - Math.sqrt(1 - currentIteration * currentIteration)) + startValue; 13235 } 13236 return changeInValue / 2 * (Math.sqrt(1 - (currentIteration -= 2) * currentIteration) + 1) + startValue; 13237 } 13238 }; 13239 13240})(jQuery); 13241(function($) { 13242 'use strict'; 13243 13244 MK.component.Sortable = function(el) { 13245 this.el = el; 13246 }; 13247 13248 MK.component.Sortable.prototype = {
13249 init: function init() { 13250 this.cacheElements(); 13251 this.bindEvents(); 13252 }, 13253 13254 cacheElements: function cacheElements() { 13255 this.unique = Date.now(); 13256 this.$filter = $(this.el); 13257 this.config = this.$filter.data('sortable-config'); 13258 13259 this.ajaxLoader = new MK.utils.ajaxLoader(this.config.container); 13260 this.ajaxLoader.init(); 13261 13262 this.$container = $( this.config.container ); 13263 this.$navItems = this.$filter.find('a'); 13264 this.$filterItems = this.$container.find(this.config.item); 13265 }, 13266 13267 bindEvents: function bindEvents() { 13268 this.$navItems.on('click', this.handleClick.bind(this)); 13269 MK.utils.eventManager.subscribe('ajaxLoaded', this.onLoad.bind(this)); 13270 }, 13271 13272 handleClick: function handleClick(e) { 13273 e.preventDefault(); 13274 13275 var $item = $(e.currentTarget); 13276 var term = $item.data('filter'); 13277 13278 this.$navItems.removeClass('current'); 13279 $item.addClass('current'); 13280 13281 if(this.config.mode === 'ajax') this.inDB(term, $item); 13282 else this.inPage(term); 13283 }, 13284 13285 inDB: function inDB(term, $item) { 13286 // Add load indicator only for long requests 13287 MK.ui.loader.remove(this.$filter); 13288 MK.ui.loader.add($item); 13289 13290 // If mk-ajax-loaded-posts span exists and one of the filter is clicked, 13291 // clear post ids 13292 if ( this.$container.siblings('.mk-ajax-loaded-posts').length ) { 13293 this.$container.siblings('.mk-ajax-loaded-posts').attr('data-loop-loaded-posts', ''); 13294 } 13295 13296 this.ajaxLoader.setData({ 13297 paged: 1, 13298 term: term 13299 }); 13300 this.ajaxLoader.load(this.unique); 13301 }, 13302 13303 inPage: function inPage(term) { 13304 var $filterItems = this.$container.find(this.config.item); 13305 $filterItems.removeClass('is-hidden'); // show all first 13306 // Replace all ', ' with ', .'. It's used to add '.' as class selector of each category. 13307 var className = term.replace( /, /g, ", ." ); 13308 if(term !== '*') $filterItems.not( '.' + className ).addClass('is-hidden'); // hide filtered 13309 MK.utils.eventManager.publish('staticFilter'); 13310 }, 13311 13312 onLoad: function onLoad(e, response) { 13313 if(this.config.mode === 'static') { 13314 this.$navItems.removeClass('current').first().addClass('current'); 13315 } 13316 if( typeof response !== 'undefined' && response.id === this.config.container) { 13317 MK.ui.loader.remove(this.$filter); 13318 if(response.unique === this.unique) { 13319 this.$container.html(response.content); 13320 this.ajaxLoader.setData({paged: 1}); 13321 } 13322 } 13323 } 13324 }; 13325 13326})(jQuery); 13327(function($) { 13328 'use strict'; 13329 13330 MK.component.Tabs = function( el ) { 13331 var defaults = { 13332 activeClass : 'is-active' 13333 }; 13334 13335 this.config = defaults; 13336 this.el = el; 13337 }; 13338 13339 MK.component.Tabs.prototype = { 13340 13341 init : function() { 13342 this.cacheElements(); 13343 this.bindEvents(); 13344 }, 13345 13346 cacheElements : function() { 13347 this.$this = $( this.el ); 13348 this.$tabs = this.$this.find( '.mk-tabs-tab' ); 13349 this.$panes = this.$this.find( '.mk-tabs-pane' ); 13350 this.currentId = 0; 13351 }, 13352 13353 bindEvents : function() { 13354 var self = this; 13355 13356 this.$tabs.on( 'click', this.switchPane.bind( this ) ); 13357 }, 13358 13359 switchPane : function( evt ) { 13360 evt.preventDefault(); 13361 13362 var clickedId = $( evt.currentTarget ).index(); 13363 13364 this.hide( this.currentId ); 13365 this.show( clickedId ); 13366 13367 // Update current id 13368 this.currentId = clickedId; 13369 13370 // Notify rest of the app 13371 MK.utils.eventManager.publish('item-expanded'); 13372 }, 13373 13374 show : function( id ) { 13375 this.$tabs.eq( id ).addClass( this.config.activeClass ); 13376 this.$panes.eq( id ).addClass( this.config.activeClass ); 13377 }, 13378 13379 hide : function( id ) { 13380 this.$tabs.eq( id ).removeClass( this.config.activeClass ); 13381 this.$panes.eq( id ).removeClass( this.config.activeClass ); 13382 } 13383 }; 13384 13385})(jQuery); 13386 13387 13388/* Tabs */ 13389/* -------------------------------------------------------------------- */ 13390 13391function mk_tabs() { 13392 13393 // "use strict"; 13394 13395 // if ($.exists('.mk-tabs, .mk-news-tab, .mk-woo-tabs')) { 13396 // $(".mk-tabs, .mk-news-tab, .mk-woo-tabs").tabs(); 13397 13398 // $('.mk-tabs').on('click', function () { 13399 // $('.mk-theme-loop').isotope('layout'); 13400 // }); 13401 13402 // $('.mk-tabs.vertical-style').each(function () { 13403 // $(this).find('.mk-tabs-pane').css('minHeight', $(this).find('.mk-tabs-tabs').height() - 1); 13404 // }); 13405 13406 // } 13407} 13408 13409function mk_tabs_responsive(){ 13410 // $('.mk-tabs, .mk-news-tab').each(function () { 13411 // $this = $(this); 13412 // if ($this.hasClass('mobile-true')) { 13413 // if (window.matchMedia('(max-width: 767px)').matches) 13414 // { 13415 // $this.tabs("destroy"); 13416 // } else { 13417 // $this.tabs(); 13418 // } 13419 // } 13420 // }); 13421 13422} 13423 13424 13425(function($) { 13426 'use strict'; 13427 13428 $(document).on('click', function(e) { 13429 $('.mk-toggle-trigger').removeClass('mk-toggle-active'); 13430 }); 13431 13432 function toggle(e) { 13433 e.preventDefault(); 13434 e.stopPropagation(); 13435 var $this = $(e.currentTarget); 13436 13437 if (!$this.hasClass('mk-toggle-active')) { 13438 13439 $('.mk-box-to-trigger').fadeOut(200); 13440 $this.parent().find('.mk-box-to-trigger').fadeIn(250); 13441 $('.mk-toggle-trigger').removeClass('mk-toggle-active'); 13442 $this.addClass('mk-toggle-active'); 13443 13444 } else { 13445 13446 $('.mk-box-to-trigger').fadeOut(200); 13447 $this.removeClass('mk-toggle-active'); 13448 13449 } 13450 } 13451 13452 function assignToggle() { 13453 // wait for ajax response propagation and insertion 13454 setTimeout(function() { 13455 $('.mk-toggle-trigger').off('click', toggle); 13456 $('.mk-toggle-trigger').on('click', toggle); 13457 }, 100); 13458 } 13459 13460 assignToggle(); 13461 MK.utils.eventManager.subscribe('ajaxLoaded', assignToggle); 13462 MK.utils.eventManager.subscribe('ajax-preview', assignToggle); 13463 13464 $(window).on('vc_reload', function(){ 13465 assignToggle(); 13466 MK.utils.eventManager.subscribe('ajaxLoaded', assignToggle); 13467 MK.utils.eventManager.subscribe('ajax-preview', assignToggle); 13468 }); 13469 13470}(jQuery)); 13471(function($) { 13472 'use strict'; 13473 13474 var $iframes = $('iframe'); 13475 13476 $iframes.each(function() { 13477 var $iframe = $(this); 13478 var parent = $iframe.parent().get(0); 13479 var tagName = parent.tagName; 13480 13481 if(tagName === 'P') $iframe.wrap('<div class="mk-video-container"></div>'); 13482 }); 13483 13484}(jQuery)); 13485(function( $ ) { 13486 'use strict'; 13487 if( MK.utils.isMobile() ) { 13488 $('.mk-animate-element').removeClass('mk-animate-element'); 13489 return; 13490 }
13491 var init = function init() { 13492 var $rootLevelEls = $('.js-master-row, .widget'); 13493 $rootLevelEls.each( spyViewport ); 13494 $rootLevelEls.each( function rootLevelEl() { 13495 var $animateEl = $(this).find( '.mk-animate-element' ); 13496 $animateEl.each( spyViewport ); 13497 /** 13498 * Firefox has known issue where horizontal scrollbar will appear if an 13499 * element uses animation CSS. The solution should be set the element 13500 * position as fixed or overflow-x as hidden. Position fixed is not possible 13501 * to use because it's only cause other big problems. The best way is 13502 * set overflow-x as hidden in the page content container #theme-page. 13503 * 13504 * NOTE: The problem is spotted on Right To Left viewport only. So, it's 13505 * limited to '.right-to-left' selector only for now to avoid other 13506 * problems. Please extend the functionallity if it's happen in 13507 * other viewport animation effect. 13508 */ 13509 var browserName = MK.utils.browser.name; 13510 if ( browserName === 'Firefox' ) { 13511 var $rightToLeft = $( this ).find( '.right-to-left' ); 13512 if ( $rightToLeft.length > 0 ) { 13513 $( '#theme-page' ).css( 'overflow-x', 'hidden' ); 13514 } 13515 } 13516 }); 13517 }; 13518 var spyViewport = function spyViewport(i) { 13519 var self = this; 13520 MK.utils.scrollSpy( this, { 13521 position : 'bottom', 13522 threshold : 200, 13523 after : function() { 13524 animate.call(self, i); 13525 } 13526 }); 13527 }; 13528 var animate = function animate(i) { 13529 var $this = $(this); 13530 setTimeout(function() { 13531 $this.addClass( 'mk-in-viewport' ); 13532 }, 100 * i); 13533 }; 13534 $(window).on('load vc_reload', init); 13535}(jQuery)); 13536 13537function product_loop_add_cart() { 13538 var $body = $('body'); 13539 $body.on('click', '.add_to_cart_button', function() { 13540 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>'; 13541 var $holder = $(this).parents('.product:eq(0)'); 13542 var $i = $holder.find('.product-loading-icon'); 13543 $holder.addClass('adding-to-cart').removeClass('added-to-cart'); 13544 $i.html(icon); 13545 }); 13546 $body.bind('added_to_cart', function() { 13547 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>'; 13548 var $holder = $('.adding-to-cart'); 13549 var $i = $holder.find('.product-loading-icon'); 13550 $holder.removeClass('adding-to-cart').addClass('added-to-cart'); 13551 $i.html(icon); 13552 }); 13553} 13554(function($) { 13555 'use strict'; 13556 13557 /** 13558 * Entry point of application. Runs all components 13559 */ 13560 $( window ).on( 'load', function() { 13561 MK.core.initAll( document ); 13562 MK.utils.scrollToURLHash(); 13563 // TODO move preloader to components and manage it state from within 13564 setTimeout( function() { 13565 MK.ui.preloader.hide(); // site wide 13566 $('.mk-preloader').hide(); // components 13567 $('body').removeClass('loading'); 13568 }, 150 ); 13569 }); 13570 13571 /** 13572 * VC frontend editor. Init all components. 13573 */ 13574 $( window ).on( 'vc_reload', function() { 13575 setTimeout(function(){ 13576 MK.core.initAll( document ); 13577 }, 100); 13578 }); 13579 13580 /** 13581 * Assign global click handlers 13582 */ 13583 $( document ).on( 'click', '.js-smooth-scroll, .js-main-nav a', smoothScrollToAnchor); 13584 $( '.side_dashboard_menu a' ).on( 'click', smoothScrollToAnchor); 13585 13586 function smoothScrollToAnchor( evt ) { 13587 var anchor = MK.utils.detectAnchor( this ); 13588 var $this = $(evt.currentTarget); 13589 var loc = window.location; 13590 var currentPage = loc.origin + loc.pathname; 13591 var href = $this.attr( 'href' ); 13592 var linkSplit = (href) ? href.split( '#' ) : ''; 13593 var hrefPage = linkSplit[0] ? linkSplit[0] : ''; 13594 var hrefHash = linkSplit[1] ? linkSplit[1] : ''; 13595 13596 if( anchor.length ) { 13597 if(hrefPage === currentPage || hrefPage === '') evt.preventDefault(); 13598 MK.utils.scrollToAnchor( anchor ); 13599 13600 } else if( $this.attr( 'href' ) === '#' ) { 13601 evt.preventDefault(); 13602 } 13603 } 13604 13605}(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.