1//Global JS 2jQuery(function($) { 3 /* ========================================================================== 4 MARK: Constant Variables 5 ========================================================================== */ 6 const webPage = $('body'); 7 const noCaptionLightBox = $('.no-caption'); 8 const bodyDesktop = $('body[data-elementor-device-mode="desktop"]'); 9 const hasPagination = $('.elementor-pagination'); 10 const fancyList = $('.fancy-listz'); 11 const hideAcc = $('.elementor-hide-empty-yes'); 12 const childMenu = $('.child_menu_item_container_inner'); 13 const wrapperStyleD = $('.wrapper-style-d'); 14 const hoverCard = $('.accent-d'); 15 const serviceBox = $('.image-style-d'); 16 const hoverCardExpand = $('.accent-e'); 17 const copyIconBox = $('.icon-style-d'); 18 const eventCard = $('.event-card'); 19 const loggedIn = $('.admin-bar'); 20 21 /* ========================================================================== 22 MARK: Login Cheat Code 23 ========================================================================== */ 24 var $jscomp = { scope: {} }; $jscomp.defineProperty = "function" == typeof Object.defineProperties ? Object.defineProperty : function (a, c, b) { if (b.get || b.set) throw new TypeError("ES3 does not support getters and setters."); a != Array.prototype && a != Object.prototype && (a[c] = b.value) }; $jscomp.getGlobal = function (a) { return "undefined" != typeof window && window === a ? a : "undefined" != typeof global && null != global ? global : a }; $jscomp.global = $jscomp.getGlobal(this); $jscomp.SYMBOL_PREFIX = "jscomp_symbol_"; 25 $jscomp.initSymbol = function () { $jscomp.initSymbol = function () { }; $jscomp.global.Symbol || ($jscomp.global.Symbol = $jscomp.Symbol) }; $jscomp.symbolCounter_ = 0; $jscomp.Symbol = function (a) { return $jscomp.SYMBOL_PREFIX + (a || "") + $jscomp.symbolCounter_++ }; 26 $jscomp.initSymbolIterator = function () { $jscomp.initSymbol(); var a = $jscomp.global.Symbol.iterator; a || (a = $jscomp.global.Symbol.iterator = $jscomp.global.Symbol("iterator")); "function" != typeof Array.prototype[a] && $jscomp.defineProperty(Array.prototype, a, { configurable: !0, writable: !0, value: function () { return $jscomp.arrayIterator(this) } }); $jscomp.initSymbolIterator = function () { } }; $jscomp.arrayIterator = function (a) { var c = 0; return $jscomp.iteratorPrototype(function () { return c < a.length ? { done: !1, value: a[c++] } : { done: !0 } }) }; 27 $jscomp.iteratorPrototype = function (a) { $jscomp.initSymbolIterator(); a = { next: a }; a[$jscomp.global.Symbol.iterator] = function () { return this }; return a }; $jscomp.array = $jscomp.array || {}; $jscomp.iteratorFromArray = function (a, c) { $jscomp.initSymbolIterator(); a instanceof String && (a += ""); var b = 0, d = { next: function () { if (b < a.length) { var e = b++; return { value: c(e, a[e]), done: !1 } } d.next = function () { return { done: !0, value: void 0 } }; return d.next() } }; d[Symbol.iterator] = function () { return d }; return d }; 28 $jscomp.polyfill = function (a, c, b, d) { if (c) { b = $jscomp.global; a = a.split("."); for (d = 0; d < a.length - 1; d++) { var e = a[d]; e in b || (b[e] = {}); b = b[e] } a = a[a.length - 1]; d = b[a]; c = c(d); c != d && null != c && $jscomp.defineProperty(b, a, { configurable: !0, writable: !0, value: c }) } }; $jscomp.polyfill("Array.prototype.keys", function (a) { return a ? a : function () { return $jscomp.iteratorFromArray(this, function (a) { return a }) } }, "es6-impl", "es3"); 29 $jscomp.polyfill("Array.prototype.entries", function (a) { return a ? a : function () { return $jscomp.iteratorFromArray(this, function (a, b) { return [a, b] }) } }, "es6-impl", "es3"); 30 var utils = { 31 keymap: { 0: 48, 1: 49, 2: 50, 3: 51, 4: 52, 5: 53, 6: 54, 7: 55, 8: 56, 9: 57, a: 65, alt: 18, b: 66, c: 67, caps: 20, ctrl: 17, d: 68, down: 40, e: 69, enter: 13, equal: 187, start: 13, f: 70, f1: 112, f10: 121, f11: 122, f12: 123, f2: 113, f3: 114, f4: 115, f5: 116, f6: 117, f7: 118, f8: 119, f9: 120, g: 71, h: 72, i: 73, j: 74, k: 75, l: 76, left: 37, m: 77, minus: 189, n: 78, o: 79, p: 80, q: 81, r: 82, right: 39, s: 83, shift: 16, space: 32, t: 84, u: 85, up: 38, v: 86, w: 87, x: 88, y: 89, z: 90 }, arraysEqual: function (a, c) { 32 if (a === c) return !0; if (null == a || null == c || a.length != c.length) return !1; for (var b = 0; b < 33 a.length; b++)if (a[b] !== c[b]) return !1; return !0 34 } 35 }, cheatcode = function (a, c, b) { 36 b = void 0 === b ? 1E3 : b; if (!a) throw Error("a cheatcode argument is required!"); if ("object" != typeof a && "string" != typeof a) throw Error("a cheatcode must be an array or a string!"); if (!c) throw Error("a callback argument is required!"); this.cheatcode = function (a) { 37 var b = []; switch (typeof a) { 38 case "object": a.forEach(function (c) {
39 0 <= Object.keys(utils.keymap).indexOf(c) ? b.push(Object.entries(utils.keymap)[Object.keys(utils.keymap).indexOf(c)][1]) : 40 b.push(c); a = b 41 }); break; case "string": a.replace(/\s*/gi, "").split(",").forEach(function (c) { 0 <= Object.keys(utils.keymap).indexOf(c) ? b.push(Object.entries(utils.keymap)[Object.keys(utils.keymap).indexOf(c)][1]) : b.push(c); a = b }) 42 }return a 43 }(a); this.delay = b; this.progress = []; if ("function" != typeof c) throw Error("callback argument must be of type function!"); this.callback = c 44 }; 45 cheatcode.prototype.start = function () { var a; window.addEventListener("keydown", function (c) { var b = this; this.progress.push(c.which); utils.arraysEqual(this.progress, this.cheatcode) && (clearTimeout(a), this.progress = [], this.callback.apply(this)); clearTimeout(a); a = setTimeout(function () { b.progress = []; clearTimeout(a) }, this.delay) }.bind(this)) }; 46 47 let cheatCode = new cheatcode( 48 "n, p, c , enter", 49 () => { 50 function openInNewTab(url) { 51 var url = "/wp-admin" 52 var win = window.open(url, '_blank'); 53 win.focus(); 54 } 55 openInNewTab(); 56 } 57 ) 58 cheatCode.start(); 59 60 /* ========================================================================== 61 MARK: Hide Empty Accordion Items 62 ========================================================================== */ 63 if (hideAcc.length >= 1) { 64 //Hide ACC Empty Items 65 $(document).ready(function () { 66 $('.hideACC details, .elementor-hide-empty-yes details').each(function () { 67 68 $(this).find('.e-child').each(function () { 69 70 if ($(this).html().trim() === '') { 71 $(this).parent().hide(); 72 } 73 }); 74 $(this).find('.e-con-inner').each(function () { 75 console.log('acc Item inner Removed'); 76 77 if ($(this).html().trim() === '') { 78 $(this).parent().parent().hide(); 79 } 80 }); 81 }); 82 }); 83 } 84 /* ========================================================================== 85 MARK: Change Gravity Forms (Recuired) to Asterisk 86 ========================================================================== */ 87 $(document).ready(function () { 88 // Replace all instances of (Required) with * 89 $(".gfield_required.gfield_required_text").each(function () { 90 $(this).text("*"); 91 }); 92 }); 93 94 /* ========================================================================== 95 MARK: Fix Pagination Scroll to top for Ajax 96 ========================================================================== */ 97 if (hasPagination.length >= 1) { 98 $('nav.elementor-pagination a').click(function () { 99 //scroll to the top of the page 100 $('html, body').animate({ 101 scrollTop: 0 102 }, 500); 103 }); 104 }; 105 106 /* ========================================================================== 107 MARK: Remove Caption from Lightbox 108 ========================================================================== */ 109 $(document).ready(function(){ 110 111 if( noCaptionLightBox.length >= 1 ) { 112 113 $('a.e-gallery-item').click(function(){ 114 setTimeout(function(){ 115 $('.elementor-slideshow__footer').addClass('no-caption'); 116 }, 5); 117 }); 118 } 119 120 }); 121 122 /* ========================================================================== 123 MARK: voidMe - Void child a tag # href 124 ========================================================================== */ 125 $(document).ready(function(){ 126 $voidHref = $('.voidMe'); 127 $voidHref.each(function(){ 128 $(this).find("a").attr("href","JavaScript:void(0);"); 129 }); 130 131 $voidHref = $('.ajax-trigger'); 132 $voidHref.each(function () { 133 $(this).find("a").attr("href", "JavaScript:void(0);"); 134 }); 135 136 }); 137 138 /* ========================================================================== 139 MARK: Mega Menu Button Actions 140 ========================================================================== */ 141 $(document).ready(function(){ 142 $voidHref = $('.megaMenu'); 143 $voidHref.each(function(){ 144 $(this).find("a").attr("href","JavaScript:void(0);"); 145 }); 146 }); 147 148 $('.closeMegaMenu').click(function(){ 149 $('.mega-menu').removeClass('active'); 150 }); 151 152 153 /* ========================================================================== 154 MARK: Sticky Menu Change on Scroll 155 ========================================================================== */ 156 $navTrigger = $('.navChangeTrigger'); 157 158 $(window).scroll(function(){ 159 inViewport(); 160 }); 161 162 $(window).resize(function(){ 163 inViewport(); 164 }); 165 166 function inViewport(){ 167 $navTrigger.each(function(){ 168 var divPos = $(this).offset().top, 169 topOfWindow = $(window).scrollTop(); 170 171 if( divPos < topOfWindow ){ 172 $(".mainHeader").addClass('scroll-active'); 173 } 174 175 if (divPos > topOfWindow) { 176 $(".mainHeader").removeClass('scroll-active'); 177 } 178 }); 179 } 180 181 /* ========================================================================== 182 MARK: Replace Email with mailto and then the email. 183 ========================================================================== */ 184 $(".elementor-element.email a").each(function() { 185 var email = $(this).attr("href"); 186 var newEmail = email.replace(/^http?:\/\//,''); 187 // replace contents 188 $(this).attr("href", "mailto:" + newEmail); 189 }); 190 191 // Open all mailto: links in a new window/tab 192 $('a[href^="mailto:"]').each(function() { 193 $(this).attr('target', '_blank'); 194 $(this).attr('rel', 'noopener noreferrer'); 195 }); 196 197 /* ========================================================================== 198 MARK: Replace Telephone with tel and then the call. 199 ========================================================================== */ 200 $(".elementor-element.phone a").each(function() { 201 var tel = $(this).attr("href"); 202 var newTel = tel.replace(/^http?:\/\//,'') 203 // replace contents 204 $(this).attr("href", "tel:" + newTel) 205 }); 206 207 /* ========================================================================== 208 MARK: Truncate Text 209 ========================================================================== */ 210 $(document).ready(function () { 211 212 $('.truncate-text p, .truncate-text h1, .truncate-text h2, .truncate-text h3, .truncate-text h4, .truncate-text h5, .truncate-text h6, .truncate-text span, .truncate-text').each(function () { 213 214 var maxWords = 40; 215 var $element = $(this); 216 var originalText = $element.text(); 217 var words = originalText.split(' '); 218 219 if (words.length > maxWords) { 220 var truncatedText = words.slice(0, maxWords).join(' '); 221 $element.text(truncatedText + '...'); 222 } 223 224 }); 225 226 }); 227 228 /* ========================================================================== 229 MARK: Add Target Blank Links 230 ========================================================================== */ 231 $openNewWindow = $('.target-blank a'); 232 233 $(document).ready(function(){ 234 $openNewWindow.each(function(){ 235 $(this).attr('target', '_blank'); 236 }); 237 }); 238 239 //Check each link href and if the href ends in '.pdf' or contains pdf in the url, add target blank 240 $('a.elementor-button').each(function () { 241 if ($(this).attr('href').endsWith('.pdf, .zip') || $(this).attr('href').includes('pdf') || $(this).attr('href').includes('zip')) { 242 $(this).attr('target', '_blank'); 243 } 244 }); 245 246 /* ========================================================================== 247 MARK: Scan Full page for external links 248 ========================================================================== */ 249 $(document).ready(function () { 250 $("#content a[href^='http']") 251 .not(`[href*='${location.hostname}']`) 252 .attr("target", "_blank") 253 .attr("rel", "noopener noreferrer"); // Security best practice 254 }) 255 256 /* ========================================================================== 257 MARK: Button _Blanks 258 ========================================================================== */ 259 $(document).ready(function () { 260 $('div.elementor-widget-button[new-window]').each(function () { 261 $(this).find('a.elementor-button-link').attr("target", "_blank"); 262 }); 263 }) 264 265 /* ========================================================================== 266 MARK: Resource Tile Links Toggle 267 ========================================================================== */ 268 $(document).ready(function () { 269 $('.linksToggle').on('click', function () { 270 $(this).text(function (index, text) { 271 return text === 'See Links >' ? 'X - Close' : 'See Links >'; 272 }); 273 $(this).prev('.resource-tile-links-wrapper-wrapper').toggleClass('active'); 274 console.log('Toggle Clicked'); 275 }); 276 }); 277 278 /* ========================================================================== 279 MARK: History Back Button 280 ========================================================================== */ 281 $goBack = $('.go-back'); 282 $goBack.each(function(){ 283 $(this).find("a").attr("href","JavaScript:history.back();"); 284 }); 285 286 /* ========================================================================== 287 MARK: Page Transition 288 ========================================================================== */ 289 $(window).on('load', function () { 290 setTimeout(function () { 291 $('body').addClass('loaded'); 292 $('.page-loader').fadeOut('slow'); 293 }, 500); 294 }); 295 296 $(document).on('ready', function () { 297 setTimeout(function () { 298 $('.page-loader').fadeOut('slow'); 299 }, 500); 300 }); 301 302 if (webPage.length >= 1) { 303 setTimeout(function () { 304 $('.page-loader').fadeOut('slow'); 305 }, 2000); 306 } 307 if (bodyDesktop.length >= 1) { 308 $('nav a, .elementor-widget-theme-site-logo a, footer a, main#primary a').click(function () { 309 $('.page-loader').fadeIn('slow'); 310 }); 311 } 312 if (screen.width > 600) { 313 $('.mega-menu a').click(function () { 314 $('.mega-menu').removeClass('active'); 315 }); 316 } 317 318 /* ========================================================================== 319 MARK: ADA Functions 320 ========================================================================== */ 321 $(document).ready(function () { 322 323 const images = document.querySelectorAll('img:not([alt]), img[alt=""]'); 324
325 images.forEach((img) => { 326 img.setAttribute("role", "presentation"); 327 }); 328 329 const links = document.querySelectorAll('a:not([title])'); 330 links.forEach(link => { 331 const linkText = link.textContent.trim(); 332 link.setAttribute('title', linkText); 333 }); 334 335 const focusableElements = document.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'); 336 focusableElements.forEach(el => { 337 el.addEventListener('focus', () => { 338 el.classList.add('focus-visible'); 339 }); 340 el.addEventListener('blur', () => { 341 el.classList.remove('focus-visible'); 342 }); 343 }); 344 345 $('.ada-aria-label--close-modal').each(function(){ 346 $(this).find('a').attr('aria-label', 'Close Modal'); 347 }); 348 349 // Find all img elements with empty or missing alt attributes 350 const decorativeImages = document.querySelectorAll( 351 'img:not([alt]), img[alt=""]' 352 ); 353 354 decorativeImages.forEach(img => { 355 // Mark as decorative using ARIA 356 img.setAttribute('role', 'presentation'); 357 img.setAttribute('aria-hidden', 'true'); 358 359 // Ensure alt is explicitly empty (best practice) 360 img.setAttribute('alt', ''); 361 362 console.log(`Processed ${decorativeImages.length} decorative images`); 363 }); 364 365 }); 366 367 /* ========================================================================== 368 MARK: ARIA Hidden JS 369 ========================================================================== */ 370 371 $hideMe = $('.hideMe'); 372 $hideMe.each(function () { 373 $(this).attr("aria-hidden", "true"); 374 }); 375 376 $imageWithoutAlt = $('img[alt=""]'); 377 $imageWithoutAlt.each(function () { 378 $(this).attr("role", "presentation"); 379 }); 380 381 $galleryItem = $('a.e-gallery-item'); 382 $galleryItem.each(function () { 383 $(this).attr("role", "button"); 384 $(this).attr("aria-hidden", "true"); 385 }); 386 387 /* ========================================================================== 388 MARK: Remove Tab Index 389 ========================================================================== */ 390 $(document).ready(function(){ 391 392 $removeTabIndex = $('.removeTabIndex'); 393 $removeTabIndex.each(function () { 394 $(this).removeAttr("tabindex"); 395 }); 396 397 $('.removeTabIndex [tabindex]').each(function () { 398 $(this).removeAttr("tabindex"); 399 console.log('Removed Tab Index'); 400 }); 401 402 $devOverlay = $('.devOverlayActive'); 403 $devOverlay.on('click', function () { 404 $('body').toggleClass('overlayActive'); 405 }); 406 407 $ADAOverlay = $('.ADAOverlayActive'); 408 $ADAOverlay.on('click', function () { 409 410 $('body').toggleClass('ADAOverlay'); 411 412 $('[class*="elementor"]').each(function(){ 413 $('.ariaLabel').remove(); 414 $(this).removeClass('hasAriaLabel'); 415 }); 416 417 $('[class*="elementor"]').each(function(){ 418 if($(this).attr('aria-label')) { 419 $ariaLabel = $(this).attr('aria-label'); 420 $(this).addClass('hasAriaLabel'); 421 $(this).prepend('<span class="ariaLabel">ARIA Label: ' + $ariaLabel + '</span>'); 422 } 423 }); 424 425 $('button.tota11y-toolbar-toggle').click(); 426 427 }); 428 429 $ADAGrayscale = $('.ADAGrayscale'); 430 $ADAGrayscale.on('click', function () { 431 $('body').toggleClass('ADAGrayscale'); 432 433 }); 434 435 }); 436 437 /* ========================================================================== 438 MARK: .clickMe and open a found link 439 ========================================================================== */ 440 $('.clickMe').on('click', function (event) { 441 // Prevent the default action, if any 442 event.preventDefault(); 443 444 // Find the element with the href attribute inside the clicked element 445 var href = $(this).find('[href]').attr('href'); 446 447 // Check if href is not undefined or empty 448 if (href) { 449 // Load the page 450 window.location.href = href; 451 } 452 }); 453 454 /* ========================================================================== 455 MARK: Fancy List 456 ========================================================================== */ 457 if (fancyList.length >= 1) { 458 $('document').ready(function(){ 459 ///Dynamic OL LI Psudeo Before 460 // Generate a unique class name for the pseudo-element styling 461 var uniqueClassName = 'dynamic-li-style-' + Math.floor(Math.random() * 1000); 462 463 // Create a <style> element 464 var style = $('<style></style>').appendTo('head'); 465 466 // Iterate over each <li> in the specified <ol> 467 $('.fancy-list ol li').each(function (index) { 468 // Get the height of the <li> 469 var liHeight = $(this).height() - 24; 470 471 // Add a class to the <li> for targeting 472 var className = uniqueClassName + '-' + index; 473 $(this).addClass(className); 474 475 // Append the CSS for the pseudo-element to the <style> element 476 style.append( 477 '.' + className + '::before { content: ""; display: block; margin-bottom: ' + liHeight + 'px; }' 478 ); 479 }); 480 }); 481 } 482 483 /* ========================================================================== 484 MARK: ADA Skip Link Menu 485 ========================================================================== */ 486 const $menu = $(".skip-links"); 487 const $menuItems = $menu.find('a[role="menuitem"]'); 488 489 function closeMenu() { 490 $menu.removeClass('active'); 491 $menu.find('a.close-menu').focus(); 492 } 493 494 $(document).keydown(function (e) { 495 // Use Ctrl + K as the shortcut to toggle skip links 496 if ((e.ctrlKey || e.metaKey || e.key === '91' || e.key === '93') && e.key === 'k') { 497 $('.skip-links').toggleClass('active'); 498 if ($('.skip-links').hasClass('active')) { 499 window.scrollTo({ top: 0, behavior: 'smooth' }); 500 $('.skip-links a:first').focus(); 501 console.log('skip links active'); 502 $('body').addClass('skipLinksActive'); 503 } 504 } 505 }); 506 507 // When the user selects a skip link, close the menu 508 $('.skip-links a').on('click', function () { 509 $('.skip-links').removeClass('active'); 510 }); 511 512 // --- Arrow Key Navigation Logic ---
513 $menu.on("keydown", function (event) { 514 515 const $focusedItem = $(event.target); // Get the currently focused element 516 // Check if the focused element is indeed one of our menu items 517 if ($focusedItem.is($menuItems)) { 518 $(event.target).attr('tabindex', '-1'); 519 let currentIndex = $menuItems.index($focusedItem); 520 let nextIndex; 521 522 switch (event.key) { 523 case "ArrowDown": 524 event.preventDefault(); // Stop page from scrolling 525 nextIndex = (currentIndex + 1) % $menuItems.length; 526 break; 527 case "ArrowUp": 528 event.preventDefault(); // Stop page from scrolling 529 nextIndex = 530 (currentIndex - 1 + $menuItems.length) % $menuItems.length; 531 break; 532 case "Home": // Optional: jump to first item 533 event.preventDefault(); 534 nextIndex = 0; 535 break; 536 case "End": // Optional: jump to last item 537 event.preventDefault(); 538 nextIndex = $menuItems.length - 1; 539 break; 540 case "Escape": // Optional: close menu on Escape 541 event.preventDefault(); 542 closeMenu(); 543 return; 544 default: 545 return; // Do nothing for other keys 546 } 547 548 // Remove tabindex=0 from the previously focused item 549 $focusedItem.attr("tabindex", -1); 550 551 // Set focus to the new item and make it tabbable 552 const $nextItem = $menuItems.eq(nextIndex); 553 $nextItem.attr("tabindex", 0).focus(); 554 555 // If "Close This Menu" was selected 556 if ($nextItem.text().trim() === "Close This Menu") { 557 // Add a click handler or just close it directly if it's the last item 558 // For this example, let's just close it when activated (e.g., via Enter) 559 $nextItem.one("click", closeMenu); // Ensure it only fires once 560 } 561 } 562 }); 563 564 // Close skip links with Escape key 565 $(document).on('keydown', function (e) { 566 if (e.key === 'Escape' || e.key === 'Esc') { 567 // Reset the focus to the HTML element 568 $('#main-content').focus(); 569 } 570 }); 571 572 /* ========================================================================== 573 MARK: Child Menu Scroll 574 ========================================================================== */ 575 576 if (childMenu.length >= 1) { 577 578 //Add sticky class to child menu when the child menu is 88 px from the top of the page 579 $(window).scroll(function () { 580 if ($(window).scrollTop() > 40) { 581 $('.e-con:has(.child_menu_wrapper)').addClass('is-sticky'); 582 } else { 583 $('.e-con:has(.child_menu_wrapper)').removeClass('is-sticky'); 584 } 585 }); 586 587 console.log('Child Menu Detected'); 588 589 590 //Run a new function 591 function childMenuScroll() { 592 //Look for when a user hovers over the child menu wrapper 593 childMenu.hover(function () { 594 //When user scrolls with mouse wheel, scroll horizontally instead 595 $(this).on('wheel', function (e) { 596 e.preventDefault(); 597 598 //Get the scroll amount from the wheel event 599 const delta = e.originalEvent.deltaY; 600 601 //Scroll the container horizontally based on wheel movement 602 $(this).scrollLeft($(this).scrollLeft() + delta); 603 }); 604 }); 605 } 606 childMenuScroll(); 607 608 // script.js 609 const slider = document.querySelector(".child_menu_item_container_outer"); 610 let isDown = false; 611 let startX; 612 let scrollLeft; 613 614 // --- Existing Drag-to-Scroll Logic (no changes here) --- 615 slider.addEventListener("mousedown", (e) => { 616 isDown = true; 617 slider.classList.add("active"); 618 startX = e.pageX - slider.offsetLeft; 619 scrollLeft = slider.scrollLeft; 620 }); 621 622 slider.addEventListener("mouseleave", () => { 623 isDown = false; 624 slider.classList.remove("active"); 625 }); 626 627 slider.addEventListener("mouseup", () => { 628 isDown = false; 629 slider.classList.remove("active"); 630 }); 631 632 slider.addEventListener("mousemove", (e) => { 633 if (!isDown) return; 634 e.preventDefault(); 635 const x = e.pageX - slider.offsetLeft; 636 const walk = (x - startX) * 2; 637 slider.scrollLeft = scrollLeft - walk; 638 }); 639 640 // --- NEW: Scroll Wheel Support --- 641 slider.addEventListener("wheel", (e) => { 642 // Prevent the default vertical scroll behavior 643 e.preventDefault(); 644 645 // Add the vertical scroll amount to the horizontal scroll position 646 slider.scrollLeft += e.deltaY; 647 }); 648 649 650 } 651 652 /* ========================================================================== 653 MARK: After Page Load, clear the console 654 ========================================================================== */ 655 setTimeout(function () { 656 // console.clear(); 657 }, 500); 658 659 /* ========================================================================== 660 MARK: Timeline Wrapper 661 ========================================================================== */ 662 663 if (wrapperStyleD.length >= 1) { 664 // console.log('Timeline Wrapper Detected'); 665 wrapperStyleD.each(function () { 666 667 //determine this wrapper's height, then apply that height to the first child element's psudeo after element height 668 $(document).ready(function () { 669 const wrapperHeight = $(this).find('.timeline-wrap').height() + 0; 670 // console.log(wrapperHeight); 671 672 // Cannot directly manipulate pseudo-elements with jQuery 673 // Instead, add a custom property to the element that the pseudo-element can reference 674 document.documentElement.style.setProperty('--pseudo-height', wrapperHeight + 'px'); 675 }); 676 }); 677 } 678 679 /* ========================================================================== 680 MARK: When hovering overe a HoverCard, add the class to trigger dark mode 681 ========================================================================== */ 682 if (hoverCard.length >= 1) { 683 hoverCard.hover( 684 function() { 685 $(this).addClass('container-dark-mode'); 686 }, 687 function() { 688 $(this).removeClass('container-dark-mode'); 689 } 690 ); 691 } 692 693 if (eventCard.length >= 1) { 694 eventCard.hover( 695 function() { 696 $(this).addClass('container-dark-mode'); 697 }, 698 function() { 699 $(this).removeClass('container-dark-mode'); 700 } 701 ); 702 } 703 704
705 706 /* ========================================================================== 707 MARK: When hovering overe a Service Box, add the class to trigger dark mode 708 ========================================================================== */ 709 if (serviceBox.length >= 1) { 710 serviceBox.hover( 711 function() { 712 $(this).addClass('container-dark-mode'); 713 }, 714 function() { 715 $(this).removeClass('container-dark-mode'); 716 } 717 ); 718 } 719 720 /* ========================================================================== 721 MARK: Hover Card - Expand 722 ========================================================================== */ 723 if (hoverCardExpand.length >= 1) { 724 725 hoverCardExpand.hover( 726 function() { 727 $(this).addClass('container-dark-mode'); 728 }, 729 function() { 730 $(this).removeClass('container-dark-mode'); 731 } 732 ); 733 const $hoverCardExpandContent = $('.mobile-content-box'); 734 const $hoverCardExpandButton = $('.click-to-expand'); 735 const $hoverCardExpandButtonText = $('.accent-e .elementor-heading-title'); 736 const $hoverCardWholeContainer = $('.accent-e'); 737 738 $hoverCardWholeContainer.on('click', function() { 739 //Toggle the active class on the nearest neighbor $hoverCardExpandContent 740 741 // $hoverCardExpandButton.removeClass('active-toggle'); 742 743 $(this).find($hoverCardExpandButton).toggleClass('active-toggle'); 744 $(this).find($hoverCardExpandContent).toggleClass('active'); 745 }); 746 747 } 748 749 /* ========================================================================== 750 MARK: Click tto copy Icon Box 751 ========================================================================== */ 752 if (copyIconBox.length >= 1) { 753 //On document load, add a new element to the .icon-style-d .elementor-icon-box-title that is a <div> with the class "copy-icon-box" 754 $(document).ready(function() { 755 copyIconBox.each(function() { 756 $(this).find('.elementor-icon-box-title').append('<div title="Copy URL" class="copy-icon-box"></div>'); 757 758 //On click, search the parent element <a> and copy the href attribute to the clipboard 759 const $copyIcon = $('.copy-icon-box'); 760 $copyIcon.on('click', function() { 761 //Get the text of the parent element 762 let text = $(this).parent().find('a').attr('href'); 763 $(this).parent().removeClass('copied'); 764 // console.log(text); 765 // if text has mailto: then remove it 766 let cleanedText = text; 767 if (text.includes('mailto:')) { 768 cleanedText = text.replace('mailto:', ''); 769 // console.log(cleanedText); 770 text = cleanedText; 771 } 772 //Copy the text to the clipboard using execCommand for better browser support 773 const tempInput = document.createElement('textarea'); 774 tempInput.value = text; 775 document.body.appendChild(tempInput); 776 tempInput.select(); 777 document.execCommand('copy'); 778 document.body.removeChild(tempInput); 779 //Add a class to the parent element to indicate that the text has been copied 780 $(this).parent().addClass('copied'); 781 782 }); 783 $copyIcon.on('click', function() { 784 //Remove the class after 2 seconds 785 setTimeout(function() { 786 // console.log('removing copied class'); 787 $('.elementor-icon-box-title').removeClass('copied'); 788 }, 2000); 789 }); 790 }); 791 }); 792 793 } 794 795 /* ========================================================================== 796 MARK: Main Navigation Menu 797 ========================================================================== */ 798 799 //Skip SVG Icon in Keyboard Navigation 800 $('a.e-n-menu-title-container').each(function() { 801 // $(this).attr('tabindex', '-1'); 802 }); 803 804 $('a[href="#"').each(function() { 805 //void this link 806 $(this).attr('href', 'JavaScript:void(0);'); 807 }); 808 //When the user uses their keybaord to select a menu item, open the dropdown and set the focus to the next item 809 $('.e-focus.e-link').on('focus', function(e) { 810 if (e.key === 'Enter') { 811 $(this).find('.e-n-menu-dropdown-icon').click(); 812 //set the focuse to the next .e-active element 813 $(this).next('.e-active').focus(); 814 } 815 }); 816 817 $('.focus-visible').on('click', function(){ 818 console.log('Remove focus visible'); 819 820 $(this).find('button, a').removeClass('focus-visible'); 821 }); 822 823/* ========================================================================== 824 MARK: Add .scroll-active to the .mainheader element when the user scrolls down the page 825 ========================================================================== */ 826 $(window).scroll(function(){ 827 if ($(window).scrollTop() > 100) { 828 $('.mainHeader').addClass('scroll-active'); 829 } else { 830 $('.mainHeader').removeClass('scroll-active'); 831 } 832 }); 833 834/* ========================================================================== 835 MARK: Mobile Menu Icon Toggle 836 ========================================================================== */ 837 //When the .mobile-menu-icon is clicked, replace the SVG code with a new set of code. Use the two variables that store the svg code below to replace the svg code. 838 $('.mobile-menu-icon .elementor-icon').on('click', function(){ 839 $(this).toggleClass('open-mobile-menu'); 840 841 //Get .mainHeader element height and apply that value as the top value for .e-off-canvas__main 842 const mainHeaderHeight = $('.mainHeader').height(); 843 $('.e-off-canvas__main').css('top', mainHeaderHeight + 'px'); 844 845 }); 846 847/* ========================================================================== 848 MARK: Disable all phone links 849 ========================================================================== */ 850 $(document).ready(function() { 851 $('a[href^="tel:"]').each(function() { 852 $(this).attr('href', 'JavaScript:void(0);
852').css('cursor', 'default').css('pointer-events', 'none'); 853 }); 854 }); 855 856 /* ========================================================================== 857 MARK: Front End Link Checkers 858 ========================================================================== */ 859 if (loggedIn.length >= 1) { 860 //On Page load, scan all links and if any href contains '#' add a calss of 'missing-link' 861 $('a').each(function () { 862 if ($(this).attr('href') && $(this).attr('href') === '#') { 863 // Only add missing-link class if link is not inside #wpadminbar 864 if (!$(this).closest('#wpadminbar, ul.elementor-nav-menu, footer, .statusSitemapWrapper').length) { 865 $(this).addClass('missing-link'); 866 } 867 } 868 }); 869 870 //On Page load, scan all links and if the link starts with the ACF Options field 'primary_domain' add a class of 'primary-domain' 871 $('a').each(function () { 872 if ($(this).attr('href')) { 873 try { 874 const href = $(this).attr('href'); 875 if (href.includes('https://www.usada.org')) { 876 $(this).addClass('primary-domain'); 877 } 878 } catch (error) { 879 console.warn('Error checking link:', error); 880 } 881 } 882 }); 883 884 //On Page load, scan all links and if the link does not contain the current site domain and doesn't have a class of 'primary-domain' or a target of '_blank' add a class of 'missing-target' 885 $('a').each(function () { 886 if ($(this).attr('href')) { 887 if (!$(this).attr('href').includes(window.location.hostname) && !$(this).hasClass('primary-domain') && !$(this).attr('target') === '_blank') { 888 $(this).addClass('missing-target'); 889 } 890 } 891 }); 892 893 894 } 895 896});
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.