1 2window.mr = window.mr || {}; 3 4mr = (function (mr, $, window, document){ 5 "use strict"; 6 7 mr = mr || {}; 8 9 var components = {documentReady: [],documentReadyDeferred: [], windowLoad: [], windowLoadDeferred: []}; 10 11 mr.status = {documentReadyRan: false, windowLoadPending: false}; 12 13 $(document).ready(documentReady); 14 $(window).on("load", windowLoad); 15 16 function documentReady(context){ 17 18 context = typeof context === typeof undefined ? $ : context; 19 components.documentReady.concat(components.documentReadyDeferred).forEach(function(component){ 20 component(context); 21 }); 22 mr.status.documentReadyRan = true; 23 if(mr.status.windowLoadPending){ 24 windowLoad(mr.setContext()); 25 } 26 } 27 28 function windowLoad(context){ 29 if(mr.status.documentReadyRan){ 30 mr.status.windowLoadPending = false; 31 context = typeof context === "object" ? $ : context; 32 components.windowLoad.concat(components.windowLoadDeferred).forEach(function(component){ 33 component(context); 34 }); 35 }else{ 36 mr.status.windowLoadPending = true; 37 } 38 } 39 40 mr.setContext = function (contextSelector){ 41 var context = $; 42 if(typeof contextSelector !== typeof undefined){ 43 return function(selector){ 44 return $(contextSelector).find(selector); 45 }; 46 } 47 return context; 48 }; 49 50 mr.components = components; 51 mr.documentReady = documentReady; 52 mr.windowLoad = windowLoad; 53 54 return mr; 55}(window.mr, jQuery, window, document)); 56 57 58//////////////// Utility Functions 59mr = (function (mr, $, window, document){ 60 "use strict"; 61 mr.util = {}; 62 63 mr.util.requestAnimationFrame = window.requestAnimationFrame || 64 window.mozRequestAnimationFrame || 65 window.webkitRequestAnimationFrame || 66 window.msRequestAnimationFrame; 67 68 mr.util.documentReady = function($){ 69 var today = new Date(); 70 var year = today.getFullYear(); 71 $('.update-year').text(year); 72 }; 73 74 mr.util.windowLoad = function($){ 75 $('[data-delay-src]').each(function(){ 76 var $el = $(this); 77 $el.attr('src', $el.attr('data-delay-src')); 78 $el.removeAttr('data-delay-src'); 79 }); 80 }; 81 82 mr.util.getURLParameter = function(name) { 83 return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [undefined, ""])[1].replace(/\+/g, '%20')) || null; 84 }; 85 86 87 mr.util.capitaliseFirstLetter = function(string) { 88 return string.charAt(0).toUpperCase() + string.slice(1); 89 }; 90 91 mr.util.slugify = function(text, spacesOnly){ 92 if(typeof spacesOnly !== typeof undefined){ 93 return text.replace(/ +/g, ''); 94 }else{ 95 return text 96 .toLowerCase() 97 .replace(/[\~\!\@\#\$\%\^\&\*\(\)\-\_\=\+\]\[\}\{\'\"\;\\\:\?\/\>\<\.\,]+/g, '') 98 .replace(/ +/g, '-'); 99 } 100 }; 101 102 mr.util.sortChildrenByText = function(parentElement, reverse){ 103 var $parentElement = $(parentElement); 104 var items = $parentElement.children().get(); 105 var order = -1; 106 var order2 = 1; 107 if(typeof reverse !== typeof undefined){order = 1; order2 = -1;} 108 109 items.sort(function(a,b){ 110 var keyA = $(a).text(); 111 var keyB = $(b).text(); 112 113 if (keyA < keyB) return order; 114 if (keyA > keyB) return order2; 115 return 0; 116 }); 117 118 // Append back into place 119 $parentElement.empty(); 120 $(items).each(function(i, itm){ 121 $parentElement.append(itm); 122 }); 123 }; 124 125 // Set data-src attribute of element from src to be restored later 126 mr.util.idleSrc = function(context, selector){ 127 128 selector = (typeof selector !== typeof undefined) ? selector : '';
129 var elems = context.is(selector+'[src]') ? context : context.find(selector+'[src]'); 130 131 elems.each(function(index, elem){ 132 elem = $(elem); 133 var currentSrc = elem.attr('src'), 134 dataSrc = elem.attr('data-src'); 135 136 // If there is no data-src, save current source to it 137 if(typeof dataSrc === typeof undefined){ 138 elem.attr('data-src', currentSrc); 139 } 140 141 // Clear the src attribute 142 elem.attr('src', ''); 143 144 }); 145 }; 146 147 // Set src attribute of element from its data-src where it was temporarily stored earlier 148 mr.util.activateIdleSrc = function(context, selector){ 149 150 selector = (typeof selector !== typeof undefined) ? selector : ''; 151 var elems = context.is(selector+'[data-src]') ? context : context.find(selector+'[data-src]'); 152 153 elems.each(function(index, elem){ 154 elem = $(elem); 155 var dataSrc = elem.attr('data-src'); 156 157 // Write the 'src' attribute using the 'data-src' value 158 elem.attr('src', dataSrc); 159 }); 160 }; 161 162 mr.util.pauseVideo = function(context){ 163 var elems = context.is('video') ? context : context.find('video'); 164 165 elems.each(function(index, video){ 166 var playingVideo = $(video).get(0); 167 playingVideo.pause(); 168 }); 169 }; 170 171 // Take a text value in either px (eg. 150px) or vh (eg. 65vh) and return a number in pixels. 172 mr.util.parsePixels = function(text){ 173 var windowHeight = $(window).height(), value; 174 175 // Text text against regular expression for px value. 176 if(/^[1-9]{1}[0-9]*[p][x]$/.test(text)){ 177 return parseInt(text.replace('px', ''),10); 178 } 179 // Otherwise it is vh value. 180 else if(/^[1-9]{1}[0-9]*[v][h]$/.test(text)){ 181 value = parseInt(text.replace('vh', ''),10); 182 // Return conversion to percentage of window height. 183 return windowHeight * (value/100); 184 }else{ 185 // If it is not proper text, return -1 to indicate bad value. 186 return -1; 187 } 188 }; 189 190 mr.util.removeHash = function() { 191 // Removes hash from URL bar without reloading and without losing search query 192 history.pushState("", document.title, window.location.pathname + window.location.search); 193 } 194 195 mr.components.documentReady.push(mr.util.documentReady); 196 mr.components.windowLoad.push(mr.util.windowLoad); 197 return mr; 198 199}(mr, jQuery, window, document)); 200 201//////////////// Window Functions 202mr = (function (mr, $, window, document){ 203 "use strict"; 204 205 mr.window = {}; 206 mr.window.height = $(window).height(); 207 mr.window.width = $(window).width(); 208 209 $(window).on('resize',function(){ 210 mr.window.height = $(window).height(); 211 mr.window.width = $(window).width(); 212 }); 213 214 return mr; 215}(mr, jQuery, window, document)); 216 217 218//////////////// Scroll Functions 219mr = (function (mr, $, window, document){ 220 "use strict"; 221 222 223 mr.scroll = {}; 224 var raf = window.requestAnimationFrame || 225 window.mozRequestAnimationFrame || 226 window.webkitRequestAnimationFrame || 227 window.msRequestAnimationFrame; 228 mr.scroll.listeners = []; 229 mr.scroll.busy = false; 230 mr.scroll.y = 0; 231 mr.scroll.x = 0; 232 233 var documentReady = function($){ 234
235 //////////////// Capture Scroll Event and fire scroll function 236 jQuery(window).off('scroll.mr'); 237 jQuery(window).on('scroll.mr', function(evt) { 238 if(mr.scroll.busy === false){ 239 240 mr.scroll.busy = true; 241 raf(function(evt){ 242 mr.scroll.update(evt); 243 }); 244 245 } 246 if(evt.stopPropagation){ 247 evt.stopPropagation(); 248 } 249 }); 250 251 }; 252 253 mr.scroll.update = function(event){ 254 255 // Loop through all mr scroll listeners 256 var parallax = typeof window.mr_parallax !== typeof undefined ? true : false; 257 mr.scroll.y = (parallax ? mr_parallax.mr_getScrollPosition() : window.pageYOffset); 258 mr.scroll.busy = false; 259 if(parallax){ 260 mr_parallax.mr_parallaxBackground(); 261 } 262 263 264 if(mr.scroll.listeners.length > 0){ 265 for (var i = 0, l = mr.scroll.listeners.length; i < l; i++) { 266 mr.scroll.listeners[i](event); 267 } 268 } 269 270 }; 271 272 mr.scroll.documentReady = documentReady; 273 274 mr.components.documentReady.push(documentReady); 275 276 return mr; 277 278}(mr, jQuery, window, document)); 279 280 281//////////////// Scroll Class Modifier 282mr = (function (mr, $, window, document){ 283 "use strict"; 284 285 mr.scroll.classModifiers = {}; 286 // Globally accessible list of elements/rules 287 mr.scroll.classModifiers.rules = []; 288 289 mr.scroll.classModifiers.parseScrollRules = function(element){ 290 var text = element.attr('data-scroll-class'), 291 rules = text.split(";"); 292
293 rules.forEach(function(rule){ 294 var ruleComponents, scrollPoint, ruleObject = {}; 295 ruleComponents = rule.replace(/\s/g, "").split(':'); 296 if(ruleComponents.length === 2){ 297 scrollPoint = mr.util.parsePixels(ruleComponents[0]); 298 if(scrollPoint > -1){ 299 ruleObject.scrollPoint = scrollPoint; 300 if(ruleComponents[1].length){ 301 var toggleClass = ruleComponents[1]; 302 ruleObject.toggleClass = toggleClass; 303 // Set variable in object to indicate that element already has class applied 304 ruleObject.hasClass = element.hasClass(toggleClass); 305 ruleObject.element = element.get(0); 306 mr.scroll.classModifiers.rules.push(ruleObject); 307 }else{ 308 // Error: toggleClass component does not exist. 309 //console.log('Error - toggle class not found.'); 310 return false; 311 } 312 }else{ 313 // Error: scrollpoint component was malformed 314 //console.log('Error - Scrollpoint not found.'); 315 return false; 316 } 317 } 318 }); 319 320 if(mr.scroll.classModifiers.rules.length){ 321 return true; 322 }else{ 323 return false; 324 } 325 }; 326 327 mr.scroll.classModifiers.update = function(event){ 328 var currentScroll = mr.scroll.y, 329 scrollRules = mr.scroll.classModifiers.rules, 330 l = scrollRules.length, 331 currentRule; 332 333 // Given the current scrollPoint, check for necessary changes 334 while(l--) { 335 336 currentRule = scrollRules[l]; 337 338 if(currentScroll > currentRule.scrollPoint && !currentRule.hasClass){ 339 // Set local copy and glogal copy at the same time; 340 currentRule.element.classList.add(currentRule.toggleClass); 341 currentRule.hasClass = mr.scroll.classModifiers.rules[l].hasClass = true; 342 } 343 if(currentScroll < currentRule.scrollPoint && currentRule.hasClass){ 344 // Set local copy and glogal copy at the same time; 345 currentRule.element.classList.remove(currentRule.toggleClass); 346 currentRule.hasClass = mr.scroll.classModifiers.rules[l].hasClass = false; 347 } 348 } 349 }; 350 351 var fixedElementSizes = function(){ 352 $('.main-container [data-scroll-class*="pos-fixed"]').each(function(){ 353 var element = $(this); 354 element.css('max-width',element.parent().outerWidth()); 355 element.parent().css('min-height',element.outerHeight()); 356 }); 357 }; 358 359 var documentReady = function($){ 360 // Collect info on all elements that require class modification at load time 361 // Each element has data-scroll-class with a formatted value to represent class to add/remove at a particular scroll point. 362 $('[data-scroll-class]').each(function(){ 363 var element = $(this); 364 365 // Test the rules to be added to an array of rules. 366 if(!mr.scroll.classModifiers.parseScrollRules(element)){ 367 console.log('Error parsing scroll rules on: '+element); 368 } 369 }); 370 371 // For 'position fixed' elements, give them a max-width for correct fixing behaviour 372 fixedElementSizes(); 373 $(window).on('resize', fixedElementSizes); 374 375 // If there are valid scroll rules add classModifiers update function to the scroll event processing queue. 376 if(mr.scroll.classModifiers.rules.length){ 377 mr.scroll.listeners.push(mr.scroll.classModifiers.update); 378 } 379 }; 380 381 mr.components.documentReady.push(documentReady); 382 mr.scroll.classModifiers.documentReady = documentReady; 383 384 385 386 return mr; 387 388}(mr, jQuery, window, document)); 389 390 391//////////////// Accordions 392mr = (function (mr, $, window, document){ 393 "use strict"; 394 395 mr.accordions = mr.accordions || {}; 396 397 mr.accordions.documentReady = function($){ 398 $('.accordion__title').on('click', function(){ 399 mr.accordions.activatePanel($(this)); 400 }); 401 402 $('.accordion').each(function(){ 403 var accordion = $(this); 404 var minHeight = accordion.outerHeight(true); 405 accordion.css('min-height',minHeight); 406 }); 407 408 if(window.location.hash !== '' && window.location.hash !== '#' && window.location.hash.match(/#\/.*/) === null){ 409 if($('.accordion > li > .accordion__title'+window.location.hash).length){ 410 mr.accordions.activatePanelById(window.location.hash, true); 411 } 412 } 413 414 jQuery(document).on('click', 'a[href^="#"]:not(a[href="#"])', function(){ 415 416 if($('.accordion > li > .accordion__title'+$(this).attr('href')).length){ 417 mr.accordions.activatePanelById($(this).attr('href'), true); 418 } 419 }); 420 }; 421 422 423 424 mr.accordions.activatePanel = function(panel, forceOpen){ 425 426 var $panel = $(panel), 427 accordion = $panel.closest('.accordion'), 428 li = $panel.closest('li'), 429 openEvent = document.createEvent('Event'), 430 closeEvent = document.createEvent('Event'); 431 432 openEvent.initEvent('panelOpened.accordions.mr', true, true); 433 closeEvent.initEvent('panelClosed.accordions.mr', true, true); 434 435 436 437 if(li.hasClass('active')){ 438 439 if(forceOpen !== true){ 440 441 li.removeClass('active'); 442 $panel.trigger('panelClosed.accordions.mr').get(0).dispatchEvent(closeEvent); 443 } 444 }else{ 445 446 if(accordion.hasClass('accordion--oneopen')){ 447 448 var wasActive = accordion.find('li.active'); 449 if(wasActive.length){ 450 wasActive.removeClass('active'); 451 wasActive.trigger('panelClosed.accordions.mr').get(0).dispatchEvent(closeEvent); 452 } 453 li.addClass('active'); 454 li.trigger('panelOpened.accordions.mr').get(0).dispatchEvent(openEvent); 455 456 }else{ 457 458 if(!li.is('.active')){ 459 li.trigger('panelOpened.accordions.mr').get(0).dispatchEvent(openEvent); 460 } 461 li.addClass('active'); 462 } 463 } 464 }; 465 466 mr.accordions.activatePanelById = function(id, forceOpen){ 467 var panel; 468 469 if(id !== '' && id !== '#' && id.match(/#\/.*/) === null){ 470 panel = $('.accordion > li > .accordion__title#'+id.replace('#', '')); 471 if(panel.length){ 472 $('html, body').stop(true).animate({ 473 scrollTop: (panel.offset().top - 50) 474 }, 1200); 475 476 mr.accordions.activatePanel(panel, forceOpen); 477 } 478 } 479 }; 480 481 mr.components.documentReady.push(mr.accordions.documentReady); 482 return mr; 483 484}(mr, jQuery, window, document)); 485 486
487//////////////// Alerts 488mr = (function (mr, $, window, document){ 489 "use strict"; 490 491 mr.alerts = mr.alerts || {}; 492 493 mr.alerts.documentReady = function($){ 494 $('.alert__close').on('click touchstart', function(){ 495 jQuery(this).closest('.alert').addClass('alert--dismissed'); 496 }); 497 }; 498 499 mr.components.documentReady.push(mr.alerts.documentReady); 500 return mr; 501 502}(mr, jQuery, window, document)); 503 504 505//////////////// Backgrounds 506mr = (function (mr, $, window, document){ 507 "use strict"; 508 509 mr.backgrounds = mr.backgrounds || {}; 510 511 mr.backgrounds.documentReady = function($){ 512 513 //////////////// Append .background-image-holder <img>'s as CSS backgrounds 514 515 $('.background-image-holder').each(function() { 516 var imgSrc = $(this).children('img').attr('src'); 517 $(this).css('background', 'url("' + imgSrc + '")').css('background-position', 'initial').css('opacity','1'); 518 }); 519 }; 520 521 mr.components.documentReady.push(mr.backgrounds.documentReady); 522 return mr; 523 524}(mr, jQuery, window, document)); 525 526//////////////// Bars 527mr = (function (mr, $, window, document){ 528 "use strict"; 529 530 mr.bars = mr.bars || {}; 531 532 mr.bars.documentReady = function($){ 533 $('.nav-container .bar[data-scroll-class*="fixed"]:not(.bar--absolute)').each(function(){ 534 var bar = $(this), 535 barHeight = bar.outerHeight(true); 536 bar.closest('.nav-container').css('min-height',barHeight); 537 }); 538 }; 539 540 mr.components.documentReady.push(mr.bars.documentReady); 541 return mr; 542 543}(mr, jQuery, window, document)); 544 545//////////////// Cookies 546mr = (function (mr, $, window, document){ 547 "use strict"; 548 549 mr.cookies = { 550 551 getItem: function (sKey) { 552 if (!sKey) { return null; } 553 return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null; 554 }, 555 setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) { 556 if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; } 557 var sExpires = ""; 558 if (vEnd) { 559 switch (vEnd.constructor) { 560 case Number: 561 sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd; 562 break; 563 case String: 564 sExpires = "; expires=" + vEnd; 565 break; 566 case Date: 567 sExpires = "; expires=" + vEnd.toUTCString(); 568 break; 569 } 570 } 571 document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : ""); 572 return true; 573 }, 574 removeItem: function (sKey, sPath, sDomain) { 575 if (!this.hasItem(sKey)) { return false; } 576 document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : ""); 577 return true; 578 }, 579 hasItem: function (sKey) { 580 if (!sKey) { return false; } 581 return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); 582 }, 583 keys: function () { 584 var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/); 585 for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); } 586 return aKeys; 587 } 588 }; 589 590 return mr; 591 592}(mr, jQuery, window, document)); 593 594//////////////// Countdown 595mr = (function (mr, $, window, document){ 596 "use strict"; 597 598 mr.countdown = mr.countdown || {}; 599 mr.countdown.options = mr.countdown.options || {}; 600 601 mr.countdown.documentReady = function($){ 602 603 $('.countdown[data-date]').each(function(){ 604 var element = $(this), 605 date = element.attr('data-date'), 606 daysText = typeof element.attr('data-days-text') !== typeof undefined ? '%D '+element.attr('data-days-text')+' %H:%M:%S': '%D days %H:%M:%S', 607 daysText = typeof mr.countdown.options.format !== typeof undefined ? mr.countdown.options.format : daysText, 608 dateFormat = typeof element.attr('data-date-format') !== typeof undefined ? element.attr('data-date-format'): daysText, 609 610 fallback; 611 612 if(typeof element.attr('data-date-fallback') !== typeof undefined){ 613 fallback = element.attr('data-date-fallback') || "Timer Done"; 614 } 615 616 element.countdown(date, function(event) { 617 if(event.elapsed){ 618 element.text(fallback); 619 }else{ 620 element.text( 621 event.strftime(dateFormat) 622 ); 623 } 624 }); 625 }); 626 627 }; 628 629 mr.components.documentReadyDeferred.push(mr.countdown.documentReady); 630 return mr; 631 632}(mr, jQuery, window, document)); 633 634//////////////// Datepicker 635mr = (function (mr, $, window, document){ 636 "use strict"; 637 638 mr.datepicker = mr.datepicker || {}; 639 640 var options = mr.datepicker.options || {}; 641 642 mr.datepicker.documentReady = function($){ 643 if($('.datepicker').length){ 644 $('.datepicker').pickadate(options); 645 } 646 }; 647 648 mr.components.documentReadyDeferred.push(mr.datepicker.documentReady); 649 return mr; 650 651}(mr, jQuery, window, document)); 652 653//////////////// Dropdowns 654mr = (function (mr, $, window, document){ 655 "use strict"; 656 657 mr.dropdowns = mr.dropdowns || {}; 658 659 mr.dropdowns.done = false;
660 661 mr.dropdowns.documentReady = function($){ 662 663 var rtl = false; 664 665 if($('html[dir="rtl"]').length){ 666 rtl = true; 667 } 668 669 if(!mr.dropdowns.done){ 670 jQuery(document).on('click','body:not(.dropdowns--hover) .dropdown, body.dropdowns--hover .dropdown.dropdown--click',function(event){ 671 var dropdown = jQuery(this); 672 if(jQuery(event.target).is('.dropdown--active > .dropdown__trigger')){ 673 dropdown.siblings().removeClass('dropdown--active').find('.dropdown').removeClass('dropdown--active'); 674 dropdown.toggleClass('dropdown--active'); 675 }else{ 676 $('.dropdown--active').removeClass('dropdown--active'); 677 dropdown.addClass('dropdown--active'); 678 } 679 }); 680 jQuery(document).on('click touchstart', 'body:not(.dropdowns--hover)', function(event){ 681 if(!jQuery(event.target).is('[class*="dropdown"], [class*="dropdown"] *')){ 682 $('.dropdown--active').removeClass('dropdown--active'); 683 } 684 }); 685 jQuery('body.dropdowns--hover .dropdown').on('click', function(event){ 686 event.stopPropagation(); 687 var hoverDropdown = jQuery(this); 688 hoverDropdown.toggleClass('dropdown--active'); 689 }); 690 691 // Append a container to the body for measuring purposes 692 jQuery('body').append('<div class="container containerMeasure" style="opacity:0;pointer-events:none;"></div>'); 693 694 695 696 697 // Menu dropdown positioning 698 if(rtl === false){ 699 mr.dropdowns.repositionDropdowns($); 700 jQuery(window).on('resize', function(){mr.dropdowns.repositionDropdowns($);}); 701 }else{ 702 mr.dropdowns.repositionDropdownsRtl($); 703 jQuery(window).on('resize', function(){mr.dropdowns.repositionDropdownsRtl($);}); 704 } 705 706 mr.dropdowns.done = true; 707 } 708 }; 709 710 mr.dropdowns.repositionDropdowns = function($){ 711 $('.dropdown__container').each(function(){ 712 var container, containerOffset, masterOffset, menuItem, content; 713 714 jQuery(this).css('left', ''); 715 716 container = jQuery(this); 717 containerOffset = container.offset().left; 718 masterOffset = jQuery('.containerMeasure').offset().left; 719 menuItem = container.closest('.dropdown').offset().left; 720 content = null; 721 722 container.css('left',((-containerOffset)+(masterOffset))); 723 724 if(container.find('.dropdown__content:not([class*="lg-12"])').length){ 725 content = container.find('.dropdown__content'); 726 content.css('left', ((menuItem)-(masterOffset))); 727 } 728 729 }); 730 $('.dropdown__content').each(function(){ 731 var dropdown, offset, width, offsetRight, winWidth, leftCorrect; 732 733 dropdown = jQuery(this); 734 offset = dropdown.offset().left; 735 width = dropdown.outerWidth(true); 736 offsetRight = offset + width; 737 winWidth = jQuery(window).outerWidth(true); 738 leftCorrect = jQuery('.containerMeasure').outerWidth() - width; 739 740 if(offsetRight > winWidth){ 741 dropdown.css('left', leftCorrect); 742 } 743 744 }); 745 }; 746 747 mr.dropdowns.repositionDropdownsRtl = function($){ 748 749 var windowWidth = jQuery(window).width(); 750 751 $('.dropdown__container').each(function(){ 752 var container, containerOffset, masterOffset, menuItem, content; 753 754 jQuery(this).css('left', ''); 755 756 container = jQuery(this); 757 containerOffset = windowWidth - (container.offset().left + container.outerWidth(true)); 758 masterOffset = jQuery('.containerMeasure').offset().left; 759 menuItem = windowWidth - (container.closest('.dropdown').offset().left + container.closest('.dropdown').outerWidth(true)); 760 content = null; 761 762 container.css('right',((-containerOffset)+(masterOffset))); 763 764 if(container.find('.dropdown__content:not([class*="lg-12"])').length){ 765 content = container.find('.dropdown__content'); 766 content.css('right', ((menuItem)-(masterOffset))); 767 } 768 }); 769 $('.dropdown__content').each(function(){ 770 var dropdown, offset, width, offsetRight, winWidth, rightCorrect; 771 772 dropdown = jQuery(this); 773 offset = windowWidth - (dropdown.offset().left + dropdown.outerWidth(true)); 774 width = dropdown.outerWidth(true); 775 offsetRight = offset + width; 776 winWidth = jQuery(window).outerWidth(true); 777 rightCorrect = jQuery('.containerMeasure').outerWidth() - width; 778 779 if(offsetRight > winWidth){ 780 dropdown.css('right', rightCorrect); 781 } 782 783 }); 784 }; 785 786 787 mr.components.documentReady.push(mr.dropdowns.documentReady); 788 return mr; 789 790}(mr, jQuery, window, document)); 791 792//////////////// Forms 793 794mr = (function (mr, $, window, document){ 795 "use strict"; 796 797 mr.forms = mr.forms || {}; 798 mr.forms.captcha = {}; 799 mr.forms.captcha.widgets = []; 800 mr.forms.captcha.done = false;
801 802 mr.forms.documentReady = function($){ 803 804 mr.forms.captcha.widgets = []; 805 806 /// Checkbox & Radio Inputs 807 808 $('.input-checkbox input[type="checkbox"], .input-radio input[type="radio"]').each(function(index){ 809 var input = $(this), 810 label = input.siblings('label'), 811 id = "input-assigned-"+index; 812 if(typeof input.attr('id') === typeof undefined || input.attr('id') === ""){ 813 input.attr('id',id); 814 label.attr('for',id); 815 }else{ 816 id = input.attr('id'); 817 label.attr('for',id); 818 } 819 }); 820 821 //////////////// Number Inputs 822 823 $('.input-number__controls > span').off('click.mr').on('click.mr',function(){ 824 var control = jQuery(this), 825 parent = control.closest('.input-number'), 826 input = parent.find('input[type="number"]'), 827 max = input.attr('max'), 828 min = input.attr('min'), 829 step = 1, 830 current = parseInt(input.val(),10); 831 832 if(parent.is('[data-step]')){ 833 step = parseInt(parent.attr('data-step'),10); 834 } 835 836 if(control.hasClass('input-number__increase')){ 837 if((current+step) <= max){ 838 input.val(current+step); 839 } 840 }else{ 841 if((current-step) >= min){ 842 input.val(current-step); 843 } 844 } 845 }); 846 847
848 //////////////// File Uploads 849 850 $('.input-file .btn').off('click.mr').on('click.mr',function(){ 851 $(this).siblings('input').trigger('click'); 852 return false; 853 }); 854 855 //////////////// Handle Form Submit 856 857 $('form.form-email, form[action*="list-manage.com"], form[action*="createsend.com"]').attr('novalidate', true).off('submit').on('submit', mr.forms.submit); 858 859 //////////////// Handle Form Submit 860 $(document).on('change, input, paste, keyup', '.attempted-submit .field-error', function(){ 861 $(this).removeClass('field-error'); 862 }); 863 864 //////////////// Check forms for Google reCaptcha site keys 865 866 $('form[data-recaptcha-sitekey]:not([data-recaptcha-sitekey=""])').each(function(){ 867 var $thisForm = jQuery(this), 868 $captchaDiv = $thisForm.find('div.recaptcha'), 869 $insertBefore, $column, widgetObject, $script, scriptSrc, widgetColourTheme, widgetSize; 870 871 widgetColourTheme = $thisForm.attr('data-recaptcha-theme'); 872 widgetColourTheme = typeof widgetColourTheme !== typeof undefined ? widgetColourTheme : ''; 873 874 widgetSize = $thisForm.attr('data-recaptcha-size'); 875 widgetSize = typeof widgetSize !== typeof undefined ? widgetSize : ''; 876 877 // Store the site key for later use 878 mr.forms.captcha.sitekey = $thisForm.attr('data-recaptcha-sitekey'); 879 880 if($captchaDiv.length){ 881 // If a div.recaptcha was already present on this form, do nothing at this stage, 882 // It will be populated with a captcha widget later. 883 }else{ 884 // Create a captcha div and insert it before the submit button. 885 $insertBefore = $thisForm.find('button[type=submit]').closest('[class*="col-"]'); 886 $captchaDiv = jQuery('<div>').addClass('recaptcha'); 887 $column = jQuery('<div>').addClass('col-12').append($captchaDiv); 888 $column.insertBefore($insertBefore); 889 } 890 891 892 // Add the widget div to the widgets array 893 widgetObject = { 894 element: $captchaDiv.get(0), 895 parentForm: $thisForm, 896 theme: widgetColourTheme, 897 size: widgetSize, 898 }; 899 900 901 902 mr.forms.captcha.widgets.push(widgetObject); 903 904 // mr.forms.captcha.done indicates whether the api script has been appended yet. 905 if(mr.forms.captcha.done === false){ 906 if(!jQuery('script[src*="recaptcha/api.js"]').length){ 907 $script = jQuery('<script async defer>'); 908 scriptSrc = 'https://www.google.com/recaptcha/api.js?onload=mrFormsCaptchaInit&render=explicit'; 909 $script.attr('src', scriptSrc); 910 jQuery('body').append($script); 911 mr.forms.captcha.done = true; 912 } 913 }else{ 914 if(typeof grecaptcha !== typeof undefined){ 915 mr.forms.captcha.renderWidgets(); 916 } 917 } 918 919 }); 920 921 922 }; 923 924 mr.forms.submit = function(e){ 925 // return false so form submits through jQuery rather than reloading page. 926 if (e.preventDefault) e.preventDefault(); 927 else e.returnValue = false; 928 929 var body = $('body'), 930 thisForm = $(e.target).closest('form'), 931 formAction = typeof thisForm.attr('action') !== typeof undefined ? thisForm.attr('action') : "", 932 submitButton = thisForm.find('button[type="submit"], input[type="submit"]'), 933 error = 0, 934 originalError = thisForm.attr('original-error'), 935 captchaUsed = thisForm.find('div.recaptcha').length ? true:false, 936 successRedirect, formError, formSuccess, errorText, successText; 937 938 body.find('.form-error, .form-success').remove(); 939 submitButton.attr('data-text', submitButton.text()); 940 errorText = thisForm.attr('data-error') ? thisForm.attr('data-error') : "Please fill all fields correctly"; 941 successText = thisForm.attr('data-success') ? thisForm.attr('data-success') : "Thanks, we'll be in touch shortly"; 942 body.append('<div class="form-error" style="display: none;">' + errorText + '</div>'); 943 body.append('<div class="form-success" style="display: none;">
943' + successText + '</div>'); 944 formError = body.find('.form-error'); 945 formSuccess = body.find('.form-success'); 946 thisForm.addClass('attempted-submit'); 947 948 // Do this if the form is intended to be submitted to MailChimp or Campaign Monitor 949 if (formAction.indexOf('createsend.com') !== -1 || formAction.indexOf('list-manage.com') !== -1 ) { 950 951 console.log('Mail list form signup detected.'); 952 if (typeof originalError !== typeof undefined && originalError !== false) { 953 formError.html(originalError); 954 } 955 956 // validateFields returns 1 on error; 957 if (mr.forms.validateFields(thisForm) !== 1) { 958 959 thisForm.removeClass('attempted-submit'); 960 961 // Hide the error if one was shown 962 formError.fadeOut(200); 963 // Create a new loading spinner in the submit button. 964 submitButton.addClass('btn--loading'); 965 966 try{ 967 $.ajax({ 968 url: thisForm.attr('action'), 969 crossDomain: true, 970 data: thisForm.serialize(), 971 method: "GET", 972 cache: false, 973 dataType: 'json', 974 contentType: 'application/json; charset=utf-8', 975 success: function(data){ 976 // Request was a success, what was the response? 977 978 if (data.result !== "success" && data.Status !== 200) { 979 980 // Got an error from Mail Chimp or Campaign Monitor 981 982 // Keep the current error text in a data attribute on the form 983 formError.attr('original-error', formError.text()); 984 // Show the error with the returned error text. 985 formError.html(data.msg).stop(true).fadeIn(1000); 986 formSuccess.stop(true).fadeOut(1000); 987 988 submitButton.removeClass('btn--loading'); 989 } else { 990 991 // Got success from Mail Chimp or Campaign Monitor 992 993 submitButton.removeClass('btn--loading'); 994 995 successRedirect = thisForm.attr('data-success-redirect'); 996 // For some browsers, if empty `successRedirect` is undefined; for others, 997 // `successRedirect` is false. Check for both. 998 if (typeof successRedirect !== typeof undefined && successRedirect !== false && successRedirect !== "") { 999 window.location = successRedirect; 1000 }else{ 1001 mr.forms.resetForm(thisForm); 1002 mr.forms.showFormSuccess(formSuccess, formError, 1000, 5000, 500); 1003 } 1004 } 1005 } 1006 }); 1007 }catch(err){ 1008 // Keep the current error text in a data attribute on the form 1009 formError.attr('original-error', formError.text()); 1010 // Show the error with the returned error text. 1011 formError.html(err.message); 1012 mr.forms.showFormError(formSuccess, formError, 1000, 5000, 500); 1013 1014 submitButton.removeClass('btn--loading'); 1015 } 1016 1017 1018 1019 } else { 1020 // There was a validation error - show the default form error message 1021 mr.forms.showFormError(formSuccess, formError, 1000, 5000, 500); 1022 } 1023 } else { 1024 // If no MailChimp or Campaign Monitor form was detected then this is treated as an email form instead. 1025 if (typeof originalError !== typeof undefined && originalError !== false) { 1026 formError.text(originalError); 1027 } 1028 1029 error = mr.forms.validateFields(thisForm); 1030 1031 if (error === 1) { 1032 mr.forms.showFormError(formSuccess, formError, 1000, 5000, 500); 1033 } else { 1034 1035 thisForm.removeClass('attempted-submit'); 1036 1037 // Hide the error if one was shown 1038 formError.fadeOut(200); 1039 1040 // Create a new loading spinner in the submit button. 1041 submitButton.addClass('btn--loading'); 1042 1043 jQuery.ajax({ 1044 type: "POST", 1045 url: (formAction !== "" ? formAction : "mail/mail.php"), 1046 data: thisForm.serialize()+"&url="+window.location.href+"&captcha="+captchaUsed, 1047 success: function(response) { 1048 // Swiftmailer always sends back a number representing number of emails sent. 1049 // If this is numeric (not Swift Mailer error text) AND greater than 0 then show success message. 1050 1051 submitButton.removeClass('btn--loading'); 1052 1053 if ($.isNumeric(response)) { 1054 if (parseInt(response,10) > 0) { 1055 // For some browsers, if empty 'successRedirect' is undefined; for others, 1056 // 'successRedirect' is false. Check for both. 1057 successRedirect = thisForm.attr('data-success-redirect'); 1058 if (typeof successRedirect !== typeof undefined && successRedirect !== false && successRedirect !== "") { 1059 window.location = successRedirect; 1060 } 1061 1062 mr.forms.resetForm(thisForm); 1063 mr.forms.showFormSuccess(formSuccess, formError, 1000, 5000, 500); 1064 mr.forms.captcha.resetWidgets(); 1065 } 1066 } 1067 // If error text was returned, put the text in the .form-error div and show it. 1068 else { 1069 // Keep the current error text in a data attribute on the form 1070 formError.attr('original-error', formError.text()); 1071 // Show the error with the returned error text. 1072 formError.text(response).stop(true).fadeIn(1000); 1073 formSuccess.stop(true).fadeOut(1000); 1074 } 1075 }, 1076 error: function(errorObject, errorText, errorHTTP) { 1077 // Keep the current error text in a data attribute on the form 1078 formError.attr('original-error', formError.text()); 1079 // Show the error with the returned error text. 1080 formError.text(errorHTTP).stop(true).fadeIn(1000); 1081 formSuccess.stop(true).fadeOut(1000); 1082 submitButton.removeClass('btn--loading'); 1083 } 1084 }); 1085 } 1086 } 1087 return false;
1088 }; 1089 1090 mr.forms.validateFields = function(form) { 1091 var body = $(body), 1092 error = false, 1093 originalErrorMessage, 1094 name, 1095 thisElement; 1096 1097 form = $(form); 1098 1099 1100 1101 1102 form.find('.validate-required[type="checkbox"]').each(function() { 1103 var checkbox = $(this); 1104 if (!$('[name="' + $(this).attr('name') + '"]:checked').length) { 1105 error = 1; 1106 name = $(this).attr('data-name') || 'check'; 1107 checkbox.parent().addClass('field-error'); 1108 //body.find('.form-error').text('Please tick at least one ' + name + ' box.'); 1109 } 1110 }); 1111 1112 form.find('.validate-required, .required, [required]').not('input[type="checkbox"]').each(function() { 1113 if ($(this).val() === '') { 1114 $(this).addClass('field-error'); 1115 error = 1; 1116 } else { 1117 $(this).removeClass('field-error'); 1118 } 1119 }); 1120 1121 form.find('.validate-email, .email, [name*="cm-"][type="email"]').each(function() { 1122 if (!(/(.+)@(.+){2,}\.(.+){2,}/.test($(this).val()))) { 1123 $(this).addClass('field-error'); 1124 error = 1; 1125 } else { 1126 $(this).removeClass('field-error'); 1127 } 1128 }); 1129 1130 form.find('.validate-number-dash').each(function() { 1131 if (!(/^[0-9][0-9-]+[0-9]$/.test($(this).val()))) { 1132 $(this).addClass('field-error'); 1133 error = 1; 1134 } else { 1135 $(this).removeClass('field-error'); 1136 } 1137 }); 1138 1139 // Validate recaptcha 1140 if(form.find('div.recaptcha').length && typeof form.attr('data-recaptcha-sitekey') !== typeof undefined){ 1141 thisElement = $(form.find('div.recaptcha')); 1142 1143 if(grecaptcha.getResponse(form.data('recaptchaWidgetID')) !== ""){ 1144 thisElement.removeClass('field-error'); 1145 }else{ 1146 thisElement.addClass('field-error'); 1147 error = 1; 1148 } 1149 } 1150 1151 if (!form.find('.field-error').length) { 1152 body.find('.form-error').fadeOut(1000); 1153 }else{ 1154 1155 var firstError = $(form).find('.field-error:first'); 1156 1157 if(firstError.length){ 1158 $('html, body').stop(true).animate({ 1159 scrollTop: (firstError.offset().top - 100) 1160 }, 1200, function(){firstError.focus();}); 1161 } 1162 } 1163 1164 1165 1166 return error; 1167 }; 1168 1169 mr.forms.showFormSuccess = function(formSuccess, formError, fadeOutError, wait, fadeOutSuccess){ 1170 1171 formSuccess.stop(true).fadeIn(fadeOutError); 1172 1173 formError.stop(true).fadeOut(fadeOutError); 1174 setTimeout(function() { 1175 formSuccess.stop(true).fadeOut(fadeOutSuccess); 1176 }, wait); 1177 }; 1178 1179 mr.forms.showFormError = function(formSuccess, formError, fadeOutSuccess, wait, fadeOutError){ 1180 1181 formError.stop(true).fadeIn(fadeOutSuccess); 1182 1183 formSuccess.stop(true).fadeOut(fadeOutSuccess); 1184 setTimeout(function() { 1185 formError.stop(true).fadeOut(fadeOutError); 1186 }, wait); 1187 }; 1188 1189 // Reset form to empty/default state. 1190 mr.forms.resetForm = function(form){ 1191 form = $(form); 1192 form.get(0).reset(); 1193 form.find('.input-radio, .input-checkbox').removeClass('checked'); 1194 form.find('[data-default-value]').filter('[type="text"],[type="number"],[type="email"],[type="url"],[type="search"],[type="tel"]').each(function(){ 1195 var elem = jQuery(this); 1196 elem.val(elem.attr('data-default-value')); 1197 }); 1198 1199 }; 1200 1201 // Defined on the window scope as the recaptcha js api seems not to be able to call function in mr scope 1202 window.mrFormsCaptchaInit = function(){ 1203 mr.forms.captcha.renderWidgets(); 1204 }; 1205 1206 mr.forms.captcha.renderWidgets = function(){ 1207 mr.forms.captcha.widgets.forEach(function(widget){ 1208 if(widget.element.innerHTML.replace(/[\s\xA0]+/g,'') === ''){ 1209 widget.id = grecaptcha.render(widget.element, { 1210 'sitekey' : mr.forms.captcha.sitekey, 1211 'theme' : widget.theme, 1212 'size' : widget.size, 1213 'callback' : mr.forms.captcha.setHuman 1214 }); 1215 widget.parentForm.data('recaptchaWidgetID', widget.id); 1216 } 1217 }); 1218 }; 1219 1220 mr.forms.captcha.resetWidgets = function(){
1221 mr.forms.captcha.widgets.forEach(function(widget){ 1222 grecaptcha.reset(widget.id); 1223 }); 1224 }; 1225 1226 mr.forms.captcha.setHuman = function(){ 1227 jQuery('div.recaptcha.field-error').removeClass('field-error'); 1228 }; 1229 1230 mr.components.documentReadyDeferred.push(mr.forms.documentReady); 1231 return mr; 1232 1233}(mr, jQuery, window, document)); 1234 1235//////////////// Granim 1236mr = (function (mr, $, window, document){ 1237 "use strict"; 1238 1239 mr.granim = mr.granim || {}; 1240 1241 mr.granim.documentReady = function($){ 1242 $('[data-gradient-bg]').each(function(index,element){ 1243 var granimParent = $(this), 1244 granimID = 'granim-'+index+'', 1245 colours = granimParent.attr('data-gradient-bg'), 1246 pairs = [], 1247 tempPair = [], 1248 ao = {}, 1249 count, 1250 passes, 1251 i, 1252 themeDefaults, 1253 1254 options; 1255 1256 // Canvas element forms the gradient background 1257 granimParent.prepend('<canvas id="'+granimID+'"></canvas>'); 1258 1259 // Regular expression to match comma separated list of hex colour values 1260 passes = /^(#[0-9|a-f|A-F]{6}){1}([ ]*,[ ]*#[0-9|a-f|A-F]{6})*$/.test(colours); 1261 1262 if(passes === true){ 1263 colours = colours.replace(' ',''); 1264 colours = colours.split(','); 1265 count = colours.length; 1266 // If number of colours is odd - duplicate last colour to make even array 1267 if(count%2 !== 0){ 1268 colours.push(colours[count-1]); 1269 } 1270 for(i = 0; i < (count/2); i++){ 1271 tempPair = []; 1272 tempPair.push(colours.shift()); 1273 tempPair.push(colours.shift()); 1274 pairs.push(tempPair); 1275 } 1276 1277 // attribute overrides - allows per-gradient override of global options. 1278 ao.states = { 1279 "default-state": { 1280 gradients: pairs 1281 } 1282 } 1283 } 1284 1285 themeDefaults = { 1286 element: '#'+granimID, 1287 name: 'basic-gradient', 1288 direction: 'left-right', 1289 opacity: [1, 1], 1290 isPausedWhenNotInView: true, 1291 states : { 1292 "default-state": { 1293 gradients: pairs 1294 } 1295 } 1296 }; 1297 1298 options = jQuery.extend({}, themeDefaults, mr.granim.options, ao); 1299 $(this).data('gradientOptions', options); 1300 var granimElement = $(this); 1301 var granimInstance = new Granim(options); 1302 }); 1303 }; 1304 1305 mr.components.documentReadyDeferred.push(mr.granim.documentReady); 1306 return mr; 1307 1308}(mr, jQuery, window, document)); 1309 1310//////////////// Instagram 1311mr = (function (mr, $, window, document){ 1312 "use strict"; 1313 1314 mr.instagram = mr.instagram || {}; 1315 1316 mr.instagram.documentReady = function($){ 1317 1318 var themeDefaults, options, ao = {}; 1319 1320 if($('.instafeed').length){ 1321 1322 // Replace with your own Access Token and Client ID 1323 var token = '4079540202.b9b1d8a.1d13c245c68d4a17bfbff87919aaeb14', 1324 client = 'b9b1d8ae049d4153b24a6332f0088686', 1325 elementToken, elementClient; 1326 1327 if($('.instafeed[data-access-token][data-client-id]').length){ 1328 elementToken = $('.instafeed[data-access-token][data-client-id]').first().attr('data-access-token'); 1329 elementClient = $('.instafeed[data-access-token][data-client-id]').first().attr('data-client-id'); 1330 1331 if(elementToken !== ""){token = elementToken;} 1332 if(elementClient !== ""){client = elementClient;} 1333 } 1334 1335 jQuery.fn.spectragram.accessData = { 1336 accessToken: token, 1337 clientID: client 1338 }; 1339 } 1340 1341 $('.instafeed').each(function(){ 1342 var feed = $(this), 1343 feedID = feed.attr('data-user-name'), 1344 fetchNumber = 12; 1345 1346 themeDefaults = { 1347 query: 'mediumrarethemes', 1348 max: 12 1349 }; 1350 1351 // Attribute Overrides taken from data attributes allow for per-feed customization 1352 ao.max = feed.attr('data-amount') 1353 ao.query = feed.attr('data-user-name'); 1354 1355 options = jQuery.extend({}, themeDefaults, mr.instagram.options, ao); 1356 1357 feed.append('<ul></ul>'); 1358 feed.children('ul').spectragram('getUserFeed', options); 1359 }); 1360 }; 1361 1362 mr.components.documentReadyDeferred.push(mr.instagram.documentReady); 1363 return mr; 1364 1365}(mr, jQuery, window, document)); 1366 1367//////////////// Maps 1368mr = (function (mr, $, window, document){ 1369 "use strict"; 1370 1371 mr.maps = mr.maps || {}; 1372 mr.maps.options = mr.maps.options || {}; 1373 1374 mr.maps.documentReady = function($){ 1375 // Interact with Map once the user has clicked (to prevent scrolling the page = zooming the map 1376 1377 $('.map-holder').on('click', function() { 1378 $(this).addClass('interact'); 1379 }).removeClass('interact'); 1380 1381 var mapsOnPage = $('.map-container[data-maps-api-key]'); 1382 if(mapsOnPage.length){ 1383 mapsOnPage.addClass('gmaps-active'); 1384 mr.maps.initAPI($); 1385 mr.maps.init(); 1386 } 1387 1388 }; 1389 1390 mr.maps.initAPI = function($){ 1391 // Load Google MAP API JS with callback to initialise when fully loaded 1392 if(document.querySelector('[data-maps-api-key]') && !document.querySelector('.gMapsAPI')){ 1393 if($('[data-maps-api-key]').length){ 1394 var script = document.createElement('script'); 1395 var apiKey = $('[data-maps-api-key]:first').attr('data-maps-api-key'); 1396 apiKey = typeof apiKey !== typeof undefined ? apiKey : ''; 1397 if(apiKey !== ''){ 1398 script.type = 'text/javascript'; 1399 script.src = 'https://maps.googleapis.com/ma
1399ps/api/js?key='+apiKey+'&callback=mr.maps.init'; 1400 script.className = 'gMapsAPI'; 1401 document.body.appendChild(script); 1402 } 1403 } 1404 } 1405 }; 1406 1407 mr.maps.init = function(){ 1408 if(typeof window.google !== "undefined"){ 1409 if(typeof window.google.maps !== "undefined"){ 1410 1411 mr.maps.instances = []; 1412 1413 1414 jQuery('.gmaps-active').each(function(){ 1415 var mapElement = this, 1416 mapInstance = jQuery(this), 1417 isDraggable = jQuery(document).width() > 766 ? true : false, 1418 showZoomControl = typeof mapInstance.attr('data-zoom-controls') !== typeof undefined ? true : false, 1419 zoomControlPos = typeof mapInstance.attr('data-zoom-controls') !== typeof undefined ? mapInstance.attr('data-zoom-controls'): false, 1420 latlong = typeof mapInstance.attr('data-latlong') !== typeof undefined ? mapInstance.attr('data-latlong') : false, 1421 latitude = latlong ? 1 *latlong.substr(0, latlong.indexOf(',')) : false, 1422 longitude = latlong ? 1 * latlong.substr(latlong.indexOf(",") + 1) : false, 1423 geocoder = new google.maps.Geocoder(), 1424 address = typeof mapInstance.attr('data-address') !== typeof undefined ? mapInstance.attr('data-address').split(';'): [""], 1425 map, marker, markerDefaults,mapDefaults,mapOptions, markerOptions, mapAo = {}, markerAo = {}, mapCreatedEvent; 1426 1427 mapCreatedEvent = document.createEvent('Event'); 1428 mapCreatedEvent.initEvent('mapCreated.maps.mr', true, true); 1429 1430 1431 1432 1433 mapDefaults = { 1434 disableDefaultUI: true, 1435 draggable: isDraggable, 1436 scrollwheel: false, 1437 styles: [{"featureType":"landscape","stylers":[{"saturation":-100},{"lightness":65},{"visibility":"on"}]},{"featureType":"poi","stylers":[{"saturation":-100},{"lightness":51},{"visibility":"simplified"}]},{"featureType":"road.highway","stylers":[{"saturation":-100},{"visibility":"simplified"}]},{"featureType":"road.arterial","stylers":[{"saturation":-100},{"lightness":30},{"visibility":"on"}]},{"featureType":"road.local","stylers":[{"saturation":-100},{"lightness":40},{"visibility":"on"}]},{"featureType":"transit","stylers":[{"saturation":-100},{"visibility":"simplified"}]},{"featureType":"administrative.province","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"labels","stylers":[{"visibility":"on"},{"lightness":-25},{"saturation":-100}]},{"featureType":"water","elementType":"geometry","stylers":[{"hue":"#ffff00"},{"lightness":-25},{"saturation":-97}]}], 1438 zoom: 17, 1439 zoomControl: false, 1440 }; 1441 1442 // Attribute overrides - allows data attributes on the map to override global options 1443 mapAo.styles = typeof mapInstance.attr('data-map-style') !== typeof undefined ? JSON.parse(mapInstance.attr('data-map-style')): undefined; 1444 mapAo.zoom = mapInstance.attr('data-map-zoom') ? parseInt(mapInstance.attr('data-map-zoom'),10) : undefined; 1445 mapAo.zoomControlOptions = zoomControlPos !== false ? {position: google.maps.ControlPosition[zoomControlPos]} : undefined; 1446 1447 markerDefaults = { 1448 icon: {url:( typeof mr_variant !== typeof undefined ? '../': '' )+'img/mapmarker.png', scaledSize: new google.maps.Size(50,50)}, 1449 title: 'We Are Here', 1450 optimised: false 1451 }; 1452 1453 markerAo.icon = typeof mapInstance.attr('data-marker-image') !== typeof undefined ? {url: mapInstance.attr('data-marker-image'), scaledSize: new google.maps.Size(50,50)} : undefined; 1454 markerAo.title = mapInstance.attr('data-marker-title'); 1455 1456 mapOptions = jQuery.extend({}, mapDefaults, mr.maps.options.map, mapAo); 1457 markerOptions = jQuery.extend({}, markerDefaults, mr.maps.options.marker, markerAo); 1458 1459 1460 if(address !== undefined && address[0] !== ""){ 1461 geocoder.geocode( { 'address': address[0].replace('[nomarker]','')}, function(results, status) { 1462 if (status === google.maps.GeocoderStatus.OK) { 1463 map = new google.maps.Map(mapElement, mapOptions); 1464 1465 1466 mr.maps.instances.push(map); 1467 jQuery(mapElement).trigger('mapCreated.maps.mr').get(0).dispatchEvent(mapCreatedEvent); 1468 map.setCenter(results[0].geometry.location); 1469 1470 address.forEach(function(address){ 1471 var markerGeoCoder; 1472 1473 if(/(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)/.test(address) ){ 1474 var latlong = address.split(','), 1475 marker = new google.maps.Marker(jQuery.extend({}, markerOptions, { 1476 position: { lat: 1*latlong[0], lng: 1*latlong[1] }, 1477 map: map, 1478 })); 1479 }
1480 else if(address.indexOf('[nomarker]') < 0){ 1481 markerGeoCoder = new google.maps.Geocoder(); 1482 markerGeoCoder.geocode( { 'address': address.replace('[nomarker]','')}, function(results, status) { 1483 if (status === google.maps.GeocoderStatus.OK) { 1484 marker = new google.maps.Marker(jQuery.extend({}, markerOptions, { 1485 map: map, 1486 position: results[0].geometry.location, 1487 })); 1488 } 1489 else{ 1490 console.log('Map marker error: '+status); 1491 } 1492 }); 1493 } 1494 1495 }); 1496 } else { 1497 console.log('There was a problem geocoding the address.'); 1498 } 1499 }); 1500 } 1501 else if(typeof latitude !== typeof undefined && latitude !== "" && latitude !== false && typeof longitude !== typeof undefined && longitude !== "" && longitude !== false ){ 1502 1503 mapOptions.center = { lat: latitude, lng: longitude}; 1504 map = new google.maps.Map(mapElement, mapOptions); 1505 marker = new google.maps.Marker(jQuery.extend({}, markerOptions, { 1506 position: { lat: latitude, lng: longitude }, 1507 map: map })); 1508 mr.maps.instances.push(map); 1509 jQuery(mapElement).trigger('mapCreated.maps.mr').get(0).dispatchEvent(mapCreatedEvent); 1510 1511 1512 } 1513 1514 1515 1516 }); 1517 } 1518 } 1519 }; 1520 1521 mr.components.documentReady.push(mr.maps.documentReady); 1522 return mr; 1523 1524}(mr, jQuery, window, document)); 1525 1526 1527//////////////// Masonry 1528mr = (function (mr, $, window, document){ 1529 "use strict"; 1530 1531 mr.masonry = mr.masonry || {}; 1532 1533 mr.masonry.documentReady = function($){ 1534 1535 mr.masonry.updateFilters(); 1536 1537 $(document).on('click touchstart', '.masonry__filters li:not(.js-no-action)', function(){ 1538 var masonryFilter = $(this); 1539 var masonryContainer = masonryFilter.closest('.masonry').find('.masonry__container'); 1540 var filterValue = '*'; 1541 if(masonryFilter.attr('data-masonry-filter') !== '*'){ 1542 filterValue = '.filter-'+masonryFilter.attr('data-masonry-filter'); 1543 } 1544 masonryFilter.siblings('li').removeClass('active'); 1545 masonryFilter.addClass('active'); 1546 masonryContainer.removeClass('masonry--animate'); 1547 masonryContainer.on('layoutComplete',function(){ 1548 $(this).addClass('masonry--active'); 1549 if(typeof mr_parallax !== typeof undefined){ 1550 setTimeout(function(){ mr_parallax.profileParallaxElements(); },100); 1551 } 1552 }); 1553 masonryContainer.isotope({ filter: filterValue }); 1554 1555 }); 1556 1557 }; 1558 1559 mr.masonry.windowLoad = function(){ 1560 1561 $('.masonry').each(function(){ 1562 var masonry = $(this).find('.masonry__container'), 1563 masonryParent = $(this), 1564 defaultFilter = '*', 1565 themeDefaults, ao = {}; 1566 1567 themeDefaults = { 1568 itemSelector: '.masonry__item', 1569 filter: '*', 1570 masonry: { 1571 columnWidth: '.masonry__item' 1572 } 1573 }; 1574 1575 // Check for a default filter attribute 1576 if(masonryParent.is('[data-default-filter]')){ 1577 defaultFilter = masonryParent.attr('data-default-filter').toLowerCase(); 1578 defaultFilter = '.filter-'+defaultFilter; 1579 masonryParent.find('li[data-masonry-filter]').removeClass('active'); 1580 masonryParent.find('li[data-masonry-filter="'+masonryParent.attr("data-default-filter").toLowerCase()+'"]').addClass('active'); 1581 } 1582 1583 // Use data attributes to override the default settings and provide a per-masonry customisation where necessary. 1584 ao.filter = defaultFilter !== '*' ? defaultFilter : undefined; 1585 1586 masonry.on('layoutComplete',function(){ 1587 masonry.addClass('masonry--active'); 1588 if(typeof mr_parallax !== typeof undefined){ 1589 setTimeout(function(){ mr_parallax.profileParallaxElements(); },100); 1590 } 1591 }); 1592 1593 1594 masonry.isotope(jQuery.extend({}, themeDefaults, mr.masonry.options, ao)); 1595 1596 }); 1597 }; 1598 1599 mr.masonry.updateFilters = function(masonry){ 1600 1601 // If no argument is supplied, just apply the update to all masonry sets on the page. 1602 masonry = typeof masonry !== typeof undefined ? masonry : '.masonry'; 1603 1604 var $masonry = $(masonry); 1605 1606 $masonry.each(function(){ 1607 var $masonry = $(this), 1608 masonryContainer = $masonry.find('.masonry__container'), 1609 filters = $masonry.find('.masonry__filters'), 1610 // data-filter-all-text can be used to set the word for "all" 1611 filterAllText = typeof filters.attr('data-filter-all-text') !== typeof undefined ? filters.attr('data-filter-all-text') : "All", 1612 filtersList; 1613 1614 // Ensure we are working with a .masonry element 1615 if($masonry.is('.masonry')){ 1616 // If a filterable masonry item exists 1617 if(masonryContainer.find('.masonry__item[data-masonry-filter]').length){ 1618 1619 // Create empty ul for filters 1620 filtersList = filters.find('> ul'); 1621 1622 if(!filtersList.length){ 1623 filtersList = filters.append('<ul></ul>').find('> ul'); 1624 } 1625 1626 // To avoid cases where user leave filter attribute blank 1627 // only take items that have filter attribute 1628 masonryContainer.find('.masonry__item[data-masonry-filter]').each(function(){ 1629 var masonryItem = $(this), 1630 filterString = masonryItem.attr('data-masonry-filter'), 1631 filtersArray = []; 1632 1633 // If not undefined or empty 1634 if(typeof filterString !== typeof undefined && filterString !== ""){ 1635 // Split tags from string into array 1636 filtersArray = filterString.split(','); 1637 } 1638 $(filtersArray).each(function(index, tag){ 1639 1640 // Slugify the tag 1641 1642 var slug = mr.util.slugify(tag); 1643 1644 // Add the filter class to the masonry item 1645 1646 masonryItem.addClass('filter-'+slug); 1647 1648 // If this tag does not appear in the list already, add it 1649 if(!filtersList.find('[data-masonry-filter="'+slug+'"]').length){ 1650 filtersList.append('<li data-masonry-filter="'+slug+'">'+tag+'</li>'); 1651 1652 } 1653 }); 1654 }); 1655
1656 // Remove any unnused filter options in list 1657 filtersList.find('[data-masonry-filter]').each(function(){ 1658 var $this = $(this), 1659 filter = $this.text(); 1660 1661 if($(this).attr('data-masonry-filter') !== "*"){ 1662 if(!$masonry.find('.masonry__item[data-masonry-filter*="'+filter+'"]').length){ 1663 $this.remove(); 1664 } 1665 } 1666 }); 1667 1668 mr.util.sortChildrenByText($(this).find('.masonry__filters ul')); 1669 // Add a filter "all" option 1670 if(!filtersList.find('[data-masonry-filter="*"]').length){ 1671 filtersList.prepend('<li class="active" data-masonry-filter="*">'+filterAllText+'</li>'); 1672 } 1673 1674 } 1675 //End of "if filterable masonry item exists" 1676 } 1677 //End of "if $masonry is .masonry" 1678 }); 1679 1680 }; 1681 1682 mr.masonry.updateLayout = function(masonry){ 1683 1684 // If no argument is supplied, just apply the update to all masonry sets on the page. 1685 masonry = typeof masonry !== typeof undefined ? masonry : '.masonry'; 1686 1687 var $masonry = $(masonry); 1688 1689 1690 $masonry.each(function(){ 1691 var collection = $(this), 1692 newItems = collection.find('.masonry__item:not([style])'), 1693 masonryContainer = collection.find('.masonry__container'); 1694 1695 if(collection.is('.masonry')){ 1696 if(newItems.length){ 1697 masonryContainer.isotope('appended', newItems).isotope( 'layout'); 1698 } 1699 1700 masonryContainer.isotope('layout'); 1701 } 1702 }); 1703 }; 1704 1705 mr.components.documentReady.push(mr.masonry.documentReady); 1706 mr.components.windowLoad.push(mr.masonry.windowLoad); 1707 return mr; 1708 1709}(mr, jQuery, window, document)); 1710 1711 1712//////////////// Modals 1713mr = (function (mr, $, window, document){ 1714 "use strict"; 1715 1716 mr.modals = mr.modals || {}; 1717 1718 mr.modals.documentReady = function($){ 1719 var allPageModals = "<div class=\"all-page-modals\"></div>", 1720 mainContainer = $('div.main-container'); 1721 1722 if(mainContainer.length){ 1723 jQuery(allPageModals).insertAfter(mainContainer); 1724 mr.modals.allModalsContainer = $('div.all-page-modals'); 1725 } 1726 else{ 1727 jQuery('body').append(allPageModals); 1728 mr.modals.allModalsContainer = jQuery('body div.all-page-modals'); 1729 } 1730 1731 $('.modal-container').each(function(){ 1732 1733 // Add modal close if none exists 1734 1735 var modal = $(this), 1736 $window = $(window), 1737 modalContent = modal.find('.modal-content'); 1738 1739 1740 if(!modal.find('.modal-close').length){ 1741 modal.find('.modal-content').append('<div class="modal-close modal-close-cross"></div>'); 1742 } 1743 1744 // Set modal height 1745 1746 if(modalContent.attr('data-width') !== undefined){ 1747 var modalWidth = modalContent.attr('data-width').substr(0,modalContent.attr('data-width').indexOf('%')) * 1; 1748 modalContent.css('width',modalWidth + '%'); 1749 } 1750 if(modalContent.attr('data-height') !== undefined){ 1751 var modalHeight = modalContent.attr('data-height').substr(0,modalContent.attr('data-height').indexOf('%')) * 1; 1752 modalContent.css('height',modalHeight + '%'); 1753 } 1754 1755 // Set iframe's src to data-src to stop autoplaying iframes 1756 mr.util.idleSrc(modal, 'iframe'); 1757 1758 }); 1759 1760 1761 $('.modal-instance').each(function(index){ 1762 var modalInstance = $(this); 1763 var modal = modalInstance.find('.modal-container'); 1764 var modalContent = modalInstance.find('.modal-content'); 1765 var trigger = modalInstance.find('.modal-trigger'); 1766 1767 // Link modal with modal-id attribute 1768 1769 trigger.attr('data-modal-index',index); 1770 modal.attr('data-modal-index',index); 1771 1772 // Set unique id for multiple triggers 1773 1774 if(typeof modal.attr('data-modal-id') !== typeof undefined){ 1775 trigger.attr('data-modal-id', modal.attr('data-modal-id')); 1776 } 1777 1778 1779 // Attach the modal to the body 1780 modal = modal.detach(); 1781 mr.modals.allModalsContainer.append(modal); 1782 }); 1783 1784 1785 $('.modal-trigger').on('click', function(){ 1786 1787 var modalTrigger = $(this); 1788 var uniqueID, targetModal; 1789 // Determine if the modal id is set by user or is set programatically 1790 1791 if(typeof modalTrigger.attr('data-modal-id') !== typeof undefined){ 1792 uniqueID = modalTrigger.attr('data-modal-id'); 1793 targetModal = mr.modals.allModalsContainer.find('.modal
1793-container[data-modal-id="'+uniqueID+'"]'); 1794 }else{ 1795 uniqueID = $(this).attr('data-modal-index'); 1796 targetModal = mr.modals.allModalsContainer.find('.modal-container[data-modal-index="'+uniqueID+'"]'); 1797 } 1798 1799 mr.util.activateIdleSrc(targetModal, 'iframe'); 1800 mr.modals.autoplayVideo(targetModal); 1801 1802 mr.modals.showModal(targetModal); 1803 1804 return false; 1805 }); 1806 1807 jQuery(document).on('click', '.modal-close', mr.modals.closeActiveModal); 1808 1809 jQuery(document).keyup(function(e) { 1810 if (e.keyCode === 27) { // escape key maps to keycode `27` 1811 mr.modals.closeActiveModal(); 1812 } 1813 }); 1814 1815 $('.modal-container:not(.modal--prevent-close)').on('click', function(e) { 1816 if( e.target !== this ) return; 1817 mr.modals.closeActiveModal(); 1818 }); 1819 1820 // Trigger autoshow modals 1821 $('.modal-container[data-autoshow]').each(function(){ 1822 var modal = $(this); 1823 var millisecondsDelay = modal.attr('data-autoshow')*1; 1824 1825 mr.util.activateIdleSrc(modal); 1826 mr.modals.autoplayVideo(modal); 1827 1828 // If this modal has a cookie attribute, check to see if a cookie is set, and if so, don't show it. 1829 if(typeof modal.attr('data-cookie') !== typeof undefined){ 1830 if(!mr.cookies.hasItem(modal.attr('data-cookie'))){ 1831 mr.modals.showModal(modal, millisecondsDelay); 1832 } 1833 }else{ 1834 mr.modals.showModal(modal, millisecondsDelay); 1835 } 1836 }); 1837 1838 // Exit modals 1839 $('.modal-container[data-show-on-exit]').each(function(){ 1840 var modal = jQuery(this), 1841 exitSelector = modal.attr('data-show-on-exit'), 1842 delay = 0; 1843 1844 if(modal.attr('data-delay')){ 1845 delay = parseInt(modal.attr('data-delay'), 10) || 0; 1846 } 1847 1848 // If a valid selector is found, attach leave event to show modal. 1849 if($(exitSelector).length){ 1850 modal.prepend($('<i class="ti-close close-modal">')); 1851 jQuery(document).on('mouseleave', exitSelector, function(){ 1852 if(!$('.modal-active').length){ 1853 if(typeof modal.attr('data-cookie') !== typeof undefined){ 1854 if(!mr.cookies.hasItem(modal.attr('data-cookie'))){ 1855 mr.modals.showModal(modal, delay); 1856 } 1857 }else{ 1858 mr.modals.showModal(modal, delay); 1859 } 1860 } 1861 }); 1862 } 1863 }); 1864 1865 1866 // Autoshow modal by ID from location href 1867 if(window.location.href.split('#').length === 2){ 1868 var modalID = window.location.href.split('#').pop(); 1869 if($('[data-modal-id="'+modalID+'"]').length){ 1870 mr.modals.closeActiveModal(); 1871 mr.modals.showModal($('[data-modal-id="'+modalID+'"]')); 1872 } 1873 } 1874 1875 jQuery(document).on('click','a[href^="#"]', function(){ 1876 var modalID = $(this).attr('href').replace('#', ''); 1877 if($('[data-modal-id="'+modalID+'"]').length){ 1878 mr.modals.closeActiveModal(); 1879 setTimeout(mr.modals.showModal, 500,'[data-modal-id="'+modalID+'"]', 0); 1880 } 1881 }); 1882 1883 // Make modal scrollable 1884 jQuery(document).on('wheel mousewheel scroll','.modal-content, .modal-content .scrollable', function(evt){ 1885 if(evt.preventDefault){evt.preventDefault();} 1886 if(evt.stopPropagation){evt.stopPropagation();} 1887 this.scrollTop += (evt.originalEvent.deltaY); 1888 }); 1889 }; 1890 //////////////// 1891 //////////////// End documentReady 1892 //////////////// 1893 1894 mr.modals.showModal = function(modal, millisecondsDelay){ 1895 1896 var delay = (typeof millisecondsDelay !== typeof undefined) ? (1*millisecondsDelay) : 0, $modal = $(modal); 1897 1898 if($modal.length){ 1899 setTimeout(function(){ 1900 var openEvent = document.createEvent('Event'); 1901 openEvent.initEvent('modalOpened.modals.mr', true, true); 1902 $(modal).addClass('modal-active').trigger('modalOpened.modals.mr').get(0).dispatchEvent(openEvent); 1903 1904 },delay); 1905 } 1906 }; 1907 1908 mr.modals.closeActiveModal = function(){ 1909 var modal = jQuery('body div.modal-active'), 1910 closeEvent = document.createEvent('Event'); 1911 1912 mr.util.idleSrc(modal, 'iframe'); 1913 mr.util.pauseVideo(modal); 1914 1915 // If this modal requires to be closed permanently using a cookie, set the cookie now. 1916 if(typeof modal.attr('data-cookie') !== typeof undefined){ 1917 mr.cookies.setItem(modal.attr('data-cookie'), "true", Infinity, '/'); 1918 } 1919 1920 if(modal.length){ 1921 // Remove hash from URL bar if this modal was opened via url bar ID 1922 if(modal.is('[data-modal-id]') && window.location.hash === '#'+modal.attr('data-modal-id')){ 1923 mr.util.removeHash(); 1924 } 1925 closeEvent.initEvent('modalClosed.modals.mr', true, true); 1926 modal.removeClass('modal-active').trigger('modalClosed.modals.mr').get(0).dispatchEvent(closeEvent); 1927 } 1928 }; 1929 1930 mr.modals.autoplayVideo = function(modal){ 1931 // If modal contains HTML5 video with autoplay, play the video 1932 if(modal.find('video[autoplay]').length){ 1933 var video = modal.find('video').get(0); 1934 video.play(); 1935 } 1936 }; 1937 1938 mr.components.documentReady.push(mr.modals.documentReady); 1939 return mr; 1940 1941}(mr, jQuery, window, document)); 1942 1943//////////////// Newsletter Providers 1944mr = (function (mr, $, window, document){ 1945 "use strict"; 1946 1947 mr.newsletters = mr.newsletters || {}; 1948 1949 mr.newsletters.documentReady = function($){ 1950 1951 var form,checkbox,label,id,parent,radio; 1952 1953 // Treat Campaign Monitor forms 1954 $('form[action*="createsend.com"]').each(function(){ 1955 form = $(this); 1956 1957 // Override browser validation and allow us to use our own 1958 form.attr('novalidate', 'novalidate'); 1959 1960 // Give each text input a placeholder value 1961 1962 if(!form.is('.form--no-placeholders')){
1963 form.find('input:not([checkbox]):not([radio])').each(function(){ 1964 var $input = $(this); 1965 if(typeof $input.attr('placeholder') !== typeof undefined){ 1966 if($input.attr('placeholder') === ""){ 1967 if($input.siblings('label').length){ 1968 $input.attr('placeholder', $input.siblings('label').first().text()); 1969 if(form.is('.form--no-labels')){ 1970 $input.siblings('label').first().remove(); 1971 } 1972 } 1973 } 1974 }else if($input.siblings('label').length){ 1975 $input.attr('placeholder', $input.siblings('label').first().text()); 1976 if(form.is('.form--no-labels')){ 1977 $input.siblings('label').first().remove(); 1978 } 1979 } 1980 if($input.parent().is('p')){ 1981 $input.unwrap(); 1982 } 1983 }); 1984 }else{ 1985 form.find('input[placeholder]').removeAttr('placeholder'); 1986 } 1987 1988 1989 // Wrap select elements in template code 1990 1991 form.find('select').wrap('<div class="input-select"></div>'); 1992 1993 // Wrap radios elements in template code 1994 1995 form.find('input[type="radio"]').wrap('<div class="input-radio"></div>'); 1996 1997 // Wrap checkbox elements in template code 1998 1999 form.find('input[type="checkbox"]').each(function(){ 2000 checkbox = $(this); 2001 id = checkbox.attr('id'); 2002 label = form.find('label[for='+id+']'); 2003 if(!label.length){ 2004 label = $('<label for="'+id+'"></label>'); 2005 } 2006 2007 checkbox.before('<div class="input-checkbox" data-id="'+id+'"></div>'); 2008 $('.input-checkbox[data-id="'+id+'"]').prepend(checkbox); 2009 $('.input-checkbox[data-id="'+id+'"]').prepend(label); 2010 }); 2011 2012 form.find('button[type="submit"]').each(function(){ 2013 var button = $(this); 2014 button.addClass('btn'); 2015 if(button.parent().is('p')){ 2016 button.unwrap(); 2017 } 2018 }); 2019 2020 form.find('[required]').attr('required', 'required').addClass('validate-required'); 2021 2022 form.addClass('form--active'); 2023 2024 mr.newsletters.prepareAjaxAction(form); 2025 2026 2027 }); 2028 2029 // Treat MailChimp forms 2030 $('form[action*="list-manage.com"]').each(function(){ 2031 form = $(this); 2032 2033 // Override browser validation and allow us to use our own 2034 form.attr('novalidate', 'novalidate'); 2035 2036 // Give each text input a placeholder value 2037 if(!form.is('.form--no-placeholders')){ 2038 form.find('input:not([checkbox]):not([radio])').each(function(){ 2039 var $input = $(this); 2040 if(typeof $input.attr('placeholder') !== typeof undefined){ 2041 if($input.attr('placeholder') === ""){ 2042 if($input.siblings('label').length){ 2043 $input.attr('placeholder', $input.siblings('label').first().text()); 2044 if(form.is('.form--no-labels')){ 2045 $input.siblings('label').first().remove(); 2046 } 2047 } 2048 } 2049 }else if($input.siblings('label').length){ 2050 $input.attr('placeholder', $input.siblings('label').first().text()); 2051 if(form.is('.form--no-labels')){ 2052 $input.siblings('label').first().remove(); 2053 } 2054 } 2055 }); 2056 }else{ 2057 form.find('input[placeholder]').removeAttr('placeholder'); 2058 } 2059 2060 if(form.is('.form--no-labels')){ 2061 form.find('input:not([checkbox]):not([radio])').each(function(){ 2062 var $input = $(this); 2063 if($input.siblings('label').length){ 2064 $input.siblings('label').first().remove(); 2065 } 2066 }); 2067 } 2068 2069 // Wrap select elements in template code 2070 2071 form.find('select').wrap('<div class="input-select"></div>'); 2072 2073 // Wrap checboxes elements in template code 2074 2075 form.find('input[type="checkbox"]').each(function(){ 2076 checkbox = jQuery(this); 2077 parent = checkbox.parent(); 2078 label = parent.find('label'); 2079 if(!label.length){ 2080 label = jQuery('<label>'); 2081 } 2082 checkbox.before('<div class="input-checkbox"></div>'); 2083 parent.find('.input-checkbox').append(checkbox); 2084 parent.find('.input-checkbox').append(label); 2085 }); 2086 2087 // Wrap radio elements in template code 2088 2089 form.find('input[type="radio"]').each(function(){ 2090 radio = jQuery(this); 2091 parent = radio.closest('li'); 2092 label = parent.find('label'); 2093 if(!label.length){ 2094 label = jQuery('<label>'); 2095 } 2096 radio.before('<div class="input-radio"></div>'); 2097 parent.find('.input-radio').prepend(radio); 2098 parent.find('.input-radio').prepend(label); 2099 }); 2100 2101 // Convert MailChimp input[type="submit"] to div.button 2102 2103 form.find('input[type="submit"]').each(function(){ 2104 var submit = $(this); 2105 2106 var newButton = jQuery('<button/>
2106').attr('type','submit').attr('class', submit.attr('class')).addClass('btn').text(submit.attr('value')); 2107 2108 if(submit.parent().is('div.clear')){ 2109 submit.unwrap(); 2110 } 2111 2112 newButton.insertBefore(submit); 2113 submit.remove(); 2114 }); 2115 2116 form.find('input').each(function(){ 2117 var input = $(this); 2118 if(input.hasClass('required')){ 2119 input.removeClass('required').addClass('validate-required'); 2120 } 2121 }); 2122 2123 form.find('input[type="email"]').removeClass('email').addClass('validate-email'); 2124 2125 form.find('#mce-responses').remove(); 2126 2127 form.find('.mc-field-group').each(function(){ 2128 $(this).children().first().unwrap(); 2129 }); 2130 2131 form.find('[required]').attr('required', 'required').addClass('validate-required'); 2132 2133 form.addClass('form--active'); 2134 2135 mr.newsletters.prepareAjaxAction(form); 2136 2137 }); 2138 2139 // Reinitialize the forms so interactions work as they should 2140 2141 mr.forms.documentReady(mr.setContext('form.form--active')); 2142 2143 }; 2144 2145 mr.newsletters.prepareAjaxAction = function(form){ 2146 var action = $(form).attr('action'); 2147 2148 // Alter action for a Mail Chimp-compatible ajax request url. 2149 if(/list-manage\.com/.test(action)){ 2150 action = action.replace('/post?', '/post-json?') + "&c=?"; 2151 if(action.substr(0,2) === "//"){ 2152 action = 'http:' + action; 2153 } 2154 } 2155 2156 // Alter action for a Campaign Monitor-compatible ajax request url. 2157 if(/createsend\.com/.test(action)){ 2158 action = action + '?callback=?'; 2159 } 2160 2161 // Set action on the form 2162 $(form).attr('action', action); 2163 2164 }; 2165 2166 2167 2168 mr.components.documentReady.push(mr.newsletters.documentReady); 2169 return mr; 2170 2171}(mr, jQuery, window, document)); 2172 2173//////////////// Notifications 2174mr = (function (mr, $, window, document){ 2175 "use strict"; 2176 2177 mr.notifications = mr.notifications || {}; 2178 2179 mr.notifications.documentReady = function($){ 2180 2181 $('.notification').each(function(){ 2182 var notification = $(this); 2183 if(!notification.find('.notification-close').length){ 2184 notification.append('<div class="notification-close-cross notification-close"></div>'); 2185 } 2186 }); 2187 2188 2189 $('.notification[data-autoshow]').each(function(){ 2190 var notification = $(this); 2191 var millisecondsDelay = parseInt(notification.attr('data-autoshow'),10); 2192 2193 // If this notification has a cookie attribute, check to see if a cookie is set, and if so, don't show it. 2194 if(typeof notification.attr('data-cookie') !== typeof undefined){ 2195 if(!mr.cookies.hasItem(notification.attr('data-cookie'))){ 2196 mr.notifications.showNotification(notification, millisecondsDelay); 2197 } 2198 }else{ 2199 mr.notifications.showNotification(notification, millisecondsDelay); 2200 } 2201 }); 2202 2203 $('[data-notification-link]:not(.notification)').on('click', function(){ 2204 var notificationID = jQuery(this).attr('data-notification-link'); 2205 var notification = $('.notification[data-notification-link="'+notificationID+'"]'); 2206 jQuery('.notification--reveal').addClass('notification--dismissed'); 2207 notification.removeClass('notification--dismissed'); 2208 mr.notifications.showNotification(notification, 0); 2209 return false; 2210 }); 2211 2212 $('.notification-close').on('click', function(){ 2213 var closeButton = jQuery(this); 2214 // Pass the closeNotification function a reference to the close button 2215 mr.notifications.closeNotification(closeButton); 2216 2217 if(closeButton.attr('href') === '#'){ 2218 return false; 2219 } 2220 }); 2221 2222 $('.notification .inner-link').on('click', function(){ 2223 var notificationLink = jQuery(this).closest('.notification').attr('data-notification-link'); 2224 mr.notifications.closeNotification(notificationLink); 2225 }); 2226 2227 }; 2228 2229 2230 mr.notifications.showNotification = function(notification, millisecondsDelay){ 2231 var $notification = jQuery(notification), 2232 delay = (typeof millisecondsDelay !== typeof undefined) ? (1*millisecondsDelay) : 0, 2233 openEvent = document.createEvent('Event'); 2234 2235 setTimeout(function(){ 2236 openEvent.initEvent('notificationOpened.notifications.mr', true, true); 2237 $notification.addClass('notification--reveal').trigger('notificationOpened.notifications.mr').get(0).dispatchEvent(openEvent); 2238 $notification.closest('nav').addClass('notification--reveal'); 2239 if($notification.find('input').length){ 2240 $notification.find('input').first().focus(); 2241 } 2242 2243 2244 2245 },delay); 2246 // If notification has autohide attribute, set a timeout 2247 // for the autohide time plus the original delay time in case notification was called 2248 // on page load 2249 if(notification.is('[data-autohide]')){ 2250 var hideDelay = parseInt(notification.attr('data-autohide'),10); 2251 setTimeout(function(){ 2252 mr.notifications.closeNotification(notification); 2253 },hideDelay+delay); 2254 } 2255 }; 2256 2257 mr.notifications.closeNotification = function(notification){ 2258 var $notification = jQuery(notification), 2259 closeEvent = document.createEvent('Event'); 2260 notification = $notification.is('.notification') ? 2261 $notification : 2262 $notification.is('.notification-close') ? 2263 $notification.closest('.notification') : 2264 $('.notification[data-notification-link="'+notification+'"]'); 2265 2266 closeEvent.initEvent('notificationClosed.notifications.mr', true, true); 2267 notification.addClass('notification--dismissed').trigger('notificationClosed.notifications.mr').get(0).dispatchEvent(closeEvent); 2268 notification.closest('nav').removeClass('notification--reveal'); 2269 2270 // If this notification requires to be closed permanently using a cookie, set the cookie now. 2271 if(typeof notification.attr('data-cookie') !== typeof undefined){ 2272 mr.cookies.setItem(notification.attr('data-cookie'), "true", Infinity, '/'); 2273 } 2274 }; 2275 2276 mr.components.documentReady.push(mr.notifications.documentReady); 2277 return mr; 2278 2279}(mr, jQuery, window, document)); 2280 2281//////////////// Parallax 2282mr = (function (mr, $, window, document){ 2283 "use strict"; 2284 2285 mr.parallax = mr.parallax || {}; 2286 2287 mr.parallax.documentReady = function($){ 2288 2289 var $window = $(window); 2290 var windowWidth = $window.width(); 2291 var windowHeight = $window.height(); 2292 var navHeight = $('nav').outerHeight(true); 2293 2294 if (windowWidth > 768) { 2295 var parallaxHero = $('.parallax:nth-of-type(1)'), 2296 parallaxHeroImage = $('.parallax:nth-of-type(1) .background-image-holder'); 2297 2298 parallaxHeroImage.css('top', -(navHeight)); 2299 if(parallaxHero.outerHeight(true) === windowHeight){ 2300 parallaxHeroImage.css('height', windowHeight + navHeight); 2301 } 2302 } 2303 }; 2304 2305 mr.parallax.update = function(){ 2306 if(typeof mr_parallax !== typeof undefined){ 2307 mr_parallax.profileParallaxElements();
2308 mr_parallax.mr_parallaxBackground(); 2309 } 2310 }; 2311 2312 mr.components.documentReady.push(mr.parallax.documentReady); 2313 return mr; 2314 2315}(mr, jQuery, window, document)); 2316 2317//////////////// Progress Horizontal (bars) 2318mr = (function (mr, $, window, document){ 2319 "use strict"; 2320 2321 mr.progressHorizontal = mr.progressHorizontal || {}; 2322 2323 mr.progressHorizontal.documentReady = function($){ 2324 2325 var progressBars = []; 2326 2327 $('.progress-horizontal').each(function(){ 2328 var bar = jQuery(this).find('.progress-horizontal__bar'), 2329 barObject = {}, 2330 progress = jQuery('<div class="progress-horizontal__progress"></div>'); 2331 2332 bar.prepend(progress); 2333 2334 barObject.element = bar; 2335 barObject.progress = progress; 2336 barObject.value = parseInt(bar.attr('data-value'),10)+"%"; 2337 barObject.offsetTop = bar.offset().top; 2338 barObject.animate = false; 2339 2340 if(jQuery(this).hasClass('progress-horizontal--animate')){ 2341 barObject.animate = true; 2342 }else{ 2343 progress.css('width',barObject.value); 2344 } 2345 progressBars.push(barObject); 2346 }); 2347 }; 2348 2349 mr.components.documentReady.push(mr.progressHorizontal.documentReady); 2350 return mr; 2351 2352}(mr, jQuery, window, document)); 2353 2354//////////////// EasyPiecharts 2355mr = (function (mr, $, window, document){ 2356 "use strict"; 2357 2358 mr.easypiecharts = mr.easypiecharts || {}; 2359 mr.easypiecharts.pies = []; 2360 mr.easypiecharts.options = mr.easypiecharts.options || {}; 2361 2362 mr.easypiecharts.documentReady = function($){ 2363 2364 $('.radial').each(function(){ 2365 var chart = jQuery(this), 2366 value = 0, 2367 color = '#000000', 2368 time = 2000, 2369 pieSize = 110, 2370 barWidth = 3, 2371 defaults = {}, 2372 attributeOverrides = {}, 2373 options; 2374 2375 defaults = { 2376 animate: ({duration: time, enabled: true}), 2377 barColor: color, 2378 scaleColor: false, 2379 size: pieSize, 2380 lineWidth: barWidth 2381 }; 2382 2383 if(typeof mr.easypiecharts.options.size !== typeof undefined){ 2384 pieSize = mr.easypiecharts.options.size; 2385 } 2386 if(typeof chart.attr('data-timing') !== typeof undefined){ 2387 attributeOverrides.animate = {duration: parseInt(chart.attr('data-timing'), 10), enabled: true}; 2388 } 2389 if(typeof chart.attr('data-color') !== typeof undefined){ 2390 attributeOverrides.barColor = chart.attr('data-color'); 2391 } 2392 if(typeof chart.attr('data-size') !== typeof undefined){ 2393 pieSize = attributeOverrides.size = parseInt(chart.attr('data-size'), 10); 2394 } 2395 if(typeof chart.attr('data-bar-width') !== typeof undefined){ 2396 attributeOverrides.lineWidth = parseInt(chart.attr('data-bar-width'), 10); 2397 } 2398 2399 chart.css('height',pieSize).css('width',pieSize); 2400 2401 2402 2403 if(typeof mr.easypiecharts.options === 'object'){ 2404 options = jQuery.extend({}, defaults, mr.easypiecharts.options, attributeOverrides); 2405 } 2406 2407 chart.easyPieChart(options); 2408 chart.data('easyPieChart').update(0); 2409 }); 2410 2411 if($('.radial').length){ 2412 mr.easypiecharts.init($); 2413 mr.easypiecharts.activate(); 2414 mr.scroll.listeners.push(mr.easypiecharts.activate); 2415 } 2416 2417 }; 2418 2419 mr.easypiecharts.init = function($){ 2420 2421 mr.easypiecharts.pies = []; 2422 2423 $('.radial').each(function(){ 2424 var pieObject = {}, 2425 currentPie = jQuery(this); 2426 2427 pieObject.element = currentPie; 2428 pieObject.value = parseInt(currentPie.attr('data-value'),10); 2429 pieObject.top = currentPie.offset().top; 2430 pieObject.height = currentPie.height()/2; 2431 pieObject.active = false; 2432 mr.easypiecharts.pies.push(pieObject); 2433 }); 2434 }; 2435 2436 mr.easypiecharts.activate = function(){ 2437 mr.easypiecharts.pies.forEach(function(pie){ 2438 if(Math.round((mr.scroll.y + mr.window.height)) >= Math.round(pie.top+pie.height)){ 2439 if(pie.active === false){ 2440 2441 pie.element.data('easyPieChart').enableAnimation(); 2442 pie.element.data('easyPieChart').update(pie.value); 2443 pie.element.addClass('radial--active'); 2444 pie.active = true; 2445 } 2446 } 2447 }); 2448 }; 2449 2450 mr.components.documentReadyDeferred.push(mr.easypiecharts.documentReady); 2451 return mr; 2452 2453}(mr, jQuery, window, document)); 2454 2455//////////////// Smoothscroll 2456mr = (function (mr, $, window, document){ 2457 "use strict"; 2458 2459 mr.smoothscroll = mr.smoothscroll || {}; 2460 mr.smoothscroll.sections = []; 2461 2462 mr.smoothscroll.init = function(){ 2463 mr.smoothscroll.sections = []; 2464 2465 2466 2467 $('a.inner-link').each(function(){ 2468 var sectionObject = {}, 2469 link = $(this), 2470 href = link.attr('href'), 2471 validLink = new RegExp('^#[^\r\n\t\f\v\#\.]+$','gm'); 2472 2473 if(validLink.test(href)){ 2474 2475 if($('section'+href).length){ 2476 2477 sectionObject.id = href; 2478 sectionObject.top = Math.round($(href).offset().top); 2479 sectionObject.height = Math.round($(href).outerHeight()); 2480 sectionObject.link = link.get(0); 2481 sectionObject.active = false;
2482 2483 mr.smoothscroll.sections.push(sectionObject); 2484 } 2485 } 2486 }); 2487 2488 mr.smoothscroll.highlight(); 2489 }; 2490 2491 mr.smoothscroll.highlight = function(){ 2492 mr.smoothscroll.sections.forEach(function(section){ 2493 if(mr.scroll.y >= section.top && mr.scroll.y < (section.top + section.height)){ 2494 if(section.active === false){ 2495 section.link.classList.add("inner-link--active"); 2496 section.active = true; 2497 } 2498 }else{ 2499 section.link.classList.remove("inner-link--active"); 2500 section.active = false; 2501 } 2502 }); 2503 }; 2504 2505 mr.scroll.listeners.push(mr.smoothscroll.highlight); 2506 2507 mr.smoothscroll.documentReady = function($){ 2508 // Smooth scroll to inner links 2509 var innerLinks = $('a.inner-link'), offset, themeDefaults, ao = {}; 2510 2511 themeDefaults = { 2512 selector: '.inner-link', 2513 selectorHeader: null, 2514 speed: 750, 2515 easing: 'easeInOutCubic', 2516 offset: 0 2517 }; 2518 2519 if(innerLinks.length){ 2520 innerLinks.each(function(index){ 2521 var link = $(this), 2522 href = link.attr('href'); 2523 if(href.charAt(0) !== "#"){ 2524 link.removeClass('inner-link'); 2525 } 2526 }); 2527 2528 mr.smoothscroll.init(); 2529 $(window).on('resize', mr.smoothscroll.init); 2530 2531 offset = 0; 2532 if($('body[data-smooth-scroll-offset]').length){ 2533 offset = $('body').attr('data-smooth-scroll-offset'); 2534 offset = offset*1; 2535 } 2536 2537 ao.offset = offset !== 0 ? offset: undefined; 2538 2539 smoothScroll.init(jQuery.extend({}, themeDefaults, mr.smoothscroll.options, ao)); 2540 } 2541 }; 2542 2543 mr.components.documentReady.push(mr.smoothscroll.documentReady); 2544 mr.components.windowLoad.push(mr.smoothscroll.init); 2545 return mr; 2546 2547}(mr, jQuery, window, document)); 2548 2549//////////////// Tabs 2550mr = (function (mr, $, window, document){ 2551 "use strict"; 2552 2553 mr.tabs = mr.tabs || {}; 2554 2555 mr.tabs.documentReady = function($){ 2556 $('.tabs').each(function(){ 2557 var tabs = $(this); 2558 tabs.after('<ul class="tabs-content">'); 2559 tabs.find('li').each(function(){ 2560 var currentTab = $(this), 2561 tabContent = currentTab.find('.tab__content').wrap('<li></li>').parent(), 2562 tabContentClone = tabContent.clone(true,true); 2563 tabContent.remove(); 2564 currentTab.closest('.tabs-container').find('.tabs-content').append(tabContentClone); 2565 }); 2566 }); 2567 2568 $('.tabs > li').on('click', function(){ 2569 var clickedTab = $(this), hash; 2570 mr.tabs.activateTab(clickedTab); 2571 2572 // Update the URL bar if the currently clicked tab has an ID 2573 if(clickedTab.is('[id]')){ 2574 // Create the hash from the tab's ID 2575 hash = '#'+ clickedTab.attr('id'); 2576 // Check we are in a newish browser with the history API 2577 if(history.pushState) { 2578 history.pushState(null, null, hash); 2579 } 2580 else { 2581 location.hash = hash; 2582 } 2583 } 2584 }); 2585 2586 $('.tabs li.active').each(function(){ 2587 mr.tabs.activateTab(this); 2588 }); 2589 2590 if(window.location.hash !== ''){ 2591 mr.tabs.activateTabById(window.location.hash); 2592 } 2593 2594 $('a[href^="#"]').on('click', function(){ 2595 mr.tabs.activateTabById($(this).attr('href')); 2596 }); 2597 2598 }; 2599 2600 mr.tabs.activateTab = function(tab){ 2601 var clickedTab = $(tab), 2602 tabContainer = clickedTab.closest('.tabs-container'), 2603 activeIndex = (clickedTab.index()*1)+(1), 2604 activeContent = tabContainer.find('> .tabs-content > li:nth-of-type('+activeIndex+')'), 2605 openEvent = document.createEvent('Event'), 2606 iframe, radial; 2607 2608 openEvent.initEvent('tabOpened.tabs.mr', true, true); 2609 2610 2611 tabContainer.find('> .tabs > li').removeClass('active'); 2612 tabContainer.find('> .tabs-content > li').removeClass('active'); 2613 2614 clickedTab.addClass('active').trigger('tabOpened.tabs.mr').get(0).dispatchEvent(openEvent); 2615 activeContent.addClass('active'); 2616 2617 2618 2619 // If there is an <iframe> element in the tab, reload its content when the tab is made active. 2620 iframe = activeContent.find('iframe'); 2621 if(iframe.length){ 2622 iframe.attr('src', iframe.attr('src')); 2623 } 2624 }; 2625 2626 2627 2628 mr.tabs.activateTabById = function(id){ 2629 if(id !== '' && id !== '#' && id.match(/#\/.*/) === null){ 2630 if($('.tabs > li#'+id.replace('#', '')).length){ 2631 $('.tabs > li#'+id.replace('#', '')).click(); 2632 } 2633 } 2634 }; 2635 2636 mr.components.documentReady.push(mr.tabs.documentReady); 2637 return mr; 2638 2639}(mr, jQuery, window, document)); 2640 2641//////////////// Toggle Class 2642mr = (function (mr, $, window, document){ 2643 "use strict"; 2644 2645 mr.toggleClass = mr.toggleClass || {}; 2646 2647 mr.toggleClass.documentReady = function($){ 2648 $('[data-toggle-class]').each(function(){ 2649 var element = $(this), 2650 data = element.attr('data-toggle-class').split("|"); 2651 2652 2653 $(data).each(function(){ 2654 var candidate = element, 2655 dataArray = [], 2656 toggleClass = '', 2657 toggleElement = '', 2658 dataArray = this.split(";"); 2659 2660 if(dataArray.length === 2){ 2661 toggleElement = dataArray[0]; 2662 toggleClass = dataArray[1]; 2663 $(candidate).on('click',function(){ 2664 if(!candidate.hasClass('toggled-class')){ 2665 candidate.toggleClass('toggled-class'); 2666 }else{ 2667 candidate.removeClass('toggled-class'); 2668 } 2669 $(toggleElement).toggleClass(toggleClass); 2670 return false;
2671 }); 2672 }else{ 2673 console.log('Error in [data-toggle-class] attribute. This attribute accepts an element, or comma separated elements terminated witha ";" followed by a class name to toggle'); 2674 } 2675 }); 2676 }); 2677 }; 2678 2679 mr.components.documentReady.push(mr.toggleClass.documentReady); 2680 return mr; 2681 2682}(mr, jQuery, window, document)); 2683 2684//////////////// Typed Headline Effect 2685mr = (function (mr, $, window, document){ 2686 "use strict"; 2687 2688 mr.typed = mr.typed || {}; 2689 2690 2691 mr.typed.documentReady = function($){ 2692 $('.typed-text').each(function(){ 2693 var text = $(this); 2694 var strings = text.attr("data-typed-strings") ? text.attr("data-typed-strings").split(",") : [], 2695 themeDefaults = { 2696 strings: [], 2697 typeSpeed: 100, 2698 loop: true, 2699 showCursor: false 2700 }, ao = {}; 2701 2702 ao.strings = text.attr("data-typed-strings") ? text.attr("data-typed-strings").split(",") : undefined; 2703 2704 $(text).typed(jQuery.extend({}, themeDefaults, mr.typed.options, ao)); 2705 2706 }); 2707 }; 2708 2709 mr.components.documentReady.push(mr.typed.documentReady); 2710 return mr; 2711 2712}(mr, jQuery, window, document)); 2713 2714//////////////// Twitter Feeds 2715mr = (function (mr, $, window, document){ 2716 "use strict"; 2717 2718 mr.twitter = mr.twitter || {}; 2719 mr.twitter.options = mr.twitter.options || {}; 2720 2721 mr.twitter.documentReady = function($){ 2722 $('.tweets-feed').each(function(index) { 2723 $(this).attr('id', 'tweets-' + index); 2724 }).each(function(index) { 2725 var element = $('#tweets-' + index); 2726 2727 var TweetConfig = { 2728 "domId": '', 2729 "maxTweets": 6, 2730 "enableLinks": true, 2731 "showUser": true, 2732 "showTime": true, 2733 "dateFunction": '', 2734 "showRetweet": false, 2735 "customCallback": handleTweets 2736 }; 2737 2738 TweetConfig = jQuery.extend(TweetConfig, mr.twitter.options); 2739 2740 2741 2742 if(typeof element.attr('data-widget-id') !== typeof undefined){ 2743 TweetConfig.id = element.attr('data-widget-id'); 2744 }else if(typeof element.attr('data-feed-name') !== typeof undefined && element.attr('data-feed-name') !== ""){ 2745 TweetConfig.profile = {"screenName": element.attr('data-feed-name').replace('@', '')}; 2746 }else if(typeof mr.twitter.options.profile !== typeof undefined){ 2747 TweetConfig.profile = {"screenName": mr.twitter.options.profile.replace('@', '')}; 2748 }else{ 2749 TweetConfig.profile = {"screenName": 'twitter'}; 2750 } 2751 2752 TweetConfig.maxTweets = element.attr('data-amount') ? element.attr('data-amount'): TweetConfig.maxTweets; 2753 2754 if(element.closest('.twitter-feed--slider').length){ 2755 element.addClass('slider'); 2756 } 2757 2758 function handleTweets(tweets) { 2759 var x = tweets.length; 2760 var n = 0; 2761 var html = '<ul class="slides">'; 2762 while (n < x) { 2763 html += '<li>' + tweets[n] + '</li>'; 2764 n++; 2765 } 2766 html += '</ul>'; 2767 element.html(html); 2768 2769 // Initialize twitter feed slider 2770 if(element.closest('.slider').length){ 2771 mr.sliders.documentReady(mr.setContext()); 2772 2773 return html; 2774 } 2775 } 2776 twitterFetcher.fetch(TweetConfig); 2777 }); 2778 }; 2779 2780 mr.components.documentReady.push(mr.twitter.documentReady); 2781 return mr; 2782 2783}(mr, jQuery, window, document)); 2784 2785//////////////// Video 2786mr = (function (mr, $, window, document){ 2787 "use strict"; 2788 2789 mr.video = mr.video || {}; 2790 mr.video.options = mr.video.options || {}; 2791 mr.video.options.ytplayer = mr.video.options.ytplayer || {}; 2792 2793 mr.video.documentReady = function($){ 2794
2795 //////////////// Youtube Background 2796 2797 if($('.youtube-background').length){ 2798 $('.youtube-background').each(function(){ 2799 2800 2801 var player = $(this), 2802 2803 themeDefaults = { 2804 containment: "self", 2805 autoPlay: true, 2806 mute: true, 2807 opacity: 1 2808 }, ao = {}; 2809 2810 // Attribute overrides - provides overrides to the global options on a per-video basis 2811 ao.videoURL = $(this).attr('data-video-url'); 2812 ao.startAt = $(this).attr('data-start-at')? parseInt($(this).attr('data-start-at'), 10): undefined; 2813 2814 2815 player.closest('.videobg').append('<div class="loading-indicator"></div>'); 2816 player.YTPlayer(jQuery.extend({}, themeDefaults, mr.video.options.ytplayer, ao)); 2817 player.on("YTPStart",function(){ 2818 player.closest('.videobg').addClass('video-active'); 2819 }); 2820 2821 }); 2822 } 2823 2824 if($('.videobg').find('video').length){ 2825 $('.videobg').find('video').closest('.videobg').addClass('video-active'); 2826 } 2827 2828 //////////////// Video Cover Play Icons 2829 2830 $('.video-cover').each(function(){ 2831 var videoCover = $(this); 2832 if(videoCover.find('iframe[src]').length){ 2833 videoCover.find('iframe').attr('data-src', videoCover.find('iframe').attr('src')); 2834 videoCover.find('iframe').attr('src',''); 2835 } 2836 }); 2837 2838 $('.video-cover .video-play-icon').on("click", function(){ 2839 var playIcon = $(this); 2840 var videoCover = playIcon.closest('.video-cover'); 2841 if(videoCover.find('video').length){ 2842 var video = videoCover.find('video').get(0); 2843 videoCover.addClass('reveal-video'); 2844 video.play(); 2845 return false; 2846 }else if(videoCover.find('iframe').length){ 2847 var iframe = videoCover.find('iframe'); 2848 iframe.attr('src',iframe.attr('data-src')); 2849 videoCover.addClass('reveal-video'); 2850 return false; 2851 } 2852 }); 2853 }; 2854 2855 mr.components.documentReady.push(mr.video.documentReady); 2856 return mr; 2857 2858}(mr, jQuery, window, document)); 2859 2860//////////////// Wizard 2861mr = (function (mr, $, window, document){ 2862 "use strict"; 2863 2864 mr.wizard = mr.wizard || {}; 2865 2866 mr.wizard.documentReady = function($){ 2867 2868 $('.wizard').each(function(){ 2869 var wizard = jQuery(this), themeDefaults = {}; 2870 2871 themeDefaults = { 2872 headerTag: "h5", 2873 bodyTag: "section", 2874 transitionEffect: "slideLeft", 2875 autoFocus: true 2876 } 2877 2878 2879 if(!wizard.is('[role="application"][id^="steps-uid"]')){ 2880 wizard.steps(jQuery.extend({}, themeDefaults, mr.wizard.options)); 2881 2882 wizard.addClass('active'); 2883 } 2884 2885 }); 2886 }; 2887 2888 mr.components.documentReady.push(mr.wizard.documentReady); 2889 return mr; 2890 2891}(mr, jQuery, window, document)); 2892 2893$(document).ready(function(){ 2894 $('.blog-article img').parents('p').css('text-align', 'center'); 2895 $('.blog-article img').each(function(index, img){ 2896 $(img).parent('a').attr('data-lightbox', 'image-' + index); 2897 }); 2898 Gifffer(); 2899});
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.