1jQuery(function () { 2 initDropDownClasses() 3 initCustomHover() 4 initAccordion() 5 initBackgroundVideo() 6 initSelectDropdown() 7 initDetectResize() 8 initTabNav() 9 initAnchors() 10}) 11 12jQuery(window).on('load', function () { 13 initFixedScrollBlock() 14}) 15 16// initialize smooth anchor links 17function initAnchors() { 18 new SmoothScroll({ 19 anchorLinks: '[data-smooth-anchor]', 20 extraOffset: function () { 21 var totalHeight = 0 22 jQuery('#header').each(function () { 23 var $box = jQuery(this) 24 var stickyInstance = $box.data('StickyScrollBlock') 25 if (stickyInstance) { 26 stickyInstance.stickyFlag = false 27 stickyInstance.stickyOn() 28 totalHeight += $box.outerHeight() 29 stickyInstance.onResize() 30 } else { 31 totalHeight += 32 $box.css('position') === 'fixed' ? $box.outerHeight() : 0 33 } 34 }) 35 return totalHeight 36 }, 37 activeClasses: 'link', 38 wheelBehavior: 'none', 39 }) 40} 41 42// "tab" key handling 43function initTabNav() { 44 jQuery('[data-nav-list]').tabNav({ 45 items: 'li', 46 }) 47} 48 49function initDetectResize() { 50 jQuery(window).on('resize orientationchange', function () { 51 var body = jQuery('body') 52 var resizeActiveClass = 'resize-active' 53 54 body.addClass(resizeActiveClass) 55 setTimeout(function () { 56 body.removeClass(resizeActiveClass) 57 }, 500) 58 }) 59} 60 61function initSelectDropdown() { 62 var selectDropdown = jQuery('[data-select-dropdown]') 63 64 selectDropdown.each(function () { 65 var select = jQuery(this) 66 var selectPicker = select.find('[data-select-picker]') 67 var selectList = select.find('[data-select-list]') 68 var selectListItem = jQuery(selectList).find('li') 69 70 selectListItem.each(function () { 71 var item = jQuery(this) 72 73 item.on('click', function (e) { 74 e.preventDefault() 75 var title = item.text() 76 selectPicker.html(title) 77 }) 78 }) 79 }) 80} 81 82// background video init
83function initBackgroundVideo() { 84 jQuery('.bg-video').backgroundVideo({ 85 activeClass: 'video-active', 86 holder: '.bg-video-holder', 87 }) 88} 89 90// initialize fixed blocks on scroll 91function initFixedScrollBlock() { 92 var win = jQuery(window) 93 var scrolledClass = 'is-sticky' 94 var extraOffset = 0 //class appear after this top value 95 96 jQuery('[data-sticky-header]').each(function () { 97 var header = jQuery(this) 98 var isScrolled = false 99 100 scrollHandler() 101 win.on('resize orientationchange scroll', scrollHandler) 102 103 function scrollHandler() { 104 if (win.scrollTop() > extraOffset) { 105 if (!isScrolled) { 106 header.addClass(scrolledClass) 107 isScrolled = true 108 } 109 } else if (isScrolled) { 110 header.removeClass(scrolledClass) 111 isScrolled = false 112 } 113 } 114 }) 115} 116 117// accordion menu init 118function initAccordion() { 119 ResponsiveHelper.addRange({ 120 '..1023': { 121 on: function () { 122 jQuery('[data-nav-list]').slideAccordion({ 123 opener: '.has-drop-down-a', 124 slider: '>[data-dropdown]', 125 animSpeed: 300, 126 }) 127 128 jQuery('[data-nav-list-inner]').slideAccordion({ 129 opener: '.has-drop-down-a-inner', 130 slider: '>[data-dropdown-inner]', 131 animSpeed: 300, 132 }) 133 }, 134 off: function () { 135 jQuery('[data-nav-list]').slideAccordion('destroy') 136 jQuery('[data-nav-list-inner]').slideAccordion('destroy') 137 }, 138 }, 139 }) 140} 141 142// add classes if item has dropdown
143function initDropDownClasses() { 144 jQuery('[data-nav-list] > li').each(function () { 145 var item = jQuery(this) 146 var drop = item.find('[data-dropdown]') 147 var link = item.find('a').eq(0) 148 if (drop.length) { 149 item.addClass('has-drop-down') 150 if (link.length) link.addClass('has-drop-down-a') 151 } 152 }) 153 154 jQuery('[data-nav-list-inner] > li').each(function () { 155 var item = jQuery(this) 156 var drop = item.find('[data-dropdown-inner]') 157 var link = item.find('a').eq(0) 158 if (drop.length) { 159 item.addClass('has-drop-down-inner') 160 if (link.length) link.addClass('has-drop-down-a-inner') 161 } 162 }) 163} 164 165// add classes on hover/touch 166function initCustomHover() { 167 ResponsiveHelper.addRange({ 168 '768..': { 169 on: function () { 170 jQuery('[data-nav-list]>li>a').touchHover() 171 jQuery('[data-nav-list-inner]>li>a').touchHover() 172 }, 173 }, 174 }) 175} 176 177/* 178 * jQuery Accordion plugin new 179 */ 180;(function (root, factory) { 181 'use strict' 182 if (typeof define === 'function' && define.amd) { 183 define(['jquery'], factory) 184 } else if (typeof exports === 'object') { 185 module.exports = factory(require('jquery')) 186 } else { 187 root.SlideAccordion = factory(jQuery) 188 } 189})(this, function ($) { 190 'use strict' 191 var accHiddenClass = 'js-acc-hidden' 192 193 function SlideAccordion(options) { 194 this.options = $.extend( 195 true, 196 { 197 allowClickWhenExpanded: false, 198 activeClass: 'active', 199 opener: '.opener', 200 slider: '.slide', 201 animSpeed: 300, 202 collapsible: true, 203 event: 'click', 204 scrollToActiveItem: { 205 enable: false, 206 breakpoint: 767, // max-width 207 animSpeed: 600, 208 extraOffset: null, 209 }, 210 }, 211 options 212 ) 213 this.init() 214 } 215 216 SlideAccordion.prototype = { 217 init: function () { 218 if (this.options.holder) { 219 this.findElements() 220 this.setStateOnInit() 221 this.attachEvents() 222 this.makeCallback('onInit') 223 } 224 }, 225 226 findElements: function () { 227 this.$holder = $(this.options.holder).data('SlideAccordion', this) 228 this.$items = this.$holder.find(':has(' + this.options.slider + ')') 229 }, 230 231 setStateOnInit: function () { 232 var self = this 233 234 this.$items.each(function () { 235 if (!$(this).hasClass(self.options.activeClass)) { 236 $(this).find(self.options.slider).addClass(accHiddenClass) 237 } 238 }) 239 }, 240 241 attachEvents: function () { 242 var self = this 243 244 this.accordionToggle = function (e) { 245 var $item = jQuery(this).closest(self.$items) 246 var $actiItem = self.getActiveItem($item) 247 248 if ( 249 !self.options.allowClickWhenExpanded || 250 !$item.hasClass(self.options.activeClass) 251 ) { 252 e.preventDefault() 253 self.toggle($item, $actiItem) 254 } 255 } 256 257 this.$items.on( 258 this.options.event, 259 this.options.opener, 260 this.accordionToggle 261 ) 262 }, 263 264 toggle: function ($item, $prevItem) { 265 if (!$item.hasClass(this.options.activeClass)) { 266 this.show($item) 267 } else if (this.options.collapsible) { 268 this.hide($item) 269 } 270 271 if (!$item.is($prevItem) && $prevItem.length) { 272 this.hide($prevItem) 273 } 274 275 this.makeCallback('beforeToggle') 276 }, 277 278 show: function ($item) { 279 var $slider = $item.find(this.options.slider) 280 281 $item.addClass(this.options.activeClass) 282 $slider 283 .stop() 284 .hide() 285 .removeClass(accHiddenClass) 286 .slideDown({ 287 duration: this.options.animSpeed, 288 complete: function () { 289 $slider.removeAttr('style') 290 if ( 291 this.options.scrollToActiveItem.enable && 292 window.innerWidth <= this.options.scrollToActiveItem.breakpoint 293 ) { 294 this.goToItem($item) 295 } 296 this.makeCallback('onShow', $item) 297 }.bind(this), 298 }) 299 300 this.makeCallback('beforeShow', $item) 301 }, 302 303 hide: function ($item) { 304 var $slider = $item.find(this.options.slider) 305 306 $item.removeClass(this.options.activeClass) 307 $slider 308 .stop() 309 .show() 310 .slideUp({ 311 duration: this.options.animSpeed, 312 complete: function () { 313 $slider.addClass(accHiddenClass) 314 $slider.removeAttr('style') 315 this.makeCallback('onHide', $item) 316 }.bind(this), 317 }) 318 319 this.makeCallback('beforeHide', $item) 320 }, 321 322 goToItem: function ($item) { 323 var itemOffset = $item.offset().top 324 325 if (itemOffset < $(window).scrollTop()) { 326 // handle extra offset 327 if (typeof this.options.scrollToActiveItem.extraOffset === 'number') { 328 itemOffset -= this.options.scrollToActiveItem.extraOffset 329 } else if ( 330 typeof this.options.scrollToActiveItem.extraOffset === 'function' 331 ) { 332 itemOffset -= this.options.scrollToActiveItem.extraOffset() 333 } 334 335 $('body, html').animate( 336 { 337 scrollTop: itemOffset, 338 }, 339 this.options.scrollToActiveItem.animSpeed 340 ) 341 } 342 }, 343 344 getActiveItem: function ($item) { 345 return $item.siblings().filter('.' + this.options.activeClass) 346 }, 347 348 makeCallback: function (name) { 349 if (typeof this.options[name] === 'function') { 350 var args = Array.prototype.slice.call(arguments) 351 args.shift() 352 this.options[name].apply(this, args) 353 } 354 }, 355 356 destroy: function () { 357 this.$holder.removeData('SlideAccordion') 358 this.$items.off( 359 this.options.event, 360 this.options.opener, 361 this.accordionToggle 362 ) 363 this.$items.removeClass(this.options.activeClass).each( 364 function (i, item) { 365 $(item) 366 .find(this.options.slider) 367 .removeAttr('style') 368 .removeClass(accHiddenClass) 369 }.bind(this) 370 ) 371 this.makeCallback('onDestroy') 372 }, 373 } 374 375 $.fn.slideAccordion = function (opt) { 376 var args = Array.prototype.slice.call(arguments) 377 var method = args[0] 378 379 return this.each(function () { 380 var $holder = jQuery(this) 381 var instance = $holder.data('SlideAccordion') 382 383 if (typeof opt === 'object' || typeof opt === 'undefined') { 384 new SlideAccordion( 385 $.extend( 386 true, 387 { 388 holder: this, 389 }, 390 opt 391 ) 392 ) 393 } else if (typeof method === 'string' && instance) { 394 if (typeof instance[method] === 'function') { 395 args.shift() 396 instance[method].apply(instance, args) 397 } 398 } 399 }) 400 } 401 ;(function () { 402 var tabStyleSheet = $('<style type="text/css">')[0] 403 var tabStyleRule = '.' + accHiddenClass 404 tabStyleRule += 405 '{position:absolute !important;left:-9999px !important;top:-9999px !important;display:block !important; width: 100% !important;}' 406 if (tabStyleSheet.styleSheet) { 407 tabStyleSheet.styleSheet.cssText = tabStyleRule 408 } else { 409 tabStyleSheet.appendChild(document.createTextNode(tabStyleRule)) 410 } 411 $('head').append(tabStyleSheet) 412 })() 413 414 return SlideAccordion 415}) 416 417/* 418 * Mobile hover plugin 419 */ 420;(function ($) { 421 var doc = jQuery(document) 422 // detect device type 423 var isTouchDevice = 424 'ontouchstart' in window || 425 (window.DocumentTouch && document instanceof DocumentTouch), 426 isWinPhoneDevice = /Windows Phone/.test(navigator.userAgent) 427 428 // define events 429 var eventOn = 430 (isTouchDevice && 'touchstart') || 431 (isWinPhoneDevice && navigator.pointerEnabled && 'pointerdown') || 432 (isWinPhoneDevice && navigator.msPointerEnabled && 'MSPointerDown') || 433 'mouseenter', 434 eventOff = 435 (isTouchDevice && 'touchend') || 436 (isWinPhoneDevice && navigator.pointerEnabled && 'pointerup') || 437 (isWinPhoneDevice && navigator.msPointerEnabled && 'MSPointerUp') || 438 'mouseleave' 439 440 isTouchDevice = 441 /Windows Phone/.test(navigator.userAgent) || 442 'ontouchstart' in window || 443 (window.DocumentTouch && document instanceof DocumentTouch) 444 445 function toggleClass(opt, e) { 446 var el = jQuery(e.currentTarget.parentElement) 447 448 if (!isTouchDevice) { 449 el.one(eventOff, function () { 450 jQuery(this).removeClass(opt.hoverClass) 451 jQuery('.header').removeClass('has-dropdown-active') 452 }) 453 } else { 454 if (!el.hasClass(opt.hoverClass)) { 455 jQuery(this).off('click.hover', function (e) { 456 e.preventDefault() 457 }) 458 setTimeout(function () { 459 doc.on(eventOn + '.hover', function (e) { 460 var target = jQuery(e.target) 461 if (!target.is(el) && !target.closest(el).length) { 462 el.removeClass(opt.hoverClass) 463 jQuery('.header').removeClass('has-dropdown-active') 464 jQuery(this).off('click.hover') 465 doc.off(eventOn + '.hover') 466 } 467 }) 468 }) 469 } 470 } 471 472 if (!el.hasClass(opt.hoverClass)) { 473 if (e) e.preventDefault() 474 el.addClass(opt.hoverClass) 475 jQuery('.header').addClass('has-dropdown-active') 476 } 477 } 478 479 // jQuery plugin 480 $.fn.touchHover = function (opt) { 481 var options = $.extend( 482 { 483 hoverClass: 'hover', 484 }, 485 opt 486 ) 487 488 this.on(eventOn, toggleClass.bind(this, options)) 489 return this 490 } 491})(jQuery) 492 493/* 494 * Responsive Layout helper 495 */ 496window.ResponsiveHelper = (function ($) { 497 // init variables 498 var handlers = [], 499 prevWinWidth, 500 win = $(window), 501 nativeMatchMedia = false 502 503 // detect match media support 504 if (window.matchMedia) { 505 if (window.Window && window.matchMedia === Window.prototype.matchMedia) { 506 nativeMatchMedia = true 507 } else if (window.matchMedia.toString().indexOf('native') > -1) { 508 nativeMatchMedia = true 509 } 510 } 511 512 // prepare resize handler 513 function resizeHandler() { 514 var winWidth = win.width() 515 if (winWidth !== prevWinWidth) { 516 prevWinWidth = winWidth 517 518 // loop through range groups 519 $.each(handlers, function (index, rangeObject) { 520 // disable current active area if needed 521 $.each(rangeObject.data, function (property, item) { 522 if (item.currentActive && !matchRange(item.range[0], item.range[1])) { 523 item.currentActive = false 524 if (typeof item.disableCallback === 'function') { 525 item.disableCallback() 526 } 527 } 528 }) 529 530 // enable areas that match current width 531 $.each(rangeObject.data, function (property, item) { 532 if (!item.currentActive && matchRange(item.range[0], item.range[1])) { 533 // make callback 534 item.currentActive = true 535 if (typeof item.enableCallback === 'function') { 536 item.enableCallback() 537 } 538 } 539 }) 540 }) 541 } 542 } 543 win.bind('load resize orientationchange', resizeHandler) 544 545 // test range 546 function matchRange(r1, r2) { 547 var mediaQueryString = '' 548 if (r1 > 0) { 549 mediaQueryString += '(min-width: ' + r1 + 'px)' 550 }
551 if (r2 < Infinity) { 552 mediaQueryString += 553 (mediaQueryString ? ' and ' : '') + '(max-width: ' + r2 + 'px)' 554 } 555 return matchQuery(mediaQueryString, r1, r2) 556 } 557 558 // media query function 559 function matchQuery(query, r1, r2) { 560 if (window.matchMedia && nativeMatchMedia) { 561 return matchMedia(query).matches 562 } else if (window.styleMedia) { 563 return styleMedia.matchMedium(query) 564 } else if (window.media) { 565 return media.matchMedium(query) 566 } else { 567 return prevWinWidth >= r1 && prevWinWidth <= r2 568 } 569 } 570 571 // range parser 572 function parseRange(rangeStr) { 573 var rangeData = rangeStr.split('..') 574 var x1 = parseInt(rangeData[0], 10) || -Infinity 575 var x2 = parseInt(rangeData[1], 10) || Infinity 576 return [x1, x2].sort(function (a, b) { 577 return a - b 578 }) 579 } 580 581 // export public functions 582 return { 583 addRange: function (ranges) { 584 // parse data and add items to collection 585 var result = { data: {} } 586 $.each(ranges, function (property, data) { 587 result.data[property] = { 588 range: parseRange(property), 589 enableCallback: data.on, 590 disableCallback: data.off, 591 } 592 }) 593 handlers.push(result) 594 595 // call resizeHandler to recalculate all events 596 prevWinWidth = null 597 resizeHandler() 598 }, 599 } 600})(jQuery) 601 602/* 603 * jQuery video background plugin 604 */ 605;(function ($, $win) { 606 var BgVideoController = (function () { 607 var videos = [] 608 609 return { 610 init: function () { 611 $win.on( 612 'load.bgVideo resize.bgVideo orientationchange.bgVideo', 613 this.resizeHandler.bind(this) 614 ) 615 }, 616 617 resizeHandler: function () { 618 if (this.isInit) { 619 $.each(videos, this.resizeVideo.bind(this)) 620 } 621 }, 622 623 buildPoster: function ($video, $holder) { 624 $holder.css({ 625 'background-image': 'url(' + $video.attr('poster') + ')', 626 'background-repeat': 'no-repeat', 627 'background-size': 'cover', 628 }) 629 }, 630 631 resizeVideo: function (i) { 632 var item = videos[i] 633 var styles = this.getDimensions({ 634 videoRatio: item.ratio, 635 maskWidth: item.$holder.outerWidth(), 636 maskHeight: item.$holder.outerHeight(), 637 }) 638 639 item.$video.css({ 640 width: styles.width, 641 height: styles.height, 642 marginTop: styles.top, 643 marginLeft: styles.left, 644 }) 645 }, 646 647 getRatio: function ($video) { 648 return ( 649 $video[0].videoWidth / $video[0].videoHeight || 650 $video.attr('width') / $video.attr('height') || 651 $video.width() / $video.height() 652 ) 653 }, 654 655 getDimensions: function (data) { 656 var ratio = data.videoRatio, 657 slideWidth = data.maskWidth, 658 slideHeight = slideWidth / ratio 659 660 if (slideHeight < data.maskHeight) { 661 slideHeight = data.maskHeight 662 slideWidth = slideHeight * ratio 663 } 664 return { 665 width: slideWidth, 666 height: slideHeight, 667 top: (data.maskHeight - slideHeight) / 2, 668 left: (data.maskWidth - slideWidth) / 2, 669 } 670 }, 671 672 add: function ($video, options) { 673 var $holder = options.videoHolder 674 ? $video.closest(options.videoHolder) 675 : $video.parent() 676 var item = { 677 $video: $video, 678 $holder: $holder, 679 options: options, 680 } 681 682 if ($video.attr('poster')) { 683 this.buildPoster($video, $holder) 684 } 685 686 if ($video[0].readyState) { 687 this.onVideoReady(item) 688 if ($video[0].paused) { 689 $video[0].play() 690 } else { 691 $holder.addClass(options.activeClass) 692 } 693 } else { 694 $video.one( 695 'loadedmetadata', 696 function () { 697 if ($video[0].paused) { 698 $video[0].play() 699 } else { 700 $holder.addClass(options.activeClass) 701 } 702 this.onVideoReady(item) 703 }.bind(this) 704 ) 705 } 706 707 $video.one( 708 'play', 709 function () { 710 $holder.addClass(options.activeClass) 711 this.makeCallback.apply($.extend(true, {}, this, item), ['onPlay']) 712 }.bind(this) 713 ) 714 715 this.makeCallback.apply($.extend(true, {}, this, item), ['onInit']) 716 return this 717 }, 718 719 onVideoReady: function (item) { 720 if (!this.isInit) { 721 this.isInit = true 722 this.init() 723 } 724 videos.push( 725 $.extend(item, { 726 ratio: this.getRatio(item.$video), 727 }) 728 ) 729 this.resizeVideo(videos.length - 1) 730 }, 731 732 destroy: function ($video) { 733 if (!$video) { 734 videos = videos.filter(this.destroySingle) 735 } else { 736 videos = videos.filter( 737 function (item) { 738 var removeFlag = item.$video.is($video) 739 740 removeFlag && this.destroySingle(item) 741 742 return !removeFlag 743 }.bind(this) 744 ) 745 } 746 747 if (!videos.length) { 748 this.isInit = false 749 $win.off('.bgVideo') 750 } 751 }, 752 753 destroySingle: function (item) {
754 item.$video.removeAttr('style').removeData('BackgroundVideo')[0].pause() 755 item.$holder.removeClass(item.options.activeClass) 756 }, 757 758 makeCallback: function (name) { 759 if (typeof this.options[name] === 'function') { 760 var args = Array.prototype.slice.call(arguments) 761 args.shift() 762 this.options[name].apply(this, args) 763 } 764 }, 765 } 766 })() 767 768 $.fn.backgroundVideo = function (opt) { 769 var args = Array.prototype.slice.call(arguments) 770 var method = args[0] 771 var options = $.extend( 772 { 773 activeClass: 'video-active', 774 videoHolder: null, 775 }, 776 opt 777 ) 778 779 return this.each(function () { 780 var $video = jQuery(this) 781 var instance = $video.data('BackgroundVideo') 782 783 if (typeof opt === 'object' || typeof opt === 'undefined') { 784 $video.data('BackgroundVideo', BgVideoController.add($video, options)) 785 } else if (typeof method === 'string' && instance) { 786 if (typeof instance[method] === 'function') { 787 args.shift() 788 instance[method].apply(instance, args) 789 } 790 } 791 }) 792 } 793 794 window.BgVideoController = BgVideoController 795 796 return BgVideoController 797})(jQuery, jQuery(window)) 798 799/* 800 * Accessible TAB navigation 801 */ 802;(function ($) { 803 var isWindowsPhone = /Windows Phone/.test(navigator.userAgent) 804 var isTouchDevice = 805 'ontouchstart' in window || 806 (window.DocumentTouch && document instanceof DocumentTouch) 807 808 $.fn.tabNav = function (opt) { 809 var options = $.extend( 810 { 811 hoverClass: 'hover', 812 items: 'li', 813 opener: '>a', 814 delay: 10, 815 }, 816 opt 817 ) 818 819 if (isWindowsPhone || isTouchDevice) { 820 return this 821 } 822 823 return this.each(function () { 824 var nav = $(this), 825 items = nav.find(options.items) 826 827 items.each(function (index, navItem) { 828 var item = $(this), 829 navActive, 830 touchNavActive 831 var link = item.find(options.opener), 832 timer 833 834 link 835 .bind('focus', function () { 836 navActive = nav.hasClass('js-nav-active') 837 touchNavActive = window.TouchNav && TouchNav.isActiveOn(navItem) 838 if (!navActive || touchNavActive) { 839 initSimpleNav() 840 } 841 item.trigger( 842 navActive && touchNavActive ? 'itemhover' : 'mouseenter' 843 ) 844 }) 845 .bind('blur', function () { 846 item.trigger( 847 navActive && touchNavActive ? 'itemleave' : 'mouseleave' 848 ) 849 }) 850 851 var initSimpleNav = function () { 852 if (!initSimpleNav.done) { 853 initSimpleNav.done = true 854 item.hover( 855 function () { 856 clearTimeout(timer) 857 timer = setTimeout(function () { 858 item.addClass(options.hoverClass) 859 }, options.delay) 860 }, 861 function () { 862 clearTimeout(timer) 863 timer = setTimeout(function () { 864 item.removeClass(options.hoverClass) 865 }, options.delay) 866 } 867 ) 868 } 869 } 870 }) 871 }) 872 } 873})(jQuery) 874 875/*! 876 * SmoothScroll module 877 */ 878;(function ($, exports) { 879 // private variables 880 var page, 881 win = $(window), 882 activeBlock, 883 activeWheelHandler, 884 wheelEvents = 885 'onwheel' in document || document.documentMode >= 9 886 ? 'wheel' 887 : 'mousewheel DOMMouseScroll' 888 889 // animation handlers 890 function scrollTo(offset, options, callback) { 891 // initialize variables 892 var scrollBlock 893 if (document.body) { 894 if (typeof options === 'number') { 895 options = { 896 duration: options, 897 } 898 } else { 899 options = options || {} 900 } 901 page = page || $('html, body') 902 scrollBlock = options.container || page 903 } else { 904 return 905 } 906 907 // treat single number as scrollTop 908 if (typeof offset === 'number') { 909 offset = { 910 top: offset, 911 } 912 } 913 914 // handle mousewheel/trackpad while animation is active 915 if (activeBlock && activeWheelHandler) { 916 activeBlock.off(wheelEvents, activeWheelHandler) 917 } 918 if (options.wheelBehavior && options.wheelBehavior !== 'none') { 919 activeWheelHandler = function (e) { 920 if (options.wheelBehavior === 'stop') { 921 scrollBlock.off(wheelEvents, activeWheelHandler) 922 scrollBlock.stop() 923 } else if (options.wheelBehavior === 'ignore') { 924 e.preventDefault() 925 } 926 } 927 activeBlock = scrollBlock.on(wheelEvents, activeWheelHandler) 928 } 929 930 // start scrolling animation 931 scrollBlock.stop().animate( 932 { 933 scrollLeft: offset.left, 934 scrollTop: offset.top, 935 }, 936 options.duration, 937 function () { 938 if (activeWheelHandler) { 939 scrollBlock.off(wheelEvents, activeWheelHandler) 940 } 941 if ($.isFunction(callback)) { 942 callback() 943 } 944 } 945 ) 946 } 947 948 // smooth scroll contstructor 949 function SmoothScroll(options) { 950 this.options = $.extend( 951 { 952 anchorLinks: 'a[href^="#"]', // selector or jQuery object 953 container: null, // specify container for scrolling (default - whole page) 954 extraOffset: null, // function or fixed number 955 activeClasses: null, // null, "link", "parent" 956 easing: 'swing', // easing of scrolling 957 animMode: 'duration', // or "speed" mode
958 animDuration: 800, // total duration for scroll (any distance) 959 animSpeed: 1500, // pixels per second 960 anchorActiveClass: 'anchor-active', 961 sectionActiveClass: 'section-active', 962 wheelBehavior: 'stop', // "stop", "ignore" or "none" 963 useNativeAnchorScrolling: false, // do not handle click in devices with native smooth scrolling 964 }, 965 options 966 ) 967 this.init() 968 } 969 SmoothScroll.prototype = { 970 init: function () { 971 this.initStructure() 972 this.attachEvents() 973 this.isInit = true 974 }, 975 initStructure: function () { 976 var self = this 977 978 this.container = this.options.container 979 ? $(this.options.container) 980 : $('html,body') 981 this.scrollContainer = this.options.container ? this.container : win 982 this.anchorLinks = jQuery(this.options.anchorLinks).filter(function () { 983 return jQuery(self.getAnchorTarget(jQuery(this))).length 984 }) 985 }, 986 getId: function (str) { 987 try { 988 return '#' + str.replace(/^.*?(#|$)/, '') 989 } catch (err) { 990 return null 991 } 992 }, 993 getAnchorTarget: function (link) { 994 // get target block from link href 995 var targetId = this.getId($(link).attr('href')) 996 return $(targetId.length > 1 ? targetId : 'html') 997 }, 998 getTargetOffset: function (block) { 999 // get target offset 1000 var blockOffset = block.offset().top 1001 if (this.options.container) { 1002 blockOffset -= 1003 this.container.offset().top - this.container.prop('scrollTop') 1004 } 1005 1006 // handle extra offset 1007 if (typeof this.options.extraOffset === 'number') { 1008 blockOffset -= this.options.extraOffset 1009 } else if (typeof this.options.extraOffset === 'function') { 1010 blockOffset -= this.options.extraOffset(block) 1011 } 1012 return { 1013 top: blockOffset, 1014 } 1015 }, 1016 attachEvents: function () { 1017 var self = this 1018 1019 // handle active classes 1020 if (this.options.activeClasses && this.anchorLinks.length) { 1021 // cache structure 1022 this.anchorData = [] 1023 1024 for (var i = 0; i < this.anchorLinks.length; i++) { 1025 var link = jQuery(this.anchorLinks[i]), 1026 targetBlock = self.getAnchorTarget(link), 1027 anchorDataItem = null 1028 1029 $.each(self.anchorData, function (index, item) { 1030 if (item.block[0] === targetBlock[0]) { 1031 anchorDataItem = item 1032 } 1033 }) 1034 1035 if (anchorDataItem) { 1036 anchorDataItem.link = anchorDataItem.link.add(link) 1037 } else { 1038 self.anchorData.push({ 1039 link: link, 1040 block: targetBlock, 1041 }) 1042 } 1043 } 1044 1045 // add additional event handlers 1046 this.resizeHandler = function () { 1047 if (!self.isInit) return 1048 self.recalculateOffsets() 1049 } 1050 this.scrollHandler = function () { 1051 self.refreshActiveClass() 1052 } 1053 1054 this.recalculateOffsets() 1055 this.scrollContainer.on('scroll', this.scrollHandler) 1056 win.on( 1057 'resize.SmoothScroll load.SmoothScroll orientationchange.SmoothScroll refreshAnchor.SmoothScroll', 1058 this.resizeHandler 1059 ) 1060 } 1061 1062 // handle click event 1063 this.clickHandler = function (e) { 1064 self.onClick(e) 1065 } 1066 if (!this.options.useNativeAnchorScrolling) { 1067 this.anchorLinks.on('click', this.clickHandler) 1068 } 1069 }, 1070 recalculateOffsets: function () { 1071 var self = this 1072 $.each(this.anchorData, function (index, data) { 1073 data.offset = self.getTargetOffset(data.block) 1074 data.height = data.block.outerHeight() 1075 }) 1076 this.refreshActiveClass() 1077 }, 1078 toggleActiveClass: function (anchor, block, state) { 1079 anchor.toggleClass(this.options.anchorActiveClass, state) 1080 block.toggleClass(this.options.sectionActiveClass, state) 1081 }, 1082 refreshActiveClass: function () { 1083 var self = this, 1084 foundFlag = false, 1085 containerHeight = this.container.prop('scrollHeight'), 1086 viewPortHeight = this.scrollContainer.height(), 1087 scrollTop = this.options.container 1088 ? this.container.prop('scrollTop') 1089 : win.scrollTop() 1090 1091 // user function instead of default handler 1092 if (this.options.customScrollHandler) { 1093 this.options.customScrollHandler.call(this, scrollTop, this.anchorData) 1094 return 1095 } 1096 1097 // sort anchor data by offsets 1098 this.anchorData.sort(function (a, b) { 1099 return a.offset.top - b.offset.top 1100 }) 1101 1102 // default active class handler 1103 $.each(this.anchorData, function (index) { 1104 var reverseIndex = self.anchorData.length - index - 1, 1105 data = self.anchorData[reverseIndex], 1106 anchorElement = 1107 self.options.activeClasses === 'parent' 1108 ? data.link.parent() 1109 : data.link 1110 1111 if (scrollTop >= containerHeight - viewPortHeight) { 1112 // handle last section 1113 if (reverseIndex === self.anchorData.length - 1) { 1114 self.toggleActiveClass(anchorElement, data.block, true) 1115 } else { 1116 self.toggleActiveClass(anchorElement, data.block, false) 1117 } 1118 } else { 1119 // handle other sections 1120 if ( 1121 !foundFlag && 1122 (scrollTop >= data.offset.top - 1 || reverseIndex === 0) 1123 ) { 1124 foundFlag = true 1125 self.toggleActiveClass(anchorElement, data.block, true) 1126 } else { 1127 self.toggleActiveClass(anchorElement, data.block, false) 1128 } 1129 } 1130 }) 1131 }, 1132 calculateScrollDuration: function (offset) { 1133 var distance 1134 if (this.options.animMode === 'speed') { 1135 distance = Math.abs(this.scrollContainer.scrollTop() - offset.top) 1136 return (distance / this.options.animSpeed) * 1000 1137 } else { 1138 return this.options.animDuration 1139 } 1140 }, 1141 onClick: function (e) { 1142 var targetBlock = this.getAnchorTarget(e.currentTarget), 1143 targetOffset = this.getTargetOffset(targetBlock) 1144 1145 e.preventDefault() 1146 scrollTo(targetOffset, { 1147 container: this.container, 1148 wheelBehavior: this.options.wheelBehavior, 1149 duration: this.calculateScrollDuration(targetOffset), 1150 }) 1151 this.makeCallback('onBeforeScroll', e.currentTarget) 1152 }, 1153 makeCallback: function (name) { 1154 if (typeof this.options[name] === 'function') { 1155 var args = Array.prototype.slice.call(arguments) 1156 args.shift() 1157 this.options[name].apply(this, args) 1158 } 1159 }, 1160 destroy: function () { 1161 var self = this 1162 1163 this.isInit = false 1164 if (this.options.activeClasses) { 1165 win.off( 1166 'resize.SmoothScroll load.SmoothScroll orientationchange.SmoothScroll refreshAnchor.SmoothScroll', 1167 this.resizeHandler 1168 ) 1169 this.scrollContainer.off('scroll', this.scrollHandler) 1170 $.each(this.anchorData, function (index) { 1171 var reverseIndex = self.anchorData.length - index - 1, 1172 data = self.anchorData[reverseIndex], 1173 anchorElement = 1174 self.options.activeClasses === 'parent' 1175 ? data.link.parent() 1176 : data.link 1177 1178 self.toggleActiveClass(anchorElement, data.block, false) 1179 }) 1180 } 1181 this.anchorLinks.off('click', this.clickHandler) 1182 }, 1183 } 1184 1185 // public API 1186 $.extend(SmoothScroll, { 1187 scrollTo: function (blockOrOffset, durationOrOptions, callback) { 1188 scrollTo(blockOrOffset, durationOrOptions, callback) 1189 }, 1190 }) 1191 1192 // export module 1193 exports.SmoothScroll = SmoothScroll 1194})(jQuery, this) 1195 1196/** 1197 * jquery.mask.js 1198 * @version: v1.14.16 1199 * @author: Igor Escobar 1200 * 1201 * Created by Igor Escobar on 2012-03-10. Please report any bug at github.com/igorescobar/jQuery-Mask-Plugin 1202 * 1203 * Copyright (c) 2012-2023 Igor Escobar http://igorescobar.com 1204 * 1205 * The MIT License (http://www.opensource.org/licenses/mit-license.php) 1206 * 1207 * Permission is hereby granted, free of charge, to any person 1208 * obtaining a copy of this software and associated documentation 1209 * files (the "Software"), to deal in the Software without 1210 * restriction, including without limitation the rights to use, 1211 * copy, modify, merge, publish, distribute, sublicense, and/or sell 1212 * copies of the Software, and to permit persons to whom the 1213 * Software is furnished to do so, subject to the following 1214 * conditions: 1215 * 1216 * The above copyright notice and this permission notice shall be 1217 * included in all copies or substantial portions of the Software. 1218 * 1219 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1220 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 1221 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1222 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 1223 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 1224 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 1225 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 1226 * OTHER DEALINGS IN THE SOFTWARE. 1227 */ 1228 1229/* jshint laxbreak: true */ 1230/* jshint maxcomplexity:17 */ 1231/* global define */ 1232 1233// UMD (Universal Module Definition) patterns for JavaScript modules that work everywhere. 1234// https://github.com/umdjs/umd/blob/master/templates/jqueryPlugin.js 1235// prettier-ignore 1236!function(t,a,e){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof exports&&"undefined"==typeof Meteor?module.exports=t(require("jquery")):t(a||e)}(function(t){"use strict";var a=function(a,e,n){var s={invalid:[],getCaret:function(){try{var t,e=0,n=a.get(0),r=document.selection,o=n.selectionStart;return r&&-1===navigator.appVersion.indexOf("MSIE 10")?((t=r.createRange()).moveStart("character",-s.val().length),e=t.text.length):(o||"0"===o)&&(e=o),e}catch(t){}},setCaret:function(t){try{if(a.is(":focus")){var e,n=a.get(0);n.setSelectionRange?n.setSelectionRange(t,t):((e=n.createTextRange()).collapse(!0),e.moveEnd("character",t),e.moveStart("character",t),e.select())}}catch(t){}},events:function(){a.on("keydown.mask",function(t){a.data("mask-keycode",t.keyCode||t.which),a.data("mask-previus-value",a.val()),a.data("mask-previus-caret-pos",s.getCaret()),s.maskDigitPosMapOld=s.maskDigitPosMap}).on(t.jMaskGlobals.useInput?"input.mask":"keyup.mask",s.behaviour).on("paste.mask drop.mask",function(){setTimeout(function(){a.keydown().keyup()},100)}).on("change.mask",function(){a.data("changed",!0)}).on("blur.mask",function(){i===s.val()||a.data("changed")||a.trigger("change"),a.data("changed",!1)}).on("blur.mask",function(){i=s.val()}).on("focus.mask",function(a){!0===n.selectOnFocus&&t(a.target).select()}).on("focusout.mask",function(){n.clearIfNotMatch&&!r.test(s.val())&&s.val("")}
1236)},getRegexMask:function(){for(var t,a,n,s,r,i,l=[],c=0;c<e.length;c++)(t=o.translation[e.charAt(c)])?(a=t.pattern.toString().replace(/.{1}$|^.{1}/g,""),n=t.optional,(s=t.recursive)?(l.push(e.charAt(c)),r={digit:e.charAt(c),pattern:a}):l.push(n||s?a+"?":a)):l.push(e.charAt(c).replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"));return i=l.join(""),r&&(i=i.replace(new RegExp("("+r.digit+"(.*"+r.digit+")?)"),"($1)?").replace(new RegExp(r.digit,"g"),r.pattern)),new RegExp(i)},destroyEvents:function(){a.off(["input","keydown","keyup","paste","drop","blur","focusout",""].join(".mask "))},val:function(t){var e,n=a.is("input")?"val":"text";return arguments.length>0?(a[n]()!==t&&a[n](t),e=a):e=a[n](),e},calculateCaretPosition:function(t){var e=s.getMasked(),n=s.getCaret();if(t!==e){var r=a.data("mask-previus-caret-pos")||0,o=e.length,i=t.length,l=0,c=0,u=0,k=0,f=0;for(f=n;f<o&&s.maskDigitPosMap[f];f++)c++;for(f=n-1;f>=0&&s.maskDigitPosMap[f];f--)l++;for(f=n-1;f>=0;f--)s.maskDigitPosMap[f]&&u++;for(f=r-1;f>=0;f--)s.maskDigitPosMapOld[f]&&k++;if(n>i)n=10*o;else if(r>=n&&r!==i){if(!s.maskDigitPosMapOld[n]){var d=n;n-=k-u,n-=l,s.maskDigitPosMap[n]&&(n=d)}}else n>r&&(n+=u-k,n+=c)}return n},behaviour:function(e){e=e||window.event,s.invalid=[];var n=a.data("mask-keycode");if(-1===t.inArray(n,o.byPassKeys)){var r=s.getMasked(),i=s.getCaret(),l=a.data("mask-previus-value")||"";return setTimeout(function(){s.setCaret(s.calculateCaretPosition(l))},t.jMaskGlobals.keyStrokeCompensation),s.val(r),s.setCaret(i),s.callbacks(e)}},getMasked:function(t,a){var r,i,l,c=[],u=void 0===a?s.val():a+"",k=0,f=e.length,d=0,p=u.length,v=1,h="push",m=-1,g=0,M=[];for(n.reverse?(h="unshift",v=-1,r=0,k=f-1,d=p-1,i=function(){return k>-1&&d>-1}):(r=f-1,i=function(){return k<f&&d<p});i();){var y=e.charAt(k),b=u.charAt(d),w=o.translation[y];w?(b.match(w.pattern)?(c[h](b),w.recursive&&(-1===m?m=k:k===r&&k!==m&&(k=m-v),r===m&&(k-=v)),k+=v):b===l?(g--,l=void 0):w.optional?(k+=v,d-=v):w.fallback?(c[h](w.fallback),k+=v,d-=v):s.invalid.push({p:d,v:b,e:w.pattern}),d+=v):(t||c[h](y),b===y?(M.push(d),d+=v):(l=y,M.push(d+g),g++),k+=v)}var C=e.charAt(r);f!==p+1||o.translation[C]||c.push(C);var j=c.join("");return s.mapMaskdigitPositions(j,M,p),j},mapMaskdigitPositions:function(t,a,e){var r=n.reverse?t.length-e:0;s.maskDigitPosMap={};for(var o=0;o<a.length;o++)s.maskDigitPosMap[a[o]+r]=1},callbacks:function(t){var r=s.val(),o=r!==i,l=[r,t,a,n],c=function(t,a,e){"function"==typeof n[t]&&a&&n[t].apply(this,e)};c("onChange",!0===o,l),c("onKeyPress",!0===o,l),c("onComplete",r.length===e.length,l),c("onInvalid",s.invalid.length>0,[r,t,a,s.invalid,n])}};a=t(a);var r,o=this,i=s.val();e="function"==typeof e?e(s.val(),void 0,a,n):e,o.mask=e,o.options=n,o.remove=function(){var t=s.getCaret();return o.options.placeholder&&a.removeAttr("placeholder"),a.data("mask-maxlength")&&a.removeAttr("maxlength"),s.destroyEvents(),s.val(o.getCleanVal()),s.setCaret(t),a},o.getCleanVal=function(){return s.getMasked(!0)},o.getMaskedVal=function(t){return s.getMasked(!1,t)},o.init=function(i){if(i=i||!1,n=n||{},o.clearIfNotMatch=t.jMaskGlobals.clearIfNotMatch,o.byPassKeys=t.jMaskGlobals.byPassKeys,o.translation=t.extend({},t.jMaskGlobals.translation,n.translation),o=t.extend(!0,{},o,n),r=s.getRegexMask(),i)s.events(),s.val(s.getMasked());else{n.placeholder&&a.attr("placeholder",n.placeholder),a.data("mask")&&a.attr("autocomplete","off");for(var l=0,c=!0;l<e.length;l++){var u=o.translation[e.charAt(l)];if(u&&u.recursive){c=!1;break}}c&&a.attr("maxlength",e.length).data("mask-maxlength",!0),s.destroyEvents(),s.events();var k=s.getCaret();s.val(s.getMasked()),s.setCaret(k)}},o.init(!a.is("input"))};t.maskWatchers={};var e=function(){var e=t(this),s={},r=e.attr("data-mask");if(e.attr("data-mask-reverse")&&(s.reverse=!0),e.attr("data-mask-clearifnotmatch")&&(s.clearIfNotMatch=!0),"true"===e.attr("data-mask-selectonfocus")&&(s.selectOnFocus=!0),n(e,r,s))return e.data("mask",new a(this,r,s))},n=function(a,e,n){n=n||{};var s=t(a).data("mask"),r=JSON.stringify,o=t(a).val()||t(a).text();try{return"function"==typeof e&&(e=e(o)),"object"!=typeof s||r(s.options)!==r(n)||s.mask!==e}catch(t){}};t.fn.mask=function(e,s){s=s||{};var r=this.selector,o=t.jMaskGlobals,i=o.watchInterval,l=s.watchInputs||o.watchInputs,c=function(){if(n(this,e,s))return t(this).data("mask",new a(this,e,s))};return t(this).each(c),r&&""!==r&&l&&(clearInterval(t.maskWatchers[r]),t.maskWatchers[r]=setInterval(function(){t(document).find(r).each(c)},i)),this},t.fn.masked=function(t){return this.data("mask").getMaskedVal(t)},t.fn.unmask=function(){return clearInterval(t.maskWatchers[this.selector]),delete t.maskWatchers[this.selector],this.each(function(){var a=t(this).data("mask");a&&a.remove().removeData("mask")})},t.fn.cleanVal=function(){return this.data("mask").getCleanVal()},t.applyDataMask=function(a){((a=a||t.jMaskGlobals.maskElements)instanceof t?a:t(a)).filter(t.jMaskGlobals.dataMaskAttr).each(e)};var s,r,o,i={maskElements:"input,td,span,div",dataMaskAttr:"[data-mask]",dataMask:!0,watchInterval:300,watchInputs:!0,keyStrokeCompensation:10,useInput:!/Chrome\/[2-4][0-9]|SamsungBrowser/.test(window.navigator.userAgent)&&(s="input",o=document.createElement("div"),(r=(s="on"+s)in o)||(o.setAttribute(s,"return;"),r="function"==typeof o[s]),o=null,r),watchDataMask:!1,byPassKeys:[9,16,17,18,36,37,38,39,40,91],translation:{0:{pattern:/\d/},9:{pattern:/\d/,optional:!0},"#":{pattern:/\d/,recursive:!0},A:{pattern:/[a-zA-Z0-9]/},S:{pattern:/[a-zA-Z]/}}};t.jMaskGlobals=t.jMaskGlobals||{},(i=t.jMaskGlobals=t.extend(!0,{},i,t.jMaskGlobals)).dataMask&&t.applyDataMask(),setInterval(function(){t.jMaskGlobals.watchDataMask&&t.applyDataMask()},i.watchInterval)},window.jQuery,window.Zepto);
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.