1/* dane custom.js: lean init + lazy third-party */ 2(function ($) { 3 "use strict"; 4 5 /* ---------- utils ---------- */ 6 7 function throttle(fn, wait) { 8 var t = 0; 9 return function () { 10 var now = Date.now(); 11 if (now - t > wait) { 12 t = now; 13 fn.apply(this, arguments); 14 } 15 }; 16 } 17 18 function loadStyle(href) { 19 return new Promise(function (res, rej) { 20 if (document.querySelector('link[href="' + href + '"]')) return res(); 21 var l = document.createElement("link"); 22 l.rel = "stylesheet"; 23 l.href = href; 24 l.onload = res; 25 l.onerror = rej; 26 document.head.appendChild(l); 27 }); 28 } 29 30 function loadScript(src) { 31 return new Promise(function (res, rej) { 32 if (document.querySelector('script[src="' + src + '"]')) { 33 return setTimeout(res, 0); 34 } 35 var s = document.createElement("script"); 36 s.src = src; 37 s.async = true; 38 s.defer = true; 39 s.onload = res; 40 s.onerror = rej; 41 document.head.appendChild(s); 42 }); 43 } 44 45 function onIdle(fn, timeout) { 46 if ("requestIdleCallback" in window) { 47 requestIdleCallback(fn, { timeout: timeout || 1200 }); 48 } else { 49 setTimeout(fn, timeout || 600); 50 } 51 } 52 53 /* ---------- 1) button: add class when text === Learn More ---------- */ 54 function flagLearnMoreButtons() { 55 $(".et_pb_button").each(function () { 56 if ($(this).text().trim().toLowerCase() === "learn more") { 57 $(this).addClass("learn-more-btn-hide"); 58 } 59 }); 60 } 61 62 /* ---------- 2) SLICK: init only when visible + library ready ---------- */ 63 var SLICK_JS = "https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"; 64 var SLICK_CSS = "https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css"; 65 var SLICK_THEME = "https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css"; 66 67 function ensureSlick() { 68 if ($.fn && $.fn.slick) return Promise.resolve(); 69 return Promise.all([loadStyle(SLICK_CSS), loadStyle(SLICK_THEME), loadScript(SLICK_JS)]); 70 } 71 72 function initOneSlick($carousel) { 73 if ($carousel.data("slick-initialized")) return; 74 $carousel.data("slick-initialized", true); 75 76 var $pagination = $('<div class="dane-carousel-pagination">' + 77 '<button class="dane-carousel-prev"><img src="/wp-content/uploads/dane-icons_chevron-left-red.svg" alt="Previous"></button>' + 78 '<button class="dane-carousel-next"><img src="/wp-content/uploads/dane-icons_chevron-right-red.svg" alt="Next"></button>' + 79 "</div>"); 80 81 var hasMultiple = $carousel.find(".dane-carousel-slide").length > 1; 82 83 if (hasMultiple) { 84 $carousel.after($pagination); 85 } 86 87 $carousel.on("init", function () { 88 $carousel.closest(".dane-carousel-container").addClass("loaded"); 89 }); 90 91 $carousel.slick({ 92 infinite: true, 93 slidesToShow: 1, 94 slidesToScroll: 1, 95 autoplay: !!hasMultiple, 96 autoplaySpeed: 3000, 97 arrows: !!hasMultiple, 98 prevArrow: hasMultiple ? $pagination.find(".dane-carousel-prev") : undefined, 99 nextArrow: hasMultiple ? $pagination.find(".dane-carousel-next") : undefined, 100 pauseOnHover: true, 101 fade: true, 102 lazyLoad: "ondemand", 103 responsive: [ 104 { 105 breakpoint: 768, 106 settings: { slidesToShow: 1, slidesToScroll: 1, arrows: false } 107 } 108 ] 109 }); 110 } 111 112 function initSlickWhenVisible() { 113 var $carousels = $(".dane-carousel"); 114 if (!$carousels.length) return; 115 116 var io = "IntersectionObserver" in window ? new IntersectionObserver(function (entries) { 117 entries.forEach(function (entry) { 118 if (!entry.isIntersecting) return; 119 var el = entry.target; 120 io.unobserve(el); 121 ensureSlick().then(function () { initOneSlick($(el)); }); 122 }); 123 }, { rootMargin: "200px 0px" }) : null; 124 125 $carousels.each(function () { 126 if (io) { 127 io.observe(this); 128 } else { 129 onIdle(function () { 130 ensureSlick().then(function () { initOneSlick($(this)); }.bind(this)); 131 }, 600); 132 } 133 }); 134 135 $(window).on("resize", throttle(function () { 136 $(".dane-carousel.slick-initialized").slick("setPosition"); 137 }, 300)); 138 } 139 140 /* ---------- 3) LIGHTBOX: lazy-load Magnific on first click ---------- */ 141 var MFP_JS = "https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/jquery.magnific-popup.min.js"; 142 var MFP_CSS = "https://cdnjs.cloudflare.com/ajax/libs/magnific-popup.js/1.1.0/magnific-popup.min.css"; 143 144 function ensureMagnific() {
145 if ($.magnificPopup && $.magnificPopup.open) return Promise.resolve(); 146 return Promise.all([loadStyle(MFP_CSS), loadScript(MFP_JS)]); 147 } 148 149 $(document).on("click", "a.lightbox-trigger", function (e) { 150 e.preventDefault(); 151 var href = $(this).attr("href"); 152 ensureMagnific().then(function () { 153 $.magnificPopup.open({ 154 items: { src: href }, 155 type: "image", 156 gallery: { enabled: true }, 157 callbacks: { 158 open: function () { 159 $(".mfp-img").css({ 160 minWidth: "40vw", 161 width: "auto", 162 height: "auto", 163 maxWidth: "90vw", 164 maxHeight: "90vh" 165 }); 166 } 167 } 168 }); 169 }); 170 }); 171 172 /* ---------- 4) scrolling strip ---------- */ 173 function setupScrolling() { 174 var $wrap = $(".scrolling-wrap").first(); 175 if (!$wrap.length || $wrap.data("cloned")) return; 176 var $clone = $wrap.clone(); 177 $wrap.after($clone); 178 $wrap.data("cloned", true); 179 180 var totalWidth = $wrap[0].scrollWidth; 181 var pxPerSec = 180; 182 var duration = Math.max(10, Math.min(120, totalWidth / pxPerSec)); 183 184 $wrap.css("animation-duration", duration + "s"); 185 $clone.css("animation-duration", duration + "s"); 186 } 187 188 /* ---------- 5) accordion ---------- */ 189 /* 190 function bindAccordion() { 191 $(".et_pb_accordion .et_pb_toggle_open") 192 .addClass("et_pb_toggle_close") 193 .removeClass("et_pb_toggle_open"); 194 195 $(".et_pb_toggle_title").on("click", function () { 196 var $toggle = $(this).closest(".et_pb_toggle"); 197 var $acc = $toggle.closest(".et_pb_accordion"); 198 if ($acc.hasClass("et_pb_accordion_toggling")) return; 199 $acc.addClass("et_pb_accordion_toggling"); 200 201 $toggle.find(".et_pb_toggle_content").slideToggle(300, function () { 202 $toggle.toggleClass("et_pb_toggle_open et_pb_toggle_close"); 203 setTimeout(function () { $acc.removeClass("et_pb_accordion_toggling"); }, 50); 204 }); 205 }); 206 } 207 */ 208 209 /* ---------- 6) minor DOM tidies ---------- */ 210 function tidyDOM() { 211 $("p").filter(function () { return this.textContent.trim() === "" && this.children.length === 0; }).remove(); 212 213 function removeOnMobile() { 214 if (window.innerWidth <= 768) $(".remove-on-mobile").remove(); 215 } 216 removeOnMobile(); 217 $(window).on("resize", throttle(removeOnMobile, 250)); 218 219 $(".side_by_btn_column").each(function () { 220 var $btnParents = $(this).find(".et_pb_button").parent(); 221 if ($btnParents.length > 1 && !$(this).find(".side-by-side-wrap").length) { 222 $btnParents.wrapAll('<div class="side-by-side-wrap"></div>'); 223 } 224 }); 225 226 $(".add-checkmark-class li").addClass("checkmark"); 227 $(".add-arrow-right-class li").addClass("arrow-right"); 228 } 229 230 /* ---------- 7) menu arrows ---------- */ 231 function decorateMenu() { 232 var $links = $("#menu-primary-menu-desktop li a"); 233 $links.each(function () { 234 var txt = $(this).text().toLowerCase(); 235 if (/(products|sectors|resources|about|contact)/.test(txt)) { 236 if ($(this).find("img.down-arrow").length) return; 237 $(this).append(' <img class="down-arrow default-arrow" src="/wp-content/uploads/dane-icons_carrot-down-black.svg" alt="down arrow">'); 238 $(this).append(' <img class="down-arrow hover-arrow" src="/wp-content/uploads/dane-icons_carrot-down-red.svg" alt="down arrow">'); 239 } 240 }); 241 } 242 243 /* ---------- HERO VIDEO: drop-in optimized ---------- */ 244 (function () { 245 "use strict"; 246 247 let built = false; 248 249 function inViewport(el) { 250 const r = el.getBoundingClientRect(); 251 return r.top < window.innerHeight && r.bottom > 0 && r.left < window.innerWidth && r.right > 0; 252 } 253 254 function build() { 255 if (built) return; 256 257 const root = document.getElementById("bh-hero"); 258 if (!root) return; 259 260 const holder = root.querySelector(".bh-hero__media"); 261 if (!holder) return; 262 263 const mp4 = (root.dataset.mp4 || "").trim(); 264 const posterURL = (root.dataset.poster || "").trim(); 265 if (!mp4) return; 266 267 let posterEl = holder.querySelector("img.bh-hero__poster") || null; 268 269 if (!posterEl && posterURL) { 270 const pre = new Image(); 271 pre.decoding = "async"; 272 pre.onload = function () { 273 posterEl = document.createElement("img"); 274 posterEl.className = "bh-hero__poster"; 275 posterEl.src = posterURL; 276 posterEl.fetchPriority = "high";
277 holder.appendChild(posterEl); 278 }; 279 pre.src = posterURL; 280 } else if (posterEl) { 281 try { posterEl.fetchPriority = "high"; } catch (_) {} 282 } 283 284 const v = document.createElement("video"); 285 v.autoplay = true; 286 v.loop = true; 287 v.muted = true; 288 v.playsInline = true; 289 v.preload = "metadata"; 290 v.setAttribute("aria-hidden", "true"); 291 292 /* ensure correct sizing from first paint */ 293 v.style.position = "absolute"; 294 v.style.inset = "0"; 295 v.style.width = "100%"; 296 v.style.height = "100%"; 297 v.style.objectFit = "cover"; 298 v.style.objectPosition = "center"; 299 v.style.opacity = "0"; 300 v.style.background = "#000"; 301 v.style.transition = "opacity .35s ease"; 302 v.style.display = "block"; 303 304 const reveal = () => { 305 v.style.opacity = "1"; 306 if (posterEl) posterEl.style.opacity = "0"; 307 v.play().catch(() => {}); 308 }; 309 310 v.addEventListener("loadedmetadata", () => { 311 try { if (v.readyState < 2) v.currentTime = 0.05; } catch (_) {} 312 }, { once: true }); 313 314 v.addEventListener("seeked", reveal, { once: true }); 315 v.addEventListener("loadeddata", reveal, { once: true }); 316 v.addEventListener("playing", reveal, { once: true }); 317 v.addEventListener("error", (e) => console.error("[bh-hero] video error", e)); 318 319 requestAnimationFrame(() => { 320 holder.appendChild(v); 321 v.src = mp4; 322 }); 323 324 setTimeout(() => { 325 if (getComputedStyle(v).opacity === "0") reveal(); 326 }, 1800); 327 328 built = true; 329 } 330 331 function init() { 332 const root = document.getElementById("bh-hero"); 333 if (!root) return; 334 335 if ("IntersectionObserver" in window) { 336 const io = new IntersectionObserver((entries) => { 337 if (entries[0].isIntersecting) { 338 build(); 339 io.disconnect(); 340 } 341 }, { rootMargin: "400px" }); 342 io.observe(root); 343 } 344 345 if (inViewport(root)) build(); 346 347 const onScroll = () => { if (inViewport(root)) build(); }; 348 window.addEventListener("scroll", onScroll, { passive: true }); 349 window.addEventListener("resize", onScroll, { passive: true }); 350 351 setTimeout(build, 1200); 352 } 353 354 if (document.readyState === "loading") { 355 document.addEventListener("DOMContentLoaded", init); 356 } else { 357 init(); 358 } 359 })(); 360 361 /* ---------- 9) reCAPTCHA lazy loader ---------- */ 362 (function () { 363 var loaded = false; 364 var srcV2or3 = null; 365 366 function inferRecaptchaSrc() { 367 return "https://www.gstatic.com/recaptcha/releases/naPR4A6FAh-yZLuCX253WaZq/recaptcha__en.js"; 368 } 369 370 function loadRecaptcha() { 371 if (loaded) return; 372 loaded = true; 373 if (!srcV2or3) srcV2or3 = inferRecaptchaSrc(); 374 loadScript(srcV2or3).catch(function(){ loaded = false; }); 375 } 376 377 function watchForms() { 378 var candidates = document.querySelectorAll( 379 ".wpforms-form, form[action*='wpforms'], .g-recaptcha, [data-recaptcha], .wpcf7-form" 380 ); 381 if (!candidates.length) return; 382 383 if ("IntersectionObserver" in window) { 384 var io = new IntersectionObserver(function (entries) { 385 entries.forEach(function (e) { 386 if (e.isIntersecting) { loadRecaptcha(); io.disconnect(); } 387 }); 388 }, { rootMargin: "300px" }); 389 390 candidates.forEach(function (el) { io.observe(el); }); 391 } 392 393 ["click", "focusin", "touchstart"].forEach(function (evt) { 394 document.addEventListener(evt, loadRecaptcha, { once: true, passive: true }); 395 }); 396 397 onIdle(loadRecaptcha, 3000); 398 } 399 400 $(function(){ watchForms(); }); 401 })(); 402 403 /* ---------- ready ---------- */ 404 $(function () { 405 flagLearnMoreButtons(); 406 tidyDOM(); 407 // bindAccordion(); 408 if ($(".scrolling-wrap").length) onIdle(setupScrolling, 500); 409 onIdle(initSlickWhenVisible, 400); 410 decorateMenu(); 411 }); 412 413 /* ---------- AIR DEMO MODAL ---------- */ 414 function initAirDemoModal() { 415 var $trigger = $(".air-demo-trigger"); 416 var $modal = $(".air-demo-modal"); 417 418 if (!$trigger.length || !$modal.length) return; 419 420 $trigger.on("click", function (e) { 421 e.preventDefault(); 422 $modal.css("display", "flex"); 423 $("body").addClass("air-demo-open"); 424 }); 425 426 $(document).on("click", ".air-demo-close", function () { 427 $modal.hide(); 428 $("body").removeClass("air-demo-open"); 429 }); 430 431 $modal.on("click", function (e) { 432 if ($(e.target).closest(".wpforms-container, .air-demo-close").length) return; 433 $modal.hide(); 434 $("body").removeClass("air-demo-open"); 435 }); 436 437 $(document).on("keydown", function (e) { 438 if (e.key === "Escape") { 439 $modal.hide(); 440 $("body").removeClass("air-demo-open"); 441 } 442 }); 443 } 444 445 /* ---------- ready ---------- */ 446 $(function () { 447 flagLearnMoreButtons(); 448 tidyDOM(); 449 // bindAccordion(); 450 if ($(".scrolling-wrap").length) onIdle(setupScrolling, 500); 451 onIdle(initSlickWhenVisible, 400); 452 decorateMenu(); 453 454 initAirDemoModal(); 455 }); 456 457})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.