1(function () { 2 'use strict'; 3 4 /* ââ Mobile burger menu ââââââââââââââââââââââââââââââââ */ 5 var header = document.querySelector('[data-header]'); 6 if (header) { 7 var burger = header.querySelector('[data-burger]'); 8 if (burger) { 9 burger.addEventListener('click', function () { 10 var open = header.classList.toggle('is-open'); 11 burger.setAttribute('aria-expanded', open ? 'true' : 'false'); 12 document.body.style.overflow = open ? 'hidden' : ''; 13 }); 14 } 15 header.addEventListener('click', function (e) { 16 if (e.target.closest('.site-header__overlay a')) { 17 header.classList.remove('is-open'); 18 document.body.style.overflow = ''; 19 } 20 }); 21 } 22 23 /* ââ Category bar dropdown ââââââââââââââââââââââââââââââ */ 24 var catBar = document.querySelector('[data-cat-bar]'); 25 if (catBar) { 26 var toggle = catBar.querySelector('[data-cat-toggle]'); 27 var closeCat = function () { 28 catBar.classList.remove('is-open'); 29 if (toggle) toggle.setAttribute('aria-expanded', 'false'); 30 }; 31 if (toggle) { 32 toggle.addEventListener('click', function () { 33 var open = catBar.classList.toggle('is-open'); 34 toggle.setAttribute('aria-expanded', open ? 'true' : 'false'); 35 }); 36 } 37 catBar.addEventListener('click', function (e) { 38 if (e.target.closest('[data-cat-close]')) closeCat(); 39 }); 40 } 41 42 /* ââ Book a call modal (HubSpot meetings embed) âââââââââ */ 43 var modal = document.querySelector('[data-book-modal]'); 44 if (modal) { 45 var HUBSPOT_SRC = 46 'https://static.hsappstatic.net/MeetingsEmbed/ex/MeetingsEmbedCode.js'; 47 var loaded = false; 48 49 var openModal = function () { 50 modal.classList.add('is-open'); 51 modal.setAttribute('aria-hidden', 'false'); 52 document.body.style.overflow = 'hidden'; 53 if (!loaded) { 54 var s = document.createElement('script'); 55 s.src = HUBSPOT_SRC; 56 s.type = 'text/javascript'; 57 s.async = true; 58 document.body.appendChild(s); 59 loaded = true; 60 } 61 }; 62 63 var closeModal = function () { 64 modal.classList.remove('is-open'); 65 modal.setAttribute('aria-hidden', 'true'); 66 document.body.style.overflow = ''; 67 }; 68 69 document.addEventListener('click', function (e) { 70 if (e.target.closest('[data-book-call]')) { 71 e.preventDefault(); 72 openModal(); 73 } else if (e.target.closest('[data-book-close]')) { 74 closeModal(); 75 } 76 }); 77 78 document.addEventListener('keydown', function (e) { 79 if (e.key === 'Escape') closeModal(); 80 }); 81 } 82 83 /* ââ Table-of-contents scroll spy âââââââââââââââââââââââ */ 84 var tocLinks = document.querySelectorAll('[data-toc-link]'); 85 if (tocLinks.length && 'IntersectionObserver' in window) { 86 var linkById = {}; 87 var headings = []; 88 Array.prototype.forEach.call(tocLinks, function (l) { 89 var id = l.getAttribute('data-toc-link'); 90 linkById[id] = l; 91 var h = document.getElementById(id); 92 if (h) headings.push(h); 93 }); 94 95 var setActive = function (id) { 96 Array.prototype.forEach.call(tocLinks, function (l) { 97 l.classList.remove('is-active'); 98 }); 99 if (linkById[id]) linkById[id].classList.add('is-active'); 100 }; 101 102 var observer = new IntersectionObserver( 103 function (entries) { 104 entries.forEach(function (entry) { 105 if (entry.isIntersecting) setActive(entry.target.id); 106 }); 107 }, 108 { rootMargin: '-110px 0px -70% 0px', threshold: 0 } 109 );
110 headings.forEach(function (h) { 111 observer.observe(h); 112 }); 113 } 114 115 /* ââ Drag / swipe horizontal carousel âââââââââââââââââââ */ 116 Array.prototype.forEach.call( 117 document.querySelectorAll('[data-drag-scroll]'), 118 function (track) { 119 var down = false; 120 var moved = false; 121 var startX = 0; 122 var startScroll = 0; 123 124 // Edge fade only when something is actually hidden on that side. 125 var updateFade = function () { 126 var max = track.scrollWidth - track.clientWidth; 127 track.classList.toggle('at-start', track.scrollLeft <= 1); 128 track.classList.toggle('at-end', track.scrollLeft >= max - 1); 129 }; 130 updateFade(); 131 track.addEventListener('scroll', updateFade, { passive: true }); 132 window.addEventListener('resize', updateFade); 133 134 track.addEventListener('pointerdown', function (e) { 135 down = true; 136 moved = false; 137 startX = e.pageX; 138 startScroll = track.scrollLeft; 139 // NOTE: capture is deferred to the first real move â capturing on 140 // pointerdown retargets the follow-up click to the track, which 141 // swallows plain clicks on the cards (desktop navigation broke). 142 }); 143 track.addEventListener('pointermove', function (e) { 144 if (!down) return; 145 var dx = e.pageX - startX; 146 if (!moved && Math.abs(dx) > 4) { 147 moved = true; 148 track.classList.add('is-dragging'); 149 try { 150 track.setPointerCapture(e.pointerId); 151 } catch (err) {} 152 } 153 if (moved) track.scrollLeft = startScroll - dx; 154 }); 155 var end = function () { 156 down = false; 157 track.classList.remove('is-dragging'); 158 }; 159 track.addEventListener('pointerup', end); 160 track.addEventListener('pointercancel', end); 161 // suppress the click that follows a drag (a plain click never sets moved) 162 track.addEventListener( 163 'click', 164 function (e) { 165 if (moved) { 166 e.preventDefault(); 167 e.stopPropagation(); 168 } 169 }, 170 true 171 ); 172 } 173 ); 174})();
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.