1// page init; 2(function () { 3 'use strict'; 4 var requestAnimationFrame = 5 window.requestAnimationFrame || 6 window.mozRequestAnimationFrame || 7 window.webkitRequestAnimationFrame || 8 window.msRequestAnimationFrame || 9 function (f) { 10 return setTimeout(f, 17); 11 }; 12 13 var cancelAnimationFrame = 14 window.cancelAnimationFrame || 15 window.mozCancelAnimationFrame || 16 function (requestId) { 17 clearTimeout(requestId); 18 }; 19 /** 20 * Property Decorator constant 21 * @param value 22 * @returns {{enumerable: boolean, value: *}} 23 */ 24 25 function constant(value) { 26 return { 27 enumerable: true, 28 value: value, 29 }; 30 } 31 32 function mutable(value) { 33 return { 34 enumerable: true, 35 writable: true, 36 value: value, 37 }; 38 } 39 40 /** 41 * Property Decorator Get/Set 42 * @param getter 43 * @param setter 44 * @returns {{enumerable: boolean, get: *, set: *}} 45 */ 46 function getterSetter(getter, setter) { 47 return { 48 enumerable: true, 49 get: getter, 50 set: setter, 51 }; 52 } 53 54 function abstractMethod() { 55 throw new Error('This method has not been configured!'); 56 } 57 58 /** 59 * @param $ {JQueryStatic} 60 */ 61 jQuery(document).ready(function ($) { 62 var $body = $('body'), 63 $window = $(window), 64 $noPlace = $('<span></span>'), 65 noPlace = $noPlace.get(0); 66 var $contactForm = $('.contactform').first(); 67 68 function throttleResize(callback) { 69 var id = 0; 70 71 function throttle() { 72 cancelAnimationFrame(id); 73 id = requestAnimationFrame(callback); 74 } 75 return { 76 start: function () { 77 $window.on('resize', throttle); 78 }, 79 stop: function () { 80 $window.off('resize', throttle); 81 cancelAnimationFrame(id); 82 id = 0; 83 }, 84 }; 85 } 86 87 function scrollTo($el) { 88 return function () { 89 $('html, body').animate( 90 { 91 scrollTop: $el.offset().top, 92 }, 93 'slow' 94 ); 95 }; 96 } 97 98 function getPLESection($target) { 99 return $target.closest('.section[data-control="section"]'); 100 } 101 102 /** 103 * @param {HTMLElement} child 104 * @param {Element} container 105 * @returns {Number} 106 */ 107 function absoluteOffsetFrom(child, container) { 108 var total = 0; 109 for ( 110 var currentChild = child; 111 currentChild && 112 currentChild !== container && 113 container.contains(currentChild); 114 currentChild = currentChild.offsetParent 115 ) { 116 total += currentChild.offsetTop; 117 } 118 return total; 119 } 120 121 function positionOnSection($menuBlock) { 122 var menuBlock = $menuBlock.get(0), 123 $sectionBlock = getPLESection($menuBlock), 124 sectionBlock = $sectionBlock.get(0) || noPlace; 125 return function () { 126 var relativeParent = menuBlock.offsetParent; 127 $menuBlock.css({ 128 width: $body.width() + 'px', 129 left: -relativeParent.getBoundingClientRect().left, 130 top: 131 $sectionBlock.outerHeight() - 132 absoluteOffsetFrom(relativeParent, sectionBlock), 133 }); 134 }; 135 } 136 137 /** 138 * use common script for group menu option 139 * replace the global scope nav menu variables 140 * prepare the menu and add the more button 141 */ 142 function groupNavMoreButton($el) { 143 //menuHolder = $el; 144 //menu = $el.find('.more_nav'); 145 //currentMenu = menu; 146 //currentMenuWidth = menuHolder.outerWidth(true); 147 //menuChildrenCount = currentMenu.children().length; 148 //origMenuContent = ''; 149 //moreButton = $('<li class="navigation__item navigation__item--default has-drop-down more"> <a href="#" class="navigation__item--link">More</a> <ul class="navigation__list navigation__list--sub"></ul> </li>'); 150 //allMenus = []; 151 //menuPrepare(); 152 //addMoreButton(); 153 } 154 155 (function NavigationLayoutA() { 156 var expandedClass = 'navigation-open', 157 megaMenuClass = 'mega-menu', 158 expandedSelector = '.' + expandedClass; 159 $('.component.navigation .navigation-a').each(function (index, navEl) { 160 new DesktopMenu(navEl); 161 }); 162 163 /** 164 * @param element {Element} 165 * @constructor 166 */ 167 function DesktopMenu(element) { 168 var dis = this; 169 var watchingBody = false; 170 this.el = element; 171 /** 172 * @type {jQuery} 173 */ 174 this.$el = $(element); 175 // call groupNavMoreButton() before manipulation 176 this.$el.data('more-button') === 1 ? groupNavMoreButton(this.$el) : ''; 177 this.$ul = this.$el.children('ul:first-child');
178 var $navItems = this.$el.children('ul').children('li'); 179 var focusTree = { 180 prev: function ($a) { 181 $a.parent('li').prev('li').children('a').focus(); 182 }, 183 next: function ($a) { 184 $a.parent('li').next('li').children('a').focus(); 185 }, 186 parent: function ($a) { 187 $a.parent('li').parent('ul').siblings('a').focus(); 188 }, 189 child: function ($a) { 190 $a.siblings('ul').find('> li:first-child > a:first-child').focus(); 191 }, 192 }; 193 194 function isTopRow(el) { 195 return dis.$ul.children('li').children('a').is(el); 196 } 197 var keyboardNav = { 198 ArrowDown: function (event, $a) { 199 if (isTopRow(event.target)) { 200 focusTree.child($a); 201 } else { 202 focusTree.next($a); 203 } 204 }, 205 ArrowUp: function (event, $a) { 206 if (!isTopRow(event.target)) { 207 focusTree.prev($a); 208 } 209 }, 210 ArrowLeft: function (event, $a) { 211 if (isTopRow(event.target)) { 212 focusTree.prev($a); 213 } else { 214 focusTree.parent($a); 215 } 216 }, 217 ArrowRight: function (event, $a) { 218 if (isTopRow(event.target)) { 219 focusTree.next($a); 220 } else { 221 focusTree.child($a); 222 } 223 }, 224 }; 225 226 this.$el.on( 227 'keydown', 228 '.navigation__item--link:focus', 229 function kbEventRouter(event) { 230 keyboardNav.hasOwnProperty(event.key) && 231 keyboardNav[event.key](event, $(event.target)); 232 } 233 ); 234 235 this.subMenuR = $navItems.toArray().map(function (li) { 236 return new ( 237 li.classList.contains(megaMenuClass) 238 ? DesktopSubMenuItemDefault 239 : DesktopSubMenuItemDefault 240 )(li, dis); 241 }); 242 243 function offClick(evt) { 244 if (!dis.el.contains(evt.target)) { 245 dis.closeAll(); 246 } 247 } 248 249 this.watchAfterOpen = function () { 250 if (!watchingBody) { 251 watchingBody = true; 252 $body.on('click touchstart', offClick); 253 } 254 }; 255 256 this.ignoreAfterClose = function () { 257 if (watchingBody) { 258 watchingBody = false; 259 $body.off('click touchstart', offClick); 260 } 261 }; 262 } 263 264 Object.defineProperties(DesktopMenu, {}); 265 Object.defineProperties(DesktopMenu.prototype, { 266 hasFocus: getterSetter(function () { 267 return Boolean(this.$el.find('a:focus').length); 268 }), 269 expandedClass: constant(expandedClass), 270 expandedSelector: constant(expandedSelector), 271 markOpened: constant(function () { 272 this.watchAfterOpen(); 273 }), 274 closeAll: constant(function () { 275 this.$el.find(this.expandedSelector).removeClass(this.expandedClass); 276 this.ignoreAfterClose(); 277 }), 278 watchAfterOpen: mutable(abstractMethod), 279 ignoreAfterClose: mutable(abstractMethod), 280 }); 281 282 /** 283 * @param element {HTMLLIElement} 284 * @param root {DesktopMenu} 285 * @param parent {=DesktopSubMenuItem} 286 * @constructor 287 */ 288 function DesktopSubMenuItemDefault(element, root, parent) { 289 var dis = this; 290 this.root = root; 291 this.parent = parent || null; 292 this.el = element; 293 this.$el = $(element); 294 this.$a = this.$el.children('a'); 295 this.$ul = this.$el.children('ul'); 296 297 this.$a.on('focus', function () { 298 dis.clearExpand(); 299 dis.expand(); 300 }); 301 this.$ul 302 .find('a') 303 .last() 304 .on('blur', function () { 305 dis.contract(); 306 }); 307 308 if (this.$ul.length) { 309 this.$el.hover( 310 function over() { 311 dis.expand(); 312 }, 313 function out(evt) { 314 dis.contract(); 315 } 316 ); 317 this.$a.on('touchend', function (evt) { 318 if (!dis.isExpanded) { 319 dis.clearExpand(); 320 dis.expand(); 321 return false; 322 } 323 }); 324 325 this.subMenuR = this.$ul 326 .children('li') 327 .toArray() 328 .map(function (li) { 329 return new DesktopSubMenuItemDefault(li, root, dis); 330 }); 331 } else { 332 this.subMenuR = []; 333 } 334 } 335 Object.defineProperties(DesktopSubMenuItemDefault, {}); 336 Object.defineProperties(DesktopSubMenuItemDefault.prototype, { 337 expandedClass: constant(expandedClass), 338 expandedSelector: constant(expandedSelector), 339 isExpanded: getterSetter(function () { 340 return this.el.classList.contains(this.expandedClass); 341 }), 342 expand: constant(function () {
343 this.root.markOpened(); 344 // Set submenu visible if there is one 345 this.$el.addClass(this.expandedClass); 346 // echo up the tree 347 this.$a.parents('li').addClass(this.expandedClass); 348 }), 349 contract: constant(function () { 350 this.$el 351 .removeClass(this.expandedClass) 352 .find(this.expandedSelector) 353 .removeClass(this.expandedClass); 354 }), 355 clearExpand: constant(function () { 356 this.root.closeAll(); 357 }), 358 }); 359 })(); 360 361 // Provide a mobile view 362 (function MobileView($desktopContactForm) { 363 var $mobileSection; 364 /** 365 * @typedef MobileSectionClusterItem 366 * @property {JQuery} $el - Element to be inserted 367 * @property {Node} source 368 * 369 * @type MobileSectionClusterItem[]*/ 370 var mobileSectionCluster = []; 371 var mobileClass = 'mobile-controls'; 372 var $desktopNav = $( 373 '.section-navigation-mobile, .section-navigation-mobile--no-hide' 374 ) 375 .find('.component.navigation') 376 .find('.navigation-a, .navigation-b, .navigation-c') 377 .first(); 378 var $desktopPhone = $('.section-phone-mobile .phone__container') 379 .find('.phone__number') 380 .first(); 381 var $desktopMap = $('.map__container').first(); 382 383 if ( 384 [$desktopNav, $desktopPhone, $desktopContactForm, $desktopMap].every( 385 function isEmpty($el) { 386 return $el.length === 0; 387 } 388 ) 389 ) { 390 return; 391 } 392 393 if ($desktopNav.length) { 394 $mobileSection = $( 395 '<div class="' + mobileClass + ' d-lg-none sticky-top"></div>' 396 ).prependTo($body); 397 398 (function MmenuButton() { 399 var $mobileNav, $menuButton, mmenuAPI; 400 $mobileNav = $desktopNav.clone(); 401 402 // Remove any buttons 403 $mobileNav.find('button').remove(); 404 405 // Strip call classes 406 $mobileNav 407 .removeClass() 408 .addClass('d-lg-none') 409 .find('ul, li, a') 410 .removeClass(); 411 $desktopNav.addClass('d-none d-lg-block'); 412 413 // Build the menu button 414 $menuButton = $( 415 '<button type="button" title="Show Navigation Menu">' + 416 '<i aria-hidden="true" class="icon icon-bars"></i><span> Menu</span>' + 417 '</button>' 418 ).appendTo($mobileSection); 419 420 // Initialize MMenu Plugin 421 $mobileNav.mmenu({ 422 extensions: ['pagedim-black'], 423 counters: true, 424 navbars: [ 425 { 426 position: 'top', 427 content: ['prev', 'title', 'close'], 428 }, 429 { 430 position: 'top', 431 content: ['searchfield'], 432 }, 433 ], 434 }); 435 436 mmenuAPI = $mobileNav.data('mmenu'); 437 438 // Bind the menu button to the API 439 $menuButton.on('click', function () { 440 mmenuAPI.open(); 441 }); 442 })(); 443 } 444 445 function mobileLinkTemplate(classSubName, description, icon, href) { 446 var $el = $( 447 '<div class="' + mobileClass + '__' + classSubName + '"></div>' 448 ); 449 var $link = $( 450 '<a title="' + 451 description + 452 '" class="btn btn-link">' + 453 ('<i class="icon ' + 454 icon + 455 '" aria-hidden="true"></i>' + 456 '<span class="sr-only">' + 457 description + 458 '</span>') + 459 '</a>' 460 ) 461 .attr('href', href) 462 .appendTo($el); 463 return { 464 $el: $el, 465 $link: $link, 466 }; 467 } 468 469 if ($desktopPhone.length) { 470 mobileSectionCluster.push( 471 (function PhoneLink($selector) { 472 var sectionId = getPLESection($selector).attr('id') || ''; 473 // Valid separators are (-.), valid digits are 0-9 474 // See: https://tools.ietf.org/html/rfc3966#section-3 'global-number-digits' 475 var tel = $selector 476 .text() 477 .trim() 478 .replace(/([^0123456789\-.()])/g, ''); 479 var template = mobileLinkTemplate( 480 'phone', 481 'Call', 482 'icon-phone', 483 'tel:+' + tel 484 ); 485 return { 486 $el: template.$el, 487 source: $selector.get(0), 488 }; 489 })($desktopPhone) 490 ); 491 } 492 493 function mobileAnchorLink($selector, classSubName, description, icon) { 494 var sectionId = getPLESection($selector).attr('id') || ''; 495 var template = mobileLinkTemplate( 496 classSubName, 497 description, 498 icon, 499 '#' + sectionId 500 ); 501 template.$link.on('click', scrollTo($selector)); 502 return { 503 $el: template.$el, 504 source: $selector.get(0), 505 }; 506 } 507 508 if ($desktopMap.length) { 509 mobileSectionCluster.push( 510 mobileAnchorLink( 511 $desktopMap, 512 'location', 513 'Location', 514 'icon icon-location-arrow' 515 ) 516 ); 517 } 518 519 if ($desktopContactForm.length) { 520 mobileSectionCluster.push( 521 mobileAnchorLink( 522 $desktopContactForm, 523 'contact-us', 524 'Contact Us', 525 'icon-envelope-o' 526 ) 527 ); 528 } 529 530 if (mobileSectionCluster.length) { 531 mobileSectionCluster 532 .sort(function (a, b) { 533 return a.source.compareDocumentPosition(b.source) & 534 Node.DOCUMENT_POSITION_PRECEDING 535 ? 1 536 : -1; 537 }) 538 .reduce(function ($target, value) { 539 return $target.append(value.$el); 540 }, $('<div class="' + mobileClass + '__quick-links"></div>')) 541 .appendTo($mobileSection); 542 } 543 })($contactForm); 544 545 // Add Browserlock 546 (function BrowserLock($target) { 547 if ($target.length) { 548 // Create ContactForm lock 549 var $contactFormLock = $('<div>').addClass('contactform-lock'); 550 551 // Add ContactForm click event 552 $contactFormLock.on('click', scrollTo($target)); 553 554 // Draw browser lock containers, prepend to body
555 var $lockContainer = $('<div>') 556 .addClass('browser-lock') 557 .append($contactFormLock); 558 559 $('body').prepend($lockContainer); 560 } 561 })($contactForm); 562 563 // Preview link fix 564 (function cleanUpRedactorLinks() { 565 // Check if we're in an iFrame or not (editor mode or preview link) 566 if (self != top) return; 567 568 var link = $('link[rel=canonical]').attr('href'); 569 if (link != undefined) { 570 var parts = link.split('/'), 571 index = parts.indexOf('my.martindalenolo.com'); 572 if (index >= 0) { 573 var siteId = parts[index + 1]; 574 if (!siteId) return; 575 576 var $links = $( 577 'div[data-component-name=editable] a[data-source-type=my-pages]' 578 ); 579 if ($links == undefined || $links.length == 0) return; 580 581 $links.each(function () { 582 var currentLink = $(this).attr('href'); 583 584 // Check for edge-case of absolute my-page 585 var index = currentLink.split('/').indexOf(siteId); 586 if (index >= 0) return; 587 588 var newLink = '/' + siteId + currentLink; 589 $(this).attr('href', newLink); 590 }); 591 } 592 } 593 })(); 594 595 (function setBrowserlock() { 596 var rawSettings = $('#ple-data-json').text(); 597 var settings = JSON.parse(rawSettings); 598 var browserlockSettings = settings.fixedSection; 599 600 //#SMBWMGR-8501 this check can be removed after merging - /editor/merge_requests/1922 601 if (typeof browserlockSettings !== 'undefined') { 602 var $browserLockContainer = $('#' + browserlockSettings.id).find( 603 '.ple__browserlock-modules' 604 ); 605 var $browserLockModules = $browserLockContainer.find('> .row .row'); 606 607 if ( 608 browserlockSettings.spacing.space == 'custom' && 609 browserlockSettings.spacing.offsetDistance && 610 parseInt(browserlockSettings.spacing.offsetDistance) != NaN 611 ) { 612 $browserLockModules.each(function (index, element) { 613 $(element).css({ 614 marginBottom: browserlockSettings.spacing.offsetDistance, 615 }); 616 }); 617 } 618 619 if (browserlockSettings.placement.place != null) { 620 switch (browserlockSettings.placement.place) { 621 case 'center-right': 622 $browserLockContainer.css({ 623 top: '50%', 624 transform: 'translateY(-50%)', 625 }); 626 break; 627 628 case 'bottom-right': 629 $browserLockContainer.css({ 630 top: 'auto', 631 }); 632 633 if ( 634 parseInt(browserlockSettings.placement.offsetDistance) != NaN && 635 !browserlockSettings.placement.useDefaultOffset 636 ) { 637 $browserLockContainer.css({ 638 bottom: browserlockSettings.placement.offsetDistance, 639 }); 640 } 641 break; 642 643 case 'top-right': 644 default: 645 if ( 646 parseInt(browserlockSettings.placement.offsetDistance) != NaN && 647 !browserlockSettings.placement.useDefaultOffset 648 ) { 649 $browserLockContainer.css({ 650 top: browserlockSettings.placement.offsetDistance, 651 }); 652 } 653 break; 654 } 655 } 656 } else { 657 console.log('browserlock Settings is undefinded'); 658 } 659 })(); 660 661 (function backToTop() { 662 var $bttButton = $('.ple__back-to-top'); 663 var activeClass = 'active'; 664 var showPoint = 400; 665 666 $bttButton.on('click', function (event) { 667 event.preventDefault(); 668 669 $([document.documentElement, document.body]).animate( 670 { 671 scrollTop: 0, 672 }, 673 1000 674 ); 675 }); 676 677 $(window).scroll(function () { 678 var window_x = $(window).scrollTop(); 679 if (window_x >= showPoint) { 680 $bttButton.addClass(activeClass); 681 } else { 682 $bttButton.removeClass(activeClass); 683 } 684 }); 685 })(); 686 687 (function mobileHeader() { 688 function mobileHeaderInit() { 689 var $mhContainer = $('.mobileHeader-container'), 690 mhHeaight = $mhContainer.height(), 691 $navButton = $('#mobileHeaderNavBtn'), 692 $navMenu = $('#mobileHeaderNav'), 693 $homeIcon = $('.mobileHeader-homeIcon'), 694 $formIcon = $('.formIconLink'), 695 $mapIcon = $('.locIconLink'), 696 $phoneIcon = $('.phoneIconLinkExpand'), 697 $mapContainer = $('.map__container').first(), 698 $formContainer = $('.form__container').first(), 699 $locList = $('.location-list'), 700 $pleMSticky = $('.ple_module_sticky'), 701 navAPI; 702 703 // if there is no form module in the view target the contactform module 704 if (!$formContainer.length) 705 $formContainer = $('.contactform__container').first(); 706 707 // if sticky module is present set top space to the first elem for the mobileHeader 708 if ($pleMSticky.length) { 709 var $pleMStickEl = $pleMSticky.first().find('.container'); 710 $(window).resize(function () { 711 mhHeaight = $mhContainer.height(); 712 $pleMStickEl.css('padding-top', mhHeaight); 713 }); 714 } 715 716 if ($navMenu.children().length) { 717 // init mMenu 718 $navMenu.mmenu({ 719 extensions: ['pagedim-black'], 720 counters: true, 721 navbars: [ 722 { 723 position: 'top', 724 content: ['prev', 'title', 'close'], 725 }, 726 ], 727 }); 728 // bind menu button
729 navAPI = $navMenu.data('mmenu'); 730 $navButton.on('click', function () { 731 navAPI.open(); 732 }); 733 } 734 735 // handle click events for the icons 736 $formContainer.length 737 ? $formIcon.click(scrollToEl($formContainer)) 738 : $formIcon.fadeOut(); 739 $mapContainer.length 740 ? $mapIcon.click(scrollToEl($mapContainer)) 741 : $mapIcon.fadeOut(); 742 $phoneIcon.click(function () { 743 $locList.addClass('expand'); 744 }); 745 $('.mobileHeader-locWrap') 746 .find('.icon-times') 747 .click(function () { 748 $locList.removeClass('expand'); 749 }); 750 751 // replace the mm title with the home icon 752 if ($homeIcon.length) { 753 $('.mobileHeader-homeIcon .mm-homeIcon').insertBefore( 754 $('#mobileHeaderNav .mm-navbar-top .mm-title') 755 ); 756 } 757 758 // set the section bg class 759 if ($mhContainer.is('[class*=section__bg]')) { 760 var classList = $mhContainer.prop('classList'); 761 $.each(classList, function (index, item) { 762 if (item.startsWith('section__bg')) { 763 $navMenu.addClass(item); 764 } 765 }); 766 } 767 768 $(window).load(function () { 769 alignLogo(); 770 }); 771 772 $(window).resize(function () { 773 alignLogo(); 774 }); 775 } 776 777 // align logo with if only navigation is present or only one icon is present on the right hand side 778 function alignLogo() { 779 if ( 780 !$('.mobileHeader-form').length && 781 !$('.mobileHeader-location').length && 782 !$('.mobileHeader-phone').length && 783 $('#mobileHeaderNavBtn').length 784 ) { 785 var hamburgerMenuWidth = $( 786 '.mobileHeader-navigation #mobileHeaderNavBtn' 787 ).outerWidth(true); 788 $('.mobileHeader-logo').css('margin-right', hamburgerMenuWidth); 789 } 790 if ( 791 ($('.mobileHeader-form').length || 792 $('.mobileHeader-location').length || 793 $('.mobileHeader-phone').length) && 794 !$('#mobileHeaderNavBtn').length 795 ) { 796 var totalWidthIcons = 797 $('.mobileHeader-form').width() + 798 $('.mobileHeader-location').width() + 799 $('.mobileHeader-phone').width(); 800 if (totalWidthIcons < 46) { 801 $('.mobileHeader-logo').css('margin-left', totalWidthIcons); 802 } 803 } 804 } 805 806 function scrollToEl($el) { 807 return function () { 808 var $moduleSticky = $('.ple_module_sticky'), 809 moduleStickyHeight = 0; 810 if ($moduleSticky.length) 811 $moduleSticky.each(function () { 812 moduleStickyHeight += $(this).find('.container').outerHeight(true); 813 }); 814 if (moduleStickyHeight == 0) 815 moduleStickyHeight = $('.mobileHeader-container').height(); 816 $('html, body').animate( 817 { scrollTop: $el.offset().top - moduleStickyHeight }, 818 'slow' 819 ); 820 }; 821 } 822 823 if ($('.mobileHeader-container').length) mobileHeaderInit(); 824 })(); 825 }); 826})(); 827 828$(document).ready(function () { 829 featuredBlocksAAccordion(); 830 bluredBladeBG(); 831 staffOverlapped(); 832 galleryTitle(); 833 navigationVisibility(); 834 bannerOverImage(); 835 bannerAboveImage(); 836 bannerFAbstractShape(); 837 footerParallax(); 838 bladeParallax(); 839 bannerTitleHighlight(); 840 partialTestimonialsSlider(); 841 fbFullImage(); 842}); 843 844$(window).load(function () { 845 navADropDown2(); 846 bannerDSwoop(); 847 bladeNarrowSbg(); 848}); 849 850$(window).resize(function () { 851 navADropDown2(); 852}); 853 854function navADropDown2() { 855 /* this will enable the hover submenu when in edit mode */ 856 var isEditMode = $('body').hasClass('isEditor'); 857 858 if (isEditMode) { 859 var $navSection = $("nav[class^='navigation-']"), 860 zindex = 110; 861 862 if ($navSection.length) { 863 $navSection.closest('.section--inner').addClass('fix-hover'); 864 865 $navSection.each(function (index) { 866 $(this).closest('.section-base-container').css({ 867 'z-index': --zindex, 868 }); 869 }); 870 } 871 } 872 873 $('.navigation-a').on( 874 'mouseover', 875 '.navigation__list--default li.has-drop-down', 876 function () { 877 $(this).parent().css('overflow', 'visible'); 878 } 879 ); 880} 881 882function bannerDSwoop() { 883 $('.section.banner-d-swoop .banner-d .banner__text-overlay--triangle').html( 884 '<svg preserveAspectRatio="none" viewBox="0 0 230 640"><path d="M19.0476 320C19.9223 175.303 175 60 200 0H0V640H192.381C175 580 18.1822 463.173 19.0476 320Z"/></svg>' 885 ); 886} 887
888function bannerFAbstractShape() { 889 $('.section.banner-f-abstract-shape .banner-f .banner__image').append( 890 '<svg viewBox="0 0 485 604" preserveAspectRatio="none"><path d="M483.517 276.495C478.395 332.998 417.997 361.109 384.893 407.184C338.52 471.726 330.461 573.271 254.203 595.653C170.328 620.271 61.9045 589.488 14.9268 515.771C-30.1316 445.066 46.0074 360.199 50.8125 276.495C55.053 202.625 -3.38703 122.467 40.9069 63.1982C86.8067 1.78029 178.409 -7.24325 254.203 4.34036C320.879 14.5304 367.485 68.1701 410.947 119.751C449.514 165.523 488.921 216.885 483.517 276.495Z"/></svg>' 891 ); 892} 893 894function bladeNarrowSbg() { 895 $('.section.blade-narrow-sbg .blade__text-media--swapped') 896 .closest('.section') 897 .addClass('blade__text-media--swapped'); 898} 899 900function featuredBlocksAAccordion() { 901 $('.section.fb-grid-a-accordion .featuredblock__wrap').each(function () { 902 $(this).append('<div class="featuredblock__accordion"></div>'); 903 904 var fbTitleWrapper = $(this).find('.featuredblock-image-title-wrapper'); 905 var fbAccordion = $(this).find('.featuredblock__accordion'); 906 var fbContent = $(this).find('.featuredblock__content'); 907 var fbSubMenu = $(this).find('.featuredblock__sub-menu'); 908 var fbCTA = $(this).find('.featuredblock__cta'); 909 var hasIcon = fbTitleWrapper.has('.featuredblock__icon').length; 910 var hasImg = fbTitleWrapper.has('.featuredblock__image').length; 911 912 fbAccordion.append(fbContent, fbSubMenu, fbCTA); 913 fbTitleWrapper.click(function (e) { 914 e.preventDefault(); 915 $(this).toggleClass('expanded'); 916 fbAccordion.slideToggle(); 917 }); 918 919 if (hasIcon == 0 && hasImg == 0) { 920 fbAccordion.addClass('no-margin'); 921 } 922 }); 923} 924 925function bluredBladeBG() { 926 $('.section.blade-background-blur').each(function () { 927 let imgHolder = $(this).find('.blade__media'), 928 img = imgHolder.find('img'), 929 imgSrc = img.attr('src'); 930 if (!!imgHolder.length && !!img.length && !!imgSrc) { 931 imgHolder.css({ 932 backgroundImage: 'url(' + imgSrc + ')', 933 backgroundSize: 'cover', 934 backgroundPosition: '50% 50%', 935 backgroundRepeat: 'no-repeat', 936 }); 937 img.remove(); 938 } 939 }); 940} 941function staffOverlapped() { 942 let maxHeight = 0; 943 $('.section.staff-overlapped-card .staff-member').each(function () { 944 //for image replace to bg 945 let imgHolder = $(this).find('.staff-member__image-wrapper'), 946 img = imgHolder.find('img'), 947 imgSrc = img.attr('src'), 948 textHolder = $(this).find('.staff-member__text'); 949 if (!!imgHolder.length && !!img.length && !!imgSrc) { 950 imgHolder.css({ 951 backgroundImage: 'url(' + imgSrc + ')', 952 backgroundSize: 'cover', 953 backgroundPosition: '50% 50%', 954 backgroundRepeat: 'no-repeat', 955 }); 956 img.remove(); 957 } 958 }); 959} 960 961function galleryTitle() { 962 var galTitle = $('.award-banner-1 .gallery .gallery__title').text(); 963 $('.award-banner-1 .gallery .gallery__title').replaceWith('<h1></h1>'); 964 $('.award-banner-1 .gallery h1') 965 .text(galTitle) 966 .addClass('gallery__title component__title'); 967} 968 969function navigationVisibility() { 970 var mhEnabled = $('.mobileHeader-container').length; 971 if (mhEnabled) { 972 var tabletFlag = $('#tabletHeaderEnabledFlag').val(), 973 $navSection = $('.section-navigation .navigation'); 974 if (tabletFlag == 1) { 975 $navSection.addClass('d-none d-lg-block'); 976 } else { 977 $navSection.addClass('d-none d-md-block'); 978 } 979 } 980} 981 982function bannerOverImage() { 983 'use strict'; 984 let banner = $('.banner-f-title-over-image'); 985 banner.each(function () { 986 let curBanner = $(this), 987 curItems = curBanner.find('.banner__item'); 988 curItems.each(function () { 989 let cur = $(this), 990 curTextImage = cur.find('.banner__text-wrapper, .banner__image-wrapper'), 991 imageTextHolder = "<div class='holder'/>"; 992 curTextImage.wrapAll(imageTextHolder); 993 }); 994 }); 995} 996function bannerAboveImage() { 997 'use strict'; 998 let banner = $('.banner-a-title-above'); 999 banner.each(function () { 1000 let curBanner = $(this), 1001 curText = curBanner.find('.banner__title, .banner__tc-divider'), 1002 curCta = curBanner.find('.banner__subtitle, .banner__cta-wrapper'), 1003 ctaHolder = "<div class='cta__holder'/>", 1004 textHolder = "<div class='text__holder'/>"; 1005 curText.wrapAll(textHolder); 1006 curCta.wrapAll(ctaHolder); 1007 }); 1008} 1009 1010// This function implements a parallax effect for the footer. 1011function footerParallax() { 1012 'use strict'; 1013 let target = document.querySelector('.footer-parallax'); 1014 if (!target) { 1015 // If the target element with class 'footer-parallax' is not found, stop execution. 1016 //console.error('.footer-parallax not find'); 1017 return; 1018 } 1019 1020 // Apply smooth transition effect to background position change. 1021 target.style.transition = 'background-position .5s'; 1022 1023 // Options for IntersectionObserver 1024 const options = { 1025 root: null, 1026 rootMargin: '0px', 1027 threshold: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], 1028 }; 1029 1030 // Callback function to handle changes in the intersection of the target element. 1031 let callback = function (entries, observer) {
1032 entries.forEach((entry) => { 1033 // Calculate the threshold value (intersectionRatio) for each entry. 1034 const thresholdValue = entry.intersectionRatio; 1035 // Adjust the background position based on the threshold value to create the parallax effect. 1036 entry.target.style.backgroundPosition = `50% ${50 + thresholdValue * 40}%`; 1037 }); 1038 }; 1039 1040 // Create an IntersectionObserver instance with the defined callback and options. 1041 const observer = new IntersectionObserver(callback, options); 1042 1043 // Start observing the target element. 1044 observer.observe(target); 1045} 1046 1047function bladeParallax() { 1048 let target = document.querySelector('.blade-parallax'); 1049 if (!target) { 1050 //console.error('.blade-parallax not find'); 1051 return; // Stop if class not find 1052 } 1053 const options = { 1054 root: null, 1055 rootMargin: '0px', 1056 threshold: [ 1057 0, 0.25, 0.3, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1, 1058 ], 1059 }; 1060 1061 let callback = function (entries, observer) { 1062 entries.forEach((entry) => { 1063 const thresholdValue = entry.intersectionRatio; 1064 const target = entry.target.querySelector('.blade__media'); 1065 target.style.transition = 'transform .5s'; 1066 const transformValue = 100 * (1 - thresholdValue); 1067 target.style.transform = `translateY(${transformValue}px)`; 1068 }); 1069 }; 1070 1071 const observer = new IntersectionObserver(callback, options); 1072 observer.observe(target); 1073} 1074 1075function bannerTitleHighlight() { 1076 'use strict'; 1077 // Select the target element with the class '.section.banner-a-highlighted-title' 1078 let target = document.querySelector('.section.banner-a-highlighted-title'); 1079 if (!target) { 1080 // If the target element is not found, log an error and return 1081 //console.error('.blade-parallax not find'); 1082 return; // Stop if class not found 1083 } 1084 1085 // Define options for the IntersectionObserver 1086 const options = { 1087 root: null, // Use the viewport as the root 1088 rootMargin: '0px', // No margin around the root 1089 threshold: [0.75], // Trigger callback when 75% of the target is visible 1090 }; 1091 1092 // Define the callback function for the IntersectionObserver 1093 let callback = function (entries, observer) { 1094 // Iterate over each entry in the observer 1095 entries.forEach((entry) => { 1096 // If the target is intersecting with the viewport 1097 if (entry.isIntersecting) { 1098 // Add the 'highlighted' class to the target element 1099 entry.target.classList.add('highlighted'); 1100 } else { 1101 // If the target is not intersecting, remove the 'highlighted' class 1102 entry.target.classList.remove('highlighted'); 1103 } 1104 }); 1105 }; 1106 1107 // Create a new IntersectionObserver instance with the defined callback and options 1108 const observer = new IntersectionObserver(callback, options); 1109 1110 // Select all elements with the class '.banner__title' within the target element 1111 let targets = target.querySelectorAll('.banner__title'); 1112 // Iterate over each selected target element 1113 targets.forEach((target) => { 1114 // Observe each target element with the IntersectionObserver 1115 observer.observe(target); 1116 // Wrap text content of banner__title in span 1117 let titleText = target.textContent.trim(); 1118 target.innerHTML = `<span>${titleText}</span>`; 1119 // Add height to banner__title 1120 target.style.height = `${target.offsetHeight}px`; 1121 }); 1122} 1123 1124function partialTestimonialsSlider() { 1125 'use strict'; 1126 let testimonialsPartial = $( 1127 '.partial-testimonials-cta .js-testimonials-layout-settings.flexslider' 1128 ); 1129 1130 // Check if testimonialsPartial exists 1131 if (!testimonialsPartial) { 1132 return; // Exit the function if testimonialsPartial is not found 1133 } 1134 1135 // Function to set itemWidth and itemMargin based on window width 1136 function setItemSettings() { 1137 if (window.innerWidth < 768) { 1138 // Example breakpoint, adjust as needed 1139 return { 1140 itemWidth: 75, // Set itemWidth to 75 for smaller screens 1141 itemMargin: 5, // Set itemMargin to 5 for smaller screens 1142 }; 1143 } else { 1144 return { 1145 itemWidth: 98, // Set itemWidth to 98 for larger screens 1146 itemMargin: 22, // Set itemMargin to 22 for larger screens 1147 }; 1148 } 1149 } 1150 1151 // Re-initialize flexslider for testimonialsPartial 1152 testimonialsPartial.flexslider({ 1153 animation: 'slide', // Set animation type to slide 1154 controlNav: false, // Hide navigation bullets 1155 directionNav: false, // Hide direction navigation arrows 1156 maxItems: 5, // Maximum number of items visible in the slider 1157 ...setItemSettings(), // Spread the returned object from setItemSettings function 1158 keyboard: false, // Disable keyboard navigation 1159 slideshow: false, // Disable slideshow 1160 }); 1161 1162 // Add event listener for window resize to update itemWidth and itemMargin dynamically 1163 $(window).on('resize', function () { 1164 const { itemWidth, itemMargin } = setItemSettings(); 1165 testimonialsPartial.flexslider('setOption', 'itemWidth', itemWidth); 1166 testimonialsPartial.flexslider('setOption', 'itemMargin', itemMargin); 1167 }); 1168} 1169 1170// Function fbFullImage() 1171// This function moves specific elements inside each .featuredblock__item element inside .featuredblock__wrap, 1172// creating a container with the class .featuredblock__content--holder and moving selected elements into it. 1173function fbFullImage() { 1174 'use strict'; 1175 // Get the .section.fb-grid-a-full-image element 1176 let fbHolder = document.querySelector('.section.fb-grid-a-full-image'); 1177 // Check if fbHolder exists 1178 if (!fbHolder) { 1179 return; // If fbHolder doesn't exist, exit the function 1180 } 1181 // Get all .featuredblock__item elements inside fbHolder 1182 let fbItems = fbHolder.querySelectorAll('.featuredblock__item'); 1183 // Iterate through each .featuredblock__item element
1184 fbItems.forEach(function (fbItem) { 1185 // Get all inner elements we want to move 1186 let itemInnerItems = fbItem.querySelectorAll( 1187 '.featuredblock__icon, .featuredblock__title, .featuredblock__content, .featuredblock__sub-menu, .featuredblock__cta' 1188 ); 1189 // Get the .featuredblock__wrap element inside the current fbItem 1190 let featuredblockWrap = fbItem.querySelector('.featuredblock__wrap'); 1191 // Create a new div element with the class .featuredblock__content--holder 1192 let itemContentHolder = document.createElement('div'); 1193 itemContentHolder.classList.add('featuredblock__content--holder'); 1194 // Iterate through each inner item and append it to itemContentHolder 1195 itemInnerItems.forEach(function (innerItem) { 1196 itemContentHolder.appendChild(innerItem); 1197 }); 1198 // Append itemContentHolder inside featuredblockWrap 1199 featuredblockWrap.appendChild(itemContentHolder); 1200 }); 1201}
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.