1/* JS for preset "Menu Hamburger" */ 2(function() { 3 $(function() { 4 $('.menu-wrapper-hamburger').each(function() { 5 initMenu($(this)) 6 }); 7 }); 8 9 // Make :active pseudo classes work on iOS 10 document.addEventListener("touchstart", function() {}, false); 11 12 var initMenu = function($menuWrapper) { 13 var $body = $('body'); 14 var $menu = $('.ed-menu', $menuWrapper); 15 var $hamburgerMenu = $('.hamburger-menu', $menuWrapper); 16 var $menuLinks = $('a', $menu); 17 var $menuTrigger = $('.menu-trigger-hamburger', $menuWrapper); 18 var $banner = $('.banner').first(); 19 20 var menuWrapperHeight = $menuWrapper.outerHeight(); 21 var bannerHeight = $banner.length ? $banner.outerHeight() : 0; 22 var smoothScrollOffset = 20; 23 24 toggleClassOnClick($body.add($hamburgerMenu), $menuTrigger, null, 'open open-menu-hamburger'); // Keep open on $menu for backward compatibility 25 activateSmoothScroll($menuLinks.add($('.scroll a')), smoothScrollOffset); 26 addClassOnVisibleLinkTargets($menuLinks, 'active', 2 / 3); 27 handleSticky($menuWrapper, 'sticky', $banner); 28 }; 29 30 /** 31 * Observe element's height changes and reload the initMenu() function 32 * 33 * @param {HTMLElement} elm Element to observe 34 * @param {function} callback to call when elmement's height changed 35 */ 36 var observeHeightChange = function(elm, callback) { 37 if (!('ResizeObserver' in window) || elm == null) return; 38 39 var ro = new ResizeObserver(callback); 40 ro.observe(elm); 41 } 42 43 /** 44 * Toggles class on a target when a trigger is clicked 45 * 46 * @param {jQuery} $target The target to apply the CSS class to 47 * @param {jQuery} $trigger The Trigger 48 * @param {jQuery} $closeTrigger Optional close trigger 49 * @param {string} cssClass CSS Class to toggle on the target 50 */ 51 var toggleClassOnClick = function($target, $trigger, $closeTrigger, cssClass) { 52 53 // Reset in case class "open" was saved accidentally 54 $target.removeClass(cssClass); 55 $trigger.removeClass(cssClass); 56 57 // Click on trigger toggles class "open" 58 $trigger.off('.toggle').on('click.toggle', function() { 59 $(this).toggleClass(cssClass); 60 $target.toggleClass(cssClass); 61 }); 62 63 // Close target when link inside is clicked 64 $target.find('a').click(function() { 65 $target.removeClass(cssClass); 66 $trigger.removeClass(cssClass); 67 }); 68 69 if (!$closeTrigger || !$closeTrigger.length) { 70 return; 71 } 72 73 $closeTrigger.click(function() { 74 $target.removeClass(cssClass); 75 $trigger.removeClass(cssClass); 76 }); 77 }; 78 79 /** 80 * Smooth scroll to link targets 81 * 82 * @param {jQuery} $scrollLinks The links 83 * @param {jQuery} scrollOffset Offset to subtract from the scroll target position (e.g. for fixed positioned elements like a menu) 84 */ 85 var activateSmoothScroll = function($scrollLinks, scrollOffset) { 86 if (typeof scrollOffset === 'undefined') { 87 scrollOffset = 0; 88 } 89 90 var determineTarget = function($trigger, hash) { 91 if (hash == '#!next') { 92 return $trigger.closest('.ed-element').next(); 93 } 94 95 return $(hash); 96 } 97 98 $scrollLinks.click(function(e) { 99 var $target = determineTarget($(this), this.hash); 100 if (!$target.length) return; 101 e.preventDefault(); 102 103 viewport.scrollTo($target, 'top', 500, 0); 104 105 }); 106 }; 107 108 /** 109 * We are using the fill property on an element to pass user's choices from CSS to JavaScript 110 * 111 * @param {jQuery} $element 112 */ 113 var getStickyMode = function($element) { 114 var fillValue = getComputedStyle($element[0]).fill; 115 116 return fillValue === 'rgb(255, 0, 0)' ? 117 'sticky_banner' : 118 fillValue === 'rgb(0, 255, 0)' ? 119 'sticky_menu' : 120 fillValue === 'rgb(0, 0, 255)' ? 121 'sticky_instant' : 122 fillValue === 'rgb(255, 255, 255)' ? 123 'sticky_reverse' : 124 'sticky_none'; 125 }; 126 127 /** 128 * Adds a class to an element when not currently visible 129 * 130 * @param {jQuery} $element The element to handle stickyness for 131 * @param {string} cssClass The actual CSS class to be applied to the element when it's above a certain scroll position 132 * @param {jQuery} $banner A banner to reference the scroll position to 133 */ 134 var handleSticky = function($element, cssClass, $banner) { 135 var triggerPos = 0, 136 offset = 0; 137 var menuWrapperHeight = $element.outerHeight(); 138 var mode; 139 var prevScroll = 0; 140 $element.removeClass(cssClass); 141 142 var toggleSpacer = function(toggle) { 143 document.body.style.setProperty('--spacer-height', toggle ? menuWrapperHeight + 'px' : ''); 144 }; 145 146 var handleScroll = function() { 147 if (!$element.length || mode === 'sticky_none') return; 148 149 var isReverse = mode === 'sticky_reverse', 150 curScroll = viewport.getScrollTop(); 151 152 if (triggerPos <= curScroll && (!isReverse || prevScroll > curScroll)) { 153 $element.addClass(cssClass); 154 toggleSpacer(true); 155 } else { 156 $element.removeClass(cssClass); 157 toggleSpacer(false); 158 } 159 160 prevScroll = curScroll; 161 }; 162
163 var updateOffset = function() { 164 mode = getStickyMode($element); 165 menuWrapperHeight = $element.outerHeight(); 166 if (!$element.hasClass(cssClass)) { 167 offset = $element.offset().top; 168 } 169 if (mode === 'sticky_banner' && !$banner.length) { 170 mode = 'sticky_menu'; 171 } 172 if (mode === 'sticky_banner') { 173 triggerPos = $banner.offset().top + ($banner.length ? $banner.outerHeight() : $element.outerHeight()); 174 } 175 if (mode === 'sticky_menu' || mode === 'sticky_reverse') { 176 triggerPos = offset + $element.outerHeight(); 177 } 178 if (mode === 'sticky_instant') { 179 triggerPos = offset; 180 } 181 182 handleScroll(); 183 } 184 185 viewport.observe('resize', updateOffset); 186 viewport.observe('animation.end', updateOffset); 187 observeHeightChange($element[0], updateOffset); 188 updateOffset(); 189 190 viewport.observe('scroll', handleScroll); 191 handleScroll(); 192 }; 193 194 /** 195 * Adds a class to links whose target is currently inside the viewport 196 * 197 * @param {jQuery} $links Link(s) to be observed 198 * @param {string} cssClass CSS Class to be applied 199 * @param {float} sectionViewportRatio Ratio by which the target should be within the viewport 200 */ 201 var addClassOnVisibleLinkTargets = function($links, cssClass, sectionViewportRatio) { 202 if (typeof sectionViewportRatio === 'undefined') { 203 sectionViewportRatio = 1 / 2; 204 } 205 206 var menuTargets = []; 207 var activeLink = $links.filter('.active:not(.wv-link-elm)').eq(0); 208 209 var links = $links.filter(function() { 210 var $target = $(this.hash); 211 if (!$target.length) { 212 return false; 213 } 214 215 // Cache offset position to improve performance (update on resize) 216 var updateOffset = function() { 217 $target.data('offset', $target.offset().top); 218 }; 219 220 viewport.observe('resize', updateOffset); 221 viewport.observe('animation.end', updateOffset); 222 updateOffset(); 223 224 menuTargets.push($target); 225 return true; 226 }); 227 228 // No hash links found, so don't handle it at all 229 if (!links.length) { 230 return; 231 } 232 233 var checkVisibility = function() { 234 $links.removeClass('active'); 235 236 // Check section position reversely 237 for (var i = menuTargets.length - 1; i >= 0; i--) { 238 var desiredScrollPosition = menuTargets[i].data('offset') - viewport.getHeight() * (1 - sectionViewportRatio); 239 if (viewport.getScrollTop() >= desiredScrollPosition && menuTargets[i][0].offsetParent !== null) { 240 links.eq(i).addClass(cssClass); 241 return; 242 } 243 } 244 245 // Fallback to originally active item 246 activeLink.addClass(cssClass); 247 }; 248 249 viewport.observe('scroll', checkVisibility); 250 checkVisibility(); 251 }; 252})(); 253/* End JS for preset "Menu Hamburger" */ 254 255/* JS for preset "Menu V2" */ 256(function() { 257 $(function() { 258 $('.menu-wrapper').each(function() { 259 initMenu($(this)) 260 }); 261 }); 262 263 // Make :active pseudo classes work on iOS 264 document.addEventListener("touchstart", function() {}, false); 265 266 var initMenu = function($menuWrapper) { 267 var $body = $('body'); 268 var $menu = $('.ed-menu', $menuWrapper); 269 var $menuLinks = $('a', $menu); 270 var $menuTrigger = $('.menu-trigger', $menuWrapper); 271 var $banner = $('.banner').first(); 272 273 var menuWrapperHeight = $menuWrapper.outerHeight(); 274 var bannerHeight = $banner.length ? $banner.outerHeight() : 0; 275 var smoothScrollOffset = 20; 276 277 toggleClassOnClick($body.add($menu), $menuTrigger, null, 'open open-menu'); // Keep open on $menu for backward compatibility 278 activateSmoothScroll($menuLinks.add($('.scroll a')), smoothScrollOffset); 279 addClassOnVisibleLinkTargets($menuLinks, 'active', 2 / 3); 280 handleSticky($menuWrapper, 'sticky', $banner); 281 }; 282 283 /** 284 * Observe element's height changes and reload the initMenu() function 285 * 286 * @param {HTMLElement} elm Element to observe 287 * @param {function} callback to call when elmement's height changed 288 */ 289 var observeHeightChange = function(elm, callback) { 290 if (!('ResizeObserver' in window) || elm == null) return; 291 292 var ro = new ResizeObserver(callback); 293 ro.observe(elm); 294 } 295 296 /** 297 * Toggles class on a target when a trigger is clicked 298 * 299 * @param {jQuery} $target The target to apply the CSS class to 300 * @param {jQuery} $trigger The Trigger 301 * @param {jQuery} $closeTrigger Optional close trigger 302 * @param {string} cssClass CSS Class to toggle on the target 303 */ 304 var toggleClassOnClick = function($target, $trigger, $closeTrigger,
304cssClass) { 305 306 // Reset in case class "open" was saved accidentally 307 $target.removeClass(cssClass); 308 $trigger.removeClass(cssClass); 309 310 // Click on trigger toggles class "open" 311 $trigger.off('.toggle').on('click.toggle', function() { 312 $(this).toggleClass(cssClass); 313 $target.toggleClass(cssClass); 314 }); 315 316 // Close target when link inside is clicked 317 $target.find('a').click(function() { 318 $target.removeClass(cssClass); 319 $trigger.removeClass(cssClass); 320 }); 321 322 if (!$closeTrigger || !$closeTrigger.length) { 323 return; 324 } 325 326 $closeTrigger.click(function() { 327 $target.removeClass(cssClass); 328 $trigger.removeClass(cssClass); 329 }); 330 }; 331 332 /** 333 * Smooth scroll to link targets 334 * 335 * @param {jQuery} $scrollLinks The links 336 * @param {jQuery} scrollOffset Offset to subtract from the scroll target position (e.g. for fixed positioned elements like a menu) 337 */ 338 var activateSmoothScroll = function($scrollLinks, scrollOffset) { 339 if (typeof scrollOffset === 'undefined') { 340 scrollOffset = 0; 341 } 342 343 var determineTarget = function($trigger, hash) { 344 if (hash == '#!next') { 345 return $trigger.closest('.ed-element').next(); 346 } 347 348 return $(hash); 349 } 350 351 $scrollLinks.click(function(e) { 352 var $target = determineTarget($(this), this.hash); 353 if (!$target.length) return; 354 e.preventDefault(); 355 356 viewport.scrollTo($target, 'top', 500, 0); 357 358 }); 359 }; 360 361 /** 362 * We are using the fill property on an element to pass user's choices from CSS to JavaScript 363 * 364 * @param {jQuery} $element 365 */ 366 var getStickyMode = function($element) { 367 var fillValue = getComputedStyle($element[0]).fill; 368 369 return fillValue === 'rgb(255, 0, 0)' ? 370 'sticky_banner' : 371 fillValue === 'rgb(0, 255, 0)' ? 372 'sticky_menu' : 373 fillValue === 'rgb(0, 0, 255)' ? 374 'sticky_instant' : 375 fillValue === 'rgb(255, 255, 255)' ? 376 'sticky_reverse' : 377 'sticky_none'; 378 }; 379 380 /** 381 * Adds a class to an element when not currently visible 382 * 383 * @param {jQuery} $element The element to handle stickyness for 384 * @param {string} cssClass The actual CSS class to be applied to the element when it's above a certain scroll position 385 * @param {jQuery} $banner A banner to reference the scroll position to 386 */ 387 var handleSticky = function($element, cssClass, $banner) { 388 var triggerPos = 0, 389 offset = 0; 390 var menuWrapperHeight = $element.outerHeight(); 391 var mode; 392 var prevScroll = 0; 393 $element.removeClass(cssClass); 394 395 var toggleSpacer = function(toggle) { 396 document.body.style.setProperty('--spacer-height', toggle ? menuWrapperHeight + 'px' : ''); 397 }; 398 399 var handleScroll = function() { 400 if (!$element.length || mode === 'sticky_none') return; 401 402 var isReverse = mode === 'sticky_reverse', 403 curScroll = viewport.getScrollTop(); 404 405 if (triggerPos <= curScroll && (!isReverse || prevScroll > curScroll)) { 406 $element.addClass(cssClass); 407 toggleSpacer(true); 408 } else { 409 $element.removeClass(cssClass); 410 toggleSpacer(false); 411 } 412 413 prevScroll = curScroll; 414 }; 415 416 var updateOffset = function() { 417 mode = getStickyMode($element); 418 menuWrapperHeight = $element.outerHeight(); 419 if (!$element.hasClass(cssClass)) { 420 offset = $element.offset().top; 421 } 422 if (mode === 'sticky_banner' && !$banner.length) { 423 mode = 'sticky_menu'; 424 } 425 if (mode === 'sticky_banner') { 426 triggerPos = $banner.offset().top + ($banner.length ? $banner.outerHeight() : $element.outerHeight()); 427 } 428 if (mode === 'sticky_menu' || mode === 'sticky_reverse') { 429 triggerPos = offset + $element.outerHeight(); 430 } 431 if (mode === 'sticky_instant') { 432 triggerPos = offset; 433 } 434 435 handleScroll(); 436 } 437 438 viewport.observe('resize', updateOffset); 439 viewport.observe('animation.end', updateOffset); 440 observeHeightChange($element[0], updateOffset); 441 updateOffset(); 442 443 viewport.observe('scroll', handleScroll); 444 handleScroll(); 445 }; 446 447 /** 448 * Adds a class to links whose target is currently inside the viewport 449 * 450 * @param {jQuery} $links Link(s) to be observed 451 * @param {string} cssClass CSS Class to be applied 452 * @param {float} sectionViewportRatio Ratio by which the target should be within the viewport 453 */ 454 var addClassOnVisibleLinkTargets = function($links, cssClass, sectionViewportRatio) { 455 if (typeof sectionViewportRatio === 'undefined') { 456 sectionViewportRatio = 1 / 2; 457 } 458 459 var menuTargets = []; 460 var activeLink = $links.filter('.active:not(.wv-link-elm)').eq(0); 461 462 var links = $links.filter(function() { 463 var $target = $(this.hash); 464 if (!$target.length) { 465 return false;
466 } 467 468 // Cache offset position to improve performance (update on resize) 469 var updateOffset = function() { 470 $target.data('offset', $target.offset().top); 471 }; 472 473 viewport.observe('resize', updateOffset); 474 viewport.observe('animation.end', updateOffset); 475 updateOffset(); 476 477 menuTargets.push($target); 478 return true; 479 }); 480 481 // No hash links found, so don't handle it at all 482 if (!links.length) { 483 return; 484 } 485 486 var checkVisibility = function() { 487 $links.removeClass('active'); 488 489 // Check section position reversely 490 for (var i = menuTargets.length - 1; i >= 0; i--) { 491 var desiredScrollPosition = menuTargets[i].data('offset') - viewport.getHeight() * (1 - sectionViewportRatio); 492 if (viewport.getScrollTop() >= desiredScrollPosition && menuTargets[i][0].offsetParent !== null) { 493 links.eq(i).addClass(cssClass); 494 return; 495 } 496 } 497 498 // Fallback to originally active item 499 activeLink.addClass(cssClass); 500 }; 501 502 viewport.observe('scroll', checkVisibility); 503 checkVisibility(); 504 }; 505})(); 506/* End JS for preset "Menu V2" */ 507 508/* JS for preset "Back to top button V3" */ 509(function() { 510 var initBackToTop = function() { 511 var $button = $('.back-to-top-button-icon'); 512 513 clickToTop($button); 514 515 // Show back to top only below the fold 516 viewport.observe('scroll', function() { 517 if (viewport.getScrollTop() > (viewport.getHeight() / 3)) { 518 $button.addClass('show'); 519 } else { 520 $button.removeClass('show'); 521 } 522 }); 523 }; 524 525 var clickToTop = function($trigger) { 526 $trigger.removeClass('show'); 527 528 $trigger.click(function(e) { 529 e.preventDefault(); 530 viewport.scrollTo(0, 'top', 500, 0); 531 }); 532 }; 533 534 $(initBackToTop); 535})(); 536/* End JS for preset "Back to top button V3" */ 537 538/* JS for preset "Cookie Consent Bar V3" */ 539$(function() { 540 $('#cookieClose').click(function(e) { 541 e.preventDefault(); 542 createCookie('cookieConsentBar', "rejected", 0.5); 543 $('.cookie-consent-bar').hide(); 544 545 // If inside of an overlay, close it too 546 if ($('.cookie-consent-bar').closest('.mfp-content').length) { 547 $.magnificPopup.close(); 548 return; 549 } 550 }); 551 552 $('#acceptCookie').click(function(e) { 553 e.preventDefault(); 554 createCookie('cookieConsentBar', "accepted", 0.5); 555 $('.cookie-consent-bar').hide(); 556 557 if (typeof ThirdPartyScripts !== "undefined") { 558 ThirdPartyScripts.unblock(); 559 } 560 561 // If inside of an overlay, close it too 562 if ($('.cookie-consent-bar').closest('.mfp-content').length) { 563 $.magnificPopup.close(); 564 return; 565 } 566 }); 567 568 var preview = false; 569 570 var listener = function() { 571 if (!preview && document.body.classList.contains('preview')) { 572 console.log("entering preview"); 573 preview = true; 574 } else if (preview && !document.body.classList.contains('preview')) { 575 console.log("leaving preview"); 576 $('.cookie-consent-bar').show(); 577 preview = false; 578 } 579 requestAnimationFrame(listener); 580 }; 581 582 requestAnimationFrame(listener); 583 584 if (document.body.classList.contains('edit') || document.body.classList.contains('preview')) { 585 return; 586 } 587 588 589 // Cookie bar 590 if (readCookie('cookieConsentBar') == "accepted") { 591 $('.cookie-consent-bar').hide(); 592 window.setTimeout(function() { 593 if (typeof ThirdPartyScripts !== "undefined") { 594 ThirdPartyScripts.unblock(); 595 } 596 }, 100); 597 } else if (readCookie('cookieConsentBar') == "rejected") { 598 $('.cookie-consent-bar').hide(); 599 } else { 600 $('.cookie-consent-bar').show(); 601 } 602 603 function readCookie(name) { 604 var nameEQ = name + "="; 605 var ca = document.cookie.split(';'); 606 for (var i = 0; i < ca.length; i++) { 607 var c = ca[i]; 608 while (c.charAt(0) == ' ') c = c.substring(1, c.length); 609 if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); 610 } 611 return null; 612 } 613 614 function createCookie(name, value, days) { 615 if (days) { 616 var date = new Date(); 617 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 618 var expires = "; expires=" + date.toGMTString(); 619 } else expires = ""; 620 document.cookie = name + "=" + value + expires + "; path=/"; 621 } 622 623 // Fix for hiding Content till page is loaded 624 $(document).ready(function() { 625 $('.hide-cookie-content').removeClass("hide-cookie-content"); 626 }); 627}); 628/* End JS for preset "Cookie Consent Bar V3" */
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.