1// ================================================== 2// fancyBox v3.2.10 3// 4// Licensed GPLv3 for open source use 5// or fancyBox Commercial License for commercial use 6// 7// http://fancyapps.com/fancybox/ 8// Copyright 2017 fancyApps 9// 10// ================================================== 11;(function (window, document, $, undefined) { 12 'use strict'; 13 14 // If there's no jQuery, fancyBox can't work 15 // ========================================= 16 17 if ( !$ ) { 18 return; 19 } 20 21 // Check if fancyBox is already initialized 22 // ======================================== 23 24 if ( $.fn.fancybox ) { 25 26 if ( 'console' in window ) { 27 console.log( 'fancyBox already initialized' ); 28 } 29 30 return; 31 } 32 33 // Private default settings 34 // ======================== 35 36 var defaults = { 37 38 // Enable infinite gallery navigation 39 loop : false, 40 41 // Space around image, ignored if zoomed-in or viewport width is smaller than 800px 42 margin : [44, 0], 43 44 // Horizontal space between slides 45 gutter : 50, 46 47 // Enable keyboard navigation 48 keyboard : true, 49 50 // Should display navigation arrows at the screen edges 51 arrows : true, 52 53 // Should display infobar (counter and arrows at the top) 54 infobar : true, 55 56 // Should display toolbar (buttons at the top) 57 toolbar : true, 58 59 // What buttons should appear in the top right corner. 60 // Buttons will be created using templates from `btnTpl` option 61 // and they will be placed into toolbar (class="fancybox-toolbar"` element) 62 buttons : [ 63 'slideShow', 64 'fullScreen', 65 'thumbs', 66 'share', 67 //'download', 68 //'zoom', 69 'close' 70 ], 71 72 // Detect "idle" time in seconds 73 idleTime : 3, 74 75 // Should display buttons at top right corner of the content 76 // If 'auto' - they will be created for content having type 'html', 'inline' or 'ajax' 77 // Use template from `btnTpl.smallBtn` for customization 78 smallBtn : 'auto', 79 80 // Disable right-click and use simple image protection for images 81 protect : false, 82 83 // Shortcut to make content "modal" - disable keyboard navigtion, hide buttons, etc 84 modal : false, 85 86 image : { 87 88 // Wait for images to load before displaying 89 // Requires predefined image dimensions 90 // If 'auto' - will zoom in thumbnail if 'width' and 'height' attributes are found 91 preload : "auto" 92 93 }, 94 95 ajax : { 96 97 // Object containing settings for ajax request 98 settings : { 99 100 // This helps to indicate that request comes from the modal 101 // Feel free to change naming 102 data : { 103 fancybox : true 104 } 105 } 106 107 }, 108 109 iframe : { 110 111 // Iframe template 112 tpl : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen allowtransparency="true" src=""></iframe>', 113 114 // Preload iframe before displaying it 115 // This allows to calculate iframe content width and height 116 // (note: Due to "Same Origin Policy", you can't get cross domain data). 117 preload : true, 118 119 // Custom CSS styling for iframe wrapping element 120 // You can use this to set custom iframe dimensions 121 css : {}, 122 123 // Iframe tag attributes 124 attr : { 125 scrolling : 'auto' 126 } 127 128 }, 129 130 // Default content type if cannot be detected automatically 131 defaultType : 'image', 132 133 // Open/close animation type 134 // Possible values: 135 // false - disable 136 // "zoom" - zoom images from/to thumbnail 137 // "fade" 138 // "zoom-in-out" 139 // 140 animationEffect : "zoom", 141 142 // Duration in ms for open/close animation 143 animationDuration : 500, 144 145 // Should image change opacity while zooming 146 // If opacity is "auto", then opacity will be changed if image and thumbnail have different aspect ratios 147 zoomOpacity : "auto", 148 149 // Transition effect between slides 150 // 151 // Possible values: 152 // false - disable 153 // "fade' 154 // "slide' 155 // "circular' 156 // "tube' 157 // "zoom-in-out' 158 // "rotate' 159 // 160 transitionEffect : "fade", 161 162 // Duration in ms for transition animation 163 transitionDuration : 366, 164 165 // Custom CSS class for slide element 166 slideClass : '', 167 168 // Custom CSS class for layout 169 baseClass : '', 170 171 // Base template for layout 172 baseTpl : 173 '<div class="fancybox-container" role="dialog" tabindex="-1">' + 174 '<div class="fancybox-bg"></div>' + 175 '<div class="fancybox-inner">' + 176 '<div class="fancybox-infobar">' + 177 '<span data-fancybox-index></span> / <span data-fancybox-count></span>' + 178 '</div>' + 179 '<div class="fancybox-toolbar">{{buttons}}</div>' + 180 '<div class="fancybox-navigation">{{arrows}}</div>' + 181 '<div class="fancybox-stage"></div>' + 182 '<div class="fancybox-caption-wrap"><div class="fancybox-caption"></div></div>' + 183 '</div>' + 184 '</div>', 185 186 // Loading indicator template 187 spinnerTpl : '<div class="fancybox-loading"></div>', 188 189 // Error message template 190 errorTpl : '<div class="fancybox-error"><p>{{ERROR}}<p></div>', 191 192 btnTpl : { 193 194 download : '<a download data-fancybox-download class="fancybox-button fancybox-button--download" title="{{DOWNLOAD}}">' + 195 '<svg viewBox="0 0 40 40">' + 196 '<path d="M20,23 L20,8 L20,23 L13,16 L20,23 L27,16 L20,23 M26,28 L13,28 L27,28 L14,28" />' + 197 '</svg>' + 198 '</a>', 199 200 zoom : '<button data-fancybox-zoom class="fancybox-button fancybox-button--zoom" title="{{ZOOM}}">' + 201 '<svg viewBox="0 0 40 40">' + 202 '<path d="M 18,17 m-8,0 a 8,8 0 1,0 16,0 a 8,8 0 1,0 -16,0 M25,23 L31,29 L25,23" />' + 203 '</svg>' + 204 '</button>', 205 206 close : '<button data-fancybox-close class="fancybox-button fancybox-button--close" title="{{CLOSE}}">' + 207 '<svg viewBox="0 0 40 40">' + 208 '<path d="M10,10 L30,30 M30,10 L10,30" />' + 209 '</svg>' + 210 '</button>', 211 212 // This small close button will be appended to your html/inline/ajax content by default, 213 // if "smallBtn" option is not set to false 214 smallBtn : '<button data-fancybox-close class="fancybox-close-small" title="{{CLOSE}}"></button>', 215 216 // Arrows 217 arrowLeft : '<button data-fancybox-prev class="fancybox-button fancybox-button--arrow_left" title="{{PREV}}">' + 218 '<svg viewBox="0 0 40 40">' + 219 '<path d="M10,20 L30,20 L10,20 L18,28 L10,20 L18,12 L10,20"></path>' + 220 '</svg>' + 221 '</button>', 222 223 arrowRight : '<button data-fancybox-next class="fancybox-button fancybox-button--arrow_right" title="{{NEXT}}">' + 224 '<svg viewBox="0 0 40 40">' + 225 '<path d="M30,20 L10,20 L30,20 L22,28 L30,20 L22,12 L30,20"></path>' + 226 '</svg>' + 227 '</button>' 228 }, 229 230 // Container is injected into this element 231 parentEl : 'body', 232 233 234 // Focus handling 235 // ============== 236 237 // Try to focus on the first focusable element after opening 238 autoFocus : false, 239 240 // Put focus back to active element after closing 241 backFocus : true, 242
vendor: 5,349 bytes, lines 243-395
243 // Do not let user to focus on element outside modal content 244 trapFocus : true, 245 246 247 // Module specific options 248 // ======================= 249 250 fullScreen : { 251 autoStart : false, 252 }, 253 254 // Set `touch: false` to disable dragging/swiping 255 touch : { 256 vertical : true, // Allow to drag content vertically 257 momentum : true // Continue movement after releasing mouse/touch when panning 258 }, 259 260 // Hash value when initializing manually, 261 // set `false` to disable hash change 262 hash : null, 263 264 // Customize or add new media types 265 // Example: 266 /* 267 media : { 268 youtube : { 269 params : { 270 autoplay : 0 271 } 272 } 273 } 274 */ 275 media : {}, 276 277 slideShow : { 278 autoStart : false, 279 speed : 4000 280 }, 281 282 thumbs : { 283 autoStart : false, // Display thumbnails on opening 284 hideOnClose : true, // Hide thumbnail grid when closing animation starts 285 parentEl : '.fancybox-container', // Container is injected into this element 286 axis : 'y' // Vertical (y) or horizontal (x) scrolling 287 }, 288 289 // Use mousewheel to navigate gallery 290 // If 'auto' - enabled for images only 291 wheel : 'auto', 292 293 // Callbacks 294 //========== 295 296 // See Documentation/API/Events for more information 297 // Example: 298 /* 299 afterShow: function( instance, current ) { 300 console.info( 'Clicked element:' ); 301 console.info( current.opts.$orig ); 302 } 303 */ 304 305 onInit : $.noop, // When instance has been initialized 306 307 beforeLoad : $.noop, // Before the content of a slide is being loaded 308 afterLoad : $.noop, // When the content of a slide is done loading 309 310 beforeShow : $.noop, // Before open animation starts 311 afterShow : $.noop, // When content is done loading and animating 312 313 beforeClose : $.noop, // Before the instance attempts to close. Return false to cancel the close. 314 afterClose : $.noop, // After instance has been closed 315 316 onActivate : $.noop, // When instance is brought to front 317 onDeactivate : $.noop, // When other instance has been activated 318 319 320 // Interaction 321 // =========== 322 323 // Use options below to customize taken action when user clicks or double clicks on the fancyBox area, 324 // each option can be string or method that returns value. 325 // 326 // Possible values: 327 // "close" - close instance 328 // "next" - move to next gallery item 329 // "nextOrClose" - move to next gallery item or close if gallery has only one item 330 // "toggleControls" - show/hide controls 331 // "zoom" - zoom image (if loaded) 332 // false - do nothing 333 334 // Clicked on the content 335 clickContent : function( current, event ) { 336 return current.type === 'image' ? 'zoom' : false; 337 }, 338 339 // Clicked on the slide 340 clickSlide : 'close', 341 342 // Clicked on the background (backdrop) element 343 clickOutside : 'close', 344 345 // Same as previous two, but for double click 346 dblclickContent : false, 347 dblclickSlide : false, 348 dblclickOutside : false, 349 350 351 // Custom options when mobile device is detected 352 // ============================================= 353 354 mobile : { 355 idleTime : false, 356 margin : 0, 357 358 clickContent : function( current, event ) { 359 return current.type === 'image' ? 'toggleControls' : false; 360 }, 361 clickSlide : function( current, event ) { 362 return current.type === 'image' ? 'toggleControls' : 'close'; 363 }, 364 dblclickContent : function( current, event ) { 365 return current.type === 'image' ? 'zoom' : false; 366 }, 367 dblclickSlide : function( current, event ) { 368 return current.type === 'image' ? 'zoom' : false; 369 } 370 }, 371 372 373 // Internationalization 374 // ============ 375 376 lang : 'en', 377 i18n : { 378 'en' : { 379 CLOSE : 'Close', 380 NEXT : 'Next', 381 PREV : 'Previous', 382 ERROR : 'The requested content cannot be loaded. <br/> Please try again later.', 383 PLAY_START : 'Start slideshow', 384 PLAY_STOP : 'Pause slideshow', 385 FULL_SCREEN : 'Full screen', 386 THUMBS : 'Thumbnails', 387 DOWNLOAD : 'Download', 388 SHARE : 'Share', 389 ZOOM : 'Zoom' 390 }, 391 'de' : { 392 CLOSE : 'Schliessen', 393 NEXT : 'Weiter', 394 PREV : 'Zurück', 395 ERROR : 'Die angeforderten Daten konnten nicht geladen werden. <br/>
395 Bitte versuchen Sie es später nochmal.', 396 PLAY_START : 'Diaschau starten', 397 PLAY_STOP : 'Diaschau beenden', 398 FULL_SCREEN : 'Vollbild', 399 THUMBS : 'Vorschaubilder', 400 DOWNLOAD : 'Herunterladen', 401 SHARE : 'Teilen', 402 ZOOM : 'MaÃstab' 403 } 404 } 405 406 }; 407 408 // Few useful variables and methods 409 // ================================ 410 411 var $W = $(window); 412 var $D = $(document); 413 414 var called = 0; 415 416 417 // Check if an object is a jQuery object and not a native JavaScript object 418 // ======================================================================== 419 420 var isQuery = function ( obj ) { 421 return obj && obj.hasOwnProperty && obj instanceof $; 422 }; 423 424 425 // Handle multiple browsers for "requestAnimationFrame" and "cancelAnimationFrame" 426 // =============================================================================== 427 428 var requestAFrame = (function () { 429 return window.requestAnimationFrame || 430 window.webkitRequestAnimationFrame || 431 window.mozRequestAnimationFrame || 432 window.oRequestAnimationFrame || 433 // if all else fails, use setTimeout 434 function (callback) { 435 return window.setTimeout(callback, 1000 / 60); 436 }; 437 })(); 438 439 440 // Detect the supported transition-end event property name 441 // ======================================================= 442 443 var transitionEnd = (function () { 444 var t, el = document.createElement("fakeelement"); 445 446 var transitions = { 447 "transition" : "transitionend", 448 "OTransition" : "oTransitionEnd", 449 "MozTransition" : "transitionend", 450 "WebkitTransition": "webkitTransitionEnd" 451 }; 452 453 for (t in transitions) { 454 if (el.style[t] !== undefined){ 455 return transitions[t]; 456 } 457 } 458 459 return 'transitionend'; 460 })(); 461 462 463 // Force redraw on an element. 464 // This helps in cases where the browser doesn't redraw an updated element properly. 465 // ================================================================================= 466 467 var forceRedraw = function( $el ) { 468 return ( $el && $el.length && $el[0].offsetHeight ); 469 }; 470 471 472 // Class definition 473 // ================ 474 475 var FancyBox = function( content, opts, index ) { 476 var self = this; 477 478 self.opts = $.extend( true, { index : index }, $.fancybox.defaults, opts || {} ); 479 480 if ( $.fancybox.isMobile ) { 481 self.opts = $.extend( true, {}, self.opts, self.opts.mobile ); 482 } 483 484 // Exclude buttons option from deep merging 485 if ( opts && $.isArray( opts.buttons ) ) { 486 self.opts.buttons = opts.buttons; 487 } 488 489 self.id = self.opts.id || ++called; 490 self.group = []; 491 492 self.currIndex = parseInt( self.opts.index, 10 ) || 0; 493 self.prevIndex = null; 494 495 self.prevPos = null; 496 self.currPos = 0; 497 498 self.firstRun = null; 499 500 // Create group elements from original item collection 501 self.createGroup( content ); 502 503 if ( !self.group.length ) { 504 return; 505 } 506 507 // Save last active element and current scroll position 508 self.$lastFocus = $(document.activeElement).blur(); 509 510 // Collection of gallery objects 511 self.slides = {}; 512 513 self.init(); 514 }; 515 516 $.extend(FancyBox.prototype, { 517 518 // Create DOM structure 519 // ==================== 520 521 init : function() { 522 var self = this, 523 firstItem = self.group[ self.currIndex ], 524 firstItemOpts = firstItem.opts, 525 scrollbarWidth = $.fancybox.scrollbarWidth, 526 $scrollDiv, 527 $container, 528 buttonStr; 529 530 self.scrollTop = $D.scrollTop(); 531 self.scrollLeft = $D.scrollLeft(); 532 533 534 // Hide scrollbars 535 // =============== 536 537 if ( !$.fancybox.getInstance() ) { 538 539 $( 'body' ).addClass( 'fancybox-active' ); 540 541 // iOS hack 542 if ( /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream ) { 543 544 // iOS has problems for input elements inside fixed containers, 545 // the workaround is to apply `position: fixed` to `<body>` element, 546 // unfortunately, this makes it lose the scrollbars and forces address bar to appear. 547
548 if ( firstItem.type !== 'image' ) { 549 $( 'body' ).css( 'top', $( 'body' ).scrollTop() * -1 ).addClass( 'fancybox-iosfix' ); 550 } 551 552 } else if ( !$.fancybox.isMobile && document.body.scrollHeight > window.innerHeight ) { 553 554 if ( scrollbarWidth === undefined ) { 555 $scrollDiv = $('<div style="width:50px;height:50px;overflow:scroll;" />').appendTo( 'body' ); 556 557 scrollbarWidth = $.fancybox.scrollbarWidth = $scrollDiv[0].offsetWidth - $scrollDiv[0].clientWidth; 558 559 $scrollDiv.remove(); 560 } 561 562 $( 'head' ).append( '<style id="fancybox-style-noscroll" type="text/css">.compensate-for-scrollbar { margin-right: ' + scrollbarWidth + 'px; }</style>' ); 563 $( 'body' ).addClass( 'compensate-for-scrollbar' ); 564 } 565 } 566 567 568 // Build html markup and set references 569 // ==================================== 570 571 // Build html code for buttons and insert into main template 572 buttonStr = ''; 573 574 $.each( firstItemOpts.buttons, function( index, value ) { 575 buttonStr += ( firstItemOpts.btnTpl[ value ] || '' ); 576 }); 577 578 // Create markup from base template, it will be initially hidden to 579 // avoid unnecessary work like painting while initializing is not complete 580 $container = $( 581 self.translate( self, 582 firstItemOpts.baseTpl 583 .replace( '\{\{buttons\}\}', buttonStr ) 584 .replace( '\{\{arrows\}\}', firstItemOpts.btnTpl.arrowLeft + firstItemOpts.btnTpl.arrowRight ) 585 ) 586 ) 587 .attr( 'id', 'fancybox-container-' + self.id ) 588 .addClass( 'fancybox-is-hidden' ) 589 .addClass( firstItemOpts.baseClass ) 590 .data( 'FancyBox', self ) 591 .appendTo( firstItemOpts.parentEl ); 592 593 // Create object holding references to jQuery wrapped nodes 594 self.$refs = { 595 container : $container 596 }; 597 598 [ 'bg', 'inner', 'infobar', 'toolbar', 'stage', 'caption', 'navigation' ].forEach(function(item) { 599 self.$refs[ item ] = $container.find( '.fancybox-' + item ); 600 }); 601 602 self.trigger( 'onInit' ); 603 604 // Enable events, deactive previous instances 605 self.activate(); 606 607 // Build slides, load and reveal content 608 self.jumpTo( self.currIndex ); 609 }, 610 611 612 // Simple i18n support - replaces object keys found in template 613 // with corresponding values 614 // ============================================================ 615 616 translate : function( obj, str ) { 617 var arr = obj.opts.i18n[ obj.opts.lang ]; 618 619 return str.replace(/\{\{(\w+)\}\}/g, function(match, n) { 620 var value = arr[n]; 621 622 if ( value === undefined ) { 623 return match; 624 } 625 626 return value; 627 }); 628 }, 629 630 // Create array of gally item objects 631 // Check if each object has valid type and content 632 // =============================================== 633 634 createGroup : function ( content ) { 635 var self = this; 636 var items = $.makeArray( content ); 637 638 $.each(items, function( i, item ) { 639 var obj = {}, 640 opts = {}, 641 $item, 642 type, 643 found, 644 src, 645 srcParts; 646 647 // Step 1 - Make sure we have an object 648 // ==================================== 649 650 if ( $.isPlainObject( item ) ) { 651 652 // We probably have manual usage here, something like 653 // $.fancybox.open( [ { src : "image.jpg", type : "image" } ] ) 654 655 obj = item; 656 opts = item.opts || item; 657 658 } else if ( $.type( item ) === 'object' && $( item ).length ) { 659 660 // Here we probably have jQuery collection returned by some selector 661 $item = $( item ); 662 663 opts = $item.data(); 664 opts = $.extend( {}, opts, opts.options || {} ); 665 666 // Here we store clicked element 667 opts.$orig = $item; 668 669 obj.src = opts.src || $item.attr( 'href' ); 670 671 // Assume that simple syntax is used, for example: 672 // `$.fancybox.open( $("#test"), {} );` 673 if ( !obj.type && !obj.src ) { 674 obj.type = 'inline'; 675 obj.src = item; 676 } 677 678 } else { 679 680 // Assume we have a simple html code, for example: 681 // $.fancybox.open( '<div><h1>Hi!</h1></div>' ); 682 683 obj = { 684 type : 'html', 685 src : item + '' 686 }; 687 688 } 689 690 // Each gallery object has full collection of options 691 obj.opts = $.extend( true, {}, self.opts, opts ); 692
693 // Do not merge buttons array 694 if ( $.isArray( opts.buttons ) ) { 695 obj.opts.buttons = opts.buttons; 696 } 697 698 699 // Step 2 - Make sure we have content type, if not - try to guess 700 // ============================================================== 701 702 type = obj.type || obj.opts.type; 703 src = obj.src || ''; 704 705 if ( !type && src ) { 706 if ( src.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i) ) { 707 type = 'image'; 708 709 } else if ( src.match(/\.(pdf)((\?|#).*)?$/i) ) { 710 type = 'pdf'; 711 712 } else if ( found = src.match(/\.(mp4|mov|ogv)((\?|#).*)?$/i) ) { 713 type = 'video'; 714 715 if ( !obj.opts.videoFormat ) { 716 obj.opts.videoFormat = 'video/' + ( found[1] === 'ogv' ? 'ogg' : found[1] ); 717 } 718 719 } else if ( src.charAt(0) === '#' ) { 720 type = 'inline'; 721 } 722 } 723 724 if ( type ) { 725 obj.type = type; 726 727 } else { 728 self.trigger( 'objectNeedsType', obj ); 729 } 730 731 732 // Step 3 - Some adjustments 733 // ========================= 734 735 obj.index = self.group.length; 736 737 // Check if $orig and $thumb objects exist 738 if ( obj.opts.$orig && !obj.opts.$orig.length ) { 739 delete obj.opts.$orig; 740 } 741 742 if ( !obj.opts.$thumb && obj.opts.$orig ) { 743 obj.opts.$thumb = obj.opts.$orig.find( 'img:first' ); 744 } 745 746 if ( obj.opts.$thumb && !obj.opts.$thumb.length ) { 747 delete obj.opts.$thumb; 748 } 749 750 // "caption" is a "special" option, it can be used to customize caption per gallery item .. 751 if ( $.type( obj.opts.caption ) === 'function' ) { 752 obj.opts.caption = obj.opts.caption.apply( item, [ self, obj ] ); 753 } 754 755 if ( $.type( self.opts.caption ) === 'function' ) { 756 obj.opts.caption = self.opts.caption.apply( item, [ self, obj ] ); 757 } 758 759 // Make sure we have caption as a string or jQuery object 760 if ( !( obj.opts.caption instanceof $ ) ) { 761 obj.opts.caption = obj.opts.caption === undefined ? '' : obj.opts.caption + ''; 762 } 763 764 // Check if url contains "filter" used to filter the content 765 // Example: "ajax.html #something" 766 if ( type === 'ajax' ) { 767 srcParts = src.split(/\s+/, 2); 768 769 if ( srcParts.length > 1 ) { 770 obj.src = srcParts.shift(); 771 772 obj.opts.filter = srcParts.shift(); 773 } 774 } 775 776 if ( obj.opts.smallBtn == 'auto' ) { 777 778 if ( $.inArray( type, ['html', 'inline', 'ajax'] ) > -1 ) { 779 obj.opts.toolbar = false; 780 obj.opts.smallBtn = true; 781 782 } else { 783 obj.opts.smallBtn = false; 784 } 785 786 } 787 788 // If the type is "pdf", then simply load file into iframe 789 if ( type === 'pdf' ) { 790 obj.type = 'iframe'; 791 792 obj.opts.iframe.preload = false; 793 } 794 795 // Hide all buttons and disable interactivity for modal items 796 if ( obj.opts.modal ) { 797 798 obj.opts = $.extend(true, obj.opts, { 799 // Remove buttons 800 infobar : 0, 801 toolbar : 0, 802 803 smallBtn : 0, 804 805 // Disable keyboard navigation 806 keyboard : 0, 807 808 // Disable some modules 809 slideShow : 0, 810 fullScreen : 0, 811 thumbs : 0, 812 touch : 0, 813 814 // Disable click event handlers 815 clickContent : false, 816 clickSlide : false, 817 clickOutside : false, 818 dblclickContent : false, 819 dblclickSlide : false, 820 dblclickOutside : false 821 }); 822 823 } 824 825 // Step 4 - Add processed object to group 826 // ====================================== 827 828 self.group.push( obj ); 829 830 }); 831 832 }, 833 834 835 // Attach an event handler functions for: 836 // - navigation buttons 837 // - browser scrolling, resizing; 838 // - focusing 839 // - keyboard 840 // - detect idle 841 // ====================================== 842 843 addEvents : function() { 844 var self = this; 845 846 self.removeEvents(); 847 848 // Make navigation elements clickable 849 self.$refs.container.on('click.fb-close', '[data-fancybox-close]', function(e) { 850 e.stopPropagation(); 851 e.preventDefault(); 852 853 self.close( e ); 854 855 }).on( 'click.fb-prev touchend.fb-prev', '[data-fancybox-prev]', function(e) { 856 e.stopPropagation(); 857 e.preventDefault(); 858 859 self.previous(); 860 861 }).on( 'click.fb-next touchend.fb-next', '[data-fancybox-next]', function(e) { 862 e.stopPropagation(); 863 e.preventDefault(); 864 865 self.next(); 866 867 }).on( 'click.fb', '[data-fancybox-zoom]', function(e) { 868 // Click handler for zoom button 869 self[ self.isScaledDown() ? 'scaleToActual' : 'scaleToFit' ](); 870 }); 871 872 873 // Handle page scrolling and browser resizing 874 $W.on('orientationchange.fb resize.fb', function(e) { 875 876 if ( e && e.originalEvent && e.originalEvent.type === "resize" ) { 877 878 requestAFrame(function() {
879 self.update(); 880 }); 881 882 } else { 883 884 self.$refs.stage.hide(); 885 886 setTimeout(function() { 887 self.$refs.stage.show(); 888 889 self.update(); 890 }, 600); 891 892 } 893 894 }); 895 896 // Trap keyboard focus inside of the modal, so the user does not accidentally tab outside of the modal 897 // (a.k.a. "escaping the modal") 898 $D.on('focusin.fb', function(e) { 899 var instance = $.fancybox ? $.fancybox.getInstance() : null; 900 901 if ( instance.isClosing || !instance.current || !instance.current.opts.trapFocus || $( e.target ).hasClass( 'fancybox-container' ) || $( e.target ).is( document ) ) { 902 return; 903 } 904 905 if ( instance && $( e.target ).css( 'position' ) !== 'fixed' && !instance.$refs.container.has( e.target ).length ) { 906 e.stopPropagation(); 907 908 instance.focus(); 909 910 // Sometimes page gets scrolled, set it back 911 $W.scrollTop( self.scrollTop ).scrollLeft( self.scrollLeft ); 912 } 913 }); 914 915 916 // Enable keyboard navigation 917 $D.on('keydown.fb', function (e) { 918 var current = self.current, 919 keycode = e.keyCode || e.which; 920 921 if ( !current || !current.opts.keyboard ) { 922 return; 923 } 924 925 if ( $(e.target).is('input') || $(e.target).is('textarea') ) { 926 return; 927 } 928 929 // Backspace and Esc keys 930 if ( keycode === 8 || keycode === 27 ) { 931 e.preventDefault(); 932 933 self.close( e ); 934 935 return; 936 } 937 938 // Left arrow and Up arrow 939 if ( keycode === 37 || keycode === 38 ) { 940 e.preventDefault(); 941 942 self.previous(); 943 944 return; 945 } 946 947 // Righ arrow and Down arrow 948 if ( keycode === 39 || keycode === 40 ) { 949 e.preventDefault(); 950 951 self.next(); 952 953 return; 954 } 955 956 self.trigger('afterKeydown', e, keycode); 957 }); 958 959 960 // Hide controls after some inactivity period 961 if ( self.group[ self.currIndex ].opts.idleTime ) { 962 self.idleSecondsCounter = 0; 963 964 $D.on('mousemove.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle', function(e) { 965 self.idleSecondsCounter = 0; 966 967 if ( self.isIdle ) { 968 self.showControls(); 969 } 970 971 self.isIdle = false; 972 }); 973 974 self.idleInterval = window.setInterval(function() { 975 self.idleSecondsCounter++; 976 977 if ( self.idleSecondsCounter >= self.group[ self.currIndex ].opts.idleTime && !self.isDragging ) { 978 self.isIdle = true; 979 self.idleSecondsCounter = 0; 980 981 self.hideControls(); 982 } 983 984 }, 1000); 985 } 986 987 }, 988 989 990 // Remove events added by the core 991 // =============================== 992 993 removeEvents : function() { 994 var self = this; 995 996 $W.off( 'orientationchange.fb resize.fb' ); 997 $D.off( 'focusin.fb keydown.fb .fb-idle' ); 998 999 this.$refs.container.off( '.fb-close .fb-prev .fb-next' ); 1000 1001 if ( self.idleInterval ) { 1002 window.clearInterval( self.idleInterval ); 1003 1004 self.idleInterval = null; 1005 } 1006 }, 1007 1008 1009 // Change to previous gallery item 1010 // =============================== 1011 1012 previous : function( duration ) { 1013 return this.jumpTo( this.currPos - 1, duration ); 1014 }, 1015 1016 1017 // Change to next gallery item 1018 // =========================== 1019 1020 next : function( duration ) { 1021 return this.jumpTo( this.currPos + 1, duration ); 1022 }, 1023 1024 1025 // Switch to selected gallery item 1026 // =============================== 1027 1028 jumpTo : function ( pos, duration, slide ) { 1029 var self = this, 1030 firstRun, 1031 loop, 1032 current, 1033 previous, 1034 canvasWidth, 1035 currentPos, 1036 transitionProps; 1037 1038 var groupLen = self.group.length; 1039 1040 if ( self.isDragging || self.isClosing || ( self.isAnimating && self.firstRun ) ) { 1041 return; 1042 } 1043 1044 pos = parseInt( pos, 10 ); 1045 loop = self.current ? self.current.opts.loop : self.opts.loop; 1046 1047 if ( !loop && ( pos < 0 || pos >= groupLen ) ) { 1048 return false; 1049 } 1050 1051 firstRun = self.firstRun = ( self.firstRun === null ); 1052 1053 if ( groupLen < 2 && !firstRun && !!self.isDragging ) { 1054 return; 1055 } 1056 1057 previous = self.current; 1058 1059 self.prevIndex = self.currIndex; 1060 self.prevPos = self.currPos; 1061 1062 // Create slides 1063 current = self.createSlide( pos ); 1064 1065 if ( groupLen > 1 ) { 1066 if ( loop || current.index > 0 ) { 1067 self.createSlide( pos - 1 ); 1068 } 1069 1070 if ( loop || current.index < groupLen - 1 ) { 1071 self.createSlide( pos + 1 ); 1072 } 1073 } 1074 1075 self.current = current; 1076 self.currIndex = current.index; 1077 self.currPos = current.pos; 1078 1079 self.trigger( 'beforeShow', firstRun ); 1080 1081 self.updateControls(); 1082 1083 currentPos = $.fancybox.getTranslate( current.$slide ); 1084 1085 current.isMoved = ( currentPos.left !== 0 || currentPos.top !== 0 ) && !current.$slide.hasClass( 'fancybox-animated' ); 1086 current.forcedDuration = undefined; 1087 1088 if ( $.isNumeric( duration ) ) { 1089 current.forcedDuration = duration; 1090 } else { 1091 duration = current.opts[ firstRun ? 'animationDuration' : 'transitionDuration' ]; 1092 } 1093 1094 duration = parseInt( duration, 10 ); 1095 1096 // Fresh start - reveal container, current slide and start loading content 1097 if ( firstRun ) { 1098 1099 if ( current.opts.animationEffect && duration ) { 1100 self.$refs.container.css( 'transition-duration', duration + 'ms' ); 1101 } 1102 1103 self.$refs.container.removeClass( 'fancybox-is-hidden' ); 1104 1105 forceRedraw( self.$refs.container ); 1106 1107 self.$refs.container.addClass( 'fancybox-is-open' ); 1108 1109 // Make first slide visible (to display loading icon, if needed) 1110 current.$slide.addClass( 'fancybox-slide--current' ); 1111 1112 self.loadSlide( current ); 1113 1114 self.preload( 'image' ); 1115 1116 return; 1117 } 1118 1119 // Clean up 1120 $.each(self.slides, function( index, slide ) { 1121 $.fancybox.stop( slide.$slide ); 1122 }); 1123 1124 // Make current that slide is visible even if content is still loading 1125 current.$slide.removeClass( 'fancybox-slide--next fancybox-slide--previous' ).addClass( 'fancybox-slide--current' ); 1126 1127 // If slides have been dragged, animate them to correct position 1128 if ( current.isMoved ) { 1129 canvasWidth = Math.round( current.$slide.width() ); 1130 1131 $.each(self.slides, function( index, slide ) { 1132 var pos = slide.pos - current.pos; 1133 1134 $.fancybox.animate( slide.$slide, { 1135 top : 0, 1136 left : ( pos * canvasWidth ) + ( pos * slide.opts.gutter ) 1137 }, duration, function() { 1138 1139 slide.$slide.removeAttr('style').removeClass( 'fancybox-slide--next fancybox-slide--previous' ); 1140 1141 if ( slide.pos === self.currPos ) { 1142 current.isMoved = false; 1143 1144 self.complete(); 1145 } 1146 }); 1147 }); 1148 1149 } else { 1150 self.$refs.stage.children().removeAttr( 'style' ); 1151 } 1152 1153 // Start transition that reveals current content 1154 // or wait when it will be loaded 1155 1156 if ( current.isLoaded ) { 1157 self.revealContent( current ); 1158 1159 } else { 1160 self.loadSlide( current ); 1161 } 1162 1163 self.preload( 'image' ); 1164 1165 if ( previous.pos === current.pos ) { 1166 return; 1167 } 1168 1169 // Handle previous slide 1170 // ===================== 1171 1172 transitionProps = 'fancybox-slide--' + ( previous.pos > current.pos ? 'next' : 'previous' ); 1173 1174 previous.$slide.removeClass( 'fancybox-slide--complete fancybox-slide--current fancybox-slide--next fancybox-slide--previous' ); 1175 1176 previous.isComplete = false; 1177 1178 if ( !duration || ( !current.isMoved && !current.opts.transitionEffect ) ) { 1179 return; 1180 } 1181 1182 if ( current.isMoved ) { 1183 previous.$slide.addClass( transitionProps ); 1184 1185 } else { 1186 1187 transitionProps = 'fancybox-animated ' + transitionProps + ' fancybox-fx-' + current.opts.transitionEffect; 1188 1189 $.fancybox.animate( previous.$slide, transitionProps, duration, function() { 1190 previous.$slide.removeClass( transitionProps ).removeAttr( 'style' ); 1191 }); 1192 1193 } 1194 1195 }, 1196 1197 1198 // Create new "slide" element 1199 // These are gallery items that are actually added to DOM 1200 // ======================================================= 1201 1202 createSlide : function( pos ) { 1203 1204 var self = this; 1205 var $slide; 1206 var index; 1207 1208 index = pos % self.group.length; 1209 index = index < 0 ? self.group.length + index : index; 1210 1211 if ( !self.slides[ pos ] && self.group[ index ] ) {
1212 $slide = $('<div class="fancybox-slide"></div>').appendTo( self.$refs.stage ); 1213 1214 self.slides[ pos ] = $.extend( true, {}, self.group[ index ], { 1215 pos : pos, 1216 $slide : $slide, 1217 isLoaded : false, 1218 }); 1219 1220 self.updateSlide( self.slides[ pos ] ); 1221 } 1222 1223 return self.slides[ pos ]; 1224 }, 1225 1226 1227 // Scale image to the actual size of the image 1228 // =========================================== 1229 1230 scaleToActual : function( x, y, duration ) { 1231 1232 var self = this; 1233 1234 var current = self.current; 1235 var $what = current.$content; 1236 1237 var imgPos, posX, posY, scaleX, scaleY; 1238 1239 var canvasWidth = parseInt( current.$slide.width(), 10 ); 1240 var canvasHeight = parseInt( current.$slide.height(), 10 ); 1241 1242 var newImgWidth = current.width; 1243 var newImgHeight = current.height; 1244 1245 if ( !( current.type == 'image' && !current.hasError) || !$what || self.isAnimating ) { 1246 return; 1247 } 1248 1249 $.fancybox.stop( $what ); 1250 1251 self.isAnimating = true; 1252 1253 x = x === undefined ? canvasWidth * 0.5 : x; 1254 y = y === undefined ? canvasHeight * 0.5 : y; 1255 1256 imgPos = $.fancybox.getTranslate( $what ); 1257 1258 scaleX = newImgWidth / imgPos.width; 1259 scaleY = newImgHeight / imgPos.height; 1260 1261 // Get center position for original image 1262 posX = ( canvasWidth * 0.5 - newImgWidth * 0.5 ); 1263 posY = ( canvasHeight * 0.5 - newImgHeight * 0.5 ); 1264 1265 // Make sure image does not move away from edges 1266 if ( newImgWidth > canvasWidth ) { 1267 posX = imgPos.left * scaleX - ( ( x * scaleX ) - x ); 1268 1269 if ( posX > 0 ) { 1270 posX = 0; 1271 } 1272 1273 if ( posX < canvasWidth - newImgWidth ) { 1274 posX = canvasWidth - newImgWidth; 1275 } 1276 } 1277 1278 if ( newImgHeight > canvasHeight) { 1279 posY = imgPos.top * scaleY - ( ( y * scaleY ) - y ); 1280 1281 if ( posY > 0 ) { 1282 posY = 0; 1283 } 1284 1285 if ( posY < canvasHeight - newImgHeight ) { 1286 posY = canvasHeight - newImgHeight; 1287 } 1288 } 1289 1290 self.updateCursor( newImgWidth, newImgHeight ); 1291 1292 $.fancybox.animate( $what, { 1293 top : posY, 1294 left : posX, 1295 scaleX : scaleX, 1296 scaleY : scaleY 1297 }, duration || 330, function() { 1298 self.isAnimating = false; 1299 }); 1300 1301 // Stop slideshow 1302 if ( self.SlideShow && self.SlideShow.isActive ) { 1303 self.SlideShow.stop(); 1304 } 1305 }, 1306 1307 1308 // Scale image to fit inside parent element 1309 // ======================================== 1310 1311 scaleToFit : function( duration ) { 1312 1313 var self = this; 1314 1315 var current = self.current; 1316 var $what = current.$content; 1317 var end; 1318 1319 if ( !( current.type == 'image' && !current.hasError) || !$what || self.isAnimating ) { 1320 return; 1321 } 1322 1323 $.fancybox.stop( $what ); 1324 1325 self.isAnimating = true; 1326 1327 end = self.getFitPos( current ); 1328 1329 self.updateCursor( end.width, end.height ); 1330 1331 $.fancybox.animate( $what, { 1332 top : end.top, 1333 left : end.left, 1334 scaleX : end.width / $what.width(), 1335 scaleY : end.height / $what.height() 1336 }, duration || 330, function() { 1337 self.isAnimating = false; 1338 }); 1339 1340 }, 1341 1342 // Calculate image size to fit inside viewport 1343 // =========================================== 1344 1345 getFitPos : function( slide ) { 1346 var self = this; 1347 var $what = slide.$content; 1348 1349 var imgWidth = slide.width; 1350 var imgHeight = slide.height; 1351 1352 var margin = slide.opts.margin; 1353 1354 var canvasWidth, canvasHeight, minRatio, width, height; 1355 1356 if ( !$what || !$what.length || ( !imgWidth && !imgHeight) ) { 1357 return false; 1358 } 1359 1360 // Convert "margin to CSS style: [ top, right, bottom, left ] 1361 if ( $.type( margin ) === "number" ) { 1362 margin = [ margin, margin ]; 1363 } 1364 1365 if ( margin.length == 2 ) { 1366 margin = [ margin[0], margin[1], margin[0], margin[1] ]; 1367 } 1368 1369 // We can not use $slide width here, because it can have different diemensions while in transiton 1370 canvasWidth = parseInt( self.$refs.stage.width(), 10 ) - ( margin[ 1 ] + margin[ 3 ] ); 1371 canvasHeight = parseInt( self.$refs.stage.height(), 10 ) - ( margin[ 0 ] + margin[ 2 ] ); 1372 1373 minRatio = Math.min(1, canvasWidth / imgWidth, canvasHeight / imgHeight ); 1374 1375 width = Math.floor( minRatio * imgWidth ); 1376 height = Math.floor( minRatio * imgHeight ); 1377 1378 // Use floor rounding to make sure it really fits 1379 return { 1380 top : Math.floor( ( canvasHeight - height ) * 0.5 ) + margin[ 0 ], 1381 left : Math.floor( ( canvasWidth - width ) * 0.5 ) + margin[ 3 ], 1382 width : width, 1383 height : height 1384 }; 1385 1386 }, 1387 1388 1389 // Update content size and position for all slides 1390 // ============================================== 1391 1392 update : function() { 1393 var self = this; 1394 1395 $.each( self.slides, function( key, slide ) { 1396 self.updateSlide( slide ); 1397 }); 1398 }, 1399 1400 1401 // Update slide content position and size 1402 // ====================================== 1403 1404 updateSlide : function( slide, duration ) { 1405 var self = this, 1406 $what = slide && slide.$content; 1407 1408 if ( $what && ( slide.width || slide.height ) ) { 1409 self.isAnimating = false; 1410 1411 $.fancybox.stop( $what ); 1412 1413 $.fancybox.setTranslate( $what, self.getFitPos( slide ) ); 1414 1415 if ( slide.pos === self.currPos ) {
1416 self.updateCursor(); 1417 } 1418 } 1419 1420 slide.$slide.trigger( 'refresh' ); 1421 1422 self.trigger( 'onUpdate', slide ); 1423 1424 }, 1425 1426 1427 // Horizontally center slide 1428 // ========================= 1429 1430 centerSlide : function( slide, duration ) { 1431 var self = this, canvasWidth, pos; 1432 1433 if ( self.current ) { 1434 canvasWidth = Math.round( slide.$slide.width() ); 1435 pos = slide.pos - self.current.pos; 1436 1437 $.fancybox.animate( slide.$slide, { 1438 top : 0, 1439 left : ( pos * canvasWidth ) + ( pos * slide.opts.gutter ), 1440 opacity : 1 1441 }, duration === undefined ? 0 : duration, null, false); 1442 } 1443 }, 1444 1445 1446 // Update cursor style depending if content can be zoomed 1447 // ====================================================== 1448 1449 updateCursor : function( nextWidth, nextHeight ) { 1450 1451 var self = this; 1452 var isScaledDown; 1453 1454 var $container = self.$refs.container.removeClass( 'fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-drag fancybox-can-zoomOut' ); 1455 1456 if ( !self.current || self.isClosing ) { 1457 return; 1458 } 1459 1460 if ( self.isZoomable() ) { 1461 1462 $container.addClass( 'fancybox-is-zoomable' ); 1463 1464 if ( nextWidth !== undefined && nextHeight !== undefined ) { 1465 isScaledDown = nextWidth < self.current.width && nextHeight < self.current.height; 1466 1467 } else { 1468 isScaledDown = self.isScaledDown(); 1469 } 1470 1471 if ( isScaledDown ) { 1472 1473 // If image is scaled down, then, obviously, it can be zoomed to full size 1474 $container.addClass( 'fancybox-can-zoomIn' ); 1475 1476 } else { 1477 1478 if ( self.current.opts.touch ) { 1479 1480 // If image size ir largen than available available and touch module is not disable, 1481 // then user can do panning 1482 $container.addClass( 'fancybox-can-drag' ); 1483 1484 } else { 1485 $container.addClass( 'fancybox-can-zoomOut' ); 1486 } 1487 1488 } 1489 1490 } else if ( self.current.opts.touch ) { 1491 $container.addClass( 'fancybox-can-drag' ); 1492 } 1493 1494 }, 1495 1496 1497 // Check if current slide is zoomable 1498 // ================================== 1499 1500 isZoomable : function() { 1501 1502 var self = this; 1503 1504 var current = self.current; 1505 var fitPos; 1506 1507 if ( !current || self.isClosing ) { 1508 return; 1509 } 1510 1511 // Assume that slide is zoomable if 1512 // - image is loaded successfuly 1513 // - click action is "zoom" 1514 // - actual size of the image is smaller than available area 1515 if ( current.type === 'image' && current.isLoaded && !current.hasError && 1516 ( current.opts.clickContent === 'zoom' || ( $.isFunction( current.opts.clickContent ) && current.opts.clickContent( current ) === "zoom" ) ) 1517 ) { 1518 1519 fitPos = self.getFitPos( current ); 1520 1521 if ( current.width > fitPos.width || current.height > fitPos.height ) { 1522 return true; 1523 } 1524 1525 } 1526 1527 return false; 1528 1529 }, 1530 1531 1532 // Check if current image dimensions are smaller than actual 1533 // ========================================================= 1534 1535 isScaledDown : function() { 1536 1537 var self = this; 1538 1539 var current = self.current; 1540 var $what = current.$content; 1541 1542 var rez = false; 1543 1544 if ( $what ) { 1545 rez = $.fancybox.getTranslate( $what ); 1546 rez = rez.width < current.width || rez.height < current.height; 1547 } 1548 1549 return rez; 1550 1551 }, 1552 1553 1554 // Check if image dimensions exceed parent element 1555 // =============================================== 1556 1557 canPan : function() { 1558 1559 var self = this; 1560 1561 var current = self.current; 1562 var $what = current.$content; 1563 1564 var rez = false; 1565 1566 if ( $what ) { 1567 rez = self.getFitPos( current ); 1568 rez = Math.abs( $what.width() - rez.width ) > 1 || Math.abs( $what.height() - rez.height ) > 1; 1569 } 1570 1571 return rez; 1572 1573 }, 1574 1575 1576 // Load content into the slide 1577 // =========================== 1578 1579 loadSlide : function( slide ) { 1580 1581 var self = this, type, $slide; 1582 var ajaxLoad; 1583 1584 if ( slide.isLoading ) { 1585 return; 1586 } 1587 1588 if ( slide.isLoaded ) { 1589 return; 1590 } 1591 1592 slide.isLoading = true; 1593 1594 self.trigger( 'beforeLoad', slide ); 1595 1596 type = slide.type; 1597 $slide = slide.$slide; 1598 1599 $slide 1600 .off( 'refresh' ) 1601 .trigger( 'onReset' ) 1602 .addClass( 'fancybox-slide--' + ( type || 'unknown' ) ) 1603 .addClass( slide.opts.slideClass ); 1604 1605 // Create content depending on the type 1606 1607 switch ( type ) { 1608 1609 case 'image': 1610 1611 self.setImage( slide ); 1612 1613 break; 1614 1615 case 'iframe': 1616 1617 self.setIframe( slide ); 1618 1619 break; 1620 1621 case 'html': 1622 1623 self.setContent( slide, slide.src || slide.content ); 1624 1625 break; 1626 1627 case 'inline': 1628 1629 if ( $( slide.src ).length ) { 1630 self.setContent( slide, $( slide.src ) ); 1631 1632 } else { 1633 self.setError( slide ); 1634 } 1635 1636 break; 1637 1638 case 'ajax': 1639 1640 self.showLoading( slide ); 1641 1642 ajaxLoad = $.ajax( $.extend( {}, slide.opts.ajax.settings, { 1643 url : slide.src, 1644 success : function ( data, textStatus ) { 1645 1646 if ( textStatus === 'success' ) { 1647 self.setContent( slide, data ); 1648 } 1649 1650 }, 1651 error : function ( jqXHR, textStatus ) { 1652 1653 if ( jqXHR && textStatus !== 'abort' ) { 1654 self.setError( slide ); 1655 } 1656 1657 } 1658 })); 1659 1660 $slide.one( 'onReset', function () { 1661 ajaxLoad.abort(); 1662 }); 1663 1664 break; 1665 1666 case 'video' : 1667 1668 self.setContent( slide, 1669 '<video controls>' + 1670 '<source src="' + slide.src + '" type="' + slide.opts.videoFormat + '">' + 1671 'Your browser doesn\'t support HTML5 video' + 1672 '</video>' 1673 ); 1674 1675 break; 1676 1677 default: 1678 1679 self.setError( slide ); 1680 1681 break; 1682 1683 } 1684 1685 return true; 1686 1687 }, 1688 1689 1690 // Use thumbnail image, if possible 1691 // ================================ 1692 1693 setImage : function( slide ) { 1694 1695 var self = this; 1696 var srcset = slide.opts.srcset || slide.opts.image.srcset; 1697
1698 var found, temp, pxRatio, windowWidth; 1699 1700 // If we have "srcset", then we need to find matching "src" value. 1701 // This is necessary, because when you set an src attribute, the browser will preload the image 1702 // before any javascript or even CSS is applied. 1703 if ( srcset ) { 1704 pxRatio = window.devicePixelRatio || 1; 1705 windowWidth = window.innerWidth * pxRatio; 1706 1707 temp = srcset.split(',').map(function ( el ) { 1708 var ret = {}; 1709 1710 el.trim().split(/\s+/).forEach(function ( el, i ) { 1711 var value = parseInt( el.substring(0, el.length - 1), 10 ); 1712 1713 if ( i === 0 ) { 1714 return ( ret.url = el ); 1715 } 1716 1717 if ( value ) { 1718 ret.value = value; 1719 ret.postfix = el[ el.length - 1 ]; 1720 } 1721 1722 }); 1723 1724 return ret; 1725 }); 1726 1727 // Sort by value 1728 temp.sort(function (a, b) { 1729 return a.value - b.value; 1730 }); 1731 1732 // Ok, now we have an array of all srcset values 1733 for ( var j = 0; j < temp.length; j++ ) { 1734 var el = temp[ j ]; 1735 1736 if ( ( el.postfix === 'w' && el.value >= windowWidth ) || ( el.postfix === 'x' && el.value >= pxRatio ) ) { 1737 found = el; 1738 break; 1739 } 1740 } 1741 1742 // If not found, take the last one 1743 if ( !found && temp.length ) { 1744 found = temp[ temp.length - 1 ]; 1745 } 1746 1747 if ( found ) { 1748 slide.src = found.url; 1749 1750 // If we have default width/height values, we can calculate height for matching source 1751 if ( slide.width && slide.height && found.postfix == 'w' ) { 1752 slide.height = ( slide.width / slide.height ) * found.value; 1753 slide.width = found.value; 1754 } 1755 } 1756 } 1757 1758 // This will be wrapper containing both ghost and actual image 1759 slide.$content = $('<div class="fancybox-image-wrap"></div>') 1760 .addClass( 'fancybox-is-hidden' ) 1761 .appendTo( slide.$slide ); 1762 1763 1764 // If we have a thumbnail, we can display it while actual image is loading 1765 // Users will not stare at black screen and actual image will appear gradually 1766 if ( slide.opts.preload !== false && slide.opts.width && slide.opts.height && ( slide.opts.thumb || slide.opts.$thumb ) ) { 1767 1768 slide.width = slide.opts.width; 1769 slide.height = slide.opts.height; 1770 1771 slide.$ghost = $('<img />') 1772 .one('error', function() { 1773 1774 $(this).remove(); 1775 1776 slide.$ghost = null; 1777 1778 self.setBigImage( slide ); 1779 1780 }) 1781 .one('load', function() { 1782 1783 self.afterLoad( slide ); 1784 1785 self.setBigImage( slide ); 1786 1787 }) 1788 .addClass( 'fancybox-image' ) 1789 .appendTo( slide.$content ) 1790 .attr( 'src', slide.opts.thumb || slide.opts.$thumb.attr( 'src' ) ); 1791 1792 } else { 1793 1794 self.setBigImage( slide ); 1795 1796 } 1797 1798 }, 1799 1800 1801 // Create full-size image 1802 // ====================== 1803 1804 setBigImage : function ( slide ) { 1805 var self = this; 1806 var $img = $('<img />'); 1807 1808 slide.$image = $img 1809 .one('error', function() { 1810 1811 self.setError( slide ); 1812 1813 }) 1814 .one('load', function() { 1815 1816 // Clear timeout that checks if loading icon needs to be displayed 1817 clearTimeout( slide.timouts ); 1818 1819 slide.timouts = null; 1820 1821 if ( self.isClosing ) { 1822 return; 1823 } 1824 1825 slide.width = slide.opts.width || this.naturalWi
1825dth; 1826 slide.height = slide.opts.height || this.naturalHeight; 1827 1828 if ( slide.opts.image.srcset ) { 1829 $img.attr( 'sizes', '100vw' ).attr( 'srcset', slide.opts.image.srcset ); 1830 } 1831 1832 self.hideLoading( slide ); 1833 1834 if ( slide.$ghost ) { 1835 1836 slide.timouts = setTimeout(function() { 1837 slide.timouts = null; 1838 1839 slide.$ghost.hide(); 1840 1841 }, Math.min( 300, Math.max( 1000, slide.height / 1600 ) ) ); 1842 1843 } else { 1844 self.afterLoad( slide ); 1845 } 1846 1847 }) 1848 .addClass( 'fancybox-image' ) 1849 .attr('src', slide.src) 1850 .appendTo( slide.$content ); 1851 1852 if ( ( $img[0].complete || $img[0].readyState == "complete" ) && $img[0].naturalWidth && $img[0].naturalHeight ) { 1853 $img.trigger( 'load' ); 1854 1855 } else if( $img[0].error ) { 1856 $img.trigger( 'error' ); 1857 1858 } else { 1859 1860 slide.timouts = setTimeout(function() { 1861 if ( !$img[0].complete && !slide.hasError ) { 1862 self.showLoading( slide ); 1863 } 1864 1865 }, 100); 1866 1867 } 1868 1869 }, 1870 1871 1872 // Create iframe wrapper, iframe and bindings 1873 // ========================================== 1874 1875 setIframe : function( slide ) { 1876 var self = this, 1877 opts = slide.opts.iframe, 1878 $slide = slide.$slide, 1879 $iframe; 1880 1881 slide.$content = $('<div class="fancybox-content' + ( opts.preload ? ' fancybox-is-hidden' : '' ) + '"></div>') 1882 .css( opts.css ) 1883 .appendTo( $slide ); 1884 1885 $iframe = $( opts.tpl.replace(/\{rnd\}/g, new Date().getTime()) ) 1886 .attr( opts.attr ) 1887 .appendTo( slide.$content ); 1888 1889 if ( opts.preload ) { 1890 1891 self.showLoading( slide ); 1892 1893 // Unfortunately, it is not always possible to determine if iframe is successfully loaded 1894 // (due to browser security policy) 1895 1896 $iframe.on('load.fb error.fb', function(e) { 1897 this.isReady = 1; 1898 1899 slide.$slide.trigger( 'refresh' ); 1900 1901 self.afterLoad( slide ); 1902 }); 1903 1904 // Recalculate iframe content size 1905 // =============================== 1906 1907 $slide.on('refresh.fb', function() { 1908 var $wrap = slide.$content, 1909 frameWidth = opts.css.width, 1910 frameHeight = opts.css.height, 1911 scrollWidth, 1912 $contents, 1913 $body; 1914 1915 if ( $iframe[0].isReady !== 1 ) { 1916 return; 1917 } 1918 1919 // Check if content is accessible, 1920 // it will fail if frame is not with the same origin 1921 1922 try { 1923 $contents = $iframe.contents(); 1924 $body = $contents.find('body'); 1925 1926 } catch (ignore) {} 1927 1928 // Calculate dimensions for the wrapper 1929 if ( $body && $body.length ) { 1930 1931 if ( frameWidth === undefined ) { 1932 scrollWidth = $iframe[0].contentWindow.document.documentElement.scrollWidth; 1933 1934 frameWidth = Math.ceil( $body.outerWidth(true) + ( $wrap.width() - scrollWidth ) ); 1935 frameWidth += $wrap.outerWidth() - $wrap.innerWidth(); 1936 } 1937 1938 if ( frameHeight === undefined ) { 1939 frameHeight = Math.ceil( $body.outerHeight(true) ); 1940 frameHeight += $wrap.outerHeight() - $wrap.innerHeight(); 1941 } 1942 1943 // Resize wrapper to fit iframe content 1944 if ( frameWidth ) { 1945 $wrap.width( frameWidth ); 1946 } 1947 1948 if ( frameHeight ) { 1949 $wrap.height( frameHeight ); 1950 } 1951 } 1952 1953 $wrap.removeClass( 'fancybox-is-hidden' ); 1954 1955 }); 1956 1957 } else { 1958 1959 this.afterLoad( slide ); 1960 1961 } 1962 1963 $iframe.attr( 'src', slide.src ); 1964 1965 if ( slide.opts.smallBtn === true ) {
1966 slide.$content.prepend( self.translate( slide, slide.opts.btnTpl.smallBtn ) ); 1967 } 1968 1969 // Remove iframe if closing or changing gallery item 1970 $slide.one( 'onReset', function () { 1971 1972 // This helps IE not to throw errors when closing 1973 try { 1974 1975 $( this ).find( 'iframe' ).hide().attr( 'src', '//about:blank' ); 1976 1977 } catch ( ignore ) {} 1978 1979 $( this ).empty(); 1980 1981 slide.isLoaded = false; 1982 1983 }); 1984 1985 }, 1986 1987 1988 // Wrap and append content to the slide 1989 // ====================================== 1990 1991 setContent : function ( slide, content ) { 1992 1993 var self = this; 1994 1995 if ( self.isClosing ) { 1996 return; 1997 } 1998 1999 self.hideLoading( slide ); 2000 2001 slide.$slide.empty(); 2002 2003 if ( isQuery( content ) && content.parent().length ) { 2004 2005 // If content is a jQuery object, then it will be moved to the slide. 2006 // The placeholder is created so we will know where to put it back. 2007 // If user is navigating gallery fast, then the content might be already inside fancyBox 2008 // ===================================================================================== 2009 2010 // Make sure content is not already moved to fancyBox 2011 content.parent( '.fancybox-slide--inline' ).trigger( 'onReset' ); 2012 2013 // Create temporary element marking original place of the content 2014 slide.$placeholder = $( '<div></div>' ).hide().insertAfter( content ); 2015 2016 // Make sure content is visible 2017 content.css('display', 'inline-block'); 2018 2019 } else if ( !slide.hasError ) { 2020 2021 // If content is just a plain text, try to convert it to html 2022 if ( $.type( content ) === 'string' ) { 2023 content = $('<div>').append( $.trim( content ) ).contents(); 2024 2025 // If we have text node, then add wrapping element to make vertical alignment work 2026 if ( content[0].nodeType === 3 ) { 2027 content = $('<div>').html( content ); 2028 } 2029 } 2030 2031 // If "filter" option is provided, then filter content 2032 if ( slide.opts.filter ) { 2033 content = $('<div>').html( content ).find( slide.opts.filter ); 2034 } 2035 2036 } 2037 2038 slide.$slide.one('onReset', function () { 2039 2040 // Pause all html5 video/audio 2041 $( this ).find( 'video,audio' ).trigger( 'pause' ); 2042 2043 // Put content back 2044 if ( slide.$placeholder ) { 2045 slide.$placeholder.after( content.hide() ).remove(); 2046 2047 slide.$placeholder = null; 2048 } 2049 2050 // Remove custom close button 2051 if ( slide.$smallBtn ) { 2052 slide.$smallBtn.remove(); 2053 2054 slide.$smallBtn = null; 2055 } 2056 2057 // Remove content and mark slide as not loaded 2058 if ( !slide.hasError ) { 2059 $(this).empty(); 2060 2061 slide.isLoaded = false; 2062 } 2063 2064 }); 2065 2066 slide.$content = $( content ).appendTo( slide.$slide ); 2067 2068 this.afterLoad( slide ); 2069 }, 2070 2071 // Display error message 2072 // ===================== 2073 2074 setError : function ( slide ) { 2075 2076 slide.hasError = true; 2077 2078 slide.$slide.removeClass( 'fancybox-slide--' + slide.type ); 2079 2080 this.setContent( slide, this.translate( slide, slide.opts.errorTpl ) ); 2081 2082 }, 2083 2084 2085 // Show loading icon inside the slide 2086 // ================================== 2087 2088 showLoading : function( slide ) { 2089 2090 var self = this; 2091 2092 slide = slide || self.current; 2093 2094 if ( slide && !slide.$spinner ) { 2095 slide.$spinner = $( self.opts.spinnerTpl ).appendTo( slide.$slide ); 2096 } 2097 2098 }, 2099 2100 // Remove loading icon from the slide 2101 // ================================== 2102 2103 hideLoading : function( slide ) { 2104 2105 var self = this; 2106 2107 slide = slide || self.current; 2108 2109 if ( slide && slide.$spinner ) { 2110 slide.$spinner.remove(); 2111 2112 delete slide.$spinner; 2113 } 2114 2115 }, 2116 2117 2118 // Adjustments after slide content has been loaded 2119 // =============================================== 2120 2121 afterLoad : function( slide ) { 2122 2123 var self = this; 2124 2125 if ( self.isClosing ) { 2126 return; 2127 } 2128 2129 slide.isLoading = false; 2130 slide.isLoaded = true; 2131 2132 self.trigger( 'afterLoad', slide ); 2133 2134 self.hideLoading( slide ); 2135 2136 if ( slide.opts.smallBtn && !slide.$smallBtn ) { 2137 slide.$smallBtn = $( self.translate( slide, slide.opts.btnTpl.smallBtn ) ).appendTo( slide.$content.filter('div,form').first() ); 2138 } 2139 2140 if ( slide.opts.protect && slide.$content && !slide.hasError ) { 2141 2142 // Disable right click 2143 slide.$content.on( 'contextmenu.fb', function( e ) { 2144 if ( e.button == 2 ) { 2145 e.preventDefault(); 2146 } 2147 2148 return true; 2149 }); 2150 2151 // Add fake element on top of the image 2152 // This makes a bit harder for user to select image 2153 if ( slide.type === 'image' ) { 2154 $( '<div class="fancybox-spaceball"></div>' ).appendTo( slide.$content ); 2155 } 2156 2157 } 2158 2159 self.revealContent( slide ); 2160 2161 }, 2162 2163 2164 // Make content visible 2165 // This method is called right after content has been loaded or 2166 // user navigates gallery and transition should start 2167 // ============================================================ 2168 2169 revealContent : function( slide ) { 2170 2171 var self = this; 2172 var $slide = slide.$slide; 2173 2174 var effect, effectClassName, duration, opacity, end, start = false; 2175 2176 effect = slide.opts[ self.firstRun ? 'animationEffect' : 'transitionEffect' ]; 2177 duration = slide.opts[ self.firstRun ? 'animationDuration' : 'transitionDuration' ]; 2178 2179 duration = parseInt( slide.forcedDuration === undefined ? duration : slide.forcedDuration, 10 ); 2180 2181 if ( slide.isMoved || slide.pos !== self.currPos || !duration ) { 2182 effect = false; 2183 } 2184 2185 // Check if can zoom 2186 if ( effect === 'zoom' && !( slide.pos === self.currPos && duration && slide.type === 'image' && !slide.hasError && ( start = self.getThumbPos( slide ) ) ) ) { 2187 effect = 'fade'; 2188 } 2189 2190 // Zoom animation 2191 // ============== 2192 2193 if ( effect === 'zoom' ) { 2194 end = self.getFitPos( slide ); 2195 2196 end.scaleX = end.width / start.width; 2197 end.scaleY = end.height / start.height; 2198 2199 delete end.width; 2200 delete end.height; 2201 2202 // Check if we need to animate opacity 2203 opacity = slide.opts.zoomOpacity; 2204 2205 if ( opacity == 'auto' ) { 2206 opacity = Math.abs( slide.width / slide.height - start.width / start.height ) > 0.1; 2207 } 2208 2209 if ( opacity ) { 2210 start.opacity = 0.1; 2211 end.opacity = 1; 2212 } 2213 2214 // Draw image at start position 2215 $.fancybox.setTranslate( slide.$content.removeClass( 'fancybox-is-hidden' ), start ); 2216 2217 forceRedraw( slide.$content ); 2218 2219 // Start animation 2220 $.fancybox.animate( slide.$content, end, duration, function() { 2221 self.complete(); 2222 }); 2223 2224 return; 2225 } 2226 2227 self.updateSlide( slide ); 2228 2229 2230 // Simply show content 2231 // =================== 2232 2233 if ( !effect ) { 2234 forceRedraw( $slide ); 2235 2236 slide.$content.removeClass( 'fancybox-is-hidden' ); 2237 2238 if ( slide.pos === self.currPos ) { 2239 self.complete(); 2240 } 2241 2242 return; 2243 } 2244 2245 $.fancybox.stop( $slide ); 2246 2247 effectClassName = 'fancybox-animated fancybox-slide--' + ( slide.pos >= self.prevPos ? 'next' : 'previous' ) + ' fancybox-fx-' + effect; 2248 2249 $slide.removeAttr( 'style' ).removeClass( 'fancybox-slide--current fancybox-slide--next fancybox-slide--previous' ).addClass( effectClassName ); 2250 2251 slide.$content.removeClass( 'fancybox-is-hidden' ); 2252 2253 //Force reflow for CSS3 transitions 2254 forceRedraw( $slide ); 2255 2256 $.fancybox.animate( $slide, 'fancybox-slide--current', duration, function(e) { 2257 $slide.removeClass( effectClassName ).removeAttr( 'style' ); 2258 2259 if ( slide.pos === self.currPos ) { 2260 self.complete(); 2261 } 2262 2263 }, true); 2264 2265 }, 2266 2267 2268 // Check if we can and have to zoom from thumbnail 2269 //================================================ 2270 2271 getThumbPos : function( slide ) { 2272 2273 var self = this; 2274 var rez = false; 2275 2276 // Check if element is inside the viewport by at least 1 pixel 2277 var isElementVisible = function( $el ) { 2278 var element = $el[0]; 2279 2280 var elementRect = element.getBoundingClientRect(); 2281 var parentRects = []; 2282 2283 var visibleInAllParents; 2284 2285 while ( element.parentElement !== null ) { 2286 if ( $(element.parentElement).css('overflow') === 'hidden' || $(element.parentElement).css('overflow') === 'auto' ) { 2287 parentRects.push(element.parentElement.getBoundingClientRect()); 2288 } 2289 2290 element = element.parentElement; 2291 } 2292 2293 visibleInAllParents = parentRects.every(function(parentRect){ 2294 var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left); 2295 var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top); 2296 2297 return visiblePixelX > 0 && visiblePixelY > 0; 2298 }); 2299 2300 return visibleInAllParents && 2301 elementRect.bottom > 0 && elementRect.right > 0 && 2302 elementRect.left < $(window).width() && elementRect.top < $(window).height(); 2303 }; 2304 2305 var $thumb = slide.opts.$thumb; 2306 var thumbPos = $thumb ? $thumb.offset() : 0; 2307 var slidePos; 2308 2309 if ( thumbPos && $thumb[0].ownerDocument === document && isElementVisible( $thumb ) ) { 2310 slidePos = self.$refs.stage.offset(); 2311 2312 rez = { 2313 top : thumbPos.top - slidePos.top + parseFloat( $thumb.css( "border-top-width" ) || 0 ), 2314 left : thumbPos.left - slidePos.left + parseFloat( $thumb.css( "border-left-width" ) || 0 ), 2315 width : $thumb.width(), 2316 height : $thumb.height(), 2317 scaleX : 1, 2318 scaleY : 1 2319 }; 2320 } 2321 2322 return rez; 2323 }, 2324 2325 2326 // Final adjustments after current gallery item is moved to position 2327 // and it`s content is loaded 2328 // ================================================================== 2329 2330 complete : function() { 2331 var self = this, 2332 current = self.current, 2333 slides = {}, 2334 promise; 2335 2336 if ( current.isMoved || !current.isLoaded || current.isComplete ) { 2337 return; 2338 } 2339 2340 current.isComplete = true; 2341 2342 current.$slide.siblings().trigger( 'onReset' ); 2343 2344 self.preload( 'inline' ); 2345 2346 // Trigger any CSS3 transiton inside the slide 2347 forceRedraw( current.$slide ); 2348 2349 current.$slide.addClass( 'fancybox-slide--complete' ); 2350 2351 // Remove unnecessary slides 2352 $.each( self.slides, function( key, slide ) { 2353 if ( slide.pos >= self.currPos - 1 && slide.pos <= self.currPos + 1 ) { 2354 slides[ slide.pos ] = slide; 2355 2356 } else if ( slide ) { 2357 $.fancybox.stop( slide.$slide ); 2358 2359 slide.$slide.off().remove(); 2360 } 2361 }); 2362 2363 self.slides = slides; 2364
2365 self.updateCursor(); 2366 2367 self.trigger( 'afterShow' ); 2368 2369 // Play first html5 video/audio 2370 current.$slide.find( 'video,audio' ).first().trigger( 'play' ); 2371 2372 // Try to focus on the first focusable element 2373 if ( $( document.activeElement ).is( '[disabled]' ) || ( current.opts.autoFocus && !( current.type == 'image' || current.type === 'iframe' ) ) ) { 2374 self.focus(); 2375 } 2376 2377 }, 2378 2379 2380 // Preload next and previous slides 2381 // ================================ 2382 2383 preload : function( type ) { 2384 var self = this, 2385 next = self.slides[ self.currPos + 1 ], 2386 prev = self.slides[ self.currPos - 1 ]; 2387 2388 if ( next && next.type === type ) { 2389 self.loadSlide( next ); 2390 } 2391 2392 if ( prev && prev.type === type ) { 2393 self.loadSlide( prev ); 2394 } 2395 }, 2396 2397 2398 // Try to find and focus on the first focusable element 2399 // ==================================================== 2400 2401 focus : function() { 2402 var current = this.current; 2403 var $el; 2404 2405 if ( this.isClosing ) { 2406 return; 2407 } 2408 2409 if ( current && current.isComplete ) { 2410 2411 // Look for first input with autofocus attribute 2412 $el = current.$slide.find('input[autofocus]:enabled:visible:first'); 2413 2414 if ( !$el.length ) { 2415 $el = current.$slide.find('button,:input,[tabindex],a').filter(':enabled:visible:first'); 2416 } 2417 } 2418 2419 $el = $el && $el.length ? $el : this.$refs.container; 2420 2421 $el.focus(); 2422 }, 2423 2424 2425 // Activates current instance - brings container to the front and enables keyboard, 2426 // notifies other instances about deactivating 2427 // ================================================================================= 2428 2429 activate : function () { 2430 var self = this; 2431 2432 // Deactivate all instances 2433 $( '.fancybox-container' ).each(function () { 2434 var instance = $(this).data( 'FancyBox' ); 2435 2436 // Skip self and closing instances 2437 if (instance && instance.id !== self.id && !instance.isClosing) { 2438 instance.trigger( 'onDeactivate' ); 2439 2440 instance.removeEvents(); 2441 2442 instance.isVisible = false; 2443 } 2444 2445 }); 2446 2447 self.isVisible = true; 2448 2449 if ( self.current || self.isIdle ) { 2450 self.update(); 2451 2452 self.updateControls(); 2453 } 2454 2455 self.trigger( 'onActivate' ); 2456 2457 self.addEvents(); 2458 }, 2459 2460 2461 // Start closing procedure 2462 // This will start "zoom-out" animation if needed and clean everything up afterwards 2463 // ================================================================================= 2464 2465 close : function( e, d ) { 2466 2467 var self = this; 2468 var current = self.current; 2469 2470 var effect, duration; 2471 var $what, opacity, start, end; 2472 2473 var done = function() { 2474 self.cleanUp( e ); 2475 }; 2476 2477 if ( self.isClosing ) { 2478 return false; 2479 } 2480 2481 self.isClosing = true; 2482 2483 // If beforeClose callback prevents closing, make sure content is centered 2484 if ( self.trigger( 'beforeClose', e ) === false ) { 2485 self.isClosing = false; 2486 2487 requestAFrame(function() { 2488 self.update(); 2489 }); 2490 2491 return false; 2492 } 2493 2494 // Remove all events 2495 // If there are multiple instances, they will be set again by "activate" method 2496 self.removeEvents(); 2497 2498 if ( current.timouts ) { 2499 clearTimeout( current.timouts ); 2500 } 2501 2502 $what = current.$content; 2503 effect = current.opts.animationEffect; 2504 duration = $.isNumeric( d ) ? d : ( effect ? current.opts.animationDuration : 0 ); 2505 2506 // Remove other slides 2507 current.$slide.off( transitionEnd ).removeClass( 'fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated' ); 2508 2509 current.$slide.siblings().trigger( 'onReset' ).remove(); 2510 2511 // Trigger animations 2512 if ( duration ) { 2513 self.$refs.container.removeClass( 'fancybox-is-open' ).addClass( 'fancybox-is-closing' ); 2514 } 2515 2516 // Clean up 2517 self.hideLoading( current ); 2518 2519 self.hideControls(); 2520
2521 self.updateCursor(); 2522 2523 // Check if possible to zoom-out 2524 if ( effect === 'zoom' && !( e !== true && $what && duration && current.type === 'image' && !current.hasError && ( end = self.getThumbPos( current ) ) ) ) { 2525 effect = 'fade'; 2526 } 2527 2528 if ( effect === 'zoom' ) { 2529 $.fancybox.stop( $what ); 2530 2531 start = $.fancybox.getTranslate( $what ); 2532 2533 start.width = start.width * start.scaleX; 2534 start.height = start.height * start.scaleY; 2535 2536 // Check if we need to animate opacity 2537 opacity = current.opts.zoomOpacity; 2538 2539 if ( opacity == 'auto' ) { 2540 opacity = Math.abs( current.width / current.height - end.width / end.height ) > 0.1; 2541 } 2542 2543 if ( opacity ) { 2544 end.opacity = 0; 2545 } 2546 2547 start.scaleX = start.width / end.width; 2548 start.scaleY = start.height / end.height; 2549 2550 start.width = end.width; 2551 start.height = end.height; 2552 2553 $.fancybox.setTranslate( current.$content, start ); 2554 2555 forceRedraw( current.$content ); 2556 2557 $.fancybox.animate( current.$content, end, duration, done ); 2558 2559 return true; 2560 } 2561 2562 if ( effect && duration ) { 2563 2564 // If skip animation 2565 if ( e === true ) { 2566 setTimeout( done, duration ); 2567 2568 } else { 2569 $.fancybox.animate( current.$slide.removeClass( 'fancybox-slide--current' ), 'fancybox-animated fancybox-slide--previous fancybox-fx-' + effect, duration, done ); 2570 } 2571 2572 } else { 2573 done(); 2574 } 2575 2576 return true; 2577 }, 2578 2579 2580 // Final adjustments after removing the instance 2581 // ============================================= 2582 2583 cleanUp : function( e ) { 2584 var self = this, 2585 $body = $( 'body' ), 2586 instance, 2587 offset; 2588 2589 self.current.$slide.trigger( 'onReset' ); 2590 2591 self.$refs.container.empty().remove(); 2592 2593 self.trigger( 'afterClose', e ); 2594 2595 // Place back focus 2596 if ( self.$lastFocus && !!self.current.opts.backFocus ) { 2597 self.$lastFocus.focus(); 2598 } 2599 2600 self.current = null; 2601 2602 // Check if there are other instances 2603 instance = $.fancybox.getInstance(); 2604 2605 if ( instance ) { 2606 instance.activate(); 2607 2608 } else { 2609 2610 $W.scrollTop( self.scrollTop ).scrollLeft( self.scrollLeft ); 2611 2612 $body.removeClass( 'fancybox-active compensate-for-scrollbar' ); 2613 2614 if ( $body.hasClass( 'fancybox-iosfix' ) ) { 2615 offset = parseInt(document.body.style.top, 10); 2616 2617 $body.removeClass( 'fancybox-iosfix' ).css( 'top', '' ).scrollTop( offset * -1 ); 2618 } 2619 2620 $( '#fancybox-style-noscroll' ).remove(); 2621 2622 } 2623 2624 }, 2625 2626 2627 // Call callback and trigger an event 2628 // ================================== 2629 2630 trigger : function( name, slide ) { 2631 var args = Array.prototype.slice.call(arguments, 1), 2632 self = this, 2633 obj = slide && slide.opts ? slide : self.current, 2634 rez; 2635 2636 if ( obj ) { 2637 args.unshift( obj ); 2638 2639 } else { 2640 obj = self; 2641 } 2642 2643 args.unshift( self ); 2644 2645 if ( $.isFunction( obj.opts[ name ] ) ) { 2646 rez = obj.opts[ name ].apply( obj, args ); 2647 } 2648 2649 if ( rez === false ) { 2650 return rez; 2651 } 2652 2653 if ( name === 'afterClose' || !self.$refs ) { 2654 $D.trigger( name + '.fb', args ); 2655 2656 } else { 2657 self.$refs.container.trigger( name + '.fb', args ); 2658 } 2659 2660 }, 2661 2662 2663 // Update infobar values, navigation button states and reveal caption 2664 // ================================================================== 2665 2666 updateControls : function ( force ) { 2667 2668 var self = this; 2669 2670 var current = self.current, 2671 index = current.index, 2672 caption = current.opts.caption, 2673 $container = self.$refs.container, 2674 $caption = self.$refs.caption; 2675 2676 // Recalculate content dimensions 2677 current.$slide.trigger( 'refresh' ); 2678 2679 self.$caption = caption && caption.length ? $caption.html( caption ) : null; 2680
2681 if ( !self.isHiddenControls && !self.isIdle ) { 2682 self.showControls(); 2683 } 2684 2685 // Update info and navigation elements 2686 $container.find('[data-fancybox-count]').html( self.group.length ); 2687 $container.find('[data-fancybox-index]').html( index + 1 ); 2688 2689 $container.find('[data-fancybox-prev]').prop( 'disabled', ( !current.opts.loop && index <= 0 ) ); 2690 $container.find('[data-fancybox-next]').prop( 'disabled', ( !current.opts.loop && index >= self.group.length - 1 ) ); 2691 2692 if ( current.type === 'image' ) { 2693 2694 // Update download button source 2695 $container.find('[data-fancybox-download]').attr( 'href', current.opts.image.src || current.src ).show(); 2696 2697 } else { 2698 $container.find('[data-fancybox-download],[data-fancybox-zoom]').hide(); 2699 } 2700 }, 2701 2702 // Hide toolbar and caption 2703 // ======================== 2704 2705 hideControls : function () { 2706 2707 this.isHiddenControls = true; 2708 2709 this.$refs.container.removeClass( 'fancybox-show-infobar fancybox-show-toolbar fancybox-show-caption fancybox-show-nav' ); 2710 2711 }, 2712 2713 showControls : function() { 2714 var self = this; 2715 var opts = self.current ? self.current.opts : self.opts; 2716 var $container = self.$refs.container; 2717 2718 self.isHiddenControls = false; 2719 self.idleSecondsCounter = 0; 2720 2721 $container 2722 .toggleClass( 'fancybox-show-toolbar', !!( opts.toolbar && opts.buttons ) ) 2723 .toggleClass( 'fancybox-show-infobar', !!( opts.infobar && self.group.length > 1 ) ) 2724 .toggleClass( 'fancybox-show-nav', !!( opts.arrows && self.group.length > 1 ) ) 2725 .toggleClass( 'fancybox-is-modal', !!opts.modal ); 2726 2727 if ( self.$caption ) { 2728 $container.addClass( 'fancybox-show-caption '); 2729 2730 } else { 2731 $container.removeClass( 'fancybox-show-caption' ); 2732 } 2733 2734 }, 2735 2736 2737 // Toggle toolbar and caption 2738 // ========================== 2739 2740 toggleControls : function() { 2741 if ( this.isHiddenControls ) { 2742 this.showControls(); 2743 2744 } else { 2745 this.hideControls(); 2746 } 2747 2748 }, 2749 2750 2751 }); 2752 2753 2754 $.fancybox = { 2755 2756 version : "3.2.10", 2757 defaults : defaults, 2758 2759 2760 // Get current instance and execute a command. 2761 // 2762 // Examples of usage: 2763 // 2764 // $instance = $.fancybox.getInstance(); 2765 // $.fancybox.getInstance().jumpTo( 1 ); 2766 // $.fancybox.getInstance( 'jumpTo', 1 ); 2767 // $.fancybox.getInstance( function() { 2768 // console.info( this.currIndex ); 2769 // }); 2770 // ====================================================== 2771 2772 getInstance : function ( command ) { 2773 var instance = $('.fancybox-container:not(".fancybox-is-closing"):last').data( 'FancyBox' ); 2774 var args = Array.prototype.slice.call(arguments, 1); 2775 2776 if ( instance instanceof FancyBox ) { 2777 2778 if ( $.type( command ) === 'string' ) { 2779 instance[ command ].apply( instance, args ); 2780 2781 } else if ( $.type( command ) === 'function' ) { 2782 command.apply( instance, args ); 2783 } 2784 2785 return instance; 2786 } 2787 2788 return false; 2789 2790 }, 2791 2792 2793 // Create new instance 2794 // =================== 2795 2796 open : function ( items, opts, index ) { 2797 return new FancyBox( items, opts, index ); 2798 }, 2799 2800 2801 // Close current or all instances 2802 // ============================== 2803 2804 close : function ( all ) { 2805 var instance = this.getInstance(); 2806 2807 if ( instance ) { 2808 instance.close(); 2809 2810 // Try to find and close next instance 2811 2812 if ( all === true ) { 2813 this.close(); 2814 } 2815 } 2816 2817 }, 2818 2819 // Close instances and unbind all events 2820 // ============================== 2821 2822 destroy : function() { 2823 2824 this.close( true ); 2825 2826 $D.off( 'click.fb-start' ); 2827 2828 }, 2829 2830 2831 // Try to detect mobile devices 2832 // ============================ 2833 2834 isMobile : document.createTouch !== undefined && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent), 2835 2836 2837 // Detect if 'translate3d' support is available 2838 // ============================================ 2839 2840 use3d : (function() { 2841 var div = document.createElement('div'); 2842 2843 return window.getComputedStyle && window.getComputedStyle( div ).getPropertyValue('transform') && !(document.documentMode && document.documentMode < 11);
2844 }()), 2845 2846 // Helper function to get current visual state of an element 2847 // returns array[ top, left, horizontal-scale, vertical-scale, opacity ] 2848 // ===================================================================== 2849 2850 getTranslate : function( $el ) { 2851 var matrix; 2852 2853 if ( !$el || !$el.length ) { 2854 return false; 2855 } 2856 2857 matrix = $el.eq( 0 ).css('transform'); 2858 2859 if ( matrix && matrix.indexOf( 'matrix' ) !== -1 ) { 2860 matrix = matrix.split('(')[1]; 2861 matrix = matrix.split(')')[0]; 2862 matrix = matrix.split(','); 2863 } else { 2864 matrix = []; 2865 } 2866 2867 if ( matrix.length ) { 2868 2869 // If IE 2870 if ( matrix.length > 10 ) { 2871 matrix = [ matrix[13], matrix[12], matrix[0], matrix[5] ]; 2872 2873 } else { 2874 matrix = [ matrix[5], matrix[4], matrix[0], matrix[3]]; 2875 } 2876 2877 matrix = matrix.map(parseFloat); 2878 2879 } else { 2880 matrix = [ 0, 0, 1, 1 ]; 2881 2882 var transRegex = /\.*translate\((.*)px,(.*)px\)/i; 2883 var transRez = transRegex.exec( $el.eq( 0 ).attr('style') ); 2884 2885 if ( transRez ) { 2886 matrix[ 0 ] = parseFloat( transRez[2] ); 2887 matrix[ 1 ] = parseFloat( transRez[1] ); 2888 } 2889 } 2890 2891 return { 2892 top : matrix[ 0 ], 2893 left : matrix[ 1 ], 2894 scaleX : matrix[ 2 ], 2895 scaleY : matrix[ 3 ], 2896 opacity : parseFloat( $el.css('opacity') ), 2897 width : $el.width(), 2898 height : $el.height() 2899 }; 2900 2901 }, 2902 2903 2904 // Shortcut for setting "translate3d" properties for element 2905 // Can set be used to set opacity, too 2906 // ======================================================== 2907 2908 setTranslate : function( $el, props ) { 2909 var str = ''; 2910 var css = {}; 2911 2912 if ( !$el || !props ) { 2913 return; 2914 } 2915 2916 if ( props.left !== undefined || props.top !== undefined ) { 2917 str = ( props.left === undefined ? $el.position().left : props.left ) + 'px, ' + ( props.top === undefined ? $el.position().top : props.top ) + 'px'; 2918 2919 if ( this.use3d ) { 2920 str = 'translate3d(' + str + ', 0px)'; 2921 2922 } else { 2923 str = 'translate(' + str + ')'; 2924 } 2925 } 2926 2927 if ( props.scaleX !== undefined && props.scaleY !== undefined ) { 2928 str = (str.length ? str + ' ' : '') + 'scale(' + props.scaleX + ', ' + props.scaleY + ')'; 2929 } 2930 2931 if ( str.length ) { 2932 css.transform = str; 2933 } 2934 2935 if ( props.opacity !== undefined ) { 2936 css.opacity = props.opacity; 2937 } 2938 2939 if ( props.width !== undefined ) { 2940 css.width = props.width; 2941 } 2942 2943 if ( props.height !== undefined ) { 2944 css.height = props.height; 2945 } 2946 2947 return $el.css( css ); 2948 }, 2949 2950 2951 // Simple CSS transition handler 2952 // ============================= 2953 2954 animate : function ( $el, to, duration, callback, leaveAnimationName ) { 2955 if ( $.isFunction( duration ) ) { 2956 callback = duration; 2957 duration = null; 2958 } 2959 2960 if ( !$.isPlainObject( to ) ) { 2961 $el.removeAttr( 'style' ); 2962 } 2963 2964 $el.on( transitionEnd, function(e) { 2965 2966 // Skip events from child elements and z-index change 2967 if ( e && e.originalEvent && ( !$el.is( e.originalEvent.target ) || e.originalEvent.propertyName == 'z-index' ) ) { 2968 return; 2969 } 2970 2971 $.fancybox.stop( $el ); 2972 2973 if ( $.isPlainObject( to ) ) { 2974 2975 if ( to.scaleX !== undefined && to.scaleY !== undefined ) { 2976 $el.css( 'transition-duration', '' ); 2977 2978 to.width = Math.round( $el.width() * to.scaleX ); 2979 to.height = Math.round( $el.height() * to.scaleY ); 2980 2981 to.scaleX = 1; 2982 to.scaleY = 1; 2983 2984 $.fancybox.setTranslate( $el, to ); 2985 } 2986 2987 if ( leaveAnimationName === false ) { 2988 $el.removeAttr( 'style' ); 2989 } 2990 2991 } else if ( leaveAnimationName !== true ) { 2992 $el.removeClass( to ); 2993 } 2994 2995 if ( $.isFunction( callback ) ) { 2996 callback( e ); 2997 } 2998 2999 }); 3000 3001 if ( $.isNumeric( duration ) ) { 3002 $el.css( 'transition-duration', duration + 'ms' ); 3003 } 3004 3005 if ( $.isPlainObject( to ) ) { 3006 $.fancybox.setTranslate( $el, to ); 3007 3008 } else { 3009 $el.addClass( to ); 3010 } 3011 3012 if ( to.scaleX && $el.hasClass( 'fancybox-image-wrap' ) ) { 3013 $el.parent().addClass( 'fancybox-is-scaling' ); 3014 } 3015 3016 // Make sure that `transitionend` callback gets fired 3017 $el.data("timer", setTimeout(function() { 3018 $el.trigger( 'transitionend' ); 3019 }, duration + 16)); 3020 3021 }, 3022 3023 stop : function( $el ) { 3024 clearTimeout( $el.data("timer") ); 3025 3026 $el.off( 'transitionend' ).css( 'transition-duration', '' ); 3027 3028 if ( $el.hasClass( 'fancybox-image-wrap' ) ) { 3029 $el.parent().removeClass( 'fancybox-is-scaling' ); 3030 } 3031 } 3032 3033 }; 3034 3035 3036 // Default click handler for "fancyboxed" links 3037 // ============================================ 3038 3039 function _run( e ) { 3040 var $target = $( e.currentTarget ), 3041 opts = e.data ? e.data.options : {}, 3042 value = $target.attr( 'data-fancybox' ) || '', 3043 index = 0, 3044 items = []; 3045 3046 // Avoid opening multiple times 3047 if ( e.isDefaultPrevented() ) { 3048 return; 3049 } 3050 3051 e.preventDefault(); 3052 3053 // Get all related items and find index for clicked one 3054 if ( value ) { 3055 items = opts.selector ? $( opts.selector ) : ( e.data ? e.data.items : [] ); 3056 items = items.length ? items.filter( '[data-fancybox="' + value + '"]' ) : $( '[data-fancybox="' + value + '"]' ); 3057 3058 index = items.index( $target ); 3059 3060 // Sometimes current item can not be found 3061 // (for example, when slider clones items) 3062 if ( index < 0 ) { 3063 index = 0; 3064 } 3065 3066 } else { 3067 items = [ $target ]; 3068 } 3069 3070 $.fancybox.open( items, opts, index ); 3071 } 3072 3073 3074 // Create a jQuery plugin 3075 // ====================== 3076 3077 $.fn.fancybox = function (options) { 3078 var selector; 3079 3080 options = options || {}; 3081 selector = options.selector || false; 3082 3083 if ( selector ) { 3084 3085 $( 'body' ).off( 'click.fb-start', selector ).on( 'click.fb-start', selector, { 3086 options : options 3087 }, _run ); 3088 3089 } else { 3090 3091 this.off( 'click.fb-start' ).on( 'click.fb-start', { 3092 items : this, 3093 options : options 3094 }, _run); 3095 3096 } 3097 3098 return this; 3099 }; 3100 3101 3102 // Self initializing plugin 3103 // ======================== 3104 3105 $D.on( 'click.fb-start', '[data-fancybox]', _run ); 3106 3107}( window, document, window.jQuery || jQuery ));
vendor: 4,127 bytes, lines 3108-3258
3108 3109// ========================================================================== 3110// 3111// Media 3112// Adds additional media type support 3113// 3114// ========================================================================== 3115;(function ($) { 3116 3117 'use strict'; 3118 3119 // Formats matching url to final form 3120 3121 var format = function (url, rez, params) { 3122 if ( !url ) { 3123 return; 3124 } 3125 3126 params = params || ''; 3127 3128 if ( $.type(params) === "object" ) { 3129 params = $.param(params, true); 3130 } 3131 3132 $.each(rez, function (key, value) { 3133 url = url.replace('$' + key, value || ''); 3134 }); 3135 3136 if (params.length) { 3137 url += (url.indexOf('?') > 0 ? '&' : '?') + params; 3138 } 3139 3140 return url; 3141 }; 3142 3143 // Object containing properties for each media type 3144 3145 var defaults = { 3146 youtube : { 3147 matcher : /(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i, 3148 params : { 3149 autoplay : 1, 3150 autohide : 1, 3151 fs : 1, 3152 rel : 0, 3153 hd : 1, 3154 wmode : 'transparent', 3155 enablejsapi : 1, 3156 html5 : 1 3157 }, 3158 paramPlace : 8, 3159 type : 'iframe', 3160 url : '//www.youtube.com/embed/$4', 3161 thumb : '//img.youtube.com/vi/$4/hqdefault.jpg' 3162 }, 3163 3164 vimeo : { 3165 matcher : /^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/, 3166 params : { 3167 autoplay : 1, 3168 hd : 1, 3169 show_title : 1, 3170 show_byline : 1, 3171 show_portrait : 0, 3172 fullscreen : 1, 3173 api : 1 3174 }, 3175 paramPlace : 3, 3176 type : 'iframe', 3177 url : '//player.vimeo.com/video/$2' 3178 }, 3179 3180 metacafe : { 3181 matcher : /metacafe.com\/watch\/(\d+)\/(.*)?/, 3182 type : 'iframe', 3183 url : '//www.metacafe.com/embed/$1/?ap=1' 3184 }, 3185 3186 dailymotion : { 3187 matcher : /dailymotion.com\/video\/(.*)\/?(.*)/, 3188 params : { 3189 additionalInfos : 0, 3190 autoStart : 1 3191 }, 3192 type : 'iframe', 3193 url : '//www.dailymotion.com/embed/video/$1' 3194 }, 3195 3196 vine : { 3197 matcher : /vine.co\/v\/([a-zA-Z0-9\?\=\-]+)/, 3198 type : 'iframe', 3199 url : '//vine.co/v/$1/embed/simple' 3200 }, 3201 3202 instagram : { 3203 matcher : /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i, 3204 type : 'image', 3205 url : '//$1/p/$2/media/?size=l' 3206 }, 3207 3208 // Examples: 3209 // http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16 3210 // https://www.google.com/maps/@37.7852006,-122.4146355,14.65z 3211 // https://www.google.com/maps/place/Googleplex/@37.4220041,-122.0833494,17z/data=!4m5!3m4!1s0x0:0x6c296c66619367e0!8m2!3d37.4219998!4d-122.0840572 3212 gmap_place : { 3213 matcher : /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(((maps\/(place\/(.*)\/)?\@(.*),(\d+.?\d+?)z))|(\?ll=))(.*)?/i, 3214 type : 'iframe', 3215 url : function (rez) { 3216 return '//maps.google.' + rez[2] + '/?ll=' + ( rez[9] ? rez[9] + '&z=' + Math.floor( rez[10] ) + ( rez[12] ? rez[12].replace(/^\//, "&") : '' ) : rez[12] ) + '&output=' + ( rez[12] && rez[12].indexOf('layer=c') > 0 ? 'svembed' : 'embed' ); 3217 } 3218 }, 3219 3220 // Examples: 3221 // https://www.google.com/maps/search/Empire+State+Building/ 3222 // https://www.google.com/maps/search/?api=1&query=centurylink+field 3223 // https://www.google.com/maps/search/?api=1&query=47.5951518,-122.3316393 3224 gmap_search : { 3225 matcher : /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(maps\/search\/)(.*)/i, 3226 type : 'iframe', 3227 url : function (rez) { 3228 return '//maps.google.' + rez[2] + '/maps?q=' + rez[5].replace('query=', 'q=').replace('api=1', '') + '&output=embed'; 3229 } 3230 } 3231 }; 3232 3233 $(document).on('objectNeedsType.fb', function (e, instance, item) { 3234 3235 var url = item.src || '', 3236 type = false, 3237 media, 3238 thumb, 3239 rez, 3240 params, 3241 urlParams, 3242 paramObj, 3243 provider; 3244 3245 media = $.extend( true, {}, defaults, item.opts.media ); 3246 3247 // Look for any matching media type 3248 $.each(media, function ( providerName, providerOpts ) { 3249 rez = url.match( providerOpts.matcher ); 3250 3251 if ( !rez ) { 3252 return; 3253 } 3254 3255 type = providerOpts.type; 3256 paramObj = {}; 3257 3258 if ( providerOpts.paramPlace && rez[ providerOpts.paramPlace ] ) {
3259 urlParams = rez[ providerOpts.paramPlace ]; 3260 3261 if ( urlParams[ 0 ] == '?' ) { 3262 urlParams = urlParams.substring(1); 3263 } 3264 3265 urlParams = urlParams.split('&'); 3266 3267 for ( var m = 0; m < urlParams.length; ++m ) { 3268 var p = urlParams[ m ].split('=', 2); 3269 3270 if ( p.length == 2 ) { 3271 paramObj[ p[0] ] = decodeURIComponent( p[1].replace(/\+/g, " ") ); 3272 } 3273 } 3274 } 3275 3276 params = $.extend( true, {}, providerOpts.params, item.opts[ providerName ], paramObj ); 3277 3278 url = $.type( providerOpts.url ) === "function" ? providerOpts.url.call( this, rez, params, item ) : format( providerOpts.url, rez, params ); 3279 thumb = $.type( providerOpts.thumb ) === "function" ? providerOpts.thumb.call( this, rez, params, item ) : format( providerOpts.thumb, rez ); 3280 3281 if ( providerName === 'vimeo' ) { 3282 url = url.replace('&%23', '#'); 3283 } 3284 3285 return false; 3286 }); 3287 3288 // If it is found, then change content type and update the url 3289 3290 if ( type ) { 3291 item.src = url; 3292 item.type = type; 3293 3294 if ( !item.opts.thumb && !( item.opts.$thumb && item.opts.$thumb.length ) ) { 3295 item.opts.thumb = thumb; 3296 } 3297 3298 if ( type === 'iframe' ) { 3299 $.extend(true, item.opts, { 3300 iframe : { 3301 preload : false, 3302 attr : { 3303 scrolling : "no" 3304 } 3305 } 3306 }); 3307 3308 item.contentProvider = provider; 3309 3310 item.opts.slideClass += ' fancybox-slide--' + ( provider == 'gmap_place' || provider == 'gmap_search' ? 'map' : 'video' ); 3311 } 3312 3313 } else if ( url ) { 3314 item.type = item.opts.defaultType; 3315 } 3316 3317 }); 3318 3319}( window.jQuery || jQuery )); 3320 3321// ========================================================================== 3322// 3323// Guestures 3324// Adds touch guestures, handles click and tap events 3325// 3326// ========================================================================== 3327;(function (window, document, $) { 3328 'use strict'; 3329 3330 var requestAFrame = (function () { 3331 return window.requestAnimationFrame || 3332 window.webkitRequestAnimationFrame || 3333 window.mozRequestAnimationFrame || 3334 window.oRequestAnimationFrame || 3335 // if all else fails, use setTimeout 3336 function (callback) { 3337 return window.setTimeout(callback, 1000 / 60); 3338 }; 3339 })(); 3340 3341 var cancelAFrame = (function () { 3342 return window.cancelAnimationFrame || 3343 window.webkitCancelAnimationFrame || 3344 window.mozCancelAnimationFrame || 3345 window.oCancelAnimationFrame || 3346 function (id) { 3347 window.clearTimeout(id); 3348 }; 3349 })(); 3350 3351 var pointers = function( e ) { 3352 var result = []; 3353 3354 e = e.originalEvent || e || window.e; 3355 e = e.touches && e.touches.length ? e.touches : ( e.changedTouches && e.changedTouches.length ? e.changedTouches : [ e ] ); 3356 3357 for ( var key in e ) { 3358 3359 if ( e[ key ].pageX ) { 3360 result.push( { x : e[ key ].pageX, y : e[ key ].pageY } ); 3361 3362 } else if ( e[ key ].clientX ) { 3363 result.push( { x : e[ key ].clientX, y : e[ key ].clientY } ); 3364 } 3365 } 3366 3367 return result; 3368 }; 3369 3370 var distance = function( point2, point1, what ) { 3371 if ( !point1 || !point2 ) { 3372 return 0; 3373 } 3374 3375 if ( what === 'x' ) { 3376 return point2.x - point1.x; 3377 3378 } else if ( what === 'y' ) { 3379 return point2.y - point1.y; 3380 } 3381 3382 return Math.sqrt( Math.pow( point2.x - point1.x, 2 ) + Math.pow( point2.y - point1.y, 2 ) ); 3383 }; 3384 3385 var isClickable = function( $el ) { 3386 if ( $el.is('a,area,button,[role="button"],input,label,select,summary,textarea') || $.isFunction( $el.get(0).onclick ) || $el.data('selectable') ) { 3387 return true; 3388 } 3389 3390 // Check for attributes like data-fancybox-next or data-fancybox-close 3391 for ( var i = 0, atts = $el[0].attributes, n = atts.length; i < n; i++ ) { 3392 if ( atts[i].nodeName.substr(0, 14) === 'data-fancybox-' ) { 3393 return true; 3394 } 3395 } 3396 3397 return false; 3398 }; 3399 3400 var hasScrollbars = function( el ) { 3401 var overflowY = window.getComputedStyle( el )['overflow-y']; 3402 var overflowX = window.getComputedStyle( el )['overflow-x']; 3403 3404 var vertical = (overflowY === 'scroll' || overflowY === 'auto') && el.scrollHeight > el.clientHeight; 3405 var horizontal = (overflowX === 'scroll' || overflowX === 'auto') && el.scrollWidth > el.clientWidth; 3406 3407 return vertical || horizontal; 3408 }; 3409 3410 var isScrollable = function ( $el ) { 3411 var rez = false; 3412 3413 while ( true ) { 3414 rez = hasScrollbars( $el.get(0) ); 3415 3416 if ( rez ) { 3417 break; 3418 } 3419 3420 $el = $el.parent(); 3421 3422 if ( !$el.length || $el.hasClass( 'fancybox-stage' ) || $el.is( 'body' ) ) { 3423 break; 3424 } 3425 } 3426 3427 return rez; 3428 }; 3429 3430 3431 var Guestures = function ( instance ) { 3432 var self = this; 3433 3434 self.instance = instance; 3435 3436 self.$bg = instance.$refs.bg; 3437 self.$stage = instance.$refs.stage; 3438 self.$container = instance.$refs.container; 3439 3440 self.destroy(); 3441 3442 self.$container.on( 'touchstart.fb.touch mousedown.fb.touch', $.proxy(self, 'ontouchstart') ); 3443 }; 3444 3445 Guestures.prototype.destroy = function() { 3446 this.$container.off( '.fb.touch' ); 3447 }; 3448 3449 Guestures.prototype.ontouchstart = function( e ) { 3450 var self = this; 3451 3452 var $target = $( e.target ); 3453 var instance = self.instance; 3454 var current = instance.current; 3455 var $content = current.$content; 3456 3457 var isTouchDevice = ( e.type == 'touchstart' ); 3458
3459 // Do not respond to both (touch and mouse) events 3460 if ( isTouchDevice ) { 3461 self.$container.off( 'mousedown.fb.touch' ); 3462 } 3463 3464 // Ignore right click 3465 if ( e.originalEvent && e.originalEvent.button == 2 ) { 3466 return; 3467 } 3468 3469 // Ignore taping on links, buttons, input elements 3470 if ( !$target.length || isClickable( $target ) || isClickable( $target.parent() ) ) { 3471 return; 3472 } 3473 3474 // Ignore clicks on the scrollbar 3475 if ( !$target.is('img') && e.originalEvent.clientX > $target[0].clientWidth + $target.offset().left ) { 3476 return; 3477 } 3478 3479 // Ignore clicks while zooming or closing 3480 if ( !current || self.instance.isAnimating || self.instance.isClosing ) { 3481 e.stopPropagation(); 3482 e.preventDefault(); 3483 3484 return; 3485 } 3486 3487 self.realPoints = self.startPoints = pointers( e ); 3488 3489 if ( !self.startPoints ) { 3490 return; 3491 } 3492 3493 e.stopPropagation(); 3494 3495 self.startEvent = e; 3496 3497 self.canTap = true; 3498 self.$target = $target; 3499 self.$content = $content; 3500 self.opts = current.opts.touch; 3501 3502 self.isPanning = false; 3503 self.isSwiping = false; 3504 self.isZooming = false; 3505 self.isScrolling = false; 3506 3507 self.sliderStartPos = self.sliderLastPos || { top: 0, left: 0 }; 3508 self.contentStartPos = $.fancybox.getTranslate( self.$content ); 3509 self.contentLastPos = null; 3510 3511 self.startTime = new Date().getTime(); 3512 self.distanceX = self.distanceY = self.distance = 0; 3513 3514 self.canvasWidth = Math.round( current.$slide[0].clientWidth ); 3515 self.canvasHeight = Math.round( current.$slide[0].clientHeight ); 3516 3517 $(document) 3518 .off( '.fb.touch' ) 3519 .on( isTouchDevice ? 'touchend.fb.touch touchcancel.fb.touch' : 'mouseup.fb.touch mouseleave.fb.touch', $.proxy(self, "ontouchend")) 3520 .on( isTouchDevice ? 'touchmove.fb.touch' : 'mousemove.fb.touch', $.proxy(self, "ontouchmove")); 3521 3522 if ( $.fancybox.isMobile ) { 3523 document.addEventListener('scroll', self.onscroll, true); 3524 } 3525 3526 if ( !(self.opts || instance.canPan() ) || !( $target.is( self.$stage ) || self.$stage.find( $target ).length ) ) { 3527 3528 // Prevent image ghosting while dragging 3529 if ( $target.is('img') ) { 3530 e.preventDefault(); 3531 } 3532 3533 return; 3534 } 3535 3536 if ( !( $.fancybox.isMobile && ( isScrollable( $target ) || isScrollable( $target.parent() ) ) ) ) { 3537 e.preventDefault(); 3538 } 3539 3540 if ( self.startPoints.length === 1 ) { 3541 if ( current.type === 'image' && ( self.contentStartPos.width > self.canvasWidth + 1 || self.contentStartPos.height > self.canvasHeight + 1 ) ) { 3542 $.fancybox.stop( self.$content ); 3543 3544 self.$content.css( 'transition-duration', '' ); 3545 3546 self.isPanning = true; 3547 3548 } else { 3549 self.isSwiping = true; 3550 } 3551 3552 self.$container.addClass( 'fancybox-controls--isGrabbing' ); 3553 } 3554 3555 if ( self.startPoints.length === 2 && !instance.isAnimating && !current.hasError && current.type === 'image' && ( current.isLoaded || current.$ghost ) ) { 3556 self.canTap = false; 3557 self.isSwiping = false; 3558 self.isPanning = false; 3559 3560 self.isZooming = true; 3561 3562 $.fancybox.stop( self.$content ); 3563 3564 self.$content.css( 'transition-duration', '' ); 3565 3566 self.centerPointStartX = ( ( self.startPoints[0].x + self.startPoints[1].x ) * 0.5 ) - $(window).scrollLeft(); 3567 self.centerPointStartY = ( ( self.startPoints[0].y + self.startPoints[1].y ) * 0.5 ) - $(window).scrollTop(); 3568 3569 self.percentageOfImageAtPinchPointX = ( self.centerPointStartX - self.contentStartPos.left ) / self.contentStartPos.width; 3570 self.percentageOfImageAtPinchPointY = ( self.centerPointStartY - self.contentStartPos.top ) / self.contentStartPos.height; 3571 3572 self.startDistanceBetweenFingers = distance( self.startPoints[0], self.startPoints[1] ); 3573 } 3574 3575 }; 3576 3577 Guestures.prototype.onscroll = function(e) { 3578 self.isScrolling = true; 3579 }; 3580 3581 Guestures.prototype.ontouchmove = function( e ) { 3582 var self = this, 3583 $target = $(e.target); 3584 3585 if ( self.isScrolling || !( $target.is( self.$stage ) || self.$stage.find( $target ).length ) ) { 3586 self.canTap = false; 3587 3588 return; 3589 } 3590 3591 self.newPoints = pointers( e ); 3592 3593 if ( !( self.opts || self.instance.canPan() ) || !self.newPoints || !self.newPoints.length ) { 3594 return; 3595 } 3596 3597 if ( !(self.isSwiping && self.isSwiping === true) ) { 3598 e.preventDefault(); 3599 } 3600 3601 self.distanceX = distance( self.newPoints[0], self.startPoints[0], 'x' ); 3602 self.distanceY = distance( self.newPoints[0], self.startPoints[0], 'y' ); 3603 3604 self.distance = distance( self.newPoints[0], self.startPoints[0] ) 3605 3606 // Skip false ontouchmove events (Chrome) 3607 if ( self.distance > 0 ) { 3608 if ( self.isSwiping ) { 3609 self.onSwipe(e); 3610 3611 } else if ( self.isPanning ) { 3612 self.onPan(); 3613 3614 } else if ( self.isZooming ) { 3615 self.onZoom(); 3616 } 3617 } 3618 3619 }; 3620 3621 Guestures.prototype.onSwipe = function(e) { 3622 var self = this, 3623 swiping = self.isSwiping, 3624 left = self.sliderStartPos.left || 0, 3625 angle; 3626 3627 // If direction is not yet determined 3628 if ( swiping === true ) { 3629 3630 // We need at least 10px distance to correctly calculate an angle 3631 if ( Math.abs( self.distance ) > 10 ) { 3632 self.canTap = false; 3633 3634 if ( self.instance.group.length < 2 && self.opts.vertical ) { 3635 self.isSwiping = 'y'; 3636 3637 } else if ( self.instance.isDragging || self.opts.vertical === false || ( self.opts.vertical === 'auto' && $( window ).width() > 800 ) ) { 3638 self.isSwiping = 'x'; 3639 3640 } else { 3641 angle = Math.abs( Math.atan2( self.distanceY, self.distanceX ) * 180 / Math.PI ); 3642 3643 self.isSwiping = ( angle > 45 && angle < 135 ) ? 'y' : 'x'; 3644 } 3645 3646 self.canTap = false; 3647 3648 if ( self.isSwiping === 'y' && $.fancybox.isMobile && ( isScrollable( self.$target ) || isScrollable( self.$target.parent() ) ) ) { 3649 self.isScrolling = true; 3650 3651 return; 3652 } 3653 3654 self.instance.isDragging = self.isSwiping; 3655 3656 // Reset points to avoid jumping, because we dropped first swipes to calculate the angle 3657 self.startPoints = self.newPoints; 3658 3659 $.each(self.instance.slides, function( index, slide ) { 3660 $.fancybox.stop( slide.$slide ); 3661 3662 slide.$slide.css( 'transition-duration', '' ); 3663 3664 slide.inTransition = false; 3665 3666 if ( slide.pos === self.instance.current.pos ) { 3667 self.sliderStartPos.left = $.fancybox.getTranslate( slide.$slide ).left; 3668 } 3669 }); 3670 3671 // Stop slideshow 3672 if ( self.instance.SlideShow && self.instance.SlideShow.isActive ) { 3673 self.instance.SlideShow.stop(); 3674 } 3675 } 3676 3677 return; 3678 } 3679 3680 // Sticky edges 3681 if ( swiping == 'x' ) { 3682 if ( self.distanceX > 0 && ( self.instance.group.length < 2 || ( self.instance.current.index === 0 && !self.instance.current.opts.loop ) ) ) { 3683 left = left + Math.pow( self.distanceX, 0.8 ); 3684 3685 } else if ( self.distanceX < 0 && ( self.instance.group.length < 2 || ( self.instance.current.index === self.instance.group.length - 1 && !self.instance.current.opts.loop ) ) ) { 3686 left = left - Math.pow( -self.distanceX, 0.8 ); 3687 3688 } else { 3689 left = left + self.distanceX; 3690 } 3691 } 3692 3693 self.sliderLastPos = { 3694 top : swiping == 'x' ? 0 : self.sliderStartPos.top + self.distanceY, 3695 left : left 3696 }; 3697 3698 if ( self.requestId ) { 3699 cancelAFrame( self.requestId ); 3700 3701 self.requestId = null; 3702 } 3703 3704 self.requestId = requestAFrame(function() { 3705 3706 if ( self.sliderLastPos ) { 3707 $.each(self.instance.slides, function( index, slide ) { 3708 var pos = slide.pos - self.instance.currPos; 3709 3710 $.fancybox.setTranslate( slide.$slide, { 3711 top : self.sliderLastPos.top, 3712 left : self.sliderLastPos.left + ( pos * self.canvasWidth ) + ( pos * slide.opts.gutter ) 3713 });
3714 }); 3715 3716 self.$container.addClass( 'fancybox-is-sliding' ); 3717 } 3718 3719 }); 3720 3721 }; 3722 3723 Guestures.prototype.onPan = function() { 3724 var self = this; 3725 3726 // Sometimes, when tapping causally, image can move a bit and that breaks double tapping 3727 if ( distance( self.newPoints[0], self.realPoints[0] ) < ($.fancybox.isMobile ? 10 : 5) ) { 3728 self.startPoints = self.newPoints; 3729 return; 3730 } 3731 3732 self.canTap = false; 3733 3734 self.contentLastPos = self.limitMovement(); 3735 3736 if ( self.requestId ) { 3737 cancelAFrame( self.requestId ); 3738 3739 self.requestId = null; 3740 } 3741 3742 self.requestId = requestAFrame(function() { 3743 $.fancybox.setTranslate( self.$content, self.contentLastPos ); 3744 }); 3745 }; 3746 3747 // Make panning sticky to the edges 3748 Guestures.prototype.limitMovement = function() { 3749 var self = this; 3750 3751 var canvasWidth = self.canvasWidth; 3752 var canvasHeight = self.canvasHeight; 3753 3754 var distanceX = self.distanceX; 3755 var distanceY = self.distanceY; 3756 3757 var contentStartPos = self.contentStartPos; 3758 3759 var currentOffsetX = contentStartPos.left; 3760 var currentOffsetY = contentStartPos.top; 3761 3762 var currentWidth = contentStartPos.width; 3763 var currentHeight = contentStartPos.height; 3764 3765 var minTranslateX, minTranslateY, 3766 maxTranslateX, maxTranslateY, 3767 newOffsetX, newOffsetY; 3768 3769 if ( currentWidth > canvasWidth ) { 3770 newOffsetX = currentOffsetX + distanceX; 3771 3772 } else { 3773 newOffsetX = currentOffsetX; 3774 } 3775 3776 newOffsetY = currentOffsetY + distanceY; 3777 3778 // Slow down proportionally to traveled distance 3779 minTranslateX = Math.max( 0, canvasWidth * 0.5 - currentWidth * 0.5 ); 3780 minTranslateY = Math.max( 0, canvasHeight * 0.5 - currentHeight * 0.5 ); 3781 3782 maxTranslateX = Math.min( canvasWidth - currentWidth, canvasWidth * 0.5 - currentWidth * 0.5 ); 3783 maxTranslateY = Math.min( canvasHeight - currentHeight, canvasHeight * 0.5 - currentHeight * 0.5 ); 3784 3785 if ( currentWidth > canvasWidth ) { 3786 3787 // -> 3788 if ( distanceX > 0 && newOffsetX > minTranslateX ) { 3789 newOffsetX = minTranslateX - 1 + Math.pow( -minTranslateX + currentOffsetX + distanceX, 0.8 ) || 0; 3790 } 3791 3792 // <- 3793 if ( distanceX < 0 && newOffsetX < maxTranslateX ) { 3794 newOffsetX = maxTranslateX + 1 - Math.pow( maxTranslateX - currentOffsetX - distanceX, 0.8 ) || 0; 3795 } 3796 3797 } 3798 3799 if ( currentHeight > canvasHeight ) { 3800 3801 // \/ 3802 if ( distanceY > 0 && newOffsetY > minTranslateY ) { 3803 newOffsetY = minTranslateY - 1 + Math.pow(-minTranslateY + currentOffsetY + distanceY, 0.8 ) || 0; 3804 } 3805 3806 // /\ 3807 if ( distanceY < 0 && newOffsetY < maxTranslateY ) { 3808 newOffsetY = maxTranslateY + 1 - Math.pow ( maxTranslateY - currentOffsetY - distanceY, 0.8 ) || 0; 3809 } 3810 3811 } 3812 3813 return { 3814 top : newOffsetY, 3815 left : newOffsetX, 3816 scaleX : contentStartPos.scaleX, 3817 scaleY : contentStartPos.scaleY 3818 }; 3819 3820 }; 3821 3822 Guestures.prototype.limitPosition = function( newOffsetX, newOffsetY, newWidth, newHeight ) { 3823 var self = this; 3824 3825 var canvasWidth = self.canvasWidth; 3826 var canvasHeight = self.canvasHeight; 3827 3828 if ( newWidth > canvasWidth ) { 3829 newOffsetX = newOffsetX > 0 ? 0 : newOffsetX; 3830 newOffsetX = newOffsetX < canvasWidth - newWidth ? canvasWidth - newWidth : newOffsetX; 3831 3832 } else { 3833 3834 // Center horizontally 3835 newOffsetX = Math.max( 0, canvasWidth / 2 - newWidth / 2 ); 3836 3837 } 3838 3839 if ( newHeight > canvasHeight ) { 3840 newOffsetY = newOffsetY > 0 ? 0 : newOffsetY; 3841 newOffsetY = newOffsetY < canvasHeight - newHeight ? canvasHeight - newHeight : newOffsetY; 3842 3843 } else { 3844 3845 // Center vertically 3846 newOffsetY = Math.max( 0, canvasHeight / 2 - newHeight / 2 ); 3847 3848 } 3849 3850 return { 3851 top : newOffsetY, 3852 left : newOffsetX 3853 }; 3854 3855 }; 3856 3857 Guestures.prototype.onZoom = function() { 3858 var self = this; 3859 3860 // Calculate current distance between points to get pinch ratio and new width and height 3861 3862 var currentWidth = self.contentStartPos.width; 3863 var currentHeight = self.contentStartPos.height; 3864 3865 var currentOffsetX = self.contentStartPos.left; 3866 var currentOffsetY = self.contentStartPos.top; 3867 3868 var endDistanceBetweenFingers = distance( self.newPoints[0], self.newPoints[1] ); 3869 3870 var pinchRatio = endDistanceBetweenFingers / self.startDistanceBetweenFingers; 3871 3872 var newWidth = Math.floor( currentWidth * pinchRatio ); 3873 var newHeight = Math.floor( currentHeight * pinchRatio ); 3874 3875 // This is the translation due to pinch-zooming 3876 var translateFromZoomingX = (currentWidth - newWidth) * self.percentageOfImageAtPinchPointX; 3877 var translateFromZoomingY = (currentHeight - newHeight) * self.percentageOfImageAtPinchPointY; 3878 3879 //Point between the two touches 3880 3881 var centerPointEndX = ((self.newPoints[0].x + self.newPoints[1].x) / 2) - $(window).scrollLeft(); 3882 var centerPointEndY = ((self.newPoints[0].y + self.newPoints[1].y) / 2) - $(window).scrollTop(); 3883 3884 // And this is the translation due to translation of the centerpoint 3885 // between the two fingers 3886 3887 var translateFromTranslatingX = centerPointEndX - self.centerPointStartX; 3888 var translateFromTranslatingY = centerPointEndY - self.centerPointStartY; 3889 3890 // The new offset is the old/current one plus the total translation 3891 3892 var newOffsetX = currentOffsetX + ( translateFromZoomingX + translateFromTranslatingX ); 3893 var newOffsetY = currentOffsetY + ( translateFromZoomingY + translateFromTranslatingY ); 3894 3895 var newPos = { 3896 top : newOffsetY, 3897 left : newOffsetX, 3898 scaleX : self.contentStartPos.scaleX * pinchRatio, 3899 scaleY : self.contentStartPos.scaleY * pinchRatio 3900 }; 3901 3902 self.canTap = false; 3903 3904 self.newWidth = newWidth; 3905 self.newHeight = newHeight; 3906 3907 self.contentLastPos = newPos; 3908 3909 if ( self.requestId ) { 3910 cancelAFrame( self.requestId ); 3911 3912 self.requestId = null; 3913 } 3914 3915 self.requestId = requestAFrame(function() { 3916 $.fancybox.setTranslate( self.$content, self.contentLastPos ); 3917 }); 3918 3919 }; 3920 3921 Guestures.prototype.ontouchend = function( e ) { 3922 var self = this; 3923 var dMs = Math.max( (new Date().getTime() ) - self.startTime, 1); 3924 3925 var swiping = self.isSwiping; 3926 var panning = self.isPanning; 3927 var zooming = self.isZooming; 3928 var scrolling = self.isScrolling; 3929 3930 self.endPoints = pointers( e ); 3931 3932 self.$container.removeClass( 'fancybox-controls--isGrabbing' ); 3933 3934 $(document).off( '.fb.touch' ); 3935 3936 document.removeEventListener('scroll', self.onscroll, true); 3937 3938 if ( self.requestId ) { 3939 cancelAFrame( self.requestId ); 3940 3941 self.requestId = null; 3942 } 3943 3944 self.isSwiping = false; 3945 self.isPanning = false; 3946 self.isZooming = false; 3947 self.isScrolling = false; 3948 3949 self.instance.isDragging = false; 3950 3951 if ( self.canTap ) {
3952 return self.onTap( e ); 3953 } 3954 3955 self.speed = 366; 3956 3957 // Speed in px/ms 3958 self.velocityX = self.distanceX / dMs * 0.5; 3959 self.velocityY = self.distanceY / dMs * 0.5; 3960 3961 self.speedX = Math.max( self.speed * 0.5, Math.min( self.speed * 1.5, ( 1 / Math.abs( self.velocityX ) ) * self.speed ) ); 3962 3963 if ( panning ) { 3964 self.endPanning(); 3965 3966 } else if ( zooming ) { 3967 self.endZooming(); 3968 3969 } else { 3970 self.endSwiping( swiping, scrolling ); 3971 } 3972 3973 return; 3974 }; 3975 3976 Guestures.prototype.endSwiping = function( swiping, scrolling ) { 3977 var self = this, 3978 ret = false, 3979 len = self.instance.group.length; 3980 3981 self.sliderLastPos = null; 3982 3983 // Close if swiped vertically / navigate if horizontally 3984 if ( swiping == 'y' && !scrolling && Math.abs( self.distanceY ) > 50 ) { 3985 3986 // Continue vertical movement 3987 $.fancybox.animate( self.instance.current.$slide, { 3988 top : self.sliderStartPos.top + self.distanceY + ( self.velocityY * 150 ), 3989 opacity : 0 3990 }, 150 ); 3991 3992 ret = self.instance.close( true, 300 ); 3993 3994 } else if ( swiping == 'x' && self.distanceX > 50 && len > 1 ) { 3995 ret = self.instance.previous( self.speedX ); 3996 3997 } else if ( swiping == 'x' && self.distanceX < -50 && len > 1 ) { 3998 ret = self.instance.next( self.speedX ); 3999 } 4000 4001 if ( ret === false && ( swiping == 'x' || swiping == 'y' ) ) { 4002 if ( scrolling || len < 2 ) { 4003 self.instance.centerSlide( self.instance.current, 150 ); 4004 } else { 4005 self.instance.jumpTo( self.instance.current.index ); 4006 } 4007 } 4008 4009 self.$container.removeClass( 'fancybox-is-sliding' ); 4010 4011 }; 4012 4013 // Limit panning from edges 4014 // ======================== 4015 4016 Guestures.prototype.endPanning = function() { 4017 4018 var self = this; 4019 var newOffsetX, newOffsetY, newPos; 4020 4021 if ( !self.contentLastPos ) { 4022 return; 4023 } 4024 4025 if ( self.opts.momentum === false ) { 4026 newOffsetX = self.contentLastPos.left; 4027 newOffsetY = self.contentLastPos.top; 4028 4029 } else { 4030 4031 // Continue movement 4032 newOffsetX = self.contentLastPos.left + ( self.velocityX * self.speed ); 4033 newOffsetY = self.contentLastPos.top + ( self.velocityY * self.speed ); 4034 } 4035 4036 newPos = self.limitPosition( newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height ); 4037 4038 newPos.width = self.contentStartPos.width; 4039 newPos.height = self.contentStartPos.height; 4040 4041 $.fancybox.animate( self.$content, newPos, 330 ); 4042 }; 4043 4044 4045 Guestures.prototype.endZooming = function() { 4046 var self = this; 4047 4048 var current = self.instance.current; 4049 4050 var newOffsetX, newOffsetY, newPos, reset; 4051 4052 var newWidth = self.newWidth; 4053 var newHeight = self.newHeight; 4054 4055 if ( !self.contentLastPos ) { 4056 return; 4057 } 4058 4059 newOffsetX = self.contentLastPos.left; 4060 newOffsetY = self.contentLastPos.top; 4061 4062 reset = { 4063 top : newOffsetY, 4064 left : newOffsetX, 4065 width : newWidth, 4066 height : newHeight, 4067 scaleX : 1, 4068 scaleY : 1 4069 }; 4070 4071 // Reset scalex/scaleY values; this helps for perfomance and does not break animation 4072 $.fancybox.setTranslate( self.$content, reset ); 4073 4074 if ( newWidth < self.canvasWidth && newHeight < self.canvasHeight ) { 4075 self.instance.scaleToFit( 150 ); 4076 4077 } else if ( newWidth > current.width || newHeight > current.height ) { 4078 self.instance.scaleToActual( self.centerPointStartX, self.centerPointStartY, 150 ); 4079 4080 } else { 4081 4082 newPos = self.limitPosition( newOffsetX, newOffsetY, newWidth, newHeight ); 4083 4084 // Switch from scale() to width/height or animation will not work correctly 4085 $.fancybox.setTranslate( self.content, $.fancybox.getTranslate( self.$content ) ); 4086 4087 $.fancybox.animate( self.$content, newPos, 150 ); 4088 } 4089 4090 }; 4091 4092 Guestures.prototype.onTap = function(e) { 4093 var self = this; 4094 var $target = $( e.target ); 4095 4096 var instance = self.instance; 4097 var current = instance.current; 4098 4099 var endPoints = ( e && pointers( e ) ) || self.startPoints; 4100 4101 var tapX = endPoints[0] ? endPoints[0].x - self.$stage.offset().left : 0; 4102 var tapY = endPoints[0] ? endPoints[0].y - self.$stage.offset().top : 0; 4103 4104 var where; 4105 4106 var process = function ( prefix ) { 4107 4108 var action = current.opts[ prefix ]; 4109 4110 if ( $.isFunction( action ) ) { 4111 action = action.apply( instance, [ current, e ] ); 4112 } 4113 4114 if ( !action) { 4115 return; 4116 } 4117 4118 switch ( action ) { 4119 4120 case "close" : 4121 4122 instance.close( self.startEvent ); 4123 4124 break; 4125 4126 case "toggleControls" : 4127 4128 instance.toggleControls( true ); 4129 4130 break; 4131 4132 case "next" : 4133 4134 instance.next(); 4135 4136 break; 4137 4138 case "nextOrClose" : 4139 4140 if ( instance.group.length > 1 ) { 4141 instance.next(); 4142 4143 } else { 4144 instance.close( self.startEvent ); 4145 } 4146 4147 break; 4148 4149 case "zoom" : 4150 4151 if ( current.type == 'image' && ( current.isLoaded || current.$ghost ) ) { 4152 4153 if ( instance.canPan() ) { 4154 instance.scaleToFit(); 4155 4156 } else if ( instance.isScaledDown() ) { 4157 instance.scaleToActual( tapX, tapY ); 4158 4159 } else if ( instance.group.length < 2 ) { 4160 instance.close( self.startEvent ); 4161 } 4162 } 4163 4164 break; 4165 } 4166 4167 }; 4168 4169 // Ignore right click 4170 if ( e.originalEvent && e.originalEvent.button == 2 ) { 4171 return; 4172 } 4173 4174 // Skip if clicked on the scrollbar 4175 if ( !$target.is('img') && tapX > $target[0].clientWidth + $target.offset().left ) { 4176 return; 4177 } 4178 4179 // Check where is clicked 4180 if ( $target.is( '.fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container' ) ) { 4181 where = 'Outside'; 4182 4183 } else if ( $target.is( '.fancybox-slide' ) ) { 4184 where = 'Slide'; 4185 4186 } else if ( instance.current.$content && instance.current.$content.find( $target ).addBack().filter( $target ).length ) { 4187 where = 'Content'; 4188 4189 } else { 4190 return; 4191 } 4192 4193 // Check if this is a double tap 4194 if ( self.tapped ) { 4195 4196 // Stop previously created single tap 4197 clearTimeout( self.tapped ); 4198 self.tapped = null; 4199 4200 // Skip if distance between taps is too big 4201 if ( Math.abs( tapX - self.tapX ) > 50 || Math.abs( tapY - self.tapY ) > 50 ) { 4202 return this; 4203 } 4204 4205 // OK, now we assume that this is a double-tap
4206 process( 'dblclick' + where ); 4207 4208 } else { 4209 4210 // Single tap will be processed if user has not clicked second time within 300ms 4211 // or there is no need to wait for double-tap 4212 self.tapX = tapX; 4213 self.tapY = tapY; 4214 4215 if ( current.opts[ 'dblclick' + where ] && current.opts[ 'dblclick' + where ] !== current.opts[ 'click' + where ] ) { 4216 4217 self.tapped = setTimeout(function() { 4218 self.tapped = null; 4219 4220 process( 'click' + where ); 4221 4222 }, 500); 4223 4224 } else { 4225 process( 'click' + where ); 4226 } 4227 4228 } 4229 4230 return this; 4231 }; 4232 4233 $(document).on('onActivate.fb', function (e, instance) { 4234 if ( instance && !instance.Guestures ) { 4235 instance.Guestures = new Guestures( instance ); 4236 } 4237 }); 4238 4239}( window, document, window.jQuery || jQuery )); 4240 4241// ========================================================================== 4242// 4243// SlideShow 4244// Enables slideshow functionality 4245// 4246// Example of usage: 4247// $.fancybox.getInstance().SlideShow.start() 4248// 4249// ========================================================================== 4250;(function (document, $) { 4251 'use strict'; 4252 4253 $.extend(true, $.fancybox.defaults, { 4254 btnTpl : { 4255 slideShow : 4256 '<button data-fancybox-play class="fancybox-button fancybox-button--play" title="{{PLAY_START}}">' + 4257 '<svg viewBox="0 0 40 40">' + 4258 '<path d="M13,12 L27,20 L13,27 Z" />' + 4259 '<path d="M15,10 v19 M23,10 v19" />' + 4260 '</svg>' + 4261 '</button>' 4262 }, 4263 slideShow : { 4264 autoStart : false, 4265 speed : 3000 4266 } 4267 }); 4268 4269 var SlideShow = function( instance ) { 4270 this.instance = instance; 4271 this.init(); 4272 }; 4273 4274 $.extend( SlideShow.prototype, { 4275 timer : null, 4276 isActive : false, 4277 $button : null, 4278 4279 init : function() { 4280 var self = this; 4281 4282 self.$button = self.instance.$refs.toolbar.find('[data-fancybox-play]').on('click', function() { 4283 self.toggle(); 4284 }); 4285 4286 if ( self.instance.group.length < 2 || !self.instance.group[ self.instance.currIndex ].opts.slideShow ) { 4287 self.$button.hide(); 4288 } 4289 }, 4290 4291 set : function( force ) { 4292 var self = this; 4293 4294 // Check if reached last element 4295 if ( self.instance && self.instance.current && (force === true || self.instance.current.opts.loop || self.instance.currIndex < self.instance.group.length - 1 )) { 4296 self.timer = setTimeout(function() { 4297 if ( self.isActive ) { 4298 self.instance.jumpTo( (self.instance.currIndex + 1) % self.instance.group.length ); 4299 } 4300 4301 }, self.instance.current.opts.slideShow.speed); 4302 4303 } else { 4304 self.stop(); 4305 self.instance.idleSecondsCounter = 0; 4306 self.instance.showControls(); 4307 } 4308 }, 4309 4310 clear : function() { 4311 var self = this; 4312 4313 clearTimeout( self.timer ); 4314 4315 self.timer = null; 4316 }, 4317 4318 start : function() { 4319 var self = this; 4320 var current = self.instance.current; 4321 4322 if ( current ) { 4323 self.isActive = true; 4324 4325 self.$button 4326 .attr( 'title', current.opts.i18n[ current.opts.lang ].PLAY_STOP ) 4327 .removeClass( 'fancybox-button--play' ) 4328 .addClass( 'fancybox-button--pause' ); 4329 4330 self.set( true ); 4331 } 4332 }, 4333 4334 stop : function() { 4335 var self = this; 4336 var current = self.instance.current; 4337 4338 self.clear(); 4339 4340 self.$button 4341 .attr( 'title', current.opts.i18n[ current.opts.lang ].PLAY_START ) 4342 .removeClass( 'fancybox-button--pause' ) 4343 .addClass( 'fancybox-button--play' ); 4344 4345 self.isActive = false; 4346 }, 4347 4348 toggle : function() { 4349 var self = this; 4350 4351 if ( self.isActive ) { 4352 self.stop(); 4353 4354 } else { 4355 self.start(); 4356 } 4357 } 4358 4359 }); 4360 4361 $(document).on({ 4362 'onInit.fb' : function(e, instance) { 4363 if ( instance && !instance.SlideShow ) { 4364 instance.SlideShow = new SlideShow( instance ); 4365 } 4366 }, 4367 4368 'beforeShow.fb' : function(e, instance, current, firstRun) { 4369 var SlideShow = instance && instance.SlideShow; 4370 4371 if ( firstRun ) { 4372 4373 if ( SlideShow && current.opts.slideShow.autoStart ) { 4374 SlideShow.start(); 4375 } 4376 4377 } else if ( SlideShow && SlideShow.isActive ) { 4378 SlideShow.clear(); 4379 } 4380 }, 4381 4382 'afterShow.fb' : function(e, instance, current) { 4383 var SlideShow = instance && instance.SlideShow; 4384 4385 if ( SlideShow && SlideShow.isActive ) { 4386 SlideShow.set(); 4387 } 4388 }, 4389 4390 'afterKeydown.fb' : function(e, instance, current, keypress, keycode) { 4391 var SlideShow = instance && instance.SlideShow; 4392 4393 // "P" or Spacebar 4394 if ( SlideShow && current.opts.slideShow && ( keycode === 80 || keycode === 32 ) && !$(document.activeElement).is( 'button,a,input' ) ) { 4395 keypress.preventDefault(); 4396 4397 SlideShow.toggle(); 4398 } 4399 }, 4400 4401 'beforeClose.fb onDeactivate.fb' : function(e, instance) { 4402 var SlideShow = instance && instance.SlideShow; 4403 4404 if ( SlideShow ) { 4405 SlideShow.stop(); 4406 } 4407 } 4408 }); 4409 4410 // Page Visibility API to pause slideshow when window is not active 4411 $(document).on("visibilitychange", function() { 4412 var instance = $.fancybox.getInstance(); 4413 var SlideShow = instance && instance.SlideShow; 4414 4415 if ( SlideShow && SlideShow.isActive ) { 4416 if ( document.hidden ) { 4417 SlideShow.clear(); 4418 4419 } else { 4420 SlideShow.set(); 4421 } 4422 } 4423 }); 4424 4425}( document, window.jQuery || jQuery ));
4426 4427// ========================================================================== 4428// 4429// FullScreen 4430// Adds fullscreen functionality 4431// 4432// ========================================================================== 4433;(function (document, $) { 4434 'use strict'; 4435 4436 // Collection of methods supported by user browser 4437 var fn = (function () { 4438 4439 var fnMap = [ 4440 [ 4441 'requestFullscreen', 4442 'exitFullscreen', 4443 'fullscreenElement', 4444 'fullscreenEnabled', 4445 'fullscreenchange', 4446 'fullscreenerror' 4447 ], 4448 // new WebKit 4449 [ 4450 'webkitRequestFullscreen', 4451 'webkitExitFullscreen', 4452 'webkitFullscreenElement', 4453 'webkitFullscreenEnabled', 4454 'webkitfullscreenchange', 4455 'webkitfullscreenerror' 4456 4457 ], 4458 // old WebKit (Safari 5.1) 4459 [ 4460 'webkitRequestFullScreen', 4461 'webkitCancelFullScreen', 4462 'webkitCurrentFullScreenElement', 4463 'webkitCancelFullScreen', 4464 'webkitfullscreenchange', 4465 'webkitfullscreenerror' 4466 4467 ], 4468 [ 4469 'mozRequestFullScreen', 4470 'mozCancelFullScreen', 4471 'mozFullScreenElement', 4472 'mozFullScreenEnabled', 4473 'mozfullscreenchange', 4474 'mozfullscreenerror' 4475 ], 4476 [ 4477 'msRequestFullscreen', 4478 'msExitFullscreen', 4479 'msFullscreenElement', 4480 'msFullscreenEnabled', 4481 'MSFullscreenChange', 4482 'MSFullscreenError' 4483 ] 4484 ]; 4485 4486 var val; 4487 var ret = {}; 4488 var i, j; 4489 4490 for ( i = 0; i < fnMap.length; i++ ) { 4491 val = fnMap[ i ]; 4492 4493 if ( val && val[ 1 ] in document ) { 4494 for ( j = 0; j < val.length; j++ ) { 4495 ret[ fnMap[ 0 ][ j ] ] = val[ j ]; 4496 } 4497 4498 return ret; 4499 } 4500 } 4501 4502 return false; 4503 })(); 4504 4505 // If browser does not have Full Screen API, then simply unset default button template and stop 4506 if ( !fn ) { 4507 4508 if ( $ && $.fancybox ) { 4509 $.fancybox.defaults.btnTpl.fullScreen = false; 4510 } 4511 4512 return; 4513 } 4514 4515 var FullScreen = { 4516 4517 request : function ( elem ) { 4518 4519 elem = elem || document.documentElement; 4520 4521 elem[ fn.requestFullscreen ]( elem.ALLOW_KEYBOARD_INPUT ); 4522 4523 }, 4524 exit : function () { 4525 4526 document[ fn.exitFullscreen ](); 4527 4528 }, 4529 toggle : function ( elem ) { 4530 4531 elem = elem || document.documentElement; 4532 4533 if ( this.isFullscreen() ) { 4534 this.exit(); 4535 4536 } else { 4537 this.request( elem ); 4538 } 4539 4540 }, 4541 isFullscreen : function() { 4542 4543 return Boolean( document[ fn.fullscreenElement ] ); 4544 4545 }, 4546 enabled : function() { 4547 4548 return Boolean( document[ fn.fullscreenEnabled ] ); 4549 4550 } 4551 }; 4552 4553 $.extend(true, $.fancybox.defaults, { 4554 btnTpl : { 4555 fullScreen : 4556 '<button data-fancybox-fullscreen class="fancybox-button fancybox-button--fullscreen" title="{{FULL_SCREEN}}">' + 4557 '<svg viewBox="0 0 40 40">' + 4558 '<path d="M9,12 h22 v16 h-22 v-16 v16 h22 v-16 Z" />' + 4559 '</svg>' + 4560 '</button>' 4561 }, 4562 fullScreen : { 4563 autoStart : false 4564 } 4565 }); 4566 4567 $(document).on({ 4568 'onInit.fb' : function(e, instance) { 4569 var $container; 4570 4571 if ( instance && instance.group[ instance.currIndex ].opts.fullScreen ) { 4572 $container = instance.$refs.container; 4573 4574 $container.on('click.fb-fullscreen', '[data-fancybox-fullscreen]', function(e) { 4575 4576 e.stopPropagation(); 4577 e.preventDefault(); 4578 4579 FullScreen.toggle( $container[ 0 ] ); 4580 4581 }); 4582 4583 if ( instance.opts.fullScreen && instance.opts.fullScreen.autoStart === true ) { 4584 FullScreen.request( $container[ 0 ] ); 4585 } 4586 4587 // Expose API 4588 instance.FullScreen = FullScreen; 4589 4590 } else if ( instance ) { 4591 instance.$refs.toolbar.find('[data-fancybox-fullscreen]').hide(); 4592 } 4593 4594 }, 4595 4596 'afterKeydown.fb' : function(e, instance, current, keypress, keycode) { 4597 4598 // "P" or Spacebar 4599 if ( instance && instance.FullScreen && keycode === 70 ) { 4600 keypress.preventDefault(); 4601 4602 instance.FullScreen.toggle( instance.$refs.container[ 0 ] ); 4603 } 4604 4605 }, 4606 4607 'beforeClose.fb' : function( instance ) { 4608 if ( instance && instance.FullScreen ) { 4609 FullScreen.exit(); 4610 } 4611 } 4612 }); 4613 4614 $(document).on(fn.fullscreenchange, function() { 4615 var isFullscreen = FullScreen.isFullscreen(), 4616 instance = $.fancybox.getInstance(); 4617 4618 if ( instance ) { 4619 4620 // If image is zooming, then force to stop and reposition properly 4621 if ( instance.current && instance.current.type === 'image' && instance.isAnimating ) { 4622 instance.current.$content.css( 'transition', 'none' ); 4623 4624 instance.isAnimating = false; 4625 4626 instance.update( true, true, 0 ); 4627 } 4628 4629 instance.trigger( 'onFullscreenChange', isFullscreen ); 4630 4631 instance.$refs.container.toggleClass( 'fancybox-is-fullscreen', isFullscreen ); 4632 } 4633 4634 }); 4635 4636}( document, window.jQuery || jQuery ));
4637 4638// ========================================================================== 4639// 4640// Thumbs 4641// Displays thumbnails in a grid 4642// 4643// ========================================================================== 4644;(function (document, $) { 4645 'use strict'; 4646 4647 // Make sure there are default values 4648 $.fancybox.defaults = $.extend(true, { 4649 btnTpl : { 4650 thumbs : 4651 '<button data-fancybox-thumbs class="fancybox-button fancybox-button--thumbs" title="{{THUMBS}}">' + 4652 '<svg viewBox="0 0 120 120">' + 4653 '<path d="M30,30 h14 v14 h-14 Z M50,30 h14 v14 h-14 Z M70,30 h14 v14 h-14 Z M30,50 h14 v14 h-14 Z M50,50 h14 v14 h-14 Z M70,50 h14 v14 h-14 Z M30,70 h14 v14 h-14 Z M50,70 h14 v14 h-14 Z M70,70 h14 v14 h-14 Z" />' + 4654 '</svg>' + 4655 '</button>' 4656 }, 4657 thumbs : { 4658 autoStart : false, // Display thumbnails on opening 4659 hideOnClose : true, // Hide thumbnail grid when closing animation starts 4660 parentEl : '.fancybox-container', // Container is injected into this element 4661 axis : 'y' // Vertical (y) or horizontal (x) scrolling 4662 } 4663 }, $.fancybox.defaults); 4664 4665 var FancyThumbs = function( instance ) { 4666 this.init( instance ); 4667 }; 4668 4669 $.extend( FancyThumbs.prototype, { 4670 4671 $button : null, 4672 $grid : null, 4673 $list : null, 4674 isVisible : false, 4675 isActive : false, 4676 4677 init : function( instance ) { 4678 var self = this; 4679 4680 self.instance = instance; 4681 4682 instance.Thumbs = self; 4683 4684 // Enable thumbs if at least two group items have thumbnails 4685 var first = instance.group[0], 4686 second = instance.group[1]; 4687 4688 self.opts = instance.group[ instance.currIndex ].opts.thumbs; 4689 4690 self.$button = instance.$refs.toolbar.find( '[data-fancybox-thumbs]' ); 4691 4692 if ( self.opts && first && second && ( 4693 ( first.type == 'image' || first.opts.thumb || first.opts.$thumb ) && 4694 ( second.type == 'image' || second.opts.thumb || second.opts.$thumb ) 4695 )) { 4696 4697 self.$button.show().on('click', function() { 4698 self.toggle(); 4699 }); 4700 4701 self.isActive = true; 4702 4703 } else { 4704 self.$button.hide(); 4705 } 4706 }, 4707 4708 create : function() { 4709 var self = this, 4710 instance = self.instance, 4711 parentEl = self.opts.parentEl, 4712 list, 4713 src; 4714 4715 self.$grid = $('<div class="fancybox-thumbs fancybox-thumbs-' + self.opts.axis + '"></div>').appendTo( instance.$refs.container.find( parentEl ).addBack().filter( parentEl ) ); 4716 4717 // Build list HTML 4718 list = '<ul>'; 4719 4720 $.each(instance.group, function( i, item ) { 4721 src = item.opts.thumb || ( item.opts.$thumb ? item.opts.$thumb.attr( 'src' ) : null ); 4722 4723 if ( !src && item.type === 'image' ) { 4724 src = item.src; 4725 } 4726 4727 if ( src && src.length ) { 4728 list += '<li data-index="' + i + '" tabindex="0" class="fancybox-thumbs-loading"><img data-src="' + src + '" /></li>'; 4729 } 4730 }); 4731 4732 list += '</ul>'; 4733 4734 self.$list = $( list ).appendTo( self.$grid ).on('click', 'li', function() { 4735 instance.jumpTo( $(this).data('index') ); 4736 }); 4737
4738 self.$list.find( 'img' ).hide().one('load', function() { 4739 var $parent = $(this).parent().removeClass( 'fancybox-thumbs-loading' ), 4740 thumbWidth = $parent.outerWidth(), 4741 thumbHeight = $parent.outerHeight(), 4742 width, 4743 height, 4744 widthRatio, 4745 heightRatio; 4746 4747 width = this.naturalWidth || this.width; 4748 height = this.naturalHeight || this.height; 4749 4750 // Calculate thumbnail dimensions; center vertically and horizontally 4751 widthRatio = width / thumbWidth; 4752 heightRatio = height / thumbHeight; 4753 4754 if (widthRatio >= 1 && heightRatio >= 1) { 4755 if (widthRatio > heightRatio) { 4756 width = width / heightRatio; 4757 height = thumbHeight; 4758 4759 } else { 4760 width = thumbWidth; 4761 height = height / widthRatio; 4762 } 4763 } 4764 4765 $(this).css({ 4766 width : Math.floor(width), 4767 height : Math.floor(height), 4768 'margin-top' : height > thumbHeight ? ( Math.floor(thumbHeight * 0.3 - height * 0.3 ) ) : Math.floor(thumbHeight * 0.5 - height * 0.5 ), 4769 'margin-left' : Math.floor(thumbWidth * 0.5 - width * 0.5 ) 4770 }).show(); 4771 4772 }) 4773 .each(function() { 4774 this.src = $( this ).data( 'src' ); 4775 }); 4776 4777 if ( self.opts.axis === 'x' ) { 4778 self.$list.width( parseInt( self.$grid.css("padding-right") ) + ( instance.group.length * self.$list.children().eq(0).outerWidth(true) ) + 'px' ); 4779 } 4780 }, 4781 4782 focus : function( duration ) { 4783 var self = this, 4784 $list = self.$list, 4785 thumb, 4786 thumbPos; 4787 4788 if ( self.instance.current ) { 4789 thumb = $list.children() 4790 .removeClass( 'fancybox-thumbs-active' ) 4791 .filter('[data-index="' + self.instance.current.index + '"]') 4792 .addClass('fancybox-thumbs-active'); 4793 4794 thumbPos = thumb.position(); 4795 4796 // Check if need to scroll to make current thumb visible 4797 if ( self.opts.axis === 'y' && ( thumbPos.top < 0 || thumbPos.top > ( $list.height() - thumb.outerHeight() ) ) ) { 4798 $list.stop().animate({ 'scrollTop' : $list.scrollTop() + thumbPos.top }, duration); 4799 4800 } else if ( self.opts.axis === 'x' && ( 4801 thumbPos.left < $list.parent().scrollLeft() || 4802 thumbPos.left > ( $list.parent().scrollLeft() + ( $list.parent().width() - thumb.outerWidth() ) ) 4803 ) 4804 ) { 4805 $list.parent().stop().animate({ 'scrollLeft' : thumbPos.left }, duration); 4806 } 4807 } 4808 }, 4809 4810 update : function() { 4811 this.instance.$refs.container.toggleClass( 'fancybox-show-thumbs', this.isVisible ); 4812 4813 if ( this.isVisible ) { 4814 if ( !this.$grid ) { 4815 this.create(); 4816 } 4817 4818 this.instance.trigger( 'onThumbsShow' ); 4819 4820 this.focus( 0 ); 4821 4822 } else if ( this.$grid ) { 4823 this.instance.trigger( 'onThumbsHide' ); 4824 } 4825 4826 // Update content position 4827 this.instance.update(); 4828 }, 4829 4830 hide : function() { 4831 this.isVisible = false; 4832 this.update(); 4833 }, 4834 4835 show : function() { 4836 this.isVisible = true; 4837 this.update(); 4838 }, 4839 4840 toggle : function() { 4841 this.isVisible = !this.isVisible; 4842 this.update(); 4843 } 4844 }); 4845 4846 $(document).on({ 4847 4848 'onInit.fb' : function(e, instance) { 4849 var Thumbs; 4850 4851 if ( instance && !instance.Thumbs ) { 4852 Thumbs = new FancyThumbs( instance ); 4853 4854 if ( Thumbs.isActive && Thumbs.opts.autoStart === true ) { 4855 Thumbs.show(); 4856 } 4857 } 4858 }, 4859 4860 'beforeShow.fb' : function(e, instance, item, firstRun) { 4861 var Thumbs = instance && instance.Thumbs; 4862 4863 if ( Thumbs && Thumbs.isVisible ) { 4864 Thumbs.focus( firstRun ? 0 : 250 ); 4865 } 4866 }, 4867 4868 'afterKeydown.fb' : function(e, instance, current, keypress, keycode) { 4869 var Thumbs = instance && instance.Thumbs; 4870 4871 // "G" 4872 if ( Thumbs && Thumbs.isActive && keycode === 71 ) { 4873 keypress.preventDefault(); 4874 4875 Thumbs.toggle(); 4876 } 4877 }, 4878 4879 'beforeClose.fb' : function( e, instance ) { 4880 var Thumbs = instance && instance.Thumbs; 4881 4882 if ( Thumbs && Thumbs.isVisible && Thumbs.opts.hideOnClose !== false ) { 4883 Thumbs.$grid.hide(); 4884 } 4885 } 4886 4887 }); 4888 4889}(document, window.jQuery)); 4890 4891//// ========================================================================== 4892// 4893// Share 4894// Displays simple form for sharing current url 4895// 4896// ========================================================================== 4897;(function (document, $) { 4898 'use strict'; 4899 4900 $.extend(true, $.fancybox.defaults, { 4901 btnTpl : { 4902 share : 4903 '<button data-fancybox-share class="fancybox-button fancybox-button--share" title="{{SHARE}}">' + 4904 '<svg viewBox="0 0 40 40">' + 4905 '<path d="M6,30 C8,18 19,16 23,16 L23,16 L23,10 L33,20 L23,29 L23,24 C19,24 8,27 6,30 Z">' + 4906 '</svg>' + 4907 '</button>' 4908 }, 4909 share : { 4910 tpl : 4911 '<div class="fancybox-share">' + 4912 '<h1>{{SHARE}}</h1>' + 4913 '<p class="fancybox-share__links">' + 4914 '<a class="fancybox-share__button fancybox-share__button--fb" href="https://www.facebook.com/sharer/sharer.php?u={{url}}">' + 4915 '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m287 456v-299c0-21 6-35 35-35h38v-63c-7-1-29-3-55-3-54 0-91 33-91 94v306m143-254h-205v72h196" /></svg>
4915' + 4916 '<span>Facebook</span>' + 4917 '</a>' + 4918 '<a class="fancybox-share__button fancybox-share__button--pt" href="https://www.pinterest.com/pin/create/button/?url={{url}}&description={{descr}}&media={{media}}">' + 4919 '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m265 56c-109 0-164 78-164 144 0 39 15 74 47 87 5 2 10 0 12-5l4-19c2-6 1-8-3-13-9-11-15-25-15-45 0-58 43-110 113-110 62 0 96 38 96 88 0 67-30 122-73 122-24 0-42-19-36-44 6-29 20-60 20-81 0-19-10-35-31-35-25 0-44 26-44 60 0 21 7 36 7 36l-30 125c-8 37-1 83 0 87 0 3 4 4 5 2 2-3 32-39 42-75l16-64c8 16 31 29 56 29 74 0 124-67 124-157 0-69-58-132-146-132z" fill="#fff"/></svg>' + 4920 '<span>Pinterest</span>' + 4921 '</a>' + 4922 '<a class="fancybox-share__button fancybox-share__button--tw" href="https://twitter.com/intent/tweet?url={{url}}&text={{descr}}">' + 4923 '<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m456 133c-14 7-31 11-47 13 17-10 30-27 37-46-15 10-34 16-52 20-61-62-157-7-141 75-68-3-129-35-169-85-22 37-11 86 26 109-13 0-26-4-37-9 0 39 28 72 65 80-12 3-25 4-37 2 10 33 41 57 77 57-42 30-77 38-122 34 170 111 378-32 359-208 16-11 30-25 41-42z" /></svg>' + 4924 '<span>Twitter</span>' + 4925 '</a>' + 4926 '</p>' + 4927 '<p><input class="fancybox-share__input" type="text" value="{{url_raw}}" /></p>' + 4928 '</div>' 4929 } 4930 }); 4931 4932 function escapeHtml(string) { 4933 var entityMap = { 4934 '&': '&', 4935 '<': '<', 4936 '>': '>', 4937 '"': '"', 4938 "'": ''', 4939 '/': '/', 4940 '`': '`', 4941 '=': '=' 4942 }; 4943 4944 return String(string).replace(/[&<>"'`=\/]/g, function (s) { 4945 return entityMap[s]; 4946 }); 4947 } 4948 4949 $(document).on('click', '[data-fancybox-share]', function() { 4950 var f = $.fancybox.getInstance(), 4951 url, 4952 tpl; 4953 4954 if ( f ) { 4955 url = f.current.opts.hash === false ? f.current.src : window.location; 4956 tpl = f.current.opts.share.tpl 4957 .replace( /\{\{media\}\}/g, f.current.type === 'image' ? encodeURIComponent( f.current.src ) : '' ) 4958 .replace( /\{\{url\}\}/g, encodeURIComponent( url ) ) 4959 .replace( /\{\{url_raw\}\}/g, escapeHtml( url ) ) 4960 .replace( /\{\{descr\}\}/g, f.$caption ? encodeURIComponent( f.$caption.text() ) : '' ); 4961 4962 $.fancybox.open({ 4963 src : f.translate( f, tpl ), 4964 type : 'html', 4965 opts : { 4966 animationEffect : "fade", 4967 animationDuration : 250, 4968 afterLoad : function(instance, current) { 4969 // Opening links in a popup window 4970 current.$content.find('.fancybox-share__links a').click(function() { 4971 window.open(this.href, "Share", "width=550, height=450"); 4972 return false; 4973 }); 4974 } 4975 } 4976 }); 4977 } 4978 4979 }); 4980 4981}( document, window.jQuery || jQuery )); 4982 4983// ========================================================================== 4984// 4985// Hash 4986// Enables linking to each modal 4987// 4988// ========================================================================== 4989;(function (document, window, $) { 4990 'use strict'; 4991 4992 // Simple $.escapeSelector polyfill (for jQuery prior v3) 4993 if ( !$.escapeSelector ) { 4994 $.escapeSelector = function( sel ) { 4995 var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; 4996 var fcssescape = function( ch, asCodePoint ) { 4997 if ( asCodePoint ) { 4998 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 4999 if ( ch === "\0" ) { 5000 return "\uFFFD"; 5001 } 5002 5003 // Control characters and (dependent upon position) numbers get escaped as code points 5004 return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 5005 } 5006 5007 // Other potentially-special ASCII characters get backslash-escaped 5008 return "\\" + ch; 5009 }; 5010 5011 return ( sel + "" ).replace( rcssescape, fcssescape ); 5012 }; 5013 } 5014 5015 // Create new history entry only once 5016 var shouldCreateHistory = true; 5017 5018 // Variable containing last hash value set by fancyBox 5019 // It will be used to determine if fancyBox needs to close after hash change is detected 5020 var currentHash = null; 5021 5022 // Throttling the history change 5023 var timerID = null; 5024 5025 // Get info about gallery name and current index from url 5026 function parseUrl() { 5027 var hash = window.location.hash.substr( 1 ); 5028 var rez = hash.split( '-' ); 5029 var index = rez.length > 1 && /^\+?\d+$/.test( rez[ rez.length - 1 ] ) ? parseInt( rez.pop( -1 ), 10 ) || 1 : 1; 5030 var gallery = rez.join( '-' ); 5031 5032 // Index is starting from 1 5033 if ( index < 1 ) { 5034 index = 1; 5035 } 5036 5037 return { 5038 hash : hash, 5039 index : index, 5040 gallery : gallery 5041 }; 5042 } 5043 5044 // Trigger click evnt on links to open new fancyBox instance 5045 function triggerFromUrl( url ) { 5046 var $el; 5047 5048 if ( url.gallery !== '' ) { 5049 5050 // If we can find element matching 'data-fancybox' atribute, then trigger click event for that .. 5051 $el = $( "[data-fancybox='" + $.escapeSelector( url.gallery ) + "']" ).eq( url.index - 1 ); 5052 5053 if ( !$el.length ) { 5054 // .. if not, try finding element by ID 5055 $el = $( "#" + $.escapeSelector( url.gallery ) + "" ); 5056 } 5057 5058 if ( $el.length ) { 5059 shouldCreateHistory = false; 5060 5061 $el.trigger( 'click' ); 5062 } 5063 5064 } 5065 } 5066 5067 // Get gallery name from current instance 5068 function getGalleryID( instance ) { 5069 var opts; 5070 5071 if ( !instance ) { 5072 return false; 5073 } 5074 5075 opts = instance.current ? instance.current.opts : instance.opts; 5076 5077 return opts.hash || ( opts.$orig ? opts.$orig.data( 'fancybox' ) : '' ); 5078 } 5079 5080 // Start when DOM becomes ready 5081 $(function() { 5082 5083 // Check if user has disabled this module 5084 if ( $.fancybox.defaults.hash === false ) { 5085 return; 5086 } 5087 5088 // Update hash when opening/closing fancyBox 5089 $(document).on({ 5090 'onInit.fb' : function( e, instance ) { 5091 var url, gallery; 5092 5093 if ( instance.group[ instance.currIndex ].opts.hash === false ) { 5094 return; 5095 } 5096 5097 url = parseUrl(); 5098 gallery = getGalleryID( instance ); 5099 5100 // Make sure gallery start index matches index from hash 5101 if ( gallery && url.gallery && gallery == url.gallery ) { 5102 instance.currIndex = url.index - 1; 5103 } 5104 }, 5105 5106 'beforeShow.fb' : function( e, instance, current ) { 5107 var gallery; 5108 5109 if ( !current || current.opts.hash === false ) { 5110 return; 5111 } 5112 5113 gallery = getGalleryID( instance ); 5114 5115 // Update window hash 5116 if ( gallery && gallery !== '' ) { 5117 5118 if ( window.location.hash.indexOf( gallery ) < 0 ) { 5119 instance.opts.origHash = window.location.hash; 5120 } 5121 5122 currentHash = gallery + ( instance.group.length > 1 ? '-' + ( current.index + 1 ) : '' ); 5123 5124 if ( 'replaceState' in window.history ) { 5125 if ( timerID ) { 5126 clearTimeout( timerID ); 5127 } 5128 5129 timerID = setTimeout(function() { 5130 window.history[ shouldCreateHistory ? 'pushState' : 'replaceState' ]( {} , document.title, window.location.pathname + window.location.search + '#' + currentHash ); 5131 5132 timerID = null; 5133 5134 shouldCreateHistory = false; 5135 5136 }, 300); 5137 5138 } else { 5139 window.location.hash = currentHash; 5140 } 5141 5142 } 5143 5144 }, 5145 5146 'beforeClose.fb' : function( e, instance, current ) { 5147 var gallery, origHash; 5148 5149 if ( timerID ) { 5150 clearTimeout( timerID ); 5151 } 5152 5153 if ( current.opts.hash === false ) { 5154 return; 5155 } 5156 5157 gallery = getGalleryID( instance ); 5158 origHash = instance && instance.opts.origHash ? instance.opts.origHash : ''; 5159 5160 // Remove hash from location bar 5161 if ( gallery && gallery !== '' ) { 5162 5163 if ( 'replaceState' in history ) { 5164 window.history.replaceState( {} , document.title, window.location.pathname + window.location.search + origHash ); 5165 5166 } else { 5167 window.location.hash = origHash; 5168 5169 // Keep original scroll position 5170 $( window ).scrollTop( instance.scrollTop ).scrollLeft( instance.scrollLeft ); 5171 } 5172 } 5173 5174 currentHash = null; 5175 } 5176 }); 5177 5178 // Check if need to close after url has changed 5179 $(window).on('hashchange.fb', function() { 5180 var url = parseUrl(); 5181 5182 if ( $.fancybox.getInstance() ) { 5183 if ( currentHash && currentHash !== url.gallery + '-' + url.index && !( url.index === 1 && currentHash == url.gallery ) ) { 5184 currentHash = null; 5185 5186 $.fancybox.close(); 5187 } 5188 5189 } else if ( url.gallery !== '' ) { 5190 triggerFromUrl( url ); 5191 } 5192 }); 5193 5194 // Check current hash and trigger click event on matching element to start fancyBox, if needed 5195 setTimeout(function() { 5196 triggerFromUrl( parseUrl() ); 5197 }, 50); 5198 });
5199 5200}( document, window, window.jQuery || jQuery )); 5201 5202;(function (document, $) { 5203 'use strict'; 5204 5205 var prevTime = new Date().getTime(); 5206 5207 $(document).on({ 5208 'onInit.fb' : function( e, instance, current ) { 5209 instance.$refs.stage.on('mousewheel DOMMouseScroll wheel MozMousePixelScroll', function(e) { 5210 var current = instance.current, 5211 currTime = new Date().getTime(); 5212 5213 if ( instance.group.length < 1 || current.opts.wheel === false || ( current.opts.wheel === 'auto' && current.type !== 'image' ) ) { 5214 return; 5215 } 5216 5217 e.preventDefault(); 5218 e.stopPropagation(); 5219 5220 if ( current.$slide.hasClass( 'fancybox-animated' ) ) { 5221 return; 5222 } 5223 5224 e = e.originalEvent || e; 5225 5226 if ( currTime - prevTime < 250 ) { 5227 return; 5228 } 5229 5230 prevTime = currTime; 5231 5232 instance[ ( -e.deltaY || -e.deltaX || e.wheelDelta || -e.detail ) < 0 ? 'next' : 'previous' ](); 5233 5234 }); 5235 } 5236 }); 5237 5238}( document, window.jQuery || jQuery )); 5239/*! choices.js v3.0.3 | (c) 2018 Josh Johnson | https://github.com/jshjohnson/Choices#readme */ 5240!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Choices=t():e.Choices=t()}(this,function(){return function(e){function t(n){if(i[n])return i[n].exports;var s=i[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var i={};return t.m=e,t.c=i,t.p="/assets/scripts/dist/",t(0)}([function(e,t,i){e.exports=i(1)},function(e,t,i){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function s(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function o(e){if(Array.isArray(e)){for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}return Array.from(e)}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var a=function(){function e(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,i,n){return i&&e(t.prototype,i),n&&e(t,n),t}}(),c=i(2),l=n(c),h=i(3),u=n(h),d=i(4),f=n(d),p=i(31),v=i(32);i(33);var m=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"[data-choice]",i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(r(this,e),(0,v.isType)("String",t)){var n=document.querySelectorAll(t);if(n.length>1)for(var s=1;s<n.length;s++){var o=n[s];new e(o,i)}}var a={silent:!1,items:[],choices:[],renderChoiceLimit:-1,maxItemCount:-1,addItems:!0,removeItems:!0,removeItemButton:!1,editItems:!1,duplicateItems:!0,delimiter:",",paste:!0,searchEnabled:!0,searchChoices:!0,searchFloor:1,searchResultLimit:4,searchFields:["label","value"],position:"auto",resetScrollPosition:!0,regexFilter:null,shouldSort:!0,shouldSortItems:!1,sortFilter:v.sortByAlpha,placeholder:!0,placeholderValue:null,searchPlaceholderValue:null,prependValue:null,appendValue:null,renderSelectedChoices:"auto",loadingText:"Loading...",noResultsText:"No results found",noChoicesText:"No choices to choose from",itemSelectText:"Press to select",addItemText:function(e){return'Press Enter to add <b>"'+e+'"</b>'},maxItemText:function(e){return"Only "+e+" values can be added."},uniqueItemText:"Only unique values can be added.",classNames:{containerOuter:"choices",containerInner:"choices__inner",input:"choices__input",inputCloned:"choices__input--cloned",list:"choices__list",listItems:"choices__list--multiple",listSingle:"choices__list--single",listDropdown:"choices__list--dropdown",item:"choices__item",itemSelectable:"choices__item--selectable",itemDisabled:"choices__item--disabled",itemChoice:"choices__item--choice",placeholder:"choices__placeholder",group:"choices__group",groupHeading:"choices__heading",button:"choices__button",activeState:"is-active",focusState:"is-focused",openState:"is-open",disabledState:"is-disabled",highlightedState:"is-highlighted",hiddenState:"is-hidden",flippedState:"is-flipped",loadingState:"is-loading",noResults:"has-no-results",noChoices:"has-no-choices"},fuseOptions:{include:"score"},callbackOnInit:null,callbackOnCreateTemplates:null};if(this.idNames={itemChoice:"item-choice"}
5240,this.config=(0,v.extend)(a,i),"auto"!==this.config.renderSelectedChoices&&"always"!==this.config.renderSelectedChoices&&(this.config.silent||console.warn("renderSelectedChoices: Possible values are 'auto' and 'always'. Falling back to 'auto'."),this.config.renderSelectedChoices="auto"),this.store=new f.default(this.render),this.initialised=!1,this.currentState={},this.prevState={},this.currentValue="",this.element=t,this.passedElement=(0,v.isType)("String",t)?document.querySelector(t):t,!this.passedElement)return void(this.config.silent||console.error("Passed element not found"));this.isTextElement="text"===this.passedElement.type,this.isSelectOneElement="select-one"===this.passedElement.type,this.isSelectMultipleElement="select-multiple"===this.passedElement.type,this.isSelectElement=this.isSelectOneElement||this.isSelectMultipleElement,this.isValidElementType=this.isTextElement||this.isSelectElement,this.isIe11=!(!navigator.userAgent.match(/Trident/)||!navigator.userAgent.match(/rv[ :]11/)),this.isScrollingOnIe=!1,this.config.shouldSortItems===!0&&this.isSelectOneElement&&(this.config.silent||console.warn("shouldSortElements: Type of passed element is 'select-one', falling back to fal
5240se.")),this.highlightPosition=0,this.canSearch=this.config.searchEnabled,this.placeholder=!1,this.isSelectOneElement||(this.placeholder=!!this.config.placeholder&&(this.config.placeholderValue||this.passedElement.getAttribute("placeholder"))),this.presetChoices=this.config.choices,this.presetItems=this.config.items,this.passedElement.value&&(this.presetItems=this.presetItems.concat(this.passedElement.value.split(this.config.delimiter))),this.baseId=(0,v.generateId)(this.passedElement,"choices-"),this.render=this.render.bind(this),this._onFocus=this._onFocus.bind(this),this._onBlur=this._onBlur.bind(this),this._onKeyUp=this._onKeyUp.bind(this),this._onKeyDown=this._onKeyDown.bind(this),this._onClick=this._onClick.bind(this),this._onTouchMove=this._onTouchMove.bind(this),this._onTouchEnd=this._onTouchEnd.bind(this),this._onMouseDown=this._onMouseDown.bind(this),this._onMouseOver=this._onMouseOver.bind(this),this._onPaste=this._onPaste.bind(this),this._onInput=this._onInput.bind(this),this.wasTap=!0;var c="classList"in document.documentElement;c||this.config.silent||console.error("Choices: Your browser doesn't support Choices");var l=(0,v.isElement)(this.passedElement)&&this.isValidElementType;if(l){if("active"===this.passedElement.getAttribute("data-choice"))return;this.init()}else this.config.silent||console.error("Incompatible input passed")}return a(e,[{key:"init",value:function(){if(this.initialised!==!0){var e=this.config.callbackOnInit;this.initialised=!0,this._createTemplates(),this._createInput(),this.store.subscribe(this.render),this.render(),this._addEventListeners(),e&&(0,v.isType)("Function",e)&&e.call(this)}}},{key:"destroy",value:function(){if(this.initialised!==!1){this._removeEventListeners(),this.passedElement.classList.remove(this.config.classNames.input,this.config.classNames.hiddenState),this.passedElement.removeAttribute("tabindex");var e=this.passedElement.getAttribute("data-choice-orig-style");Boolean(e)?(this.passedElement.removeAttribute("data-choice-orig-style"),this.passedElement.setAttribute("style",e)):this.passedElement.removeAttribute("style"),this.passedElement.removeAttribute("aria-hidden"),this.passedElement.removeAttribute("data-choice"),this.passedElement.value=this.passedElement.value,this.containerOuter.parentNode.insertBefore(this.passedElement,this.containerOuter),this.containerOuter.parentNode.removeChild(this.containerOuter),this.clearStore(),this.config.templates=null,this.initialised=!1}}},{key:"renderGroups",value:function(e,t,i){var n=this,s=i||document.createDocumentFragment(),o=this.config.sortFilter;return this.config.shouldSort&&e.sort(o),e.forEach(function(e){var i=t.filter(function(t){return n.isSelectOneElement?t.groupId===e.id:t.groupId===e.id&&!t.selected});if(i.length>=1){var o=n._getTemplate("choiceGroup",e);s.appendChild(o),n.renderChoices(i,s,!0)}}),s}},{key:"renderChoices",value:function(e,t){var i=this,n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],s=t||document.createDocumentFragment(),r=this.config,a=r.renderSelectedChoices,c=r.searchResultLimit,l=r.renderChoiceLimit,h=this.isSearching?v.sortByScore:this.config.sortFilter,u=function(e){var t="auto"!==a||(i.isSelectOneElement||!e.selected);if(t){var n=i._getTemplate("choice",e);s.appendChild(n)}},d=e;"auto"!==a||this.isSelectOneElement||(d=e.filter(function(e){return!e.selected}));var f=d.reduce(function(e,t){return t.placeholder?e.placeholderChoices.push(t):e.normalChoices.push(t),e},{placeholderChoices:[],normalChoices:[]}),p=f.placeholderChoices,m=f.normalChoices;(this.config.shouldSort||this.isSearching)&&m.sort(h);var g=d.length,y=[].concat(o(p),o(m));this.isSearching?g=c:l>0&&!n&&(g=l);for(var b=0;b<g;b++)y[b]&&u(y[b]);return s}},{key:"renderItems",value:function(e){var t=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=i||document.createDocumentFragment();if(this.config.shouldSortItems&&!this.isSelectOneElement&&e.sort(this.config.sortFilter),this.isTextElement){var s=this.store.getItemsReducedToValues(e),o=s.join(this.config.delimiter);this.passedElement.setAttribute("value",o),this.passedElement.value=o}else{var r=document.createDocumentFragment();e.forEach(function(e){var i=t._getTemplate("option",e);r.appendChild(i)}),this.passedElement.innerHTML="",this.passedElement.appendChild(r)}return e.forEach(function(e){var i=t._getTemplate("item",e);n.appendChild(i)}),n}},{key:"render",value:function(){if(!this.store.isLoading()&&(this.currentState=this.store.getState(),this.currentState!==this.prevState)){if((this.currentState.choices!==this.prevState.choices||this.currentState.groups!==this.prevState.groups||this.currentState.items!==this.prevState.items)&&this.isSelectElement){var e=this.store.getGroupsFilteredByActive(),t=this.store.getChoicesFilteredByActive(),i=document.createDocumentFragment();this.choiceList.innerHTML="",this.config.resetScrollPosition&&(this.choiceList.scrollTop=0),e.length>=1&&this.isSearching!==!0?i=this.renderGroups(e,t,i):t.length>=1&&(i=this.renderChoices(t,i));var n=this.store.getItemsFilteredByActive(),s=this._canAddItem(n,this.input.value);if(i.childNodes&&i.childNodes.length>0)s.response?(this.choiceList.appendChild(i),this._highlightChoice()):this.choiceList.appendChild(this._getTemplate("notice",s.notice));else{var o=void 0,r=void 0;this.isSearching?(r=(0,v.isType)("Function",this.config.noResultsText)?this.config.noResultsText():this.config.noResultsText,o=this._getTemplate("notice",r,"no-results")):(r=(0,v.isType)("Function",this.config.noChoicesText)?this.config.noChoicesText():this.config.noChoicesText,o=this._getTemplate("notice",r,"no-choices")),this.choiceList.appendChild(o)}}if(this.currentState.items!==this.prevState.items){var a=this.store.getItemsFilteredByActive();if(this.itemList.innerHTML="",a&&a){var c=this.renderItems(a);c.childNodes&&this.itemList.appendChild(c)}}this.prevState=this.currentState}}},{key:"highlightItem",value:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(!e)return this;var i=e.id,n=e.groupId,s=n>=0?this.store.getGroupById(n):null;return this.store.dispatch((0,p.highlightItem)(i,!0)),t&&(s&&s.value?(0,v.triggerEvent)(this.passedElement,"highlightItem",{id:i,value:e.value,label:e.label,groupValue:s.value}):(0,v.triggerEvent)(this.passedElement,"highlightItem",{id:i,value:e.value,label:e.label})),this}},{key:"unhighlightItem",value:function(e){if(!e)return this;var t=e.id,i=e.groupId,n=i>=0?this.store.getGroupById(i):null;return this.store.dispatch((0,p.highlightItem)(t,!1)),n&&n.value?(0,v.triggerEvent)(this.passedElement,"unhighlightItem",{id:t,value:e.value,label:e.label,groupValue:n.value}):(0,v.triggerEvent)(this.passedElement,"unhighlightItem",{id:t,value:e.value,label:e.label}),this}},{key:"highlightAll",value:function(){var e=this,t=this.store.getItems();return t.forEach(function(t){e.highlightItem(t)}),this}},{key:"unhighlightAll",value:function(){var e=this,t=this.store.getItems();return t.forEach(function(t){e.unhighlightItem(t)}),this}},{key:"removeItemsByValue",value:function(e){var t=this;if(!e||!(0,v.isType)("String",e))return this;var i=this.store.getItemsFilteredByActive();
5240return i.forEach(function(i){i.value===e&&t._removeItem(i)}),this}},{key:"removeActiveItems",value:function(e){var t=this,i=this.store.getItemsFilteredByActive();return i.forEach(function(i){i.active&&e!==i.id&&t._removeItem(i)}),this}},{key:"removeHighlightedItems",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],i=this.store.getItemsFilteredByActive();return i.forEach(function(i){i.highlighted&&i.active&&(e._removeItem(i),t&&e._triggerChange(i.value))}),this}},{key:"showDropdown",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=document.body,i=document.documentElement,n=Math.max(t.scrollHeight,t.offsetHeight,i.clientHeight,i.scrollHeight,i.offsetHeight);this.containerOuter.classList.add(this.config.classNames.openState),this.containerOuter.setAttribute("aria-expanded","true"),this.dropdown.classList.add(this.config.classNames.activeState),this.dropdown.setAttribute("aria-expanded","true");var s=this.dropdown.getBoundingClientRect(),o=Math.ceil(s.top+window.scrollY+this.dropdown.offsetHeight),r=!1;return"auto"===this.config.position?r=o>=n:"top"===this.config.position&&(r=!0),r&&this.containerOuter.classList.add(this.config.classNames.flippedState),e&&this.canSearch&&document.activeElement!==this.input&&this.input.focus(),(0,v.triggerEvent)(this.passedElement,"showDropdown",{}),this}},{key:"hideDropdown",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.containerOuter.classList.contains(this.config.classNames.flippedState);return this.containerOuter.classList.remove(this.config.classNames.openState),this.containerOuter.setAttribute("aria-expanded","false"),this.dropdown.classList.remove(this.config.classNames.activeState),this.dropdown.setAttribute("aria-expanded","false"),t&&this.containerOuter.classList.remove(this.config.classNames.flippedState),e&&this.canSearch&&document.activeElement===this.input&&this.input.blur(),(0,v.triggerEvent)(this.passedElement,"hideDropdown",{}),this}},{key:"toggleDropdown",value:function(){var e=this.dropdown.classList.contains(this.config.classNames.activeState);return e?this.hideDropdown():this.showDropdown(!0),this}},{key:"getValue",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],i=this.store.getItemsFilteredByActive(),n=[];return i.forEach(function(i){e.isTextElement?n.push(t?i.value:i):i.active&&n.push(t?i.value:i)}),this.isSelectOneElement?n[0]:n}},{key:"setValue",value:function(e){var t=this;if(this.initialised===!0){var i=[].concat(o(e)),n=function(e){var i=(0,v.getType)(e);if("Object"===i){if(!e.value)return;t.isTextElement?t._addItem(e.value,e.label,e.id,void 0,e.customProperties,e.placeholder):t._addChoice(e.value,e.label,!0,!1,-1,e.customProperties,e.placeholder)}else"String"===i&&(t.isTextElement?t._addItem(e):t._addChoice(e,e,!0,!1,-1,null))};i.length>1?i.forEach(function(e){n(e)}):n(i[0])}return this}},{key:"setValueByChoice",value:function(e){var t=this;if(!this.isTextElement){var i=this.store.getChoices(),n=(0,v.isType)("Array",e)?e:[e];n.forEach(function(e){var n=i.find(function(t){return t.value===e});n?n.selected?t.config.silent||console.warn("Attempting to select choice already selected"):t._addItem(n.value,
5240n.label,n.id,n.groupId,n.customProperties,n.placeholder,n.keyCode):t.config.silent||console.warn("Attempting to select choice that does not exist")})}return this}},{key:"setChoices",value:function(e,t,i){var n=this,s=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(this.initialised===!0&&this.isSelectElement){if(!(0,v.isType)("Array",e)||!t)return this;s&&this._clearChoices(),this._setLoading(!0),e&&e.length&&(this.containerOuter.classList.remove(this.config.classNames.loadingState),e.forEach(function(e){e.choices?n._addGroup(e,e.id||null,t,i):n._addChoice(e[t],e[i],e.selected,e.disabled,void 0,e.customProperties,e.placeholder)})),this._setLoading(!1)}return this}},{key:"clearStore",value:function(){return this.store.dispatch((0,p.clearAll)()),this}},{key:"clearInput",value:function(){return this.input.value&&(this.input.value=""),this.isSelectOneElement||this._setInputWidth(),!this.isTextElement&&this.config.searchEnabled&&(this.isSearching=!1,this.store.dispatch((0,p.activateChoices)(!0))),this}},{key:"enable",value:function(){if(this.initialised){this.passedElement.disabled=!1;var e=this.containerOuter.classList.contains(this.config.classNames.disabledState);e&&(this._addEventListeners(),this.passedElement.removeAttribute("disabled"),this.input.removeAttribute("disabled"),this.containerOuter.classList.remove(this.config.classNames.disabledState),this.containerOuter.removeAttribute("aria-disabled"),this.isSelectOneElement&&this.containerOuter.setAttribute("tabindex","0"))}return this}},{key:"disable",value:function(){if(this.initialised){this.passedElement.disabled=!0;var e=!this.containerOuter.classList.contains(this.config.classNames.disabledState);e&&(this._removeEventListeners(),this.passedElement.setAttribute("disabled",""),this.input.setAttribute("disabled",""),this.containerOuter.classList.add(this.config.classNames.disabledState),this.containerOuter.setAttribute("aria-disabled","true"),this.isSelectOneElement&&this.containerOuter.setAttribute("tabindex","-1"))}return this}},{key:"ajax",value:function(e){var t=this;return this.initialised===!0&&this.isSelectElement&&(requestAnimationFrame(function(){t._handleLoadingState(!0)}),e(this._ajaxCallback())),this}},{key:"_triggerChange",value:function(e){e&&(0,v.triggerEvent)(this.passedElement,"change",{value:e})}},{key:"_handleButtonAction",value:function(e,t){if(e&&t&&this.config.removeItems&&this.config.removeItemButton){var i=t.parentNode.getAttribute("data-id"),n=e.find(function(e){return e.id===parseInt(i,10)});this._removeItem(n),this._triggerChange(n.value),this.isSelectOneElement&&this._selectPlaceholderChoice()}}},{key:"_selectPlaceholderChoice",value:function(){var e=this.store.getPlaceholderChoice();e&&(this._addItem(e.value,e.label,e.id,e.groupId,null,e.placeholder),this._triggerChange(e.value))}},{key:"_handleItemAction",value:function(e,t){var i=this,n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(e&&t&&this.config.removeItems&&!this.isSelectOneElement){var s=t.getAttribute("data-id");e.forEach(function(e){e.id!==parseInt(s,10)||e.highlighted?n||e.highlighted&&i.unhighlightItem(e):i.highlightItem(e)}),document.activeElement!==this.input&&this.input.focus()}}},{key:"_handleChoiceAction",value:function(e,t){if(e&&t){var i=t.getAttribute("data-id"),n=this.store.getChoiceById(i),s=e[0]&&e[0].keyCode?e[0].keyCode:null,o=this.dropdown.classList.contains(this.config.classNames.activeState);if(n.keyCode=s,(0,v.triggerEvent)(this.passedElement,"choice",{choice:n}),n&&!n.selected&&!n.disabled){var r=this._canAddItem(e,n.value);
5240r.response&&(this._addItem(n.value,n.label,n.id,n.groupId,n.customProperties,n.placeholder,n.keyCode),this._triggerChange(n.value))}this.clearInput(),o&&this.isSelectOneElement&&(this.hideDropdown(),this.containerOuter.focus())}}},{key:"_handleBackspace",value:function(e){if(this.config.removeItems&&e){var t=e[e.length-1],i=e.some(function(e){return e.highlighted});this.config.editItems&&!i&&t?(this.input.value=t.value,this._setInputWidth(),this._removeItem(t),this._triggerChange(t.value)):(i||this.highlightItem(t,!1),this.removeHighlightedItems(!0))}}},{key:"_canAddItem",value:function(e,t){var i=!0,n=(0,v.isType)("Function",this.config.addItemText)?this.config.addItemText(t):this.config.addItemText;(this.isSelectMultipleElement||this.isTextElement)&&this.config.maxItemCount>0&&this.config.maxItemCount<=e.length&&(i=!1,n=(0,v.isType)("Function",this.config.maxItemText)?this.config.maxItemText(this.config.maxItemCount):this.config.maxItemText),this.isTextElement&&this.config.addItems&&i&&this.config.regexFilter&&(i=this._regexFilter(t));var s=!e.some(function(e){return(0,v.isType)("String",t)?e.value===t.trim():e.value===t});return s||this.config.duplicateItems||this.isSelectOneElement||!i||(i=!1,n=(0,v.isType)("Function",this.config.uniqueItemText)?this.config.uniqueItemText(t):this.config.uniqueItemText),{response:i,notice:n}}},{key:"_handleLoadingState",value:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],t=this.itemList.querySelector("."+this.config.classNames.placeholder);e?(this.containerOuter.classList.add(this.config.classNames.loadingState),this.containerOuter.setAttribute("aria-busy","true"),this.isSelectOneElement?t?t.innerHTML=this.config.loadingText:(t=this._getTemplate("placeholder",this.config.loadingText),this.itemList.appendChild(t)):this.input.placeholder=this.config.loadingText):(this.containerOuter.classList.remove(this.config.classNames.loadingState),this.isSelectOneElement?t.innerHTML=this.placeholder||"":this.input.placeholder=this.placeholder||"")}},{key:"_ajaxCallback",value:function(){var e=this;return function(t,i,n){if(t&&i){var s=(0,v.isType)("Object",t)?[t]:t;s&&(0,v.isType)("Array",s)&&s.length?(e._handleLoadingState(!1),e._setLoading(!0),s.forEach(function(t){if(t.choices){var s=t.id||null;e._addGroup(t,s,i,n)}else e._addChoice(t[i],t[n],t.selected,t.disabled,void 0,t.customProperties,t.placeholder)}),e._setLoading(!1),e.isSelectOneElement&&e._selectPlaceholderChoice()):e._handleLoadingState(!1),e.containerOuter.removeAttribute("aria-busy")}}}},{key:"_searchChoices",value:function(e){var t=(0,v.isType)("String",e)?e.trim():e,i=(0,v.isType)("String",this.currentValue)?this.currentValue.trim():this.currentValue;if(t.length>=1&&t!==i+" "){var n=this.store.getSearchableChoices(),s=t,o=(0,v.isType)("Array",this.config.searchFields)?this.config.searchFields:[this.config.searchFields],r=Object.assign(this.config.fuseOptions,{keys:o}),a=new l.default(n,r),c=a.search(s);return this.currentValue=t,this.highlightPosition=0,this.isSearching=!0,this.store.dispatch((0,p.filterChoices)(c)),c.length}return 0}},{key:"_handleSearch",value:function(e){if(e){var t=this.store.getChoices(),i=t.some(function(e){return!e.active});if(this.input===document.activeElement)if(e&&e.length>=this.config.searchFloor){var n=0;this.config.searchChoices&&(n=this._searchChoices(e)),(0,v.triggerEvent)(this.passedElement,"search",{value:e,resultCount:n})}else i&&(this.isSearching=!1,this.store.dispatch((0,p.activateChoices)(!0)))}}},{key:"_addEventListeners",value:function(){document.addEventListener("keyup",this._onKeyUp),document.addEventListener("keydown",this._onKeyDown),document.addEventListener("click",this._onClick),document.addEventListener("touchmove",this._onTouchMove),document.addEventListener("touchend",this._onTouchEnd),document.addEventListener("mousedown",this._onMouseDown),document.addEventListener("mouseover",this._onMouseOver),this.isSelectOneElement&&(this.containerOuter.addEventListener("focus",this._onFocus),this.containerOuter.addEventListener("blur",this._onBlur)),this.input.addEventListener("input",this._onInput),this.input.addEventListener("paste",this._onPaste),this.input.addEventListener("focus",this._onFocus),this.input.addEventListener("blur",this._onBlur)}},{key:"_removeEventListeners",value:function(){document.removeEventListener("keyup",this._onKeyUp),document.removeEventListener("keydown",this._onKeyDown),document.removeEventListener("click",this._onClick),document.removeEventListener("touchmove",this._onTouchMove),document.removeEventListener("touchend",this._onTouchEnd),document.removeEventListener("mousedown",this._onMouseDown),document.removeEventListener("mouseover",this._onMouseOver),this.isSelectOneElement&&(this.containerOuter.removeEventListener("focus",this._onFocus),this.containerOuter.removeEventListener("blur",this._onBlur)),this.input.removeEventListener("input",this._onInput),this.input.removeEventListener("paste",this._onPaste),this.input.removeEventListener("focus",this._onFocus),this.input.removeEventListener("blur",this._onBlur)}},{key:"_setInputWidth",value:function(){this.placeholder?this.input.value&&this.input.value.length>=this.placeholder.length/1.25&&(this.input.style.width=(0,v.getWidthOfInput)(this.input)):this.input.style.width=(0,v.getWidthOfInput)(this.input)}},{key:"_onKeyDown",value:function(e){var t,i=this;if(e.target===this.input||this.containerOuter.contains(e.target)){var n=e.target,o=this.store.getItemsFilteredByActive(),r=this.input===document.activeElement,a=this.dropdown.classList.contains(this.config.classNames.activeState),c=this.itemList&&this.itemList.children,l=String.fromCharCode(e.keyCode),h=46,u=8,d=13,f=65,p=27,m=38,g=40,y=33,b=34,E=e.ctrlKey||e.metaKey;this.isTextElement||!/[a-zA-Z0-9-_ ]/.test(l)||a||this.showDropdown(!0),this.canSearch=this.config.searchEnabled;
5240var _=function(){E&&c&&(i.canSearch=!1,i.config.removeItems&&!i.input.value&&i.input===document.activeElement&&i.highlightAll())},S=function(){if(i.isTextElement&&n.value){var t=i.input.value,s=i._canAddItem(o,t);s.response&&(a&&i.hideDropdown(),i._addItem(t),i._triggerChange(t),i.clearInput())}if(n.hasAttribute("data-button")&&(i._handleButtonAction(o,n),e.preventDefault()),a){e.preventDefault();var r=i.dropdown.querySelector("."+i.config.classNames.highlightedState);r&&(o[0]&&(o[0].keyCode=d),i._handleChoiceAction(o,r))}else i.isSelectOneElement&&(a||(i.showDropdown(!0),e.preventDefault()))},I=function(){a&&(i.toggleDropdown(),i.containerOuter.focus())},w=function(){if(a||i.isSelectOneElement){a||i.showDropdown(!0),i.canSearch=!1;var t=e.keyCode===g||e.keyCode===b?1:-1,n=e.metaKey||e.keyCode===b||e.keyCode===y,s=void 0;if(n)s=t>0?Array.from(i.dropdown.querySelectorAll("[data-choice-selectable]")).pop():i.dropdown.querySelector("[data-choice-selectable]");else{var o=i.dropdown.querySelector("."+i.config.classNames.highlightedState);s=o?(0,v.getAdjacentEl)(o,"[data-choice-selectable]",t):i.dropdown.querySelector("[data-choice-selectable]")}s&&((0,v.isScrolledIntoView)(s,i.choiceList,t)||i._scrollToChoice(s,t),i._highlightChoice(s)),e.preventDefault()}},T=function(){!r||e.target.value||i.isSelectOneElement||(i._handleBackspace(o),e.preventDefault())},C=(t={},s(t,f,_),s(t,d,S),s(t,p,I),s(t,m,w),s(t,y,w),s(t,g,w),s(t,b,w),s(t,u,T),s(t,h,T),t);C[e.keyCode]&&C[e.keyCode]()}}},{key:"_onKeyUp",value:function(e){if(e.target===this.input){var t=this.input.value,i=this.store.getItemsFilteredByActive(),n=this._canAddItem(i,t);if(this.isTextElement){var s=this.dropdown.classList.contains(this.config.classNames.activeState);if(t){if(n.notice){var o=this._getTemplate("notice",n.notice);this.dropdown.innerHTML=o.outerHTML}n.response===!0?s||this.showDropdown():!n.notice&&s&&this.hideDropdown()}else s&&this.hideDropdown()}else{var r=46,a=8;e.keyCode!==r&&e.keyCode!==a||e.target.value?this.canSearch&&n.response&&this._handleSearch(this.input.value):!this.isTextElement&&this.isSearching&&(this.isSearching=!1,this.store.dispatch((0,p.activateChoices)(!0)))}this.canSearch=this.config.searchEnabled}}},{key:"_onInput",value:function(){this.isSelectOneElement||this._setInputWidth()}},{key:"_onTouchMove",value:function(){this.wasTap===!0&&(this.wasTap=!1)}},{key:"_onTouchEnd",value:function(e){var t=e.target||e.touches[0].target,i=this.dropdown.classList.contains(this.config.classNames.activeState);this.wasTap===!0&&this.containerOuter.contains(t)&&(t!==this.containerOuter&&t!==this.containerInner||this.isSelectOneElement||(this.isTextElement?document.activeElement!==this.input&&this.input.focus():i||this.showDropdown(!0)),e.stopPropagation()),this.wasTap=!0}},{key:"_onMouseDown",value:function(e){var t=e.target;if(t===this.choiceList&&this.isIe11&&(this.isScrollingOnIe=!0),this.containerOuter.contains(t)&&t!==this.input){var i=void 0,n=this.store.getItemsFilteredByActive(),s=e.shiftKey;(i=(0,v.findAncestorByAttrName)(t,"data-button"))?this._handleButtonAction(n,i):(i=(0,v.findAncestorByAttrName)(t,"data-item"))?this._handleItemAction(n,i,s):(i=(0,v.findAncestorByAttrName)(t,"data-choice"))&&this._handleChoiceAction(n,i),e.preventDefault()}}},{key:"_onClick",value:function(e){var t=e.target,i=this.dropdown.classList.contains(this.config.classNames.activeState),n=this.store.getItemsFilteredByActive();if(this.containerOuter.contains(t))t.hasAttribute("data-button")&&this._handleButtonAction(n,t),i?this.isSelectOneElement&&t!==this.input&&!this.dropdown.contains(t)&&this.hideDropdown(!0):this.isTextElement?document.activeElement!==this.input&&this.input.focus():this.canSearch?this.showDropdown(!0):(this.showDropdown(),this.containerOuter.focus());else{var s=n.some(function(e){return e.highlighted});s&&this.unhighlightAll(),this.containerOuter.classList.remove(this.config.classNames.focusState),i&&this.hideDropdown()}}},{key:"_onMouseOver",value:function(e){(e.target===this.dropdown||this.dropdown.contains(e.target))&&e.target.hasAttribute("data-choice")&&this._highlightChoice(e.target)}},{key:"_onPaste",value:function(e){e.target!==this.input||this.config.paste||e.preventDefault()}},{key:"_onFocus",value:function(e){var t=this,i=e.target;if(this.containerOuter.contains(i)){var n=this.dropdown.classList.contains(this.config.classNames.activeState),s={text:function(){i===t.input&&t.containerOuter.classList.add(t.config.classNames.focusState)},"select-one":function(){t.containerOuter.classList.add(t.config.classNames.focusState),i===t.input&&(n||t.showDropdown())},"select-multiple":function(){i===t.input&&(t.containerOuter.classList.add(t.config.classNames.focusState),n||t.showDropdown(!0))}};s[this.passedElement.type]()}}},{key:"_onBlur",value:function(e){var t=this,i=e.target;if(this.containerOuter.contains(i)&&!this.isScrollingOnIe){var n=this.store.getItemsFilteredByActive(),s=this.dropdown.classList.contains(this.config.classNames.activeState),o=n.some(function(e){return e.highlighted}),r={text:function(){i===t.input&&(t.containerOuter.classList.remove(t.config.classNames.focusState),o&&t.unhighlightAll(),s&&t.hideDropdown())},"select-one":function(){t.containerOuter.classList.remove(t.config.classNames.focusState),i===t.containerOuter&&s&&!t.canSearch&&t.hideDropdown(),i===t.input&&s&&t.hideDropdown()},"select-multiple":function(){i===t.input&&(t.containerOuter.classList.remove(t.config.classNames.focusState),s&&t.hideDropdown(),o&&t.unhighlightAll())}};r[this.passedElement.type]()}else this.isScrollingOnIe=!1,this.input.focus()}},{key:"_regexFilter",value:function(e){if(!e)return!1;var t=this.config.regexFilter,i=new RegExp(t.source,"i");return i.test(e)}},{key:"_scrollToChoice",value:function(e,t){var i=this;if(e){var n=this.choiceList.offsetHeight,s=e.offsetHeight,o=e.offsetTop+s,r=this.choiceList.scrollTop+n,a=t>0?this.choiceList.scrollTop+o-r:e.offsetTop,c=function e(){var n=4,s=i.choiceList.scrollTop,o=!1,r=void 0,c=void 0;t>0?(r=(a-s)/n,c=r>1?r:1,i.choiceList.scrollTop=s+c,s<a&&(o=!0)):(r=(s-a)/n,c=r>1?r:1,i.choiceList.scrollTop=s-c,s>a&&(o=!0)),o&&requestAnimationFrame(function(i){e(i,a,t)})};requestAnimationFrame(function(e){c(e,a,t)})}}},{key:"_highlightChoice",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,i=Array.from(this.dropdown.querySelectorAll("[data-choice-selectable]")),n=t;if(i&&i.length){var s=Array.from(this.dropdown.querySelectorAll("."+this.config.classNames.highlightedState));
5240s.forEach(function(t){t.classList.remove(e.config.classNames.highlightedState),t.setAttribute("aria-selected","false")}),n?this.highlightPosition=i.indexOf(n):(n=i.length>this.highlightPosition?i[this.highlightPosition]:i[i.length-1],n||(n=i[0])),n.classList.add(this.config.classNames.highlightedState),n.setAttribute("aria-selected","true"),this.containerOuter.setAttribute("aria-activedescendant",n.id)}}},{key:"_addItem",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:-1,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:-1,s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null,o=arguments.length>5&&void 0!==arguments[5]&&arguments[5],r=arguments.length>6&&void 0!==arguments[6]?arguments[6]:null,a=(0,v.isType)("String",e)?e.trim():e,c=r,l=this.store.getItems(),h=t||a,u=parseInt(i,10)||-1,d=n>=0?this.store.getGroupById(n):null,f=l?l.length+1:1;return this.config.prependValue&&(a=this.config.prependValue+a.toString()),this.config.appendValue&&(a+=this.config.appendValue.toString()),this.store.dispatch((0,p.addItem)(a,h,f,u,n,s,o,c)), 5241this.isSelectOneElement&&this.removeActiveItems(f),d&&d.value?(0,v.triggerEvent)(this.passedElement,"addItem",{id:f,value:a,label:h,groupValue:d.value,keyCode:c}):(0,v.triggerEvent)(this.passedElement,"addItem",{id:f,value:a,label:h,keyCode:c}),this}},{key:"_removeItem",value:function(e){if(!e||!(0,v.isType)("Object",e))return this;var t=e.id,i=e.value,n=e.label,s=e.choiceId,o=e.groupId,r=o>=0?this.store.getGroupById(o):null;return this.store.dispatch((0,p.removeItem)(t,s)),r&&r.value?(0,v.triggerEvent)(this.passedElement,"removeItem",{id:t,value:i,label:n,groupValue:r.value}):(0,v.triggerEvent)(this.passedElement,"removeItem",{id:t,value:i,label:n}),this}},{key:"_addChoice",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]&&arguments[2],n=arguments.length>3&&void 0!==arguments[3]&&arguments[3],s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1,o=arguments.length>5&&void 0!==arguments[5]?arguments[5]:null,r=arguments.length>6&&void 0!==arguments[6]&&arguments[6],a=arguments.length>7&&void 0!==arguments[7]?arguments[7]:null;if("undefined"!=typeof e&&null!==e){var c=this.store.getChoices(),l=t||e,h=c?c.length+1:1,u=this.baseId+"-"+this.idNames.itemChoice+"-"+h;this.store.dispatch((0,p.addChoice)(e,l,h,s,n,u,o,r,a)),i&&this._addItem(e,l,h,void 0,o,r,a)}}},{key:"_clearChoices",value:function(){this.store.dispatch((0,p.clearChoices)())}},{key:"_addGroup",value:function(e,t){var i=this,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"value",s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"label",o=(0,v.isType)("Object",e)?e.choices:Array.from(e.getElementsByTagName("OPTION")),r=t?t:Math.floor((new Date).valueOf()*Math.random()),a=!!e.disabled&&e.disabled;o?(this.store.dispatch((0,p.addGroup)(e.label,r,!0,a)),o.forEach(function(e){var t=e.disabled||e.parentNode&&e.parentNode.disabled;i._addChoice(e[n],(0,v.isType)("Object",e)?e[s]:e.innerHTML,e.selected,t,r,e.customProperties,e.placeholder)})):this.store.dispatch((0,p.addGroup)(e.label,e.id,!1,e.disabled))}},{key:"_getTemplate",value:function(e){if(!e)return null;for(var t=this.config.templates,i=arguments.length,n=Array(i>1?i-1:0),s=1;s<i;s++)n[s-1]=arguments[s];return t[e].apply(t,n)}},{key:"_createTemplates",value:function(){var e=this,t=this.config.classNames,i={containerOuter:function(i){return(0,v.strToEl)('\n <div\n class="'+t.containerOuter+'"\n '+(e.isSelectElement?e.config.searchEnabled?'role="combobox" aria-autocomplete="list"':'role="listbox"':"")+'\n data-type="'+e.passedElement.type+'"\n '+(e.isSelectOneElement?'tabindex="0"':"")+'\n aria-haspopup="true"\n aria-expanded="false"\n dir="'+i+'"\n >\n </div>\n ')},containerInner:function(){return(0,v.strToEl)('\n <div class="'+t.containerInner+'"></div>\n ')},itemList:function(){var i,n=(0,u.default)(t.list,(i={},s(i,t.listSingle,e.isSelectOneElement),s(i,t.listItems,!e.isSelectOneElement),i));return(0,v.strToEl)('\n <div class="'+n+'"></div>\n ')},placeholder:function(e){return(0,v.strToEl)('\n <div class="'+t.placeholder+'">\n '+e+"\n </div>\n ")},item:function(i){var n,o=(0,u.default)(t.item,(n={},s(n,t.highlightedState,i.highlighted),s(n,t.itemSelectable,!i.highlighted),s(n,t.placeholder,i.placeholder),n));if(e.config.removeItemButton){var r;return o=(0,u.default)(t.item,(r={},s(r,t.highlightedState,i.highlighted),s(r,t.itemSelectable,!i.disabled),s(r,t.placeholder,i.placeholder),r)),(0,v.strToEl)('\n <div\n class="'+o+'"\n data-item\n data-id="'+i.id+'"\n data-value="'+i.value+'"\n data-deletable\n '+(i.active?'aria-selected="true"':"")+"\n "+(i.disabled?'aria-disabled="true"':"")+"\n >\n "+i.label+'<!--\n --><button\n type="button"\n class="'+t.button+'"\n data-button\n aria-label="Remove item: \''+i.value+"'\"\n >\n Remove item\n </button>\n </div>\n ")}return(0,v.strToEl)('\n <div\n class="'+o+'"\n data-item\n data-id="'+i.id+'"\n data-value="'+i.value+'"\n '+(i.active?'aria-selected="true"':"")+"\n "+(i.disabled?'aria-disabled="true"':"")+"\n >\n "+i.label+"\n </div>\n ")},choiceList:function(){return(0,v.strToEl)('\n <div\n class="'+t.list+'"\n dir="ltr"\n role="listbox"\n '+(e.isSelectOneElement?"":'aria-multiselectable="true"')+"\n >\n </div>\n ")},choiceGroup:function(e){var i=(0,u.default)(t.group,s({},t.itemDisabled,e.disabled));return(0,v.strToEl)('\n <div\n class="'+i+'"\n data-group\n data-id="'+e.id+'"\n data-value="'+e.value+'"\n role="group"\n '+(e.disabled?'aria-disabled="true"':"")+'\n >\n <div class="'+t.groupHeading+'">'+e.value+"</div>\n </div>\n ")},choice:function(i){var n,o=(0,u.default)(t.item,t.itemChoice,(n={},s(n,t.itemDisabled,i.disabled),s(n,t.itemSelectable,!i.disabled),s(n,t.placeholder,i.placeholder),n));return(0,v.strToEl)('\n <div\n class="'+o+'"\n data-select-text="'+e.config.itemSelectText+'"\n data-choice\n data-id="'+i.id+'"\n data-value="'+i.value+'"\n '+(i.disabled?'data-choice-disabled aria-disabled="true"':"data-choice-selectable")+'\n id="'+i.elementId+'"\n '+(i.groupId>0?'role="treeitem"':'role="option"')+"\n >\n "+i.label+"\n </div>\n ")}
5241,input:function(){var e=(0,u.default)(t.input,t.inputCloned);return(0,v.strToEl)('\n <input\n type="text"\n class="'+e+'"\n autocomplete="off"\n autocapitalize="off"\n spellcheck="false"\n role="textbox"\n aria-autocomplete="list"\n >\n ')},dropdown:function(){var e=(0,u.default)(t.list,t.listDropdown);return(0,v.strToEl)('\n <div\n class="'+e+'"\n aria-expanded="false"\n >\n </div>\n ')},notice:function(e){var i,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",o=(0,u.default)(t.item,t.itemChoice,(i={},s(i,t.noResults,"no-results"===n),s(i,t.noChoices,"no-choices"===n),i));return(0,v.strToEl)('\n <div class="'+o+'">\n '+e+"\n </div>\n ")},option:function(e){return(0,v.strToEl)('\n <option value="'+e.value+'" selected>'+e.label+"</option>\n ")}},n=this.config.callbackOnCreateTemplates,o={};n&&(0,v.isType)("Function",n)&&(o=n.call(this,v.strToEl)),this.config.templates=(0,v.extend)(i,o)}},{key:"_setLoading",value:function(e){this.store.dispatch((0,p.setIsLoading)(e))}},{key:"_createInput",value:function(){var e=this,t=this.passedElement.getAttribute("dir")||"ltr",i=this._getTemplate("containerOuter",t),n=this._getTemplate("containerInner"),s=this._getTemplate("itemList"),o=this._getTemplate("choiceList"),r=this._getTemplate("input"),a=this._getTemplate("dropdown");this.containerOuter=i,this.containerInner=n,this.input=r,this.choiceList=o,this.itemList=s,this.dropdown=a,this.passedElement.classList.add(this.config.classNames.input,this.config.classNames.hiddenState),this.passedElement.tabIndex="-1";var c=this.passedElement.getAttribute("style");if(Boolean(c)&&this.passedElement.setAttribute("data-choice-orig-style",c),this.passedElement.setAttribute("style","display:none;"),this.passedElement.setAttribute("aria-hidden","true"),this.passedElement.setAttribute("data-choice","active"),(0,v.wrap)(this.passedElement,n),(0,v.wrap)(n,i),this.isSelectOneElement?r.placeholder=this.config.searchPlaceholderValue||"":this.placeholder&&(r.placeholder=this.placeholder,r.style.width=(0,v.getWidthOfInput)(r)),this.config.addItems||this.disable(),i.appendChild(n),i.appendChild(a),n.appendChild(s),this.isTextElement||a.appendChild(o),this.isSelectMultipleElement||this.isTextElement?n.appendChild(r):this.canSearch&&a.insertBefore(r,a.firstChild),this.isSelectElement){var l=Array.from(this.passedElement.getElementsByTagName("OPTGROUP"));if(this.highlightPosition=0,this.isSearching=!1,this._setLoading(!0),l&&l.length)l.forEach(function(t){e._addGroup(t,t.id||null)});else{var h=Array.from(this.passedElement.options),u=this.config.sortFilter,d=this.presetChoices;h.forEach(function(e){d.push({value:e.value,label:e.innerHTML,selected:e.selected,disabled:e.disabled||e.parentNode.disabled,placeholder:e.hasAttribute("placeholder")})}),this.config.shouldSort&&d.sort(u);var f=d.some(function(e){return e.selected});d.forEach(function(t,i){if(e.isSelectOneElement){var n=f||!f&&i>0;e._addChoice(t.value,t.label,!n||t.selected,!!n&&t.disabled,void 0,t.customProperties,t.placeholder)}else e._addChoice(t.value,t.label,t.selected,t.disabled,void 0,t.customProperties,t.placeholder)})}this._setLoading(!1)}else this.isTextElement&&this.presetItems.forEach(function(t){var i=(0,v.getType)(t);if("Object"===i){if(!t.value)return;e._addItem(t.value,t.label,t.id,void 0,t.customProperties,t.placeholder)}else"String"===i&&e._addItem(t)})}}]),e}();e.exports=m},function(e,t,i){!function(t){"use strict";function i(){console.log.apply(console,arguments)}function n(e,t){var i;this.list=e,this.options=t=t||{};for(i in a)a.hasOwnProperty(i)&&("boolean"==typeof a[i]?this.options[i]=i in t?t[i]:a[i]:this.options[i]=t[i]||a[i])}function s(e,t,i){var n,r,a,c,l,h;if(t){if(a=t.indexOf("."),a!==-1?(n=t.slice(0,a),r=t.slice(a+1)):n=t,c=e[n],null!==c&&void 0!==c)if(r||"string"!=typeof c&&"number"!=typeof c)if(o(c))for(l=0,h=c.length;l<h;l++)s(c[l],r,i);else r&&s(c,r,i);else i.push(c)}else i.push(e);return i}function o(e){return"[object Array]"===Object.prototype.toString.call(e)}function r(e,t){t=t||{},this.options=t,this.options.location=t.location||r.defaultOptions.location,this.options.distance="distance"in t?t.distance:r.defaultOptions.distance,this.options.threshold="threshold"in t?t.threshold:r.defaultOptions.threshold,this.options.maxPatternLength=t.maxPatternLength||r.defaultOptions.maxPatternLength,this.pattern=t.caseSensitive?e:e.toLowerCase(),this.patternLen=e.length,this.patternLen<=this.options.maxPatternLength&&(this.matchmask=1<<this.patternLen-1,this.patternAlphabet=this._calculatePatternAlphabet())}var a={id:null,caseSensitive:!1,include:[],shouldSort:!0,searchFn:r,sortFn:function(e,t){return e.score-t.score}
5241,getFn:s,keys:[],verbose:!1,tokenize:!1,matchAllTokens:!1,tokenSeparator:/ +/g,minMatchCharLength:1,findAllMatches:!1};n.VERSION="2.7.3",n.prototype.set=function(e){return this.list=e,e},n.prototype.search=function(e){this.options.verbose&&i("\nSearch term:",e,"\n"),this.pattern=e,this.results=[],this.resultMap={},this._keyMap=null,this._prepareSearchers(),this._startSearch(),this._computeScore(),this._sort();var t=this._format();return t},n.prototype._prepareSearchers=function(){var e=this.options,t=this.pattern,i=e.searchFn,n=t.split(e.tokenSeparator),s=0,o=n.length;if(this.options.tokenize)for(this.tokenSearchers=[];s<o;s++)this.tokenSearchers.push(new i(n[s],e));this.fullSeacher=new i(t,e)},n.prototype._startSearch=function(){var e,t,i,n,s=this.options,o=s.getFn,r=this.list,a=r.length,c=this.options.keys,l=c.length,h=null;if("string"==typeof r[0])for(i=0;i<a;i++)this._analyze("",r[i],i,i);else for(this._keyMap={},i=0;i<a;i++)for(h=r[i],n=0;n<l;n++){if(e=c[n],"string"!=typeof e){if(t=1-e.weight||1,this._keyMap[e.name]={weight:t},e.weight<=0||e.weight>1)throw new Error("Key weight has to be > 0 and <= 1");e=e.name}else this._keyMap[e]={weight:1};this._analyze(e,o(h,e,[]),h,i)}},n.prototype._analyze=function(e,t,n,s){var r,a,c,l,h,u,d,f,p,v,m,g,y,b,E,_=this.options,S=!1;if(void 0!==t&&null!==t){a=[];var I=0;if("string"==typeof t){if(r=t.split(_.tokenSeparator),_.verbose&&i("---------\nKey:",e),this.options.tokenize){for(b=0;b<this.tokenSearchers.length;b++){for(f=this.tokenSearchers[b],_.verbose&&i("Pattern:",f.pattern),p=[],g=!1,E=0;E<r.length;E++){v=r[E],m=f.search(v);var w={};m.isMatch?(w[v]=m.score,S=!0,g=!0,a.push(m.score)):(w[v]=1,this.options.matchAllTokens||a.push(1)),p.push(w)}g&&I++,_.verbose&&i("Token scores:",p)}for(l=a[0],u=a.length,b=1;b<u;b++)l+=a[b];l/=u,_.verbose&&i("Token score average:",l)}d=this.fullSeacher.search(t),_.verbose&&i("Full text score:",d.score),h=d.score,void 0!==l&&(h=(h+l)/2),_.verbose&&i("Score average:",h),y=!this.options.tokenize||!this.options.matchAllTokens||I>=this.tokenSearchers.length,_.verbose&&i("Check Matches",y),(S||d.isMatch)&&y&&(c=this.resultMap[s],c?c.output.push({key:e,score:h,matchedIndices:d.matchedIndices}):(this.resultMap[s]={item:n,output:[{key:e,score:h,matchedIndices:d.matchedIndices}]},this.results.push(this.resultMap[s])))}else if(o(t))for(b=0;b<t.length;b++)this._analyze(e,t[b],n,s)}},n.prototype._computeScore=function(){var e,t,n,s,o,r,a,c,l,h=this._keyMap,u=this.results;for(this.options.verbose&&i("\n\nComputing score:\n"),e=0;e<u.length;e++){for(n=0,s=u[e].output,o=s.length,c=1,t=0;t<o;t++)r=s[t].score,a=h?h[s[t].key].weight:1,l=r*a,1!==a?c=Math.min(c,l):(n+=l,s[t].nScore=l);1===c?u[e].score=n/o:u[e].score=c,this.options.verbose&&i(u[e])}},n.prototype._sort=function(){var e=this.options;e.shouldSort&&(e.verbose&&i("\n\nSorting...."),this.results.sort(e.sortFn))},n.prototype._format=function(){var e,t,n,s,o=this.options,r=o.getFn,a=[],c=this.results,l=o.include;for(o.verbose&&i("\n\nOutput:\n\n",c),n=o.id?function(e){c[e].item=r(c[e].item,o.id,[])[0]}:function(){},s=function(e){var t,i,n,s,o,r=c[e];if(l.length>0){if(t={item:r.item},l.indexOf("matches")!==-1)for(n=r.output,t.matches=[],i=0;i<n.length;i++)s=n[i],o={indices:s.matchedIndices},s.key&&(o.key=s.key),t.matches.push(o);l.indexOf("score")!==-1&&(t.score=c[e].score)}else t=r.item;return t},e=0,t=c.length;e<t;e++)n(e),a.push(s(e));return a},r.defaultOptions={location:0,distance:100,threshold:.6,maxPatternLength:32},r.prototype._calculatePatternAlphabet=function(){var e={},t=0;for(t=0;t<this.patternLen;t++)e[this.pattern.charAt(t)]=0;for(t=0;t<this.patternLen;t++)e[this.pattern.charAt(t)]|=1<<this.pattern.length-t-1;return e},r.prototype._bitapScore=function(e,t){var i=e/this.patternLen,n=Math.abs(this.options.location-t);return this.options.distance?i+n/this.options.distance:n?1:i},r.prototype.search=function(e){var t,i,n,s,o,r,a,c,l,h,u,d,f,p,v,m,g,y,b,E,_,S,I,w=this.options;if(e=w.caseSensitive?e:e.toLowerCase(),this.pattern===e)return{isMatch:!0,score:0,matchedIndices:[[0,e.length-1]]};if(this.patternLen>w.maxPatternLength){if(y=e.match(new RegExp(this.pattern.replace(w.tokenSeparator,"|"))),b=!!y)for(_=[],t=0,S=y.length;t<S;
5241t++)I=y[t],_.push([e.indexOf(I),I.length-1]);return{isMatch:b,score:b?.5:1,matchedIndices:_}}for(s=w.findAllMatches,o=w.location,n=e.length,r=w.threshold,a=e.indexOf(this.pattern,o),E=[],t=0;t<n;t++)E[t]=0;for(a!=-1&&(r=Math.min(this._bitapScore(0,a),r),a=e.lastIndexOf(this.pattern,o+this.patternLen),a!=-1&&(r=Math.min(this._bitapScore(0,a),r))),a=-1,m=1,g=[],h=this.patternLen+n,t=0;t<this.patternLen;t++){for(c=0,l=h;c<l;)this._bitapScore(t,o+l)<=r?c=l:h=l,l=Math.floor((h-c)/2+c);for(h=l,u=Math.max(1,o-l+1),d=s?n:Math.min(o+l,n)+this.patternLen,f=Array(d+2),f[d+1]=(1<<t)-1,i=d;i>=u;i--)if(v=this.patternAlphabet[e.charAt(i-1)],v&&(E[i-1]=1),f[i]=(f[i+1]<<1|1)&v,0!==t&&(f[i]|=(p[i+1]|p[i])<<1|1|p[i+1]),f[i]&this.matchmask&&(m=this._bitapScore(t,i-1),m<=r)){if(r=m,a=i-1,g.push(a),a<=o)break;u=Math.max(1,2*o-a)}if(this._bitapScore(t+1,o)>r)break;p=f}return _=this._getMatchedIndices(E),{isMatch:a>=0,score:0===m?.001:m,matchedIndices:_}},r.prototype._getMatchedIndices=function(e){for(var t,i=[],n=-1,s=-1,o=0,r=e.length;o<r;o++)t=e[o],t&&n===-1?n=o:t||n===-1||(s=o-1,s-n+1>=this.options.minMatchCharLength&&i.push([n,s]),n=-1);return e[o-1]&&o-1-n+1>=this.options.minMatchCharLength&&i.push([n,o-1]),i},e.exports=n}(this)},function(e,t,i){var n,s;!function(){"use strict";function i(){for(var e=[],t=0;t<arguments.length;t++){var n=arguments[t];if(n){var s=typeof n;if("string"===s||"number"===s)e.push(n);else if(Array.isArray(n))e.push(i.apply(null,n));else if("object"===s)for(var r in n)o.call(n,r)&&n[r]&&e.push(r)}}return e.join(" ")}var o={}.hasOwnProperty;"undefined"!=typeof e&&e.exports?e.exports=i:(n=[],s=function(){return i}.apply(t,n),!(void 0!==s&&(e.exports=s)))}()},function(e,t,i){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function s(e){if(Array.isArray(e)){for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}return Array.from(e)}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var i=0;i<t.length;i++){var n=t[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,i,n){return i&&e(t.prototype,i),n&&e(t,n),t}}(),a=i(5),c=i(26),l=n(c),h=function(){function e(){o(this,e),this.store=(0,a.createStore)(l.default,window.devToolsExtension?window.devToolsExtension():void 0)}return r(e,[{key:"getState",value:function(){return this.store.getState()}},{key:"dispatch",value:function(e){this.store.dispatch(e)}},{key:"subscribe",value:function(e){this.store.subscribe(e)}},{key:"isLoading",value:function(){var e=this.store.getState();return e.general.loading}},{key:"getItems",value:function(){var e=this.store.getState();return e.items}},{key:"getItemsFilteredByActive",value:function(){var e=this.getItems(),t=e.filter(function(e){return e.active===!0},[]);return t}},{key:"getItemsReducedToValues",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.getItems(),t=e.reduce(function(e,t){return e.push(t.value),e},[]);return t}},{key:"getChoices",value:function(){var e=this.store.getState();return e.choices}},{key:"getChoicesFilteredByActive",value:function(){var e=this.getChoices(),t=e.filter(function(e){return e.active===!0});return t}},{key:"getChoicesFilteredBySelectable",value:function(){var e=this.getChoices(),t=e.filter(function(e){return e.disabled!==!0});return t}},{key:"getSearchableChoices",value:function(){var e=this.getChoicesFilteredBySelectable();return e.filter(function(e){return e.placeholder!==!0})}},{key:"getChoiceById",value:function(e){if(e){var t=this.getChoicesFilteredByActive(),i=t.find(function(t){return t.id===parseInt(e,10)});return i}return!1}},{key:"getGroups",value:function(){var e=this.store.getState();return e.groups}},{key:"getGroupsFilteredByActive",value:function(){var e=this.getGroups(),t=this.getChoices(),i=e.filter(function(e){var i=e.active===!0&&e.disabled===!1,n=t.some(function(e){return e.active===!0&&e.disabled===!1});return i&&n},[]);return i}},{key:"getGroupById",value:function(e){var t=this.getGroups(),i=t.find(function(t){return t.id===e});return i}},{key:"getPlaceholderChoice",value:function(){var e=this.getChoices(),t=[].concat(s(e)).reverse().find(function(e){return e.placeholder===!0});return t}}]),e}();t.default=h,e.exports=h},function(e,t,i){"use strict";
5241function n(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0,t.compose=t.applyMiddleware=t.bindActionCreators=t.combineReducers=t.createStore=void 0;var s=i(6),o=n(s),r=i(21),a=n(r),c=i(23),l=n(c),h=i(24),u=n(h),d=i(25),f=n(d),p=i(22);n(p);t.createStore=o.default,t.combineReducers=a.default,t.bindActionCreators=l.default,t.applyMiddleware=u.default,t.compose=f.default},function(e,t,i){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function s(e,t,i){function n(){g===m&&(g=m.slice())}function o(){return v}function a(e){if("function"!=typeof e)throw new Error("Expected listener to be a function.");var t=!0;return n(),g.push(e),function(){if(t){t=!1,n();var i=g.indexOf(e);g.splice(i,1)}}}function h(e){if(!(0,r.default)(e))throw new Error("Actions must be plain objects. Use custom middleware for async actions.");if("undefined"==typeof e.type)throw new Error('Actions may not have an undefined "type" property. Have you misspelled a constant?');if(y)throw new Error("Reducers may not dispatch actions.");try{y=!0,v=p(v,e)}finally{y=!1}for(var t=m=g,i=0;i<t.length;i++){var n=t[i];n()}return e}function u(e){if("function"!=typeof e)throw new Error("Expected the nextReducer to be a function.");p=e,h({type:l.INIT})}function d(){var e,t=a;return e={subscribe:function(e){function i(){e.next&&e.next(o())}if("object"!=typeof e)throw new TypeError("Expected the observer to be an object.");i();var n=t(i);return{unsubscribe:n}}},e[c.default]=function(){return this},e}var f;if("function"==typeof t&&"undefined"==typeof i&&(i=t,t=void 0),"undefined"!=typeof i){if("function"!=typeof i)throw new Error("Expected the enhancer to be a function.");return i(s)(e,t)}if("function"!=typeof e)throw new Error("Expected the reducer to be a function.");var p=e,v=t,m=[],g=m,y=!1;return h({type:l.INIT}),f={dispatch:h,subscribe:a,getState:o,replaceReducer:u},f[c.default]=d,f}t.__esModule=!0,t.ActionTypes=void 0,t.default=s;var o=i(7),r=n(o),a=i(17),c=n(a),l=t.ActionTypes={INIT:"@@redux/INIT"}},function(e,t,i){function n(e){if(!r(e)||s(e)!=a)return!1;var t=o(e);if(null===t)return!0;var i=u.call(t,"constructor")&&t.constructor;return"function"==typeof i&&i instanceof i&&h.call(i)==d}var s=i(8),o=i(14),r=i(16),a="[object Object]",c=Function.prototype,l=Object.prototype,h=c.toString,u=l.hasOwnProperty,d=h.call(Object);e.exports=n},function(e,t,i){function n(e){return null==e?void 0===e?c:a:l&&l in Object(e)?o(e):r(e)}var s=i(9),o=i(12),r=i(13),a="[object Null]",c="[object Undefined]",l=s?s.toStringTag:void 0;e.exports=n},function(e,t,i){var n=i(10),s=n.Symbol;e.exports=s},function(e,t,i){var n=i(11),s="object"==typeof self&&self&&self.Object===Object&&self,o=n||s||Function("return this")();e.exports=o},function(e,t){(function(t){var i="object"==typeof t&&t&&t.Object===Object&&t;e.exports=i}).call(t,function(){return this}())},function(e,t,i){function n(e){var t=r.call(e,c),i=e[c];try{e[c]=void 0;var n=!0}catch(e){}var s=a.call(e);return n&&(t?e[c]=i:delete e[c]),s}var s=i(9),o=Object.prototype,r=o.hasOwnProperty,a=o.toString,c=s?s.toStringTag:void 0;e.exports=n},function(e,t){function i(e){return s.call(e)}var n=Object.prototype,s=n.toString;e.exports=i},function(e,t,i){var n=i(15),s=n(Object.getPrototypeOf,Object);e.exports=s},function(e,t){function i(e,t){return function(i){return e(t(i))}}e.exports=i},function(e,t){function i(e){return null!=e&&"object"==typeof e}e.exports=i},function(e,t,i){e.exports=i(18)},function(e,t,i){(function(e,n){"use strict";function s(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var o,r=i(20),a=s(r);o="undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof e?e:n;var c=(0,a.default)(o);t.default=c}).call(t,function(){return this}(),i(19)(e))},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children=[],e.webpackPolyfill=1),e}},function(e,t){"use strict";function i(e){var t,i=e.Symbol;return"function"==typeof i?i.observable?t=i.observable:(t=i("observable"),i.observable=t):t="@@observable",t}
5241Object.defineProperty(t,"__esModule",{value:!0}),t.default=i},function(e,t,i){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function s(e,t){var i=t&&t.type,n=i&&'"'+i.toString()+'"'||"an action";return"Given action "+n+', reducer "'+e+'" returned undefined. To ignore an action, you must explicitly return the previous state. If you want this reducer to hold no value, you can return null instead of undefined.'}function o(e){Object.keys(e).forEach(function(t){var i=e[t],n=i(void 0,{type:a.ActionTypes.INIT});if("undefined"==typeof n)throw new Error('Reducer "'+t+"\" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined. If you don't want to set a value for this reducer, you can use null instead of undefined.");var s="@@redux/PROBE_UNKNOWN_ACTION_"+Math.random().toString(36).substring(7).split("").join(".");if("undefined"==typeof i(void 0,{type:s}))throw new Error('Reducer "'+t+'" returned undefined when probed with a random type. '+("Don't try to handle "+a.ActionTypes.INIT+' or other actions in "redux/*" ')+"namespace. They are considered private. Instead, you must return the current state for any unknown actions, unless it is undefined, in which case you must return the initial state, regardless of the action type. The initial state may not be undefined, but can be null.")})}function r(e){for(var t=Object.keys(e),i={},n=0;n<t.length;n++){var r=t[n];"function"==typeof e[r]&&(i[r]=e[r])}var a=Object.keys(i),c=void 0;try{o(i)}catch(e){c=e}return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments[1];if(c)throw c;for(var n=!1,o={},r=0;r<a.length;r++){var l=a[r],h=i[l],u=e[l],d=h(u,t);if("undefined"==typeof d){var f=s(l,t);throw new Error(f)}o[l]=d,n=n||d!==u}return n?o:e}}
5241t.__esModule=!0,t.default=r;var a=i(6),c=i(7),l=(n(c),i(22));n(l)},function(e,t){"use strict";function i(e){"undefined"!=typeof console&&"function"==typeof console.error&&console.error(e);try{throw new Error(e)}catch(e){}}t.__esModule=!0,t.default=i},function(e,t){"use strict";function i(e,t){return function(){return t(e.apply(void 0,arguments))}}function n(e,t){if("function"==typeof e)return i(e,t);if("object"!=typeof e||null===e)throw new Error("bindActionCreators expected an object or a function, instead received "+(null===e?"null":typeof e)+'. Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?');for(var n=Object.keys(e),s={},o=0;o<n.length;o++){var r=n[o],a=e[r];"function"==typeof a&&(s[r]=i(a,t))}return s}t.__esModule=!0,t.default=n},function(e,t,i){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function s(){for(var e=arguments.length,t=Array(e),i=0;i<e;i++)t[i]=arguments[i];return function(e){return function(i,n,s){var r=e(i,n,s),c=r.dispatch,l=[],h={getState:r.getState,dispatch:function(e){return c(e)}};return l=t.map(function(e){return e(h)}),c=a.default.apply(void 0,l)(r.dispatch),o({},r,{dispatch:c})}}}t.__esModule=!0;var o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var i=arguments[t];for(var n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n])}return e};t.default=s;var r=i(25),a=n(r)},function(e,t){"use strict";function i(){for(var e=arguments.length,t=Array(e),i=0;i<e;i++)t[i]=arguments[i];return 0===t.length?function(e){return e}:1===t.length?t[0]:t.reduce(function(e,t){return function(){return e(t.apply(void 0,arguments))}})}t.__esModule=!0,t.default=i},function(e,t,i){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(t,"__esModule",{value:!0});var s=i(5),o=i(27),r=n(o),a=i(28),c=n(a),l=i(29),h=n(l),u=i(30),d=n(u),f=(0,s.combineReducers)({items:r.default,groups:c.default,choices:h.default,general:d.default}),p=function(e,t){var i=e;return"CLEAR_ALL"===t.type&&(i=void 0),f(i,t)};t.default=p},function(e,t){"use strict";function i(e){if(Array.isArray(e)){for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}return Array.from(e)}Object.defineProperty(t,"__esModule",{value:!0});var n=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1];switch(t.type){case"ADD_ITEM":var n=[].concat(i(e),[{id:t.id,choiceId:t.choiceId,groupId:t.groupId,value:t.value,label:t.label,active:!0,highlighted:!1,customProperties:t.customProperties,placeholder:t.placeholder||!1,keyCode:null}]);return n.map(function(e){return e.highlighted&&(e.highlighted=!1),e});case"REMOVE_ITEM":return e.map(function(e){return e.id===t.id&&(e.active=!1),e});case"HIGHLIGHT_ITEM":return e.map(function(e){return e.id===t.id&&(e.highlighted=t.highlighted),e});default:return e}};t.default=n},function(e,t){"use strict";function i(e){if(Array.isArray(e)){for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}return Array.from(e)}Object.defineProperty(t,"__esModule",{value:!0});var n=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1];switch(t.type){case"ADD_GROUP":return[].concat(i(e),[{id:t.id,value:t.value,active:t.active,disabled:t.disabled}]);case"CLEAR_CHOICES":return e.groups=[];default:return e}};t.default=n},function(e,t){"use strict";function i(e){if(Array.isArray(e)){for(var t=0,i=Array(e.length);t<e.length;t++)i[t]=e[t];return i}return Array.from(e)}Object.defineProperty(t,"__esModule",{value:!0});var n=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments[1];switch(t.type){case"ADD_CHOICE":return[].concat(i(e),[{id:t.id,elementId:t.elementId,groupId:t.groupId,value:t.value,label:t.label||t.value,disabled:t.disabled||!1,selected:!1,active:!0,score:9999,customProperties:t.customProperties,placeholder:t.placeholder||!1,keyCode:null}]);case"ADD_ITEM":var n=e;return t.activateOptions&&(n=e.map(function(e){return e.active=t.active,e})),t.choiceId>-1&&(n=e.map(function(e){return e.id===parseInt(t.choiceId,10)&&(e.selected=!0),e})),n;case"REMOVE_ITEM":return t.choiceId>-1?e.map(function(e){return e.id===parseInt(t.choiceId,10)&&(e.selected=!1),e}):e;case"FILTER_CHOICES":var s=t.results,o=e.map(function(e){return e.active=s.some(function(t){return t.item.id===e.id&&(e.score=t.score,!0)}),e});return o;case"ACTIVATE_CHOICES":return e.map(function(e){return e.active=t.active,e});case"CLEAR_CHOICES":return e.choices=[];default:return e}};t.default=n},function(e,t){"use strict";
5241Object.defineProperty(t,"__esModule",{value:!0});var i=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{loading:!1},t=arguments[1];switch(t.type){case"LOADING":return{loading:t.isLoading};default:return e}};t.default=i},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.addItem=function(e,t,i,n,s,o,r,a){return{type:"ADD_ITEM",value:e,label:t,id:i,choiceId:n,groupId:s,customProperties:o,placeholder:r,keyCode:a}},t.removeItem=function(e,t){return{type:"REMOVE_ITEM",id:e,choiceId:t}},t.highlightItem=function(e,t){return{type:"HIGHLIGHT_ITEM",id:e,highlighted:t}},t.addChoice=function(e,t,i,n,s,o,r,a,c){return{type:"ADD_CHOICE",value:e,label:t,id:i,groupId:n,disabled:s,elementId:o,customProperties:r,placeholder:a,keyCode:c}},t.filterChoices=function(e){return{type:"FILTER_CHOICES",results:e}},t.activateChoices=function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];return{type:"ACTIVATE_CHOICES",active:e}},t.clearChoices=function(){return{type:"CLEAR_CHOICES"}},t.addGroup=function(e,t,i,n){return{type:"ADD_GROUP",value:e,id:t,active:i,disabled:n}},t.clearAll=function(){return{type:"CLEAR_ALL"}},t.setIsLoading=function(e){return{type:"LOADING",isLoading:e}}},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n=(t.capitalise=function(e){return e.replace(/\w\S*/g,function(e){return e.charAt(0).toUpperCase()+e.substr(1).toLowerCase()})},t.generateChars=function(e){for(var t="",i=0;i<e;i++){var n=a(0,36);t+=n.toString(36)}return t}),s=(t.generateId=function(e,t){var i=e.id||e.name&&e.name+"-"+n(2)||n(4);return i=i.replace(/(:|\.|\[|\]|,)/g,""),i=t+i},t.getType=function(e){return Object.prototype.toString.call(e).slice(8,-1)}),o=t.isType=function(e,t){var i=s(t); 5242return void 0!==t&&null!==t&&i===e},r=(t.isNode=function(e){return"object"===("undefined"==typeof Node?"undefined":i(Node))?e instanceof Node:e&&"object"===("undefined"==typeof e?"undefined":i(e))&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName},t.isElement=function(e){return"object"===("undefined"==typeof HTMLElement?"undefined":i(HTMLElement))?e instanceof HTMLElement:e&&"object"===("undefined"==typeof e?"undefined":i(e))&&null!==e&&1===e.nodeType&&"string"==typeof e.nodeName},t.extend=function e(){for(var t={},i=arguments.length,n=function(i){for(var n in i)Object.prototype.hasOwnProperty.call(i,n)&&(o("Object",i[n])?t[n]=e(!0,t[n],i[n]):t[n]=i[n])},s=0;s<i;s++){var r=arguments[s];o("Object",r)&&n(r)}return t},t.whichTransitionEvent=function(){var e,t=document.createElement("fakeelement"),i={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(e in i)if(void 0!==t.style[e])return i[e]},t.whichAnimationEvent=function(){var e,t=document.createElement("fakeelement"),i={animation:"animationend",OAnimation:"oAnimationEnd",MozAnimation:"animationend",WebkitAnimation:"webkitAnimationEnd"};for(e in i)if(void 0!==t.style[e])return i[e]}),a=(t.getParentsUntil=function(e,t,i){for(var n=[];e&&e!==document;e=e.parentNode){if(t){var s=t.charAt(0);if("."===s&&e.classList.contains(t.substr(1)))break;if("#"===s&&e.id===t.substr(1))break;if("["===s&&e.hasAttribute(t.substr(1,t.length-1)))break;if(e.tagName.toLowerCase()===t)break}if(i){var o=i.charAt(0);"."===o&&e.classList.contains(i.substr(1))&&n.push(e),"#"===o&&e.id===i.substr(1)&&n.push(e),"["===o&&e.hasAttribute(i.substr(1,i.length-1))&&n.push(e),e.tagName.toLowerCase()===i&&n.push(e)}else n.push(e)}return 0===n.length?null:n},t.wrap=function(e,t){return t=t||document.createElement("div"),e.nextSibling?e.parentNode.insertBefore(t,e.nextSibling):e.parentNode.appendChild(t),t.appendChild(e)},t.getSiblings=function(e){for(var t=[],i=e.parentNode.firstChild;i;i=i.nextSibling)1===i.nodeType&&i!==e&&t.push(i);return t},t.findAncestor=function(e,t){for(;(e=e.parentElement)&&!e.classList.contains(t););return e}
5242,t.findAncestorByAttrName=function(e,t){for(var i=e;i;){if(i.hasAttribute(t))return i;i=i.parentElement}return null},t.debounce=function(e,t,i){var n;return function(){var s=this,o=arguments,r=function(){n=null,i||e.apply(s,o)},a=i&&!n;clearTimeout(n),n=setTimeout(r,t),a&&e.apply(s,o)}},t.getElemDistance=function(e){var t=0;if(e.offsetParent)do t+=e.offsetTop,e=e.offsetParent;while(e);return t>=0?t:0},t.getElementOffset=function(e,t){var i=t;return i>1&&(i=1),i>0&&(i=0),Math.max(e.offsetHeight*i)},t.getAdjacentEl=function(e,t){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1;if(e&&t){var n=e.parentNode.parentNode,s=Array.from(n.querySelectorAll(t)),o=s.indexOf(e),r=i>0?1:-1;return s[o+r]}},t.getScrollPosition=function(e){return"bottom"===e?Math.max((window.scrollY||window.pageYOffset)+(window.innerHeight||document.documentElement.clientHeight)):window.scrollY||window.pageYOffset},t.isInView=function(e,t,i){return this.getScrollPosition(t)>this.getElemDistance(e)+this.getElementOffset(e,i)},t.isScrolledIntoView=function(e,t){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1;if(e){var n=void 0;return n=i>0?t.scrollTop+t.offsetHeight>=e.offsetTop+e.offsetHeight:e.offsetTop>=t.scrollTop}},t.stripHTML=function(e){var t=document.createElement("DIV");return t.innerHTML=e,t.textContent||t.innerText||""},t.addAnimation=function(e,t){var i=r(),n=function n(){e.classList.remove(t),e.removeEventListener(i,n,!1)};e.classList.add(t),e.addEventListener(i,n,!1)},t.getRandomNumber=function(e,t){return Math.floor(Math.random()*(t-e)+e)}),c=t.strToEl=function(){var e=document.createElement("div");return function(t){var i=t.trim(),n=void 0;for(e.innerHTML=i,n=e.children[0];e.firstChild;)e.removeChild(e.firstChild);return n}}();t.getWidthOfInput=function(e){var t=e.value||e.placeholder,i=e.offsetWidth;if(t){var n=c("<span>"+t+"</span>");if(n.style.position="absolute",n.style.padding="0",n.style.top="-9999px",n.style.left="-9999px",n.style.width="auto",n.style.whiteSpace="pre",document.body.contains(e)&&window.getComputedStyle){var s=window.getComputedStyle(e);s&&(n.style.fontSize=s.fontSize,n.style.fontFamily=s.fontFamily,n.style.fontWeight=s.fontWeight,n.style.fontStyle=s.fontStyle,n.style.letterSpacing=s.letterSpacing,n.style.textTransform=s.textTransform,n.style.padding=s.padding)}document.body.appendChild(n),t&&n.offsetWidth!==e.offsetWidth&&(i=n.offsetWidth+4),document.body.removeChild(n)}return i+"px"},t.sortByAlpha=function(e,t){var i=(e.label||e.value).toLowerCase(),n=(t.label||t.value).toLowerCase();return i<n?-1:i>n?1:0},t.sortByScore=function(e,t){return e.score-t.score},t.triggerEvent=function(e,t){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,n=new CustomEvent(t,{detail:i,bubbles:!0,cancelable:!0});return e.dispatchEvent(n)}},function(e,t){"use strict";!function(){function e(e,t){t=t||{bubbles:!1,cancelable:!1,detail:void 0};var i=document.createEvent("CustomEvent");return i.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),i}Array.from||(Array.from=function(){var e=Object.prototype.toString,t=function(t){return"function"==typeof t||"[object Function]"===e.call(t)},i=function(e){var t=Number(e);return isNaN(t)?0:0!==t&&isFinite(t)?(t>0?1:-1)*Math.floor(Math.abs(t)):t},n=Math.pow(2,53)-1,s=function(e){var t=i(e);return Math.min(Math.max(t,0),n)};return function(e){var i=this,n=Object(e);if(null==e)throw new TypeError("Array.from requires an array-like object - not null or undefined");var o,r=arguments.length>1?arguments[1]:void 0;if("undefined"!=typeof r){if(!t(r))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(o=arguments[2])}for(var a,c=s(n.length),l=t(i)?Object(new i(c)):new Array(c),h=0;h<c;)a=n[h],r?l[h]="undefined"==typeof o?r(a,h):r.call(o,a,h):l[h]=a,h+=1;return l.length=c,l}}()),Array.prototype.find||(Array.prototype.find=function(e){if(null==this)throw new TypeError("Array.prototype.find called on null or undefined");if("function"!=typeof e)throw new TypeError("predicate must be a function");for(var t,i=Object(this),n=i.length>>>0,s=arguments[1],o=0;o<n;o++)if(t=i[o],e.call(s,t,o,i))return t}),e.prototype=window.Event.prototype,window.CustomEvent=e}()}])}); 5243//# sourceMappingURL=choices.min.js.map 5244/*! 5245 * jQuery.scrollTo 5246 * Copyright (c) 2007-2015 Ariel Flesler - aflesler<a>gmail<d>com | http://flesler.blogspot.com 5247 * Licensed under MIT 5248 * http://flesler.blogspot.com/2007/10/jqueryscrollto.html 5249 * @projectDescription Lightweight, cross-browser and highly customizable animated scrolling with jQuery 5250 * @author Ariel Flesler 5251 * @version 2.1.2 5252 */ 5253;(function(factory) { 5254 'use strict'; 5255 if (typeof define === 'function' && define.amd) { 5256 // AMD 5257 define( ['jquery'], factory ); 5258 } else if (typeof module !== 'undefined' && module.exports) { 5259 // CommonJS 5260 module.exports = factory( require( 'jquery' ) ); 5261 } else { 5262 // Global 5263 factory( jQuery ); 5264 } 5265})(function($) { 5266 'use strict'; 5267 5268 var $scrollTo = $.scrollTo = function(target, duration, settings) { 5269 return $( window ).scrollTo( target, duration, settings ); 5270 }; 5271 5272 $scrollTo.defaults = { 5273 axis:'xy', 5274 duration: 0, 5275 limit:true 5276 }; 5277 5278 function isWin(elem) { 5279 return ! elem.nodeName || 5280 $.inArray( elem.nodeName.toLowerCase(), ['iframe','#document','html','body'] ) !== -1; 5281 } 5282 5283 $.fn.scrollTo = function(target, duration, settings) { 5284 if (typeof duration === 'object') { 5285 settings = duration; 5286 duration = 0; 5287 } 5288 if (typeof settings === 'function') { 5289 settings = { onAfter:settings }; 5290 } 5291 if (target === 'max') { 5292 target = 9e9; 5293 } 5294 5295 settings = $.extend( {}, $scrollTo.defaults, settings ); 5296 // Speed is still recognized for backwards compatibility 5297 duration = duration || settings.duration; 5298 // Make sure the settings are given right 5299 var queue = settings.queue && settings.axis.length > 1; 5300 if (queue) { 5301 // Let's keep the overall duration 5302 duration /= 2; 5303 } 5304 settings.offset = both( settings.offset ); 5305 settings.over = both( settings.over ); 5306 5307 return this.each(function() { 5308 // Null target yields nothing, just like jQuery does 5309 if (target === null) { return; } 5310 5311 var win = isWin( this ), 5312 elem = win ? this.contentWindow || window : this, 5313 $elem = $( elem ), 5314 targ = target, 5315 attr = {}, 5316 toff; 5317 5318 switch (typeof targ) { 5319 // A number will pass the regex 5320 case 'number': 5321 case 'string': 5322 if (/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test( targ )) { 5323 targ = both( targ ); 5324 // We are done 5325 break; 5326 } 5327 // Relative/Absolute selector 5328 targ = win ? $( targ ) : $( targ, elem ); 5329 /* falls through */ 5330 case 'object': 5331 if (targ.length === 0) { return; } 5332 // DOMElement / jQuery 5333 if (targ.is || targ.style) { 5334 // Get the real position of the target 5335 toff = (targ = $( targ )).offset(); 5336 } 5337 } 5338 5339 var offset = $.isFunction( settings.offset ) && settings.offset( elem, targ ) || settings.offset; 5340 5341 $.each(settings.axis.split( '' ), function(i, axis) { 5342 var Pos = axis === 'x' ? 'Left' : 'Top', 5343 pos = Pos.toLowerCase(), 5344 key = 'scroll' + Pos, 5345 prev = $elem[key](), 5346 max = $scrollTo.max( elem, axis ); 5347 5348 if (toff) {// jQuery / DOMElement 5349 attr[key] = toff[pos] + (win ? 0 : prev - $elem.offset()[pos]); 5350 5351 // If it's a dom element, reduce the margin 5352 if (settings.margin) { 5353 attr[key] -= parseInt( targ.css( 'margin' + Pos ), 10 ) || 0; 5354 attr[key] -= parseInt( targ.css( 'border' + Pos + 'Width' ), 10 ) || 0; 5355 } 5356 5357 attr[key] += offset[pos] || 0; 5358 5359 if (settings.over[pos]) { 5360 // Scroll to a fraction of its width/height
5361 attr[key] += targ[axis === 'x'?'width':'height']() * settings.over[pos]; 5362 } 5363 } else { 5364 var val = targ[pos]; 5365 // Handle percentage values 5366 attr[key] = val.slice && val.slice( -1 ) === '%' ? 5367 parseFloat( val ) / 100 * max 5368 : val; 5369 } 5370 5371 // Number or 'number' 5372 if (settings.limit && /^\d+$/.test( attr[key] )) { 5373 // Check the limits 5374 attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max ); 5375 } 5376 5377 // Don't waste time animating, if there's no need. 5378 if ( ! i && settings.axis.length > 1) { 5379 if (prev === attr[key]) { 5380 // No animation needed 5381 attr = {}; 5382 } else if (queue) { 5383 // Intermediate animation 5384 animate( settings.onAfterFirst ); 5385 // Don't animate this axis again in the next iteration. 5386 attr = {}; 5387 } 5388 } 5389 }); 5390 5391 animate( settings.onAfter ); 5392 5393 function animate(callback) { 5394 var opts = $.extend({}, settings, { 5395 // The queue setting conflicts with animate() 5396 // Force it to always be true 5397 queue: true, 5398 duration: duration, 5399 complete: callback && function() { 5400 callback.call( elem, targ, settings ); 5401 } 5402 }); 5403 $elem.animate( attr, opts ); 5404 } 5405 }); 5406 }; 5407 5408 // Max scrolling position, works on quirks mode 5409 // It only fails (not too badly) on IE, quirks mode. 5410 $scrollTo.max = function(elem, axis) { 5411 var Dim = axis === 'x' ? 'Width' : 'Height', 5412 scroll = 'scroll' + Dim; 5413 5414 if ( ! isWin( elem )) { 5415 return elem[scroll] - $( elem )[Dim.toLowerCase()](); } 5416 5417 var size = 'client' + Dim, 5418 doc = elem.ownerDocument || elem.document, 5419 html = doc.documentElement, 5420 body = doc.body; 5421 5422 return Math.max( html[scroll], body[scroll] ) - Math.min( html[size], body[size] ); 5423 }; 5424 5425 function both(val) { 5426 return $.isFunction( val ) || $.isPlainObject( val ) ? val : { top:val, left:val }; 5427 } 5428 5429 // Add special hooks so that window scroll properties can be animated 5430 $.Tween.propHooks.scrollLeft = $.Tween.propHooks.scrollTop = { 5431 get: function(t) { 5432 return $( t.elem )[t.prop](); 5433 }, 5434 set: function(t) { 5435 var curr = this.get( t ); 5436 // If interrupt is true and user scrolled, stop animating 5437 if (t.options.interrupt && t._last && t._last !== curr) { 5438 return $( t.elem ).stop(); 5439 } 5440 var next = Math.round( t.now ); 5441 // Don't waste CPU 5442 // Browsers don't render floating point scroll 5443 if (curr !== next) { 5444 $( t.elem )[t.prop](next); 5445 t._last = this.get( t ); 5446 } 5447 } 5448 }; 5449 5450 // AMD requirement 5451 return $scrollTo; 5452}); 5453 5454/*! modernizr 3.5.0 (Custom Build) | MIT * 5455 * https://modernizr.com/download/?-mq !*/ 5456 !function(e,n,t){function o(e,n){return typeof e===n}function a(){var e,n,t,a,i,s,r;for(var d in l)if(l.hasOwnProperty(d)){if(e=[],n=l[d],n.name&&(e.push(n.name.toLowerCase()),n.options&&n.options.aliases&&n.options.aliases.length))for(t=0;t<n.options.aliases.length;t++)e.push(n.options.aliases[t].toLowerCase());for(a=o(n.fn,"function")?n.fn():n.fn,i=0;i<e.length;i++)s=e[i],r=s.split("."),1===r.length?Modernizr[r[0]]=a:(!Modernizr[r[0]]||Modernizr[r[0]]instanceof Boolean||(Modernizr[r[0]]=new Boolean(Modernizr[r[0]])),Modernizr[r[0]][r[1]]=a),f.push((a?"":"no-")+r.join("-"))}}function i(){return"function"!=typeof n.createElement?n.createElement(arguments[0]):c?n.createElementNS.call(n,"http://www.w3.org/2000/svg",arguments[0]):n.createElement.apply(n,arguments)}function s(){var e=n.body;return e||(e=i(c?"svg":"body"),e.fake=!0),e}function r(e,t,o,a){var r,l,d,f,c="modernizr",p=i("div"),h=s();if(parseInt(o,10))for(;o--;)d=i("div"),d.id=a?a[o]:c+(o+1),p.appendChild(d);return r=i("style"),r.type="text/css",r.id="s"+c,(h.fake?h:p).appendChild(r),h.appendChild(p),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(n.createTextNode(e)),p.id=c,h.fake&&(h.style.background="",h.style.overflow="hidden",f=u.style.overflow,u.style.overflow="hidden",u.appendChild(h)),l=t(p,e),h.fake?(h.parentNode.removeChild(h),u.style.overflow=f,u.offsetHeight):p.parentNode.removeChild(p),!!l}var l=[],d={_version:"3.5.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,n){var t=this;setTimeout(function(){n(t[e])},0)},addTest:function(e,n,t){l.push({name:e,fn:n,options:t})},addAsyncTest:function(e){l.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=d,Modernizr=new Modernizr;var f=[],u=n.documentElement,c="svg"===u.nodeName.toLowerCase(),p=function(){var n=e.matchMedia||e.msMatchMedia;return n?function(e){var t=n(e);return t&&t.matches||!1}:function(n){var t=!1;return r("@media "+n+" { #modernizr { position: absolute; } }",function(n){t="absolute"==(e.getComputedStyle?e.getComputedStyle(n,null):n.currentStyle).position}),t}}();d.mq=p,a(),delete d.addTest,delete d.addAsyncTest;for(var h=0;h<Modernizr._q.length;h++)Modernizr._q[h]();e.Modernizr=Modernizr}(window,document); 5457(function( $ ) { 5458 // Since wp form used multiple times add id for aria control 5459 $('#utility-bar .search-form').attr("id", "header-search"); 5460 5461 $('#utility-bar .toggle-search').on('click', function(){ 5462 var siblingMenu = $(this).siblings("form"); 5463 if(siblingMenu.attr('aria-hidden') == "true"){ 5464 siblingMenu.attr("aria-hidden", "false"); 5465 $(this).attr("aria-expanded", "true"); 5466 } else { 5467 siblingMenu.attr("aria-hidden", "true"); 5468 $(this).attr("aria-expanded", "false"); 5469 } 5470 }); 5471 5472 $('#utility-bar .search-form input[type="search"]').focus( function() { 5473 $('#utility-bar .search-form label').addClass('slide-label'); 5474 }); 5475 5476 $('#utility-bar .search-form input[type="search"]').blur( function() { 5477 if($(this).val() == ""){ 5478 $('#utility-bar .search-form label').removeClass('slide-label'); 5479 } 5480 }); 5481 5482 // Main Menu Aria Items 5483 if(Modernizr.mq('(min-width: 1366px)')) { 5484 $('#site-navigation .menu-toggle').attr("aria-expanded", "true"); 5485 $('#menu-main-menu').attr("aria-hidden", "false"); 5486 } else { 5487 $('#site-navigation .menu-toggle').attr("aria-expanded", "false"); 5488 $('#menu-main-menu').attr("aria-hidden", "true"); 5489 } 5490 5491 $('#site-navigation .menu-toggle').on('click', function(){ 5492 var siblingMenu = $(this).siblings("ul"); 5493 if(siblingMenu.attr('aria-hidden') == "true"){ 5494 siblingMenu.attr("aria-hidden", "false"); 5495 $(this).attr("aria-expanded", "true"); 5496 } else { 5497 siblingMenu.attr("aria-hidden", "true"); 5498 $(this).attr("aria-expanded", "false"); 5499 } 5500 }); 5501 5502 $('#menu-primary-navigation > li').on('click', function(){ 5503 $(this).toggleClass('expanded'); 5504 }); 5505 5506 $('#menu-primary-navigation > li > a').on('click', function(e){
5507 e.stopPropagation(); 5508 }); 5509 5510 // Focus styles for menus when using keyboard navigation 5511 // Properly update the ARIA states on focus (keyboard) and mouse over events 5512 /*$( 'nav > ul' ).on( 'focus.wparia mouseenter.wparia', '[aria-haspopup="true"]', function ( ev ) { 5513 $( ev.currentTarget ).attr( 'aria-expanded', true ); 5514 } );*/ 5515 5516 // Properly update the ARIA states on blur (keyboard) and mouse out events 5517 /*$( 'nav > ul' ).on( 'blur.wparia mouseleave.wparia', '[aria-haspopup="true"]', function ( ev ) { 5518 $( ev.currentTarget ).attr( 'aria-expanded', false ); 5519 } );*/ 5520})( jQuery ); 5521/** 5522 * File skip-link-focus-fix.js. 5523 * 5524 * Helps with accessibility for keyboard only users. 5525 * 5526 * Learn more: https://git.io/vWdr2 5527 */ 5528(function() { 5529 var isIe = /(trident|msie)/i.test( navigator.userAgent ); 5530 5531 if ( isIe && document.getElementById && window.addEventListener ) { 5532 window.addEventListener( 'hashchange', function() { 5533 var id = location.hash.substring( 1 ), 5534 element; 5535 5536 if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) { 5537 return; 5538 } 5539 5540 element = document.getElementById( id ); 5541 5542 if ( element ) { 5543 if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) { 5544 element.tabIndex = -1; 5545 } 5546 5547 element.focus(); 5548 } 5549 }, false ); 5550 } 5551})(); 5552 5553/** 5554 * All Job application javascript calls 5555 */ 5556function job_application() { 5557 var hide_all_forms = function() { 5558 // Get all the .application-form divs as an Array so we can map over them 5559 var application_forms = Array.prototype.slice.call(document.querySelectorAll(".application-form")); 5560 // Hide all the forms 5561 return application_forms.map(function(form) { 5562 form.classList.remove("selected-form"); 5563 }); 5564 }; 5565 5566 var show_form_by_name = function(selected_form_name) { 5567 // Get a reference to the div wrapping the corresponding form 5568 var selectedFormSelector = ".application-form-" + selected_form_name; 5569 var selected_form = document.querySelector(selectedFormSelector); 5570 5571 // Reveal the selected one by adding .selected-form 5572 return selected_form.classList.add("selected-form"); 5573 }; 5574 5575 /** 5576 * Event handler for the job application dropdown 5577 */ 5578 var applicationChoiceSelectFunc = function(event) { 5579 var selected_form_name = event.detail.choice.value; 5580 5581 if (selected_form_name) { 5582 hide_all_forms(); 5583 return show_form_by_name(selected_form_name); 5584 } 5585 }; 5586 5587 // Check that this is the application template before proceeding 5588 if (document.querySelector("body.page-template-page-application") !== null) { 5589 var under_18 = "#gf_2"; 5590 var over_18 = "#gf_1"; 5591 var select = document.querySelector("#application-selector"); 5592 var over_18_option = document.createElement("option"); 5593 var under_18_option = document.createElement("option"); 5594 over_18_option.value = "18-plus"; 5595 over_18_option.text = "Over 18 Application"; 5596 under_18_option.value = "under-18"; 5597 under_18_option.text = "Under 18 Application"; 5598 5599 select.innerHTML = ""; 5600 select.appendChild(under_18_option); 5601 select.appendChild(over_18_option); 5602 5603 switch (window.location.hash) { 5604 default: 5605 case over_18: 5606 hide_all_forms(); 5607 show_form_by_name("18-plus"); 5608 over_18_option.setAttribute("selected", true); 5609 break; 5610 5611 case under_18: 5612 hide_all_forms(); 5613 show_form_by_name("under-18"); 5614 under_18_option.setAttribute("selected", true); 5615 break; 5616 } 5617 5618 select.appendChild(under_18_option); 5619 select.appendChild(over_18_option); 5620 5621 // Get a handle on the dropdown 5622 var application_select = document.querySelector("select.application-selector"); 5623 // Make it into a Choices list box 5624 var choiceListBox = new Choices(application_select, { 5625 searchEnabled: false, 5626 itemSelectText: "", 5627 classNames: { 5628 containerOuter: "choices application-selector" 5629 } 5630 }); 5631 // Add the logic for changing the form with an event 5632 application_select.addEventListener("choice", applicationChoiceSelectFunc); 5633 5634 var position_select = document.querySelector(".gfield.position select"); 5635 var positionListBox = new Choices(position_select, { 5636 searchEnabled: false, 5637 placeholder: true, 5638 searchPlaceholderValue: "[Choose Position]", 5639 itemSelectText: "", 5640 classNames: { 5641 containerOuter: "choices position-selector" 5642 } 5643 }); 5644 } 5645} 5646 5647function makeSelectsIntoChoiceLists() { 5648 var single_selects = Array.prototype.slice.call(document.querySelectorAll("select"));
5649 single_selects = single_selects.filter(function(select) { 5650 if (select.getAttribute("multiple")) { 5651 return false; 5652 } 5653 return true; 5654 }); 5655 //console.dir(single_selects); 5656 single_selects.map(function(select) { 5657 return new Choices(select, { 5658 searchEnabled: false, 5659 itemSelectText: "" 5660 }); 5661 }); 5662 var multi_selects = Array.prototype.slice.call(document.querySelectorAll("select[multiple='multiple']")); 5663 multi_selects.map(function(select) { 5664 return new Choices(select, { 5665 searchEnabled: false, 5666 itemSelectText: "", 5667 removeItems: true, 5668 removeItemButton: true, 5669 shouldSort: false 5670 }); 5671 }); 5672} 5673/** 5674 * Callback function for the Attraction Choices 5675 * @param {*} template 5676 */ 5677function attractions_custom_dropdown_templates(template) { 5678 var classNames = this.config.classNames; 5679 5680 // Object Map of tag slugs to class names 5681 var colors = { 5682 "main-attractions": "grey", 5683 rides: "yellow", 5684 "water-park": "blue", 5685 entertainment: "dark-blue", 5686 dining: "red", 5687 shopping: "green" 5688 }; 5689 5690 var itemTemplateFunction = function(data) { 5691 var aria_disabled = data.disabled ? 'aria-disabled="true"' : ""; 5692 var aria_selected = data.active ? 'aria-selected="true"' : ""; 5693 var class_highlight = data.highlighted ? classNames.highlightedState : classNames.itemSelectable; 5694 var slug = data.value.toString().toLowerCase(); 5695 5696 return template( 5697 '<div class="' + 5698 classNames.item + 5699 " " + 5700 class_highlight + 5701 '" data-item data-id="' + 5702 data.id + 5703 '" data-value="' + 5704 slug + 5705 '" ' + 5706 aria_selected + 5707 " " + 5708 aria_disabled + 5709 ">" + 5710 data.label + 5711 "</div>" 5712 ); 5713 }; 5714 var choiceTemplateFunction = function(data) { 5715 var classes = classNames.item + " " + classNames.itemChoice; 5716 var class_disabled = data.disabled ? classNames.itemDisabled : classNames.itemSelectable; 5717 var itemSelectText = this.config && this.config.itemSelectText ? this.config.itemSelectText : ""; 5718 var role = data.groupId > 0 ? 'role="treeitem"' : 'role="option"'; 5719 var aria_disabled = data.disabled ? 'data-choice-disabled aria-disabled="true"' : "data-choice-selectable"; 5720 var slug = data.value 5721 .toString() 5722 .toLowerCase() 5723 .replace(" ", ""); 5724 5725 return template( 5726 '<div class="' + 5727 classes + 5728 " " + 5729 class_disabled + 5730 '" ' + 5731 'data-select-text="' + 5732 itemSelectText + 5733 ' " ' + 5734 "data-choice " + 5735 aria_disabled + 5736 ' data-id="' + 5737 data.id + 5738 '" data-value="' + 5739 data.value.trim() + 5740 '" ' + 5741 role + 5742 ">" + 5743 '<span class="circle ' + 5744 colors[slug] + 5745 '" aria-hidden="true" role="presentation"></span>' + 5746 data.label + 5747 "</div>" 5748 ); 5749 }; 5750 5751 return { 5752 item: itemTemplateFunction, 5753 choice: choiceTemplateFunction 5754 }; 5755} 5756 5757/** 5758 * Create the custom template for the attractions sort selector 5759 */ 5760function attractions_dropdowns() { 5761 /** 5762 * Set the location to a given URL, optionally add the displaymap argument if it is present on the current screen 5763 */ 5764 var set_location_href = function(path, query_string) { 5765 if (query_string) { 5766 return (window.location.href = path + query_string); 5767 } 5768 return (window.location.href = path); 5769 }; 5770 /** 5771 * Category onChange function 5772 */ 5773 var onCatChange = function() { 5774 var query_string = window.location.search; 5775 var selectValue = this.options[this.selectedIndex].value; 5776 5777 if (this.options[this.selectedIndex].value == 0) { 5778 set_location_href("/things-to-do", query_string); 5779 } else { 5780 set_location_href("/things-to-do/" + selectValue, query_string); 5781 } 5782 }; 5783 5784 // Get the select 5785 var attractions_sort_select = document.querySelector("#attractions-selector"); 5786 5787 // Create the Choices list box 5788 if (attractions_sort_select) { 5789 new Choices(attractions_sort_select, { 5790 searchEnabled: false, 5791 classNames: { 5792 containerOuter: "choices attraction-selector" 5793 }, 5794 callbackOnCreateTemplates: attractions_custom_dropdown_templates 5795 }); 5796 5797 attractions_sort_select.onchange = onCatChange; 5798 } 5799} 5800 5801/** 5802 * List/Map Toggle logic 5803 * Creates listeners to add/remove the attractions-map class for the <main> to 5804 * show the park map 5805 */
5806function map_view_toggle() { 5807 var application_list_template = document.querySelector(".page-template-page-attractions-list"); 5808 var view_as_map, view_as_list; 5809 5810 if (application_list_template) { 5811 view_as_map = document.querySelector("#view_as_map"); 5812 view_as_map.addEventListener("change", function() { 5813 var main = document.querySelector("main"); 5814 if (this.checked) { 5815 var displaymap = window.location.search.indexOf("displaymap"); 5816 // if already on displaymap, don't reload, just re-add the class 5817 if (displaymap !== -1) { 5818 return main.classList.add("attractions-map"); 5819 } 5820 // Otherwise just reload the page with displaymap as the param 5821 return (window.location.search = "displaymap"); 5822 } 5823 }); 5824 5825 view_as_list = document.querySelector("#view_as_list"); 5826 view_as_list.addEventListener("change", function() { 5827 if (this.checked) { 5828 // Set the href to the pathname because setting the search would 5829 // keep the ? from the query string which causes bugs 5830 return (window.location.href = window.location.pathname); 5831 } 5832 }); 5833 } 5834} 5835/** 5836 * Creates on click listeners for accordions 5837 * @param {object} $ (jquery) 5838 */ 5839function accordion_toggles($) { 5840 $("div.accordion > h5").on("click", function() { 5841 $(this).toggleClass("expanded"); 5842 }); 5843} 5844 5845/** 5846 * Constructs the slick slider for the front page 5847 */ 5848function front_page_slider($) { 5849 var slider = $(".slider"); 5850 $(slider).slick({ 5851 slidesToShow: 1, 5852 slidesToScroll: 1, 5853 autoplay: true, 5854 autoplaySpeed: 5000, 5855 arrows: true, 5856 fade: true, 5857 dots: true, 5858 infinite: true, 5859 speed: 300 5860 }); 5861} 5862 5863function gaEvent($) { 5864 $(".buy-tickets").click(function() { 5865 gtag('event', 'conversion', { 5866 'allow_custom_scripts': true, 5867 'send_to': 'DC-8024144/conve0/buyti0+standard' 5868 }); 5869 }); 5870} 5871 5872function initialize_modals($) { 5873 $("[data-fancybox]").fancybox({}); 5874} 5875 5876/** 5877 * On attractions map pages, clicks the map marker 5878 */ 5879function attractions_marker_click_from_query() { 5880 var attractions_list_template = document.querySelector("body.page-template-page-attractions-list"), 5881 display_map = window.location.search.indexOf("?displaymap") > -1, 5882 indexOfAmpersand, 5883 attraction_id, 5884 attraction_map_marker; 5885 5886 if (attractions_list_template && display_map) { 5887 indexOfAmpersand = window.location.search.indexOf("&"); 5888 attraction_id = window.location.search.substring(indexOfAmpersand + "&id=".length); 5889 attraction_map_marker = document.querySelector(".map-marker.attraction-" + attraction_id); 5890 if (attraction_map_marker) { 5891 attraction_map_marker.click(); 5892 } 5893 } 5894} 5895/** 5896 * Secure Target Blanks 5897 * Make any link that has target="_blank" that doesn not have noreferrer noopener 5898 * have those in their rel attribute 5899 */ 5900function secure_target_blanks() { 5901 var anchor_tags = Array.prototype.slice.call(document.querySelectorAll("a[target]")); 5902 5903 anchor_tags.map(function(el) { 5904 if (el.getAttribute("target") === "_blank") { 5905 el.setAttribute("rel", "noopener noreferrer"); 5906 } 5907 }); 5908} 5909 5910/** 5911 * Main Function 5912 */ 5913 5914(function($) { 5915 job_application(); 5916 attractions_dropdowns(); 5917 makeSelectsIntoChoiceLists(); 5918 map_view_toggle(); 5919 accordion_toggles($); 5920 front_page_slider($); 5921 gaEvent($); 5922 initialize_modals($); 5923 attractions_marker_click_from_query(); 5924 secure_target_blanks(); 5925})(jQuery); 5926
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.