1/******/ (function(modules) { // webpackBootstrap 2/******/ // The module cache 3/******/ var installedModules = {}; 4/******/ 5/******/ // The require function 6/******/ function __webpack_require__(moduleId) { 7/******/ 8/******/ // Check if module is in cache 9/******/ if(installedModules[moduleId]) { 10/******/ return installedModules[moduleId].exports; 11/******/ } 12/******/ // Create a new module (and put it into the cache) 13/******/ var module = installedModules[moduleId] = { 14/******/ i: moduleId, 15/******/ l: false, 16/******/ exports: {} 17/******/ }; 18/******/ 19/******/ // Execute the module function 20/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21/******/ 22/******/ // Flag the module as loaded 23/******/ module.l = true; 24/******/ 25/******/ // Return the exports of the module 26/******/ return module.exports; 27/******/ } 28/******/ 29/******/ 30/******/ // expose the modules object (__webpack_modules__) 31/******/ __webpack_require__.m = modules; 32/******/ 33/******/ // expose the module cache 34/******/ __webpack_require__.c = installedModules; 35/******/ 36/******/ // define getter function for harmony exports 37/******/ __webpack_require__.d = function(exports, name, getter) { 38/******/ if(!__webpack_require__.o(exports, name)) { 39/******/ Object.defineProperty(exports, name, { 40/******/ configurable: false, 41/******/ enumerable: true, 42/******/ get: getter 43/******/ }); 44/******/ } 45/******/ }; 46/******/ 47/******/ // getDefaultExport function for compatibility with non-harmony modules 48/******/ __webpack_require__.n = function(module) { 49/******/ var getter = module && module.__esModule ? 50/******/ function getDefault() { return module['default']; } : 51/******/ function getModuleExports() { return module; }; 52/******/ __webpack_require__.d(getter, 'a', getter); 53/******/ return getter; 54/******/ }; 55/******/ 56/******/ // Object.prototype.hasOwnProperty.call 57/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 58/******/ 59/******/ // __webpack_public_path__ 60/******/ __webpack_require__.p = "/wp-content/themes/closer-to-truth/dist/"; 61/******/ 62/******/ // Load entry module and return exports 63/******/ return __webpack_require__(__webpack_require__.s = 13); 64/******/ }) 65/************************************************************************/ 66/******/ ([ 67/* 0 */ 68/***/ (function(module, exports) { 69 70module.exports = jQuery; 71 72/***/ }), 73/* 1 */ 74/***/ (function(module, exports, __webpack_require__) { 75 76var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 77 * Fizzy UI utils v2.0.7 78 * MIT license 79 */ 80 81/*jshint browser: true, undef: true, unused: true, strict: true */ 82 83( function( window, factory ) { 84 // universal module definition 85 /*jshint strict: false */ /*globals define, module, require */ 86 87 if ( true ) { 88 // AMD 89 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 90 __webpack_require__(12) 91 ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( matchesSelector ) { 92 return factory( window, matchesSelector ); 93 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 94 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 95 } else if ( typeof module == 'object' && module.exports ) { 96 // CommonJS 97 module.exports = factory( 98 window, 99 require('desandro-matches-selector') 100 ); 101 } else { 102 // browser global 103 window.fizzyUIUtils = factory( 104 window, 105 window.matchesSelector 106 ); 107 } 108 109}( window, function factory( window, matchesSelector ) { 110 111'use strict'; 112 113var utils = {}; 114 115// ----- extend ----- // 116 117// extends objects 118utils.extend = function( a, b ) { 119 for ( var prop in b ) { 120 a[ prop ] = b[ prop ]; 121 } 122 return a; 123}; 124 125// ----- modulo ----- // 126 127utils.modulo = function( num, div ) { 128 return ( ( num % div ) + div ) % div; 129}; 130 131// ----- makeArray ----- // 132 133var arraySlice = Array.prototype.slice; 134 135// turn element or nodeList into an array 136utils.makeArray = function( obj ) { 137 if ( Array.isArray( obj ) ) { 138 // use object if already an array 139 return obj; 140 } 141 // return empty array if undefined or null. #6 142 if ( obj === null || obj === undefined ) { 143 return []; 144 } 145 146 var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; 147 if ( isArrayLike ) { 148 // convert nodeList to array 149 return arraySlice.call( obj ); 150 } 151 152 // array of single index 153 return [ obj ]; 154}; 155 156// ----- removeFrom ----- // 157 158utils.removeFrom = function( ary, obj ) { 159 var index = ary.indexOf( obj ); 160 if ( index != -1 ) { 161 ary.splice( index, 1 ); 162 } 163}; 164 165// ----- getParent ----- // 166 167utils.getParent = function( elem, selector ) { 168 while ( elem.parentNode && elem != document.body ) { 169 elem = elem.parentNode; 170 if ( matchesSelector( elem, selector ) ) { 171 return elem; 172 } 173 } 174}; 175 176// ----- getQueryElement ----- // 177 178// use element as selector string 179utils.getQueryElement = function( elem ) { 180 if ( typeof elem == 'string' ) { 181 return document.querySelector( elem ); 182 } 183 return elem; 184}; 185 186// ----- handleEvent ----- // 187 188// enable .ontype to trigger from .addEventListener( elem, 'type' ) 189utils.handleEvent = function( event ) { 190 var method = 'on' + event.type; 191 if ( this[ method ] ) { 192 this[ method ]( event ); 193 } 194}; 195 196// ----- filterFindElements ----- // 197 198utils.filterFindElements = function( elems, selector ) { 199 // make array of elems 200 elems = utils.makeArray( elems ); 201 var ffElems = []; 202
203 elems.forEach( function( elem ) { 204 // check that elem is an actual element 205 if ( !( elem instanceof HTMLElement ) ) { 206 return; 207 } 208 // add elem if no selector 209 if ( !selector ) { 210 ffElems.push( elem ); 211 return; 212 } 213 // filter & find items if we have a selector 214 // filter 215 if ( matchesSelector( elem, selector ) ) { 216 ffElems.push( elem ); 217 } 218 // find children 219 var childElems = elem.querySelectorAll( selector ); 220 // concat childElems to filterFound array 221 for ( var i=0; i < childElems.length; i++ ) { 222 ffElems.push( childElems[i] ); 223 } 224 }); 225 226 return ffElems; 227}; 228 229// ----- debounceMethod ----- // 230 231utils.debounceMethod = function( _class, methodName, threshold ) { 232 threshold = threshold || 100; 233 // original method 234 var method = _class.prototype[ methodName ]; 235 var timeoutName = methodName + 'Timeout'; 236 237 _class.prototype[ methodName ] = function() { 238 var timeout = this[ timeoutName ]; 239 clearTimeout( timeout ); 240 241 var args = arguments; 242 var _this = this; 243 this[ timeoutName ] = setTimeout( function() { 244 method.apply( _this, args ); 245 delete _this[ timeoutName ]; 246 }, threshold ); 247 }; 248}; 249 250// ----- docReady ----- // 251 252utils.docReady = function( callback ) { 253 var readyState = document.readyState; 254 if ( readyState == 'complete' || readyState == 'interactive' ) { 255 // do async to allow for other scripts to run. metafizzy/flickity#441 256 setTimeout( callback ); 257 } else { 258 document.addEventListener( 'DOMContentLoaded', callback ); 259 } 260}; 261 262// ----- htmlInit ----- // 263 264// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ 265utils.toDashed = function( str ) { 266 return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { 267 return $1 + '-' + $2; 268 }).toLowerCase(); 269}; 270 271var console = window.console; 272/** 273 * allow user to initialize classes via [data-namespace] or .js-namespace class 274 * htmlInit( Widget, 'widgetName' ) 275 * options are parsed from data-namespace-options 276 */ 277utils.htmlInit = function( WidgetClass, namespace ) { 278 utils.docReady( function() { 279 var dashedNamespace = utils.toDashed( namespace ); 280 var dataAttr = 'data-' + dashedNamespace; 281 var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' ); 282 var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace ); 283 var elems = utils.makeArray( dataAttrElems ) 284 .concat( utils.makeArray( jsDashElems ) ); 285 var dataOptionsAttr = dataAttr + '-options'; 286 var jQuery = window.jQuery; 287 288 elems.forEach( function( elem ) { 289 var attr = elem.getAttribute( dataAttr ) || 290 elem.getAttribute( dataOptionsAttr ); 291 var options; 292 try { 293 options = attr && JSON.parse( attr ); 294 } catch ( error ) { 295 // log error, do not initialize 296 if ( console ) { 297 console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className + 298 ': ' + error ); 299 } 300 return; 301 } 302 // initialize 303 var instance = new WidgetClass( elem, options ); 304 // make available via $().data('namespace') 305 if ( jQuery ) { 306 jQuery.data( elem, namespace, instance ); 307 } 308 }); 309 310 }); 311}; 312 313// ----- ----- // 314 315return utils; 316 317})); 318 319 320/***/ }), 321/* 2 */ 322/***/ (function(module, exports, __webpack_require__) { 323 324var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// core 325( function( window, factory ) { 326 // universal module definition 327 /* globals define, module, require */ 328 if ( true ) { 329 // AMD 330 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 331 __webpack_require__(31), 332 __webpack_require__(1), 333 ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( EvEmitter, utils) { 334 return factory( window, EvEmitter, utils ); 335 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 336 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 337 } else if ( typeof module == 'object' && module.exports ) { 338 // CommonJS 339 module.exports = factory( 340 window, 341 require('ev-emitter'), 342 require('fizzy-ui-utils') 343 ); 344 } else { 345 // browser global 346 window.InfiniteScroll = factory( 347 window, 348 window.EvEmitter, 349 window.fizzyUIUtils 350 ); 351 } 352 353}( window, function factory( window, EvEmitter, utils ) { 354 355var jQuery = window.jQuery; 356// internal store of all InfiniteScroll intances 357var instances = {}; 358 359function InfiniteScroll( element, options ) { 360 var queryElem = utils.getQueryElement( element ); 361 362 if ( !queryElem ) { 363 console.error( 'Bad element for InfiniteScroll: ' + ( queryElem || element ) ); 364 return; 365 } 366 element = queryElem; 367 // do not initialize twice on same element 368 if ( element.infiniteScrollGUID ) { 369 var instance = instances[ element.infiniteScrollGUID ]; 370 instance.option( options ); 371 return instance; 372 } 373 374 this.element = element; 375 // options 376 this.options = utils.extend( {}, InfiniteScroll.defaults ); 377 this.option( options ); 378 // add jQuery 379 if ( jQuery ) { 380 this.$element = jQuery( this.element ); 381 } 382 383 this.create(); 384} 385 386// defaults 387InfiniteScroll.defaults = { 388 // path: null, 389 // hideNav: null, 390 // debug: false, 391}; 392 393// create & destroy methods 394InfiniteScroll.create = {}; 395InfiniteScroll.destroy = {}; 396 397var proto = InfiniteScroll.prototype; 398// inherit EvEmitter 399utils.extend( proto, EvEmitter.prototype ); 400 401// -------------------------- -------------------------- // 402 403// globally unique identifiers 404var GUID = 0; 405 406proto.create = function() { 407 // create core 408 // add id for InfiniteScroll.data 409 var id = this.guid = ++GUID; 410 this.element.infiniteScrollGUID = id; // expando 411 instances[ id ] = this; // associate via id 412 // properties 413 this.pageIndex = 1; // default to first page 414 this.loadCount = 0; 415 this.updateGetPath(); 416 // bail if getPath not set 417 if ( !this.getPath ) { 418 console.error('Disabling InfiniteScroll'); 419 return; 420 } 421 this.updateGetAbsolutePath(); 422 this.log( 'initialized', [ this.element.className ] ); 423 this.callOnInit(); 424 // create features 425 for ( var method in InfiniteScroll.create ) { 426 InfiniteScroll.create[ method ].call( this ); 427 } 428}; 429 430proto.option = function( opts ) { 431 utils.extend( this.options, opts ); 432}; 433 434// call onInit option, used for binding events on init 435proto.callOnInit = function() { 436 var onInit = this.options.onInit; 437 if ( onInit ) { 438 onInit.call( this, this ); 439 } 440}; 441 442// ----- events ----- // 443 444proto.dispatchEvent = function( type, event, args ) { 445 this.log( type, args ); 446 var emitArgs = event ? [ event ].concat( args ) : args; 447 this.emitEvent( type, emitArgs ); 448 // trigger jQuery event 449 if ( !jQuery || !this.$element ) { 450 return; 451 } 452 // namespace jQuery event 453 type += '.infiniteScroll'; 454 var $event = type; 455 if ( event ) { 456 // create jQuery event 457 var jQEvent = jQuery.Event( event ); 458 jQEvent.type = type; 459 $event = jQEvent; 460 } 461 this.$element.trigger( $event, args ); 462}; 463 464var loggers = { 465 initialized: function( className ) { 466 return 'on ' + className; 467 }, 468 request: function( path ) { 469 return 'URL: ' + path; 470 }, 471 load: function( response, path ) { 472 return ( response.title || '' ) + '. URL: ' + path; 473 }, 474 error: function( error, path ) { 475 return error + '. URL: ' + path; 476 }, 477 append: function( response, path, items ) { 478 return items.length + ' items. URL: ' + path; 479 }, 480 last: function( response, path ) { 481 return 'URL: ' + path; 482 }, 483 history: function( title, path ) { 484 return 'URL: ' + path; 485 }, 486 pageIndex: function( index, origin ) { 487 return 'current page determined to be: ' + index + ' from ' + origin; 488 }, 489}; 490 491// log events 492proto.log = function( type, args ) { 493 if ( !this.options.debug ) { 494 return; 495 } 496 var message = '[InfiniteScroll] ' + type; 497 var logger = loggers[ type ]; 498 if ( logger ) { 499 message += '. ' + logger.apply( this, args ); 500 } 501 console.log( message ); 502}; 503 504// -------------------------- methods used amoung features -------------------------- // 505 506proto.updateMeasurements = function() { 507 this.windowHeight = window.innerHeight; 508 var rect = this.element.getBoundingClientRect(); 509 this.top = rect.top + window.pageYOffset; 510}; 511 512proto.updateScroller = function() { 513 var elementScroll = this.options.elementScroll; 514 if ( !elementScroll ) { 515 // default, use window 516 this.scroller = window; 517 return; 518 } 519 // if true, set to element, otherwise use option 520 this.scroller = elementScroll === true ? this.element : 521 utils.getQueryElement( elementScroll ); 522 if ( !this.scroller ) { 523 throw 'Unable to find elementScroll: ' + elementScroll; 524 } 525}; 526 527// -------------------------- page path -------------------------- // 528 529proto.updateGetPath = function() { 530 var optPath = this.options.path; 531 if ( !optPath ) { 532 console.error( 'InfiniteScroll path option required. Set as: ' + optPath ); 533 return; 534 } 535 // function 536 var type = typeof optPath; 537 if ( type == 'function' ) { 538 this.getPath = optPath; 539 return; 540 } 541 // template string: '/pages/{{#}}.html' 542 var templateMatch = type == 'string' && optPath.match('{{#}}'); 543 if ( templateMatch ) { 544 this.updateGetPathTemplate( optPath ); 545 return; 546 } 547 // selector: '.next-page-selector' 548 this.updateGetPathSelector( optPath ); 549}; 550 551proto.updateGetPathTemplate = function( optPath ) { 552 // set getPath with template string 553 this.getPath = function() { 554 var nextIndex = this.pageIndex + 1; 555 return optPath.replace( '{{#}}', nextIndex ); 556 }.bind( this ); 557 // get pageIndex from location 558 // convert path option into regex to look for pattern in location 559 var regexString = optPath.replace( '{{#}}', '(\\d\\d?\\d?)' ); 560 var templateRe = new RegExp( regexString ); 561 var match = location.href.match( templateRe ); 562 if ( match ) { 563 this.pageIndex = parseInt( match[1], 10 ); 564 this.log( 'pageIndex', this.pageIndex, 'template string' ); 565 } 566}; 567 568var pathRegexes = [ 569 // WordPress & Tumblr - example.com/page/2 570 // Jekyll - example.com/page2 571 /^(.*?\/?page\/?)(\d\d?\d?)(.*?$)/, 572 // Drupal - example.com/?page=1 573 /^(.*?\/?\?page=)(\d\d?\d?)(.*?$)/, 574 // catch all, last occurence of a number 575 /(.*?)(\d\d?\d?)(?!.*\d)(.*?$)/, 576]; 577 578proto.updateGetPathSelector = function( optPath ) { 579 // parse href of link: '.next-page-link' 580 var hrefElem = document.querySelector( optPath ); 581 if ( !hrefElem ) { 582 console.error( 'Bad InfiniteScroll path option. Next link not found: ' + 583 optPath ); 584 return; 585 } 586 var href = hrefElem.getAttribute('href'); 587 // try matching href to pathRegexes patterns 588 var pathParts, regex; 589 for ( var i=0; href && i < pathRegexes.length; i++ ) { 590 regex = pathRegexes[i]; 591 var match = href.match( regex ); 592 if ( match ) { 593 pathParts = match.slice(1); // remove first part 594 break; 595 } 596 } 597 if ( !pathParts ) { 598 console.error( 'InfiniteScroll unable to parse next link href: ' + href ); 599 return; 600 } 601 this.isPathSelector = true; // flag for checkLastPage() 602 this.getPath = function() { 603 var nextIndex = this.pageIndex + 1; 604 return pathParts[0] + nextIndex + pathParts[2]; 605 }.bind( this ); 606 // get pageIndex from href 607 this.pageIndex = parseInt( pathParts[1], 10 ) - 1; 608 this.log( 'pageIndex', [ this.pageIndex, 'next link' ] ); 609}; 610 611proto.updateGetAbsolutePath = function() { 612 var path = this.getPath(); 613 // path doesn't start with http or / 614 var isAbsolute = path.match( /^http/ ) || path.match( /^\// ); 615 if ( isAbsolute ) { 616 this.getAbsolutePath = this.getPath; 617 return; 618 } 619 620 var pathname = location.pathname; 621 // /foo/bar/index.html => /foo/bar 622 var directory = pathname.substring( 0, pathname.lastIndexOf('/') ); 623 624 this.getAbsolutePath = function() { 625 return directory + '/' + this.getPath(); 626 }; 627}; 628 629// -------------------------- nav -------------------------- // 630 631// hide navigation 632InfiniteScroll.create.hideNav = function() { 633 var nav = utils.getQueryElement( this.options.hideNav ); 634 if ( !nav ) { 635 return; 636 } 637 nav.style.display = 'none'; 638 this.nav = nav; 639}; 640 641InfiniteScroll.destroy.hideNav = function() { 642 if ( this.nav ) { 643 this.nav.style.display = ''; 644 } 645}; 646 647// -------------------------- destroy -------------------------- // 648 649proto.destroy = function() { 650 this.allOff(); // remove all event listeners 651 // call destroy methods 652 for ( var method in InfiniteScroll.destroy ) { 653 InfiniteScroll.destroy[ method ].call( this ); 654 } 655 656 delete this.element.infiniteScrollGUID; 657 delete instances[ this.guid ]; 658}; 659 660// -------------------------- utilities -------------------------- // 661 662// https://remysharp.com/2010/07/21/throttling-function-calls 663InfiniteScroll.throttle = function( fn, threshold ) { 664 threshold = threshold || 200; 665 var last, timeout; 666 667 return function() { 668 var now = +new Date(); 669 var args = arguments; 670 var trigger = function() { 671 last = now; 672 fn.apply( this, args ); 673 }.bind( this ); 674 if ( last && now < last + threshold ) { 675 // hold on to it 676 clearTimeout( timeout ); 677 timeout = setTimeout( trigger, threshold ); 678 } else { 679 trigger(); 680 } 681 }; 682}; 683 684InfiniteScroll.data = function( elem ) { 685 elem = utils.getQueryElement( elem ); 686 var id = elem && elem.infiniteScrollGUID; 687 return id && instances[ id ]; 688}; 689 690// set internal jQuery, for Webpack + jQuery v3
vendor: 5,988 bytes, lines 691-913
691InfiniteScroll.setJQuery = function( $ ) { 692 jQuery = $; 693}; 694 695// -------------------------- setup -------------------------- // 696 697utils.htmlInit( InfiniteScroll, 'infinite-scroll' ); 698 699if ( jQuery && jQuery.bridget ) { 700 jQuery.bridget( 'infiniteScroll', InfiniteScroll ); 701} 702 703// -------------------------- -------------------------- // 704 705return InfiniteScroll; 706 707})); 708 709 710/***/ }), 711/* 3 */ 712/***/ (function(module, exports, __webpack_require__) { 713 714var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 715 * getSize v2.0.3 716 * measure size of elements 717 * MIT license 718 */ 719 720/* jshint browser: true, strict: true, undef: true, unused: true */ 721/* globals console: false */ 722 723( function( window, factory ) { 724 /* jshint strict: false */ /* globals define, module */ 725 if ( true ) { 726 // AMD 727 !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 728 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 729 (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : 730 __WEBPACK_AMD_DEFINE_FACTORY__), 731 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 732 } else if ( typeof module == 'object' && module.exports ) { 733 // CommonJS 734 module.exports = factory(); 735 } else { 736 // browser global 737 window.getSize = factory(); 738 } 739 740})( window, function factory() { 741'use strict'; 742 743// -------------------------- helpers -------------------------- // 744 745// get a number from a string, not a percentage 746function getStyleSize( value ) { 747 var num = parseFloat( value ); 748 // not a percent like '100%', and a number 749 var isValid = value.indexOf('%') == -1 && !isNaN( num ); 750 return isValid && num; 751} 752 753function noop() {} 754 755var logError = typeof console == 'undefined' ? noop : 756 function( message ) { 757 console.error( message ); 758 }; 759 760// -------------------------- measurements -------------------------- // 761 762var measurements = [ 763 'paddingLeft', 764 'paddingRight', 765 'paddingTop', 766 'paddingBottom', 767 'marginLeft', 768 'marginRight', 769 'marginTop', 770 'marginBottom', 771 'borderLeftWidth', 772 'borderRightWidth', 773 'borderTopWidth', 774 'borderBottomWidth' 775]; 776 777var measurementsLength = measurements.length; 778 779function getZeroSize() { 780 var size = { 781 width: 0, 782 height: 0, 783 innerWidth: 0, 784 innerHeight: 0, 785 outerWidth: 0, 786 outerHeight: 0 787 }; 788 for ( var i=0; i < measurementsLength; i++ ) { 789 var measurement = measurements[i]; 790 size[ measurement ] = 0; 791 } 792 return size; 793} 794 795// -------------------------- getStyle -------------------------- // 796 797/** 798 * getStyle, get style of element, check for Firefox bug 799 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397 800 */ 801function getStyle( elem ) { 802 var style = getComputedStyle( elem ); 803 if ( !style ) { 804 logError( 'Style returned ' + style + 805 '. Are you running this code in a hidden iframe on Firefox? ' + 806 'See https://bit.ly/getsizebug1' ); 807 } 808 return style; 809} 810 811// -------------------------- setup -------------------------- // 812 813var isSetup = false; 814 815var isBoxSizeOuter; 816 817/** 818 * setup 819 * check isBoxSizerOuter 820 * do on first getSize() rather than on page load for Firefox bug 821 */ 822function setup() { 823 // setup once 824 if ( isSetup ) { 825 return; 826 } 827 isSetup = true; 828 829 // -------------------------- box sizing -------------------------- // 830 831 /** 832 * Chrome & Safari measure the outer-width on style.width on border-box elems 833 * IE11 & Firefox<29 measures the inner-width 834 */ 835 var div = document.createElement('div'); 836 div.style.width = '200px'; 837 div.style.padding = '1px 2px 3px 4px'; 838 div.style.borderStyle = 'solid'; 839 div.style.borderWidth = '1px 2px 3px 4px'; 840 div.style.boxSizing = 'border-box'; 841 842 var body = document.body || document.documentElement; 843 body.appendChild( div ); 844 var style = getStyle( div ); 845 // round value for browser zoom. desandro/masonry#928 846 isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200; 847 getSize.isBoxSizeOuter = isBoxSizeOuter; 848 849 body.removeChild( div ); 850} 851 852// -------------------------- getSize -------------------------- // 853 854function getSize( elem ) { 855 setup(); 856 857 // use querySeletor if elem is string 858 if ( typeof elem == 'string' ) { 859 elem = document.querySelector( elem ); 860 } 861 862 // do not proceed on non-objects 863 if ( !elem || typeof elem != 'object' || !elem.nodeType ) { 864 return; 865 } 866 867 var style = getStyle( elem ); 868 869 // if hidden, everything is 0 870 if ( style.display == 'none' ) { 871 return getZeroSize(); 872 } 873 874 var size = {}; 875 size.width = elem.offsetWidth; 876 size.height = elem.offsetHeight; 877 878 var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; 879 880 // get all measurements 881 for ( var i=0; i < measurementsLength; i++ ) { 882 var measurement = measurements[i]; 883 var value = style[ measurement ]; 884 var num = parseFloat( value ); 885 // any 'auto', 'medium' value will be 0 886 size[ measurement ] = !isNaN( num ) ? num : 0; 887 } 888 889 var paddingWidth = size.paddingLeft + size.paddingRight; 890 var paddingHeight = size.paddingTop + size.paddingBottom; 891 var marginWidth = size.marginLeft + size.marginRight; 892 var marginHeight = size.marginTop + size.marginBottom; 893 var borderWidth = size.borderLeftWidth + size.borderRightWidth; 894 var borderHeight = size.borderTopWidth + size.borderBottomWidth; 895 896 var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; 897 898 // overwrite width and height if we can get it from style 899 var styleWidth = getStyleSize( style.width ); 900 if ( styleWidth !== false ) { 901 size.width = styleWidth + 902 // add padding and border unless it's already including it 903 ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); 904 } 905 906 var styleHeight = getStyleSize( style.height ); 907 if ( styleHeight !== false ) { 908 size.height = styleHeight + 909 // add padding and border unless it's already including it 910 ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); 911 } 912 913 size.innerWidth = size.width - ( paddingWidth + borderWidth );
914 size.innerHeight = size.height - ( paddingHeight + borderHeight ); 915 916 size.outerWidth = size.width + marginWidth; 917 size.outerHeight = size.height + marginHeight; 918 919 return size; 920} 921 922return getSize; 923 924}); 925 926 927/***/ }), 928/* 4 */ 929/***/ (function(module, __webpack_exports__, __webpack_require__) { 930 931"use strict"; 932/* unused harmony export bunnyIframeUrl */ 933/* harmony export (immutable) */ __webpack_exports__["a"] = loadBunnyPlayer; 934/* harmony export (immutable) */ __webpack_exports__["b"] = swapBunnyVideo; 935/** 936 * Bunny Stream player loader â shared across video routes. 937 * 938 * The theme renders a placeholder element with `data-video` (the source id/url) 939 * and `data-source` (youtube|bunny|kaltura). YouTube and Kaltura keep their 940 * existing per-route logic; this util provides the Bunny branch so it lives in 941 * one place. Background players add `data-background="true"` for muted/looping 942 * autoplay. 943 * 944 * Bunny config (library id + pull zone) is localized to `window.CTT_BUNNY`. 945 */ 946 947var bunnyCounter = 0; 948 949/** 950 * Build a Bunny Stream iframe embed URL. 951 */ 952function bunnyIframeUrl(videoGuid, ref) { 953 if ( ref === void 0 ) ref = {}; 954 var background = ref.background; if ( background === void 0 ) background = false; 955 var autoplay = ref.autoplay; if ( autoplay === void 0 ) autoplay = true; 956 var start = ref.start; if ( start === void 0 ) start = 0; 957 958 var cfg = window.CTT_BUNNY || {}; 959 var libraryId = cfg.libraryId || ''; 960 var params = new URLSearchParams({ 961 autoplay: autoplay ? 'true' : 'false', 962 loop: background ? 'true' : 'false', 963 muted: background ? 'true' : 'false', 964 }); 965 if (start > 0) { 966 params.set('t', String(Math.floor(start))); 967 } 968 return ("https://iframe.mediadelivery.net/embed/" + libraryId + "/" + videoGuid + "?" + (params.toString())); 969} 970 971/** 972 * Render a Bunny iframe into a placeholder element and (optionally) wire 973 * Player.js events for progress tracking. 974 * 975 * @param {HTMLElement} playerEl The placeholder element (has data-video). 976 * @param {Object} opts 977 * @param {boolean} opts.background Muted/looping autoplay for mastheads. 978 * @param {boolean} opts.autoplay Defaults to `background`. Set false for 979 * overlay-driven single-video playback. 980 * @param {Function} opts.onTimeUpdate (data) => {} where data.seconds/.duration. 981 * NOTE: fires very frequently (~4x/sec) â use only to cache 982 * the latest position, never to make network calls. 983 * @param {Function} opts.onPause () => {} â coarse, for progress writes. 984 * @param {Function} opts.onEnded () => {} â coarse, for progress writes. 985 * @returns {Object|null} The Player.js instance, if created. 986 */ 987function loadBunnyPlayer(playerEl, ref) { 988 if ( ref === void 0 ) ref = {}; 989 var background = ref.background; if ( background === void 0 ) background = false; 990 var autoplay = ref.autoplay; if ( autoplay === void 0 ) autoplay = background; 991 var start = ref.start; if ( start === void 0 ) start = 0; 992 var onTimeUpdate = ref.onTimeUpdate; if ( onTimeUpdate === void 0 ) onTimeUpdate = null; 993 var onPause = ref.onPause; if ( onPause === void 0 ) onPause = null; 994 var onEnded = ref.onEnded; if ( onEnded === void 0 ) onEnded = null; 995 996 var videoGuid = playerEl.dataset.video; 997 if (!videoGuid) { 998 return null; 999 } 1000 1001 var iframe = document.createElement('iframe'); 1002 iframe.id = (playerEl.id || 'bunny-player') + '-bunny-' + (++bunnyCounter); 1003 iframe.src = bunnyIframeUrl(videoGuid, { background: background, autoplay: autoplay, start: start }); 1004 iframe.setAttribute('allow', 'autoplay; fullscreen; encrypted-media; picture-in-picture'); 1005 iframe.setAttribute('allowfullscreen', ''); 1006 iframe.style.cssText = 'width:100%;height:100%;border:0;'; 1007 playerEl.innerHTML = ''; 1008 playerEl.appendChild(iframe); 1009 1010 // Player.js (loaded via the `bunny-playerjs` handle) exposes standard 1011 // events. Progress writes should be driven by the coarse pause/ended events 1012 // (matching the YouTube/Kaltura paths), not by the high-frequency timeupdate.
1013 if (window.playerjs && (onTimeUpdate || onPause || onEnded)) { 1014 try { 1015 var player = new window.playerjs.Player(iframe); 1016 player.on('ready', function () { 1017 if (onTimeUpdate) { 1018 player.on('timeupdate', onTimeUpdate); 1019 } 1020 if (onPause) { 1021 player.on('pause', onPause); 1022 } 1023 if (onEnded) { 1024 player.on('ended', onEnded); 1025 } 1026 }); 1027 return player; 1028 } catch (e) { 1029 console.error('Bunny Player.js init failed:', e.message); // eslint-disable-line no-console 1030 } 1031 } 1032 return null; 1033} 1034 1035/** 1036 * Swap an existing Bunny player's iframe to a different video GUID 1037 * (used by the Short/Long format toggle). 1038 */ 1039function swapBunnyVideo(playerEl, videoGuid, ref) { 1040 if ( ref === void 0 ) ref = {}; 1041 var background = ref.background; if ( background === void 0 ) background = false; 1042 1043 // Keep the element's data-video in sync with the requested GUID so any 1044 // re-render uses the selected target (not the originally-loaded clip). 1045 playerEl.dataset.video = videoGuid; 1046 // Only reuse the existing iframe if it's already a Bunny embed â its 1047 // Player.js instance (and the tracking handlers bound to it) survive a 1048 // src swap. A foreign iframe (e.g. a YouTube player) must be replaced so 1049 // Bunny's Player.js events actually attach. 1050 var iframe = playerEl.querySelector('iframe'); 1051 if (iframe && iframe.src.indexOf('mediadelivery.net') > -1) { 1052 iframe.src = bunnyIframeUrl(videoGuid, { background: background }); 1053 } else { 1054 loadBunnyPlayer(playerEl, { background: background }); 1055 } 1056} 1057 1058 1059/***/ }), 1060/* 5 */ 1061/***/ (function(module, exports, __webpack_require__) { 1062 1063var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 1064 * Outlayer v2.1.1 1065 * the brains and guts of a layout library 1066 * MIT license 1067 */ 1068 1069( function( window, factory ) { 1070 'use strict'; 1071 // universal module definition 1072 /* jshint strict: false */ /* globals define, module, require */ 1073 if ( true ) { 1074 // AMD - RequireJS 1075 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 1076 __webpack_require__(11), 1077 __webpack_require__(3), 1078 __webpack_require__(1), 1079 __webpack_require__(25) 1080 ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( EvEmitter, getSize, utils, Item ) { 1081 return factory( window, EvEmitter, getSize, utils, Item); 1082 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 1083 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)
vendor: 21,459 bytes, lines 1083-2001
1083); 1084 } else if ( typeof module == 'object' && module.exports ) { 1085 // CommonJS - Browserify, Webpack 1086 module.exports = factory( 1087 window, 1088 require('ev-emitter'), 1089 require('get-size'), 1090 require('fizzy-ui-utils'), 1091 require('./item') 1092 ); 1093 } else { 1094 // browser global 1095 window.Outlayer = factory( 1096 window, 1097 window.EvEmitter, 1098 window.getSize, 1099 window.fizzyUIUtils, 1100 window.Outlayer.Item 1101 ); 1102 } 1103 1104}( window, function factory( window, EvEmitter, getSize, utils, Item ) { 1105'use strict'; 1106 1107// ----- vars ----- // 1108 1109var console = window.console; 1110var jQuery = window.jQuery; 1111var noop = function() {}; 1112 1113// -------------------------- Outlayer -------------------------- // 1114 1115// globally unique identifiers 1116var GUID = 0; 1117// internal store of all Outlayer intances 1118var instances = {}; 1119 1120 1121/** 1122 * @param {Element, String} element 1123 * @param {Object} options 1124 * @constructor 1125 */ 1126function Outlayer( element, options ) { 1127 var queryElement = utils.getQueryElement( element ); 1128 if ( !queryElement ) { 1129 if ( console ) { 1130 console.error( 'Bad element for ' + this.constructor.namespace + 1131 ': ' + ( queryElement || element ) ); 1132 } 1133 return; 1134 } 1135 this.element = queryElement; 1136 // add jQuery 1137 if ( jQuery ) { 1138 this.$element = jQuery( this.element ); 1139 } 1140 1141 // options 1142 this.options = utils.extend( {}, this.constructor.defaults ); 1143 this.option( options ); 1144 1145 // add id for Outlayer.getFromElement 1146 var id = ++GUID; 1147 this.element.outlayerGUID = id; // expando 1148 instances[ id ] = this; // associate via id 1149 1150 // kick it off 1151 this._create(); 1152 1153 var isInitLayout = this._getOption('initLayout'); 1154 if ( isInitLayout ) { 1155 this.layout(); 1156 } 1157} 1158 1159// settings are for internal use only 1160Outlayer.namespace = 'outlayer'; 1161Outlayer.Item = Item; 1162 1163// default options 1164Outlayer.defaults = { 1165 containerStyle: { 1166 position: 'relative' 1167 }, 1168 initLayout: true, 1169 originLeft: true, 1170 originTop: true, 1171 resize: true, 1172 resizeContainer: true, 1173 // item options 1174 transitionDuration: '0.4s', 1175 hiddenStyle: { 1176 opacity: 0, 1177 transform: 'scale(0.001)' 1178 }, 1179 visibleStyle: { 1180 opacity: 1, 1181 transform: 'scale(1)' 1182 } 1183}; 1184 1185var proto = Outlayer.prototype; 1186// inherit EvEmitter 1187utils.extend( proto, EvEmitter.prototype ); 1188 1189/** 1190 * set options 1191 * @param {Object} opts 1192 */ 1193proto.option = function( opts ) { 1194 utils.extend( this.options, opts ); 1195}; 1196 1197/** 1198 * get backwards compatible option value, check old name 1199 */ 1200proto._getOption = function( option ) { 1201 var oldOption = this.constructor.compatOptions[ option ]; 1202 return oldOption && this.options[ oldOption ] !== undefined ? 1203 this.options[ oldOption ] : this.options[ option ]; 1204}; 1205 1206Outlayer.compatOptions = { 1207 // currentName: oldName 1208 initLayout: 'isInitLayout', 1209 horizontal: 'isHorizontal', 1210 layoutInstant: 'isLayoutInstant', 1211 originLeft: 'isOriginLeft', 1212 originTop: 'isOriginTop', 1213 resize: 'isResizeBound', 1214 resizeContainer: 'isResizingContainer' 1215}; 1216 1217proto._create = function() { 1218 // get items from children 1219 this.reloadItems(); 1220 // elements that affect layout, but are not laid out 1221 this.stamps = []; 1222 this.stamp( this.options.stamp ); 1223 // set container style 1224 utils.extend( this.element.style, this.options.containerStyle ); 1225 1226 // bind resize method 1227 var canBindResize = this._getOption('resize'); 1228 if ( canBindResize ) { 1229 this.bindResize(); 1230 } 1231}; 1232 1233// goes through all children again and gets bricks in proper order 1234proto.reloadItems = function() { 1235 // collection of item elements 1236 this.items = this._itemize( this.element.children ); 1237}; 1238 1239 1240/** 1241 * turn elements into Outlayer.Items to be used in layout 1242 * @param {Array or NodeList or HTMLElement} elems 1243 * @returns {Array} items - collection of new Outlayer Items 1244 */ 1245proto._itemize = function( elems ) { 1246 1247 var itemElems = this._filterFindItemElements( elems ); 1248 var Item = this.constructor.Item; 1249 1250 // create new Outlayer Items for collection 1251 var items = []; 1252 for ( var i=0; i < itemElems.length; i++ ) { 1253 var elem = itemElems[i]; 1254 var item = new Item( elem, this ); 1255 items.push( item ); 1256 } 1257 1258 return items; 1259}; 1260 1261/** 1262 * get item elements to be used in layout 1263 * @param {Array or NodeList or HTMLElement} elems 1264 * @returns {Array} items - item elements 1265 */ 1266proto._filterFindItemElements = function( elems ) { 1267 return utils.filterFindElements( elems, this.options.itemSelector ); 1268}; 1269 1270/** 1271 * getter method for getting item elements 1272 * @returns {Array} elems - collection of item elements 1273 */ 1274proto.getItemElements = function() { 1275 return this.items.map( function( item ) { 1276 return item.element; 1277 }); 1278}; 1279 1280// ----- init & layout ----- // 1281 1282/** 1283 * lays out all items 1284 */ 1285proto.layout = function() { 1286 this._resetLayout(); 1287 this._manageStamps(); 1288 1289 // don't animate first layout 1290 var layoutInstant = this._getOption('layoutInstant'); 1291 var isInstant = layoutInstant !== undefined ? 1292 layoutInstant : !this._isLayoutInited; 1293 this.layoutItems( this.items, isInstant ); 1294 1295 // flag for initalized 1296 this._isLayoutInited = true; 1297}; 1298 1299// _init is alias for layout 1300proto._init = proto.layout; 1301 1302/** 1303 * logic before any new layout 1304 */ 1305proto._resetLayout = function() { 1306 this.getSize(); 1307}; 1308 1309 1310proto.getSize = function() { 1311 this.size = getSize( this.element ); 1312}; 1313 1314/** 1315 * get measurement from option, for columnWidth, rowHeight, gutter 1316 * if option is String -> get element from selector string, & get size of element 1317 * if option is Element -> get size of element 1318 * else use option as a number 1319 * 1320 * @param {String} measurement 1321 * @param {String} size - width or height 1322 * @private 1323 */ 1324proto._getMeasurement = function( measurement, size ) { 1325 var option = this.options[ measurement ]; 1326 var elem; 1327 if ( !option ) { 1328 // default to 0 1329 this[ measurement ] = 0; 1330 } else { 1331 // use option as an element 1332 if ( typeof option == 'string' ) { 1333 elem = this.element.querySelector( option ); 1334 } else if ( option instanceof HTMLElement ) { 1335 elem = option; 1336 } 1337 // use size of element, if element 1338 this[ measurement ] = elem ? getSize( elem )[ size ] : option; 1339 } 1340}; 1341 1342/** 1343 * layout a collection of item elements 1344 * @api public 1345 */ 1346proto.layoutItems = function( items, isInstant ) { 1347 items = this._getItemsForLayout( items ); 1348 1349 this._layoutItems( items, isInstant ); 1350 1351 this._postLayout(); 1352}; 1353 1354/** 1355 * get the items to be laid out 1356 * you may want to skip over some items 1357 * @param {Array} items 1358 * @returns {Array} items 1359 */ 1360proto._getItemsForLayout = function( items ) { 1361 return items.filter( function( item ) { 1362 return !item.isIgnored; 1363 }); 1364}; 1365 1366/** 1367 * layout items 1368 * @param {Array} items 1369 * @param {Boolean} isInstant 1370 */ 1371proto._layoutItems = function( items, isInstant ) { 1372 this._emitCompleteOnItems( 'layout', items ); 1373 1374 if ( !items || !items.length ) { 1375 // no items, emit event with empty array 1376 return; 1377 } 1378 1379 var queue = []; 1380 1381 items.forEach( function( item ) { 1382 // get x/y object from method 1383 var position = this._getItemLayoutPosition( item ); 1384 // enqueue 1385 position.item = item; 1386 position.isInstant = isInstant || item.isLayoutInstant; 1387 queue.push( position ); 1388 }, this ); 1389 1390 this._processLayoutQueue( queue ); 1391}; 1392 1393/** 1394 * get item layout position 1395 * @param {Outlayer.Item} item 1396 * @returns {Object} x and y position 1397 */ 1398proto._getItemLayoutPosition = function( /* item */ ) { 1399 return { 1400 x: 0, 1401 y: 0 1402 }; 1403}; 1404 1405/** 1406 * iterate over array and position each item 1407 * Reason being - separating this logic prevents 'layout invalidation' 1408 * thx @paul_irish 1409 * @param {Array} queue 1410 */ 1411proto._processLayoutQueue = function( queue ) { 1412 this.updateStagger(); 1413 queue.forEach( function( obj, i ) { 1414 this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i ); 1415 }, this ); 1416}; 1417 1418// set stagger from option in milliseconds number 1419proto.updateStagger = function() { 1420 var stagger = this.options.stagger; 1421 if ( stagger === null || stagger === undefined ) { 1422 this.stagger = 0; 1423 return; 1424 } 1425 this.stagger = getMilliseconds( stagger ); 1426 return this.stagger; 1427}; 1428 1429/** 1430 * Sets position of item in DOM 1431 * @param {Outlayer.Item} item 1432 * @param {Number} x - horizontal position 1433 * @param {Number} y - vertical position 1434 * @param {Boolean} isInstant - disables transitions 1435 */ 1436proto._positionItem = function( item, x, y, isInstant, i ) { 1437 if ( isInstant ) { 1438 // if not transition, just set CSS 1439 item.goTo( x, y ); 1440 } else { 1441 item.stagger( i * this.stagger ); 1442 item.moveTo( x, y ); 1443 } 1444}; 1445 1446/** 1447 * Any logic you want to do after each layout, 1448 * i.e. size the container 1449 */ 1450proto._postLayout = function() { 1451 this.resizeContainer(); 1452}; 1453 1454proto.resizeContainer = function() { 1455 var isResizingContainer = this._getOption('resizeContainer'); 1456 if ( !isResizingContainer ) { 1457 return; 1458 } 1459 var size = this._getContainerSize(); 1460 if ( size ) { 1461 this._setContainerMeasure( size.width, true ); 1462 this._setContainerMeasure( size.height, false ); 1463 } 1464}; 1465 1466/** 1467 * Sets width or height of container if returned 1468 * @returns {Object} size 1469 * @param {Number} width 1470 * @param {Number} height 1471 */ 1472proto._getContainerSize = noop; 1473 1474/** 1475 * @param {Number} measure - size of width or height 1476 * @param {Boolean} isWidth 1477 */ 1478proto._setContainerMeasure = function( measure, isWidth ) { 1479 if ( measure === undefined ) { 1480 return; 1481 } 1482 1483 var elemSize = this.size; 1484 // add padding and border width if border box 1485 if ( elemSize.isBorderBox ) { 1486 measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + 1487 elemSize.borderLeftWidth + elemSize.borderRightWidth : 1488 elemSize.paddingBottom + elemSize.paddingTop + 1489 elemSize.borderTopWidth + elemSize.borderBottomWidth; 1490 } 1491 1492 measure = Math.max( measure, 0 ); 1493 this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px'; 1494}; 1495 1496/** 1497 * emit eventComplete on a collection of items events 1498 * @param {String} eventName 1499 * @param {Array} items - Outlayer.Items 1500 */ 1501proto._emitCompleteOnItems = function( eventName, items ) { 1502 var _this = this; 1503 function onComplete() { 1504 _this.dispatchEvent( eventName + 'Complete', null, [ items ] ); 1505 } 1506 1507 var count = items.length; 1508 if ( !items || !count ) { 1509 onComplete(); 1510 return; 1511 } 1512 1513 var doneCount = 0; 1514 function tick() { 1515 doneCount++; 1516 if ( doneCount == count ) { 1517 onComplete(); 1518 } 1519 } 1520 1521 // bind callback 1522 items.forEach( function( item ) { 1523 item.once( eventName, tick ); 1524 }); 1525}; 1526 1527/** 1528 * emits events via EvEmitter and jQuery events 1529 * @param {String} type - name of event 1530 * @param {Event} event - original event 1531 * @param {Array} args - extra arguments 1532 */ 1533proto.dispatchEvent = function( type, event, args ) { 1534 // add original event to arguments 1535 var emitArgs = event ? [ event ].concat( args ) : args; 1536 this.emitEvent( type, emitArgs ); 1537 1538 if ( jQuery ) { 1539 // set this.$element 1540 this.$element = this.$element || jQuery( this.element ); 1541 if ( event ) { 1542 // create jQuery event 1543 var $event = jQuery.Event( event ); 1544 $event.type = type; 1545 this.$element.trigger( $event, args ); 1546 } else { 1547 // just trigger with type if no event available 1548 this.$element.trigger( type, args ); 1549 } 1550 } 1551}; 1552 1553// -------------------------- ignore & stamps -------------------------- // 1554 1555 1556/** 1557 * keep item in collection, but do not lay it out 1558 * ignored items do not get skipped in layout 1559 * @param {Element} elem 1560 */ 1561proto.ignore = function( elem ) { 1562 var item = this.getItem( elem ); 1563 if ( item ) { 1564 item.isIgnored = true; 1565 } 1566}; 1567 1568/** 1569 * return item to layout collection 1570 * @param {Element} elem 1571 */ 1572proto.unignore = function( elem ) { 1573 var item = this.getItem( elem ); 1574 if ( item ) { 1575 delete item.isIgnored; 1576 } 1577}; 1578 1579/** 1580 * adds elements to stamps 1581 * @param {NodeList, Array, Element, or String} elems 1582 */ 1583proto.stamp = function( elems ) { 1584 elems = this._find( elems ); 1585 if ( !elems ) { 1586 return; 1587 } 1588 1589 this.stamps = this.stamps.concat( elems ); 1590 // ignore 1591 elems.forEach( this.ignore, this ); 1592}; 1593 1594/** 1595 * removes elements to stamps 1596 * @param {NodeList, Array, or Element} elems 1597 */ 1598proto.unstamp = function( elems ) { 1599 elems = this._find( elems ); 1600 if ( !elems ){ 1601 return; 1602 } 1603 1604 elems.forEach( function( elem ) { 1605 // filter out removed stamp elements 1606 utils.removeFrom( this.stamps, elem ); 1607 this.unignore( elem ); 1608 }, this ); 1609}; 1610 1611/** 1612 * finds child elements 1613 * @param {NodeList, Array, Element, or String} elems 1614 * @returns {Array} elems 1615 */ 1616proto._find = function( elems ) { 1617 if ( !elems ) { 1618 return; 1619 } 1620 // if string, use argument as selector string 1621 if ( typeof elems == 'string' ) { 1622 elems = this.element.querySelectorAll( elems ); 1623 } 1624 elems = utils.makeArray( elems ); 1625 return elems; 1626}; 1627 1628proto._manageStamps = function() { 1629 if ( !this.stamps || !this.stamps.length ) { 1630 return; 1631 } 1632 1633 this._getBoundingRect(); 1634 1635 this.stamps.forEach( this._manageStamp, this ); 1636}; 1637 1638// update boundingLeft / Top 1639proto._getBoundingRect = function() { 1640 // get bounding rect for container element 1641 var boundingRect = this.element.getBoundingClientRect(); 1642 var size = this.size; 1643 this._boundingRect = { 1644 left: boundingRect.left + size.paddingLeft + size.borderLeftWidth, 1645 top: boundingRect.top + size.paddingTop + size.borderTopWidth, 1646 right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ), 1647 bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth ) 1648 }; 1649}; 1650 1651/** 1652 * @param {Element} stamp 1653**/ 1654proto._manageStamp = noop; 1655 1656/** 1657 * get x/y position of element relative to container element 1658 * @param {Element} elem 1659 * @returns {Object} offset - has left, top, right, bottom 1660 */ 1661proto._getElementOffset = function( elem ) { 1662 var boundingRect = elem.getBoundingClientRect(); 1663 var thisRect = this._boundingRect; 1664 var size = getSize( elem ); 1665 var offset = { 1666 left: boundingRect.left - thisRect.left - size.marginLeft, 1667 top: boundingRect.top - thisRect.top - size.marginTop, 1668 right: thisRect.right - boundingRect.right - size.marginRight, 1669 bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom 1670 }; 1671 return offset; 1672}; 1673 1674// -------------------------- resize -------------------------- // 1675 1676// enable event handlers for listeners 1677// i.e. resize -> onresize 1678proto.handleEvent = utils.handleEvent; 1679 1680/** 1681 * Bind layout to window resizing 1682 */ 1683proto.bindResize = function() { 1684 window.addEventListener( 'resize', this ); 1685 this.isResizeBound = true; 1686}; 1687 1688/** 1689 * Unbind layout to window resizing 1690 */ 1691proto.unbindResize = function() { 1692 window.removeEventListener( 'resize', this ); 1693 this.isResizeBound = false; 1694}; 1695 1696proto.onresize = function() { 1697 this.resize(); 1698}; 1699 1700utils.debounceMethod( Outlayer, 'onresize', 100 ); 1701 1702proto.resize = function() { 1703 // don't trigger if size did not change 1704 // or if resize was unbound. See #9 1705 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 1706 return; 1707 } 1708 1709 this.layout(); 1710}; 1711 1712/** 1713 * check if layout is needed post layout 1714 * @returns Boolean 1715 */ 1716proto.needsResizeLayout = function() { 1717 var size = getSize( this.element ); 1718 // check that this.size and size are there 1719 // IE8 triggers resize on body size change, so they might not be 1720 var hasSizes = this.size && size; 1721 return hasSizes && size.innerWidth !== this.size.innerWidth; 1722}; 1723 1724// -------------------------- methods -------------------------- // 1725 1726/** 1727 * add items to Outlayer instance 1728 * @param {Array or NodeList or Element} elems 1729 * @returns {Array} items - Outlayer.Items 1730**/ 1731proto.addItems = function( elems ) { 1732 var items = this._itemize( elems ); 1733 // add items to collection 1734 if ( items.length ) { 1735 this.items = this.items.concat( items ); 1736 } 1737 return items; 1738}; 1739 1740/** 1741 * Layout newly-appended item elements 1742 * @param {Array or NodeList or Element} elems 1743 */ 1744proto.appended = function( elems ) { 1745 var items = this.addItems( elems ); 1746 if ( !items.length ) { 1747 return; 1748 } 1749 // layout and reveal just the new items 1750 this.layoutItems( items, true ); 1751 this.reveal( items ); 1752}; 1753 1754/** 1755 * Layout prepended elements 1756 * @param {Array or NodeList or Element} elems 1757 */ 1758proto.prepended = function( elems ) { 1759 var items = this._itemize( elems ); 1760 if ( !items.length ) { 1761 return; 1762 } 1763 // add items to beginning of collection 1764 var previousItems = this.items.slice(0); 1765 this.items = items.concat( previousItems ); 1766 // start new layout 1767 this._resetLayout(); 1768 this._manageStamps(); 1769 // layout new stuff without transition 1770 this.layoutItems( items, true ); 1771 this.reveal( items ); 1772 // layout previous items 1773 this.layoutItems( previousItems ); 1774}; 1775 1776/** 1777 * reveal a collection of items 1778 * @param {Array of Outlayer.Items} items 1779 */ 1780proto.reveal = function( items ) { 1781 this._emitCompleteOnItems( 'reveal', items ); 1782 if ( !items || !items.length ) { 1783 return; 1784 } 1785 var stagger = this.updateStagger(); 1786 items.forEach( function( item, i ) { 1787 item.stagger( i * stagger ); 1788 item.reveal(); 1789 }); 1790}; 1791 1792/** 1793 * hide a collection of items 1794 * @param {Array of Outlayer.Items} items 1795 */ 1796proto.hide = function( items ) { 1797 this._emitCompleteOnItems( 'hide', items ); 1798 if ( !items || !items.length ) { 1799 return; 1800 } 1801 var stagger = this.updateStagger(); 1802 items.forEach( function( item, i ) { 1803 item.stagger( i * stagger ); 1804 item.hide(); 1805 }); 1806}; 1807 1808/** 1809 * reveal item elements 1810 * @param {Array}, {Element}, {NodeList} items 1811 */ 1812proto.revealItemElements = function( elems ) { 1813 var items = this.getItems( elems ); 1814 this.reveal( items ); 1815}; 1816 1817/** 1818 * hide item elements 1819 * @param {Array}, {Element}, {NodeList} items 1820 */ 1821proto.hideItemElements = function( elems ) { 1822 var items = this.getItems( elems ); 1823 this.hide( items ); 1824}; 1825 1826/** 1827 * get Outlayer.Item, given an Element 1828 * @param {Element} elem 1829 * @param {Function} callback 1830 * @returns {Outlayer.Item} item 1831 */ 1832proto.getItem = function( elem ) { 1833 // loop through items to get the one that matches 1834 for ( var i=0; i < this.items.length; i++ ) { 1835 var item = this.items[i]; 1836 if ( item.element == elem ) { 1837 // return item 1838 return item; 1839 } 1840 } 1841}; 1842 1843/** 1844 * get collection of Outlayer.Items, given Elements 1845 * @param {Array} elems 1846 * @returns {Array} items - Outlayer.Items 1847 */ 1848proto.getItems = function( elems ) { 1849 elems = utils.makeArray( elems ); 1850 var items = []; 1851 elems.forEach( function( elem ) { 1852 var item = this.getItem( elem ); 1853 if ( item ) { 1854 items.push( item ); 1855 } 1856 }, this ); 1857 1858 return items; 1859}; 1860 1861/** 1862 * remove element(s) from instance and DOM 1863 * @param {Array or NodeList or Element} elems 1864 */ 1865proto.remove = function( elems ) { 1866 var removeItems = this.getItems( elems ); 1867 1868 this._emitCompleteOnItems( 'remove', removeItems ); 1869 1870 // bail if no items to remove 1871 if ( !removeItems || !removeItems.length ) { 1872 return; 1873 } 1874 1875 removeItems.forEach( function( item ) { 1876 item.remove(); 1877 // remove item from collection 1878 utils.removeFrom( this.items, item ); 1879 }, this ); 1880}; 1881 1882// ----- destroy ----- // 1883 1884// remove and disable Outlayer instance 1885proto.destroy = function() { 1886 // clean up dynamic styles 1887 var style = this.element.style; 1888 style.height = ''; 1889 style.position = ''; 1890 style.width = ''; 1891 // destroy items 1892 this.items.forEach( function( item ) { 1893 item.destroy(); 1894 }); 1895 1896 this.unbindResize(); 1897 1898 var id = this.element.outlayerGUID; 1899 delete instances[ id ]; // remove reference to instance by id 1900 delete this.element.outlayerGUID; 1901 // remove data for jQuery 1902 if ( jQuery ) { 1903 jQuery.removeData( this.element, this.constructor.namespace ); 1904 } 1905 1906}; 1907 1908// -------------------------- data -------------------------- // 1909 1910/** 1911 * get Outlayer instance from element 1912 * @param {Element} elem 1913 * @returns {Outlayer} 1914 */ 1915Outlayer.data = function( elem ) { 1916 elem = utils.getQueryElement( elem ); 1917 var id = elem && elem.outlayerGUID; 1918 return id && instances[ id ]; 1919}; 1920 1921 1922// -------------------------- create Outlayer class -------------------------- // 1923 1924/** 1925 * create a layout class 1926 * @param {String} namespace 1927 */ 1928Outlayer.create = function( namespace, options ) { 1929 // sub-class Outlayer 1930 var Layout = subclass( Outlayer ); 1931 // apply new options and compatOptions 1932 Layout.defaults = utils.extend( {}, Outlayer.defaults ); 1933 utils.extend( Layout.defaults, options ); 1934 Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions ); 1935 1936 Layout.namespace = namespace; 1937 1938 Layout.data = Outlayer.data; 1939 1940 // sub-class Item 1941 Layout.Item = subclass( Item ); 1942 1943 // -------------------------- declarative -------------------------- // 1944 1945 utils.htmlInit( Layout, namespace ); 1946 1947 // -------------------------- jQuery bridge -------------------------- // 1948 1949 // make into jQuery plugin 1950 if ( jQuery && jQuery.bridget ) { 1951 jQuery.bridget( namespace, Layout ); 1952 } 1953 1954 return Layout; 1955}; 1956 1957function subclass( Parent ) { 1958 function SubClass() { 1959 Parent.apply( this, arguments ); 1960 } 1961 1962 SubClass.prototype = Object.create( Parent.prototype ); 1963 SubClass.prototype.constructor = SubClass; 1964 1965 return SubClass; 1966} 1967 1968// ----- helpers ----- // 1969 1970// how many milliseconds are in each unit 1971var msUnits = { 1972 ms: 1, 1973 s: 1000 1974}; 1975 1976// munge time-like parameter into millisecond number 1977// '0.4s' -> 40 1978function getMilliseconds( time ) { 1979 if ( typeof time == 'number' ) { 1980 return time; 1981 } 1982 var matches = time.match( /(^\d*\.?\d*)(\w*)/ ); 1983 var num = matches && matches[1]; 1984 var unit = matches && matches[2]; 1985 if ( !num.length ) { 1986 return 0; 1987 } 1988 num = parseFloat( num ); 1989 var mult = msUnits[ unit ] || 1; 1990 return num * mult; 1991} 1992 1993// ----- fin ----- // 1994 1995// back in global 1996Outlayer.Item = Item; 1997 1998return Outlayer; 1999 2000})); 2001
2002 2003/***/ }), 2004/* 6 */ 2005/***/ (function(module, exports, __webpack_require__) { 2006 2007var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 2008 * Isotope LayoutMode 2009 */ 2010 2011( function( window, factory ) { 2012 // universal module definition 2013 /* jshint strict: false */ /*globals define, module, require */ 2014 if ( true ) { 2015 // AMD 2016 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 2017 __webpack_require__(3), 2018 __webpack_require__(5) 2019 ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 2020 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 2021 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 2022 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 2023 } else if ( typeof module == 'object' && module.exports ) { 2024 // CommonJS 2025 module.exports = factory( 2026 require('get-size'), 2027 require('outlayer') 2028 ); 2029 } else { 2030 // browser global 2031 window.Isotope = window.Isotope || {}; 2032 window.Isotope.LayoutMode = factory( 2033 window.getSize, 2034 window.Outlayer 2035 ); 2036 } 2037 2038}( window, function factory( getSize, Outlayer ) { 2039 'use strict'; 2040 2041 // layout mode class 2042 function LayoutMode( isotope ) { 2043 this.isotope = isotope; 2044 // link properties 2045 if ( isotope ) { 2046 this.options = isotope.options[ this.namespace ]; 2047 this.element = isotope.element; 2048 this.items = isotope.filteredItems; 2049 this.size = isotope.size; 2050 } 2051 } 2052 2053 var proto = LayoutMode.prototype; 2054 2055 /** 2056 * some methods should just defer to default Outlayer method 2057 * and reference the Isotope instance as `this` 2058 **/ 2059 var facadeMethods = [ 2060 '_resetLayout', 2061 '_getItemLayoutPosition', 2062 '_manageStamp', 2063 '_getContainerSize', 2064 '_getElementOffset', 2065 'needsResizeLayout', 2066 '_getOption' 2067 ]; 2068 2069 facadeMethods.forEach( function( methodName ) { 2070 proto[ methodName ] = function() { 2071 return Outlayer.prototype[ methodName ].apply( this.isotope, arguments ); 2072 }; 2073 }); 2074 2075 // ----- ----- // 2076 2077 // for horizontal layout modes, check vertical size 2078 proto.needsVerticalResizeLayout = function() {
vendor: 2,698 bytes, lines 2079-2182
2079 // don't trigger if size did not change 2080 var size = getSize( this.isotope.element ); 2081 // check that this.size and size are there 2082 // IE8 triggers resize on body size change, so they might not be 2083 var hasSizes = this.isotope.size && size; 2084 return hasSizes && size.innerHeight != this.isotope.size.innerHeight; 2085 }; 2086 2087 // ----- measurements ----- // 2088 2089 proto._getMeasurement = function() { 2090 this.isotope._getMeasurement.apply( this, arguments ); 2091 }; 2092 2093 proto.getColumnWidth = function() { 2094 this.getSegmentSize( 'column', 'Width' ); 2095 }; 2096 2097 proto.getRowHeight = function() { 2098 this.getSegmentSize( 'row', 'Height' ); 2099 }; 2100 2101 /** 2102 * get columnWidth or rowHeight 2103 * segment: 'column' or 'row' 2104 * size 'Width' or 'Height' 2105 **/ 2106 proto.getSegmentSize = function( segment, size ) { 2107 var segmentName = segment + size; 2108 var outerSize = 'outer' + size; 2109 // columnWidth / outerWidth // rowHeight / outerHeight 2110 this._getMeasurement( segmentName, outerSize ); 2111 // got rowHeight or columnWidth, we can chill 2112 if ( this[ segmentName ] ) { 2113 return; 2114 } 2115 // fall back to item of first element 2116 var firstItemSize = this.getFirstItemSize(); 2117 this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] || 2118 // or size of container 2119 this.isotope.size[ 'inner' + size ]; 2120 }; 2121 2122 proto.getFirstItemSize = function() { 2123 var firstItem = this.isotope.filteredItems[0]; 2124 return firstItem && firstItem.element && getSize( firstItem.element ); 2125 }; 2126 2127 // ----- methods that should reference isotope ----- // 2128 2129 proto.layout = function() { 2130 this.isotope.layout.apply( this.isotope, arguments ); 2131 }; 2132 2133 proto.getSize = function() { 2134 this.isotope.getSize(); 2135 this.size = this.isotope.size; 2136 }; 2137 2138 // -------------------------- create -------------------------- // 2139 2140 LayoutMode.modes = {}; 2141 2142 LayoutMode.create = function( namespace, options ) { 2143 2144 function Mode() { 2145 LayoutMode.apply( this, arguments ); 2146 } 2147 2148 Mode.prototype = Object.create( proto ); 2149 Mode.prototype.constructor = Mode; 2150 2151 // default options 2152 if ( options ) { 2153 Mode.options = options; 2154 } 2155 2156 Mode.prototype.namespace = namespace; 2157 // register in Isotope 2158 LayoutMode.modes[ namespace ] = Mode; 2159 2160 return Mode; 2161 }; 2162 2163 return LayoutMode; 2164 2165})); 2166 2167 2168/***/ }), 2169/* 7 */ 2170/***/ (function(module, exports, __webpack_require__) { 2171 2172/*! 2173 * imagesLoaded v5.0.0 2174 * JavaScript is all like "You images are done yet or what?" 2175 * MIT License 2176 */ 2177 2178( function( window, factory ) { 2179 // universal module definition 2180 if ( typeof module == 'object' && module.exports ) { 2181 // CommonJS 2182 module.exports = factory( window, __webpack_require__(24
vendor: 9,235 bytes, lines 2182-2506
2182) ); 2183 } else { 2184 // browser global 2185 window.imagesLoaded = factory( window, window.EvEmitter ); 2186 } 2187 2188} )( typeof window !== 'undefined' ? window : this, 2189 function factory( window, EvEmitter ) { 2190 2191let $ = window.jQuery; 2192let console = window.console; 2193 2194// -------------------------- helpers -------------------------- // 2195 2196// turn element or nodeList into an array 2197function makeArray( obj ) { 2198 // use object if already an array 2199 if ( Array.isArray( obj ) ) return obj; 2200 2201 let isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; 2202 // convert nodeList to array 2203 if ( isArrayLike ) return [ ...obj ]; 2204 2205 // array of single index 2206 return [ obj ]; 2207} 2208 2209// -------------------------- imagesLoaded -------------------------- // 2210 2211/** 2212 * @param {[Array, Element, NodeList, String]} elem 2213 * @param {[Object, Function]} options - if function, use as callback 2214 * @param {Function} onAlways - callback function 2215 * @returns {ImagesLoaded} 2216 */ 2217function ImagesLoaded( elem, options, onAlways ) { 2218 // coerce ImagesLoaded() without new, to be new ImagesLoaded() 2219 if ( !( this instanceof ImagesLoaded ) ) { 2220 return new ImagesLoaded( elem, options, onAlways ); 2221 } 2222 // use elem as selector string 2223 let queryElem = elem; 2224 if ( typeof elem == 'string' ) { 2225 queryElem = document.querySelectorAll( elem ); 2226 } 2227 // bail if bad element 2228 if ( !queryElem ) { 2229 console.error(`Bad element for imagesLoaded ${queryElem || elem}`); 2230 return; 2231 } 2232 2233 this.elements = makeArray( queryElem ); 2234 this.options = {}; 2235 // shift arguments if no options set 2236 if ( typeof options == 'function' ) { 2237 onAlways = options; 2238 } else { 2239 Object.assign( this.options, options ); 2240 } 2241 2242 if ( onAlways ) this.on( 'always', onAlways ); 2243 2244 this.getImages(); 2245 // add jQuery Deferred object 2246 if ( $ ) this.jqDeferred = new $.Deferred(); 2247 2248 // HACK check async to allow time to bind listeners 2249 setTimeout( this.check.bind( this ) ); 2250} 2251 2252ImagesLoaded.prototype = Object.create( EvEmitter.prototype ); 2253 2254ImagesLoaded.prototype.getImages = function() { 2255 this.images = []; 2256 2257 // filter & find items if we have an item selector 2258 this.elements.forEach( this.addElementImages, this ); 2259}; 2260 2261const elementNodeTypes = [ 1, 9, 11 ]; 2262 2263/** 2264 * @param {Node} elem 2265 */ 2266ImagesLoaded.prototype.addElementImages = function( elem ) { 2267 // filter siblings 2268 if ( elem.nodeName === 'IMG' ) { 2269 this.addImage( elem ); 2270 } 2271 // get background image on element 2272 if ( this.options.background === true ) { 2273 this.addElementBackgroundImages( elem ); 2274 } 2275 2276 // find children 2277 // no non-element nodes, #143 2278 let { nodeType } = elem; 2279 if ( !nodeType || !elementNodeTypes.includes( nodeType ) ) return; 2280 2281 let childImgs = elem.querySelectorAll('img'); 2282 // concat childElems to filterFound array 2283 for ( let img of childImgs ) { 2284 this.addImage( img ); 2285 } 2286 2287 // get child background images 2288 if ( typeof this.options.background == 'string' ) { 2289 let children = elem.querySelectorAll( this.options.background ); 2290 for ( let child of children ) { 2291 this.addElementBackgroundImages( child ); 2292 } 2293 } 2294}; 2295 2296const reURL = /url\((['"])?(.*?)\1\)/gi; 2297 2298ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) { 2299 let style = getComputedStyle( elem ); 2300 // Firefox returns null if in a hidden iframe https://bugzil.la/548397 2301 if ( !style ) return; 2302 2303 // get url inside url("...") 2304 let matches = reURL.exec( style.backgroundImage ); 2305 while ( matches !== null ) { 2306 let url = matches && matches[2]; 2307 if ( url ) { 2308 this.addBackground( url, elem ); 2309 } 2310 matches = reURL.exec( style.backgroundImage ); 2311 } 2312}; 2313 2314/** 2315 * @param {Image} img 2316 */ 2317ImagesLoaded.prototype.addImage = function( img ) { 2318 let loadingImage = new LoadingImage( img ); 2319 this.images.push( loadingImage ); 2320}; 2321 2322ImagesLoaded.prototype.addBackground = function( url, elem ) { 2323 let background = new Background( url, elem ); 2324 this.images.push( background ); 2325}; 2326 2327ImagesLoaded.prototype.check = function() { 2328 this.progressedCount = 0; 2329 this.hasAnyBroken = false; 2330 // complete if no images 2331 if ( !this.images.length ) { 2332 this.complete(); 2333 return; 2334 } 2335 2336 /* eslint-disable-next-line func-style */ 2337 let onProgress = ( image, elem, message ) => { 2338 // HACK - Chrome triggers event before object properties have changed. #83 2339 setTimeout( () => { 2340 this.progress( image, elem, message ); 2341 } ); 2342 }; 2343 2344 this.images.forEach( function( loadingImage ) { 2345 loadingImage.once( 'progress', onProgress ); 2346 loadingImage.check(); 2347 } ); 2348}; 2349 2350ImagesLoaded.prototype.progress = function( image, elem, message ) { 2351 this.progressedCount++; 2352 this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; 2353 // progress event 2354 this.emitEvent( 'progress', [ this, image, elem ] ); 2355 if ( this.jqDeferred && this.jqDeferred.notify ) { 2356 this.jqDeferred.notify( this, image ); 2357 } 2358 // check if completed 2359 if ( this.progressedCount === this.images.length ) { 2360 this.complete(); 2361 } 2362 2363 if ( this.options.debug && console ) { 2364 console.log( `progress: ${message}`, image, elem ); 2365 } 2366}; 2367 2368ImagesLoaded.prototype.complete = function() { 2369 let eventName = this.hasAnyBroken ? 'fail' : 'done'; 2370 this.isComplete = true; 2371 this.emitEvent( eventName, [ this ] ); 2372 this.emitEvent( 'always', [ this ] ); 2373 if ( this.jqDeferred ) { 2374 let jqMethod = this.hasAnyBroken ? 'reject' : 'resolve'; 2375 this.jqDeferred[ jqMethod ]( this ); 2376 } 2377}; 2378 2379// -------------------------- -------------------------- // 2380 2381function LoadingImage( img ) { 2382 this.img = img; 2383} 2384 2385LoadingImage.prototype = Object.create( EvEmitter.prototype ); 2386 2387LoadingImage.prototype.check = function() { 2388 // If complete is true and browser supports natural sizes, 2389 // try to check for image status manually. 2390 let isComplete = this.getIsImageComplete(); 2391 if ( isComplete ) { 2392 // report based on naturalWidth 2393 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 2394 return; 2395 } 2396 2397 // If none of the checks above matched, simulate loading on detached element. 2398 this.proxyImage = new Image(); 2399 // add crossOrigin attribute. #204 2400 if ( this.img.crossOrigin ) { 2401 this.proxyImage.crossOrigin = this.img.crossOrigin; 2402 } 2403 this.proxyImage.addEventListener( 'load', this ); 2404 this.proxyImage.addEventListener( 'error', this ); 2405 // bind to image as well for Firefox. #191 2406 this.img.addEventListener( 'load', this ); 2407 this.img.addEventListener( 'error', this ); 2408 this.proxyImage.src = this.img.currentSrc || this.img.src; 2409}; 2410 2411LoadingImage.prototype.getIsImageComplete = function() { 2412 // check for non-zero, non-undefined naturalWidth 2413 // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671 2414 return this.img.complete && this.img.naturalWidth; 2415}; 2416 2417LoadingImage.prototype.confirm = function( isLoaded, message ) { 2418 this.isLoaded = isLoaded; 2419 let { parentNode } = this.img; 2420 // emit progress with parent <picture> or self <img> 2421 let elem = parentNode.nodeName === 'PICTURE' ? parentNode : this.img; 2422 this.emitEvent( 'progress', [ this, elem, message ] ); 2423}; 2424 2425// ----- events ----- // 2426 2427// trigger specified handler for event type 2428LoadingImage.prototype.handleEvent = function( event ) { 2429 let method = 'on' + event.type; 2430 if ( this[ method ] ) { 2431 this[ method ]( event ); 2432 } 2433}; 2434 2435LoadingImage.prototype.onload = function() { 2436 this.confirm( true, 'onload' ); 2437 this.unbindEvents(); 2438}; 2439 2440LoadingImage.prototype.onerror = function() { 2441 this.confirm( false, 'onerror' ); 2442 this.unbindEvents(); 2443}; 2444 2445LoadingImage.prototype.unbindEvents = function() { 2446 this.proxyImage.removeEventListener( 'load', this ); 2447 this.proxyImage.removeEventListener( 'error', this ); 2448 this.img.removeEventListener( 'load', this ); 2449 this.img.removeEventListener( 'error', this ); 2450}; 2451 2452// -------------------------- Background -------------------------- // 2453 2454function Background( url, element ) { 2455 this.url = url; 2456 this.element = element; 2457 this.img = new Image(); 2458} 2459 2460// inherit LoadingImage prototype 2461Background.prototype = Object.create( LoadingImage.prototype ); 2462 2463Background.prototype.check = function() { 2464 this.img.addEventListener( 'load', this ); 2465 this.img.addEventListener( 'error', this ); 2466 this.img.src = this.url; 2467 // check if image is already complete 2468 let isComplete = this.getIsImageComplete(); 2469 if ( isComplete ) { 2470 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 2471 this.unbindEvents(); 2472 } 2473}; 2474 2475Background.prototype.unbindEvents = function() { 2476 this.img.removeEventListener( 'load', this ); 2477 this.img.removeEventListener( 'error', this ); 2478}; 2479 2480Background.prototype.confirm = function( isLoaded, message ) { 2481 this.isLoaded = isLoaded; 2482 this.emitEvent( 'progress', [ this, this.element, message ] ); 2483}; 2484 2485// -------------------------- jQuery -------------------------- // 2486 2487ImagesLoaded.makeJQueryPlugin = function( jQuery ) { 2488 jQuery = jQuery || window.jQuery; 2489 if ( !jQuery ) return; 2490 2491 // set local variable 2492 $ = jQuery; 2493 // $().imagesLoaded() 2494 $.fn.imagesLoaded = function( options, onAlways ) { 2495 let instance = new ImagesLoaded( this, options, onAlways ); 2496 return instance.jqDeferred.promise( $( this ) ); 2497 }; 2498}; 2499// try making plugin 2500ImagesLoaded.makeJQueryPlugin(); 2501 2502// -------------------------- -------------------------- // 2503 2504return ImagesLoaded; 2505 2506} );
2507 2508 2509/***/ }), 2510/* 8 */ 2511/***/ (function(module, exports, __webpack_require__) { 2512 2513var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 2514 * Isotope v3.0.6 2515 * 2516 * Licensed GPLv3 for open source use 2517 * or Isotope Commercial License for commercial use 2518 * 2519 * https://isotope.metafizzy.co 2520 * Copyright 2010-2018 Metafizzy 2521 */ 2522 2523( function( window, factory ) { 2524 // universal module definition 2525 /* jshint strict: false */ /*globals define, module, require */ 2526 if ( true ) { 2527 // AMD 2528 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 2529 __webpack_require__(5), 2530 __webpack_require__(3), 2531 __webpack_require__(12), 2532 __webpack_require__(1), 2533 __webpack_require__(26), 2534 __webpack_require__(6), 2535 // include default layout modes 2536 __webpack_require__(27), 2537 __webpack_require__(29), 2538 __webpack_require__(30) 2539 ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) { 2540 return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ); 2541 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 2542 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 2543 } else if ( typeof module == 'object' && module.exports ) { 2544 // CommonJS 2545 module.exports = factory( 2546 window, 2547 require('outlayer'), 2548 require('get-size'), 2549 require('desandro-matches-selector'), 2550 require('fizzy-ui-utils'), 2551 require('./item'), 2552 require('./layout-mode'), 2553 // include default layout modes 2554 require('./layout-modes/masonry'), 2555 require('./layout-modes/fit-rows'), 2556 require('./layout-modes/vertical') 2557 ); 2558 } else { 2559 // browser global 2560 window.Isotope = factory( 2561 window, 2562 window.Outlayer, 2563 window.getSize, 2564 window.matchesSelector, 2565 window.fizzyUIUtils, 2566 window.Isotope.Item, 2567 window.Isotope.LayoutMode 2568 ); 2569 } 2570 2571}( window, function factory( window, Outlayer, getSize, matchesSelector, utils, 2572 Item, LayoutMode ) { 2573 2574'use strict';
vendor: 15,771 bytes, lines 2574-3134
2574 2575 2576// -------------------------- vars -------------------------- // 2577 2578var jQuery = window.jQuery; 2579 2580// -------------------------- helpers -------------------------- // 2581 2582var trim = String.prototype.trim ? 2583 function( str ) { 2584 return str.trim(); 2585 } : 2586 function( str ) { 2587 return str.replace( /^\s+|\s+$/g, '' ); 2588 }; 2589 2590// -------------------------- isotopeDefinition -------------------------- // 2591 2592 // create an Outlayer layout class 2593 var Isotope = Outlayer.create( 'isotope', { 2594 layoutMode: 'masonry', 2595 isJQueryFiltering: true, 2596 sortAscending: true 2597 }); 2598 2599 Isotope.Item = Item; 2600 Isotope.LayoutMode = LayoutMode; 2601 2602 var proto = Isotope.prototype; 2603 2604 proto._create = function() { 2605 this.itemGUID = 0; 2606 // functions that sort items 2607 this._sorters = {}; 2608 this._getSorters(); 2609 // call super 2610 Outlayer.prototype._create.call( this ); 2611 2612 // create layout modes 2613 this.modes = {}; 2614 // start filteredItems with all items 2615 this.filteredItems = this.items; 2616 // keep of track of sortBys 2617 this.sortHistory = [ 'original-order' ]; 2618 // create from registered layout modes 2619 for ( var name in LayoutMode.modes ) { 2620 this._initLayoutMode( name ); 2621 } 2622 }; 2623 2624 proto.reloadItems = function() { 2625 // reset item ID counter 2626 this.itemGUID = 0; 2627 // call super 2628 Outlayer.prototype.reloadItems.call( this ); 2629 }; 2630 2631 proto._itemize = function() { 2632 var items = Outlayer.prototype._itemize.apply( this, arguments ); 2633 // assign ID for original-order 2634 for ( var i=0; i < items.length; i++ ) { 2635 var item = items[i]; 2636 item.id = this.itemGUID++; 2637 } 2638 this._updateItemsSortData( items ); 2639 return items; 2640 }; 2641 2642 2643 // -------------------------- layout -------------------------- // 2644 2645 proto._initLayoutMode = function( name ) { 2646 var Mode = LayoutMode.modes[ name ]; 2647 // set mode options 2648 // HACK extend initial options, back-fill in default options 2649 var initialOpts = this.options[ name ] || {}; 2650 this.options[ name ] = Mode.options ? 2651 utils.extend( Mode.options, initialOpts ) : initialOpts; 2652 // init layout mode instance 2653 this.modes[ name ] = new Mode( this ); 2654 }; 2655 2656 2657 proto.layout = function() { 2658 // if first time doing layout, do all magic 2659 if ( !this._isLayoutInited && this._getOption('initLayout') ) { 2660 this.arrange(); 2661 return; 2662 } 2663 this._layout(); 2664 }; 2665 2666 // private method to be used in layout() & magic() 2667 proto._layout = function() { 2668 // don't animate first layout 2669 var isInstant = this._getIsInstant(); 2670 // layout flow 2671 this._resetLayout(); 2672 this._manageStamps(); 2673 this.layoutItems( this.filteredItems, isInstant ); 2674 2675 // flag for initalized 2676 this._isLayoutInited = true; 2677 }; 2678 2679 // filter + sort + layout 2680 proto.arrange = function( opts ) { 2681 // set any options pass 2682 this.option( opts ); 2683 this._getIsInstant(); 2684 // filter, sort, and layout 2685 2686 // filter 2687 var filtered = this._filter( this.items ); 2688 this.filteredItems = filtered.matches; 2689 2690 this._bindArrangeComplete(); 2691 2692 if ( this._isInstant ) { 2693 this._noTransition( this._hideReveal, [ filtered ] ); 2694 } else { 2695 this._hideReveal( filtered ); 2696 } 2697 2698 this._sort(); 2699 this._layout(); 2700 }; 2701 // alias to _init for main plugin method 2702 proto._init = proto.arrange; 2703 2704 proto._hideReveal = function( filtered ) { 2705 this.reveal( filtered.needReveal ); 2706 this.hide( filtered.needHide ); 2707 }; 2708 2709 // HACK 2710 // Don't animate/transition first layout 2711 // Or don't animate/transition other layouts 2712 proto._getIsInstant = function() { 2713 var isLayoutInstant = this._getOption('layoutInstant'); 2714 var isInstant = isLayoutInstant !== undefined ? isLayoutInstant : 2715 !this._isLayoutInited; 2716 this._isInstant = isInstant; 2717 return isInstant; 2718 }; 2719 2720 // listen for layoutComplete, hideComplete and revealComplete 2721 // to trigger arrangeComplete 2722 proto._bindArrangeComplete = function() { 2723 // listen for 3 events to trigger arrangeComplete 2724 var isLayoutComplete, isHideComplete, isRevealComplete; 2725 var _this = this; 2726 function arrangeParallelCallback() { 2727 if ( isLayoutComplete && isHideComplete && isRevealComplete ) { 2728 _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] ); 2729 } 2730 } 2731 this.once( 'layoutComplete', function() { 2732 isLayoutComplete = true; 2733 arrangeParallelCallback(); 2734 }); 2735 this.once( 'hideComplete', function() { 2736 isHideComplete = true; 2737 arrangeParallelCallback(); 2738 }); 2739 this.once( 'revealComplete', function() { 2740 isRevealComplete = true; 2741 arrangeParallelCallback(); 2742 }); 2743 }; 2744 2745 // -------------------------- filter -------------------------- // 2746 2747 proto._filter = function( items ) { 2748 var filter = this.options.filter; 2749 filter = filter || '*'; 2750 var matches = []; 2751 var hiddenMatched = []; 2752 var visibleUnmatched = []; 2753 2754 var test = this._getFilterTest( filter ); 2755 2756 // test each item 2757 for ( var i=0; i < items.length; i++ ) { 2758 var item = items[i]; 2759 if ( item.isIgnored ) { 2760 continue; 2761 } 2762 // add item to either matched or unmatched group 2763 var isMatched = test( item ); 2764 // item.isFilterMatched = isMatched; 2765 // add to matches if its a match 2766 if ( isMatched ) { 2767 matches.push( item ); 2768 } 2769 // add to additional group if item needs to be hidden or revealed 2770 if ( isMatched && item.isHidden ) { 2771 hiddenMatched.push( item ); 2772 } else if ( !isMatched && !item.isHidden ) { 2773 visibleUnmatched.push( item ); 2774 } 2775 } 2776 2777 // return collections of items to be manipulated 2778 return { 2779 matches: matches, 2780 needReveal: hiddenMatched, 2781 needHide: visibleUnmatched 2782 }; 2783 }; 2784 2785 // get a jQuery, function, or a matchesSelector test given the filter 2786 proto._getFilterTest = function( filter ) { 2787 if ( jQuery && this.options.isJQueryFiltering ) { 2788 // use jQuery 2789 return function( item ) { 2790 return jQuery( item.element ).is( filter ); 2791 }; 2792 } 2793 if ( typeof filter == 'function' ) { 2794 // use filter as function 2795 return function( item ) { 2796 return filter( item.element ); 2797 }; 2798 } 2799 // default, use filter as selector string 2800 return function( item ) { 2801 return matchesSelector( item.element, filter ); 2802 }; 2803 }; 2804 2805 // -------------------------- sorting -------------------------- // 2806 2807 /** 2808 * @params {Array} elems 2809 * @public 2810 */ 2811 proto.updateSortData = function( elems ) { 2812 // get items 2813 var items; 2814 if ( elems ) { 2815 elems = utils.makeArray( elems ); 2816 items = this.getItems( elems ); 2817 } else { 2818 // update all items if no elems provided 2819 items = this.items; 2820 } 2821 2822 this._getSorters(); 2823 this._updateItemsSortData( items ); 2824 }; 2825 2826 proto._getSorters = function() { 2827 var getSortData = this.options.getSortData; 2828 for ( var key in getSortData ) { 2829 var sorter = getSortData[ key ]; 2830 this._sorters[ key ] = mungeSorter( sorter ); 2831 } 2832 }; 2833 2834 /** 2835 * @params {Array} items - of Isotope.Items 2836 * @private 2837 */ 2838 proto._updateItemsSortData = function( items ) { 2839 // do not update if no items 2840 var len = items && items.length; 2841 2842 for ( var i=0; len && i < len; i++ ) { 2843 var item = items[i]; 2844 item.updateSortData(); 2845 } 2846 }; 2847 2848 // ----- munge sorter ----- // 2849 2850 // encapsulate this, as we just need mungeSorter 2851 // other functions in here are just for munging 2852 var mungeSorter = ( function() { 2853 // add a magic layer to sorters for convienent shorthands 2854 // `.foo-bar` will use the text of .foo-bar querySelector 2855 // `[foo-bar]` will use attribute 2856 // you can also add parser 2857 // `.foo-bar parseInt` will parse that as a number 2858 function mungeSorter( sorter ) { 2859 // if not a string, return function or whatever it is 2860 if ( typeof sorter != 'string' ) { 2861 return sorter; 2862 } 2863 // parse the sorter string 2864 var args = trim( sorter ).split(' '); 2865 var query = args[0]; 2866 // check if query looks like [an-attribute] 2867 var attrMatch = query.match( /^\[(.+)\]$/ ); 2868 var attr = attrMatch && attrMatch[1]; 2869 var getValue = getValueGetter( attr, query ); 2870 // use second argument as a parser 2871 var parser = Isotope.sortDataParsers[ args[1] ]; 2872 // parse the value, if there was a parser 2873 sorter = parser ? function( elem ) { 2874 return elem && parser( getValue( elem ) ); 2875 } : 2876 // otherwise just return value 2877 function( elem ) { 2878 return elem && getValue( elem ); 2879 }; 2880 2881 return sorter; 2882 } 2883 2884 // get an attribute getter, or get text of the querySelector 2885 function getValueGetter( attr, query ) { 2886 // if query looks like [foo-bar], get attribute 2887 if ( attr ) { 2888 return function getAttribute( elem ) { 2889 return elem.getAttribute( attr ); 2890 }; 2891 } 2892 2893 // otherwise, assume its a querySelector, and get its text 2894 return function getChildText( elem ) { 2895 var child = elem.querySelector( query ); 2896 return child && child.textContent; 2897 }; 2898 } 2899 2900 return mungeSorter; 2901 })(); 2902 2903 // parsers used in getSortData shortcut strings 2904 Isotope.sortDataParsers = { 2905 'parseInt': function( val ) { 2906 return parseInt( val, 10 ); 2907 }, 2908 'parseFloat': function( val ) { 2909 return parseFloat( val ); 2910 } 2911 }; 2912 2913 // ----- sort method ----- // 2914 2915 // sort filteredItem order 2916 proto._sort = function() { 2917 if ( !this.options.sortBy ) { 2918 return; 2919 } 2920 // keep track of sortBy History 2921 var sortBys = utils.makeArray( this.options.sortBy ); 2922 if ( !this._getIsSameSortBy( sortBys ) ) { 2923 // concat all sortBy and sortHistory, add to front, oldest goes in last 2924 this.sortHistory = sortBys.concat( this.sortHistory ); 2925 } 2926 // sort magic 2927 var itemSorter = getItemSorter( this.sortHistory, this.options.sortAscending ); 2928 this.filteredItems.sort( itemSorter ); 2929 }; 2930 2931 // check if sortBys is same as start of sortHistory 2932 proto._getIsSameSortBy = function( sortBys ) { 2933 for ( var i=0; i < sortBys.length; i++ ) { 2934 if ( sortBys[i] != this.sortHistory[i] ) { 2935 return false; 2936 } 2937 } 2938 return true; 2939 }; 2940 2941 // returns a function used for sorting 2942 function getItemSorter( sortBys, sortAsc ) { 2943 return function sorter( itemA, itemB ) { 2944 // cycle through all sortKeys 2945 for ( var i = 0; i < sortBys.length; i++ ) { 2946 var sortBy = sortBys[i]; 2947 var a = itemA.sortData[ sortBy ]; 2948 var b = itemB.sortData[ sortBy ]; 2949 if ( a > b || a < b ) { 2950 // if sortAsc is an object, use the value given the sortBy key 2951 var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc; 2952 var direction = isAscending ? 1 : -1; 2953 return ( a > b ? 1 : -1 ) * direction; 2954 } 2955 } 2956 return 0; 2957 }; 2958 } 2959 2960 // -------------------------- methods -------------------------- // 2961 2962 // get layout mode 2963 proto._mode = function() { 2964 var layoutMode = this.options.layoutMode; 2965 var mode = this.modes[ layoutMode ]; 2966 if ( !mode ) { 2967 // TODO console.error 2968 throw new Error( 'No layout mode: ' + layoutMode ); 2969 } 2970 // HACK sync mode's options 2971 // any options set after init for layout mode need to be synced 2972 mode.options = this.options[ layoutMode ]; 2973 return mode; 2974 }; 2975 2976 proto._resetLayout = function() { 2977 // trigger original reset layout 2978 Outlayer.prototype._resetLayout.call( this ); 2979 this._mode()._resetLayout(); 2980 }; 2981 2982 proto._getItemLayoutPosition = function( item ) { 2983 return this._mode()._getItemLayoutPosition( item ); 2984 }; 2985 2986 proto._manageStamp = function( stamp ) { 2987 this._mode()._manageStamp( stamp ); 2988 }; 2989 2990 proto._getContainerSize = function() { 2991 return this._mode()._getContainerSize(); 2992 }; 2993 2994 proto.needsResizeLayout = function() { 2995 return this._mode().needsResizeLayout(); 2996 }; 2997 2998 // -------------------------- adding & removing -------------------------- // 2999 3000 // HEADS UP overwrites default Outlayer appended 3001 proto.appended = function( elems ) { 3002 var items = this.addItems( elems ); 3003 if ( !items.length ) { 3004 return; 3005 } 3006 // filter, layout, reveal new items 3007 var filteredItems = this._filterRevealAdded( items ); 3008 // add to filteredItems 3009 this.filteredItems = this.filteredItems.concat( filteredItems ); 3010 }; 3011 3012 // HEADS UP overwrites default Outlayer prepended 3013 proto.prepended = function( elems ) { 3014 var items = this._itemize( elems ); 3015 if ( !items.length ) { 3016 return; 3017 } 3018 // start new layout 3019 this._resetLayout(); 3020 this._manageStamps(); 3021 // filter, layout, reveal new items 3022 var filteredItems = this._filterRevealAdded( items ); 3023 // layout previous items 3024 this.layoutItems( this.filteredItems ); 3025 // add to items and filteredItems 3026 this.filteredItems = filteredItems.concat( this.filteredItems ); 3027 this.items = items.concat( this.items ); 3028 }; 3029 3030 proto._filterRevealAdded = function( items ) { 3031 var filtered = this._filter( items ); 3032 this.hide( filtered.needHide ); 3033 // reveal all new items 3034 this.reveal( filtered.matches ); 3035 // layout new items, no transition 3036 this.layoutItems( filtered.matches, true ); 3037 return filtered.matches; 3038 }; 3039 3040 /** 3041 * Filter, sort, and layout newly-appended item elements 3042 * @param {Array or NodeList or Element} elems 3043 */ 3044 proto.insert = function( elems ) { 3045 var items = this.addItems( elems ); 3046 if ( !items.length ) { 3047 return; 3048 } 3049 // append item elements 3050 var i, item; 3051 var len = items.length; 3052 for ( i=0; i < len; i++ ) { 3053 item = items[i]; 3054 this.element.appendChild( item.element ); 3055 } 3056 // filter new stuff 3057 var filteredInsertItems = this._filter( items ).matches; 3058 // set flag 3059 for ( i=0; i < len; i++ ) { 3060 items[i].isLayoutInstant = true; 3061 } 3062 this.arrange(); 3063 // reset flag 3064 for ( i=0; i < len; i++ ) { 3065 delete items[i].isLayoutInstant; 3066 } 3067 this.reveal( filteredInsertItems ); 3068 }; 3069 3070 var _remove = proto.remove; 3071 proto.remove = function( elems ) { 3072 elems = utils.makeArray( elems ); 3073 var removeItems = this.getItems( elems ); 3074 // do regular thing 3075 _remove.call( this, elems ); 3076 // bail if no items to remove 3077 var len = removeItems && removeItems.length; 3078 // remove elems from filteredItems 3079 for ( var i=0; len && i < len; i++ ) { 3080 var item = removeItems[i]; 3081 // remove item from collection 3082 utils.removeFrom( this.filteredItems, item ); 3083 } 3084 }; 3085 3086 proto.shuffle = function() { 3087 // update random sortData 3088 for ( var i=0; i < this.items.length; i++ ) { 3089 var item = this.items[i]; 3090 item.sortData.random = Math.random(); 3091 } 3092 this.options.sortBy = 'random'; 3093 this._sort(); 3094 this._layout(); 3095 }; 3096 3097 /** 3098 * trigger fn without transition 3099 * kind of hacky to have this in the first place 3100 * @param {Function} fn 3101 * @param {Array} args 3102 * @returns ret 3103 * @private 3104 */ 3105 proto._noTransition = function( fn, args ) { 3106 // save transitionDuration before disabling 3107 var transitionDuration = this.options.transitionDuration; 3108 // disable transition 3109 this.options.transitionDuration = 0; 3110 // do it 3111 var returnValue = fn.apply( this, args ); 3112 // re-enable transition for reveal 3113 this.options.transitionDuration = transitionDuration; 3114 return returnValue; 3115 }; 3116 3117 // ----- helper methods ----- // 3118 3119 /** 3120 * getter method for getting filtered item elements 3121 * @returns {Array} elems - collection of item elements 3122 */ 3123 proto.getFilteredItemElements = function() { 3124 return this.filteredItems.map( function( item ) { 3125 return item.element; 3126 }); 3127 }; 3128 3129 // ----- ----- // 3130 3131 return Isotope; 3132 3133})); 3134
3135 3136/***/ }), 3137/* 9 */ 3138/***/ (function(module, exports, __webpack_require__) { 3139 3140var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 3141 * Infinite Scroll v3.0.3 3142 * Automatically add next page 3143 * 3144 * Licensed GPLv3 for open source use 3145 * or Infinite Scroll Commercial License for commercial use 3146 * 3147 * https://infinite-scroll.com 3148 * Copyright 2018 Metafizzy 3149 */ 3150 3151( function( window, factory ) { 3152 // universal module definition 3153 /* globals define, module, require */ 3154 if ( true ) { 3155 // AMD 3156 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 3157 __webpack_require__(2), 3158 __webpack_require__(32), 3159 __webpack_require__(33), 3160 __webpack_require__(34), 3161 __webpack_require__(35), 3162 __webpack_require__(36), 3163 ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 3164 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 3165 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
3166 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 3167 } else if ( typeof module == 'object' && module.exports ) { 3168 // CommonJS 3169 module.exports = factory( 3170 require('./core'), 3171 require('./page-load'), 3172 require('./scroll-watch'), 3173 require('./history'), 3174 require('./button'), 3175 require('./status') 3176 ); 3177 } 3178 3179})( window, function factory( InfiniteScroll ) { 3180 return InfiniteScroll; 3181}); 3182 3183 3184/***/ }), 3185/* 10 */ 3186/***/ (function(module, __webpack_exports__, __webpack_require__) { 3187 3188"use strict"; 3189/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return GSCache; }); 3190/* unused harmony export Animation */ 3191/* unused harmony export Timeline */ 3192/* unused harmony export Tween */ 3193/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return PropTween; }); 3194/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "w", function() { return gsap; }); 3195/* unused harmony export Power0 */ 3196/* unused harmony export Power1 */ 3197/* unused harmony export Power2 */ 3198/* unused harmony export Power3 */ 3199/* unused harmony export Power4 */ 3200/* unused harmony export Linear */ 3201/* unused harmony export Quad */ 3202/* unused harmony export Cubic */ 3203/* unused harmony export Quart */ 3204/* unused harmony export Quint */ 3205/* unused harmony export Strong */ 3206/* unused harmony export Elastic */ 3207/* unused harmony export Back */ 3208/* unused harmony export SteppedEase */ 3209/* unused harmony export Bounce */ 3210/* unused harmony export Sine */ 3211/* unused harmony export Expo */ 3212/* unused harmony export Circ */ 3213/* unused harmony export TweenMax */ 3214/* unused harmony export TweenLite */ 3215/* unused harmony export TimelineMax */ 3216/* unused harmony export TimelineLite */ 3217/* unused harmony export default */ 3218/* unused harmony export wrap */ 3219/* unused harmony export wrapYoyo */ 3220/* unused harmony export distribute */ 3221/* unused harmony export random */ 3222/* unused harmony export snap */ 3223/* unused harmony export normalize */ 3224/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "v", function() { return getUnit; }); 3225/* unused harmony export clamp */ 3226/* unused harmony export splitColor */ 3227/* unused harmony export toArray */ 3228/* unused harmony export mapRange */ 3229/* unused harmony export pipe */ 3230/* unused harmony export unitize */ 3231/* unused harmony export interpolate */ 3232/* unused harmony export shuffle */ 3233/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "h", function() { return _getProperty; }); 3234/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "m", function() { return _numExp; }); 3235/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "n", function() { return _numWithUnitExp; }); 3236/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "j", function() { return _isString; }); 3237/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "k", function() { return _isUndefined; }); 3238/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "q", function() { return _renderComplexString; }); 3239/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "p", function() { return _relExp; }); 3240/* unused harmony export _setDefaults */ 3241/* unused harmony export _removeLinkedListItem */ 3242/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "f", function() { return _forEachName; }); 3243/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "t", function() { return _sortPropTweensByPriority; }); 3244/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return _colorStringFilter; }); 3245/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "r", function() { return _replaceRandom; }); 3246/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return _checkPlugin; }); 3247/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "o", function() { return _plugins; }); 3248/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "u", function() { return _ticker; }); 3249/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return _config; }); 3250/* unused harmony export _roundModifier */ 3251/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "s", function() { return _round; }); 3252/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "l", function() { return _missingPlugin; }); 3253/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "i", function() { return _getSetter; }); 3254/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "g", function() { return _getCache; }); 3255function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 3256 3257function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } 3258 3259/*! 3260 * GSAP 3.6.0 3261 * https://greensock.com 3262 * 3263 * @license Copyright 2008-2021, GreenSock. All rights reserved. 3264 * Subject to the terms at https://greensock.com/standard-license or for 3265 * Club GreenSock members, the agreement issued with that membership. 3266 * @author: Jack Doyle, [email protected] 3267*/ 3268 3269/* eslint-disable */ 3270var _config = { 3271 autoSleep: 120, 3272 force3D: "auto", 3273 nullTargetWarn: 1, 3274 units: { 3275 lineHeight: "" 3276 } 3277}, 3278 _defaults = { 3279 duration: .5, 3280 overwrite: false, 3281 delay: 0 3282}, 3283 _suppressOverwrites, 3284 _bigNum = 1e8, 3285 _tinyNum = 1 / _bigNum, 3286 _2PI = Math.PI * 2, 3287 _HALF_PI = _2PI / 4, 3288 _gsID = 0, 3289 _sqrt = Math.sqrt, 3290 _cos = Math.cos, 3291 _sin = Math.sin, 3292 _isString = function _isString(value) { 3293 return typeof value === "string"; 3294}, 3295 _isFunction = function _isFunction(value) { 3296 return typeof value === "function"; 3297}, 3298 _isNumber = function _isNumber(value) { 3299 return typeof value === "number"; 3300}, 3301 _isUndefined = function _isUndefined(value) { 3302 return typeof value === "undefined"; 3303}, 3304 _isObject = function _isObject(value) { 3305 return typeof value === "object"; 3306}, 3307 _isNotFalse = function _isNotFalse(value) { 3308 return value !== false; 3309}, 3310 _windowExists = function _windowExists() { 3311 return typeof window !== "undefined"; 3312}, 3313 _isFuncOrString = function _isFuncOrString(value) { 3314 return _isFunction(value) || _isString(value); 3315}, 3316 _isTypedArray = typeof ArrayBuffer === "function" && ArrayBuffer.isView || function () {}, 3317 // note: IE10 has ArrayBuffer, but NOT ArrayBuffer.isView(). 3318_isArray = Array.isArray,
vendor: 13,896 bytes, lines 3319-3673
3319 _strictNumExp = /(?:-?\.?\d|\.)+/gi, 3320 //only numbers (including negatives and decimals) but NOT relative values. 3321_numExp = /[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/g, 3322 //finds any numbers, including ones that start with += or -=, negative numbers, and ones in scientific notation like 1e-8. 3323_numWithUnitExp = /[-+=.]*\d+[.e-]*\d*[a-z%]*/g, 3324 _complexStringNumExp = /[-+=.]*\d+\.?\d*(?:e-|e\+)?\d*/gi, 3325 //duplicate so that while we're looping through matches from exec(), it doesn't contaminate the lastIndex of _numExp which we use to search for colors too. 3326_relExp = /[+-]=-?[.\d]+/, 3327 _delimitedValueExp = /[#\-+.]*\b[a-z\d-=+%.]+/gi, 3328 _unitExp = /[\d.+\-=]+(?:e[-+]\d*)*/i, 3329 _globalTimeline, 3330 _win, 3331 _coreInitted, 3332 _doc, 3333 _globals = {}, 3334 _installScope = {}, 3335 _coreReady, 3336 _install = function _install(scope) { 3337 return (_installScope = _merge(scope, _globals)) && gsap; 3338}, 3339 _missingPlugin = function _missingPlugin(property, value) { 3340 return console.warn("Invalid property", property, "set to", value, "Missing plugin? gsap.registerPlugin()"); 3341}, 3342 _warn = function _warn(message, suppress) { 3343 return !suppress && console.warn(message); 3344}, 3345 _addGlobal = function _addGlobal(name, obj) { 3346 return name && (_globals[name] = obj) && _installScope && (_installScope[name] = obj) || _globals; 3347}, 3348 _emptyFunc = function _emptyFunc() { 3349 return 0; 3350}, 3351 _reservedProps = {}, 3352 _lazyTweens = [], 3353 _lazyLookup = {}, 3354 _lastRenderedFrame, 3355 _plugins = {}, 3356 _effects = {}, 3357 _nextGCFrame = 30, 3358 _harnessPlugins = [], 3359 _callbackNames = "", 3360 _harness = function _harness(targets) { 3361 var target = targets[0], 3362 harnessPlugin, 3363 i; 3364 _isObject(target) || _isFunction(target) || (targets = [targets]); 3365 3366 if (!(harnessPlugin = (target._gsap || {}).harness)) { 3367 // find the first target with a harness. We assume targets passed into an animation will be of similar type, meaning the same kind of harness can be used for them all (performance optimization) 3368 i = _harnessPlugins.length; 3369 3370 while (i-- && !_harnessPlugins[i].targetTest(target)) {} 3371 3372 harnessPlugin = _harnessPlugins[i]; 3373 } 3374 3375 i = targets.length; 3376 3377 while (i--) { 3378 targets[i] && (targets[i]._gsap || (targets[i]._gsap = new GSCache(targets[i], harnessPlugin))) || targets.splice(i, 1); 3379 } 3380 3381 return targets; 3382}, 3383 _getCache = function _getCache(target) { 3384 return target._gsap || _harness(toArray(target))[0]._gsap; 3385}, 3386 _getProperty = function _getProperty(target, property, v) { 3387 return (v = target[property]) && _isFunction(v) ? target[property]() : _isUndefined(v) && target.getAttribute && target.getAttribute(property) || v; 3388}, 3389 _forEachName = function _forEachName(names, func) { 3390 return (names = names.split(",")).forEach(func) || names; 3391}, 3392 //split a comma-delimited list of names into an array, then run a forEach() function and return the split array (this is just a way to consolidate/shorten some code). 3393_round = function _round(value) { 3394 return Math.round(value * 100000) / 100000 || 0; 3395}, 3396 _arrayContainsAny = function _arrayContainsAny(toSearch, toFind) { 3397 //searches one array to find matches for any of the items in the toFind array. As soon as one is found, it returns true. It does NOT return all the matches; it's simply a boolean search. 3398 var l = toFind.length, 3399 i = 0; 3400 3401 for (; toSearch.indexOf(toFind[i]) < 0 && ++i < l;) {} 3402 3403 return i < l; 3404}, 3405 _parseVars = function _parseVars(params, type, parent) { 3406 //reads the arguments passed to one of the key methods and figures out if the user is defining things with the OLD/legacy syntax where the duration is the 2nd parameter, and then it adjusts things accordingly and spits back the corrected vars object (with the duration added if necessary, as well as runBackwards or startAt or immediateRender). type 0 = to()/staggerTo(), 1 = from()/staggerFrom(), 2 = fromTo()/staggerFromTo() 3407 var isLegacy = _isNumber(params[1]), 3408 varsIndex = (isLegacy ? 2 : 1) + (type < 2 ? 0 : 1), 3409 vars = params[varsIndex], 3410 irVars; 3411 3412 isLegacy && (vars.duration = params[1]); 3413 vars.parent = parent; 3414 3415 if (type) { 3416 irVars = vars; 3417 3418 while (parent && !("immediateRender" in irVars)) { 3419 // inheritance hasn't happened yet, but someone may have set a default in an ancestor timeline. We could do vars.immediateRender = _isNotFalse(_inheritDefaults(vars).immediateRender) but that'd exact a slight performance penalty because _inheritDefaults() also runs in the Tween constructor. We're paying a small kb price here to gain speed. 3420 irVars = parent.vars.defaults || {}; 3421 parent = _isNotFalse(parent.vars.inherit) && parent.parent; 3422 } 3423 3424 vars.immediateRender = _isNotFalse(irVars.immediateRender); 3425 type < 2 ? vars.runBackwards = 1 : vars.startAt = params[varsIndex - 1]; // "from" vars 3426 } 3427 3428 return vars; 3429}, 3430 _lazyRender = function _lazyRender() { 3431 var l = _lazyTweens.length, 3432 a = _lazyTweens.slice(0), 3433 i, 3434 tween; 3435 3436 _lazyLookup = {}; 3437 _lazyTweens.length = 0; 3438 3439 for (i = 0; i < l; i++) { 3440 tween = a[i]; 3441 tween && tween._lazy && (tween.render(tween._lazy[0], tween._lazy[1], true)._lazy = 0); 3442 } 3443}, 3444 _lazySafeRender = function _lazySafeRender(animation, time, suppressEvents, force) { 3445 _lazyTweens.length && _lazyRender(); 3446 animation.render(time, suppressEvents, force); 3447 _lazyTweens.length && _lazyRender(); //in case rendering caused any tweens to lazy-init, we should render them because typically when someone calls seek() or time() or progress(), they expect an immediate render. 3448}, 3449 _numericIfPossible = function _numericIfPossible(value) { 3450 var n = parseFloat(value); 3451 return (n || n === 0) && (value + "").match(_delimitedValueExp).length < 2 ? n : _isString(value) ? value.trim() : value; 3452}, 3453 _passThrough = function _passThrough(p) { 3454 return p; 3455}, 3456 _setDefaults = function _setDefaults(obj, defaults) { 3457 for (var p in defaults) { 3458 p in obj || (obj[p] = defaults[p]); 3459 } 3460 3461 return obj; 3462}, 3463 _setKeyframeDefaults = function _setKeyframeDefaults(obj, defaults) { 3464 for (var p in defaults) { 3465 p in obj || p === "duration" || p === "ease" || (obj[p] = defaults[p]); 3466 } 3467}, 3468 _merge = function _merge(base, toMerge) { 3469 for (var p in toMerge) { 3470 base[p] = toMerge[p]; 3471 } 3472 3473 return base; 3474}, 3475 _mergeDeep = function _mergeDeep(base, toMerge) { 3476 for (var p in toMerge) { 3477 p !== "__proto__" && p !== "constructor" && p !== "prototype" && (base[p] = _isObject(toMerge[p]) ? _mergeDeep(base[p] || (base[p] = {}), toMerge[p]) : toMerge[p]); 3478 } 3479 3480 return base; 3481}, 3482 _copyExcluding = function _copyExcluding(obj, excluding) { 3483 var copy = {}, 3484 p; 3485 3486 for (p in obj) { 3487 p in excluding || (copy[p] = obj[p]); 3488 } 3489 3490 return copy; 3491}, 3492 _inheritDefaults = function _inheritDefaults(vars) { 3493 var parent = vars.parent || _globalTimeline, 3494 func = vars.keyframes ? _setKeyframeDefaults : _setDefaults; 3495 3496 if (_isNotFalse(vars.inherit)) { 3497 while (parent) { 3498 func(vars, parent.vars.defaults); 3499 parent = parent.parent || parent._dp; 3500 } 3501 } 3502 3503 return vars; 3504}, 3505 _arraysMatch = function _arraysMatch(a1, a2) { 3506 var i = a1.length, 3507 match = i === a2.length; 3508 3509 while (match && i-- && a1[i] === a2[i]) {} 3510 3511 return i < 0; 3512}, 3513 _addLinkedListItem = function _addLinkedListItem(parent, child, firstProp, lastProp, sortBy) { 3514 if (firstProp === void 0) { 3515 firstProp = "_first"; 3516 } 3517 3518 if (lastProp === void 0) { 3519 lastProp = "_last"; 3520 } 3521 3522 var prev = parent[lastProp], 3523 t; 3524 3525 if (sortBy) { 3526 t = child[sortBy]; 3527 3528 while (prev && prev[sortBy] > t) { 3529 prev = prev._prev; 3530 } 3531 } 3532 3533 if (prev) { 3534 child._next = prev._next; 3535 prev._next = child; 3536 } else { 3537 child._next = parent[firstProp]; 3538 parent[firstProp] = child; 3539 } 3540 3541 if (child._next) { 3542 child._next._prev = child; 3543 } else { 3544 parent[lastProp] = child; 3545 } 3546 3547 child._prev = prev; 3548 child.parent = child._dp = parent; 3549 return child; 3550}, 3551 _removeLinkedListItem = function _removeLinkedListItem(parent, child, firstProp, lastProp) { 3552 if (firstProp === void 0) { 3553 firstProp = "_first"; 3554 } 3555 3556 if (lastProp === void 0) { 3557 lastProp = "_last"; 3558 } 3559 3560 var prev = child._prev, 3561 next = child._next; 3562 3563 if (prev) { 3564 prev._next = next; 3565 } else if (parent[firstProp] === child) { 3566 parent[firstProp] = next; 3567 } 3568 3569 if (next) { 3570 next._prev = prev; 3571 } else if (parent[lastProp] === child) { 3572 parent[lastProp] = prev; 3573 } 3574 3575 child._next = child._prev = child.parent = null; // don't delete the _dp just so we can revert if necessary. But parent should be null to indicate the item isn't in a linked list. 3576}, 3577 _removeFromParent = function _removeFromParent(child, onlyIfParentHasAutoRemove) { 3578 child.parent && (!onlyIfParentHasAutoRemove || child.parent.autoRemoveChildren) && child.parent.remove(child); 3579 child._act = 0; 3580}, 3581 _uncache = function _uncache(animation, child) { 3582 if (animation && (!child || child._end > animation._dur || child._start < 0)) { 3583 // performance optimization: if a child animation is passed in we should only uncache if that child EXTENDS the animation (its end time is beyond the end) 3584 var a = animation; 3585 3586 while (a) { 3587 a._dirty = 1; 3588 a = a.parent; 3589 } 3590 } 3591 3592 return animation; 3593}, 3594 _recacheAncestors = function _recacheAncestors(animation) { 3595 var parent = animation.parent; 3596 3597 while (parent && parent.parent) { 3598 //sometimes we must force a re-sort of all children and update the duration/totalDuration of all ancestor timelines immediately in case, for example, in the middle of a render loop, one tween alters another tween's timeScale which shoves its startTime before 0, forcing the parent timeline to shift around and shiftChildren() which could affect that next tween's render (startTime). Doesn't matter for the root timeline though. 3599 parent._dirty = 1; 3600 parent.totalDuration(); 3601 parent = parent.parent; 3602 } 3603 3604 return animation; 3605}, 3606 _hasNoPausedAncestors = function _hasNoPausedAncestors(animation) { 3607 return !animation || animation._ts && _hasNoPausedAncestors(animation.parent); 3608}, 3609 _elapsedCycleDuration = function _elapsedCycleDuration(animation) { 3610 return animation._repeat ? _animationCycle(animation._tTime, animation = animation.duration() + animation._rDelay) * animation : 0; 3611}, 3612 // feed in the totalTime and cycleDuration and it'll return the cycle (iteration minus 1) and if the playhead is exactly at the very END, it will NOT bump up to the next cycle. 3613_animationCycle = function _animationCycle(tTime, cycleDuration) { 3614 var whole = Math.floor(tTime /= cycleDuration); 3615 return tTime && whole === tTime ? whole - 1 : whole; 3616}, 3617 _parentToChildTotalTime = function _parentToChildTotalTime(parentTime, child) { 3618 return (parentTime - child._start) * child._ts + (child._ts >= 0 ? 0 : child._dirty ? child.totalDuration() : child._tDur); 3619}, 3620 _setEnd = function _setEnd(animation) { 3621 return animation._end = _round(animation._start + (animation._tDur / Math.abs(animation._ts || animation._rts || _tinyNum) || 0)); 3622}, 3623 _alignPlayhead = function _alignPlayhead(animation, totalTime) { 3624 // adjusts the animation's _start and _end according to the provided totalTime (only if the parent's smoothChildTiming is true and the animation isn't paused). It doesn't do any rendering or forcing things back into parent timelines, etc. - that's what totalTime() is for. 3625 var parent = animation._dp; 3626 3627 if (parent && parent.smoothChildTiming && animation._ts) { 3628 animation._start = _round(parent._time - (animation._ts > 0 ? totalTime / animation._ts : ((animation._dirty ? animation.totalDuration() : animation._tDur) - totalTime) / -animation._ts)); 3629 3630 _setEnd(animation); 3631 3632 parent._dirty || _uncache(parent, animation); //for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here. 3633 } 3634 3635 return animation; 3636}, 3637 3638/* 3639_totalTimeToTime = (clampedTotalTime, duration, repeat, repeatDelay, yoyo) => { 3640 let cycleDuration = duration + repeatDelay, 3641 time = _round(clampedTotalTime % cycleDuration); 3642 if (time > duration) { 3643 time = duration; 3644 } 3645 return (yoyo && (~~(clampedTotalTime / cycleDuration) & 1)) ? duration - time : time; 3646}, 3647*/ 3648_postAddChecks = function _postAddChecks(timeline, child) { 3649 var t; 3650 3651 if (child._time || child._initted && !child._dur) { 3652 //in case, for example, the _start is moved on a tween that has already rendered. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning. 3653 t = _parentToChildTotalTime(timeline.rawTime(), child); 3654 3655 if (!child._dur || _clamp(0, child.totalDuration(), t) - child._tTime > _tinyNum) { 3656 child.render(t, true); 3657 } 3658 } //if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate. 3659 3660 3661 if (_uncache(timeline, child)._dp && timeline._initted && timeline._time >= timeline._dur && timeline._ts) { 3662 //in case any of the ancestors had completed but should now be enabled... 3663 if (timeline._dur < timeline.duration()) { 3664 t = timeline; 3665 3666 while (t._dp) { 3667 t.rawTime() >= 0 && t.totalTime(t._tTime); //moves the timeline (shifts its startTime) if necessary, and also enables it. If it's currently zero, though, it may not be scheduled to render until later so there's no need to force it to align with the current playhead position. Only move to catch up with the playhead. 3668 3669 t = t._dp; 3670 } 3671 } 3672 3673 timeline._zTime = -_tinyNum; // helps ensure that the next render() will be forced (crossingStart = true in render()), even if the duration hasn't changed (we're adding a child which w
3673ould need to get rendered). Definitely an edge case. Note: we MUST do this AFTER the loop above where the totalTime() might trigger a render() because this _addToTimeline() method gets called from the Animation constructor, BEFORE tweens even record their targets, etc. so we wouldn't want things to get triggered in the wrong order. 3674 } 3675}, 3676 _addToTimeline = function _addToTimeline(timeline, child, position, skipChecks) { 3677 child.parent && _removeFromParent(child); 3678 child._start = _round(position + child._delay); 3679 child._end = _round(child._start + (child.totalDuration() / Math.abs(child.timeScale()) || 0)); 3680 3681 _addLinkedListItem(timeline, child, "_first", "_last", timeline._sort ? "_start" : 0); 3682 3683 timeline._recent = child; 3684 skipChecks || _postAddChecks(timeline, child); 3685 return timeline; 3686}, 3687 _scrollTrigger = function _scrollTrigger(animation, trigger) { 3688 return (_globals.ScrollTrigger || _missingPlugin("scrollTrigger", trigger)) && _globals.ScrollTrigger.create(trigger, animation); 3689}, 3690 _attemptInitTween = function _attemptInitTween(tween, totalTime, force, suppressEvents) { 3691 _initTween(tween, totalTime); 3692 3693 if (!tween._initted) { 3694 return 1; 3695 } 3696 3697 if (!force && tween._pt && (tween._dur && tween.vars.lazy !== false || !tween._dur && tween.vars.lazy) && _lastRenderedFrame !== _ticker.frame) { 3698 _lazyTweens.push(tween); 3699 3700 tween._lazy = [totalTime, suppressEvents]; 3701 return 1; 3702 } 3703}, 3704 _parentPlayheadIsBeforeStart = function _parentPlayheadIsBeforeStart(_ref) { 3705 var parent = _ref.parent; 3706 return parent && parent._ts && parent._initted && !parent._lock && (parent.rawTime() < 0 || _parentPlayheadIsBeforeStart(parent)); 3707}, 3708 // check parent's _lock because when a timeline repeats/yoyos and does its artificial wrapping, we shouldn't force the ratio back to 0 3709_renderZeroDurationTween = function _renderZeroDurationTween(tween, totalTime, suppressEvents, force) { 3710 var prevRatio = tween.ratio, 3711 ratio = totalTime < 0 || !totalTime && (!tween._start && _parentPlayheadIsBeforeStart(tween) || (tween._ts < 0 || tween._dp._ts < 0) && tween.data !== "isFromStart" && tween.data !== "isStart") ? 0 : 1, 3712 // if the tween or its parent is reversed and the totalTime is 0, we should go to a ratio of 0. 3713 repeatDelay = tween._rDelay, 3714 tTime = 0, 3715 pt, 3716 iteration, 3717 prevIteration; 3718 3719 if (repeatDelay && tween._repeat) { 3720 // in case there's a zero-duration tween that has a repeat with a repeatDelay 3721 tTime = _clamp(0, tween._tDur, totalTime); 3722 iteration = _animationCycle(tTime, repeatDelay); 3723 prevIteration = _animationCycle(tween._tTime, repeatDelay); 3724 tween._yoyo && iteration & 1 && (ratio = 1 - ratio); 3725 3726 if (iteration !== prevIteration) { 3727 prevRatio = 1 - ratio; 3728 tween.vars.repeatRefresh && tween._initted && tween.invalidate(); 3729 } 3730 } 3731 3732 if (ratio !== prevRatio || force || tween._zTime === _tinyNum || !totalTime && tween._zTime) { 3733 if (!tween._initted && _attemptInitTween(tween, totalTime, force, suppressEvents)) { 3734 // if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately. 3735 return; 3736 } 3737 3738 prevIteration = tween._zTime; 3739 tween._zTime = totalTime || (suppressEvents ? _tinyNum : 0); // when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. 3740 3741 suppressEvents || (suppressEvents = totalTime && !prevIteration); // if it was rendered previously at exactly 0 (_zTime) and now the playhead is moving away, DON'T fire c
vendor: 11,087 bytes, lines 3741-4034
3741allbacks otherwise they'll seem like duplicates. 3742 3743 tween.ratio = ratio; 3744 tween._from && (ratio = 1 - ratio); 3745 tween._time = 0; 3746 tween._tTime = tTime; 3747 suppressEvents || _callback(tween, "onStart"); 3748 pt = tween._pt; 3749 3750 while (pt) { 3751 pt.r(ratio, pt.d); 3752 pt = pt._next; 3753 } 3754 3755 tween._startAt && totalTime < 0 && tween._startAt.render(totalTime, true, true); 3756 tween._onUpdate && !suppressEvents && _callback(tween, "onUpdate"); 3757 tTime && tween._repeat && !suppressEvents && tween.parent && _callback(tween, "onRepeat"); 3758 3759 if ((totalTime >= tween._tDur || totalTime < 0) && tween.ratio === ratio) { 3760 ratio && _removeFromParent(tween, 1); 3761 3762 if (!suppressEvents) { 3763 _callback(tween, ratio ? "onComplete" : "onReverseComplete", true); 3764 3765 tween._prom && tween._prom(); 3766 } 3767 } 3768 } else if (!tween._zTime) { 3769 tween._zTime = totalTime; 3770 } 3771}, 3772 _findNextPauseTween = function _findNextPauseTween(animation, prevTime, time) { 3773 var child; 3774 3775 if (time > prevTime) { 3776 child = animation._first; 3777 3778 while (child && child._start <= time) { 3779 if (!child._dur && child.data === "isPause" && child._start > prevTime) { 3780 return child; 3781 } 3782 3783 child = child._next; 3784 } 3785 } else { 3786 child = animation._last; 3787 3788 while (child && child._start >= time) { 3789 if (!child._dur && child.data === "isPause" && child._start < prevTime) { 3790 return child; 3791 } 3792 3793 child = child._prev; 3794 } 3795 } 3796}, 3797 _setDuration = function _setDuration(animation, duration, skipUncache, leavePlayhead) { 3798 var repeat = animation._repeat, 3799 dur = _round(duration) || 0, 3800 totalProgress = animation._tTime / animation._tDur; 3801 totalProgress && !leavePlayhead && (animation._time *= dur / animation._dur); 3802 animation._dur = dur; 3803 animation._tDur = !repeat ? dur : repeat < 0 ? 1e10 : _round(dur * (repeat + 1) + animation._rDelay * repeat); 3804 totalProgress && !leavePlayhead ? _alignPlayhead(animation, animation._tTime = animation._tDur * totalProgress) : animation.parent && _setEnd(animation); 3805 skipUncache || _uncache(animation.parent, animation); 3806 return animation; 3807}, 3808 _onUpdateTotalDuration = function _onUpdateTotalDuration(animation) { 3809 return animation instanceof Timeline ? _uncache(animation) : _setDuration(animation, animation._dur); 3810}, 3811 _zeroPosition = { 3812 _start: 0, 3813 endTime: _emptyFunc 3814}, 3815 _parsePosition = function _parsePosition(animation, position) { 3816 var labels = animation.labels, 3817 recent = animation._recent || _zeroPosition, 3818 clippedDuration = animation.duration() >= _bigNum ? recent.endTime(false) : animation._dur, 3819 //in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead. 3820 i, 3821 offset; 3822 3823 if (_isString(position) && (isNaN(position) || position in labels)) { 3824 //if the string is a number like "1", check to see if there's a label with that name, otherwise interpret it as a number (absolute value). 3825 i = position.charAt(0); 3826 3827 if (i === "<" || i === ">") { 3828 return (i === "<" ? recent._start : recent.endTime(recent._repeat >= 0)) + (parseFloat(position.substr(1)) || 0); 3829 } 3830 3831 i = position.indexOf("="); 3832 3833 if (i < 0) { 3834 position in labels || (labels[position] = clippedDuration); 3835 return labels[position]; 3836 } 3837 3838 offset = +(position.charAt(i - 1) + position.substr(i + 1)); 3839 return i > 1 ? _parsePosition(animation, position.substr(0, i - 1)) + offset : clippedDuration + offset; 3840 } 3841 3842 return position == null ? clippedDuration : +position; 3843}, 3844 _conditionalReturn = function _conditionalReturn(value, func) { 3845 return value || value === 0 ? func(value) : func; 3846}, 3847 _clamp = function _clamp(min, max, value) { 3848 return value < min ? min : value > max ? max : value; 3849}, 3850 getUnit = function getUnit(value) { 3851 if (typeof value !== "string") { 3852 return ""; 3853 } 3854 3855 var v = _unitExp.exec(value); 3856 3857 return v ? value.substr(v.index + v[0].length) : ""; 3858}, 3859 // note: protect against padded numbers as strings, like "100.100". That shouldn't return "00" as the unit. If it's numeric, return no unit. 3860clamp = function clamp(min, max, value) { 3861 return _conditionalReturn(value, function (v) { 3862 return _clamp(min, max, v); 3863 }); 3864}, 3865 _slice = [].slice, 3866 _isArrayLike = function _isArrayLike(value, nonEmpty) { 3867 return value && _isObject(value) && "length" in value && (!nonEmpty && !value.length || value.length - 1 in value && _isObject(value[0])) && !value.nodeType && value !== _win; 3868}, 3869 _flatten = function _flatten(ar, leaveStrings, accumulator) { 3870 if (accumulator === void 0) { 3871 accumulator = []; 3872 } 3873 3874 return ar.forEach(function (value) { 3875 var _accumulator; 3876 3877 return _isString(value) && !leaveStrings || _isArrayLike(value, 1) ? (_accumulator = accumulator).push.apply(_accumulator, toArray(value)) : accumulator.push(value); 3878 }) || accumulator; 3879}, 3880 //takes any value and returns an array. If it's a string (and leaveStrings isn't true), it'll use document.querySelectorAll() and convert that to an array. It'll also accept iterables like jQuery objects. 3881toArray = function toArray(value, leaveStrings) { 3882 return _isString(value) && !leaveStrings && (_coreInitted || !_wake()) ? _slice.call(_doc.querySelectorAll(value), 0) : _isArray(value) ? _flatten(value, leaveStrings) : _isArrayLike(value) ? _slice.call(value, 0) : value ? [value] : []; 3883}, 3884 shuffle = function shuffle(a) { 3885 return a.sort(function () { 3886 return .5 - Math.random(); 3887 }); 3888}, 3889 // alternative that's a bit faster and more reliably diverse but bigger: for (let j, v, i = a.length; i; j = Math.floor(Math.random() * i), v = a[--i], a[i] = a[j], a[j] = v); return a; 3890//for distributing values across an array. Can accept a number, a function or (most commonly) a function which can contain the following properties: {base, amount, from, ease, grid, axis, length, each}. Returns a function that expects the following parameters: index, target, array. Recognizes the following 3891distribute = function distribute(v) { 3892 if (_isFunction(v)) { 3893 return v; 3894 } 3895 3896 var vars = _isObject(v) ? v : { 3897 each: v 3898 }, 3899 //n:1 is just to indicate v was a number; we leverage that later to set v according to the length we get. If a number is passed in, we treat it like the old stagger value where 0.1, for example, would mean that things would be distributed with 0.1 between each element in the array rather than a total "amount" that's chunked out among them all. 3900 ease = _parseEase(vars.ease), 3901 from = vars.from || 0, 3902 base = parseFloat(vars.base) || 0, 3903 cache = {}, 3904 isDecimal = from > 0 && from < 1, 3905 ratios = isNaN(from) || isDecimal, 3906 axis = vars.axis, 3907 ratioX = from, 3908 ratioY = from; 3909 3910 if (_isString(from)) { 3911 ratioX = ratioY = { 3912 center: .5, 3913 edges: .5, 3914 end: 1 3915 }[from] || 0; 3916 } else if (!isDecimal && ratios) { 3917 ratioX = from[0]; 3918 ratioY = from[1]; 3919 } 3920 3921 return function (i, target, a) { 3922 var l = (a || vars).length, 3923 distances = cache[l], 3924 originX, 3925 originY, 3926 x, 3927 y, 3928 d, 3929 j, 3930 max, 3931 min, 3932 wrapAt; 3933 3934 if (!distances) { 3935 wrapAt = vars.grid === "auto" ? 0 : (vars.grid || [1, _bigNum])[1]; 3936 3937 if (!wrapAt) { 3938 max = -_bigNum; 3939 3940 while (max < (max = a[wrapAt++].getBoundingClientRect().left) && wrapAt < l) {} 3941 3942 wrapAt--; 3943 } 3944 3945 distances = cache[l] = []; 3946 originX = ratios ? Math.min(wrapAt, l) * ratioX - .5 : from % wrapAt; 3947 originY = ratios ? l * ratioY / wrapAt - .5 : from / wrapAt | 0; 3948 max = 0; 3949 min = _bigNum; 3950 3951 for (j = 0; j < l; j++) { 3952 x = j % wrapAt - originX; 3953 y = originY - (j / wrapAt | 0); 3954 distances[j] = d = !axis ? _sqrt(x * x + y * y) : Math.abs(axis === "y" ? y : x); 3955 d > max && (max = d); 3956 d < min && (min = d); 3957 } 3958 3959 from === "random" && shuffle(distances); 3960 distances.max = max - min; 3961 distances.min = min; 3962 distances.v = l = (parseFloat(vars.amount) || parseFloat(vars.each) * (wrapAt > l ? l - 1 : !axis ? Math.max(wrapAt, l / wrapAt) : axis === "y" ? l / wrapAt : wrapAt) || 0) * (from === "edges" ? -1 : 1); 3963 distances.b = l < 0 ? base - l : base; 3964 distances.u = getUnit(vars.amount || vars.each) || 0; //unit 3965 3966 ease = ease && l < 0 ? _invertEase(ease) : ease; 3967 } 3968 3969 l = (distances[i] - distances.min) / distances.max || 0; 3970 return _round(distances.b + (ease ? ease(l) : l) * distances.v) + distances.u; //round in order to work around floating point errors 3971 }; 3972}, 3973 _roundModifier = function _roundModifier(v) { 3974 //pass in 0.1 get a function that'll round to the nearest tenth, or 5 to round to the closest 5, or 0.001 to the closest 1000th, etc. 3975 var p = v < 1 ? Math.pow(10, (v + "").length - 2) : 1; //to avoid floating point math errors (like 24 * 0.1 == 2.4000000000000004), we chop off at a specific number of decimal places (much faster than toFixed() 3976 3977 return function (raw) { 3978 var n = Math.round(parseFloat(raw) / v) * v * p; 3979 return (n - n % 1) / p + (_isNumber(raw) ? 0 : getUnit(raw)); // n - n % 1 replaces Math.floor() in order to handle negative values properly. For example, Math.floor(-150.00000000000003) is 151! 3980 }; 3981}, 3982 snap = function snap(snapTo, value) { 3983 var isArray = _isArray(snapTo), 3984 radius, 3985 is2D; 3986 3987 if (!isArray && _isObject(snapTo)) { 3988 radius = isArray = snapTo.radius || _bigNum; 3989 3990 if (snapTo.values) { 3991 snapTo = toArray(snapTo.values); 3992 3993 if (is2D = !_isNumber(snapTo[0])) { 3994 radius *= radius; //performance optimization so we don't have to Math.sqrt() in the loop. 3995 } 3996 } else { 3997 snapTo = _roundModifier(snapTo.increment); 3998 } 3999 } 4000 4001 return _conditionalReturn(value, !isArray ? _roundModifier(snapTo) : _isFunction(snapTo) ? function (raw) { 4002 is2D = snapTo(raw); 4003 return Math.abs(is2D - raw) <= radius ? is2D : raw; 4004 } : function (raw) { 4005 var x = parseFloat(is2D ? raw.x : raw), 4006 y = parseFloat(is2D ? raw.y : 0), 4007 min = _bigNum, 4008 closest = 0, 4009 i = snapTo.length, 4010 dx, 4011 dy; 4012 4013 while (i--) { 4014 if (is2D) { 4015 dx = snapTo[i].x - x; 4016 dy = snapTo[i].y - y; 4017 dx = dx * dx + dy * dy; 4018 } else { 4019 dx = Math.abs(snapTo[i] - x); 4020 } 4021 4022 if (dx < min) { 4023 min = dx; 4024 closest = i; 4025 } 4026 } 4027 4028 closest = !radius || min <= radius ? snapTo[closest] : raw; 4029 return is2D || closest === raw || _isNumber(raw) ? closest : closest + getUnit(raw); 4030 }); 4031}, 4032 random = function random(min, max, roundingIncrement, returnFunction) { 4033 return _conditionalReturn(_isArray(min) ? !max : roundingIncrement === true ? !!(roundingIncrement = 0) : !returnFunction, function () { 4034 return _isArray(min) ? min[~~(Math.random() * min.length)] : (roundingIncrement = roundingIncrement || 1e
vendor: 5,141 bytes, lines 4034-4194
4034-5) && (returnFunction = roundingIncrement < 1 ? Math.pow(10, (roundingIncrement + "").length - 2) : 1) && Math.floor(Math.round((min - roundingIncrement / 2 + Math.random() * (max - min + roundingIncrement * .99)) / roundingIncrement) * roundingIncrement * returnFunction) / returnFunction; 4035 }); 4036}, 4037 pipe = function pipe() { 4038 for (var _len = arguments.length, functions = new Array(_len), _key = 0; _key < _len; _key++) { 4039 functions[_key] = arguments[_key]; 4040 } 4041 4042 return function (value) { 4043 return functions.reduce(function (v, f) { 4044 return f(v); 4045 }, value); 4046 }; 4047}, 4048 unitize = function unitize(func, unit) { 4049 return function (value) { 4050 return func(parseFloat(value)) + (unit || getUnit(value)); 4051 }; 4052}, 4053 normalize = function normalize(min, max, value) { 4054 return mapRange(min, max, 0, 1, value); 4055}, 4056 _wrapArray = function _wrapArray(a, wrapper, value) { 4057 return _conditionalReturn(value, function (index) { 4058 return a[~~wrapper(index)]; 4059 }); 4060}, 4061 wrap = function wrap(min, max, value) { 4062 // NOTE: wrap() CANNOT be an arrow function! A very odd compiling bug causes problems (unrelated to GSAP). 4063 var range = max - min; 4064 return _isArray(min) ? _wrapArray(min, wrap(0, min.length), max) : _conditionalReturn(value, function (value) { 4065 return (range + (value - min) % range) % range + min; 4066 }); 4067}, 4068 wrapYoyo = function wrapYoyo(min, max, value) { 4069 var range = max - min, 4070 total = range * 2; 4071 return _isArray(min) ? _wrapArray(min, wrapYoyo(0, min.length - 1), max) : _conditionalReturn(value, function (value) { 4072 value = (total + (value - min) % total) % total || 0; 4073 return min + (value > range ? total - value : value); 4074 }); 4075}, 4076 _replaceRandom = function _replaceRandom(value) { 4077 //replaces all occurrences of random(...) in a string with the calculated random value. can be a range like random(-100, 100, 5) or an array like random([0, 100, 500]) 4078 var prev = 0, 4079 s = "", 4080 i, 4081 nums, 4082 end, 4083 isArray; 4084 4085 while (~(i = value.indexOf("random(", prev))) { 4086 end = value.indexOf(")", i); 4087 isArray = value.charAt(i + 7) === "["; 4088 nums = value.substr(i + 7, end - i - 7).match(isArray ? _delimitedValueExp : _strictNumExp); 4089 s += value.substr(prev, i - prev) + random(isArray ? nums : +nums[0], isArray ? 0 : +nums[1], +nums[2] || 1e-5); 4090 prev = end + 1; 4091 } 4092 4093 return s + value.substr(prev, value.length - prev); 4094}, 4095 mapRange = function mapRange(inMin, inMax, outMin, outMax, value) { 4096 var inRange = inMax - inMin, 4097 outRange = outMax - outMin; 4098 return _conditionalReturn(value, function (value) { 4099 return outMin + ((value - inMin) / inRange * outRange || 0); 4100 }); 4101}, 4102 interpolate = function interpolate(start, end, progress, mutate) { 4103 var func = isNaN(start + end) ? 0 : function (p) { 4104 return (1 - p) * start + p * end; 4105 }; 4106 4107 if (!func) { 4108 var isString = _isString(start), 4109 master = {}, 4110 p, 4111 i, 4112 interpolators, 4113 l, 4114 il; 4115 4116 progress === true && (mutate = 1) && (progress = null); 4117 4118 if (isString) { 4119 start = { 4120 p: start 4121 }; 4122 end = { 4123 p: end 4124 }; 4125 } else if (_isArray(start) && !_isArray(end)) { 4126 interpolators = []; 4127 l = start.length; 4128 il = l - 2; 4129 4130 for (i = 1; i < l; i++) { 4131 interpolators.push(interpolate(start[i - 1], start[i])); //build the interpolators up front as a performance optimization so that when the function is called many times, it can just reuse them. 4132 } 4133 4134 l--; 4135 4136 func = function func(p) { 4137 p *= l; 4138 var i = Math.min(il, ~~p); 4139 return interpolators[i](p - i); 4140 }; 4141 4142 progress = end; 4143 } else if (!mutate) { 4144 start = _merge(_isArray(start) ? [] : {}, start); 4145 } 4146 4147 if (!interpolators) { 4148 for (p in end) { 4149 _addPropTween.call(master, start, p, "get", end[p]); 4150 } 4151 4152 func = function func(p) { 4153 return _renderPropTweens(p, master) || (isString ? start.p : start); 4154 }; 4155 } 4156 } 4157 4158 return _conditionalReturn(progress, func); 4159}, 4160 _getLabelInDirection = function _getLabelInDirection(timeline, fromTime, backward) { 4161 //used for nextLabel() and previousLabel() 4162 var labels = timeline.labels, 4163 min = _bigNum, 4164 p, 4165 distance, 4166 label; 4167 4168 for (p in labels) { 4169 distance = labels[p] - fromTime; 4170 4171 if (distance < 0 === !!backward && distance && min > (distance = Math.abs(distance))) { 4172 label = p; 4173 min = distance; 4174 } 4175 } 4176 4177 return label; 4178}, 4179 _callback = function _callback(animation, type, executeLazyFirst) { 4180 var v = animation.vars, 4181 callback = v[type], 4182 params, 4183 scope; 4184 4185 if (!callback) { 4186 return; 4187 } 4188 4189 params = v[type + "Params"]; 4190 scope = v.callbackScope || animation; 4191 executeLazyFirst && _lazyTweens.length && _lazyRender(); //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values. 4192 4193 return params ? callback.apply(scope, params) : callback.call(scope); 4194},
vendor: 2,477 bytes, lines 4195-4284
4195 _interrupt = function _interrupt(animation) { 4196 _removeFromParent(animation); 4197 4198 animation.progress() < 1 && _callback(animation, "onInterrupt"); 4199 return animation; 4200}, 4201 _quickTween, 4202 _createPlugin = function _createPlugin(config) { 4203 config = !config.name && config["default"] || config; //UMD packaging wraps things oddly, so for example MotionPathHelper becomes {MotionPathHelper:MotionPathHelper, default:MotionPathHelper}. 4204 4205 var name = config.name, 4206 isFunc = _isFunction(config), 4207 Plugin = name && !isFunc && config.init ? function () { 4208 this._props = []; 4209 } : config, 4210 //in case someone passes in an object that's not a plugin, like CustomEase 4211 instanceDefaults = { 4212 init: _emptyFunc, 4213 render: _renderPropTweens, 4214 add: _addPropTween, 4215 kill: _killPropTweensOf, 4216 modifier: _addPluginModifier, 4217 rawVars: 0 4218 }, 4219 statics = { 4220 targetTest: 0, 4221 get: 0, 4222 getSetter: _getSetter, 4223 aliases: {}, 4224 register: 0 4225 }; 4226 4227 _wake(); 4228 4229 if (config !== Plugin) { 4230 if (_plugins[name]) { 4231 return; 4232 } 4233 4234 _setDefaults(Plugin, _setDefaults(_copyExcluding(config, instanceDefaults), statics)); //static methods 4235 4236 4237 _merge(Plugin.prototype, _merge(instanceDefaults, _copyExcluding(config, statics))); //instance methods 4238 4239 4240 _plugins[Plugin.prop = name] = Plugin; 4241 4242 if (config.targetTest) { 4243 _harnessPlugins.push(Plugin); 4244 4245 _reservedProps[name] = 1; 4246 } 4247 4248 name = (name === "css" ? "CSS" : name.charAt(0).toUpperCase() + name.substr(1)) + "Plugin"; //for the global name. "motionPath" should become MotionPathPlugin 4249 } 4250 4251 _addGlobal(name, Plugin); 4252 4253 config.register && config.register(gsap, Plugin, PropTween); 4254}, 4255 4256/* 4257 * -------------------------------------------------------------------------------------- 4258 * COLORS 4259 * -------------------------------------------------------------------------------------- 4260 */ 4261_255 = 255, 4262 _colorLookup = { 4263 aqua: [0, _255, _255], 4264 lime: [0, _255, 0], 4265 silver: [192, 192, 192], 4266 black: [0, 0, 0], 4267 maroon: [128, 0, 0], 4268 teal: [0, 128, 128], 4269 blue: [0, 0, _255], 4270 navy: [0, 0, 128], 4271 white: [_255, _255, _255], 4272 olive: [128, 128, 0], 4273 yellow: [_255, _255, 0], 4274 orange: [_255, 165, 0], 4275 gray: [128, 128, 128], 4276 purple: [128, 0, 128], 4277 green: [0, 128, 0], 4278 red: [_255, 0, 0], 4279 pink: [_255, 192, 203], 4280 cyan: [0, _255, _255], 4281 transparent: [_255, _255, _255, 0] 4282}, 4283 _hue = function _hue(h, m1, m2) { 4284 h = h < 0 ? h + 1 : h > 1 ? h - 1 : h
vendor: 6,261 bytes, lines 4284-4488
4284; 4285 return (h * 6 < 1 ? m1 + (m2 - m1) * h * 6 : h < .5 ? m2 : h * 3 < 2 ? m1 + (m2 - m1) * (2 / 3 - h) * 6 : m1) * _255 + .5 | 0; 4286}, 4287 splitColor = function splitColor(v, toHSL, forceAlpha) { 4288 var a = !v ? _colorLookup.black : _isNumber(v) ? [v >> 16, v >> 8 & _255, v & _255] : 0, 4289 r, 4290 g, 4291 b, 4292 h, 4293 s, 4294 l, 4295 max, 4296 min, 4297 d, 4298 wasHSL; 4299 4300 if (!a) { 4301 if (v.substr(-1) === ",") { 4302 //sometimes a trailing comma is included and we should chop it off (typically from a comma-delimited list of values like a textShadow:"2px 2px 2px blue, 5px 5px 5px rgb(255,0,0)" - in this example "blue," has a trailing comma. We could strip it out inside parseComplex() but we'd need to do it to the beginning and ending values plus it wouldn't provide protection from other potential scenarios like if the user passes in a similar value. 4303 v = v.substr(0, v.length - 1); 4304 } 4305 4306 if (_colorLookup[v]) { 4307 a = _colorLookup[v]; 4308 } else if (v.charAt(0) === "#") { 4309 if (v.length < 6) { 4310 //for shorthand like #9F0 or #9F0F (could have alpha) 4311 r = v.charAt(1); 4312 g = v.charAt(2); 4313 b = v.charAt(3); 4314 v = "#" + r + r + g + g + b + b + (v.length === 5 ? v.charAt(4) + v.charAt(4) : ""); 4315 } 4316 4317 if (v.length === 9) { 4318 // hex with alpha, like #fd5e53ff 4319 a = parseInt(v.substr(1, 6), 16); 4320 return [a >> 16, a >> 8 & _255, a & _255, parseInt(v.substr(7), 16) / 255]; 4321 } 4322 4323 v = parseInt(v.substr(1), 16); 4324 a = [v >> 16, v >> 8 & _255, v & _255]; 4325 } else if (v.substr(0, 3) === "hsl") { 4326 a = wasHSL = v.match(_strictNumExp); 4327 4328 if (!toHSL) { 4329 h = +a[0] % 360 / 360; 4330 s = +a[1] / 100; 4331 l = +a[2] / 100; 4332 g = l <= .5 ? l * (s + 1) : l + s - l * s; 4333 r = l * 2 - g; 4334 a.length > 3 && (a[3] *= 1); //cast as number 4335 4336 a[0] = _hue(h + 1 / 3, r, g); 4337 a[1] = _hue(h, r, g); 4338 a[2] = _hue(h - 1 / 3, r, g); 4339 } else if (~v.indexOf("=")) { 4340 //if relative values are found, just return the raw strings with the relative prefixes in place. 4341 a = v.match(_numExp); 4342 forceAlpha && a.length < 4 && (a[3] = 1); 4343 return a; 4344 } 4345 } else { 4346 a = v.match(_strictNumExp) || _colorLookup.transparent; 4347 } 4348 4349 a = a.map(Number); 4350 } 4351 4352 if (toHSL && !wasHSL) { 4353 r = a[0] / _255; 4354 g = a[1] / _255; 4355 b = a[2] / _255; 4356 max = Math.max(r, g, b); 4357 min = Math.min(r, g, b); 4358 l = (max + min) / 2; 4359 4360 if (max === min) { 4361 h = s = 0; 4362 } else { 4363 d = max - min; 4364 s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 4365 h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4; 4366 h *= 60; 4367 } 4368 4369 a[0] = ~~(h + .5); 4370 a[1] = ~~(s * 100 + .5); 4371 a[2] = ~~(l * 100 + .5); 4372 } 4373 4374 forceAlpha && a.length < 4 && (a[3] = 1); 4375 return a; 4376}, 4377 _colorOrderData = function _colorOrderData(v) { 4378 // strips out the colors from the string, finds all the numeric slots (with units) and returns an array of those. The Array also has a "c" property which is an Array of the index values where the colors belong. This is to help work around issues where there's a mis-matched order of color/numeric data like drop-shadow(#f00 0px 1px 2px) and drop-shadow(0x 1px 2px #f00). This is basically a helper function used in _formatColors() 4379 var values = [], 4380 c = [], 4381 i = -1; 4382 v.split(_colorExp).forEach(function (v) { 4383 var a = v.match(_numWithUnitExp) || []; 4384 values.push.apply(values, a); 4385 c.push(i += a.length + 1); 4386 }); 4387 values.c = c; 4388 return values; 4389}, 4390 _formatColors = function _formatColors(s, toHSL, orderMatchData) { 4391 var result = "", 4392 colors = (s + result).match(_colorExp), 4393 type = toHSL ? "hsla(" : "rgba(", 4394 i = 0, 4395 c, 4396 shell, 4397 d, 4398 l; 4399 4400 if (!colors) { 4401 return s; 4402 } 4403 4404 colors = colors.map(function (color) { 4405 return (color = splitColor(color, toHSL, 1)) && type + (toHSL ? color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : color.join(",")) + ")"; 4406 }); 4407 4408 if (orderMatchData) { 4409 d = _colorOrderData(s); 4410 c = orderMatchData.c; 4411 4412 if (c.join(result) !== d.c.join(result)) { 4413 shell = s.replace(_colorExp, "1").split(_numWithUnitExp); 4414 l = shell.length - 1; 4415 4416 for (; i < l; i++) { 4417 result += shell[i] + (~c.indexOf(i) ? colors.shift() || type + "0,0,0,0)" : (d.length ? d : colors.length ? colors : orderMatchData).shift()); 4418 } 4419 } 4420 } 4421 4422 if (!shell) { 4423 shell = s.split(_colorExp); 4424 l = shell.length - 1; 4425 4426 for (; i < l; i++) { 4427 result += shell[i] + colors[i]; 4428 } 4429 } 4430 4431 return result + shell[l]; 4432}, 4433 _colorExp = function () { 4434 var s = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3,4}){1,2}\\b", 4435 //we'll dynamically build this Regular Expression to conserve file size. After building it, it will be able to find rgb(), rgba(), # (hexadecimal), and named color values like red, blue, purple, etc., 4436 p; 4437 4438 for (p in _colorLookup) { 4439 s += "|" + p + "\\b"; 4440 } 4441 4442 return new RegExp(s + ")", "gi"); 4443}(), 4444 _hslExp = /hsl[a]?\(/, 4445 _colorStringFilter = function _colorStringFilter(a) { 4446 var combined = a.join(" "), 4447 toHSL; 4448 _colorExp.lastIndex = 0; 4449 4450 if (_colorExp.test(combined)) { 4451 toHSL = _hslExp.test(combined); 4452 a[1] = _formatColors(a[1], toHSL); 4453 a[0] = _formatColors(a[0], toHSL, _colorOrderData(a[1])); // make sure the order of numbers/colors match with the END value. 4454 4455 return true; 4456 } 4457}, 4458 4459/* 4460 * -------------------------------------------------------------------------------------- 4461 * TICKER 4462 * -------------------------------------------------------------------------------------- 4463 */ 4464_tickerActive, 4465 _ticker = function () { 4466 var _getTime = Date.now, 4467 _lagThreshold = 500, 4468 _adjustedLag = 33, 4469 _startTime = _getTime(), 4470 _lastUpdate = _startTime, 4471 _gap = 1000 / 240, 4472 _nextTime = _gap, 4473 _listeners = [], 4474 _id, 4475 _req, 4476 _raf, 4477 _self, 4478 _delta, 4479 _i, 4480 _tick = function _tick(v) { 4481 var elapsed = _getTime() - _lastUpdate, 4482 manual = v === true, 4483 overlap, 4484 dispatch, 4485 time, 4486 frame; 4487 4488
vendor: 4,012 bytes, lines 4488-4607
4488elapsed > _lagThreshold && (_startTime += elapsed - _adjustedLag); 4489 _lastUpdate += elapsed; 4490 time = _lastUpdate - _startTime; 4491 overlap = time - _nextTime; 4492 4493 if (overlap > 0 || manual) { 4494 frame = ++_self.frame; 4495 _delta = time - _self.time * 1000; 4496 _self.time = time = time / 1000; 4497 _nextTime += overlap + (overlap >= _gap ? 4 : _gap - overlap); 4498 dispatch = 1; 4499 } 4500 4501 manual || (_id = _req(_tick)); //make sure the request is made before we dispatch the "tick" event so that timing is maintained. Otherwise, if processing the "tick" requires a bunch of time (like 15ms) and we're using a setTimeout() that's based on 16.7ms, it'd technically take 31.7ms between frames otherwise. 4502 4503 if (dispatch) { 4504 for (_i = 0; _i < _listeners.length; _i++) { 4505 // use _i and check _listeners.length instead of a variable because a listener could get removed during the loop, and if that happens to an element less than the current index, it'd throw things off in the loop. 4506 _listeners[_i](time, _delta, frame, v); 4507 } 4508 } 4509 }; 4510 4511 _self = { 4512 time: 0, 4513 frame: 0, 4514 tick: function tick() { 4515 _tick(true); 4516 }, 4517 deltaRatio: function deltaRatio(fps) { 4518 return _delta / (1000 / (fps || 60)); 4519 }, 4520 wake: function wake() { 4521 if (_coreReady) { 4522 if (!_coreInitted && _windowExists()) { 4523 _win = _coreInitted = window; 4524 _doc = _win.document || {}; 4525 _globals.gsap = gsap; 4526 (_win.gsapVersions || (_win.gsapVersions = [])).push(gsap.version); 4527 4528 _install(_installScope || _win.GreenSockGlobals || !_win.gsap && _win || {}); 4529 4530 _raf = _win.requestAnimationFrame; 4531 } 4532 4533 _id && _self.sleep(); 4534 4535 _req = _raf || function (f) { 4536 return setTimeout(f, _nextTime - _self.time * 1000 + 1 | 0); 4537 }; 4538 4539 _tickerActive = 1; 4540 4541 _tick(2); 4542 } 4543 }, 4544 sleep: function sleep() { 4545 (_raf ? _win.cancelAnimationFrame : clearTimeout)(_id); 4546 _tickerActive = 0; 4547 _req = _emptyFunc; 4548 }, 4549 lagSmoothing: function lagSmoothing(threshold, adjustedLag) { 4550 _lagThreshold = threshold || 1 / _tinyNum; //zero should be interpreted as basically unlimited 4551 4552 _adjustedLag = Math.min(adjustedLag, _lagThreshold, 0); 4553 }, 4554 fps: function fps(_fps) { 4555 _gap = 1000 / (_fps || 240); 4556 _nextTime = _self.time * 1000 + _gap; 4557 }, 4558 add: function add(callback) { 4559 _listeners.indexOf(callback) < 0 && _listeners.push(callback); 4560 4561 _wake(); 4562 }, 4563 remove: function remove(callback) { 4564 var i; 4565 ~(i = _listeners.indexOf(callback)) && _listeners.splice(i, 1) && _i >= i && _i--; 4566 }, 4567 _listeners: _listeners 4568 }; 4569 return _self; 4570}(), 4571 _wake = function _wake() { 4572 return !_tickerActive && _ticker.wake(); 4573}, 4574 //also ensures the core classes are initialized. 4575 4576/* 4577* ------------------------------------------------- 4578* EASING 4579* ------------------------------------------------- 4580*/ 4581_easeMap = {}, 4582 _customEaseExp = /^[\d.\-M][\d.\-,\s]/, 4583 _quotesExp = /["']/g, 4584 _parseObjectInString = function _parseObjectInString(value) { 4585 //takes a string like "{wiggles:10, type:anticipate})" and turns it into a real object. Notice it ends in ")" and includes the {} wrappers. This is because we only use this function for parsing ease configs and prioritized optimization rather than reusability. 4586 var obj = {}, 4587 split = value.substr(1, value.length - 3).split(":"), 4588 key = split[0], 4589 i = 1, 4590 l = split.length, 4591 index, 4592 val, 4593 parsedVal; 4594 4595 for (; i < l; i++) { 4596 val = split[i]; 4597 index = i !== l - 1 ? val.lastIndexOf(",") : val.length; 4598 parsedVal = val.substr(0, index); 4599 obj[key] = isNaN(parsedVal) ? parsedVal.replace(_quotesExp, "").trim() : +parsedVal; 4600 key = val.substr(index + 1).trim(); 4601 } 4602 4603 return obj; 4604}, 4605 _valueInParentheses = function _valueInParentheses(value) { 4606 var open = value.indexOf("(") + 1, 4607 close = value.indexOf(")"),
vendor: 5,237 bytes, lines 4608-4750
4608 nested = value.indexOf("(", open); 4609 return value.substring(open, ~nested && nested < close ? value.indexOf(")", close + 1) : close); 4610}, 4611 _configEaseFromString = function _configEaseFromString(name) { 4612 //name can be a string like "elastic.out(1,0.5)", and pass in _easeMap as obj and it'll parse it out and call the actual function like _easeMap.Elastic.easeOut.config(1,0.5). It will also parse custom ease strings as long as CustomEase is loaded and registered (internally as _easeMap._CE). 4613 var split = (name + "").split("("), 4614 ease = _easeMap[split[0]]; 4615 return ease && split.length > 1 && ease.config ? ease.config.apply(null, ~name.indexOf("{") ? [_parseObjectInString(split[1])] : _valueInParentheses(name).split(",").map(_numericIfPossible)) : _easeMap._CE && _customEaseExp.test(name) ? _easeMap._CE("", name) : ease; 4616}, 4617 _invertEase = function _invertEase(ease) { 4618 return function (p) { 4619 return 1 - ease(1 - p); 4620 }; 4621}, 4622 // allow yoyoEase to be set in children and have those affected when the parent/ancestor timeline yoyos. 4623_propagateYoyoEase = function _propagateYoyoEase(timeline, isYoyo) { 4624 var child = timeline._first, 4625 ease; 4626 4627 while (child) { 4628 if (child instanceof Timeline) { 4629 _propagateYoyoEase(child, isYoyo); 4630 } else if (child.vars.yoyoEase && (!child._yoyo || !child._repeat) && child._yoyo !== isYoyo) { 4631 if (child.timeline) { 4632 _propagateYoyoEase(child.timeline, isYoyo); 4633 } else { 4634 ease = child._ease; 4635 child._ease = child._yEase; 4636 child._yEase = ease; 4637 child._yoyo = isYoyo; 4638 } 4639 } 4640 4641 child = child._next; 4642 } 4643}, 4644 _parseEase = function _parseEase(ease, defaultEase) { 4645 return !ease ? defaultEase : (_isFunction(ease) ? ease : _easeMap[ease] || _configEaseFromString(ease)) || defaultEase; 4646}, 4647 _insertEase = function _insertEase(names, easeIn, easeOut, easeInOut) { 4648 if (easeOut === void 0) { 4649 easeOut = function easeOut(p) { 4650 return 1 - easeIn(1 - p); 4651 }; 4652 } 4653 4654 if (easeInOut === void 0) { 4655 easeInOut = function easeInOut(p) { 4656 return p < .5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2; 4657 }; 4658 } 4659 4660 var ease = { 4661 easeIn: easeIn, 4662 easeOut: easeOut, 4663 easeInOut: easeInOut 4664 }, 4665 lowercaseName; 4666 4667 _forEachName(names, function (name) { 4668 _easeMap[name] = _globals[name] = ease; 4669 _easeMap[lowercaseName = name.toLowerCase()] = easeOut; 4670 4671 for (var p in ease) { 4672 _easeMap[lowercaseName + (p === "easeIn" ? ".in" : p === "easeOut" ? ".out" : ".inOut")] = _easeMap[name + "." + p] = ease[p]; 4673 } 4674 }); 4675 4676 return ease; 4677}, 4678 _easeInOutFromOut = function _easeInOutFromOut(easeOut) { 4679 return function (p) { 4680 return p < .5 ? (1 - easeOut(1 - p * 2)) / 2 : .5 + easeOut((p - .5) * 2) / 2; 4681 }; 4682}, 4683 _configElastic = function _configElastic(type, amplitude, period) { 4684 var p1 = amplitude >= 1 ? amplitude : 1, 4685 //note: if amplitude is < 1, we simply adjust the period for a more natural feel. Otherwise the math doesn't work right and the curve starts at 1. 4686 p2 = (period || (type ? .3 : .45)) / (amplitude < 1 ? amplitude : 1), 4687 p3 = p2 / _2PI * (Math.asin(1 / p1) || 0), 4688 easeOut = function easeOut(p) { 4689 return p === 1 ? 1 : p1 * Math.pow(2, -10 * p) * _sin((p - p3) * p2) + 1; 4690 }, 4691 ease = type === "out" ? easeOut : type === "in" ? function (p) { 4692 return 1 - easeOut(1 - p); 4693 } : _easeInOutFromOut(easeOut); 4694 4695 p2 = _2PI / p2; //precalculate to optimize 4696 4697 ease.config = function (amplitude, period) { 4698 return _configElastic(type, amplitude, period); 4699 }; 4700 4701 return ease; 4702}, 4703 _configBack = function _configBack(type, overshoot) { 4704 if (overshoot === void 0) { 4705 overshoot = 1.70158; 4706 } 4707 4708 var easeOut = function easeOut(p) { 4709 return p ? --p * p * ((overshoot + 1) * p + overshoot) + 1 : 0; 4710 }, 4711 ease = type === "out" ? easeOut : type === "in" ? function (p) { 4712 return 1 - easeOut(1 - p); 4713 } : _easeInOutFromOut(easeOut); 4714 4715 ease.config = function (overshoot) { 4716 return _configBack(type, overshoot); 4717 }; 4718 4719 return ease; 4720}; // a cheaper (kb and cpu) but more mild way to get a parameterized weighted ease by feeding in a value between -1 (easeIn) and 1 (easeOut) where 0 is linear. 4721// _weightedEase = ratio => { 4722// let y = 0.5 + ratio / 2; 4723// return p => (2 * (1 - p) * p * y + p * p); 4724// }, 4725// a stronger (but more expensive kb/cpu) parameterized weighted ease that lets you feed in a value between -1 (easeIn) and 1 (easeOut) where 0 is linear. 4726// _weightedEaseStrong = ratio => { 4727// ratio = .5 + ratio / 2; 4728// let o = 1 / 3 * (ratio < .5 ? ratio : 1 - ratio), 4729// b = ratio - o, 4730// c = ratio + o; 4731// return p => p === 1 ? p : 3 * b * (1 - p) * (1 - p) * p + 3 * c * (1 - p) * p * p + p * p * p; 4732// }; 4733 4734 4735_forEachName("Linear,Quad,Cubic,Quart,Quint,Strong", function (name, i) { 4736 var power = i < 5 ? i + 1 : i; 4737 4738 _insertEase(name + ",Power" + (power - 1), i ? function (p) { 4739 return Math.pow(p, power); 4740 } : function (p) { 4741 return p; 4742 }, function (p) { 4743 return 1 - Math.pow(1 - p, power); 4744 }, function (p) { 4745 return p < .5 ? Math.pow(p * 2, power) / 2 : 1 - Math.pow((1 - p) * 2, power) / 2; 4746 }); 4747}); 4748 4749_easeMap.Linear.easeNone = _easeMap.none = _easeMap.Linear.easeIn; 4750
vendor: 4,245 bytes, lines 4751-4882
4751_insertEase("Elastic", _configElastic("in"), _configElastic("out"), _configElastic()); 4752 4753(function (n, c) { 4754 var n1 = 1 / c, 4755 n2 = 2 * n1, 4756 n3 = 2.5 * n1, 4757 easeOut = function easeOut(p) { 4758 return p < n1 ? n * p * p : p < n2 ? n * Math.pow(p - 1.5 / c, 2) + .75 : p < n3 ? n * (p -= 2.25 / c) * p + .9375 : n * Math.pow(p - 2.625 / c, 2) + .984375; 4759 }; 4760 4761 _insertEase("Bounce", function (p) { 4762 return 1 - easeOut(1 - p); 4763 }, easeOut); 4764})(7.5625, 2.75); 4765 4766_insertEase("Expo", function (p) { 4767 return p ? Math.pow(2, 10 * (p - 1)) : 0; 4768}); 4769 4770_insertEase("Circ", function (p) { 4771 return -(_sqrt(1 - p * p) - 1); 4772}); 4773 4774_insertEase("Sine", function (p) { 4775 return p === 1 ? 1 : -_cos(p * _HALF_PI) + 1; 4776}); 4777 4778_insertEase("Back", _configBack("in"), _configBack("out"), _configBack()); 4779 4780_easeMap.SteppedEase = _easeMap.steps = _globals.SteppedEase = { 4781 config: function config(steps, immediateStart) { 4782 if (steps === void 0) { 4783 steps = 1; 4784 } 4785 4786 var p1 = 1 / steps, 4787 p2 = steps + (immediateStart ? 0 : 1), 4788 p3 = immediateStart ? 1 : 0, 4789 max = 1 - _tinyNum; 4790 return function (p) { 4791 return ((p2 * _clamp(0, max, p) | 0) + p3) * p1; 4792 }; 4793 } 4794}; 4795_defaults.ease = _easeMap["quad.out"]; 4796 4797_forEachName("onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt", function (name) { 4798 return _callbackNames += name + "," + name + "Params,"; 4799}); 4800/* 4801 * -------------------------------------------------------------------------------------- 4802 * CACHE 4803 * -------------------------------------------------------------------------------------- 4804 */ 4805 4806 4807var GSCache = function GSCache(target, harness) { 4808 this.id = _gsID++; 4809 target._gsap = this; 4810 this.target = target; 4811 this.harness = harness; 4812 this.get = harness ? harness.get : _getProperty; 4813 this.set = harness ? harness.getSetter : _getSetter; 4814}; 4815/* 4816 * -------------------------------------------------------------------------------------- 4817 * ANIMATION 4818 * -------------------------------------------------------------------------------------- 4819 */ 4820 4821var Animation = /*#__PURE__*/function () { 4822 function Animation(vars, time) { 4823 var parent = vars.parent || _globalTimeline; 4824 this.vars = vars; 4825 this._delay = +vars.delay || 0; 4826 4827 if (this._repeat = vars.repeat === Infinity ? -2 : vars.repeat || 0) { 4828 // TODO: repeat: Infinity on a timeline's children must flag that timeline internally and affect its totalDuration, otherwise it'll stop in the negative direction when reaching the start. 4829 this._rDelay = vars.repeatDelay || 0; 4830 this._yoyo = !!vars.yoyo || !!vars.yoyoEase; 4831 } 4832 4833 this._ts = 1; 4834 4835 _setDuration(this, +vars.duration, 1, 1); 4836 4837 this.data = vars.data; 4838 _tickerActive || _ticker.wake(); 4839 parent && _addToTimeline(parent, this, time || time === 0 ? time : parent._time, 1); 4840 vars.reversed && this.reverse(); 4841 vars.paused && this.paused(true); 4842 } 4843 4844 var _proto = Animation.prototype; 4845 4846 _proto.delay = function delay(value) { 4847 if (value || value === 0) { 4848 this.parent && this.parent.smoothChildTiming && this.startTime(this._start + value - this._delay); 4849 this._delay = value; 4850 return this; 4851 } 4852 4853 return this._delay; 4854 }; 4855 4856 _proto.duration = function duration(value) { 4857 return arguments.length ? this.totalDuration(this._repeat > 0 ? value + (value + this._rDelay) * this._repeat : value) : this.totalDuration() && this._dur; 4858 }; 4859 4860 _proto.totalDuration = function totalDuration(value) { 4861 if (!arguments.length) { 4862 return this._tDur; 4863 } 4864 4865 this._dirty = 0; 4866 return _setDuration(this, this._repeat < 0 ? value : (value - this._repeat * this._rDelay) / (this._repeat + 1)); 4867 }; 4868 4869 _proto.totalTime = function totalTime(_totalTime, suppressEvents) { 4870 _wake(); 4871 4872 if (!arguments.length) { 4873 return this._tTime; 4874 } 4875 4876 var parent = this._dp; 4877 4878 if (parent && parent.smoothChildTiming && this._ts) { 4879 _alignPlayhead(this, _totalTime); 4880 4881 !parent._dp || parent.parent || _postAddChecks(parent, this); // edge case: if this is a child of a timeline that already completed, for example, we must re-activate the parent. 4882 //in case any of the ancestor timelines had completed but should now be enabled, we should reset the
vendor: 5,599 bytes, lines 4882-4967
4882ir totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The start of that child would get pushed out, but one of the ancestors may have completed. 4883 4884 while (parent.parent) { 4885 if (parent.parent._time !== parent._start + (parent._ts >= 0 ? parent._tTime / parent._ts : (parent.totalDuration() - parent._tTime) / -parent._ts)) { 4886 parent.totalTime(parent._tTime, true); 4887 } 4888 4889 parent = parent.parent; 4890 } 4891 4892 if (!this.parent && this._dp.autoRemoveChildren && (this._ts > 0 && _totalTime < this._tDur || this._ts < 0 && _totalTime > 0 || !this._tDur && !_totalTime)) { 4893 //if the animation doesn't have a parent, put it back into its last parent (recorded as _dp for exactly cases like this). Limit to parents with autoRemoveChildren (like globalTimeline) so that if the user manually removes an animation from a timeline and then alters its playhead, it doesn't get added back in. 4894 _addToTimeline(this._dp, this, this._start - this._delay); 4895 } 4896 } 4897 4898 if (this._tTime !== _totalTime || !this._dur && !suppressEvents || this._initted && Math.abs(this._zTime) === _tinyNum || !_totalTime && !this._initted && (this.add || this._ptLookup)) { 4899 // check for _ptLookup on a Tween instance to ensure it has actually finished being instantiated, otherwise if this.reverse() gets called in the Animation constructor, it could trigger a render() here even though the _targets weren't populated, thus when _init() is called there won't be any PropTweens (it'll act like the tween is non-functional) 4900 this._ts || (this._pTime = _totalTime); // otherwise, if an animation is paused, then the playhead is moved back to zero, then resumed, it'd revert back to the original time at the pause 4901 //if (!this._lock) { // avoid endless recursion (not sure we need this yet or if it's worth the performance hit) 4902 // this._lock = 1; 4903 4904 _lazySafeRender(this, _totalTime, suppressEvents); // this._lock = 0; 4905 //} 4906 4907 } 4908 4909 return this; 4910 }; 4911 4912 _proto.time = function time(value, suppressEvents) { 4913 return arguments.length ? this.totalTime(Math.min(this.totalDuration(), value + _elapsedCycleDuration(this)) % this._dur || (value ? this._dur : 0), suppressEvents) : this._time; // note: if the modulus results in 0, the playhead could be exactly at the end or the beginning, and we always defer to the END with a non-zero value, otherwise if you set the time() to the very end (duration()), it would render at the START! 4914 }; 4915 4916 _proto.totalProgress = function totalProgress(value, suppressEvents) { 4917 return arguments.length ? this.totalTime(this.totalDuration() * value, suppressEvents) : this.totalDuration() ? Math.min(1, this._tTime / this._tDur) : this.ratio; 4918 }; 4919 4920 _proto.progress = function progress(value, suppressEvents) { 4921 return arguments.length ? this.totalTime(this.duration() * (this._yoyo && !(this.iteration() & 1) ? 1 - value : value) + _elapsedCycleDuration(this), suppressEvents) : this.duration() ? Math.min(1, this._time / this._dur) : this.ratio; 4922 }; 4923 4924 _proto.iteration = function iteration(value, suppressEvents) { 4925 var cycleDuration = this.duration() + this._rDelay; 4926 4927 return arguments.length ? this.totalTime(this._time + (value - 1) * cycleDuration, suppressEvents) : this._repeat ? _animationCycle(this._tTime, cycleDuration) + 1 : 1; 4928 } // potential future addition: 4929 // isPlayingBackwards() { 4930 // let animation = this, 4931 // orientation = 1; // 1 = forward, -1 = backward 4932 // while (animation) { 4933 // orientation *= animation.reversed() || (animation.repeat() && !(animation.iteration() & 1)) ? -1 : 1; 4934 // animation = animation.parent; 4935 // } 4936 // return orientation < 0; 4937 // } 4938 ; 4939 4940 _proto.timeScale = function timeScale(value) { 4941 if (!arguments.length) { 4942 return this._rts === -_tinyNum ? 0 : this._rts; // recorded timeScale. Special case: if someone calls reverse() on an animation with timeScale of 0, we assign it -_tinyNum to remember it's reversed. 4943 } 4944 4945 if (this._rts === value) { 4946 return this; 4947 } 4948 4949 var tTime = this.parent && this._ts ? _parentToChildTotalTime(this.parent._time, this) : this._tTime; // make sure to do the parentToChildTotalTime() BEFORE setting the new _ts because the old one must be used in that calculation. 4950 // prioritize rendering where the parent's playhead lines up instead of this._tTime because there could be a tween that's animating another tween's timeScale in the same rendering loop (same parent), thus if the timeScale tween renders first, it would alter _start BEFORE _tTime was set on that tick (in the rendering loop), effectively freezing it until the timeScale tween finishes. 4951 4952 this._rts = +value || 0; 4953 this._ts = this._ps || value === -_tinyNum ? 0 : this._rts; // _ts is the functional timeScale which would be 0 if the animation is paused. 4954 4955 return _recacheAncestors(this.totalTime(_clamp(-this._delay, this._tDur, tTime), true)); 4956 }; 4957 4958 _proto.paused = function paused(value) { 4959 if (!arguments.length) { 4960 return this._ps; 4961 } 4962 4963 if (this._ps !== value) { 4964 this._ps = value; 4965 4966 if (value) { 4967 this._pTime = this._tTime || Math.max(-this._delay, this.rawTime()); // if the pause occurs during the delay phase, make sure that's factored
vendor: 4,401 bytes, lines 4967-5078
4967in when resuming. 4968 4969 this._ts = this._act = 0; // _ts is the functional timeScale, so a paused tween would effectively have a timeScale of 0. We record the "real" timeScale as _rts (recorded time scale) 4970 } else { 4971 _wake(); 4972 4973 this._ts = this._rts; //only defer to _pTime (pauseTime) if tTime is zero. Remember, someone could pause() an animation, then scrub the playhead and resume(). If the parent doesn't have smoothChildTiming, we render at the rawTime() because the startTime won't get updated. 4974 4975 this.totalTime(this.parent && !this.parent.smoothChildTiming ? this.rawTime() : this._tTime || this._pTime, this.progress() === 1 && (this._tTime -= _tinyNum) && Math.abs(this._zTime) !== _tinyNum); // edge case: animation.progress(1).pause().play() wouldn't render again because the playhead is already at the end, but the call to totalTime() below will add it back to its parent...and not remove it again (since removing only happens upon rendering at a new time). Offsetting the _tTime slightly is done simply to cause the final render in totalTime() that'll pop it off its timeline (if autoRemoveChildren is true, of course). Check to make sure _zTime isn't -_tinyNum to avoid an edge case where the playhead is pushed to the end but INSIDE a tween/callback, the timeline itself is paused thus halting rendering and leaving a few unrendered. When resuming, it wouldn't render those otherwise. 4976 } 4977 } 4978 4979 return this; 4980 }; 4981 4982 _proto.startTime = function startTime(value) { 4983 if (arguments.length) { 4984 this._start = value; 4985 var parent = this.parent || this._dp; 4986 parent && (parent._sort || !this.parent) && _addToTimeline(parent, this, value - this._delay); 4987 return this; 4988 } 4989 4990 return this._start; 4991 }; 4992 4993 _proto.endTime = function endTime(includeRepeats) { 4994 return this._start + (_isNotFalse(includeRepeats) ? this.totalDuration() : this.duration()) / Math.abs(this._ts); 4995 }; 4996 4997 _proto.rawTime = function rawTime(wrapRepeats) { 4998 var parent = this.parent || this._dp; // _dp = detatched parent 4999 5000 return !parent ? this._tTime : wrapRepeats && (!this._ts || this._repeat && this._time && this.totalProgress() < 1) ? this._tTime % (this._dur + this._rDelay) : !this._ts ? this._tTime : _parentToChildTotalTime(parent.rawTime(wrapRepeats), this); 5001 }; 5002 5003 _proto.globalTime = function globalTime(rawTime) { 5004 var animation = this, 5005 time = arguments.length ? rawTime : animation.rawTime(); 5006 5007 while (animation) { 5008 time = animation._start + time / (animation._ts || 1); 5009 animation = animation._dp; 5010 } 5011 5012 return time; 5013 }; 5014 5015 _proto.repeat = function repeat(value) { 5016 if (arguments.length) { 5017 this._repeat = value === Infinity ? -2 : value; 5018 return _onUpdateTotalDuration(this); 5019 } 5020 5021 return this._repeat === -2 ? Infinity : this._repeat; 5022 }; 5023 5024 _proto.repeatDelay = function repeatDelay(value) { 5025 if (arguments.length) { 5026 this._rDelay = value; 5027 return _onUpdateTotalDuration(this); 5028 } 5029 5030 return this._rDelay; 5031 }; 5032 5033 _proto.yoyo = function yoyo(value) { 5034 if (arguments.length) { 5035 this._yoyo = value; 5036 return this; 5037 } 5038 5039 return this._yoyo; 5040 }; 5041 5042 _proto.seek = function seek(position, suppressEvents) { 5043 return this.totalTime(_parsePosition(this, position), _isNotFalse(suppressEvents)); 5044 }; 5045 5046 _proto.restart = function restart(includeDelay, suppressEvents) { 5047 return this.play().totalTime(includeDelay ? -this._delay : 0, _isNotFalse(suppressEvents)); 5048 }; 5049 5050 _proto.play = function play(from, suppressEvents) { 5051 from != null && this.seek(from, suppressEvents); 5052 return this.reversed(false).paused(false); 5053 }; 5054 5055 _proto.reverse = function reverse(from, suppressEvents) { 5056 from != null && this.seek(from || this.totalDuration(), suppressEvents); 5057 return this.reversed(true).paused(false); 5058 }; 5059 5060 _proto.pause = function pause(atTime, suppressEvents) { 5061 atTime != null && this.seek(atTime, suppressEvents); 5062 return this.paused(true); 5063 }; 5064 5065 _proto.resume = function resume() { 5066 return this.paused(false); 5067 }; 5068 5069 _proto.reversed = function reversed(value) { 5070 if (arguments.length) { 5071 !!value !== this.reversed() && this.timeScale(-this._rts || (value ? -_tinyNum : 0)); // in case timeScale is zero, reversing would have no effect so we use _tinyNum. 5072 5073 return this; 5074 } 5075 5076 return this._rts < 0; 5077 }; 5078
vendor: 9,032 bytes, lines 5079-5310
5079 _proto.invalidate = function invalidate() { 5080 this._initted = this._act = 0; 5081 this._zTime = -_tinyNum; 5082 return this; 5083 }; 5084 5085 _proto.isActive = function isActive() { 5086 var parent = this.parent || this._dp, 5087 start = this._start, 5088 rawTime; 5089 return !!(!parent || this._ts && this._initted && parent.isActive() && (rawTime = parent.rawTime(true)) >= start && rawTime < this.endTime(true) - _tinyNum); 5090 }; 5091 5092 _proto.eventCallback = function eventCallback(type, callback, params) { 5093 var vars = this.vars; 5094 5095 if (arguments.length > 1) { 5096 if (!callback) { 5097 delete vars[type]; 5098 } else { 5099 vars[type] = callback; 5100 params && (vars[type + "Params"] = params); 5101 type === "onUpdate" && (this._onUpdate = callback); 5102 } 5103 5104 return this; 5105 } 5106 5107 return vars[type]; 5108 }; 5109 5110 _proto.then = function then(onFulfilled) { 5111 var self = this; 5112 return new Promise(function (resolve) { 5113 var f = _isFunction(onFulfilled) ? onFulfilled : _passThrough, 5114 _resolve = function _resolve() { 5115 var _then = self.then; 5116 self.then = null; // temporarily null the then() method to avoid an infinite loop (see https://github.com/greensock/GSAP/issues/322) 5117 5118 _isFunction(f) && (f = f(self)) && (f.then || f === self) && (self.then = _then); 5119 resolve(f); 5120 self.then = _then; 5121 }; 5122 5123 if (self._initted && self.totalProgress() === 1 && self._ts >= 0 || !self._tTime && self._ts < 0) { 5124 _resolve(); 5125 } else { 5126 self._prom = _resolve; 5127 } 5128 }); 5129 }; 5130 5131 _proto.kill = function kill() { 5132 _interrupt(this); 5133 }; 5134 5135 return Animation; 5136}(); 5137 5138_setDefaults(Animation.prototype, { 5139 _time: 0, 5140 _start: 0, 5141 _end: 0, 5142 _tTime: 0, 5143 _tDur: 0, 5144 _dirty: 0, 5145 _repeat: 0, 5146 _yoyo: false, 5147 parent: null, 5148 _initted: false, 5149 _rDelay: 0, 5150 _ts: 1, 5151 _dp: 0, 5152 ratio: 0, 5153 _zTime: -_tinyNum, 5154 _prom: 0, 5155 _ps: false, 5156 _rts: 1 5157}); 5158/* 5159 * ------------------------------------------------- 5160 * TIMELINE 5161 * ------------------------------------------------- 5162 */ 5163 5164 5165var Timeline = /*#__PURE__*/function (_Animation) { 5166 _inheritsLoose(Timeline, _Animation); 5167 5168 function Timeline(vars, time) { 5169 var _this; 5170 5171 if (vars === void 0) { 5172 vars = {}; 5173 } 5174 5175 _this = _Animation.call(this, vars, time) || this; 5176 _this.labels = {}; 5177 _this.smoothChildTiming = !!vars.smoothChildTiming; 5178 _this.autoRemoveChildren = !!vars.autoRemoveChildren; 5179 _this._sort = _isNotFalse(vars.sortChildren); 5180 _this.parent && _postAddChecks(_this.parent, _assertThisInitialized(_this)); 5181 vars.scrollTrigger && _scrollTrigger(_assertThisInitialized(_this), vars.scrollTrigger); 5182 return _this; 5183 } 5184 5185 var _proto2 = Timeline.prototype; 5186 5187 _proto2.to = function to(targets, vars, position) { 5188 new Tween(targets, _parseVars(arguments, 0, this), _parsePosition(this, _isNumber(vars) ? arguments[3] : position)); 5189 return this; 5190 }; 5191 5192 _proto2.from = function from(targets, vars, position) { 5193 new Tween(targets, _parseVars(arguments, 1, this), _parsePosition(this, _isNumber(vars) ? arguments[3] : position)); 5194 return this; 5195 }; 5196 5197 _proto2.fromTo = function fromTo(targets, fromVars, toVars, position) { 5198 new Tween(targets, _parseVars(arguments, 2, this), _parsePosition(this, _isNumber(fromVars) ? arguments[4] : position)); 5199 return this; 5200 }; 5201 5202 _proto2.set = function set(targets, vars, position) { 5203 vars.duration = 0; 5204 vars.parent = this; 5205 _inheritDefaults(vars).repeatDelay || (vars.repeat = 0); 5206 vars.immediateRender = !!vars.immediateRender; 5207 new Tween(targets, vars, _parsePosition(this, position), 1); 5208 return this; 5209 }; 5210 5211 _proto2.call = function call(callback, params, position) { 5212 return _addToTimeline(this, Tween.delayedCall(0, callback, params), _parsePosition(this, position)); 5213 } //ONLY for backward compatibility! Maybe delete? 5214 ; 5215 5216 _proto2.staggerTo = function staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 5217 vars.duration = duration; 5218 vars.stagger = vars.stagger || stagger; 5219 vars.onComplete = onCompleteAll; 5220 vars.onCompleteParams = onCompleteAllParams; 5221 vars.parent = this; 5222 new Tween(targets, vars, _parsePosition(this, position)); 5223 return this; 5224 }; 5225 5226 _proto2.staggerFrom = function staggerFrom(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 5227 vars.runBackwards = 1; 5228 _inheritDefaults(vars).immediateRender = _isNotFalse(vars.immediateRender); 5229 return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams); 5230 }; 5231 5232 _proto2.staggerFromTo = function staggerFromTo(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams) { 5233 toVars.startAt = fromVars; 5234 _inheritDefaults(toVars).immediateRender = _isNotFalse(toVars.immediateRender); 5235 return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams); 5236 }; 5237 5238 _proto2.render = function render(totalTime, suppressEvents, force) { 5239 var prevTime = this._time, 5240 tDur = this._dirty ? this.totalDuration() : this._tDur, 5241 dur = this._dur, 5242 tTime = this !== _globalTimeline && totalTime > tDur - _tinyNum && totalTime >= 0 ? tDur : totalTime < _tinyNum ? 0 : totalTime, 5243 crossingStart = this._zTime < 0 !== totalTime < 0 && (this._initted || !dur), 5244 time, 5245 child, 5246 next, 5247 iteration, 5248 cycleDuration, 5249 prevPaused, 5250 pauseTween, 5251 timeScale, 5252 prevStart, 5253 prevIteration, 5254 yoyo, 5255 isYoyo; 5256 5257 if (tTime !== this._tTime || force || crossingStart) { 5258 if (prevTime !== this._time && dur) { 5259 //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump). 5260 tTime += this._time - prevTime; 5261 totalTime += this._time - prevTime; 5262 } 5263 5264 time = tTime; 5265 prevStart = this._start; 5266 timeScale = this._ts; 5267 prevPaused = !timeScale; 5268 5269 if (crossingStart) { 5270 dur || (prevTime = this._zTime); //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. 5271 5272 (totalTime || !suppressEvents) && (this._zTime = totalTime); 5273 } 5274 5275 if (this._repeat) { 5276 //adjust the time for repeats and yoyos 5277 yoyo = this._yoyo; 5278 cycleDuration = dur + this._rDelay; 5279 5280 if (this._repeat < -1 && totalTime < 0) { 5281 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 5282 } 5283 5284 time = _round(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!) 5285 5286 if (tTime === tDur) { 5287 // the tDur === tTime is for edge cases where there's a lengthy decimal on the duration and it may reach the very end but the time is rendered as not-quite-there (remember, tDur is rounded to 4 decimals whereas dur isn't) 5288 iteration = this._repeat; 5289 time = dur; 5290 } else { 5291 iteration = ~~(tTime / cycleDuration); 5292 5293 if (iteration && iteration === tTime / cycleDuration) { 5294 time = dur; 5295 iteration--; 5296 } 5297 5298 time > dur && (time = dur); 5299 } 5300 5301 prevIteration = _animationCycle(this._tTime, cycleDuration); 5302 !prevTime && this._tTime && prevIteration !== iteration && (prevIteration = iteration); // edge case - if someone does addPause() at the very beginning of a repeating timeline, that pause is technically at the same spot as the end which causes this._time to get set to 0 when the totalTime would normally place the playhead at the end. See https://greensock.com/forums/topic/23823-closing-nav-animation-not-working-on-ie-and-iphone-6-maybe-other-older-browser/?tab=comments#comment-113005 5303 5304 if (yoyo && iteration & 1) { 5305 time = dur - time; 5306 isYoyo = 1; 5307 } 5308 /* 5309 make sure children at the end/beginning of the timeline are rendered properly. If, for example, 5310 a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which
5311 would get translated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there 5312 could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So 5313 we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must 5314 ensure that zero-duration tweens at the very beginning or end of the Timeline work. 5315 */ 5316 5317 5318 if (iteration !== prevIteration && !this._lock) { 5319 var rewinding = yoyo && prevIteration & 1, 5320 doesWrap = rewinding === (yoyo && iteration & 1); 5321 iteration < prevIteration && (rewinding = !rewinding); 5322 prevTime = rewinding ? 0 : dur; 5323 this._lock = 1; 5324 this.render(prevTime || (isYoyo ? 0 : _round(iteration * cycleDuration)), suppressEvents, !dur)._lock = 0; 5325 !suppressEvents && this.parent && _callback(this, "onRepeat"); 5326 this.vars.repeatRefresh && !isYoyo && (this.invalidate()._lock = 1); 5327 5328 if (prevTime !== this._time || prevPaused !== !this._ts) { 5329 return this; 5330 } 5331 5332 dur = this._dur; // in case the duration changed in the onRepeat 5333 5334 tDur = this._tDur; 5335 5336 if (doesWrap) { 5337 this._lock = 2; 5338 prevTime = rewinding ? dur : -0.0001; 5339 this.render(prevTime, true); 5340 this.vars.repeatRefresh && !isYoyo && this.invalidate(); 5341 } 5342 5343 this._lock = 0; 5344 5345 if (!this._ts && !prevPaused) { 5346 return this; 5347 } //in order for yoyoEase to work properly when there's a stagger, we must swap out the ease in each sub-tween. 5348 5349 5350 _propagateYoyoEase(this, isYoyo); 5351 } 5352 } 5353 5354 if (this._hasPause && !this._forcing && this._lock < 2) { 5355 pauseTween = _findNextPauseTween(this, _round(prevTime), _round(time)); 5356 5357 if (pauseTween) { 5358 tTime -= time - (time = pauseTween._start); 5359 } 5360 } 5361 5362 this._tTime = tTime; 5363 this._time = time; 5364 this._act = !timeScale; //as long as it's not paused, force it to be active so that if the user renders independent of the parent timeline, it'll be forced to re-render on the next tick. 5365 5366 if (!this._initted) { 5367 this._onUpdate = this.vars.onUpdate; 5368 this._initted = 1; 5369 this._zTime = totalTime; 5370 prevTime = 0; // upon init, the playhead should always go forward;
5370 someone could invalidate() a completed timeline and then if they restart(), that would make child tweens render in reverse order which could lock in the wrong starting values if they build on each other, like tl.to(obj, {x: 100}).to(obj, {x: 0}). 5371 } 5372 5373 !prevTime && (time || !dur && totalTime >= 0) && !suppressEvents && _callback(this, "onStart"); 5374 5375 if (time >= prevTime && totalTime >= 0) { 5376 child = this._first; 5377 5378 while (child) { 5379 next = child._next; 5380 5381 if ((child._act || time >= child._start) && child._ts && pauseTween !== child) { 5382 if (child.parent !== this) { 5383 // an extreme edge case - the child's render could do something like kill() the "next" one in the linked list, or reparent it. In that case we must re-initiate the whole render to be safe. 5384 return this.render(totalTime, suppressEvents, force); 5385 } 5386 5387 child.render(child._ts > 0 ? (time - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (time - child._start) * child._ts, suppressEvents, force); 5388 5389 if (time !== this._time || !this._ts && !prevPaused) { 5390 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 5391 pauseTween = 0; 5392 next && (tTime += this._zTime = -_tinyNum); // it didn't finish rendering, so flag zTime as negative so that so that the next time render() is called it'll be forced (to render any remaining children) 5393 5394 break; 5395 } 5396 } 5397 5398 child = next; 5399 } 5400 } else { 5401 child = this._last; 5402 var adjustedTime = totalTime < 0 ? totalTime : time; //when the playhead goes backward beyond the start of this timeline, we must pass that information down to the child animations so that zero-duration tweens know whether to render their starting or ending values. 5403 5404 while (child) { 5405 next = child._prev; 5406 5407 if ((child._act || adjustedTime <= child._end) && child._ts && pauseTween !== child) { 5408 if (child.parent !== this) { 5409 // an extreme edge case - the child's render could do something like kill() the "next" one in the linked list, or reparent it. In that case we must re-initiate the whole render to be safe. 5410 return this.render(totalTime, suppressEvents, force); 5411 } 5412 5413 child.render(child._ts > 0 ? (adjustedTime - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (adjustedTime - child._start) * child._ts, suppressEvents, force); 5414 5415 if (time !== this._time || !this._ts && !prevPaused) { 5416 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 5417 pauseTween = 0; 5418 next && (tTime += this._zTime = adjustedTime ? -_tinyNum : _tinyNum); // it didn't finish rendering, so adjust zTime so that so that the next time render() is called it'll be forced (to render any remaining children) 5419 5420 break; 5421 } 5422 } 5423 5424 child = next; 5425 } 5426 } 5427 5428 if (pauseTween && !suppressEvents) { 5429 this.pause(); 5430 pauseTween.render(time >= prevTime ? 0 : -_tinyNum)._zTime = time >= prevTime ? 1 : -1; 5431 5432 if (this._ts) { 5433 //the callback resumed playback! So since we may have held back the playhead due to where the pause is positioned, go ahead and jump to where it's SUPPOSED to be (if no pause happened). 5434 this._start = prevStart; //if the pause was at an earlier time and the user resumed in the callback, it could reposition the timeline (changing its startTime), throwing things off slightly, so we make sure the _start doesn't shift. 5435 5436 _setEnd(this); 5437 5438 return this.render(totalTime, suppressEvents, force); 5439 } 5440 } 5441
vendor: 17,787 bytes, lines 5442-5987
5442 this._onUpdate && !suppressEvents && _callback(this, "onUpdate", true); 5443 if (tTime === tDur && tDur >= this.totalDuration() || !tTime && prevTime) if (prevStart === this._start || Math.abs(timeScale) !== Math.abs(this._ts)) if (!this._lock) { 5444 (totalTime || !dur) && (tTime === tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); // don't remove if the timeline is reversed and the playhead isn't at 0, otherwise tl.progress(1).reverse() won't work. Only remove if the playhead is at the end and timeScale is positive, or if the playhead is at 0 and the timeScale is negative. 5445 5446 if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime)) { 5447 _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true); 5448 5449 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 5450 } 5451 } 5452 } 5453 5454 return this; 5455 }; 5456 5457 _proto2.add = function add(child, position) { 5458 var _this2 = this; 5459 5460 _isNumber(position) || (position = _parsePosition(this, position)); 5461 5462 if (!(child instanceof Animation)) { 5463 if (_isArray(child)) { 5464 child.forEach(function (obj) { 5465 return _this2.add(obj, position); 5466 }); 5467 return this; 5468 } 5469 5470 if (_isString(child)) { 5471 return this.addLabel(child, position); 5472 } 5473 5474 if (_isFunction(child)) { 5475 child = Tween.delayedCall(0, child); 5476 } else { 5477 return this; 5478 } 5479 } 5480 5481 return this !== child ? _addToTimeline(this, child, position) : this; //don't allow a timeline to be added to itself as a child! 5482 }; 5483 5484 _proto2.getChildren = function getChildren(nested, tweens, timelines, ignoreBeforeTime) { 5485 if (nested === void 0) { 5486 nested = true; 5487 } 5488 5489 if (tweens === void 0) { 5490 tweens = true; 5491 } 5492 5493 if (timelines === void 0) { 5494 timelines = true; 5495 } 5496 5497 if (ignoreBeforeTime === void 0) { 5498 ignoreBeforeTime = -_bigNum; 5499 } 5500 5501 var a = [], 5502 child = this._first; 5503 5504 while (child) { 5505 if (child._start >= ignoreBeforeTime) { 5506 if (child instanceof Tween) { 5507 tweens && a.push(child); 5508 } else { 5509 timelines && a.push(child); 5510 nested && a.push.apply(a, child.getChildren(true, tweens, timelines)); 5511 } 5512 } 5513 5514 child = child._next; 5515 } 5516 5517 return a; 5518 }; 5519 5520 _proto2.getById = function getById(id) { 5521 var animations = this.getChildren(1, 1, 1), 5522 i = animations.length; 5523 5524 while (i--) { 5525 if (animations[i].vars.id === id) { 5526 return animations[i]; 5527 } 5528 } 5529 }; 5530 5531 _proto2.remove = function remove(child) { 5532 if (_isString(child)) { 5533 return this.removeLabel(child); 5534 } 5535 5536 if (_isFunction(child)) { 5537 return this.killTweensOf(child); 5538 } 5539 5540 _removeLinkedListItem(this, child); 5541 5542 if (child === this._recent) { 5543 this._recent = this._last; 5544 } 5545 5546 return _uncache(this); 5547 }; 5548 5549 _proto2.totalTime = function totalTime(_totalTime2, suppressEvents) { 5550 if (!arguments.length) { 5551 return this._tTime; 5552 } 5553 5554 this._forcing = 1; 5555 5556 if (!this._dp && this._ts) { 5557 //special case for the global timeline (or any other that has no parent or detached parent). 5558 this._start = _round(_ticker.time - (this._ts > 0 ? _totalTime2 / this._ts : (this.totalDuration() - _totalTime2) / -this._ts)); 5559 } 5560 5561 _Animation.prototype.totalTime.call(this, _totalTime2, suppressEvents); 5562 5563 this._forcing = 0; 5564 return this; 5565 }; 5566 5567 _proto2.addLabel = function addLabel(label, position) { 5568 this.labels[label] = _parsePosition(this, position); 5569 return this; 5570 }; 5571 5572 _proto2.removeLabel = function removeLabel(label) { 5573 delete this.labels[label]; 5574 return this; 5575 }; 5576 5577 _proto2.addPause = function addPause(position, callback, params) { 5578 var t = Tween.delayedCall(0, callback || _emptyFunc, params); 5579 t.data = "isPause"; 5580 this._hasPause = 1; 5581 return _addToTimeline(this, t, _parsePosition(this, position)); 5582 }; 5583 5584 _proto2.removePause = function removePause(position) { 5585 var child = this._first; 5586 position = _parsePosition(this, position); 5587 5588 while (child) { 5589 if (child._start === position && child.data === "isPause") { 5590 _removeFromParent(child); 5591 } 5592 5593 child = child._next; 5594 } 5595 }; 5596 5597 _proto2.killTweensOf = function killTweensOf(targets, props, onlyActive) { 5598 var tweens = this.getTweensOf(targets, onlyActive), 5599 i = tweens.length; 5600 5601 while (i--) { 5602 _overwritingTween !== tweens[i] && tweens[i].kill(targets, props); 5603 } 5604 5605 return this; 5606 }; 5607 5608 _proto2.getTweensOf = function getTweensOf(targets, onlyActive) { 5609 var a = [], 5610 parsedTargets = toArray(targets), 5611 child = this._first, 5612 isGlobalTime = _isNumber(onlyActive), 5613 // a number is interpreted as a global time. If the animation spans 5614 children; 5615 5616 while (child) { 5617 if (child instanceof Tween) { 5618 if (_arrayContainsAny(child._targets, parsedTargets) && (isGlobalTime ? (!_overwritingTween || child._initted && child._ts) && child.globalTime(0) <= onlyActive && child.globalTime(child.totalDuration()) > onlyActive : !onlyActive || child.isActive())) { 5619 // note: if this is for overwriting, it should only be for tweens that aren't paused and are initted. 5620 a.push(child); 5621 } 5622 } else if ((children = child.getTweensOf(parsedTargets, onlyActive)).length) { 5623 a.push.apply(a, children); 5624 } 5625 5626 child = child._next; 5627 } 5628 5629 return a; 5630 } // potential future feature - targets() on timelines 5631 // targets() { 5632 // let result = []; 5633 // this.getChildren(true, true, false).forEach(t => result.push(...t.targets())); 5634 // return result; 5635 // } 5636 ; 5637 5638 _proto2.tweenTo = function tweenTo(position, vars) { 5639 vars = vars || {}; 5640 5641 var tl = this, 5642 endTime = _parsePosition(tl, position), 5643 _vars = vars, 5644 startAt = _vars.startAt, 5645 _onStart = _vars.onStart, 5646 onStartParams = _vars.onStartParams, 5647 immediateRender = _vars.immediateRender, 5648 tween = Tween.to(tl, _setDefaults({ 5649 ease: "none", 5650 lazy: false, 5651 immediateRender: false, 5652 time: endTime, 5653 overwrite: "auto", 5654 duration: vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()) || _tinyNum, 5655 onStart: function onStart() { 5656 tl.pause(); 5657 var duration = vars.duration || Math.abs((endTime - tl._time) / tl.timeScale()); 5658 tween._dur !== duration && _setDuration(tween, duration, 0, 1).render(tween._time, true, true); 5659 _onStart && _onStart.apply(tween, onStartParams || []); //in case the user had an onStart in the vars - we don't want to overwrite it. 5660 } 5661 }, vars)); 5662 5663 return immediateRender ? tween.render(0) : tween; 5664 }; 5665 5666 _proto2.tweenFromTo = function tweenFromTo(fromPosition, toPosition, vars) { 5667 return this.tweenTo(toPosition, _setDefaults({ 5668 startAt: { 5669 time: _parsePosition(this, fromPosition) 5670 } 5671 }, vars)); 5672 }; 5673 5674 _proto2.recent = function recent() { 5675 return this._recent; 5676 }; 5677 5678 _proto2.nextLabel = function nextLabel(afterTime) { 5679 if (afterTime === void 0) { 5680 afterTime = this._time; 5681 } 5682 5683 return _getLabelInDirection(this, _parsePosition(this, afterTime)); 5684 }; 5685 5686 _proto2.previousLabel = function previousLabel(beforeTime) { 5687 if (beforeTime === void 0) { 5688 beforeTime = this._time; 5689 } 5690 5691 return _getLabelInDirection(this, _parsePosition(this, beforeTime), 1); 5692 }; 5693 5694 _proto2.currentLabel = function currentLabel(value) { 5695 return arguments.length ? this.seek(value, true) : this.previousLabel(this._time + _tinyNum); 5696 }; 5697 5698 _proto2.shiftChildren = function shiftChildren(amount, adjustLabels, ignoreBeforeTime) { 5699 if (ignoreBeforeTime === void 0) { 5700 ignoreBeforeTime = 0; 5701 } 5702 5703 var child = this._first, 5704 labels = this.labels, 5705 p; 5706 5707 while (child) { 5708 if (child._start >= ignoreBeforeTime) { 5709 child._start += amount; 5710 child._end += amount; 5711 } 5712 5713 child = child._next; 5714 } 5715 5716 if (adjustLabels) { 5717 for (p in labels) { 5718 if (labels[p] >= ignoreBeforeTime) { 5719 labels[p] += amount; 5720 } 5721 } 5722 } 5723 5724 return _uncache(this); 5725 }; 5726 5727 _proto2.invalidate = function invalidate() { 5728 var child = this._first; 5729 this._lock = 0; 5730 5731 while (child) { 5732 child.invalidate(); 5733 child = child._next; 5734 } 5735 5736 return _Animation.prototype.invalidate.call(this); 5737 }; 5738 5739 _proto2.clear = function clear(includeLabels) { 5740 if (includeLabels === void 0) { 5741 includeLabels = true; 5742 } 5743 5744 var child = this._first, 5745 next; 5746 5747 while (child) { 5748 next = child._next; 5749 this.remove(child); 5750 child = next; 5751 } 5752 5753 this._dp && (this._time = this._tTime = this._pTime = 0); 5754 includeLabels && (this.labels = {}); 5755 return _uncache(this); 5756 }; 5757 5758 _proto2.totalDuration = function totalDuration(value) { 5759 var max = 0, 5760 self = this, 5761 child = self._last, 5762 prevStart = _bigNum, 5763 prev, 5764 start, 5765 parent; 5766 5767 if (arguments.length) { 5768 return self.timeScale((self._repeat < 0 ? self.duration() : self.totalDuration()) / (self.reversed() ? -value : value)); 5769 } 5770 5771 if (self._dirty) { 5772 parent = self.parent; 5773 5774 while (child) { 5775 prev = child._prev; //record it here in case the tween changes position in the sequence... 5776 5777 child._dirty && child.totalDuration(); //could change the tween._startTime, so make sure the animation's cache is clean before analyzing it. 5778 5779 start = child._start; 5780 5781 if (start > prevStart && self._sort && child._ts && !self._lock) { 5782 //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence 5783 self._lock = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add(). 5784 5785 _addToTimeline(self, child, start - child._delay, 1)._lock = 0; 5786 } else { 5787 prevStart = start; 5788 } 5789 5790 if (start < 0 && child._ts) { 5791 //children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found. 5792 max -= start; 5793 5794 if (!parent && !self._dp || parent && parent.smoothChildTiming) { 5795 self._start += start / self._ts; 5796 self._time -= start; 5797 self._tTime -= start; 5798 } 5799 5800 self.shiftChildren(-start, false, -1e999); 5801 prevStart = 0; 5802 } 5803 5804 child._end > max && child._ts && (max = child._end); 5805 child = prev; 5806 } 5807 5808 _setDuration(self, self === _globalTimeline && self._time > max ? self._time : max, 1, 1); 5809 5810 self._dirty = 0; 5811 } 5812 5813 return self._tDur; 5814 }; 5815 5816 Timeline.updateRoot = function updateRoot(time) { 5817 if (_globalTimeline._ts) { 5818 _lazySafeRender(_globalTimeline, _parentToChildTotalTime(time, _globalTimeline)); 5819 5820 _lastRenderedFrame = _ticker.frame; 5821 } 5822 5823 if (_ticker.frame >= _nextGCFrame) { 5824 _nextGCFrame += _config.autoSleep || 120; 5825 var child = _globalTimeline._first; 5826 if (!child || !child._ts) if (_config.autoSleep && _ticker._listeners.length < 2) { 5827 while (child && !child._ts) { 5828 child = child._next; 5829 } 5830 5831 child || _ticker.sleep(); 5832 } 5833 } 5834 }; 5835 5836 return Timeline; 5837}(Animation); 5838 5839_setDefaults(Timeline.prototype, { 5840 _lock: 0, 5841 _hasPause: 0, 5842 _forcing: 0 5843}); 5844 5845var _addComplexStringPropTween = function _addComplexStringPropTween(target, prop, start, end, setter, stringFilter, funcParam) { 5846 //note: we call _addComplexStringPropTween.call(tweenInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus "this" would refer to the plugin. 5847 var pt = new PropTween(this._pt, target, prop, 0, 1, _renderComplexString, null, setter), 5848 index = 0, 5849 matchIndex = 0, 5850 result, 5851 startNums, 5852 color, 5853 endNum, 5854 chunk, 5855 startNum, 5856 hasRandom, 5857 a; 5858 pt.b = start; 5859 pt.e = end; 5860 start += ""; //ensure values are strings 5861 5862 end += ""; 5863 5864 if (hasRandom = ~end.indexOf("random(")) { 5865 end = _replaceRandom(end); 5866 } 5867 5868 if (stringFilter) { 5869 a = [start, end]; 5870 stringFilter(a, target, prop); //pass an array with the starting and ending values and let the filter do whatever it needs to the values. 5871 5872 start = a[0]; 5873 end = a[1]; 5874 } 5875 5876 startNums = start.match(_complexStringNumExp) || []; 5877 5878 while (result = _complexStringNumExp.exec(end)) { 5879 endNum = result[0]; 5880 chunk = end.substring(index, result.index); 5881 5882 if (color) { 5883 color = (color + 1) % 5; 5884 } else if (chunk.substr(-5) === "rgba(") { 5885 color = 1; 5886 } 5887 5888 if (endNum !== startNums[matchIndex++]) { 5889 startNum = parseFloat(startNums[matchIndex - 1]) || 0; //these nested PropTweens are handled in a special way - we'll never actually call a render or setter method on them. We'll just loop through them in the parent complex string PropTween's render method. 5890 5891 pt._pt = { 5892 _next: pt._pt, 5893 p: chunk || matchIndex === 1 ? chunk : ",", 5894 //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case. 5895 s: startNum, 5896 c: endNum.charAt(1) === "=" ? parseFloat(endNum.substr(2)) * (endNum.charAt(0) === "-" ? -1 : 1) : parseFloat(endNum) - startNum, 5897 m: color && color < 4 ? Math.round : 0 5898 }; 5899 index = _complexStringNumExp.lastIndex; 5900 } 5901 } 5902 5903 pt.c = index < end.length ? end.substring(index, end.length) : ""; //we use the "c" of the PropTween to store the final part of the string (after the last number) 5904 5905 pt.fp = funcParam; 5906 5907 if (_relExp.test(end) || hasRandom) { 5908 pt.e = 0; //if the end string contains relative values or dynamic random(...) values, delete the end it so that on the final render we don't actually set it to the string with += or -= characters (forces it to use the calculated value). 5909 } 5910 5911 this._pt = pt; //start the linked list with this new PropTween. Remember, we call _addComplexStringPropTween.call(tweenInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus "this" would refer to the plugin. 5912 5913 return pt; 5914}, 5915 _addPropTween = function _addPropTween(target, prop, start, end, index, targets, modifier, stringFilter, funcParam) { 5916 _isFunction(end) && (end = end(index || 0, target, targets)); 5917 var currentValue = target[prop], 5918 parsedStart = start !== "get" ? start : !_isFunction(currentValue) ? currentValue : funcParam ? target[prop.indexOf("set") || !_isFunction(target["get" + prop.substr(3)]) ? prop : "get" + prop.substr(3)](funcParam) : target[prop](), 5919 setter = !_isFunction(currentValue) ? _setterPlain : funcParam ? _setterFuncWithParam : _setterFunc, 5920 pt; 5921 5922 if (_isString(end)) { 5923 if (~end.indexOf("random(")) { 5924 end = _replaceRandom(end); 5925 } 5926 5927 if (end.charAt(1) === "=") { 5928 end = parseFloat(parsedStart) + parseFloat(end.substr(2)) * (end.charAt(0) === "-" ? -1 : 1) + (getUnit(parsedStart) || 0); 5929 } 5930 } 5931 5932 if (parsedStart !== end) { 5933 if (!isNaN(parsedStart * end)) { 5934 pt = new PropTween(this._pt, target, prop, +parsedStart || 0, end - (parsedStart || 0), typeof currentValue === "boolean" ? _renderBoolean : _renderPlain, 0, setter); 5935 funcParam && (pt.fp = funcParam); 5936 modifier && pt.modifier(modifier, this, target); 5937 return this._pt = pt; 5938 } 5939 5940 !currentValue && !(prop in target) && _missingPlugin(prop, end); 5941 return _addComplexStringPropTween.call(this, target, prop, parsedStart, end, setter, stringFilter || _config.stringFilter, funcParam); 5942 } 5943}, 5944 //creates a copy of the vars object and processes any function-based values (putting the resulting values directly into the copy) as well as strings with "random()" in them. It does NOT process relative values. 5945_processVars = function _processVars(vars, index, target, targets, tween) { 5946 _isFunction(vars) && (vars = _parseFuncOrString(vars, tween, index, target, targets)); 5947 5948 if (!_isObject(vars) || vars.style && vars.nodeType || _isArray(vars) || _isTypedArray(vars)) { 5949 return _isString(vars) ? _parseFuncOrString(vars, tween, index, target, targets) : vars; 5950 } 5951 5952 var copy = {}, 5953 p; 5954 5955 for (p in vars) { 5956 copy[p] = _parseFuncOrString(vars[p], tween, index, target, targets); 5957 } 5958 5959 return copy; 5960}, 5961 _checkPlugin = function _checkPlugin(property, vars, tween, index, target, targets) { 5962 var plugin, pt, ptLookup, i; 5963 5964 if (_plugins[property] && (plugin = new _plugins[property]()).init(target, plugin.rawVars ? vars[property] : _processVars(vars[property], index, target, targets, tween), tween, index, targets) !== false) { 5965 tween._pt = pt = new PropTween(tween._pt, target, property, 0, 1, plugin.render, plugin, 0, plugin.priority); 5966 5967 if (tween !== _quickTween) { 5968 ptLookup = tween._ptLookup[tween._targets.indexOf(target)]; //note: we can't use tween._ptLookup[index] because for staggered tweens, the index from the fullTargets array won't match what it is in each individual tween that spawns from the stagger. 5969 5970 i = plugin._props.length; 5971 5972 while (i--) { 5973 ptLookup[plugin._props[i]] = pt; 5974 } 5975 } 5976 } 5977 5978 return plugin; 5979}, 5980 _overwritingTween, 5981 //store a reference temporarily so we can avoid overwriting itself. 5982_initTween = function _initTween(tween, time) { 5983 var vars = tween.vars, 5984 ease = vars.ease, 5985 startAt = vars.startAt, 5986 immediateRender = vars.immediateRender, 5987 lazy = vars.lazy,
5988 onUpdate = vars.onUpdate, 5989 onUpdateParams = vars.onUpdateParams, 5990 callbackScope = vars.callbackScope, 5991 runBackwards = vars.runBackwards, 5992 yoyoEase = vars.yoyoEase, 5993 keyframes = vars.keyframes, 5994 autoRevert = vars.autoRevert, 5995 dur = tween._dur, 5996 prevStartAt = tween._startAt, 5997 targets = tween._targets, 5998 parent = tween.parent, 5999 fullTargets = parent && parent.data === "nested" ? parent.parent._targets : targets, 6000 autoOverwrite = tween._overwrite === "auto" && !_suppressOverwrites, 6001 tl = tween.timeline, 6002 cleanVars, 6003 i, 6004 p, 6005 pt, 6006 target, 6007 hasPriority, 6008 gsData, 6009 harness, 6010 plugin, 6011 ptLookup, 6012 index, 6013 harnessVars, 6014 overwritten; 6015 tl && (!keyframes || !ease) && (ease = "none"); 6016 tween._ease = _parseEase(ease, _defaults.ease); 6017 tween._yEase = yoyoEase ? _invertEase(_parseEase(yoyoEase === true ? ease : yoyoEase, _defaults.ease)) : 0; 6018 6019 if (yoyoEase && tween._yoyo && !tween._repeat) { 6020 //there must have been a parent timeline with yoyo:true that is currently in its yoyo phase, so flip the eases. 6021 yoyoEase = tween._yEase; 6022 tween._yEase = tween._ease; 6023 tween._ease = yoyoEase; 6024 } 6025 6026 if (!tl) { 6027 //if there's an internal timeline, skip all the parsing because we passed that task down the chain. 6028 harness = targets[0] ? _getCache(targets[0]).harness : 0; 6029 harnessVars = harness && vars[harness.prop]; //someone may need to specify CSS-specific values AND non-CSS values, like if the element has an "x" property plus it's a standard DOM element. We allow people to distinguish by wrapping plugin-specific stuff in a css:{} object for example. 6030 6031 cleanVars = _copyExcluding(vars, _reservedProps); 6032 prevStartAt && prevStartAt.render(-1, true).kill(); 6033 6034 if (startAt) { 6035 _removeFromParent(tween._startAt = Tween.set(targets, _setDefaults({ 6036 data: "isStart", 6037 overwrite: false, 6038 parent: parent, 6039 immediateRender: true, 6040 lazy: _isNotFalse(lazy), 6041 startAt: null, 6042 delay: 0, 6043 onUpdate: onUpdate, 6044 onUpdateParams: onUpdateParams, 6045 callbackScope: callbackScope, 6046 stagger: 0 6047 }, startAt))); //copy the properties/values into a new object to avoid collisions, like var to = {x:0}, from = {x:500}; timeline.fromTo(e, from, to).fromTo(e, to, from); 6048 6049 6050 if (immediateRender) { 6051 if (time > 0) { 6052 autoRevert || (tween._startAt = 0); //tweens that render immediately (like most from() and fromTo() tweens) shouldn't revert when their parent timeline's playhead goes backward past the startTime because the initial render could have happened anytime and it shouldn't be directly correlated to this tween's startTime. Imagine setting up a complex animation where the beginning states of various objects are rendered immediately but the tween doesn't happen for quite some time - if we revert to the starting values as soon as the playhead goes backward past the tween's startTime, it will throw things off visually. Reversion should only happen in Timeline instances where immediateRender was false or when autoRevert is explicitly set to true. 6053 } else if (dur && !(time < 0 && prevStartAt)) { 6054 time && (tween._zTime = time); 6055 return; //we skip initialization here so that overwriting doesn't occur until the tween actually begins. Otherwise, if you create several immediateRender:true tweens of the same target/properties to drop into a Timeline, the last one created would overwrite the first ones because they didn't get placed into the timeline yet before the first render occurs and kicks in overwriting. 6056 } 6057 } 6058 } else if (runBackwards && dur) { 6059 //from() tweens must be handled uniquely: their beginning values must be rendered but we don't want overwriting to occur yet (when time is still 0). Wait until the tween actually begins before doing all the routines like overwriting. At that time, we should render at the END of the tween to ensure that things initialize correctly (remember, from() tweens go backwards) 6060 if (prevStartAt) { 6061 !autoRevert && (tween._startAt = 0); 6062 } else { 6063 time && (immediateRender = false); //in rare cases (like if a from() tween runs and then is invali
6063date()-ed), immediateRender could be true but the initial forced-render gets skipped, so there's no need to force the render in this context when the _time is greater than 0 6064 6065 p = _setDefaults({ 6066 overwrite: false, 6067 data: "isFromStart", 6068 //we tag the tween with as "isFromStart" so that if [inside a plugin] we need to only do something at the very END of a tween, we have a way of identifying this tween as merely the one that's setting the beginning values for a "from()" tween. For example, clearProps in CSSPlugin should only get applied at the very END of a tween and without this tag, from(...{height:100, clearProps:"height", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in. 6069 lazy: immediateRender && _isNotFalse(lazy), 6070 immediateRender: immediateRender, 6071 //zero-duration tweens render immediately by default, but if we're not specifically instructed to render this tween immediately, we should skip this and merely _init() to record the starting values (rendering them immediately would push them to completion which is wasteful in that case - we'd have to render(-1) immediately after) 6072 stagger: 0, 6073 parent: parent //ensures that nested tweens that had a stagger are handled properly, like gsap.from(".class", {y:gsap.utils.wrap([-100,100])}) 6074 6075 }, cleanVars); 6076 harnessVars && (p[harness.prop] = harnessVars); // in case someone does something like .from(..., {css:{}}) 6077 6078 _removeFromParent(tween._startAt = Tween.set(targets, p)); 6079 6080 if (!immediateRender) { 6081 _initTween(tween._startAt, _tinyNum); //ensures that the initial values are recorded 6082 6083 } else if (!time) { 6084 return; 6085 } 6086 } 6087 } 6088 6089 tween._pt = 0; 6090 lazy = dur && _isNotFalse(lazy) || lazy && !dur; 6091 6092 for (i = 0; i < targets.length; i++) { 6093 target = targets[i]; 6094 gsData = target._gsap || _harness(targets)[i]._gsap; 6095 tween._ptLookup[i] = ptLookup = {}; 6096 _lazyLookup[gsData.id] && _lazyTweens.length && _lazyRender(); //if other tweens of the same target have recently initted but haven't rendered yet, we've got to force the render so that the starting values are correct (imagine populating a timeline with a bunch of sequential tweens and then jumping to the end) 6097 6098 index = fullTargets === targets ? i : fullTargets.indexOf(target); 6099 6100 if (harness && (plugin = new harness()).init(target, harnessVars || cleanVars, tween, index, fullTargets) !== false) { 6101 tween._pt = pt = new PropTween(tween._pt, target, plugin.name, 0, 1, plugin.render, plugin, 0, plugin.priority); 6102 6103 plugin._props.forEach(function (name) { 6104 ptLookup[name] = pt; 6105 }); 6106 6107 plugin.priority && (hasPriority = 1); 6108 } 6109 6110 if (!harness || harnessVars) { 6111 for (p in cleanVars) { 6112 if (_plugins[p] && (plugin = _checkPlugin(p, cleanVars, tween, index, target, fullTargets))) { 6113 plugin.priority && (hasPriority = 1); 6114 } else { 6115 ptLookup[p] = pt = _addPropTween.call(tween, target, p, "get", cleanVars[p], index, fullTargets, 0, vars.stringFilter); 6116 } 6117 } 6118 } 6119 6120 tween._op && tween._op[i] && tween.kill(target, tween._op[i]); 6121 6122 if (autoOverwrite && tween._pt) { 6123 _overwritingTween = tween; 6124 6125 _globalTimeline.killTweensOf(target, ptLookup, tween.globalTime(0)); //Also make sure the overwriting doesn't overwrite THIS tween!!! 6126 6127 6128 overwritten = !tween.parent; 6129 _overwritingTween = 0; 6130 } 6131 6132 tween._pt && lazy && (_lazyLookup[gsData.id] = 1); 6133 } 6134 6135 hasPriority && _sortPropTweensByPriority(tween); 6136 tween._onInit && tween._onInit(tween); //plugins like RoundProps must wait until ALL of the PropTweens are instantiated. In the plugin's init() function, it sets the _onInit on the tween instance. May not be pretty/intuitive, but it's fast and keeps file size down. 6137 } 6138 6139 tween._from = !tl && !!vars.runBackwards; //nested timelines should never run backwards - the backwards-ness is in the child tweens. 6140 6141 tween._onUpdate = onUpdate; 6142 tween._initted = (!tween._op || tween._pt) && !overwritten;
6142 // if overwrittenProps resulted in the entire tween being killed, do NOT flag it as initted or else it may render for one tick. 6143}, 6144 _addAliasesToVars = function _addAliasesToVars(targets, vars) { 6145 var harness = targets[0] ? _getCache(targets[0]).harness : 0, 6146 propertyAliases = harness && harness.aliases, 6147 copy, 6148 p, 6149 i, 6150 aliases; 6151 6152 if (!propertyAliases) { 6153 return vars; 6154 } 6155 6156 copy = _merge({}, vars); 6157 6158 for (p in propertyAliases) { 6159 if (p in copy) { 6160 aliases = propertyAliases[p].split(","); 6161 i = aliases.length; 6162 6163 while (i--) { 6164 copy[aliases[i]] = copy[p]; 6165 } 6166 } 6167 } 6168 6169 return copy; 6170}, 6171 _parseFuncOrString = function _parseFuncOrString(value, tween, i, target, targets) { 6172 return _isFunction(value) ? value.call(tween, i, target, targets) : _isString(value) && ~value.indexOf("random(") ? _replaceRandom(value) : value; 6173}, 6174 _staggerTweenProps = _callbackNames + "repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase", 6175 _staggerPropsToSkip = (_staggerTweenProps + ",id,stagger,delay,duration,paused,scrollTrigger").split(","); 6176/* 6177 * -------------------------------------------------------------------------------------- 6178 * TWEEN 6179 * -------------------------------------------------------------------------------------- 6180 */ 6181 6182 6183var Tween = /*#__PURE__*/function (_Animation2) { 6184 _inheritsLoose(Tween, _Animation2); 6185 6186 function Tween(targets, vars, time, skipInherit) { 6187 var _this3; 6188 6189 if (typeof vars === "number") { 6190 time.duration = vars; 6191 vars = time; 6192 time = null; 6193 } 6194 6195 _this3 = _Animation2.call(this, skipInherit ? vars : _inheritDefaults(vars), time) || this; 6196 var _this3$vars = _this3.vars, 6197 duration = _this3$vars.duration, 6198 delay = _this3$vars.delay, 6199 immediateRender = _this3$vars.immediateRender, 6200 stagger = _this3$vars.stagger, 6201 overwrite = _this3$vars.overwrite, 6202 keyframes = _this3$vars.keyframes, 6203 defaults = _this3$vars.defaults, 6204 scrollTrigger = _this3$vars.scrollTrigger, 6205 yoyoEase = _this3$vars.yoyoEase, 6206 parent = _this3.parent, 6207 parsedTargets = (_isArray(targets) || _isTypedArray(targets) ? _isNumber(targets[0]) : "length" in vars) ? [targets] : toArray(targets), 6208 tl, 6209 i, 6210 copy, 6211 l, 6212 p, 6213 curTarget, 6214 staggerFunc, 6215 staggerVarsToMerge; 6216 _this3._targets = parsedTargets.length ? _harness(parsedTargets) : _warn("GSAP target " + targets + " not found. https://greensock.com", !_config.nullTargetWarn) || []; 6217 _this3._ptLookup = []; //PropTween lookup. An array containing an object for each target, having keys for each tweening property 6218 6219 _this3._overwrite = overwrite; 6220 6221 if (keyframes || stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) { 6222 vars = _this3.vars; 6223 tl = _this3.timeline = new Timeline({ 6224 data: "nested", 6225 defaults: defaults || {} 6226 }); 6227 tl.kill(); 6228 tl.parent = tl._dp = _assertThisInitialized(_this3); 6229 tl._start = 0; 6230 6231 if (keyframes) { 6232 _setDefaults(tl.vars.defaults, { 6233 ease: "none" 6234 }); 6235 6236 keyframes.forEach(function (frame) { 6237 return tl.to(parsedTargets, frame, ">"); 6238 }); 6239 } else { 6240 l = parsedTargets.length; 6241 staggerFunc = stagger ? distribute(stagger) : _emptyFunc; 6242 6243 if (_isObject(stagger)) { 6244 //users can pass in callbacks like onStart/onComplete in the stagger object. These should fire with each individual tween. 6245 for (p in stagger) { 6246 if (~_staggerTweenProps.indexOf(p)) { 6247 staggerVarsToMerge || (staggerVarsToMerge = {}); 6248 staggerVarsToMerge[p] = stagger[p]; 6249 } 6250 } 6251 } 6252 6253 for (i = 0; i < l; i++) { 6254 copy = {}; 6255 6256 for (p in vars) { 6257 if (_staggerPropsToSkip.indexOf(p) < 0) { 6258 copy[p] = vars[p]; 6259 } 6260 } 6261 6262 copy.stagger = 0; 6263 yoyoEase && (copy.yoyoEase = yoyoEase); 6264 staggerVarsToMerge && _merge(copy, staggerVarsToMerge); 6265 curTarget = parsedTargets[i]; //don't just copy duration or delay because if they're a string or function, we'd end up in an infinite loop because _isFuncOrString() would evaluate as true in the child tweens, entering this loop, etc. So we parse the value straight from vars and default to 0. 6266 6267 copy.duration = +_parseFuncOrString(duration, _assertThisInitialized(_this3), i, curTarget, parsedTargets); 6268 copy.delay = (+_parseFuncOrString(delay, _assertThisInitialized(_this3), i, curTarget, parsedTargets) || 0) - _this3._delay; 6269 6270 if (!stagger && l === 1 && copy.delay) { 6271 // if someone does delay:"random(1, 5)", repeat:-1, for example, the delay
6271shouldn't be inside the repeat. 6272 _this3._delay = delay = copy.delay; 6273 _this3._start += delay; 6274 copy.delay = 0; 6275 } 6276 6277 tl.to(curTarget, copy, staggerFunc(i, curTarget, parsedTargets)); 6278 } 6279 6280 tl.duration() ? duration = delay = 0 : _this3.timeline = 0; // if the timeline's duration is 0, we don't need a timeline internally! 6281 } 6282 6283 duration || _this3.duration(duration = tl.duration()); 6284 } else { 6285 _this3.timeline = 0; //speed optimization, faster lookups (no going up the prototype chain) 6286 } 6287 6288 if (overwrite === true && !_suppressOverwrites) { 6289 _overwritingTween = _assertThisInitialized(_this3); 6290 6291 _globalTimeline.killTweensOf(parsedTargets); 6292 6293 _overwritingTween = 0; 6294 } 6295 6296 parent && _postAddChecks(parent, _assertThisInitialized(_this3)); 6297 6298 if (immediateRender || !duration && !keyframes && _this3._start === _round(parent._time) && _isNotFalse(immediateRender) && _hasNoPausedAncestors(_assertThisInitialized(_this3)) && parent.data !== "nested") { 6299 _this3._tTime = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render) 6300 6301 _this3.render(Math.max(0, -delay)); //in case delay is negative 6302 6303 } 6304 6305 scrollTrigger && _scrollTrigger(_assertThisInitialized(_this3), scrollTrigger); 6306 return _this3; 6307 } 6308 6309 var _proto3 = Tween.prototype; 6310 6311 _proto3.render = function render(totalTime, suppressEvents, force) { 6312 var prevTime = this._time, 6313 tDur = this._tDur, 6314 dur = this._dur, 6315 tTime = totalTime > tDur - _tinyNum && totalTime >= 0 ? tDur : totalTime < _tinyNum ? 0 : totalTime, 6316 time, 6317 pt, 6318 iteration, 6319 cycleDuration, 6320 prevIteration, 6321 isYoyo, 6322 ratio, 6323 timeline, 6324 yoyoEase; 6325 6326 if (!dur) { 6327 _renderZeroDurationTween(this, totalTime, suppressEvents, force); 6328 } else if (tTime !== this._tTime || !totalTime || force || !this._initted && this._tTime || this._startAt && this._zTime < 0 !== totalTime < 0) { 6329 //this senses if we're crossing over the start time, in which case we must record _zTime and force the render, but we do it in this lengthy conditional way for performance reasons (usually we can skip the calculations): this._initted && (this._zTime < 0) !== (totalTime < 0) 6330 time = tTime; 6331 timeline = this.timeline; 6332 6333 if (this._repeat) { 6334 //adjust the time for repeats and yoyos 6335 cycleDuration = dur + this._rDelay; 6336 6337 if (this._repeat < -1 && totalTime < 0) { 6338 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 6339 } 6340 6341 time = _round(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!) 6342 6343 if (tTime === tDur) { 6344 // the tDur === tTime is for edge cases where there's a lengthy decimal on the duration and it may reach the very end but the time is rendered as not-quite-there (remember, tDur is rounded to 4 decimals whereas dur isn't) 6345 iteration = this._repeat; 6346 time = dur; 6347 } else { 6348 iteration = ~~(tTime / cycleDuration); 6349 6350 if (iteration && iteration === tTime / cycleDuration) { 6351 time = dur; 6352 iteration--; 6353 } 6354 6355 time > dur && (time = dur); 6356 } 6357 6358 isYoyo = this._yoyo && iteration & 1; 6359 6360 if (isYoyo) { 6361 yoyoEase = this._yEase; 6362 time = dur - time; 6363 } 6364 6365 prevIteration = _animationCycle(this._tTime, cycleDuration); 6366 6367 if (time === prevTime && !force && this._initted) { 6368 //could be during the repeatDelay part. No need to render and fire callbacks. 6369 return this; 6370 } 6371 6372 if (iteration !== prevIteration) { 6373 timeline && this._yEase && _propagateYoyoEase(timeline, isYoyo); //repeatRefresh functionality 6374 6375 if (this.vars.repeatRefresh && !isYoyo && !this._lock) { 6376 this._lock = force = 1; //force, otherwise if lazy is true, the _attemptInitTween() will return and we'll jump out and get caught bouncing on each tick. 6377 6378 this.render(_round(cycleDuration * iteration), true).invalidate()._lock = 0; 6379 } 6380 } 6381 } 6382 6383 if (!this._initted) { 6384 if (_attemptInitTween(this, totalTime < 0 ? totalTime : time, force, suppressEvents)) { 6385 this._tTime = 0; // in constructor if immediateRender is true, we set _tTime to -_tinyNum to have the playhead cross the starting point but we can't leave _tTime as a negative number. 6386 6387 return this; 6388 } 6389 6390 if (dur !== this._dur) { 6391 // while initting, a plugin like InertiaPlugin might alter the duration, so rerun from the start to ensure everything renders as it should. 6392 return this.render(totalTime, suppressEvents, force); 6393 } 6394 } 6395 6396 this._tTime = tTime; 6397 this._time = time; 6398 6399 if (!this._act && this._ts) { 6400 this._act = 1; //as long as it's not paused, force it to be active so that if the user renders independent of the parent timeline, it'll be forced to re-render on the next tick. 6401 6402 this._lazy = 0; 6403 } 6404 6405 this.ratio = ratio = (yoyoEase || this._ease)(time / dur); 6406 6407 if (this._from) { 6408 this.ratio = ratio = 1 - ratio; 6409 } 6410
6411 time && !prevTime && !suppressEvents && _callback(this, "onStart"); 6412 pt = this._pt; 6413 6414 while (pt) { 6415 pt.r(ratio, pt.d); 6416 pt = pt._next; 6417 } 6418 6419 timeline && timeline.render(totalTime < 0 ? totalTime : !time && isYoyo ? -_tinyNum : timeline._dur * ratio, suppressEvents, force) || this._startAt && (this._zTime = totalTime); 6420 6421 if (this._onUpdate && !suppressEvents) { 6422 totalTime < 0 && this._startAt && this._startAt.render(totalTime, true, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete. 6423 6424 _callback(this, "onUpdate"); 6425 } 6426 6427 this._repeat && iteration !== prevIteration && this.vars.onRepeat && !suppressEvents && this.parent && _callback(this, "onRepeat"); 6428 6429 if ((tTime === this._tDur || !tTime) && this._tTime === tTime) { 6430 totalTime < 0 && this._startAt && !this._onUpdate && this._startAt.render(totalTime, true, true); 6431 (totalTime || !dur) && (tTime === this._tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); // don't remove if we're rendering at exactly a time of 0, as there could be autoRevert values that should get set on the next tick (if the playhead goes backward beyond the startTime, negative totalTime). Don't remove if the timeline is reversed and the playhead isn't at 0, otherwise tl.progress(1).reverse() won't work. Only remove if the playhead is at the end and timeScale is positive, or if the playhead is at 0 and the timeScale is negative. 6432 6433 if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime)) { 6434 // if prevTime and tTime are zero, we shouldn't fire the onReverseComplete. This could happen if you gsap.to(... {paused:true}).play(); 6435 _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true); 6436 6437 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 6438 } 6439 } 6440 } 6441 6442 return this; 6443 }; 6444 6445 _proto3.targets = function targets() { 6446 return this._targets; 6447 }; 6448
vendor: 16,343 bytes, lines 6449-6966
6449 _proto3.invalidate = function invalidate() { 6450 this._pt = this._op = this._startAt = this._onUpdate = this._lazy = this.ratio = 0; 6451 this._ptLookup = []; 6452 this.timeline && this.timeline.invalidate(); 6453 return _Animation2.prototype.invalidate.call(this); 6454 }; 6455 6456 _proto3.kill = function kill(targets, vars) { 6457 if (vars === void 0) { 6458 vars = "all"; 6459 } 6460 6461 if (!targets && (!vars || vars === "all")) { 6462 this._lazy = this._pt = 0; 6463 return this.parent ? _interrupt(this) : this; 6464 } 6465 6466 if (this.timeline) { 6467 var tDur = this.timeline.totalDuration(); 6468 this.timeline.killTweensOf(targets, vars, _overwritingTween && _overwritingTween.vars.overwrite !== true)._first || _interrupt(this); // if nothing is left tweening, interrupt. 6469 6470 this.parent && tDur !== this.timeline.totalDuration() && _setDuration(this, this._dur * this.timeline._tDur / tDur, 0, 1); // if a nested tween is killed that changes the duration, it should affect this tween's duration. We must use the ratio, though, because sometimes the internal timeline is stretched like for keyframes where they don't all add up to whatever the parent tween's duration was set to. 6471 6472 return this; 6473 } 6474 6475 var parsedTargets = this._targets, 6476 killingTargets = targets ? toArray(targets) : parsedTargets, 6477 propTweenLookup = this._ptLookup, 6478 firstPT = this._pt, 6479 overwrittenProps, 6480 curLookup, 6481 curOverwriteProps, 6482 props, 6483 p, 6484 pt, 6485 i; 6486 6487 if ((!vars || vars === "all") && _arraysMatch(parsedTargets, killingTargets)) { 6488 vars === "all" && (this._pt = 0); 6489 return _interrupt(this); 6490 } 6491 6492 overwrittenProps = this._op = this._op || []; 6493 6494 if (vars !== "all") { 6495 //so people can pass in a comma-delimited list of property names 6496 if (_isString(vars)) { 6497 p = {}; 6498 6499 _forEachName(vars, function (name) { 6500 return p[name] = 1; 6501 }); 6502 6503 vars = p; 6504 } 6505 6506 vars = _addAliasesToVars(parsedTargets, vars); 6507 } 6508 6509 i = parsedTargets.length; 6510 6511 while (i--) { 6512 if (~killingTargets.indexOf(parsedTargets[i])) { 6513 curLookup = propTweenLookup[i]; 6514 6515 if (vars === "all") { 6516 overwrittenProps[i] = vars; 6517 props = curLookup; 6518 curOverwriteProps = {}; 6519 } else { 6520 curOverwriteProps = overwrittenProps[i] = overwrittenProps[i] || {}; 6521 props = vars; 6522 } 6523 6524 for (p in props) { 6525 pt = curLookup && curLookup[p]; 6526 6527 if (pt) { 6528 if (!("kill" in pt.d) || pt.d.kill(p) === true) { 6529 _removeLinkedListItem(this, pt, "_pt"); 6530 } 6531 6532 delete curLookup[p]; 6533 } 6534 6535 if (curOverwriteProps !== "all") { 6536 curOverwriteProps[p] = 1; 6537 } 6538 } 6539 } 6540 } 6541 6542 this._initted && !this._pt && firstPT && _interrupt(this); //if all tweening properties are killed, kill the tween. Without this line, if there's a tween with multiple targets and then you killTweensOf() each target individually, the tween would technically still remain active and fire its onComplete even though there aren't any more properties tweening. 6543 6544 return this; 6545 }; 6546 6547 Tween.to = function to(targets, vars) { 6548 return new Tween(targets, vars, arguments[2]); 6549 }; 6550 6551 Tween.from = function from(targets, vars) { 6552 return new Tween(targets, _parseVars(arguments, 1)); 6553 }; 6554 6555 Tween.delayedCall = function delayedCall(delay, callback, params, scope) { 6556 return new Tween(callback, 0, { 6557 immediateRender: false, 6558 lazy: false, 6559 overwrite: false, 6560 delay: delay, 6561 onComplete: callback, 6562 onReverseComplete: callback, 6563 onCompleteParams: params, 6564 onReverseCompleteParams: params, 6565 callbackScope: scope 6566 }); 6567 }; 6568 6569 Tween.fromTo = function fromTo(targets, fromVars, toVars) { 6570 return new Tween(targets, _parseVars(arguments, 2)); 6571 }; 6572 6573 Tween.set = function set(targets, vars) { 6574 vars.duration = 0; 6575 vars.repeatDelay || (vars.repeat = 0); 6576 return new Tween(targets, vars); 6577 }; 6578 6579 Tween.killTweensOf = function killTweensOf(targets, props, onlyActive) { 6580 return _globalTimeline.killTweensOf(targets, props, onlyActive); 6581 }; 6582 6583 return Tween; 6584}(Animation); 6585 6586_setDefaults(Tween.prototype, { 6587 _targets: [], 6588 _lazy: 0, 6589 _startAt: 0, 6590 _op: 0, 6591 _onInit: 0 6592}); //add the pertinent timeline methods to Tween instances so that users can chain conveniently and create a timeline automatically. (removed due to concerns that it'd ultimately add to more confusion especially for beginners) 6593// _forEachName("to,from,fromTo,set,call,add,addLabel,addPause", name => { 6594// Tween.prototype[name] = function() { 6595// let tl = new Timeline(); 6596// return _addToTimeline(tl, this)[name].apply(tl, toArray(arguments)); 6597// } 6598// }); 6599//for backward compatibility. Leverage the timeline calls. 6600 6601 6602_forEachName("staggerTo,staggerFrom,staggerFromTo", function (name) { 6603 Tween[name] = function () { 6604 var tl = new Timeline(), 6605 params = _slice.call(arguments, 0); 6606 6607 params.splice(name === "staggerFromTo" ? 5 : 4, 0, 0); 6608 return tl[name].apply(tl, params); 6609 }; 6610}); 6611/* 6612 * -------------------------------------------------------------------------------------- 6613 * PROPTWEEN 6614 * -------------------------------------------------------------------------------------- 6615 */ 6616 6617 6618var _setterPlain = function _setterPlain(target, property, value) { 6619 return target[property] = value; 6620}, 6621 _setterFunc = function _setterFunc(target, property, value) { 6622 return target[property](value); 6623}, 6624 _setterFuncWithParam = function _setterFuncWithParam(target, property, value, data) { 6625 return target[property](data.fp, value); 6626}, 6627 _setterAttribute = function _setterAttribute(target, property, value) { 6628 return target.setAttribute(property, value); 6629}, 6630 _getSetter = function _getSetter(target, property) { 6631 return _isFunction(target[property]) ? _setterFunc : _isUndefined(target[property]) && target.setAttribute ? _setterAttribute : _setterPlain; 6632}, 6633 _renderPlain = function _renderPlain(ratio, data) { 6634 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000, data); 6635}, 6636 _renderBoolean = function _renderBoolean(ratio, data) { 6637 return data.set(data.t, data.p, !!(data.s + data.c * ratio), data); 6638}, 6639 _renderComplexString = function _renderComplexString(ratio, data) { 6640 var pt = data._pt, 6641 s = ""; 6642 6643 if (!ratio && data.b) { 6644 //b = beginning string 6645 s = data.b; 6646 } else if (ratio === 1 && data.e) { 6647 //e = ending string 6648 s = data.e; 6649 } else { 6650 while (pt) { 6651 s = pt.p + (pt.m ? pt.m(pt.s + pt.c * ratio) : Math.round((pt.s + pt.c * ratio) * 10000) / 10000) + s; //we use the "p" property for the text inbetween (like a suffix). And in the context of a complex string, the modifier (m) is typically just Math.round(), like for RGB colors. 6652 6653 pt = pt._next; 6654 } 6655 6656 s += data.c; //we use the "c" of the PropTween to store the final chunk of non-numeric text. 6657 } 6658 6659 data.set(data.t, data.p, s, data); 6660}, 6661 _renderPropTweens = function _renderPropTweens(ratio, data) { 6662 var pt = data._pt; 6663 6664 while (pt) { 6665 pt.r(ratio, pt.d); 6666 pt = pt._next; 6667 } 6668}, 6669 _addPluginModifier = function _addPluginModifier(modifier, tween, target, property) { 6670 var pt = this._pt, 6671 next; 6672 6673 while (pt) { 6674 next = pt._next; 6675 pt.p === property && pt.modifier(modifier, tween, target); 6676 pt = next; 6677 } 6678}, 6679 _killPropTweensOf = function _killPropTweensOf(property) { 6680 var pt = this._pt, 6681 hasNonDependentRemaining, 6682 next; 6683 6684 while (pt) { 6685 next = pt._next; 6686 6687 if (pt.p === property && !pt.op || pt.op === property) { 6688 _removeLinkedListItem(this, pt, "_pt"); 6689 } else if (!pt.dep) { 6690 hasNonDependentRemaining = 1; 6691 } 6692 6693 pt = next; 6694 } 6695 6696 return !hasNonDependentRemaining; 6697}, 6698 _setterWithModifier = function _setterWithModifier(target, property, value, data) { 6699 data.mSet(target, property, data.m.call(data.tween, value, data.mt), data); 6700}, 6701 _sortPropTweensByPriority = function _sortPropTweensByPriority(parent) { 6702 var pt = parent._pt, 6703 next, 6704 pt2, 6705 first, 6706 last; //sorts the PropTween linked list in order of priority because some plugins need to do their work after ALL of the PropTweens were created (like RoundPropsPlugin and ModifiersPlugin) 6707 6708 while (pt) { 6709 next = pt._next; 6710 pt2 = first; 6711 6712 while (pt2 && pt2.pr > pt.pr) { 6713 pt2 = pt2._next; 6714 } 6715 6716 if (pt._prev = pt2 ? pt2._prev : last) { 6717 pt._prev._next = pt; 6718 } else { 6719 first = pt; 6720 } 6721 6722 if (pt._next = pt2) { 6723 pt2._prev = pt; 6724 } else { 6725 last = pt; 6726 } 6727 6728 pt = next; 6729 } 6730 6731 parent._pt = first; 6732}; //PropTween key: t = target, p = prop, r = renderer, d = data, s = start, c = change, op = overwriteProperty (ONLY populated when it's different than p), pr = priority, _next/_prev for the linked list siblings, set = setter, m = modifier, mSet = modifierSetter (the original setter, before a modifier was added) 6733 6734 6735var PropTween = /*#__PURE__*/function () { 6736 function PropTween(next, target, prop, start, change, renderer, data, setter, priority) { 6737 this.t = target; 6738 this.s = start; 6739 this.c = change; 6740 this.p = prop; 6741 this.r = renderer || _renderPlain; 6742 this.d = data || this; 6743 this.set = setter || _setterPlain; 6744 this.pr = priority || 0; 6745 this._next = next; 6746 6747 if (next) { 6748 next._prev = this; 6749 } 6750 } 6751 6752 var _proto4 = PropTween.prototype; 6753 6754 _proto4.modifier = function modifier(func, tween, target) { 6755 this.mSet = this.mSet || this.set; //in case it was already set (a PropTween can only have one modifier) 6756 6757 this.set = _setterWithModifier; 6758 this.m = func; 6759 this.mt = target; //modifier target 6760 6761 this.tween = tween; 6762 }; 6763 6764 return PropTween; 6765}(); //Initialization tasks 6766 6767_forEachName(_callbackNames + "parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger", function (name) { 6768 return _reservedProps[name] = 1; 6769}); 6770 6771_globals.TweenMax = _globals.TweenLite = Tween; 6772_globals.TimelineLite = _globals.TimelineMax = Timeline; 6773_globalTimeline = new Timeline({ 6774 sortChildren: false, 6775 defaults: _defaults, 6776 autoRemoveChildren: true, 6777 id: "root", 6778 smoothChildTiming: true 6779}); 6780_config.stringFilter = _colorStringFilter; 6781/* 6782 * -------------------------------------------------------------------------------------- 6783 * GSAP 6784 * -------------------------------------------------------------------------------------- 6785 */ 6786 6787var _gsap = { 6788 registerPlugin: function registerPlugin() { 6789 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 6790 args[_key2] = arguments[_key2]; 6791 } 6792 6793 args.forEach(function (config) { 6794 return _createPlugin(config); 6795 }); 6796 }, 6797 timeline: function timeline(vars) { 6798 return new Timeline(vars); 6799 }, 6800 getTweensOf: function getTweensOf(targets, onlyActive) { 6801 return _globalTimeline.getTweensOf(targets, onlyActive); 6802 }, 6803 getProperty: function getProperty(target, property, unit, uncache) { 6804 _isString(target) && (target = toArray(target)[0]); //in case selector text or an array is passed in 6805 6806 var getter = _getCache(target || {}).get, 6807 format = unit ? _passThrough : _numericIfPossible; 6808 6809 unit === "native" && (unit = ""); 6810 return !target ? target : !property ? function (property, unit, uncache) { 6811 return format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 6812 } : format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 6813 }, 6814 quickSetter: function quickSetter(target, property, unit) { 6815 target = toArray(target); 6816 6817 if (target.length > 1) { 6818 var setters = target.map(function (t) { 6819 return gsap.quickSetter(t, property, unit); 6820 }), 6821 l = setters.length; 6822 return function (value) { 6823 var i = l; 6824 6825 while (i--) { 6826 setters[i](value); 6827 } 6828 }; 6829 } 6830 6831 target = target[0] || {}; 6832 6833 var Plugin = _plugins[property], 6834 cache = _getCache(target), 6835 p = cache.harness && (cache.harness.aliases || {})[property] || property, 6836 // in case it's an alias, like "rotate" for "rotation". 6837 setter = Plugin ? function (value) { 6838 var p = new Plugin(); 6839 _quickTween._pt = 0; 6840 p.init(target, unit ? value + unit : value, _quickTween, 0, [target]); 6841 p.render(1, p); 6842 _quickTween._pt && _renderPropTweens(1, _quickTween); 6843 } : cache.set(target, p); 6844 6845 return Plugin ? setter : function (value) { 6846 return setter(target, p, unit ? value + unit : value, cache, 1); 6847 }; 6848 }, 6849 isTweening: function isTweening(targets) { 6850 return _globalTimeline.getTweensOf(targets, true).length > 0; 6851 }, 6852 defaults: function defaults(value) { 6853 value && value.ease && (value.ease = _parseEase(value.ease, _defaults.ease)); 6854 return _mergeDeep(_defaults, value || {}); 6855 }, 6856 config: function config(value) { 6857 return _mergeDeep(_config, value || {}); 6858 }, 6859 registerEffect: function registerEffect(_ref2) { 6860 var name = _ref2.name, 6861 effect = _ref2.effect, 6862 plugins = _ref2.plugins, 6863 defaults = _ref2.defaults, 6864 extendTimeline = _ref2.extendTimeline; 6865 (plugins || "").split(",").forEach(function (pluginName) { 6866 return pluginName && !_plugins[pluginName] && !_globals[pluginName] && _warn(name + " effect requires " + pluginName + " plugin."); 6867 }); 6868 6869 _effects[name] = function (targets, vars, tl) { 6870 return effect(toArray(targets), _setDefaults(vars || {}, defaults), tl); 6871 }; 6872 6873 if (extendTimeline) { 6874 Timeline.prototype[name] = function (targets, vars, position) { 6875 return this.add(_effects[name](targets, _isObject(vars) ? vars : (position = vars) && {}, this), position); 6876 }; 6877 } 6878 }, 6879 registerEase: function registerEase(name, ease) { 6880 _easeMap[name] = _parseEase(ease); 6881 }, 6882 parseEase: function parseEase(ease, defaultEase) { 6883 return arguments.length ? _parseEase(ease, defaultEase) : _easeMap; 6884 }, 6885 getById: function getById(id) { 6886 return _globalTimeline.getById(id); 6887 }, 6888 exportRoot: function exportRoot(vars, includeDelayedCalls) { 6889 if (vars === void 0) { 6890 vars = {}; 6891 } 6892 6893 var tl = new Timeline(vars), 6894 child, 6895 next; 6896 tl.smoothChildTiming = _isNotFalse(vars.smoothChildTiming); 6897 6898 _globalTimeline.remove(tl); 6899 6900 tl._dp = 0; //otherwise it'll get re-activated when adding children and be re-introduced into _globalTimeline's linked list (then added to itself). 6901 6902 tl._time = tl._tTime = _globalTimeline._time; 6903 child = _globalTimeline._first; 6904 6905 while (child) { 6906 next = child._next; 6907 6908 if (includeDelayedCalls || !(!child._dur && child instanceof Tween && child.vars.onComplete === child._targets[0])) { 6909 _addToTimeline(tl, child, child._start - child._delay); 6910 } 6911 6912 child = next; 6913 } 6914 6915 _addToTimeline(_globalTimeline, tl, 0); 6916 6917 return tl; 6918 }, 6919 utils: { 6920 wrap: wrap, 6921 wrapYoyo: wrapYoyo, 6922 distribute: distribute, 6923 random: random, 6924 snap: snap, 6925 normalize: normalize, 6926 getUnit: getUnit, 6927 clamp: clamp, 6928 splitColor: splitColor, 6929 toArray: toArray, 6930 mapRange: mapRange, 6931 pipe: pipe, 6932 unitize: unitize, 6933 interpolate: interpolate, 6934 shuffle: shuffle 6935 }, 6936 install: _install, 6937 effects: _effects, 6938 ticker: _ticker, 6939 updateRoot: Timeline.updateRoot, 6940 plugins: _plugins, 6941 globalTimeline: _globalTimeline, 6942 core: { 6943 PropTween: PropTween, 6944 globals: _addGlobal, 6945 Tween: Tween, 6946 Timeline: Timeline, 6947 Animation: Animation, 6948 getCache: _getCache, 6949 _removeLinkedListItem: _removeLinkedListItem, 6950 suppressOverwrites: function suppressOverwrites(value) { 6951 return _suppressOverwrites = value; 6952 } 6953 } 6954}; 6955 6956_forEachName("to,from,fromTo,delayedCall,set,killTweensOf", function (name) { 6957 return _gsap[name] = Tween[name]; 6958}); 6959 6960_ticker.add(Timeline.updateRoot); 6961 6962_quickTween = _gsap.to({}, { 6963 duration: 0 6964}); // ---- EXTRA PLUGINS -------------------------------------------------------- 6965 6966var _getPluginPropTween = function _getPluginPropTween(plugin, prop
6966) { 6967 var pt = plugin._pt; 6968 6969 while (pt && pt.p !== prop && pt.op !== prop && pt.fp !== prop) { 6970 pt = pt._next; 6971 } 6972 6973 return pt; 6974}, 6975 _addModifiers = function _addModifiers(tween, modifiers) { 6976 var targets = tween._targets, 6977 p, 6978 i, 6979 pt; 6980 6981 for (p in modifiers) { 6982 i = targets.length; 6983 6984 while (i--) { 6985 pt = tween._ptLookup[i][p]; 6986 6987 if (pt && (pt = pt.d)) { 6988 if (pt._pt) { 6989 // is a plugin 6990 pt = _getPluginPropTween(pt, p); 6991 } 6992 6993 pt && pt.modifier && pt.modifier(modifiers[p], tween, targets[i], p); 6994 } 6995 } 6996 } 6997}, 6998 _buildModifierPlugin = function _buildModifierPlugin(name, modifier) { 6999 return { 7000 name: name, 7001 rawVars: 1, 7002 //don't pre-process function-based values or "random()" strings. 7003 init: function init(target, vars, tween) { 7004 tween._onInit = function (tween) { 7005 var temp, p; 7006 7007 if (_isString(vars)) { 7008 temp = {}; 7009 7010 _forEachName(vars, function (name) { 7011 return temp[name] = 1; 7012 }); //if the user passes in a comma-delimited list of property names to roundProps, like "x,y", we round to whole numbers. 7013 7014 7015 vars = temp; 7016 } 7017 7018 if (modifier) { 7019 temp = {}; 7020 7021 for (p in vars) { 7022 temp[p] = modifier(vars[p]); 7023 } 7024 7025 vars = temp; 7026 } 7027 7028 _addModifiers(tween, vars); 7029 }; 7030 } 7031 }; 7032}; //register core plugins 7033 7034 7035var gsap = _gsap.registerPlugin({ 7036 name: "attr", 7037 init: function init(target, vars, tween, index, targets) { 7038 var p, pt; 7039 7040 for (p in vars) { 7041 pt = this.add(target, "setAttribute", (target.getAttribute(p) || 0) + "", vars[p], index, targets, 0, 0, p); 7042 pt && (pt.op = p); 7043 7044 this._props.push(p); 7045 } 7046 } 7047}, { 7048 name: "endArray", 7049 init: function init(target, value) { 7050 var i = value.length; 7051 7052 while (i--) { 7053 this.add(target, i, target[i] || 0, value[i]); 7054 } 7055 } 7056}, _buildModifierPlugin("roundProps", _roundModifier), _buildModifierPlugin("modifiers"), _buildModifierPlugin("snap", snap)) || _gsap; //to prevent the core plugins from being dropped via aggressive tree shaking, we must include them in the variable declaration in this way. 7057 7058Tween.version = Timeline.version = gsap.version = "3.6.0"; 7059_coreReady = 1; 7060 7061if (_windowExists()) { 7062 _wake(); 7063} 7064 7065var Power0 = _easeMap.Power0, 7066 Power1 = _easeMap.Power1, 7067 Power2 = _easeMap.Power2, 7068 Power3 = _easeMap.Power3, 7069 Power4 = _easeMap.Power4, 7070 Linear = _easeMap.Linear, 7071 Quad = _easeMap.Quad, 7072 Cubic = _easeMap.Cubic, 7073 Quart = _easeMap.Quart, 7074 Quint = _easeMap.Quint, 7075 Strong = _easeMap.Strong, 7076 Elastic = _easeMap.Elastic, 7077 Back = _easeMap.Back, 7078 SteppedEase = _easeMap.SteppedEase, 7079 Bounce = _easeMap.Bounce, 7080 Sine = _easeMap.Sine, 7081 Expo = _easeMap.Expo, 7082 Circ = _easeMap.Circ; 7083 7084 //export some internal methods/orojects for use in CSSPlugin so that we can externalize that file and allow custom builds that exclude it. 7085 7086 7087 7088/***/ }), 7089/* 11 */ 7090/***/ (function(module, exports, __webpack_require__) { 7091 7092var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 7093 * EvEmitter v1.1.0 7094 * Lil' event emitter 7095 * MIT License 7096 */ 7097 7098/* jshint unused: true, undef: true, strict: true */ 7099 7100( function( global, factory ) { 7101 // universal module definition 7102 /* jshint strict: false */ /* globals define, module, window */ 7103 if ( true ) { 7104 // AMD - RequireJS 7105 !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 7106 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 7107 (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : 7108 __WEBPACK_AMD_DEFINE_FACTORY__), 7109 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 7110 } else if ( typeof module == 'object' && module.exports ) { 7111 // CommonJS - Browserify, Webpack 7112 module.exports = factory(); 7113 } else { 7114 // Browser globals 7115 global.EvEmitter = factory(); 7116 } 7117 7118}( typeof window != 'undefined' ? window : this, function() { 7119 7120"use strict"; 7121 7122function EvEmitter() {} 7123 7124var proto = EvEmitter.prototype; 7125 7126proto.on = function( eventName, listener ) { 7127 if ( !eventName || !listener ) { 7128 return; 7129 } 7130 // set events hash 7131 var events = this._events = this._events || {}; 7132 // set listeners array 7133 var listeners = events[ eventName ] = events[ eventName ] || []; 7134 // only add once 7135 if ( listeners.indexOf( listener ) == -1 ) { 7136 listeners.push( listener ); 7137 } 7138 7139 return this; 7140}; 7141 7142proto.once = function( eventName, listener ) { 7143 if ( !eventName || !listener ) { 7144 return; 7145 } 7146 // add event 7147 this.on( eventName, listener ); 7148 // set once flag 7149 // set onceEvents hash 7150 var onceEvents = this._onceEvents = this._onceEvents || {}; 7151 // set onceListeners object 7152 var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 7153 // set flag 7154 onceListeners[ listener ] = true; 7155 7156 return this; 7157}; 7158 7159proto.off = function( eventName, listener ) { 7160 var listeners = this._events && this._events[ eventName ]; 7161 if ( !listeners || !listeners.length ) { 7162 return; 7163 } 7164 var index = listeners.indexOf( listener ); 7165 if ( index != -1 ) { 7166 listeners.splice( index, 1 ); 7167 } 7168 7169 return this; 7170}; 7171 7172proto.emitEvent = function( eventName, args ) { 7173 var listeners = this._events && this._events[ eventName ]; 7174 if ( !listeners || !listeners.length ) { 7175 return; 7176 } 7177 // copy over to avoid interference if .off() in listener 7178 listeners = listeners.slice(0); 7179 args = args || []; 7180 // once stuff 7181 var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 7182 7183 for ( var i=0; i < listeners.length; i++ ) { 7184 var listener = listeners[i] 7185 var isOnce = onceListeners && onceListeners[ listener ]; 7186 if ( isOnce ) { 7187 // remove listener 7188 // remove before trigger to prevent recursion 7189 this.off( eventName, listener ); 7190 // unset once flag 7191 delete onceListeners[ listener ]; 7192 } 7193 // trigger listener 7194 listener.apply( this, args ); 7195 } 7196 7197 return this; 7198}; 7199 7200proto.allOff = function() { 7201 delete this._events; 7202 delete this._onceEvents; 7203}; 7204 7205return EvEmitter; 7206 7207})); 7208 7209 7210/***/ }), 7211/* 12 */ 7212/***/ (function(module, exports, __webpack_require__) { 7213 7214var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 7215 * matchesSelector v2.0.2 7216 * matchesSelector( element, '.selector' ) 7217 * MIT license 7218 */ 7219 7220/*jshint browser: true, strict: true, undef: true, unused: true */ 7221 7222( function( window, factory ) { 7223 /*global define: false, module: false */ 7224 'use strict'; 7225 // universal module definition 7226 if ( true ) { 7227 // AMD 7228 !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 7229 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 7230 (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : 7231 __WEBPACK_AMD_DEFINE_FACTORY__),
7232 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 7233 } else if ( typeof module == 'object' && module.exports ) { 7234 // CommonJS 7235 module.exports = factory(); 7236 } else { 7237 // browser global 7238 window.matchesSelector = factory(); 7239 } 7240 7241}( window, function factory() { 7242 'use strict'; 7243 7244 var matchesMethod = ( function() { 7245 var ElemProto = window.Element.prototype; 7246 // check for the standard method name first 7247 if ( ElemProto.matches ) { 7248 return 'matches'; 7249 } 7250 // check un-prefixed 7251 if ( ElemProto.matchesSelector ) { 7252 return 'matchesSelector'; 7253 } 7254 // check vendor prefixes 7255 var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; 7256 7257 for ( var i=0; i < prefixes.length; i++ ) { 7258 var prefix = prefixes[i]; 7259 var method = prefix + 'MatchesSelector'; 7260 if ( ElemProto[ method ] ) { 7261 return method; 7262 } 7263 } 7264 })(); 7265 7266 return function matchesSelector( elem, selector ) { 7267 return elem[ matchesMethod ]( selector ); 7268 }; 7269 7270})); 7271 7272 7273/***/ }), 7274/* 13 */ 7275/***/ (function(module, exports, __webpack_require__) { 7276 7277__webpack_require__(14); 7278module.exports = __webpack_require__(47); 7279 7280 7281/***/ }), 7282/* 14 */ 7283/***/ (function(module, __webpack_exports__, __webpack_require__) { 7284 7285"use strict"; 7286Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); 7287/* WEBPACK VAR INJECTION */(function(jQuery) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery__ = __webpack_require__(0); 7288/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_jquery__); 7289/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_focus_visible__ = __webpack_require__(15); 7290/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_focus_visible___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_focus_visible__); 7291/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__util_Router__ = __webpack_require__(16); 7292/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__routes_common__ = __webpack_require__(18); 7293/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__routes_home__ = __webpack_require__(40); 7294/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__routes_about__ = __webpack_require__(41); 7295/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__routes_contributors__ = __webpack_require__(42); 7296/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__routes_topicGuide__ = __webpack_require__(43); 7297/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__routes_episodes__ = __webpack_require__(44); 7298/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__routes_singleVideo__ = __webpack_require__(45); 7299/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__routes_singlePlaylist__ = __webpack_require__(46); 7300// import external dependencies 7301 7302 7303 7304// Import everything from autoload 7305//; 7306 7307// import local dependencies 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317// import archive from './routes/taxonomyTopic'; 7318 7319/** Populate Router instance with DOM routes */ 7320var routes = new __WEBPACK_IMPORTED_MODULE_2__util_Router__["a" /* default */]({ 7321 // All pages 7322 common: __WEBPACK_IMPORTED_MODULE_3__routes_common__["a" /* default */], 7323 // Home page 7324 home: __WEBPACK_IMPORTED_MODULE_4__routes_home__["a" /* default */], 7325 // About Us page, note the change from about-us to aboutUs. 7326 aboutUs: __WEBPACK_IMPORTED_MODULE_5__routes_about__["a" /* default */], 7327 contributors: __WEBPACK_IMPORTED_MODULE_6__routes_contributors__["a" /* default */], 7328 singleVideo: __WEBPACK_IMPORTED_MODULE_9__routes_singleVideo__["a" /* default */], 7329 singlePlaylist: __WEBPACK_IMPORTED_MODULE_10__routes_singlePlaylist__["a" /* default */], 7330 episodes: __WEBPACK_IMPORTED_MODULE_8__routes_episodes__["a" /* default */], 7331 topicGuide: __WEBPACK_IMPORTED_MODULE_7__routes_topicGuide__["a" /* default */], 7332 // archive, 7333}); 7334 7335// Load Events 7336jQuery(document).ready(function () { return routes.loadEvents(); }); 7337 7338/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(0))) 7339 7340/***/ }), 7341/* 15 */ 7342/***/ (function(module, exports, __webpack_require__) { 7343 7344(function (global, factory) { 7345 true ? factory() : 7346 typeof define === 'function' && define.amd ? define(factory) : 7347 (factory()); 7348}(this, (function () { 'use strict'; 7349 7350 /** 7351 * Applies the :focus-visible polyfill at the given scope. 7352 * A scope in this case is either the top-level Document or a Shadow Root. 7353 * 7354 * @param {(Document|ShadowRoot)} scope 7355 * @see https://github.com/WICG/focus-visible 7356 */ 7357 function applyFocusVisiblePolyfill(scope) { 7358 var hadKeyboardEvent = true; 7359 var hadFocusVisibleRecently = false;
vendor: 4,705 bytes, lines 7360-7519
7360 var hadFocusVisibleRecentlyTimeout = null; 7361 7362 var inputTypesAllowlist = { 7363 text: true, 7364 search: true, 7365 url: true, 7366 tel: true, 7367 email: true, 7368 password: true, 7369 number: true, 7370 date: true, 7371 month: true, 7372 week: true, 7373 time: true, 7374 datetime: true, 7375 'datetime-local': true 7376 }; 7377 7378 /** 7379 * Helper function for legacy browsers and iframes which sometimes focus 7380 * elements like document, body, and non-interactive SVG. 7381 * @param {Element} el 7382 */ 7383 function isValidFocusTarget(el) { 7384 if ( 7385 el && 7386 el !== document && 7387 el.nodeName !== 'HTML' && 7388 el.nodeName !== 'BODY' && 7389 'classList' in el && 7390 'contains' in el.classList 7391 ) { 7392 return true; 7393 } 7394 return false; 7395 } 7396 7397 /** 7398 * Computes whether the given element should automatically trigger the 7399 * `focus-visible` class being added, i.e. whether it should always match 7400 * `:focus-visible` when focused. 7401 * @param {Element} el 7402 * @return {boolean} 7403 */ 7404 function focusTriggersKeyboardModality(el) { 7405 var type = el.type; 7406 var tagName = el.tagName; 7407 7408 if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) { 7409 return true; 7410 } 7411 7412 if (tagName === 'TEXTAREA' && !el.readOnly) { 7413 return true; 7414 } 7415 7416 if (el.isContentEditable) { 7417 return true; 7418 } 7419 7420 return false; 7421 } 7422 7423 /** 7424 * Add the `focus-visible` class to the given element if it was not added by 7425 * the author. 7426 * @param {Element} el 7427 */ 7428 function addFocusVisibleClass(el) { 7429 if (el.classList.contains('focus-visible')) { 7430 return; 7431 } 7432 el.classList.add('focus-visible'); 7433 el.setAttribute('data-focus-visible-added', ''); 7434 } 7435 7436 /** 7437 * Remove the `focus-visible` class from the given element if it was not 7438 * originally added by the author. 7439 * @param {Element} el 7440 */ 7441 function removeFocusVisibleClass(el) { 7442 if (!el.hasAttribute('data-focus-visible-added')) { 7443 return; 7444 } 7445 el.classList.remove('focus-visible'); 7446 el.removeAttribute('data-focus-visible-added'); 7447 } 7448 7449 /** 7450 * If the most recent user interaction was via the keyboard; 7451 * and the key press did not include a meta, alt/option, or control key; 7452 * then the modality is keyboard. Otherwise, the modality is not keyboard. 7453 * Apply `focus-visible` to any current active element and keep track 7454 * of our keyboard modality state with `hadKeyboardEvent`. 7455 * @param {KeyboardEvent} e 7456 */ 7457 function onKeyDown(e) { 7458 if (e.metaKey || e.altKey || e.ctrlKey) { 7459 return; 7460 } 7461 7462 if (isValidFocusTarget(scope.activeElement)) { 7463 addFocusVisibleClass(scope.activeElement); 7464 } 7465 7466 hadKeyboardEvent = true; 7467 } 7468 7469 /** 7470 * If at any point a user clicks with a pointing device, ensure that we change 7471 * the modality away from keyboard. 7472 * This avoids the situation where a user presses a key on an already focused 7473 * element, and then clicks on a different element, focusing it with a 7474 * pointing device, while we still think we're in keyboard modality. 7475 * @param {Event} e 7476 */ 7477 function onPointerDown(e) { 7478 hadKeyboardEvent = false; 7479 } 7480 7481 /** 7482 * On `focus`, add the `focus-visible` class to the target if: 7483 * - the target received focus as a result of keyboard navigation, or 7484 * - the event target is an element that will likely require interaction 7485 * via the keyboard (e.g. a text box) 7486 * @param {Event} e 7487 */ 7488 function onFocus(e) { 7489 // Prevent IE from focusing the document or HTML element. 7490 if (!isValidFocusTarget(e.target)) { 7491 return; 7492 } 7493 7494 if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) { 7495 addFocusVisibleClass(e.target); 7496 } 7497 } 7498 7499 /** 7500 * On `blur`, remove the `focus-visible` class from the target. 7501 * @param {Event} e 7502 */ 7503 function onBlur(e) { 7504 if (!isValidFocusTarget(e.target)) { 7505 return; 7506 } 7507 7508 if ( 7509 e.target.classList.contains('focus-visible') || 7510 e.target.hasAttribute('data-focus-visible-added') 7511 ) { 7512 // To detect a tab/window switch, we look for a blur event followed 7513 // rapidly by a visibility change. 7514 // If we don't see a visibility change within 100ms, it's probably a 7515 // regular focus change. 7516 hadFocusVisibleRecently = true; 7517 window.clearTimeout(hadFocusVisibleRecentlyTimeout); 7518 hadFocusVisibleRecentlyTimeout = window.setTimeout(function() { 7519 hadFocusVisibleRecently = false;
7520 }, 100); 7521 removeFocusVisibleClass(e.target); 7522 } 7523 } 7524 7525 /** 7526 * If the user changes tabs, keep track of whether or not the previously 7527 * focused element had .focus-visible. 7528 * @param {Event} e 7529 */ 7530 function onVisibilityChange(e) { 7531 if (document.visibilityState === 'hidden') { 7532 // If the tab becomes active again, the browser will handle calling focus 7533 // on the element (Safari actually calls it twice). 7534 // If this tab change caused a blur on an element with focus-visible, 7535 // re-apply the class when the user switches back to the tab. 7536 if (hadFocusVisibleRecently) { 7537 hadKeyboardEvent = true; 7538 } 7539 addInitialPointerMoveListeners(); 7540 } 7541 } 7542 7543 /** 7544 * Add a group of listeners to detect usage of any pointing devices. 7545 * These listeners will be added when the polyfill first loads, and anytime 7546 * the window is blurred, so that they are active when the window regains 7547 * focus. 7548 */ 7549 function addInitialPointerMoveListeners() { 7550 document.addEventListener('mousemove', onInitialPointerMove); 7551 document.addEventListener('mousedown', onInitialPointerMove); 7552 document.addEventListener('mouseup', onInitialPointerMove); 7553 document.addEventListener('pointermove', onInitialPointerMove); 7554 document.addEventListener('pointerdown', onInitialPointerMove); 7555 document.addEventListener('pointerup', onInitialPointerMove); 7556 document.addEventListener('touchmove', onInitialPointerMove); 7557 document.addEventListener('touchstart', onInitialPointerMove); 7558 document.addEventListener('touchend', onInitialPointerMove); 7559 } 7560 7561 function removeInitialPointerMoveListeners() { 7562 document.removeEventListener('mousemove', onInitialPointerMove); 7563 document.removeEventListener('mousedown', onInitialPointerMove); 7564 document.removeEventListener('mouseup', onInitialPointerMove); 7565 document.removeEventListener('pointermove', onInitialPointerMove); 7566 document.removeEventListener('pointerdown', onInitialPointerMove); 7567 document.removeEventListener('pointerup', onInitialPointerMove); 7568 document.removeEventListener('touchmove', onInitialPointerMove); 7569 document.removeEventListener('touchstart', onInitialPointerMove); 7570 document.removeEventListener('touchend', onInitialPointerMove); 7571 } 7572 7573 /** 7574 * When the polfyill first loads, assume the user is in keyboard modality. 7575 * If any event is received from a pointing device (e.g. mouse, pointer, 7576 * touch), turn off keyboard modality. 7577 * This accounts for situations where focus enters the page from the URL bar. 7578 * @param {Event} e 7579 */ 7580 function onInitialPointerMove(e) { 7581 // Work around a Safari quirk that fires a mousemove on <html> whenever the 7582 // window blurs, even if you're tabbing out of the page. ¯\_(ã)_/¯ 7583 if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') { 7584 return; 7585 } 7586 7587 hadKeyboardEvent = false; 7588 removeInitialPointerMoveListeners(); 7589 } 7590 7591 // For some kinds of state, we are interested in changes at the global scope 7592 // only. For example, global pointer input, global key presses and global 7593 // visibility change should affect the state at every scope: 7594 document.addEventListener('keydown', onKeyDown, true); 7595 document.addEventListener('mousedown', onPointerDown, true); 7596 document.addEventListener('pointerdown', onPointerDown, true); 7597 document.addEventListener('touchstart', onPointerDown, true); 7598 document.addEventListener('visibilitychange', onVisibilityChange, true); 7599 7600 addInitialPointerMoveListeners(); 7601 7602 // For focus and blur, we specifically care about state changes in the local 7603 // scope. This is because focus / blur events that originate from within a 7604 // shadow root are not re-dispatched from the host element if it was already 7605 // the active element in its own scope: 7606 scope.addEventListener('focus', onFocus, true); 7607 scope.addEventListener('blur', onBlur, true); 7608 7609 // We detect that a node is a ShadowRoot by ensuring that it is a 7610 // DocumentFragment and also has a host property. This check covers native 7611 // implementation and polyfill implementation transparently. If we only cared 7612 // about the native implementation, we could just check if the scope was 7613 // an instance of a ShadowRoot. 7614 if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) { 7615 // Since a ShadowRoot is a special kind of DocumentFragment, it does not 7616 // have a root element to add a class to. So, we add this attribute to the 7617 // host element instead: 7618 scope.host.setAttribute('data-js-focus-visible', ''); 7619 } else if (scope.nodeType === Node.DOCUMENT_NODE) { 7620 document.documentElement.classList.add('js-focus-visible'); 7621 document.documentElement.setAttribute('data-js-focus-visible', ''); 7622 } 7623 } 7624 7625 // It is important to wrap all references to global window and document in 7626 // these checks to support server-side rendering use cases 7627 // @see https://github.com/WICG/focus-visible/issues/199 7628 if (typeof window !== 'undefined' && typeof document !== 'undefined') { 7629 // Make the polyfill helper globally available. This can be used as a signal 7630 // to interested libraries that wish to coordinate with the polyfill for e.g., 7631 // applying the polyfill to a shadow root: 7632 window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill; 7633 7634 // Notify interested libraries of the polyfill's presence, in case the 7635 // polyfill was loaded lazily: 7636 var event; 7637 7638 try { 7639 event = new CustomEvent('focus-visible-polyfill-ready'); 7640 } catch (error) { 7641 // IE11 does not support using CustomEvent as a constructor directly: 7642 event = document.createEvent('CustomEvent'); 7643 event.initCustomEvent('focus-visible-polyfill-ready', false, false, {}); 7644 } 7645 7646 window.dispatchEvent(event); 7647 } 7648 7649 if (typeof document !== 'undefined') { 7650 // Apply the polyfill to the global document, so that no JavaScript 7651 // coordination is required to use the polyfill in the top-level document: 7652 applyFocusVisiblePolyfill(document); 7653 } 7654 7655}))); 7656 7657 7658/***/ }), 7659/* 16 */ 7660/***/ (function(module, __webpack_exports__, __webpack_require__) { 7661 7662"use strict"; 7663/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__camelCase__ = __webpack_require__(17); 7664 7665 7666/** 7667 * DOM-based Routing 7668 * 7669 * Based on {@link http://goo.gl/EUTi53|Markup-based Unobtrusive Comprehensive DOM-ready Execution} by Paul Irish 7670 * 7671 * The routing fires all common scripts, followed by the page specific scripts. 7672 * Add additional events for more control over timing e.g. a finalize event 7673 */ 7674var Router = function Router(routes) { 7675 this.routes = routes; 7676}; 7677 7678/** 7679 * Fire Router events 7680 * @param {string} route DOM-based route derived from body classes (`<body class="...">`) 7681 * @param {string} [event] Events on the route. By default, `init` and `finalize` events are called. 7682 * @param {string} [arg] Any custom argument to be passed to the event. 7683 */ 7684Router.prototype.fire = function fire (route, event, arg) { 7685 if ( event === void 0 ) event = 'init'; 7686 7687 document.dispatchEvent(new CustomEvent('routed', { 7688 bubbles: true, 7689 detail: { 7690 route: route, 7691 fn: event, 7692 }, 7693 })); 7694 7695 var fire = route !== '' && this.routes[route] && typeof this.routes[route][event] === 'function'; 7696 if (fire) { 7697 this.routes[route][event](arg); 7698 } 7699}; 7700 7701/** 7702 * Automatically load and fire Router events 7703 * 7704 * Events are fired in the following order: 7705 ** common init 7706 ** page-specific init 7707 ** page-specific finalize 7708 ** common finalize 7709 */ 7710Router.prototype.loadEvents = function loadEvents () { 7711 var this$1 = this; 7712 7713 // Fire common init JS 7714 this.fire('common'); 7715 7716 // Fire page-specific init JS, and then finalize JS 7717 document.body.className 7718 .toLowerCase() 7719 .replace(/-/g, '_') 7720 .split(/\s+/) 7721 .map(__WEBPACK_IMPORTED_MODULE_0__camelCase__["a" /* default */]) 7722 .forEach(function (className) { 7723 this$1.fire(className); 7724 this$1.fire(className, 'finalize'); 7725 }); 7726 7727 // Fire common finalize JS 7728 this.fire('common', 'finalize'); 7729}; 7730 7731/* harmony default export */ __webpack_exports__["a"] = (Router); 7732 7733
7734/***/ }), 7735/* 17 */ 7736/***/ (function(module, __webpack_exports__, __webpack_require__) { 7737 7738"use strict"; 7739/** 7740 * the most terrible camelizer on the internet, guaranteed! 7741 * @param {string} str String that isn't camel-case, e.g., CAMeL_CaSEiS-harD 7742 * @return {string} String converted to camel-case, e.g., camelCaseIsHard 7743 */ 7744/* harmony default export */ __webpack_exports__["a"] = (function (str) { return ("" + (str.charAt(0).toLowerCase()) + (str.replace(/[\W_]/g, '|').split('|') 7745 .map(function (part) { return ("" + (part.charAt(0).toUpperCase()) + (part.slice(1))); }) 7746 .join('') 7747 .slice(1))); });; 7748 7749 7750/***/ }), 7751/* 18 */ 7752/***/ (function(module, __webpack_exports__, __webpack_require__) { 7753 7754"use strict"; 7755/* WEBPACK VAR INJECTION */(function($, jQuery) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_gsap__ = __webpack_require__(19); 7756/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_gsap_ScrollTrigger__ = __webpack_require__(21); 7757/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_slick_carousel__ = __webpack_require__(22); 7758/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_slick_carousel___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_slick_carousel__); 7759/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__util_playerLoader__ = __webpack_require__(4); 7760/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_magnific_popup__ = __webpack_require__(23); 7761/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_magnific_popup___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_magnific_popup__); 7762/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_imagesloaded__ = __webpack_require__(7); 7763/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_imagesloaded___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_imagesloaded__); 7764/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_isotope_layout__ = __webpack_require__(8); 7765/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_isotope_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_isotope_layout__); 7766/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_infinite_scroll__ = __webpack_require__(9); 7767/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_infinite_scroll___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_infinite_scroll__); 7768/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__selectize_selectize__ = __webpack_require__(37); 7769/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__selectize_selectize___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_8__selectize_selectize__); 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780/* harmony default export */ __webpack_exports__["a"] = ({ 7781 ajaxLoadMore: function ajaxLoadMore() { 7782 // AJAX Load More 7783 function visc_load_more() { 7784 // eslint-disable-next-line no-undef 7785 if (visceral_vars !== undefined) { 7786 var data = { 7787 action: 'visc_load_more', 7788 // eslint-disable-next-line no-undef 7789 query: visceral_vars.query, 7790 // eslint-disable-next-line no-undef 7791 paged: visceral_vars.current_page, 7792 // eslint-disable-next-line no-undef 7793 security: visceral_vars.security, 7794 }; 7795 7796 var $button = $('.btn--load-more'); 7797 7798 $.ajax({ 7799 // eslint-disable-next-line no-undef 7800 url: visceral_vars.ajaxurl, // AJAX handler 7801 data: data, 7802 type: 'POST', 7803 beforeSend: function () { 7804 $button.find('span').text('Loading...'); // change the button text, you can also add a preloader image 7805 }, 7806 complete: function () { 7807 this.itemReveal(); 7808 }, 7809 success: function (data) { 7810 $button.blur(); 7811 if (data) { 7812 $button.find('span').text('Load More'); 7813 7814 var $postsContainer = $( 7815 '.posts-list-container > div' 7816 ); 7817 $postsContainer.append(data); 7818 // eslint-disable-next-line no-undef 7819 visceral_vars.current_page++; 7820 // eslint-disable-next-line no-undef 7821 if ( 7822 // eslint-disable-next-line no-undef 7823 visceral_vars.current_page == 7824 // eslint-disable-next-line no-undef 7825 visceral_vars.max_page 7826 ) { 7827 $button.remove(); // if last page, remove the button 7828 } 7829 } else { 7830 $button.remove(); // if last page, remove the button 7831 } 7832 }, 7833 }); 7834 } 7835 } 7836 7837 $('.btn--load-more').on('click', function () { 7838 visc_load_more(); 7839 }); 7840 }, 7841 buttons: function buttons() { 7842 var btnPulse = document.querySelectorAll('.btn-pulse'); 7843 7844 if (btnPulse) { 7845 btnPulse.forEach(function (btn) { 7846 btn.innerHTML = '<span class="btn-pulse__outer" aria-hidden="true"><span class="btn-pulse__inner"></span></span>' + btn.innerHTML; 7847 }); 7848 } 7849 }, 7850 header: function header() { 7851 /** FIXED HEADER ANIMATION **/ 7852 var didScroll = false, 7853 scrollOffset = 100; 7854 7855 function scrollY() { 7856 return window.pageYOffset || document.documentElement.scrollTop; 7857 } 7858 7859 function scrollPage() { 7860 var sy = scrollY(); 7861 if (sy > scrollOffset) { 7862 $('.site-header--fixed').addClass(
7863 'site-header--scroll-triggered' 7864 ); 7865 } else { 7866 $('.site-header--fixed').removeClass( 7867 'site-header--scroll-triggered' 7868 ); 7869 } 7870 didScroll = false; 7871 } 7872 7873 window.addEventListener('load', scrollPage); 7874 window.addEventListener( 7875 'scroll', 7876 function () { 7877 // eslint-disable-line no-unused-vars 7878 if (!didScroll) { 7879 didScroll = true; 7880 setTimeout(scrollPage, 100); 7881 } 7882 }, 7883 false 7884 ); 7885 /** END FIXED HEADER ANIMATION **/ 7886 7887 /** SEARCH OVERLAY **/ 7888 var body = document.querySelector('body'); 7889 var siteSearch = document.querySelector('.site-search'); 7890 var searchWrap = document.querySelector('.site-header__search-wrap'); 7891 var searchIcon = document.querySelector('.site-header__search-icon'); 7892 7893 if (searchIcon) { 7894 searchIcon.addEventListener('click', function (e) { 7895 e.preventDefault(); 7896 }); 7897 } 7898 7899 // Fade in/out site search on hover of search icon 7900 if (searchWrap) { 7901 searchWrap.addEventListener('mouseenter', function () { 7902 body.classList.add('menu-active'); 7903 siteSearch.classList.add('site-search--active'); 7904 setTimeout(function () { 7905 document.querySelector('.site-search__form input[type="text"]').focus(); 7906 }, 800); 7907 }); 7908 7909 searchWrap.addEventListener('mouseleave', function () { 7910 body.classList.remove('menu-active'); 7911 siteSearch.classList.remove('site-search--active'); 7912 }); 7913 }
7914 /** END SEARCH OVERLAY **/ 7915 7916 // Mobile Icon 7917 $('.mobile-nav-icon').on('click', function () { 7918 $(this).toggleClass('mobile-nav-icon--active'); 7919 $('.site-header').toggleClass('site-header--mobile-nav-active'); 7920 $('body').toggleClass('mobile-nav-active'); 7921 }); 7922 7923 // Disable click on mobile 7924 $('.mobile-menu__item--parent .sub-menu-toggle').on( 7925 'click', 7926 function () { 7927 $(this) 7928 .parent('.mobile-menu__item') 7929 .toggleClass('mobile-menu__item--opened'); 7930 } 7931 ); 7932 }, 7933 infScroll: function infScroll() { 7934 var grid = document.querySelector('.listing--inf-scroll'); 7935 7936 if (grid) { 7937 var select = document.querySelector('.input-iso-select'); 7938 var iso; 7939 7940 // Instantiate selectize to use in conjunction 7941 if (select) { 7942 var $selectize = $('.input-iso-select').selectize({ 7943 create: true, 7944 sortField: 'text', 7945 }); 7946 } 7947 7948 __WEBPACK_IMPORTED_MODULE_5_imagesloaded___default()(grid, function () { 7949 if (select) { 7950 // images have loaded 7951 iso = new __WEBPACK_IMPORTED_MODULE_6_isotope_layout___default.a(grid, { 7952 itemSelector: '.col', 7953 layoutMode: 'fitRows', 7954 percentPosition: true, 7955 stagger: 100, 7956 fitRows: { 7957 // set to the element 7958 gutter: 16, 7959 columnWidth: '.col', 7960 }, 7961 hiddenStyle: { 7962 opacity: 0, 7963 transform: 'translateY(10px)', 7964 }, 7965 visibleStyle: { 7966 opacity: 1, 7967 transform: 'translateY(0px)', 7968 }, 7969 }); 7970 7971 // Filter on selection 7972 // check if selectize is active, and use that as a trigger if so 7973 if ($selectize) { 7974 // fetch the instance 7975 var selectize = $selectize[0].selectize; 7976 7977 selectize.on('change', function (e) { 7978 console.log(e); 7979 iso.arrange({ 7980 filter: e, 7981 }); 7982 7983 location.hash = 'filter=' + encodeURIComponent(e); 7984 }); 7985 } else { // otherwise, use the <select> 7986 // bind filter on select change 7987 select.addEventListener('change', function () { 7988 // get filter value from option value 7989 var filterValue = this.value; 7990 // console.log(filterValue); 7991 7992 iso.arrange({ 7993 filter: filterValue, 7994 }); 7995 7996 location.hash = 'filter=' + encodeURIComponent(filterValue); 7997 }); 7998 } 7999 8000 function getHashFilter() { // eslint-disable-line no-inner-declarations 8001 var hash = location.hash; // eslint-disable-line no-unused-vars 8002 // get filter=filterName 8003 var matches = location.hash.match(/filter=([^&]+)/i); 8004 var hashFilter = matches && matches[1]; 8005 return hashFilter && decodeURIComponent(hashFilter); 8006 } 8007 8008 var isIsotopeInit = false; 8009 8010 function onHashchange() { // eslint-disable-line no-inner-declarations 8011 var hashFilter = getHashFilter(); 8012 if (!hashFilter && isIsotopeInit) { 8013 return; 8014 } 8015 isIsotopeInit = true; 8016 // filter isotope 8017 iso.arrange({ 8018 filter: hashFilter, 8019 }); 8020 8021 // set selected class on button 8022 // if (hashFilter) { 8023 // $filters.find('.is-checked').removeClass('is-checked'); 8024 // $filters.find('[data-filter="' + hashFilter + '"]').addClass('is-checked'); 8025 // } 8026 } 8027 8028 $(window).on('hashchange', onHashchange); 8029 // trigger event handler to init Isotope 8030 onHashchange(); 8031 } 8032 8033 // make imagesLoaded available for InfiniteScroll 8034 // InfiniteScroll.imagesLoaded = imagesLoaded; 8035 8036 // Infinite scroll 8037 var infScroll = new __WEBPACK_IMPORTED_MODULE_7_infinite_scroll___default.a(grid, { // eslint-disable-line no-unused-vars 8038 path: '.next', 8039 append: '.inf-post', 8040 history: 'push', 8041 outlayer: iso, 8042 // debug: true, 8043 scrollThreshold: 450, 8044 hideNav: '.pagination', 8045 status: '.page-load-status', 8046 }); 8047 }); 8048 } 8049 },
8050 interestForm: function interestForm() { 8051 var form = document.querySelector('#register-interests'); 8052 if (form) { 8053 var nextBtn = document.querySelector('.register-interests__next'); 8054 var stepOne = document.querySelector('.register-interests__topics'); 8055 var stepTwo = document.querySelector('.register-interests__formats'); 8056 8057 // On click of Next, hide Step 1 and show Step 2 8058 nextBtn.addEventListener('click', function (e) { 8059 e.preventDefault(); 8060 stepOne.classList.add('register-interests__topics--hide'); 8061 stepTwo.classList.add('register-interests__formats--show'); 8062 }); 8063 8064 // For each choice, on click of the wrapper, check the corresponding checkbox 8065 var choices = document.querySelectorAll('.register-interests__choice'); 8066 choices.forEach(function (choice) { 8067 choice.addEventListener('click', function () { 8068 var checkbox = choice.querySelector('input[type="checkbox"]'); 8069 checkbox.checked = !checkbox.checked; 8070 choice.classList.toggle('register-interests__choice--checked'); 8071 }); 8072 }); 8073 } 8074 }, 8075 itemReveal: function itemReveal() { 8076 // eslint-disable-next-line no-unused-vars 8077 // var $itemReveals = $('.reveal').waypoint({ 8078 // handler: function () { 8079 // $(this)[0].element.classList.add('revealed'); 8080 // }, 8081 // offset: '85%', 8082 // }); 8083 8084 // Use gsap and ScrollTrigger 8085 __WEBPACK_IMPORTED_MODULE_0_gsap__["a" /* default */].registerPlugin(__WEBPACK_IMPORTED_MODULE_1_gsap_ScrollTrigger__["a" /* default */]); 8086 var reveals = __WEBPACK_IMPORTED_MODULE_0_gsap__["a" /* default */].utils.toArray('.reveal'); 8087 reveals.forEach(function (reveal) { 8088 __WEBPACK_IMPORTED_MODULE_1_gsap_ScrollTrigger__["a" /* default */].create({ 8089 trigger: reveal, 8090 start: 'top 75%', // when the top of the element is 75% from the top of the viewport 8091 toggleClass: 'revealed', 8092 // toggleActions: 'play pause resume none', 8093 once: true, // only trigger the toggle once. we can control repeat behavior using toggleActions 8094 }); 8095 }); 8096 8097 // Stagger reveals with a gsap.timeline() + ScrollTrigger 8098 var staggers = __WEBPACK_IMPORTED_MODULE_0_gsap__["a" /* default */].utils.toArray('.reveal--staggered'); 8099 staggers.forEach(function (stagger) { 8100 var tl = __WEBPACK_IMPORTED_MODULE_0_gsap__["a" /* default */].timeline({ 8101 scrollTrigger: { 8102 trigger: stagger, 8103 start: 'top 75%', 8104 }, 8105 }); 8106 8107 var children = stagger.children; // the immediate children elements of the current target 8108 8109 tl.to(children, { 8110 duration: 1, 8111 y: 0, 8112 opacity: 1, 8113 stagger: 0.15, 8114 }); 8115 }); 8116 }, 8117 kalturaSession: function kalturaSession() { 8118 var partnerId = '1529571'; 8119 var playerId = '49927973'; 8120 var videoPlayer = document.getElementById('bg-video-player'); 8121 var videoId = videoPlayer.dataset.video; 8122 var body = document.querySelector('body'); 8123 8124 // https://github.com/kaltura/kaltura-player-js 8125 // config options: https://developer.kaltura.com/player/web/configuration-web 8126 try { 8127 var kalturaPlayer = KalturaPlayer.setup({ // eslint-disable-line no-undef 8128 targetId: 'bg-video-player', 8129 provider: { 8130 partnerId: partnerId, 8131 uiConfId: playerId, 8132 }, 8133 playback: { 8134 autoplay: true, 8135 loop: true, 8136 muted: true, 8137 }, 8138 // plugins: { 8139 // googleTagManager: { 8140 // containerId: 'GTM-MF367DD', // formatted as GTM-XXXXXX 8141 // customEventsTracking: { 8142 // preset: { 8143 // coreEvents: true, // Default = false 8144 // UIEvents: true, // Default = false 8145 // playlistEvents: false, // Default = false 8146 // castEvents: false, // Default = false 8147 // }, 8148 // }, 8149 // }, 8150 // }, 8151 }); 8152 kalturaPlayer.loadMedia({ 8153 entryId: videoId, 8154 }); 8155 8156 // player events: https://github.com/kaltura/playkit-js/blob/master/src/event/event-type.js 8157 kalturaPlayer.ready().then(function () { 8158 setTimeout(function () { 8159 body.classList.add('loaded'); 8160 }, 500); 8161 }); 8162 8163 } catch (e) { 8164 console.error(e.message) 8165 } 8166 }, 8167 likeButton: function likeButton() { 8168 var button = document.querySelectorAll('.ctt-like-button-link'); 8169 8170 if (button) { 8171 button.forEach(function (element) { 8172 var postId = element.dataset.post_id; 8173 var userId = element.dataset.user_id; 8174 element.addEventListener('click', function (e) { 8175 e.preventDefault(); 8176 var process = element.dataset.process; // process changes on each click 8177 8178 jQuery.ajax({ 8179 type: 'POST', 8180 dataType: 'json', 8181 url: ajax_obj.ajax_url, // eslint-disable-line no-undef 8182 data: { 8183 action: 'like_button', 8184 post_id: postId, 8185 user_id: userId, 8186 process: process, 8187 _ajax_nonce: ajax_obj.like_nonce, // eslint-disable-line no-undef 8188 }, 8189 success: function (response) { 8190 if (response.type == 'success') { 8191 var params = new Proxy(new URLSearchParams(window.location.search), { 8192 get: function (searchParams, prop) { return searchParams.get(prop); }, 8193 }); 8194 if (params.profiletab == 'likes') { 8195 $(element.closest('.list-item--video-member')).fadeOut(); 8196 } else { 8197 element.dataset.process = response.process; 8198 8199 var type = ''; 8200 if (element.innerHTML.includes('video')) { type = 'video'; } 8201 if (element.innerHTML.includes('playlist')) { type = 'playlist'; } 8202 8203 element.innerHTML = '<i class="icon-heart"></i> ' + response.process + ' ' + type; 8204 } 8205 } else { 8206 console.log(response); 8207 } 8208 }, 8209 }); 8210 }); 8211 }); 8212 } 8213 }, 8214 links: function links() { 8215 /** SKIP LINK NAVIGATION */ 8216 $('#skip-to-content').click(function () { 8217 // strip the leading hash and declare 8218 // the content we're skipping to 8219 var skipTo = '#' + this.href.split('#')[1]; 8220 // Setting 'tabindex' to -1 takes an element out of normal 8221 // tab flow but allows it to be focused via javascript 8222 $(skipTo) 8223 .attr('tabindex', -1) 8224 .on('blur focusout', function () {
8225 // when focus leaves this element, 8226 // remove the tabindex attribute 8227 $(this).removeAttr('tabindex'); 8228 }) 8229 .focus(); // focus on the content container 8230 }); 8231 /** END SKIP LINK NAVIGATION */ 8232 8233 /** ANIMATED ANCHOR LINKS **/ 8234 $('a[href*="#"]:not([href="#"])').click(function (e) { 8235 // Doesn't do it on page builder tabs 8236 if (!$(this).hasClass('tab-toggle__link')) { 8237 if ( 8238 location.pathname.replace(/^\//, '') === 8239 this.pathname.replace(/^\//, '') && 8240 location.hostname === this.hostname 8241 ) { 8242 var target = $(this.hash); 8243 var $this = this; 8244 var header = $('header.site-header'); 8245 var wpAdminBar = $('#wpadminbar'); 8246 var fixedHeaderOffset = 8247 parseInt(header.outerHeight()) - 8248 parseInt( 8249 header.css('padding-top').replace('px', '') 8250 ); 8251 // If we're logged in and WP ADmin Bar exists, add it to the offset 8252 if (wpAdminBar.length) { 8253 fixedHeaderOffset += parseInt( 8254 wpAdminBar.outerHeight() 8255 ); 8256 } 8257 target = target.length 8258 ? target 8259 : $('[name=' + this.hash.slice(1) + ']'); 8260 if (target.length) { 8261 $('html,body').animate( 8262 { 8263 scrollTop: 8264 target.offset().top - fixedHeaderOffset, 8265 }, 8266 500, 8267 function () { 8268 if (history.pushState) { 8269 history.pushState( 8270 null, 8271 null, 8272 $this.hash 8273 ); 8274 } else { 8275 location.hash = $this.hash; 8276 } 8277 } 8278 ); 8279 e.preventDefault(); 8280 } 8281 } 8282 } 8283 }); 8284 /** END ANIMATED ANCHOR LINKS **/ 8285 8286 /** Break link text to new line when link text is a URL **/ 8287 $(document).ready(function () { 8288 $('a').each(function () { 8289 var $this = $(this); 8290 var innerLink = $this.text(); 8291 if (innerLink.startsWith('http')) { 8292 $this.css('word-break', 'break-all'); 8293 } 8294 }); 8295 }); 8296 /** End Break link text to new line when link text is a URL **/ 8297 8298 /** Back link */ 8299 var backLink = document.querySelector('.back-link a'); 8300 8301 if (backLink) { 8302 backLink.addEventListener('click', function (e) { 8303 e.preventDefault(); 8304 history.back(); 8305 }) 8306 } 8307 }, 8308 loadScript: function loadScript(src, callback) { 8309 var loaded = false; 8310 var tag = document.createElement('script'); 8311 var firstScriptTag = document.getElementsByTagName('script')[0]; 8312 if (!firstScriptTag) { 8313 // when loaded in jest without jsdom setup it doesn't get any element. 8314 // In jest it doesn't really make sense to do anything, because no one is watching youtube in jest 8315 return; 8316 } 8317 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 8318 tag.onload = function () { 8319 if (!loaded) { 8320 loaded = true; 8321 callback(); 8322 } 8323 }; 8324 tag.onreadystatechange = function () { 8325 if (!loaded && (this.readyState === 'complete' || this.readyState === 'loaded')) { 8326 loaded = true; 8327 callback(); 8328 } 8329 }; 8330 tag.src = src; 8331 }, 8332 magnificPopup: function magnificPopup() { 8333 var videoLink = $('.modal-link-video'); 8334 if (videoLink) { 8335 videoLink.magnificPopup({ 8336 // disableOn: 700, 8337 type: 'iframe', 8338 mainClass: 'mfp-fade', 8339 // removalDelay: 160, 8340 preloader: false,
8341 fixedContentPos: false, 8342 closeOnBgClick: true, 8343 enableEscapeKey: true, 8344 iframe: { 8345 markup: '<div class="mfp-iframe-scaler">' + 8346 '<div class="mfp-close"></div>' + 8347 '<iframe class="mfp-iframe" frameborder="0" allow="autoplay"></iframe>' + 8348 '</div>', 8349 patterns: { 8350 youtube: { 8351 index: 'youtube.com', 8352 id: 'v=', 8353 src: 'https://www.youtube.com/embed/%id%?rel=0&autoplay=1', 8354 }, 8355 }, 8356 }, 8357 srcAction: 'iframe_src', 8358 }); 8359 } 8360 8361 var htmlLink = $('.modal-link-html'); 8362 if (htmlLink) { 8363 htmlLink.magnificPopup({ 8364 // disableOn: 700, 8365 type: 'inline', 8366 midClick: true, 8367 mainClass: 'mfp-fade', 8368 // removalDelay: 160, 8369 // preloader: false, 8370 // fixedContentPos: false, 8371 closeBtnInside: true, 8372 }); 8373 } 8374 }, 8375 mainMenu: function mainMenu() { 8376 var body = document.querySelector('body'); 8377 var itemParent = document.querySelectorAll('.main-menu__item'); 8378 // let menu = document.querySelector('.main-menu'); 8379 8380 // On mouseover of a menu item with dropdown, fade in overlay 8381 if (itemParent) { 8382 itemParent.forEach(function (item) { 8383 item.addEventListener('mouseenter', function () { 8384 body.classList.add('menu-active'); 8385 }); 8386 8387 item.addEventListener('mouseleave', function () { 8388 body.classList.remove('menu-active'); 8389 }); 8390 }); 8391 } 8392 8393 // Sliding menu 8394 // ref: https://codyhouse.co/ds/components/app/drop-menu 8395 var topicMenuWrap = document.querySelector('.main-menu__item--topic-menu .main-menu__sub-menu'); 8396 8397 if (topicMenuWrap) { 8398 var topicMenu = topicMenuWrap.querySelector('.main-menu__item--parent'); 8399 if (topicMenu) { 8400 var parentLinks = topicMenu.querySelectorAll('.main-menu__sub-menu--2__item > .main-menu__sub-menu__link'); 8401 parentLinks.forEach(function (link) { 8402 var subMenu = link.nextElementSibling; // Shift in child topic menu 8403 link.addEventListener('click', function (e) { 8404 e.preventDefault(); 8405 topicMenu.classList.toggle('shifted'); 8406 subMenu.classList.toggle('in'); 8407 }); 8408 }); 8409 8410 var gParentLinks = topicMenu.querySelectorAll('.sub-menu__item--parent > .sub-menu__link'); 8411 gParentLinks.forEach(function (link) { 8412 var parentMenu = link.closest('.sub-menu'); // parent submenu 8413 var subMenu = link.nextElementSibling; // Shift in child topic menu 8414 link.addEventListener('click', function (e) { 8415 e.preventDefault(); 8416 parentMenu.classList.toggle('shifted'); 8417 subMenu.classList.toggle('in'); 8418 }); 8419 }); 8420 8421 // On Back link click, toggle class of parent menu and topicMenu 8422 var backLink = topicMenu.querySelectorAll('.sub-menu--topics-child > .sub-menu__item > .sub-menu__link--back'); 8423 backLink.forEach(function (link) { 8424 var parentMenu = link.closest('.sub-menu'); // parent submenu 8425 var topicMenu = link.closest('.main-menu__item--parent'); 8426 8427 link.addEventListener('click', function (e) { 8428 e.preventDefault(); 8429 parentMenu.classList.toggle('in'); 8430 topicMenu.classList.toggle('shifted'); 8431 }) 8432 }) 8433 8434 var gBackLink = topicMenu.querySelectorAll('.sub-menu
8434--topics-gchild > .sub-menu__item > .sub-menu__link--back'); 8435 gBackLink.forEach(function (link) { 8436 var parentMenu = link.closest('.sub-menu--topics-gchild'); // parent submenu 8437 var topicMenu = link.closest('.sub-menu--topics-child'); 8438 8439 link.addEventListener('click', function (e) { 8440 e.preventDefault(); 8441 parentMenu.classList.toggle('in'); 8442 topicMenu.classList.toggle('shifted'); 8443 }) 8444 }) 8445 } 8446 } 8447 }, 8448 mainNavAccessibility: function mainNavAccessibility() { 8449 var $mainNavigationTopLevelItemLinks = $( 8450 '.site-header .main-menu > .main-menu__item--parent > button' 8451 ); 8452 8453 if ($mainNavigationTopLevelItemLinks.length) { 8454 $mainNavigationTopLevelItemLinks.each(function () { 8455 $(this).prev('a').attr('aria-haspopup', 'true'); 8456 $(this).on('click', function () { 8457 $(this).closest('li').toggleClass('sub-menu-open'); 8458 $(this).attr('aria-expanded', 'true'); 8459 }); 8460 }); 8461 } 8462 }, 8463 masthead: function masthead() { 8464 /** MASTHEAD PRGRESSIVE IMAGES **/ 8465 var masthead = document.querySelector('.bg-img-load'), 8466 placeholderOverlay = document.querySelector('.masthead__overlay'); 8467 8468 if (masthead && placeholderOverlay) { 8469 // Load full size image. When loaded, fade our placeholder add it as bg to masthead 8470 var img = new Image(); 8471 img.src = masthead.dataset.imageSrc; 8472 img.onload = function () { 8473 placeholderOverlay.classList.add('fade-out'); 8474 masthead.style.backgroundImage = 'url(' + img.src + ')'; 8475 }; 8476 } 8477 /** END MASTHEAD PRGRESSIVE IMAGES **/ 8478 }, 8479 mastheadFade: function mastheadFade() { 8480 var mastheadMedia = document.querySelector('.masthead__media'); 8481 8482 if (mastheadMedia) { 8483 // Use gsap and ScrollTrigger 8484 __WEBPACK_IMPORTED_MODULE_0_gsap__["a" /* default */].registerPlugin(__WEBPACK_IMPORTED_MODULE_1_gsap_ScrollTrigger__["a" /* default */]); 8485 8486 __WEBPACK_IMPORTED_MODULE_0_gsap__["a" /* default */].to('.masthead__media', { 8487 opacity: 0, 8488 scrollTrigger: { 8489 trigger: '.masthead', 8490 scrub: true, 8491 start: 'top top', 8492 end: '+=50%', 8493 // markers: true, 8494 }, 8495 }); 8496 } 8497 }, 8498 onYouTubeIframeAPIReady: function onYouTubeIframeAPIReady() { 8499 // This function creates an <iframe> (and YouTube player) after the API code downloads. 8500 8501 // Video player output 8502 var player; 8503 var videoPlayer = document.getElementById('bg-video-player'); 8504 var videoUrl = videoPlayer.dataset.video; 8505 var body = document.querySelector('body'); 8506 8507 // Get the video ID 8508 var regex = /(https?:\/\/)?((www\.)?(youtube(-nocookie)?|youtube.googleapis)\.com.*(v\/|v=|vi=|vi\/|e\/|embed\/|user\/.*\/u\/\d+\/)|youtu\.be\/)([_0-9a-z-]+)/i; 8509 var videoId = videoUrl.match(regex); 8510 8511 window.YT.ready(function () { 8512 player = new window.YT.Player(videoPlayer, { // eslint-disable-line no-undef 8513 height: '390', 8514 width: '640', 8515 videoId: videoId[7], 8516 playerVars: { 8517 'playsinline': 1, 8518 'autoplay': 1, 8519 'controls': 0, 8520 'disablekb': 1, 8521 'enablejsapi': 1, 8522 'fs': 0, 8523 'loop': 1, 8524 'rel': 0, 8525 'modestbranding': 1, 8526 }, 8527 events: { 8528 'onReady': onPlayerReady, 8529 onStateChange: 8530 function (e) { 8531 if (e.data === window.YT.PlayerState.CUED || e.data === window.YT.PlayerState.UNSTARTED || e.data === window.YT.PlayerState.ENDED || e.data === window.YT.PlayerState.PAUSED) { 8532 player.playVideo(); 8533 } 8534 8535 // Add loaded state only once video is playing 8536 if (e.data === window.YT.PlayerState.PLAYING) { 8537 setTimeout(function () { 8538 body.classList.add('loaded'); 8539 }, 500); 8540 } 8541 }, 8542 }, 8543 }); 8544 8545 document.addEventListener('visibilitychange', function () { 8546 if (document.hidden) { 8547 console.log('not visible'); 8548 } else { 8549 console.log('is visible'); 8550 player.playVideo(); 8551 } 8552 }); 8553 }); 8554
8555 // Called when the player's state changes 8556 // Available states: buffering, unstarted, cued, playing, paused, ended 8557 function onPlayerReady() { 8558 player.playVideo(); 8559 player.mute(); 8560 } 8561 }, 8562 pageLoad: function pageLoad() { 8563 // Note that this is also fired on additional media events sitewide: 8564 // - Background YouTube videos: onYouTubeIframeAPIReady() 8565 // - Background Kaltura videos: kalturaSession() 8566 // - Homepage carousel: home.js 8567 8568 // Check if masthead background image 8569 var masthead = document.querySelector('.bg-img-load'), 8570 body = document.querySelector('body'); 8571 8572 if (masthead) { 8573 // Load full size image. When loaded, set body class to trigger page animations 8574 var img = new Image(); 8575 img.src = masthead.dataset.imageSrc; 8576 img.onload = function () { 8577 setTimeout(function () { 8578 body.classList.add('loaded'); 8579 }, 500); 8580 }; 8581 } else { 8582 // Default if no masthead media set 8583 setTimeout(function () { 8584 body.classList.add('loaded'); 8585 }, 500); 8586 } 8587 }, 8588 removeButton: function removeButton() { 8589 var button = document.querySelectorAll('.ctt-remove-button-link'); 8590 8591 if (button) { 8592 button.forEach(function (element) { 8593 var postId = element.dataset.post_id; 8594 var userId = element.dataset.user_id; 8595 element.addEventListener('click', function (e) { 8596 e.preventDefault(); 8597 var process = element.dataset.process; // process changes on each click 8598 8599 jQuery.ajax({ 8600 type: 'POST', 8601 dataType: 'json', 8602 url: ajax_obj.ajax_url, // eslint-disable-line no-undef 8603 data: { 8604 action: 'remove_button', 8605 post_id: postId, 8606 user_id: userId, 8607 process: process, 8608 _ajax_nonce: ajax_obj.remove_nonce, // eslint-disable-line no-undef 8609 }, 8610 success: function (response) { 8611 if (response.type == 'success') { 8612 var params = new Proxy(new URLSearchParams(window.location.search), { 8613 get: function (searchParams, prop) { return searchParams.get(prop); }, 8614 }); 8615 if (params.profiletab == 'history') { 8616 $(element.closest('.list-item--video-member')).fadeOut(); 8617 } else { 8618 console.log(response); 8619 } 8620 } 8621 }, 8622 }); 8623 }); 8624 }); 8625 } 8626 }, 8627 selectize: function selectize() { 8628 var selectize = $('.input--alt'); 8629 if (selectize) { 8630 $('.input--alt').selectize({ 8631 create: true, 8632 sortField: 'text', 8633 }); 8634 } 8635 }, 8636 slider: function slider() { 8637 // Include .visc-posts-list which is output from visceral-addons (elementor block) 8638 var visceralSlider = $('.visceral-slider'); 8639 8640 if (visceralSlider) { 8641 visceralSlider.each(function () { 8642 var slider = $(this); 8643 var slidesToShow = slider.attr('data-slides-to-show') ? slider.attr('data-slides-to-show') : 3; 8644 8645 slider.slick({ 8646 autoplay: false, 8647 fade: false, 8648 speed: 600, 8649 infinite: false, 8650 cssEase: 'ease', 8651 centerMode: false, 8652 slidesToShow: 1, 8653 slidesToScroll: 1, 8654 swipeToSlide: true, 8655 dots: true, 8656 arrows: true, 8657 mobileFirst: true, 8658 rows: 0, 8659 nextArrow: 8660 '<button type="button" class="slick-next"><span class="screen-reader-text">Next</span><i class="icon-chevron-right"></i></button>', 8661 prevArrow: 8662 '<button type="button" class="slick-prev"><span class="screen-reader-text">Previous</span><i class="icon-chevron-left"></i></button>', 8663 responsive: [ 8664 { 8665 breakpoint: 280, 8666 settings: { 8667 slidesToShow: 1, 8668 }, 8669 }, 8670 { 8671 breakpoint: 560, // min-width 8672 settings: { 8673 slidesToShow: 2, 8674 }, 8675 }, 8676 { 8677 breakpoint: 992, // min-width 8678 settings: { 8679 slidesToShow: parseInt(slidesToShow), 8680 }, 8681 } ], 8682 }); 8683 8684 // Counter 8685 var sliderItemsNum = slider.find('.slick-slide').not('.slick-cloned').length; 8686 if (sliderItemsNum > parseInt(slidesToShow)) {
8687 var counter = $('<div class="slick-counter"><span>' + sliderItemsNum + ' items</span></div>'); 8688 counter.insertBefore(slider); 8689 } 8690 }); 8691 } 8692 }, 8693 socialShare: function socialShare() { 8694 /** SOCIAL SHARE OVERLAY **/ 8695 var body = document.querySelector('body'); 8696 var shareLinks = document.querySelectorAll('.visc-social-share-btn'); 8697 var socialShare = document.querySelector('.visc-social-share'); 8698 var socialShareClose = document.querySelector('.visc-social-share__close'); 8699 8700 if (shareLinks && socialShare) { 8701 shareLinks.forEach(function (link) { 8702 link.addEventListener('click', function () { 8703 socialShare.classList.add('visc-social-share--active'); 8704 body.classList.toggle('menu-active'); 8705 }); 8706 socialShareClose.addEventListener('click', function () { 8707 socialShare.classList.remove('visc-social-share--active'); 8708 body.classList.remove('menu-active'); 8709 }); 8710 }) 8711 }
8712 /** END SOCIAL SHARE OVERLAY **/ 8713 }, 8714 subNavigation: function subNavigation() { 8715 var toggle = document.querySelectorAll('.sub-nav__list--toggle'); 8716 8717 if (toggle) { 8718 toggle.forEach(function (item) { 8719 var toggleLink = item.querySelectorAll('.sub-nav__link'); 8720 8721 toggleLink.forEach(function (link) { 8722 link.addEventListener('click', function (e) { 8723 e.preventDefault(); 8724 8725 [].forEach.call(toggleLink, function (el) { 8726 el.classList.remove('active'); 8727 }); 8728 8729 link.classList.add('active'); 8730 }); 8731 }); 8732 }); 8733 } 8734 }, 8735 subNavigationAjax: function subNavigationAjax() { 8736 var $contentContainer = $('.post-content'); 8737 var $subNavigation = $('.list--sub-page-menu'); 8738 8739 if ($subNavigation.length) { 8740 $subNavigation.each(function () { 8741 var $subNavigationItems = $(this).find('li'); 8742 var $activeSubNavigationLinks = $(this).find('li a'); 8743 $activeSubNavigationLinks.on('click', function (e) { 8744 e.preventDefault(); 8745 $subNavigationItems.removeClass('current-menu-item'); 8746 $(this).parent('li').addClass('current-menu-item'); 8747 var url = e.target.href; 8748 console.log(e); 8749 $.ajax({ 8750 url: url, 8751 dataType: 'html', 8752 beforeSend: function () { 8753 // Show the user something is happening 8754 // $postsListLoader.addClass("visc-posts-list__loader--active"); 8755 }, 8756 success: function (data) { 8757 // Get all the new content inside of the container 8758 var updatedContent = $(data).find('.post-content > *'); 8759 8760 // Display the new data in the container 8761 $contentContainer.empty(); 8762 $contentContainer.append(updatedContent); 8763 8764 // Scroll to the top of the list container 8765 // contentContainer.scrollIntoView({ 8766 // behavior: 'smooth', 8767 // block: 'start', 8768 // inline: 'nearest', 8769 // }); 8770 // Show the user the request is comlete 8771 // $postsListLoader.removeClass( 8772 // 'visc-posts-list__loader--active' 8773 // ); 8774 // Need to re-run this after each complete AJAX too 8775 // postsListPaginationAJAXHandler(); 8776 history.pushState('', document.title, url); 8777 // Create custom JS event to listen to for custom JS after AJAX is complete 8778 // $(document).trigger('visceralPage:ajaxSuccess'); 8779 // window.elementorFrontend.init(); 8780 }, 8781 }); 8782 }); 8783 }); 8784 } 8785 }, 8786 viewCounter: function viewCounter() { 8787 jQuery(document).ready(function () { 8788 jQuery.ajax({ 8789 type: 'post', 8790 dataType: 'json', 8791 url: ajax_obj.ajax_url, // eslint-disable-line no-undef 8792 data: { 8793 action: 'view_counter', 8794 post_id: ajax_obj.post_id, // eslint-disable-line no-undef 8795 }, 8796 success: function (response) { 8797 if (response.type != 'success') { 8798 //alert('Sorry, an error occured. Please try again.'); 8799 } else { 8800 //alert('Yay!'); 8801 } 8802 }, 8803 }); 8804 }); 8805 }, 8806 zendesk: function zendesk() { 8807 var footerLink = document.querySelector('.footer-menu__item--contact a'); 8808 var contactLink = document.querySelector('.contact-trigger'); 8809
8810 if (footerLink) { 8811 footerLink.addEventListener('click', function (e) { 8812 e.preventDefault(); 8813 8814 // Show the Zendesk widget 8815 zE('webWidget', 'open'); // eslint-disable-line no-undef 8816 }); 8817 } 8818 8819 if (contactLink) { 8820 contactLink.addEventListener('click', function (e) { 8821 e.preventDefault(); 8822 8823 // Show the Zendesk widget 8824 zE('webWidget', 'open'); // eslint-disable-line no-undef 8825 }); 8826 } 8827 }, 8828 init: function init() { 8829 // JavaScript to be fired on all pages 8830 8831 /** GLOBAL VARIABLES */ 8832 // var body = document.querySelector('body'); 8833 /** END GLOBAL VARIABLES */ 8834 8835 // Load more 8836 this.ajaxLoadMore(); 8837 8838 this.buttons(); 8839 8840 // Header 8841 this.header(); 8842 8843 // Footer 8844 this.zendesk(); 8845 8846 // Global reveal animations (consider commenting out this and 'gsap' and 'ScrollTrigger' import if not in use) 8847 this.itemReveal(); 8848 8849 // infinite scroll 8850 this.infScroll(); 8851 8852 // Interest form 8853 this.interestForm(); 8854 8855 // Like button 8856 this.likeButton(); 8857 8858 // Remove button 8859 this.removeButton(); 8860 8861 // Misc. link behaviors 8862 this.links(); 8863 8864 // Modals (consider comment out this and 'magnific-popup' import if not in use) 8865 this.magnificPopup(); 8866 8867 this.mainMenu(); 8868 8869 // Main Nav Accessibility 8870 this.mainNavAccessibility(); 8871 8872 // Masthead 8873 this.masthead(); 8874 this.mastheadFade(); 8875 8876 // Page load 8877 this.pageLoad(); 8878 8879 this.selectize(); 8880 8881 // Social share 8882 this.socialShare(); 8883 8884 // Slider (consider commenting out this and 'slick-carousel' import if not in use) 8885 this.slider(); 8886 8887 // Sub-nav linking 8888 this.subNavigation(); 8889 8890 // View Counter 8891 this.viewCounter(); 8892 8893 // Video player for background videos (masthead only) 8894 // See singleVideo.js for user initiated videos 8895 var videoPlayer = document.getElementById('bg-video-player'); 8896 if (videoPlayer) { 8897 var videoId = videoPlayer.dataset.video; 8898 var source = videoPlayer.dataset.source; 8899 // data-source resolves the platform; fall back to legacy detection. 8900 if (source === 'youtube' || (!source && videoId.indexOf('youtube') > -1)) { 8901 // Loads the IFrame Player API code asynchronously. 8902 this.loadScript('https://www.youtube.com/iframe_api', this.onYouTubeIframeAPIReady); 8903 } else if (source === 'bunny') { 8904 // Bunny Stream background video (muted, looping autoplay) 8905 Object(__WEBPACK_IMPORTED_MODULE_3__util_playerLoader__["a" /* loadBunnyPlayer */])(videoPlayer, { background: true }); 8906 } else { 8907 // Kaltura Web Player 8908 // Utilizes the TV Studio Player (V7) in Kaltura Management Console (KMC) 8909 // https://developer.kaltura.com/player/web/getting-started-web 8910 var partnerId = '1529571'; 8911 var playerId = '49927973'; 8912 this.loadScript('https://cdnapisec.kaltura.com/p/' + partnerId + '/embedPlaykitJs/uiconf_id/' + playerId, this.kalturaSession); 8913 } 8914 } 8915 }, 8916 finalize: function finalize() { 8917 // JavaScript to be fired on all pages, after page specific JS is fired 8918 }, 8919}); 8920 8921/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(0), __webpack_require__(0))) 8922 8923/***/ }), 8924/* 19 */ 8925/***/ (function(module, __webpack_exports__, __webpack_require__) { 8926 8927"use strict"; 8928/* unused harmony export gsap */ 8929/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return gsapWithCSS; }); 8930/* unused harmony export TweenMax */ 8931/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__ = __webpack_require__(10); 8932/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__CSSPlugin_js__ = __webpack_require__(20); 8933/* unused harmony reexport CSSPlugin */ 8934/* unused harmony reexport TweenLite */ 8935/* unused harmony reexport TimelineMax */ 8936/* unused harmony reexport TimelineLite */ 8937/* unused harmony reexport Power0 */ 8938/* unused harmony reexport Power1 */ 8939/* unused harmony reexport Power2 */ 8940/* unused harmony reexport Power3 */ 8941/* unused harmony reexport Power4 */ 8942/* unused harmony reexport Linear */ 8943/* unused harmony reexport Quad */ 8944/* unused harmony reexport Cubic */ 8945/* unused harmony reexport Quart */ 8946/* unused harmony reexport Quint */ 8947/* unused harmony reexport Strong */ 8948/* unused harmony reexport Elastic */ 8949/* unused harmony reexport Back */ 8950/* unused harmony reexport SteppedEase */ 8951/* unused harmony reexport Bounce */ 8952/* unused harmony reexport Sine */ 8953/* unused harmony reexport Expo */ 8954/* unused harmony reexport Circ */ 8955 8956 8957var gsapWithCSS = __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["w" /* gsap */].registerPlugin(__WEBPACK_IMPORTED_MODULE_1__CSSPlugin_js__["a" /* CSSPlugin */]) || __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["w" /* gsap */], 8958 // to protect from tree shaking 8959TweenMaxWithCSS = gsapWithCSS.core.Tween; 8960 8961 8962/***/ }), 8963/* 20 */ 8964/***/ (function(module, __webpack_exports__, __webpack_require__) { 8965 8966"use strict"; 8967/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return CSSPlugin; }); 8968/* unused harmony export default */ 8969/* unused harmony export _getBBox */ 8970/* unused harmony export _createElement */ 8971/* unused harmony export checkPrefix */ 8972/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__ = __webpack_require__(10); 8973/*! 8974 * CSSPlugin 3.6.0 8975 * https://greensock.com 8976 * 8977 * Copyright 2008-2021, GreenSock. All rights reserved. 8978 * Subject to the terms at https://greensock.com/standard-license or for 8979 * Club GreenSock members, the agreement issued with that membership. 8980 * @author: Jack Doyle, [email protected] 8981*/ 8982 8983/* eslint-disable */ 8984 8985 8986var _win, 8987 _doc, 8988 _docElement, 8989 _pluginInitted, 8990 _tempDiv, 8991 _tempDivStyler, 8992 _recentSetterPlugin, 8993 _windowExists = function _windowExists() { 8994 return typeof window !== "undefined"; 8995}, 8996 _transformProps = {}, 8997 _RAD2DEG = 180 / Math.PI, 8998 _DEG2RAD = Math.PI / 180, 8999 _atan2 = Math.atan2, 9000 _bigNum = 1e8, 9001 _capsExp = /([A-Z])/g, 9002 _horizontalExp = /(?:left|right|width|margin|padding|x)/i,
vendor: 11,308 bytes, lines 9003-9246
9003 _complexExp = /[\s,\(]\S/, 9004 _propertyAliases = { 9005 autoAlpha: "opacity,visibility", 9006 scale: "scaleX,scaleY", 9007 alpha: "opacity" 9008}, 9009 _renderCSSProp = function _renderCSSProp(ratio, data) { 9010 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 9011}, 9012 _renderPropWithEnd = function _renderPropWithEnd(ratio, data) { 9013 return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 9014}, 9015 _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) { 9016 return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data); 9017}, 9018 //if units change, we need a way to render the original unit/value when the tween goes all the way back to the beginning (ratio:0) 9019_renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) { 9020 var value = data.s + data.c * ratio; 9021 data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data); 9022}, 9023 _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) { 9024 return data.set(data.t, data.p, ratio ? data.e : data.b, data); 9025}, 9026 _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) { 9027 return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data); 9028}, 9029 _setterCSSStyle = function _setterCSSStyle(target, property, value) { 9030 return target.style[property] = value; 9031}, 9032 _setterCSSProp = function _setterCSSProp(target, property, value) { 9033 return target.style.setProperty(property, value); 9034}, 9035 _setterTransform = function _setterTransform(target, property, value) { 9036 return target._gsap[property] = value; 9037}, 9038 _setterScale = function _setterScale(target, property, value) { 9039 return target._gsap.scaleX = target._gsap.scaleY = value; 9040}, 9041 _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) { 9042 var cache = target._gsap; 9043 cache.scaleX = cache.scaleY = value; 9044 cache.renderTransform(ratio, cache); 9045}, 9046 _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) { 9047 var cache = target._gsap; 9048 cache[property] = value; 9049 cache.renderTransform(ratio, cache); 9050}, 9051 _transformProp = "transform", 9052 _transformOriginProp = _transformProp + "Origin", 9053 _supports3D, 9054 _createElement = function _createElement(type, ns) { 9055 var e = _doc.createElementNS ? _doc.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc.createElement(type); //some servers swap in https for http in the namespace which can break things, making "style" inaccessible. 9056 9057 return e.style ? e : _doc.createElement(type); //some environments won't allow access to the element's style when created with a namespace in which case we default to the standard createElement() to work around the issue. Also note that when GSAP is embedded directly inside an SVG file, createElement() won't allow access to the style object in Firefox (see https://greensock.com/forums/topic/20215-problem-using-tweenmax-in-standalone-self-containing-svg-file-err-cannot-set-property-csstext-of-undefined/). 9058}, 9059 _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) { 9060 var cs = getComputedStyle(target); 9061 return cs[property] || cs.getPropertyValue(property.replace(_capsExp, "-$1").toLowerCase()) || cs.getPropertyValue(property) || !skipPrefixFallback && _getComputedProperty(target, _checkPropPrefix(property) || property, 1) || ""; //css variables may not need caps swapped out for dashes and lowercase. 9062}, 9063 _prefixes = "O,Moz,ms,Ms,Webkit".split(","), 9064 _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) { 9065 var e = element || _tempDiv, 9066 s = e.style, 9067 i = 5; 9068 9069 if (property in s && !preferPrefix) { 9070 return property; 9071 } 9072 9073 property = property.charAt(0).toUpperCase() + property.substr(1); 9074 9075 while (i-- && !(_prefixes[i] + property in s)) {} 9076 9077 return i < 0 ? null : (i === 3 ? "ms" : i >= 0 ? _prefixes[i] : "") + property; 9078}, 9079 _initCore = function _initCore() { 9080 if (_windowExists() && window.document) { 9081 _win = window; 9082 _doc = _win.document; 9083 _docElement = _doc.documentElement; 9084 _tempDiv = _createElement("div") || { 9085 style: {} 9086 }; 9087 _tempDivStyler = _createElement("div"); 9088 _transformProp = _checkPropPrefix(_transformProp); 9089 _transformOriginProp = _transformProp + "Origin"; 9090 _tempDiv.style.cssText = "border-width:0;line-height:0;position:absolute;padding:0"; //make sure to override certain properties that may contaminate measurements, in case the user has overreaching style sheets. 9091 9092 _supports3D = !!_checkPropPrefix("perspective"); 9093 _pluginInitted = 1; 9094 } 9095}, 9096 _getBBoxHack = function _getBBoxHack(swapIfPossible) { 9097 //works around issues in some browsers (like Firefox) that don't correctly report getBBox() on SVG elements inside a <defs> element and/or <mask>. We try creating an SVG, adding it to the documentElement and toss the element in there so that it's definitely part of the rendering tree, then grab the bbox and if it works, we actually swap out the original getBBox() method for our own that does these extra steps whenever getBBox is needed. This helps ensure that performance is optimal (only do all these extra steps when absolutely necessary...most elements don't need it). 9098 var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"), 9099 oldParent = this.parentNode, 9100 oldSibling = this.nextSibling, 9101 oldCSS = this.style.cssText, 9102 bbox; 9103 9104 _docElement.appendChild(svg); 9105 9106 svg.appendChild(this); 9107 this.style.display = "block"; 9108 9109 if (swapIfPossible) { 9110 try { 9111 bbox = this.getBBox(); 9112 this._gsapBBox = this.getBBox; //store the original 9113 9114 this.getBBox = _getBBoxHack; 9115 } catch (e) {} 9116 } else if (this._gsapBBox) { 9117 bbox = this._gsapBBox(); 9118 } 9119 9120 if (oldParent) { 9121 if (oldSibling) { 9122 oldParent.insertBefore(this, oldSibling); 9123 } else { 9124 oldParent.appendChild(this); 9125 } 9126 } 9127 9128 _docElement.removeChild(svg); 9129 9130 this.style.cssText = oldCSS; 9131 return bbox; 9132}, 9133 _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) { 9134 var i = attributesArray.length; 9135 9136 while (i--) { 9137 if (target.hasAttribute(attributesArray[i])) { 9138 return target.getAttribute(attributesArray[i]); 9139 } 9140 } 9141}, 9142 _getBBox = function _getBBox(target) { 9143 var bounds; 9144 9145 try { 9146 bounds = target.getBBox(); //Firefox throws errors if you try calling getBBox() on an SVG element that's not rendered (like in a <symbol> or <defs>). https://bugzilla.mozilla.org/show_bug.cgi?id=612118 9147 } catch (error) { 9148 bounds = _getBBoxHack.call(target, true); 9149 } 9150 9151 bounds && (bounds.width || bounds.height) || target.getBBox === _getBBoxHack || (bounds = _getBBoxHack.call(target, true)); //some browsers (like Firefox) misreport the bounds if the element has zero width and height (it just assumes it's at x:0, y:0), thus we need to manually grab the position in that case. 9152 9153 return bounds && !bounds.width && !bounds.x && !bounds.y ? { 9154 x: +_getAttributeFallbacks(target, ["x", "cx", "x1"]) || 0, 9155 y: +_getAttributeFallbacks(target, ["y", "cy", "y1"]) || 0, 9156 width: 0, 9157 height: 0 9158 } : bounds; 9159}, 9160 _isSVG = function _isSVG(e) { 9161 return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e)); 9162}, 9163 //reports if the element is an SVG on which getBBox() actually works 9164_removeProperty = function _removeProperty(target, property) { 9165 if (property) { 9166 var style = target.style; 9167 9168 if (property in _transformProps && property !== _transformOriginProp) { 9169 property = _transformProp; 9170 } 9171 9172 if (style.removeProperty) { 9173 if (property.substr(0, 2) === "ms" || property.substr(0, 6) === "webkit") { 9174 //Microsoft and some Webkit browsers don't conform to the standard of capitalizing the first prefix character, so we adjust so that when we prefix the caps with a dash, it's correct (otherwise it'd be "ms-transform" instead of "-ms-transform" for IE9, for example) 9175 property = "-" + property; 9176 } 9177 9178 style.removeProperty(property.replace(_capsExp, "-$1").toLowerCase()); 9179 } else { 9180 //note: old versions of IE use "removeAttribute()" instead of "removeProperty()" 9181 style.removeAttribute(property); 9182 } 9183 } 9184}, 9185 _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) { 9186 var pt = new __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["b" /* PropTween */](plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue); 9187 plugin._pt = pt; 9188 pt.b = beginning; 9189 pt.e = end; 9190 9191 plugin._props.push(property); 9192 9193 return pt; 9194}, 9195 _nonConvertibleUnits = { 9196 deg: 1, 9197 rad: 1, 9198 turn: 1 9199}, 9200 //takes a single value like 20px and converts it to the unit specified, like "%", returning only the numeric amount. 9201_convertToUnit = function _convertToUnit(target, property, value, unit) { 9202 var curValue = parseFloat(value) || 0, 9203 curUnit = (value + "").trim().substr((curValue + "").length) || "px", 9204 // some browsers leave extra whitespace at the beginning of CSS variables, hence the need to trim() 9205 style = _tempDiv.style, 9206 horizontal = _horizontalExp.test(property), 9207 isRootSVG = target.tagName.toLowerCase() === "svg", 9208 measureProperty = (isRootSVG ? "client" : "offset") + (horizontal ? "Width" : "Height"), 9209 amount = 100, 9210 toPixels = unit === "px", 9211 toPercent = unit === "%", 9212 px, 9213 parent, 9214 cache, 9215 isSVG; 9216 9217 if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) { 9218 return curValue; 9219 } 9220 9221 curUnit !== "px" && !toPixels && (curValue = _convertToUnit(target, property, value, "px")); 9222 isSVG = target.getCTM && _isSVG(target); 9223 9224 if ((toPercent || curUnit === "%") && (_transformProps[property] || ~property.indexOf("adius"))) { 9225 px = isSVG ? target.getBBox()[horizontal ? "width" : "height"] : target[measureProperty]; 9226 return Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(toPercent ? curValue / px * amount : curValue / 100 * px); 9227 } 9228 9229 style[horizontal ? "width" : "height"] = amount + (toPixels ? curUnit : unit); 9230 parent = ~property.indexOf("adius") || unit === "em" && target.appendChild && !isRootSVG ? target : target.parentNode; 9231 9232 if (isSVG) { 9233 parent = (target.ownerSVGElement || {}).parentNode; 9234 } 9235 9236 if (!parent || parent === _doc || !parent.appendChild) { 9237 parent = _doc.body; 9238 } 9239 9240 cache = parent._gsap; 9241 9242 if (cache && toPercent && cache.width && horizontal && cache.time === __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["u" /* _ticker */].time) { 9243 return Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(curValue / cache.width * amount); 9244 } else { 9245 (toPercent || curUnit === "%") && (style.position = _getComputedProperty(target, "position")); 9246 parent === target && (style.position = "static"); // like for borderRadius, if it's a % we must have it relative to the target itself but that may not have position: relative or position: absolute in
9246which case it'd go up the chain until it finds its offsetParent (bad). position: static protects against that. 9247 9248 parent.appendChild(_tempDiv); 9249 px = _tempDiv[measureProperty]; 9250 parent.removeChild(_tempDiv); 9251 style.position = "absolute"; 9252 9253 if (horizontal && toPercent) { 9254 cache = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["g" /* _getCache */])(parent); 9255 cache.time = __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["u" /* _ticker */].time; 9256 cache.width = parent[measureProperty]; 9257 } 9258 } 9259 9260 return Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0); 9261}, 9262 _get = function _get(target, property, unit, uncache) { 9263 var value; 9264 _pluginInitted || _initCore(); 9265 9266 if (property in _propertyAliases && property !== "transform") { 9267 property = _propertyAliases[property]; 9268 9269 if (~property.indexOf(",")) { 9270 property = property.split(",")[0]; 9271 } 9272 } 9273 9274 if (_transformProps[property] && property !== "transform") { 9275 value = _parseTransform(target, uncache); 9276 value = property !== "transformOrigin" ? value[property] : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + " " + value.zOrigin + "px"; 9277 } else { 9278 value = target.style[property]; 9279 9280 if (!value || value === "auto" || uncache || ~(value + "").indexOf("calc(")) { 9281 value = _specialProps[property] && _specialProps[property](target, property, unit) || _getComputedProperty(target, property) || Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["h" /* _getProperty */])(target, property) || (property === "opacity" ? 1 : 0); // note: some browsers, like Firefox, don't report borderRadius correctly! Instead, it only reports every corner like borderTopLeftRadius 9282 } 9283 } 9284 9285 return unit && !~(value + "").trim().indexOf(" ") ? _convertToUnit(target, property, value, unit) + unit : value; 9286}, 9287 _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) { 9288 //note: we call _tweenComplexCSSString.call(pluginInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus "this" would refer to the plugin. 9289 if (!start || start === "none") { 9290 // some browsers like Safari actually PREFER the prefixed property and mis-report the unprefixed value like clipPath (BUG). In other words, even though clipPath exists in the style ("clipPath" in target.style) and it's set in the CSS properly (along with -webkit-clip-path), Safari reports clipPath as "none" whereas WebkitClipPath reports accurately like "ellipse(100% 0% at 50% 0%)", so in this case we must SWITCH to using the prefixed property instead. See https://greensock.com/forums/topic/18310-clippath-doesnt-work-on-ios/ 9291 var p = _checkPropPrefix(prop, target, 1), 9292 s = p && _getComputedProperty(target, p, 1); 9293 9294 if (s && s !== start) { 9295 prop = p; 9296 start = s; 9297 } else if (prop === "borderColor") { 9298 start = _getComputedProperty(target, "borderTopColor"); // Firefox bug: always reports "borderColor" as "", so we must fall back to borderTopColor. See https://greensock.com/forums/topic/24583-how-to-return-colors-that-i-had-after-reverse/ 9299 } 9300 } 9301 9302 var pt = new __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["b" /* PropTween */](this._pt, target.style, prop, 0, 1, __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["q" /* _renderComplexString */]), 9303 index = 0, 9304 matchIndex = 0, 9305 a, 9306 result, 9307 startValues, 9308 startNum, 9309 color, 9310 startValue, 9311 endValue, 9312 endNum, 9313 chunk, 9314 endUnit, 9315 startUnit, 9316 relative, 9317 endValues; 9318 pt.b = start; 9319 pt.e = end; 9320 start += ""; //ensure values are strings 9321 9322 end += ""; 9323 9324 if (end === "auto") { 9325 target.style[prop] = end; 9326 end = _getComputedProperty(target, prop) || end; 9327 target.style[prop] = start; 9328 } 9329 9330 a = [start, end]; 9331 9332 Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["d" /* _colorStringFilter */])(a); //pass an array with the starting and ending values and let the filter do whatever it needs to the values. If colors are found, it returns true and then we must match where the color shows up order-wise because for things like boxShadow, sometimes the browser provides the computed values with the color FIRST, but the user provides it with the color LAST, so flip them if necessary. Same for drop-shadow(). 9333 9334 9335 start = a[0]; 9336 end = a[1]; 9337 startValues = start.match(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["n" /* _numWithUnitExp */]) || []; 9338 endValues = end.match(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["n" /* _numWithUnitExp */]) || []; 9339 9340 if (endValues.length) { 9341 while (result = __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["n" /* _numWithUnitExp */].exec(end)) { 9342 endValue = result[0]; 9343 chunk = end.substring(index, result.index); 9344 9345 if (color) { 9346 color = (color + 1) % 5; 9347 } else if (chunk.substr(-5) === "rgba(" || chunk.substr(-5) === "hsla(") { 9348 color = 1; 9349 } 9350 9351 if (endValue !== (startValue = startValues[matchIndex++] || "")) { 9352 startNum = parseFloat(startValue) || 0; 9353 startUnit = startValue.substr((startNum + "").length); 9354 relative = endValue.charAt(1) === "=" ? +(endValue.charAt(0) + "1") : 0; 9355 9356 if (relative) { 9357 endValue = endValue.substr(2); 9358 } 9359 9360 endNum = parseFloat(endValue); 9361 endUnit = endValue.substr((endNum + "").length); 9362 index = __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["n" /* _numWithUnitExp */].lastIndex - endUnit.length; 9363 9364 if (!endUnit) { 9365 //if something like "perspective:300" is passed in and we must add a unit to the end 9366 endUnit = endUnit || __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["e" /* _config */].units[prop] || startUnit; 9367 9368 if (index === end.length) { 9369 end += endUnit; 9370 pt.e += endUnit; 9371 } 9372 } 9373 9374 if (startUnit !== endUnit) { 9375 startNum = _convertToUnit(target, prop, startValue, endUnit) || 0; 9376 } //these nested PropTweens are handled in a special way - we'll never actually call a render or setter method on them. We'll just loop through them in the parent complex string PropTween's render method. 9377 9378 9379 pt._pt = { 9380 _next: pt._pt, 9381 p: chunk || matchIndex === 1 ? chunk : ",",
vendor: 4,794 bytes, lines 9382-9513
9382 //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case. 9383 s: startNum, 9384 c: relative ? relative * endNum : endNum - startNum, 9385 m: color && color < 4 || prop === "zIndex" ? Math.round : 0 9386 }; 9387 } 9388 } 9389 9390 pt.c = index < end.length ? end.substring(index, end.length) : ""; //we use the "c" of the PropTween to store the final part of the string (after the last number) 9391 } else { 9392 pt.r = prop === "display" && end === "none" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue; 9393 } 9394 9395 __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["p" /* _relExp */].test(end) && (pt.e = 0); //if the end string contains relative values or dynamic random(...) values, delete the end it so that on the final render we don't actually set it to the string with += or -= characters (forces it to use the calculated value). 9396 9397 this._pt = pt; //start the linked list with this new PropTween. Remember, we call _tweenComplexCSSString.call(pluginInstance...) to ensure that it's scoped properly. We may call it from within another plugin too, thus "this" would refer to the plugin. 9398 9399 return pt; 9400}, 9401 _keywordToPercent = { 9402 top: "0%", 9403 bottom: "100%", 9404 left: "0%", 9405 right: "100%", 9406 center: "50%" 9407}, 9408 _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) { 9409 var split = value.split(" "), 9410 x = split[0], 9411 y = split[1] || "50%"; 9412 9413 if (x === "top" || x === "bottom" || y === "left" || y === "right") { 9414 //the user provided them in the wrong order, so flip them 9415 value = x; 9416 x = y; 9417 y = value; 9418 } 9419 9420 split[0] = _keywordToPercent[x] || x; 9421 split[1] = _keywordToPercent[y] || y; 9422 return split.join(" "); 9423}, 9424 _renderClearProps = function _renderClearProps(ratio, data) { 9425 if (data.tween && data.tween._time === data.tween._dur) { 9426 var target = data.t, 9427 style = target.style, 9428 props = data.u, 9429 cache = target._gsap, 9430 prop, 9431 clearTransforms, 9432 i; 9433 9434 if (props === "all" || props === true) { 9435 style.cssText = ""; 9436 clearTransforms = 1; 9437 } else { 9438 props = props.split(","); 9439 i = props.length; 9440 9441 while (--i > -1) { 9442 prop = props[i]; 9443 9444 if (_transformProps[prop]) { 9445 clearTransforms = 1; 9446 prop = prop === "transformOrigin" ? _transformOriginProp : _transformProp; 9447 } 9448 9449 _removeProperty(target, prop); 9450 } 9451 } 9452 9453 if (clearTransforms) { 9454 _removeProperty(target, _transformProp); 9455 9456 if (cache) { 9457 cache.svg && target.removeAttribute("transform"); 9458 9459 _parseTransform(target, 1); // force all the cached values back to "normal"/identity, otherwise if there's another tween that's already set to render transforms on this element, it could display the wrong values. 9460 9461 9462 cache.uncache = 1; 9463 } 9464 } 9465 } 9466}, 9467 // note: specialProps should return 1 if (and only if) they have a non-zero priority. It indicates we need to sort the linked list. 9468_specialProps = { 9469 clearProps: function clearProps(plugin, target, property, endValue, tween) { 9470 if (tween.data !== "isFromStart") { 9471 var pt = plugin._pt = new __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["b" /* PropTween */](plugin._pt, target, property, 0, 0, _renderClearProps); 9472 pt.u = endValue; 9473 pt.pr = -10; 9474 pt.tween = tween; 9475 9476 plugin._props.push(property); 9477 9478 return 1; 9479 } 9480 } 9481 /* className feature (about 0.4kb gzipped). 9482 , className(plugin, target, property, endValue, tween) { 9483 let _renderClassName = (ratio, data) => { 9484 data.css.render(ratio, data.css); 9485 if (!ratio || ratio === 1) { 9486 let inline = data.rmv, 9487 target = data.t, 9488 p; 9489 target.setAttribute("class", ratio ? data.e : data.b); 9490 for (p in inline) { 9491 _removeProperty(target, p); 9492 } 9493 } 9494 }, 9495 _getAllStyles = (target) => { 9496 let styles = {}, 9497 computed = getComputedStyle(target), 9498 p; 9499 for (p in computed) { 9500 if (isNaN(p) && p !== "cssText" && p !== "length") { 9501 styles[p] = computed[p]; 9502 } 9503 } 9504 _setDefaults(styles, _parseTransform(target, 1)); 9505 return styles; 9506 }, 9507 startClassList = target.getAttribute("class"), 9508 style = target.style, 9509 cssText = style.cssText, 9510 cache = target._gsap, 9511 classPT = cache.classPT, 9512 inlineToRemoveAtEnd = {}, 9513 data = {t:target, plugin:plugin, rmv:inlineToRemoveAtEnd, b:startClassList, e:(endValue.charAt(1) !== "=") ? endValue : startClassList.replace(new RegExp("(?:\\s|^)" + endValue.substr(2) + "(?![\\w-])"), "") + ((endValue.charAt(0) === "+") ? " " + endValue.substr(2) : "")},
9514 changingVars = {}, 9515 startVars = _getAllStyles(target), 9516 transformRelated = /(transform|perspective)/i, 9517 endVars, p; 9518 if (classPT) { 9519 classPT.r(1, classPT.d); 9520 _removeLinkedListItem(classPT.d.plugin, classPT, "_pt"); 9521 } 9522 target.setAttribute("class", data.e); 9523 endVars = _getAllStyles(target, true); 9524 target.setAttribute("class", startClassList); 9525 for (p in endVars) { 9526 if (endVars[p] !== startVars[p] && !transformRelated.test(p)) { 9527 changingVars[p] = endVars[p]; 9528 if (!style[p] && style[p] !== "0") { 9529 inlineToRemoveAtEnd[p] = 1; 9530 } 9531 } 9532 } 9533 cache.classPT = plugin._pt = new PropTween(plugin._pt, target, "className", 0, 0, _renderClassName, data, 0, -11); 9534 if (style.cssText !== cssText) { //only apply if things change. Otherwise, in cases like a background-image that's pulled dynamically, it could cause a refresh. See https://greensock.com/forums/topic/20368-possible-gsap-bug-switching-classnames-in-chrome/. 9535 style.cssText = cssText; //we recorded cssText before we swapped classes and ran _getAllStyles() because in cases when a className tween is overwritten, we remove all the related tweening properties from that class change (otherwise class-specific stuff can't override properties we've directly set on the target's style object due to specificity). 9536 } 9537 _parseTransform(target, true); //to clear the caching of transforms 9538 data.css = new gsap.plugins.css();
vendor: 4,308 bytes, lines 9539-9626
9539 data.css.init(target, changingVars, tween); 9540 plugin._props.push(...data.css._props); 9541 return 1; 9542 } 9543 */ 9544 9545}, 9546 9547/* 9548 * -------------------------------------------------------------------------------------- 9549 * TRANSFORMS 9550 * -------------------------------------------------------------------------------------- 9551 */ 9552_identity2DMatrix = [1, 0, 0, 1, 0, 0], 9553 _rotationalProperties = {}, 9554 _isNullTransform = function _isNullTransform(value) { 9555 return value === "matrix(1, 0, 0, 1, 0, 0)" || value === "none" || !value; 9556}, 9557 _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) { 9558 var matrixString = _getComputedProperty(target, _transformProp); 9559 9560 return _isNullTransform(matrixString) ? _identity2DMatrix : matrixString.substr(7).match(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["m" /* _numExp */]).map(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */]); 9561}, 9562 _getMatrix = function _getMatrix(target, force2D) { 9563 var cache = target._gsap || Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["g" /* _getCache */])(target), 9564 style = target.style, 9565 matrix = _getComputedTransformMatrixAsArray(target), 9566 parent, 9567 nextSibling, 9568 temp, 9569 addedToDOM; 9570 9571 if (cache.svg && target.getAttribute("transform")) { 9572 temp = target.transform.baseVal.consolidate().matrix; //ensures that even complex values like "translate(50,60) rotate(135,0,0)" are parsed because it mashes it into a matrix. 9573 9574 matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f]; 9575 return matrix.join(",") === "1,0,0,1,0,0" ? _identity2DMatrix : matrix; 9576 } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) { 9577 //note: if offsetParent is null, that means the element isn't in the normal document flow, like if it has display:none or one of its ancestors has display:none). Firefox returns null for getComputedStyle() if the element is in an iframe that has display:none. https://bugzilla.mozilla.org/show_bug.cgi?id=548397 9578 //browsers don't report transforms accurately unless the element is in the DOM and has a display value that's not "none". Firefox and Microsoft browsers have a partial bug where they'll report transforms even if display:none BUT not any percentage-based values like translate(-50%, 8px) will be reported as if it's translate(0, 8px). 9579 temp = style.display; 9580 style.display = "block"; 9581 parent = target.parentNode; 9582 9583 if (!parent || !target.offsetParent) { 9584 // note: in 3.3.0 we switched target.offsetParent to _doc.body.contains(target) to avoid [sometimes unnecessary] MutationObserver calls but that wasn't adequate because there are edge cases where nested position: fixed elements need to get reparented to accurately sense transforms. See https://github.com/greensock/GSAP/issues/388 and https://github.com/greensock/GSAP/issues/375 9585 addedToDOM = 1; //flag 9586 9587 nextSibling = target.nextSibling; 9588 9589 _docElement.appendChild(target); //we must add it to the DOM in order to get values properly 9590 9591 } 9592 9593 matrix = _getComputedTransformMatrixAsArray(target); 9594 temp ? style.display = temp : _removeProperty(target, "display"); 9595 9596 if (addedToDOM) { 9597 nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target); 9598 } 9599 } 9600 9601 return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix; 9602}, 9603 _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) { 9604 var cache = target._gsap, 9605 matrix = matrixArray || _getMatrix(target, true), 9606 xOriginOld = cache.xOrigin || 0, 9607 yOriginOld = cache.yOrigin || 0, 9608 xOffsetOld = cache.xOffset || 0, 9609 yOffsetOld = cache.yOffset || 0, 9610 a = matrix[0], 9611 b = matrix[1], 9612 c = matrix[2], 9613 d = matrix[3], 9614 tx = matrix[4], 9615 ty = matrix[5], 9616 originSplit = origin.split(" "), 9617 xOrigin = parseFloat(originSplit[0]) || 0, 9618 yOrigin = parseFloat(originSplit[1]) || 0, 9619 bounds, 9620 determinant, 9621 x, 9622 y; 9623 9624 if (!originIsAbsolute) { 9625 bounds = _getBBox(target); 9626 xOrigin = bounds.x + (~originSplit[0].indexOf("%") ? xOrigin / 100 * boun
vendor: 6,067 bytes, lines 9626-9820
9626ds.width : xOrigin); 9627 yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf("%") ? yOrigin / 100 * bounds.height : yOrigin); 9628 } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) { 9629 //if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero. 9630 x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant; 9631 y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant; 9632 xOrigin = x; 9633 yOrigin = y; 9634 } 9635 9636 if (smooth || smooth !== false && cache.smooth) { 9637 tx = xOrigin - xOriginOld; 9638 ty = yOrigin - yOriginOld; 9639 cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx; 9640 cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty; 9641 } else { 9642 cache.xOffset = cache.yOffset = 0; 9643 } 9644 9645 cache.xOrigin = xOrigin; 9646 cache.yOrigin = yOrigin; 9647 cache.smooth = !!smooth; 9648 cache.origin = origin; 9649 cache.originIsAbsolute = !!originIsAbsolute; 9650 target.style[_transformOriginProp] = "0px 0px"; //otherwise, if someone sets an origin via CSS, it will likely interfere with the SVG transform attribute ones (because remember, we're baking the origin into the matrix() value). 9651 9652 if (pluginToAddPropTweensTo) { 9653 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOrigin", xOriginOld, xOrigin); 9654 9655 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOrigin", yOriginOld, yOrigin); 9656 9657 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOffset", xOffsetOld, cache.xOffset); 9658 9659 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOffset", yOffsetOld, cache.yOffset); 9660 } 9661 9662 target.setAttribute("data-svg-origin", xOrigin + " " + yOrigin); 9663}, 9664 _parseTransform = function _parseTransform(target, uncache) { 9665 var cache = target._gsap || new __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["a" /* GSCache */](target); 9666 9667 if ("x" in cache && !uncache && !cache.uncache) { 9668 return cache; 9669 } 9670 9671 var style = target.style, 9672 invertedScaleX = cache.scaleX < 0, 9673 px = "px", 9674 deg = "deg", 9675 origin = _getComputedProperty(target, _transformOriginProp) || "0", 9676 x, 9677 y, 9678 z, 9679 scaleX, 9680 scaleY, 9681 rotation, 9682 rotationX, 9683 rotationY, 9684 skewX, 9685 skewY, 9686 perspective, 9687 xOrigin, 9688 yOrigin, 9689 matrix, 9690 angle, 9691 cos, 9692 sin, 9693 a, 9694 b, 9695 c, 9696 d, 9697 a12, 9698 a22, 9699 t1, 9700 t2, 9701 t3, 9702 a13, 9703 a23, 9704 a33, 9705 a42, 9706 a43, 9707 a32; 9708 x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0; 9709 scaleX = scaleY = 1; 9710 cache.svg = !!(target.getCTM && _isSVG(target)); 9711 matrix = _getMatrix(target, cache.svg); 9712 9713 if (cache.svg) { 9714 t1 = !cache.uncache && target.getAttribute("data-svg-origin"); 9715 9716 _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix); 9717 } 9718 9719 xOrigin = cache.xOrigin || 0; 9720 yOrigin = cache.yOrigin || 0; 9721 9722 if (matrix !== _identity2DMatrix) { 9723 a = matrix[0]; //a11 9724 9725 b = matrix[1]; //a21 9726 9727 c = matrix[2]; //a31 9728 9729 d = matrix[3]; //a41 9730 9731 x = a12 = matrix[4]; 9732 y = a22 = matrix[5]; //2D matrix 9733 9734 if (matrix.length === 6) { 9735 scaleX = Math.sqrt(a * a + b * b); 9736 scaleY = Math.sqrt(d * d + c * c); 9737 rotation = a || b ? _atan2(b, a) * _RAD2DEG : 0; //note: if scaleX is 0, we cannot accurately measure rotation. Same for skewX with a scaleY of 0. Therefore, we default to the previously recorded value (or zero if that doesn't exist). 9738 9739 skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0; 9740 skewX && (scaleY *= Math.cos(skewX * _DEG2RAD)); 9741 9742 if (cache.svg) { 9743 x -= xOrigin - (xOrigin * a + yOrigin * c); 9744 y -= yOrigin - (xOrigin * b + yOrigin * d); 9745 } //3D matrix 9746 9747 } else { 9748 a32 = matrix[6]; 9749 a42 = matrix[7]; 9750 a13 = matrix[8]; 9751 a23 = matrix[9]; 9752 a33 = matrix[10]; 9753 a43 = matrix[11]; 9754 x = matrix[12]; 9755 y = matrix[13]; 9756 z = matrix[14]; 9757 angle = _atan2(a32, a33); 9758 rotationX = angle * _RAD2DEG; //rotationX 9759 9760 if (angle) { 9761 cos = Math.cos(-angle); 9762 sin = Math.sin(-angle); 9763 t1 = a12 * cos + a13 * sin; 9764 t2 = a22 * cos + a23 * sin; 9765 t3 = a32 * cos + a33 * sin; 9766 a13 = a12 * -sin + a13 * cos; 9767 a23 = a22 * -sin + a23 * cos; 9768 a33 = a32 * -sin + a33 * cos; 9769 a43 = a42 * -sin + a43 * cos; 9770 a12 = t1; 9771 a22 = t2; 9772 a32 = t3; 9773 } //rotationY 9774 9775 9776 angle = _atan2(-c, a33); 9777 rotationY = angle * _RAD2DEG; 9778 9779 if (angle) { 9780 cos = Math.cos(-angle); 9781 sin = Math.sin(-angle); 9782 t1 = a * cos - a13 * sin; 9783 t2 = b * cos - a23 * sin; 9784 t3 = c * cos - a33 * sin; 9785 a43 = d * sin + a43 * cos; 9786 a = t1; 9787 b = t2; 9788 c = t3; 9789 } //rotationZ 9790 9791 9792 angle = _atan2(b, a); 9793 rotation = angle * _RAD2DEG; 9794 9795 if (angle) { 9796 cos = Math.cos(angle); 9797 sin = Math.sin(angle); 9798 t1 = a * cos + b * sin; 9799 t2 = a12 * cos + a22 * sin; 9800 b = b * cos - a * sin; 9801 a22 = a22 * cos - a12 * sin; 9802 a = t1; 9803 a12 = t2; 9804 } 9805 9806 if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) { 9807 //when rotationY is set, it will often be parsed as 180 degrees different than it should be, and rotationX and rotation both being 180 (it looks the same), so we adjust for that here. 9808 rotationX = rotation = 0; 9809 rotationY = 180 - rotationY; 9810 } 9811 9812 scaleX = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(Math.sqrt(a * a + b * b + c * c)); 9813 scaleY = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(Math.sqrt(a22 * a22 + a32 * a32)); 9814 angle = _atan2(a12, a22); 9815 skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0; 9816 perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0; 9817 } 9818 9819 if (cache.svg) { 9820 //sense if there are CSS transforms applied on an SVG element in which case we must over
9820write them when rendering. The transform attribute is more reliable cross-browser, but we can't just remove the CSS ones because they may be applied in a CSS rule somewhere (not just inline). 9821 t1 = target.getAttribute("transform"); 9822 cache.forceCSS = target.setAttribute("transform", "") || !_isNullTransform(_getComputedProperty(target, _transformProp)); 9823 t1 && target.setAttribute("transform", t1); 9824 } 9825 } 9826 9827 if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) { 9828 if (invertedScaleX) { 9829 scaleX *= -1; 9830 skewX += rotation <= 0 ? 180 : -180; 9831 rotation += rotation <= 0 ? 180 : -180; 9832 } else { 9833 scaleY *= -1; 9834 skewX += skewX <= 0 ? 180 : -180; 9835 } 9836 } 9837 9838 cache.x = x - ((cache.xPercent = x && (cache.xPercent || (Math.round(target.offsetWidth / 2) === Math.round(-x) ? -50 : 0))) ? target.offsetWidth * cache.xPercent / 100 : 0) + px; 9839 cache.y = y - ((cache.yPercent = y && (cache.yPercent || (Math.round(target.offsetHeight / 2) === Math.round(-y) ? -50 : 0))) ? target.offsetHeight * cache.yPercent / 100 : 0) + px; 9840 cache.z = z + px; 9841 cache.scaleX = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(scaleX); 9842 cache.scaleY = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(scaleY); 9843 cache.rotation = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(rotation) + deg; 9844 cache.rotationX = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(rotationX) + deg; 9845 cache.rotationY = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(rotationY) + deg; 9846 cache.skewX = skewX + deg; 9847 cache.skewY = skewY + deg; 9848 cache.transformPerspective = perspective + px; 9849 9850 if (cache.zOrigin = parseFloat(origin.split(" ")[2]) || 0) { 9851 style[_transformOriginProp] = _firstTwoOnly(origin); 9852 } 9853 9854 cache.xOffset = cache.yOffset = 0; 9855 cache.force3D = __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["e" /* _config */].force3D; 9856 cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms; 9857 cache.uncache = 0; 9858 return cache; 9859}, 9860 _firstTwoOnly = function _firstTwoOnly(value) { 9861 return (value = value.split(" "))[0] + " " + value[1]; 9862}, 9863 //for handling transformOrigin values, stripping out the 3rd dimension 9864_addPxTranslate = function _addPxTranslate(target, start, value) { 9865 var unit = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["v" /* getUnit */])(start); 9866 return Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(parseFloat(start) + parseFloat(_convertToUnit(target, "x", value + "px", unit))) + unit; 9867}, 9868 _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) { 9869 cache.z = "0px"; 9870 cache.rotationY = cache.rotationX = "0deg";
vendor: 5,516 bytes, lines 9871-10032
9871 cache.force3D = 0; 9872 9873 _renderCSSTransforms(ratio, cache); 9874}, 9875 _zeroDeg = "0deg", 9876 _zeroPx = "0px", 9877 _endParenthesis = ") ", 9878 _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) { 9879 var _ref = cache || this, 9880 xPercent = _ref.xPercent, 9881 yPercent = _ref.yPercent, 9882 x = _ref.x, 9883 y = _ref.y, 9884 z = _ref.z, 9885 rotation = _ref.rotation, 9886 rotationY = _ref.rotationY, 9887 rotationX = _ref.rotationX, 9888 skewX = _ref.skewX, 9889 skewY = _ref.skewY, 9890 scaleX = _ref.scaleX, 9891 scaleY = _ref.scaleY, 9892 transformPerspective = _ref.transformPerspective, 9893 force3D = _ref.force3D, 9894 target = _ref.target, 9895 zOrigin = _ref.zOrigin, 9896 transforms = "", 9897 use3D = force3D === "auto" && ratio && ratio !== 1 || force3D === true; // Safari has a bug that causes it not to render 3D transform-origin values properly, so we force the z origin to 0, record it in the cache, and then do the math here to offset the translate values accordingly (basically do the 3D transform-origin part manually) 9898 9899 9900 if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) { 9901 var angle = parseFloat(rotationY) * _DEG2RAD, 9902 a13 = Math.sin(angle), 9903 a33 = Math.cos(angle), 9904 cos; 9905 9906 angle = parseFloat(rotationX) * _DEG2RAD; 9907 cos = Math.cos(angle); 9908 x = _addPxTranslate(target, x, a13 * cos * -zOrigin); 9909 y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin); 9910 z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin); 9911 } 9912 9913 if (transformPerspective !== _zeroPx) { 9914 transforms += "perspective(" + transformPerspective + _endParenthesis; 9915 } 9916 9917 if (xPercent || yPercent) { 9918 transforms += "translate(" + xPercent + "%, " + yPercent + "%) "; 9919 } 9920 9921 if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) { 9922 transforms += z !== _zeroPx || use3D ? "translate3d(" + x + ", " + y + ", " + z + ") " : "translate(" + x + ", " + y + _endParenthesis; 9923 } 9924 9925 if (rotation !== _zeroDeg) { 9926 transforms += "rotate(" + rotation + _endParenthesis; 9927 } 9928 9929 if (rotationY !== _zeroDeg) { 9930 transforms += "rotateY(" + rotationY + _endParenthesis; 9931 } 9932 9933 if (rotationX !== _zeroDeg) { 9934 transforms += "rotateX(" + rotationX + _endParenthesis; 9935 } 9936 9937 if (skewX !== _zeroDeg || skewY !== _zeroDeg) { 9938 transforms += "skew(" + skewX + ", " + skewY + _endParenthesis; 9939 } 9940 9941 if (scaleX !== 1 || scaleY !== 1) { 9942 transforms += "scale(" + scaleX + ", " + scaleY + _endParenthesis; 9943 } 9944 9945 target.style[_transformProp] = transforms || "translate(0, 0)"; 9946}, 9947 _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) { 9948 var _ref2 = cache || this, 9949 xPercent = _ref2.xPercent, 9950 yPercent = _ref2.yPercent, 9951 x = _ref2.x, 9952 y = _ref2.y, 9953 rotation = _ref2.rotation, 9954 skewX = _ref2.skewX, 9955 skewY = _ref2.skewY, 9956 scaleX = _ref2.scaleX, 9957 scaleY = _ref2.scaleY, 9958 target = _ref2.target, 9959 xOrigin = _ref2.xOrigin, 9960 yOrigin = _ref2.yOrigin, 9961 xOffset = _ref2.xOffset, 9962 yOffset = _ref2.yOffset, 9963 forceCSS = _ref2.forceCSS, 9964 tx = parseFloat(x), 9965 ty = parseFloat(y), 9966 a11, 9967 a21, 9968 a12, 9969 a22, 9970 temp; 9971 9972 rotation = parseFloat(rotation); 9973 skewX = parseFloat(skewX); 9974 skewY = parseFloat(skewY); 9975 9976 if (skewY) { 9977 //for performance reasons, we combine all skewing into the skewX and rotation values. Remember, a skewY of 10 degrees looks the same as a rotation of 10 degrees plus a skewX of 10 degrees. 9978 skewY = parseFloat(skewY); 9979 skewX += skewY; 9980 rotation += skewY; 9981 } 9982 9983 if (rotation || skewX) { 9984 rotation *= _DEG2RAD; 9985 skewX *= _DEG2RAD; 9986 a11 = Math.cos(rotation) * scaleX; 9987 a21 = Math.sin(rotation) * scaleX; 9988 a12 = Math.sin(rotation - skewX) * -scaleY; 9989 a22 = Math.cos(rotation - skewX) * scaleY; 9990 9991 if (skewX) { 9992 skewY *= _DEG2RAD; 9993 temp = Math.tan(skewX - skewY); 9994 temp = Math.sqrt(1 + temp * temp); 9995 a12 *= temp; 9996 a22 *= temp; 9997 9998 if (skewY) { 9999 temp = Math.tan(skewY); 10000 temp = Math.sqrt(1 + temp * temp); 10001 a11 *= temp; 10002 a21 *= temp; 10003 } 10004 } 10005 10006 a11 = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(a11); 10007 a21 = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(a21); 10008 a12 = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(a12); 10009 a22 = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(a22); 10010 } else { 10011 a11 = scaleX; 10012 a22 = scaleY; 10013 a21 = a12 = 0; 10014 } 10015 10016 if (tx && !~(x + "").indexOf("px") || ty && !~(y + "").indexOf("px")) { 10017 tx = _convertToUnit(target, "x", x, "px"); 10018 ty = _convertToUnit(target, "y", y, "px"); 10019 } 10020 10021 if (xOrigin || yOrigin || xOffset || yOffset) { 10022 tx = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset); 10023 ty = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset); 10024 } 10025 10026 if (xPercent || yPercent) { 10027 //The SVG spec doesn't support percentage-based translation in the "transform" attribute, so we merge it into the translation to simulate it. 10028 temp = target.getBBox(); 10029 tx = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(tx + xPercent / 100 * temp.width); 10030 ty = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["s" /* _round */])(ty + yPercent / 100 * temp.height); 10031 } 10032
vendor: 8,632 bytes, lines 10033-10237
10033 temp = "matrix(" + a11 + "," + a21 + "," + a12 + "," + a22 + "," + tx + "," + ty + ")"; 10034 target.setAttribute("transform", temp); 10035 forceCSS && (target.style[_transformProp] = temp); //some browsers prioritize CSS transforms over the transform attribute. When we sense that the user has CSS transforms applied, we must overwrite them this way (otherwise some browser simply won't render the transform attribute changes!) 10036}, 10037 _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue, relative) { 10038 var cap = 360, 10039 isString = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["j" /* _isString */])(endValue), 10040 endNum = parseFloat(endValue) * (isString && ~endValue.indexOf("rad") ? _RAD2DEG : 1), 10041 change = relative ? endNum * relative : endNum - startNum, 10042 finalValue = startNum + change + "deg", 10043 direction, 10044 pt; 10045 10046 if (isString) { 10047 direction = endValue.split("_")[1]; 10048 10049 if (direction === "short") { 10050 change %= cap; 10051 10052 if (change !== change % (cap / 2)) { 10053 change += change < 0 ? cap : -cap; 10054 } 10055 } 10056 10057 if (direction === "cw" && change < 0) { 10058 change = (change + cap * _bigNum) % cap - ~~(change / cap) * cap; 10059 } else if (direction === "ccw" && change > 0) { 10060 change = (change - cap * _bigNum) % cap - ~~(change / cap) * cap; 10061 } 10062 } 10063 10064 plugin._pt = pt = new __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["b" /* PropTween */](plugin._pt, target, property, startNum, change, _renderPropWithEnd); 10065 pt.e = finalValue; 10066 pt.u = "deg"; 10067 10068 plugin._props.push(property); 10069 10070 return pt; 10071}, 10072 _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) { 10073 //for handling cases where someone passes in a whole transform string, like transform: "scale(2, 3) rotate(20deg) translateY(30em)" 10074 var style = _tempDivStyler.style, 10075 startCache = target._gsap, 10076 exclude = "perspective,force3D,transformOrigin,svgOrigin", 10077 endCache, 10078 p, 10079 startValue, 10080 endValue, 10081 startNum, 10082 endNum, 10083 startUnit, 10084 endUnit; 10085 style.cssText = getComputedStyle(target).cssText + ";position:absolute;display:block;"; //%-based translations will fail unless we set the width/height to match the original target (and padding/borders can affect it) 10086 10087 style[_transformProp] = transforms; 10088 10089 _doc.body.appendChild(_tempDivStyler); 10090 10091 endCache = _parseTransform(_tempDivStyler, 1); 10092 10093 for (p in _transformProps) { 10094 startValue = startCache[p]; 10095 endValue = endCache[p]; 10096 10097 if (startValue !== endValue && exclude.indexOf(p) < 0) { 10098 //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case. 10099 startUnit = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["v" /* getUnit */])(startValue); 10100 endUnit = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["v" /* getUnit */])(endValue); 10101 startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue); 10102 endNum = parseFloat(endValue); 10103 plugin._pt = new __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["b" /* PropTween */](plugin._pt, startCache, p, startNum, endNum - startNum, _renderCSSProp); 10104 plugin._pt.u = endUnit || 0; 10105 10106 plugin._props.push(p); 10107 } 10108 } 10109 10110 _doc.body.removeChild(_tempDivStyler); 10111}; // handle splitting apart padding, margin, borderWidth, and borderRadius into their 4 components. Firefox, for example, won't report borderRadius correctly - it will only do borderTopLeftRadius and the other corners. We also want to handle paddingTop, marginLeft, borderRightWidth, etc. 10112 10113 10114Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["f" /* _forEachName */])("padding,margin,Width,Radius", function (name, index) { 10115 var t = "Top", 10116 r = "Right", 10117 b = "Bottom", 10118 l = "Left", 10119 props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) { 10120 return index < 2 ? name + side : "border" + side + name; 10121 }); 10122 10123 _specialProps[index > 1 ? "border" + name : name] = function (plugin, target, property, endValue, tween) { 10124 var a, vars; 10125 10126 if (arguments.length < 4) { 10127 // getter, passed target, property, and unit (from _get()) 10128 a = props.map(function (prop) { 10129 return _get(plugin, prop, property); 10130 }); 10131 vars = a.join(" "); 10132 return vars.split(a[0]).length === 5 ? a[0] : vars; 10133 } 10134 10135 a = (endValue + "").split(" "); 10136 vars = {}; 10137 props.forEach(function (prop, i) { 10138 return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0]; 10139 }); 10140 plugin.init(target, vars, tween); 10141 }; 10142}); 10143 10144var CSSPlugin = { 10145 name: "css", 10146 register: _initCore, 10147 targetTest: function targetTest(target) { 10148 return target.style && target.nodeType; 10149 }, 10150 init: function init(target, vars, tween, index, targets) { 10151 var props = this._props, 10152 style = target.style, 10153 startAt = tween.vars.startAt, 10154 startValue, 10155 endValue, 10156 endNum, 10157 startNum, 10158 type, 10159 specialProp, 10160 p, 10161 startUnit, 10162 endUnit, 10163 relative, 10164 isTransformRelated, 10165 transformPropTween, 10166 cache, 10167 smooth, 10168 hasPriority; 10169 _pluginInitted || _initCore(); 10170 10171 for (p in vars) { 10172 if (p === "autoRound") { 10173 continue; 10174 } 10175 10176 endValue = vars[p]; 10177 10178 if (__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["o" /* _plugins */][p] && Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["c" /* _checkPlugin */])(p, vars, tween, index, target, targets)) { 10179 // plugins 10180 continue; 10181 } 10182 10183 type = typeof endValue; 10184 specialProp = _specialProps[p]; 10185 10186 if (type === "function") { 10187 endValue = endValue.call(tween, index, target, targets); 10188 type = typeof endValue; 10189 } 10190 10191 if (type === "string" && ~endValue.indexOf("random(")) { 10192 endValue = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["r" /* _replaceRandom */])(endValue); 10193 } 10194 10195 if (specialProp) { 10196 specialProp(this, target, p, endValue, tween) && (hasPriority = 1); 10197 } else if (p.substr(0, 2) === "--") { 10198 //CSS variable 10199 startValue = (getComputedStyle(target).getPropertyValue(p) + "").trim(); 10200 endValue += ""; 10201 startUnit = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["v" /* getUnit */])(startValue); 10202 endUnit = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["v" /* getUnit */])(endValue); 10203 endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit); 10204 this.add(style, "setProperty", startValue, endValue, index, targets, 0, 0, p); 10205 } else if (type !== "undefined") { 10206 if (startAt && p in startAt) { 10207 // in case someone hard-codes a complex value as the start, like top: "calc(2vh / 2)". Without this, it'd use the computed value (always in px) 10208 startValue = typeof startAt[p] === "function" ? startAt[p].call(tween, index, target, targets) : startAt[p]; 10209 p in __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["e" /* _config */].units && !Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["v" /* getUnit */])(startValue) && (startValue += __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["e" /* _config */].units[p]); // for cases when someone passes in a unitless value like {x: 100}; if we try setting translate(100, 0px) it won't work. 10210 10211 (startValue + "").charAt(1) === "=" && (startValue = _get(target, p)); // can't work with relative values 10212 } else { 10213 startValue = _get(target, p); 10214 } 10215 10216 startNum = parseFloat(startValue); 10217 relative = type === "string" && endValue.charAt(1) === "=" ? +(endValue.charAt(0) + "1") : 0; 10218 relative && (endValue = endValue.substr(2)); 10219 endNum = parseFloat(endValue); 10220 10221 if (p in _propertyAliases) { 10222 if (p === "autoAlpha") { 10223 //special case where we control the visibility along with opacity. We still allow the opacity value to pass through and get tweened. 10224 if (startNum === 1 && _get(target, "visibility") === "hidden" && endNum) { 10225 //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience) 10226 startNum = 0; 10227 } 10228 10229 _addNonTweeningPT(this, style, "visibility", startNum ? "inherit" : "hidden", endNum ? "inherit" : "hidden", !endNum); 10230 } 10231 10232 if (p !== "scale" && p !== "transform") { 10233 p = _propertyAliases[p]; 10234 ~p.indexOf(",") && (p = p.split(",")[0]); 10235 } 10236 } 10237
10238 isTransformRelated = p in _transformProps; //--- TRANSFORM-RELATED --- 10239 10240 if (isTransformRelated) { 10241 if (!transformPropTween) { 10242 cache = target._gsap; 10243 cache.renderTransform && !vars.parseTransform || _parseTransform(target, vars.parseTransform); // if, for example, gsap.set(... {transform:"translateX(50vw)"}), the _get() call doesn't parse the transform, thus cache.renderTransform won't be set yet so force the parsing of the transform here. 10244 10245 smooth = vars.smoothOrigin !== false && cache.smooth; 10246 transformPropTween = this._pt = new __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["b" /* PropTween */](this._pt, style, _transformProp, 0, 1, cache.renderTransform, cache, 0, -1); //the first time through, create the rendering PropTween so that it runs LAST (in the linked list, we keep adding to the beginning) 10247 10248 transformPropTween.dep = 1; //flag it as dependent so that if things get killed/overwritten and this is the only PropTween left, we can safely kill the whole tween. 10249 } 10250 10251 if (p === "scale") { 10252 this._pt = new __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["b" /* PropTween */](this._pt, cache, "scaleY", cache.scaleY, relative ? relative * endNum : endNum - cache.scaleY); 10253 props.push("scaleY", p); 10254 p += "X"; 10255 } else if (p === "transformOrigin") { 10256 endValue = _convertKeywordsToPercentages(endValue); //in case something like "left top" or "bottom right" is passed in. Convert to percentages. 10257 10258 if (cache.svg) { 10259 _applySVGOrigin(target, endValue, 0, smooth, 0, this); 10260 } else { 10261 endUnit = parseFloat(endValue.split(" ")[2]) || 0; //handle the zOrigin separately! 10262 10263 endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, "zOrigin", cache.zOrigin, endUnit); 10264 10265 _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue)); 10266 } 10267 10268 continue; 10269 } else if (p === "svgOrigin") { 10270 _applySVGOrigin(target, endValue, 1, smooth, 0, this); 10271 10272 continue; 10273 } else if (p in _rotationalProperties) { 10274 _addRotationalPropTween(this, cache, p, startNum, endValue, relative); 10275 10276 continue; 10277 } else if (p === "smoothOrigin") { 10278 _addNonTweeningPT(this, cache, "smooth", cache.smooth, endValue); 10279 10280 continue; 10281 } else if (p === "force3D") { 10282 cache[p] = endValue; 10283 continue; 10284 } else if (p === "transform") { 10285 _addRawTransformPTs(this, endValue, target); 10286 10287 continue; 10288 } 10289 } else if (!(p in style)) { 10290 p = _checkPropPrefix(p) || p; 10291 } 10292 10293 if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) { 10294 startUnit = (startValue + "").substr((startNum + "").length); 10295 endNum || (endNum = 0); // protect against NaN 10296 10297 endUnit = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["v" /* getUnit */])(endValue) || (p in __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["e" /* _config */].units ? __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["e" /* _config */].units[p] : startUnit); 10298 startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit)); 10299 this._pt = new __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["b" /* PropTween */](this._pt, isTransformRelated ? cache : style, p, startNum, relative ? relative * endNum : endNum - startNum, !isTransformRelated && (endUnit === "px" || p === "zIndex") && vars.autoRound !== false ? _renderRoundedCSSProp : _renderCSSProp); 10300 this._pt.u = endUnit || 0; 10301 10302 if (startUnit !== endUnit) { 10303 //when the tween goes all the way back to the beginning, we need to revert it to the OLD/ORIGINAL value (with those units). We record that as a "b" (beginning) property and point to a render method that handles that. (performance optimization) 10304 this._pt.b = startValue; 10305 this._pt.r = _renderCSSPropWithBeginning; 10306 } 10307 } else if (!(p in style)) { 10308 if (p in target) { 10309 //maybe it's not a style - it could be a property added directly to an element in which case we'll try to animate that. 10310 this.add(target, p, target[p], endValue, index, targets); 10311 } else { 10312 Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["l" /* _missingPlugin */])(p, endValue); 10313 10314 continue; 10315 } 10316 } else { 10317 _tweenComplexCSSString.call(this, target, p, startValue, endValue); 10318 } 10319 10320 props.push(p); 10321 } 10322 } 10323 10324 hasPriority && Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["t" /* _sortPropTweensByPriority */])(this); 10325 }, 10326 get: _get, 10327 aliases: _propertyAliases, 10328 getSetter: function getSetter(target, property, plugin) { 10329 //returns a setter function that accepts target, property, value and applies it accordingly. Remember, properties like "x" aren't as simple as target.style.property = value because they've got to be applied to a proxy object and then merged into a transform string in a renderer. 10330 var p = _propertyAliases[property]; 10331 p && p.indexOf(",") < 0 && (property = p); 10332 return property in _transformProps && property !== _transformOriginProp && (target._gsap.x || _get(target, "x")) ? plugin && _recentSetterPlugin === plugin ? property === "scale" ? _setterScale : _setterTransform : (_recentSetterPlugin = plugin || {}) && (property === "scale" ? _setterScaleWithRender : _setterTransformWithRender) : target.style && !Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["k" /* _isUndefined */])(target.style[property]) ? _setterCSSStyle : ~property.indexOf("-") ? _setterCSSProp : Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["i" /* _get
10332Setter */])(target, property); 10333 }, 10334 core: { 10335 _removeProperty: _removeProperty, 10336 _getMatrix: _getMatrix 10337 } 10338}; 10339__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["w" /* gsap */].utils.checkPrefix = _checkPropPrefix; 10340 10341(function (positionAndScale, rotation, others, aliases) { 10342 var all = Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["f" /* _forEachName */])(positionAndScale + "," + rotation + "," + others, function (name) { 10343 _transformProps[name] = 1; 10344 }); 10345 10346 Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["f" /* _forEachName */])(rotation, function (name) { 10347 __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["e" /* _config */].units[name] = "deg"; 10348 _rotationalProperties[name] = 1; 10349 }); 10350 10351 _propertyAliases[all[13]] = positionAndScale + "," + rotation; 10352 10353 Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["f" /* _forEachName */])(aliases, function (name) { 10354 var split = name.split(":"); 10355 _propertyAliases[split[1]] = all[split[0]]; 10356 }); 10357})("x,y,z,scale,scaleX,scaleY,xPercent,yPercent", "rotation,rotationX,rotationY,skewX,skewY", "transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective", "0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY"); 10358 10359Object(__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["f" /* _forEachName */])("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective", function (name) { 10360 __WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["e" /* _config */].units[name] = "px"; 10361}); 10362 10363__WEBPACK_IMPORTED_MODULE_0__gsap_core_js__["w" /* gsap */].registerPlugin(CSSPlugin); 10364 10365 10366/***/ }), 10367/* 21 */ 10368/***/ (function(module, __webpack_exports__, __webpack_require__) { 10369 10370"use strict"; 10371/* unused harmony export ScrollTrigger */ 10372/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ScrollTrigger; }); 10373/*! 10374 * ScrollTrigger 3.6.0 10375 * https://greensock.com 10376 * 10377 * @license Copyright 2008-2021, GreenSock. All rights reserved. 10378 * Subject to the terms at https://greensock.com/standard-license or for 10379 * Club GreenSock members, the agreement issued with that membership. 10380 * @author: Jack Doyle, [email protected] 10381*/ 10382 10383/* eslint-disable */ 10384var gsap, 10385 _coreInitted, 10386 _win, 10387 _doc, 10388 _docEl, 10389 _body, 10390 _root, 10391 _resizeDelay, 10392 _raf, 10393 _request, 10394 _toArray, 10395 _clamp, 10396 _time2, 10397 _syncInterval, 10398 _refreshing, 10399 _pointerIsDown, 10400 _transformProp, 10401 _i, 10402 _prevWidth, 10403 _prevHeight, 10404 _autoRefresh, 10405 _sort, 10406 _suppressOverwrites, 10407 _ignoreResize, 10408 _limitCallbacks, 10409 // if true, we'll only trigger callbacks if the active state toggles, so if you scroll immediately past both the start and end positions of a ScrollTrigger (thus inactive to inactive), neither its onEnter nor onLeave will be called. This is useful during startup. 10410_startup = 1, 10411 _proxies = [], 10412 _scrollers = [], 10413 _getTime = Date.now, 10414 _time1 = _getTime(), 10415 _lastScrollTime = 0, 10416 _enabled = 1, 10417 _passThrough = function _passThrough(v) { 10418 return v; 10419}, 10420 _windowExists = function _windowExists() { 10421 return typeof window !== "undefined"; 10422}, 10423 _getGSAP = function _getGSAP() { 10424 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 10425}, 10426 _isViewport = function _isViewport(e) { 10427 return !!~_root.indexOf(e); 10428}, 10429 _getProxyProp = function _getProxyProp(element, property) { 10430 return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property]; 10431}, 10432 _getScrollFunc = function _getScrollFunc(element, _ref) { 10433 var s = _ref.s, 10434 sc = _ref.sc; 10435 10436 var i = _scrollers.indexOf(element), 10437 offset = sc === _vertical.sc ? 1 : 2; 10438 10439 !~i && (i = _scrollers.push(element) - 1); 10440 return _scrollers[i + offset] || (_scrollers[i + offset] = _getProxyProp(element, s) || (_isViewport(element) ? sc : function (value) { 10441 return arguments.length ? element[s] = value : element[s]; 10442 })); 10443}, 10444 _getBoundsFunc = function _getBoundsFunc(element) { 10445 return _getProxyProp(element, "getBoundingClientRect") || (_isViewport(element) ? function () { 10446 _winOffsets.width = _win.innerWidth; 10447 _winOffsets.height = _win.innerHeight; 10448 return _winOffsets; 10449 } : function () { 10450 return _getBounds(element); 10451 }); 10452}, 10453 _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref2) { 10454 var d = _ref2.d, 10455 d2 = _ref2.d2, 10456 a = _ref2.a; 10457 return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () { 10458 return a()[d]; 10459 } : function () { 10460 return (isViewport ? _win["inner" + d2] : scroller["client" + d2]) || 0; 10461 }; 10462}, 10463 _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) { 10464 return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () { 10465 return _winOffsets; 10466 }; 10467}, 10468 _maxScroll = function _maxScroll(element, _ref3) { 10469 var s = _ref3.s, 10470 d2 = _ref3.d2, 10471 d = _ref3.d, 10472 a = _ref3.a; 10473 return (s = "scroll" + d2) && (a = _getProxyProp(element, s)) ? a() - _getBoundsFunc(element)()[d] : _isViewport(element) ? Math.max(_docEl[s], _body[s]) - (_win["inner" + d2] || _docEl["client" + d2] || _body["client" + d2]) : element[s] - element["offset" + d2]; 10474}, 10475 _iterateAutoRefresh = function _iterateAutoRefresh(func, events) { 10476 for (var i = 0; i < _autoRefresh.length; i += 3) {
10477 (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]); 10478 } 10479}, 10480 _isString = function _isString(value) { 10481 return typeof value === "string"; 10482}, 10483 _isFunction = function _isFunction(value) { 10484 return typeof value === "function"; 10485}, 10486 _isNumber = function _isNumber(value) { 10487 return typeof value === "number"; 10488}, 10489 _isObject = function _isObject(value) { 10490 return typeof value === "object"; 10491}, 10492 _callIfFunc = function _callIfFunc(value) { 10493 return _isFunction(value) && value(); 10494}, 10495 _combineFunc = function _combineFunc(f1, f2) { 10496 return function () { 10497 var result1 = _callIfFunc(f1), 10498 result2 = _callIfFunc(f2); 10499 10500 return function () { 10501 _callIfFunc(result1); 10502 10503 _callIfFunc(result2); 10504 }; 10505 }; 10506}, 10507 _abs = Math.abs, 10508 _scrollLeft = "scrollLeft", 10509 _scrollTop = "scrollTop", 10510 _left = "left", 10511 _top = "top", 10512 _right = "right", 10513 _bottom = "bottom", 10514 _width = "width", 10515 _height = "height", 10516 _Right = "Right", 10517 _Left = "Left", 10518 _Top = "Top", 10519 _Bottom = "Bottom", 10520 _padding = "padding", 10521 _margin = "margin", 10522 _Width = "Width", 10523 _Height = "Height", 10524 _px = "px", 10525 _horizontal = { 10526 s: _scrollLeft, 10527 p: _left, 10528 p2: _Left, 10529 os: _right, 10530 os2: _Right, 10531 d: _width, 10532 d2: _Width, 10533 a: "x", 10534 sc: function sc(value) { 10535 return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0; 10536 } 10537}, 10538 _vertical = { 10539 s: _scrollTop, 10540 p: _top, 10541 p2: _Top, 10542 os: _bottom, 10543 os2: _Bottom, 10544 d: _height, 10545 d2: _Height, 10546 a: "y", 10547 op: _horizontal, 10548 sc: function sc(value) { 10549 return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0; 10550 } 10551}, 10552 _getComputedStyle = function _getComputedStyle(element) { 10553 return _win.getComputedStyle(element); 10554}, 10555 _makePositionable = function _makePositionable(element) { 10556 return element.style.position = _getComputedStyle(element).position === "absolute" ? "absolute" : "relative"; 10557}, 10558 // if the element already has position: absolute, leave that, otherwise make it position: relative 10559_setDefaults = function _setDefaults(obj, defaults) { 10560 for (var p in defaults) { 10561 p in obj || (obj[p] = defaults[p]); 10562 } 10563 10564 return obj; 10565}, 10566 //_isInViewport = element => (element = _getBounds(element)) && !(element.top > (_win.innerHeight || _docEl.clientHeight) || element.bottom < 0 || element.left > (_win.innerWidth || _docEl.clientWidth) || element.right < 0) && element, 10567_getBounds = function _getBounds(element, withoutTransforms) { 10568 var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap.to(element, { 10569 x: 0, 10570 y: 0, 10571 xPercent: 0, 10572 yPercent: 0, 10573 rotation: 0, 10574 rotationX: 0, 10575 rotationY: 0, 10576 scale: 1, 10577 skewX: 0, 10578 skewY: 0 10579 }).progress(1), 10580 bounds = element.getBoundingClientRect(); 10581 tween && tween.progress(0).kill(); 10582 return bounds; 10583}, 10584 _getSize = function _getSize(element, _ref4) { 10585 var d2 = _ref4.d2; 10586 return element["offset" + d2] || element["client" + d2] || 0; 10587}, 10588 _getLabelRatioArray = function _getLabelRatioArray(timeline) { 10589 var a = [], 10590 labels = timeline.labels, 10591 duration = timeline.duration(), 10592 p; 10593 10594 for (p in labels) { 10595 a.push(labels[p] / duration); 10596 } 10597 10598 return a; 10599}, 10600 _getClosestLabel = function _getClosestLabel(animation) { 10601 return function (value) { 10602 return gsap.utils.snap(_getLabelRatioArray(animation), value); 10603 }; 10604}, 10605 _getLabelAtDirection = function _getLabelAtDirection(timeline) { 10606 return function (value, st) { 10607 var a = _getLabelRatioArray(timeline), 10608 i; 10609 10610 a.sort(function (a, b) { 10611 return a - b; 10612 }); 10613 10614 if (st.direction > 0) { 10615 for (i = 0; i < a.length; i++) { 10616 if (a[i] >= value) { 10617 return a[i]; 10618 } 10619 } 10620 10621 return a.pop(); 10622 } else { 10623 i = a.length; 10624 10625 while (i--) { 10626 if (a[i] <= value) { 10627 return a[i]; 10628 } 10629 } 10630 } 10631 10632 return a[0]; 10633 }; 10634}, 10635 _multiListener = function _multiListener(func, element, types, callback) { 10636 return types.split(",").forEach(function (type) { 10637 return func(element, type, callback); 10638 }); 10639}, 10640 _addListener = function _addListener(element, type, func) { 10641 return element.addEventListener(type, func, { 10642 passive: true 10643 }); 10644}, 10645 _removeListener = function _removeListener(element, type, func) { 10646 return element.removeEventListener(type, func); 10647}, 10648 _markerDefaults = { 10649 startColor: "green", 10650 endColor: "red", 10651 indent: 0, 10652 fontSize: "16px", 10653 fontWeight: "normal" 10654}, 10655 _defaults = { 10656 toggleActions: "play", 10657 anticipatePin: 0 10658}, 10659 _keywords = { 10660 top: 0, 10661 left: 0, 10662 center: 0.5, 10663 bottom: 1, 10664 right: 1 10665}, 10666 _offsetToPx = function _offsetToPx(value, size) { 10667 if (_isString(value)) { 10668 var eqIndex = value.indexOf("="), 10669 relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0; 10670 10671 if (~eqIndex) { 10672 value.indexOf("%") > eqIndex && (relative *= size / 100); 10673 value = value.substr(0, eqIndex - 1); 10674 } 10675 10676 value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0); 10677 } 10678 10679 return value; 10680}, 10681 _createMarker = function _createMarker(type, name, container, direction, _ref5, offset, matchWidthEl) { 10682 var startColor = _ref5.startColor, 10683 endColor = _ref5.endColor, 10684 fontSize = _ref5.fontSize, 10685 indent = _ref5.indent, 10686 fontWeight = _ref5.fontWeight; 10687 10688 var e = _doc.createElement("div"), 10689 useFixedPosition = _isViewport(container) || _getProxyProp(container, "pinType") === "fixed", 10690 isScroller = type.indexOf("scroller") !== -1, 10691 parent = useFixedPosition ? _body : container, 10692 isStart = type.indexOf("start") !== -1, 10693 color = isStart ? startColor : endColor, 10694 css = "border-color:" + color + ";font-size:" + fontSize + ";color:" + color + ";font-weight:" + fontWeight + ";pointer-events:none;white-space:nowrap;font-family:sans-serif,Arial;z-index:1000;padding:4px 8px;border-width:0;border-style:solid;"; 10695 10696 css += "position:" + (isScroller && useFixedPosition ? "fixed;" : "absolute;"); 10697 (isScroller || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;"); 10698 matchWidthEl && (css += "box-sizing:border-box;text-align:left;
10698width:" + matchWidthEl.offsetWidth + "px;"); 10699 e._isStart = isStart; 10700 e.setAttribute("class", "gsap-marker-" + type); 10701 e.style.cssText = css; 10702 e.innerText = name || name === 0 ? type + "-" + name : type; 10703 parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e); 10704 e._offset = e["offset" + direction.op.d2]; 10705 10706 _positionMarker(e, 0, direction, isStart); 10707 10708 return e; 10709}, 10710 _positionMarker = function _positionMarker(marker, start, direction, flipped) { 10711 var vars = { 10712 display: "block" 10713 }, 10714 side = direction[flipped ? "os2" : "p2"], 10715 oppositeSide = direction[flipped ? "p2" : "os2"]; 10716 marker._isFlipped = flipped; 10717 vars[direction.a + "Percent"] = flipped ? -100 : 0; 10718 vars[direction.a] = flipped ? "1px" : 0; 10719 vars["border" + side + _Width] = 1; 10720 vars["border" + oppositeSide + _Width] = 0; 10721 vars[direction.p] = start + "px"; 10722 gsap.set(marker, vars); 10723}, 10724 _triggers = [], 10725 _ids = {}, 10726 _sync = function _sync() { 10727 return _request || (_request = _raf(_updateAll)); 10728}, 10729 _onScroll = function _onScroll() { 10730 if (!_request) { 10731 _request = _raf(_updateAll); 10732 _lastScrollTime || _dispatch("scrollStart"); 10733 _lastScrollTime = _getTime(); 10734 } 10735}, 10736 _onResize = function _onResize() { 10737 return !_refreshing && !_ignoreResize && !_doc.fullscreenElement && _resizeDelay.restart(true); 10738}, 10739 // ignore resizes triggered by refresh() 10740_listeners = {}, 10741 _emptyArray = [], 10742 _media = [], 10743 _creatingMedia, 10744 // when ScrollTrigger.matchMedia() is called, we record the current media key here (like "(min-width: 800px)") so that we can assign it to everything that's created during that call. Then we can revert just those when necessary. In the ScrollTrigger's init() call, the _creatingMedia is recorded as a "media" property on the instance. 10745_lastMediaTick, 10746 _onMediaChange = function _onMediaChange(e) { 10747 var tick = gsap.ticker.frame, 10748 matches = [], 10749 i = 0, 10750 index; 10751 10752 if (_lastMediaTick !== tick || _startup) { 10753 _revertAll(); 10754 10755 for (; i < _media.length; i += 4) { 10756 index = _win.matchMedia(_media[i]).matches; 10757 10758 if (index !== _media[i + 3]) { 10759 // note: some browsers fire the matchMedia event multiple times, like when going full screen, so we shouldn't call the function multiple times. Check to see if it's already matched. 10760 _media[i + 3] = index; 10761 index ? matches.push(i) : _revertAll(1, _media[i]) || _isFunction(_media[i + 2]) && _media[i + 2](); // Firefox doesn't update the "matches" property of the MediaQueryList object correctly - it only does so as it calls its change handler - so we must re-create a media query here to ensure it's accurate. 10762 } 10763 } 10764 10765 _revertRecorded(); // in case killing/reverting any of the animations actually added inline styles back. 10766 10767 10768 for (i = 0; i < matches.length; i++) { 10769 index = matches[i]; 10770 _creatingMedia = _media[index]; 10771 _media[index + 2] = _media[index + 1](e); 10772 } 10773 10774 _creatingMedia = 0; 10775 _coreInitted && _refreshAll(0, 1); 10776 _lastMediaTick = tick; 10777 10778 _dispatch("matchMedia"); 10779 } 10780}, 10781 _softRefresh = function _softRefresh() { 10782 return _removeListener(ScrollTrigger, "scrollEnd", _softRefresh) || _refreshAll(true); 10783}, 10784 _dispatch = function _dispatch(type) { 10785 return _listeners[type] && _listeners[type].map(function (f) { 10786 return f(); 10787 }) || _emptyArray; 10788}, 10789 _savedStyles = [], 10790 // when ScrollTrigger.saveStyles() is called, the inline styles are recorded in this Array in a sequential format like [element, cssText, gsCache, media]. This keeps it very memory-efficient and fast to iterate through. 10791_revertRecorded = function _revertRecorded(media) { 10792 for (var i = 0; i < _savedStyles.length; i += 4) { 10793 if (!media || _savedStyles[i + 3] === media) { 10794 _savedStyles[i].style.cssText = _savedStyles[i + 1]; 10795 _savedStyles[i + 2].uncache = 1; 10796 } 10797 } 10798}, 10799 _revertAll = function _revertAll(kill, media) { 10800 var trigger; 10801 10802 for (_i = 0; _i < _triggers.length; _i++) { 10803 trigger = _triggers[_i]; 10804 10805 if (!media || trigger.media === media) { 10806 if (kill) { 10807 trigger.kill(1); 10808 } else { 10809 trigger.scroll.rec || (trigger.scroll.rec = trigger.scroll()); // record the scroll positions so that in each refresh() we can ensure that it doesn't shift. Remember, pinning can make things change around, especially if the same element is pinned multiple times. If one was already recorded, don't re-record because unpinning may have occurred and made it shorter. 10810 10811 trigger.revert(); 10812 } 10813 } 10814 } 10815 10816 _revertRecorded(media); 10817 10818 media || _dispatch("revert"); 10819}, 10820 _refreshAll = function _refreshAll(force, skipRevert) { 10821 if (_lastScrollTime && !force) { 10822 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 10823 10824 return; 10825 } 10826 10827 var refreshInits = _dispatch("refreshInit"); 10828 10829 _sort && ScrollTrigger.sort(); 10830 skipRevert || _revertAll(); 10831 10832 for (_i = 0; _i < _triggers.length; _i++) { 10833 _triggers[_i].refresh(); 10834 } 10835
vendor: 8,201 bytes, lines 10836-11069
10836 refreshInits.forEach(function (result) { 10837 return result && result.render && result.render(-1); 10838 }); // if the onRefreshInit() returns an animation (typically a gsap.set()), revert it. This makes it easy to put things in a certain spot before refreshing for measurement purposes, and then put things back. 10839 10840 _i = _triggers.length; 10841 10842 while (_i--) { 10843 _triggers[_i].scroll.rec = 0; 10844 } 10845 10846 _resizeDelay.pause(); 10847 10848 _dispatch("refresh"); 10849}, 10850 _lastScroll = 0, 10851 _direction = 1, 10852 _updateAll = function _updateAll() { 10853 var l = _triggers.length, 10854 time = _getTime(), 10855 recordVelocity = time - _time1 >= 50, 10856 scroll = l && _triggers[0].scroll(); 10857 10858 _direction = _lastScroll > scroll ? -1 : 1; 10859 _lastScroll = scroll; 10860 10861 if (recordVelocity) { 10862 if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) { 10863 _lastScrollTime = 0; 10864 10865 _dispatch("scrollEnd"); 10866 } 10867 10868 _time2 = _time1; 10869 _time1 = time; 10870 } 10871 10872 if (_direction < 0) { 10873 _i = l; 10874 10875 while (_i--) { 10876 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 10877 } 10878 10879 _direction = 1; 10880 } else { 10881 for (_i = 0; _i < l; _i++) { 10882 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 10883 } 10884 } 10885 10886 _request = 0; 10887}, 10888 _propNamesToCopy = [_left, _top, _bottom, _right, _margin + _Bottom, _margin + _Right, _margin + _Top, _margin + _Left, "display", "flexShrink", "float", "zIndex"], 10889 _stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]), 10890 _swapPinOut = function _swapPinOut(pin, spacer, state) { 10891 _setState(state); 10892 10893 if (pin.parentNode === spacer) { 10894 var parent = spacer.parentNode; 10895 10896 if (parent) { 10897 parent.insertBefore(pin, spacer); 10898 parent.removeChild(spacer); 10899 } 10900 } 10901}, 10902 _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) { 10903 if (pin.parentNode !== spacer) { 10904 var i = _propNamesToCopy.length, 10905 spacerStyle = spacer.style, 10906 pinStyle = pin.style, 10907 p; 10908 10909 while (i--) { 10910 p = _propNamesToCopy[i]; 10911 spacerStyle[p] = cs[p]; 10912 } 10913 10914 spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative"; 10915 cs.display === "inline" && (spacerStyle.display = "inline-block"); 10916 pinStyle[_bottom] = pinStyle[_right] = "auto"; 10917 spacerStyle.overflow = "visible"; 10918 spacerStyle.boxSizing = "border-box"; 10919 spacerStyle[_width] = _getSize(pin, _horizontal) + _px; 10920 spacerStyle[_height] = _getSize(pin, _vertical) + _px; 10921 spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0"; 10922 10923 _setState(spacerState); 10924 10925 pinStyle[_width] = pinStyle["max" + _Width] = cs[_width]; 10926 pinStyle[_height] = pinStyle["max" + _Height] = cs[_height]; 10927 pinStyle[_padding] = cs[_padding]; 10928 pin.parentNode.insertBefore(spacer, pin); 10929 spacer.appendChild(pin); 10930 } 10931}, 10932 _capsExp = /([A-Z])/g, 10933 _setState = function _setState(state) { 10934 if (state) { 10935 var style = state.t.style, 10936 l = state.length, 10937 i = 0, 10938 p, 10939 value; 10940 (state.t._gsap || gsap.core.getCache(state.t)).uncache = 1; // otherwise transforms may be off 10941 10942 for (; i < l; i += 2) { 10943 value = state[i + 1]; 10944 p = state[i]; 10945 10946 if (value) { 10947 style[p] = value; 10948 } else if (style[p]) { 10949 style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 10950 } 10951 } 10952 } 10953}, 10954 _getState = function _getState(element) { 10955 // returns an Array with alternating values like [property, value, property, value] and a "t" property pointing to the target (element). Makes it fast and cheap. 10956 var l = _stateProps.length, 10957 style = element.style, 10958 state = [], 10959 i = 0; 10960 10961 for (; i < l; i++) { 10962 state.push(_stateProps[i], style[_stateProps[i]]); 10963 } 10964 10965 state.t = element; 10966 return state; 10967}, 10968 _copyState = function _copyState(state, override, omitOffsets) { 10969 var result = [], 10970 l = state.length, 10971 i = omitOffsets ? 8 : 0, 10972 // skip top, left, right, bottom if omitOffsets is true 10973 p; 10974 10975 for (; i < l; i += 2) { 10976 p = state[i]; 10977 result.push(p, p in override ? override[p] : state[i + 1]); 10978 } 10979 10980 result.t = state.t; 10981 return result; 10982}, 10983 _winOffsets = { 10984 left: 0, 10985 top: 0 10986}, 10987 _parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax) { 10988 _isFunction(value) && (value = value(self)); 10989 10990 if (_isString(value) && value.substr(0, 3) === "max") { 10991 value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0); 10992 } 10993 10994 if (!_isNumber(value)) { 10995 _isFunction(trigger) && (trigger = trigger(self)); 10996 10997 var element = _toArray(trigger)[0] || _body, 10998 bounds = _getBounds(element) || {}, 10999 offsets = value.split(" "), 11000 localOffset, 11001 globalOffset, 11002 display; 11003 11004 if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") { 11005 // if display is "none", it won't report getBoundingClientRect() properly 11006 display = element.style.display; 11007 element.style.display = "block"; 11008 bounds = _getBounds(element); 11009 display ? element.style.display = display : element.style.removeProperty("display"); 11010 } 11011 11012 localOffset = _offsetToPx(offsets[0], bounds[direction.d]); 11013 globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize); 11014 value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset; 11015 markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20); 11016 scrollerSize -= scrollerSize - globalOffset; // adjust for the marker 11017 } else if (markerScroller) { 11018 _positionMarker(markerScroller, scrollerSize, direction, true); 11019 } 11020 11021 if (marker) { 11022 var position = value + scrollerSize, 11023 isStart = marker._isStart; 11024 scrollerMax = "scroll" + direction.d2; 11025 11026 _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body[scrollerMax], _docEl[scrollerMax]) : marker.parentNode[scrollerMax]) <= position + 1); 11027 11028 if (useFixedPosition) { 11029 scrollerBounds = _getBounds(markerScroller); 11030 useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px); 11031 } 11032 } 11033 11034 return Math.round(value); 11035}, 11036 _prefixExp = /(?:webkit|moz|length|cssText|inset)/i, 11037 _reparent = function _reparent(element, parent, top, left) { 11038 if (element.parentNode !== parent) { 11039 var style = element.style, 11040 p, 11041 cs; 11042 11043 if (parent === _body) { 11044 element._stOrig = style.cssText; // record original inline styles so we can revert them later 11045 11046 cs = _getComputedStyle(element); 11047 11048 for (p in cs) { 11049 // must copy all relevant styles to ensure that nothing changes visually when we reparent to the <body>. Skip the vendor prefixed ones. 11050 if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") { 11051 style[p] = cs[p]; 11052 } 11053 } 11054 11055 style.top = top; 11056 style.left = left; 11057 } else { 11058 style.cssText = element._stOrig; 11059 } 11060 11061 gsap.core.getCache(element).uncache = 1; 11062 parent.appendChild(element); 11063 } 11064}, 11065 // returns a function that can be used to tween the scroll position in the direction provided, and when doing so it'll add a .tween property to the FUNCTION itself, and remove it when the tween completes or gets killed. This gives us a way to have multiple ScrollTriggers use a central function for any given scroller and see if there's a scroll tween running (which would affect if/how things get updated) 11066_getTweenCreator = function _getTweenCreator(scroller, direction) { 11067 var getScroll = _getScrollFunc(scroller, direction), 11068 prop = "_scroll" + direction.p2, 11069 // add a tweenable property to the scroller that's a getter/setter function, like _scrollTop or _scrollLeft. This way, if someone does gsap.killTweensOf(scroller) it'll
11069kill the scroll tween. 11070 lastScroll1, 11071 lastScroll2, 11072 getTween = function getTween(scrollTo, vars, initialValue, change1, change2) { 11073 var tween = getTween.tween, 11074 onComplete = vars.onComplete, 11075 modifiers = {}; 11076 tween && tween.kill(); 11077 lastScroll1 = Math.round(initialValue); 11078 vars[prop] = scrollTo; 11079 vars.modifiers = modifiers; 11080 11081 modifiers[prop] = function (value) { 11082 value = Math.round(getScroll()); // round because in some [very uncommon] Windows environments, it can get reported with decimals even though it was set without. 11083 11084 if (value !== lastScroll1 && value !== lastScroll2 && Math.abs(value - lastScroll1) > 2) { 11085 // if the user scrolls, kill the tween. iOS Safari intermittently misreports the scroll position, it may be the most recently-set one or the one before that! When Safari is zoomed (CMD-+), it often misreports as 1 pixel off too! So if we set the scroll position to 125, for example, it'll actually report it as 124. 11086 tween.kill(); 11087 getTween.tween = 0; 11088 } else { 11089 value = initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio; 11090 } 11091 11092 lastScroll2 = lastScroll1; 11093 return lastScroll1 = Math.round(value); 11094 }; 11095 11096 vars.onComplete = function () { 11097 getTween.tween = 0; 11098 onComplete && onComplete.call(tween); 11099 }; 11100 11101 tween = getTween.tween = gsap.to(scroller, vars); 11102 return tween; 11103 }; 11104 11105 scroller[prop] = getScroll; 11106 scroller.addEventListener("mousewheel", function () { 11107 return getTween.tween && getTween.tween.kill() && (getTween.tween = 0); 11108 }); // Windows machines handle mousewheel scrolling in chunks (like "3 lines per scroll") meaning the typical strategy for cancelling the scroll isn't as sensitive. It's much more likely to match one of the previous 2 scroll event positions. So we kill any snapping as soon as there's a mousewheel event. 11109 11110 return getTween; 11111}; 11112 11113_horizontal.op = _vertical; 11114var ScrollTrigger = /*#__PURE__*/function () { 11115 function ScrollTrigger(vars, animation) { 11116 _coreInitted || ScrollTrigger.register(gsap) || console.warn("Please gsap.registerPlugin(ScrollTrigger)"); 11117 this.init(vars, animation); 11118 } 11119 11120 var _proto = ScrollTrigger.prototype; 11121 11122 _proto.init = function init(vars, animation) { 11123 this.progress = this.start = 0; 11124 this.vars && this.kill(1); // in case it's being initted again 11125 11126 if (!_enabled) { 11127 this.update = this.refresh = this.kill = _passThrough; 11128 return; 11129 } 11130 11131 vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? { 11132 trigger: vars 11133 } : vars, _defaults); 11134 11135 var direction = vars.horizontal ? _horizontal : _vertical, 11136 _vars = vars, 11137 onUpdate = _vars.onUpdate, 11138 toggleClass = _vars.toggleClass, 11139 id = _vars.id, 11140 onToggle = _vars.onToggle, 11141 onRefresh = _vars.onRefresh, 11142 scrub = _vars.scrub, 11143 trigger = _vars.trigger, 11144 pin = _vars.pin, 11145 pinSpacing = _vars.pinSpacing, 11146 invalidateOnRefresh = _vars.invalidateOnRefresh, 11147 anticipatePin = _vars.anticipatePin, 11148 onScrubComplete = _vars.onScrubComplete, 11149 onSnapComplete = _vars.onSnapComplete, 11150 once = _vars.once, 11151 snap = _vars.snap, 11152 pinReparent = _vars.pinReparent, 11153 isToggle = !scrub && scrub !== 0, 11154 scroller = _toArray(vars.scroller || _win)[0], 11155 scrollerCache = gsap.core.getCache(scroller), 11156 isViewport = _isViewport(scroller), 11157 useFixedPosition = "pinType" in vars ? vars.pinType === "fixed" : isViewport || _getProxyProp(scroller, "pinType") === "fixed", 11158 callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack], 11159 toggleActions = isToggle && vars.toggleActions.split(" "), 11160 markers = "markers" in vars ? vars.markers : _defaults.markers, 11161 borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0, 11162 self = this, 11163 onRefreshInit = vars.onRefreshInit && function () { 11164 return vars.onRefreshInit(self); 11165 },
11166 getScrollerSize = _getSizeFunc(scroller, isViewport, direction), 11167 getScrollerOffsets = _getOffsetsFunc(scroller, isViewport), 11168 tweenTo, 11169 pinCache, 11170 snapFunc, 11171 isReverted, 11172 scroll1, 11173 scroll2, 11174 start, 11175 end, 11176 markerStart, 11177 markerEnd, 11178 markerStartTrigger, 11179 markerEndTrigger, 11180 markerVars, 11181 change, 11182 pinOriginalState, 11183 pinActiveState, 11184 pinState, 11185 spacer, 11186 offset, 11187 pinGetter, 11188 pinSetter, 11189 pinStart, 11190 pinChange, 11191 spacingStart, 11192 spacerState, 11193 markerStartSetter, 11194 markerEndSetter, 11195 cs, 11196 snap1, 11197 snap2, 11198 scrubTween, 11199 scrubSmooth, 11200 snapDurClamp, 11201 snapDelayedCall, 11202 prevProgress, 11203 prevScroll, 11204 prevAnimProgress; 11205 11206 self.media = _creatingMedia; 11207 anticipatePin *= 45; 11208 11209 _triggers.push(self); 11210 11211 self.scroller = scroller; 11212 self.scroll = _getScrollFunc(scroller, direction); 11213 scroll1 = self.scroll(); 11214 self.vars = vars; 11215 animation = animation || vars.animation; 11216 "refreshPriority" in vars && (_sort = 1); 11217 scrollerCache.tweenScroll = scrollerCache.tweenScroll || { 11218 top: _getTweenCreator(scroller, _vertical), 11219 left: _getTweenCreator(scroller, _horizontal) 11220 }; 11221 self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p]; 11222 11223 if (animation) { 11224 animation.vars.lazy = false; 11225 animation._initted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.render(0, true, true); 11226 self.animation = animation.pause(); 11227 animation.scrollTrigger = self; 11228 scrubSmooth = _isNumber(scrub) && scrub; 11229 scrubSmooth && (scrubTween = gsap.to(animation, { 11230 ease: "power3", 11231 duration: scrubSmooth, 11232 onComplete: function onComplete() { 11233 return onScrubComplete && onScrubComplete(self); 11234 } 11235 })); 11236 snap1 = 0; 11237 id || (id = animation.vars.id); 11238 } 11239 11240 if (snap) { 11241 _isObject(snap) || (snap = { 11242 snapTo: snap 11243 }); 11244 "scrollBehavior" in _body.style && gsap.set(isViewport ? [_body, _docEl] : scroller, { 11245 scrollBehavior: "auto" 11246 }); // smooth scrolling doesn't work with snap. 11247 11248 snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : gsap.utils.snap(snap.snapTo); 11249 snapDurClamp = snap.duration || { 11250 min: 0.1, 11251 max: 2 11252 }; 11253 snapDurClamp = _isObject(snapDurClamp) ? _clamp(snapDurClamp.min, snapDurClamp.max) : _clamp(snapDurClamp, snapDurClamp); 11254 snapDelayedCall = gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () { 11255 if (Math.abs(self.getVelocity()) < 10 && !_pointerIsDown) { 11256 var totalProgress = animation && !isToggle ? animation.totalProgress() : self.progress, 11257 velocity = (totalProgress - snap2) / (_getTime() - _time2) * 1000 || 0, 11258 change1 = _abs(velocity / 2) * velocity / 0.185, 11259 naturalEnd = totalProgress + change1, 11260 endValue = _clamp(0, 1, snapFunc(naturalEnd, self)), 11261 scroll = self.scroll(), 11262 endScroll = Math.round(start + endValue * change), 11263 tween = tweenTo.tween; 11264 11265 if (scroll <= end && scroll >= start && endScroll !== scroll) { 11266 if (tween && !tween._initted && tween.data <= Math.abs(endScroll - scroll)) { 11267 // there's an overlapping snap! So we must figure out which one is closer and let that tween live. 11268 return; 11269 } 11270 11271 tweenTo(endScroll, { 11272 duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)), 11273 ease: snap.ease || "power3", 11274 data: Math.abs(endScroll - scroll), 11275 // record the distance so that if another snap tween occurs (conflict) we
11275can prioritize the closest snap. 11276 onComplete: function onComplete() { 11277 snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress; 11278 onSnapComplete && onSnapComplete(self); 11279 } 11280 }, scroll, change1 * change, endScroll - scroll - change1 * change); 11281 } 11282 } else if (self.isActive) { 11283 snapDelayedCall.restart(true); 11284 } 11285 }).pause(); 11286 } 11287 11288 id && (_ids[id] = self); 11289 trigger = self.trigger = _toArray(trigger || pin)[0]; 11290 pin = pin === true ? trigger : _toArray(pin)[0]; 11291 _isString(toggleClass) && (toggleClass = { 11292 targets: trigger, 11293 className: toggleClass 11294 }); 11295 11296 if (pin) { 11297 pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding); // if the parent is display: flex, don't apply pinSpacing by default. 11298 11299 self.pin = pin; 11300 vars.force3D !== false && gsap.set(pin, { 11301 force3D: true 11302 }); 11303 pinCache = gsap.core.getCache(pin); 11304 11305 if (!pinCache.spacer) { 11306 // record the spacer and pinOriginalState on the cache in case someone tries pinning the same element with MULTIPLE ScrollTriggers - we don't want to have multiple spacers or record the "original" pin state after it has already been affected by another ScrollTrigger. 11307 pinCache.spacer = spacer = _doc.createElement("div"); 11308 spacer.setAttribute("class", "pin-spacer" + (id ? " pin-spacer-" + id : "")); 11309 pinCache.pinState = pinOriginalState = _getState(pin); 11310 } else { 11311 pinOriginalState = pinCache.pinState; 11312 } 11313 11314 self.spacer = spacer = pinCache.spacer; 11315 cs = _getComputedStyle(pin); 11316 spacingStart = cs[pinSpacing + direction.os2]; 11317 pinGetter = gsap.getProperty(pin); 11318 pinSetter = gsap.quickSetter(pin, direction.a, _px); // pin.firstChild && !_maxScroll(pin, direction) && (pin.style.overflow = "hidden"); // protects from collapsing margins, but can have unintended consequences as demonstrated here: https://codepen.io/GreenSock/pen/1e42c7a73bfa409d2cf1e184e7a4248d so it was removed in favor of just telling people to set up their CSS to avoid the collapsing margins (overflow: hidden | auto is just one option. Another is border-top: 1px solid transparent). 11319 11320 _swapPinIn(pin, spacer, cs); 11321 11322 pinState = _getState(pin); 11323 } 11324 11325 if (markers) { 11326 markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults; 11327 markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0); 11328 markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger); 11329 offset = markerStartTrigger["offset" + direction.op.d2]; 11330 markerStart = _createMarker("start", id, scroller, direction, markerVars, offset); 11331 markerEnd = _createMarker("end", id, scroller, direction, markerVars, offset); 11332 11333 if (!useFixedPosition) { 11334 _makePositionable(isViewport ? _body : scroller); 11335 11336 gsap.set([markerStartTrigger, markerEndTrigger], { 11337 force3D: true 11338 }); 11339 markerStartSetter = gsap.quickSetter(markerStartTrigger, direction.a, _px); 11340 markerEndSetter = gsap.quickSetter(markerEndTrigger, direction.a, _px); 11341 } 11342 } 11343 11344 self.revert = function (revert) { 11345 var r = revert !== false || !self.enabled, 11346 prevRefreshing = _refreshing; 11347 11348 if (r !== isReverted) { 11349 if (r) { 11350 prevScroll = Math.max(self.scroll(), self.scroll.rec || 0); // record the scroll so we can revert later (repositioning/pinning things can affect scroll position). In the static refresh() method, we first record all the scroll positions as a reference. 11351 11352 prevProgress = self.progress; 11353 prevAnimProgress = animation && animation.progress(); 11354 } 11355 11356 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 11357 return m.style.display = r ? "none" : "block"; 11358 }); 11359 r && (_refreshing = 1); 11360 self.update(r); // make sure the pin is back in its original position so that all the measurements are correct. 11361 11362 _refreshing = prevRefreshing; 11363 pin && (r ? _swapPinOut(pin, spacer, pinOriginalState) : (!pinReparent || !self.isActive) && _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState)); 11364 isReverted = r; 11365 } 11366 }; 11367 11368 self.refresh = function (soft) { 11369 if (_refreshing || !self.enabled) { 11370 return; 11371 } 11372 11373 if (pin && soft && _lastScrollTime) { 11374 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 11375 11376 return; 11377 } 11378 11379 _refreshing = 1; 11380 scrubTween && scrubTween.pause(); 11381 invalidateOnRefresh && animation && animation.progress(0).invalidate(); 11382 isReverted || self.revert(); 11383 11384 var size = getScrollerSize(), 11385 scrollerBounds = getScrollerOffsets(), 11386 max = _maxScroll(scroller, direction), 11387 offset = 0, 11388 otherPinOffset = 0, 11389 parsedEnd = vars.end, 11390 parsedEndTrigger = vars.endTrigger || trigger, 11391 parsedStart = vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"), 11392 triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0, 11393 i = triggerIndex, 11394 cs, 11395 bounds, 11396 scroll, 11397 isVertical, 11398 override, 11399 curTrigger, 11400 curPin, 11401 oppositeScroll, 11402 initted; 11403 11404 while (i--) { 11405 // user might try to pin the same element more than once, so we must find any prior triggers with the same pin, revert them, and determine how long they're pinning so that we can offset things appropriately. Make sure we revert from last to first so that things "rewind" properly. 11406 curPin = _triggers[i].pin; 11407 curPin && (curPin === trigger || curPin === pin) && _triggers[i].revert(); 11408 } 11409 11410 start = _parsePosition(parsedStart, trigger, size, direction, self.scroll(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max) || (pin ? -0.001 : 0); 11411 _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self)); 11412 11413 if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) { 11414 if (~parsedEnd.indexOf(" ")) { 11415 parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd; 11416 } else { 11417 offset = _offsetToPx(parsedEnd.substr(2), size); 11418 parsedEnd = _isString(parsedStart) ? parsedStart : start + offset; // _parsePosition won't factor in the offset if the start is a
11418number, so do it here. 11419 11420 parsedEndTrigger = trigger; 11421 } 11422 } 11423 11424 end = Math.max(start, _parsePosition(parsedEnd || (parsedEndTrigger ? "100% 0" : max), parsedEndTrigger, size, direction, self.scroll() + offset, markerEnd, markerEndTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max)) || -0.001; 11425 change = end - start || (start -= 0.01) && 0.001; 11426 offset = 0; 11427 i = triggerIndex; 11428 11429 while (i--) { 11430 curTrigger = _triggers[i]; 11431 curPin = curTrigger.pin; 11432 11433 if (curPin && curTrigger.start - curTrigger._pinPush < start) { 11434 cs = curTrigger.end - curTrigger.start; 11435 curPin === trigger && (offset += cs); 11436 curPin === pin && (otherPinOffset += cs); 11437 } 11438 } 11439 11440 start += offset; 11441 end += offset; 11442 self._pinPush = otherPinOffset; 11443 11444 if (markerStart && offset) { 11445 // offset the markers if necessary 11446 cs = {}; 11447 cs[direction.a] = "+=" + offset; 11448 gsap.set([markerStart, markerEnd], cs); 11449 } 11450 11451 if (pin) { 11452 cs = _getComputedStyle(pin); 11453 isVertical = direction === _vertical; 11454 scroll = self.scroll(); // recalculate because the triggers can affect the scroll 11455 11456 pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset; 11457 !max && end > 1 && ((isViewport ? _body : scroller).style["overflow-" + direction.a] = "scroll"); // makes sure the scroller has a scrollbar, otherwise if something has width: 100%, for example, it would be too big (exclude the scrollbar). See https://greensock.com/forums/topic/25182-scrolltrigger-width-of-page-increase-where-markers-are-set-to-false/ 11458 11459 _swapPinIn(pin, spacer, cs); 11460 11461 pinState = _getState(pin); // transforms will interfere with the top/left/right/bottom placement, so remove them temporarily. getBoundingClientRect() factors in transforms. 11462 11463 bounds = _getBounds(pin, true); 11464 oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)(); 11465 11466 if (pinSpacing) { 11467 spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px]; 11468 spacerState.t = spacer; 11469 i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0; 11470 i && spacerState.push(direction.d, i + _px); // for box-sizing: border-box (must include padding). 11471 11472 _setState(spacerState); 11473 11474 useFixedPosition && self.scroll(prevScroll); 11475 } 11476 11477 if (useFixedPosition) { 11478 override = { 11479 top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px, 11480 left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px, 11481 boxSizing: "border-box", 11482 position: "fixed" 11483 }; 11484 override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px; 11485 override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px; 11486 override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0"; 11487 override[_padding] = cs[_padding]; 11488 override[_padding + _Top] = cs[_padding + _Top]; 11489 override[_padding + _Right] = cs[_padding + _Right]; 11490 override[_padding + _Bottom] = cs[_padding + _Bottom]; 11491 override[_padding + _Left] = cs[_padding + _Left]; 11492 pinActiveState = _copyState(pinOriginalState, override, pinReparent); 11493 } 11494 11495 if (animation) { 11496 // the animation might be affecting the transform, so we must jump to the end, check the value, and compensate accordingly. Otherwise, when it becomes unpinned, the pinSetter() will get set to a value that doesn't include whatever the animation did. 11497 initted = animation._initted; // if not, we must invalidate() after this step, otherwise it could lock in starting values prematurely. 11498 11499 _suppressOverwrites(1); 11500 11501 animation.progress(1, true); 11502 pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset; 11503 change !== pinChange && pinActiveState.splice(pinActiveState.length - 2, 2); // transform is the last property/value set in the state Array. Since the animation is controlling that, we should omit it. 11504 11505 animation.progress(0, true); 11506 initted || animation.invalidate(); 11507 11508 _suppressOverwrites(0); 11509 } else { 11510 pinChange = change; 11511 } 11512 } else if (trigger && self.scroll()) { 11513 // it may be INSIDE a pinned element, so walk up the tree and look for any elements with _pinOffset to compensate because anything with pinSpacing that's already scrolled would throw off the measurements in getBoundingClientRect() 11514 bounds = trigger.parentNode; 11515 11516 while (bounds && bounds !== _body) { 11517 if (bounds._pinOffset) { 11518 start -= bounds._pinOffset; 11519 end -= bounds._pinOffset; 11520 } 11521 11522 bounds = bounds.parentNode; 11523 } 11524 } 11525 11526 for (i = 0; i < triggerIndex; i++) { 11527 // make sure we revert from first to last to make sure things reach their end state properly 11528 curTrigger = _triggers[i].pin; 11529 curTrigger && (curTrigger === trigger || curTrigger === pin) && _triggers[i].revert(false); 11530 } 11531 11532 self.start = start; 11533 self.end = end; 11534 scroll1 = scroll2 = self.scroll(); // reset velocity 11535 11536 scroll1 < prevScroll && self.scroll(prevScroll); 11537 self.revert(false); 11538 _refreshing = 0; 11539 animation && isToggle && animation._initted && animation.progress(prevAnimProgress, true).render(animation.time(), true, true); // must force a re-render because if saveStyles() was used on the target(s), the styles could have been wiped out during the refresh(). 11540 11541 if (prevProgress !== self.progress) { 11542 // ensures that the direction is set properly (when refreshing, progress is set back to 0 initially, then back again to wherever it needs to be) and that callbacks are triggered. 11543 scrubTween && animation.totalProgress(prevProgress, true); // to avoid issues where animation callbacks like onStart aren't triggered. 11544 11545 self.progress = prevProgress;
11546 self.update(); 11547 } 11548 11549 pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange)); 11550 onRefresh && onRefresh(self); 11551 }; 11552 11553 self.getVelocity = function () { 11554 return (self.scroll() - scroll2) / (_getTime() - _time2) * 1000 || 0; 11555 }; 11556 11557 self.update = function (reset, recordVelocity) { 11558 var scroll = self.scroll(), 11559 p = reset ? 0 : (scroll - start) / change, 11560 clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0, 11561 prevProgress = self.progress, 11562 isActive, 11563 wasActive, 11564 toggleState, 11565 action, 11566 stateChanged, 11567 toggled; 11568 11569 if (recordVelocity) { 11570 scroll2 = scroll1; 11571 scroll1 = scroll; 11572 11573 if (snap) { 11574 snap2 = snap1; 11575 snap1 = animation && !isToggle ? animation.totalProgress() : clipped; 11576 } 11577 } // anticipate the pinning a few ticks ahead of time based on velocity to avoid a visual glitch due to the fact that most browsers do scrolling on a separate thread (not synced with requestAnimationFrame). 11578 11579 11580 anticipatePin && !clipped && pin && !_refreshing && !_startup && _lastScrollTime && start < scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin && (clipped = 0.0001); 11581 11582 if (clipped !== prevProgress && self.enabled) { 11583 isActive = self.isActive = !!clipped && clipped < 1; 11584 wasActive = !!prevProgress && prevProgress < 1; 11585 toggled = isActive !== wasActive; 11586 stateChanged = toggled || !!clipped !== !!prevProgress; // could go from start all the way to end, thus it didn't toggle but it did change state in a sense (may need to fire a callback) 11587 11588 self.direction = clipped > prevProgress ? 1 : -1; 11589 self.progress = clipped; 11590 11591 if (!isToggle) { 11592 if (scrubTween && !_refreshing && !_startup) { 11593 scrubTween.vars.totalProgress = clipped; 11594 scrubTween.invalidate().restart(); 11595 } else if (animation) { 11596 animation.totalProgress(clipped, !!_refreshing); 11597 } 11598 } 11599 11600 if (pin) { 11601 reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart); 11602 11603 if (!useFixedPosition) { 11604 pinSetter(pinStart + pinChange * clipped); 11605 } else if (stateChanged) { 11606 action = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction); // if it's at the VERY end of the page, don't switch away from position: fixed because it's pointless and it could cause a brief flash when the user scrolls back up (when it gets pinned again) 11607 11608 if (pinReparent) { 11609 if (!reset && (isActive || action)) { 11610 var bounds = _getBounds(pin, true), 11611 _offset = scroll - start; 11612 11613 _reparent(pin, _body, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px); 11614 } else { 11615 _reparent(pin, spacer); 11616 } 11617 } 11618 11619 _setState(isActive || action ? pinActiveState : pinState); 11620 11621 pinChange !== change && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !action ? pinChange : 0)); 11622 } 11623 } 11624 11625 snap && !tweenTo.tween && !_refreshing && !_startup && snapDelayedCall.restart(true); 11626 toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) { 11627 return el.classList[isActive || once ? "add" : "remove"](toggleClass.className); 11628 }); // classes could affect positioning, so do it even if reset or refreshing is true. 11629 11630 onUpdate && !isToggle && !reset && onUpdate(self); 11631 11632 if (stateChanged && !_refreshing) { 11633 toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3; // 0 = enter, 1 = leave, 2 = enterBack, 3 = leaveBack (we prioritize the FIRST encounter, thus if you scroll really fast past the onEnter and onLeave in one tick, it'd prioritize onEnter. 11634 11635 if (isToggle) { 11636 action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState]; // if it didn't toggle, that means it shot right past and since we prioritize the "enter" action, we should switch to the "leave" in this case (but only if one is defined) 11637 11638 if (animation && (action === "complete" || action === "reset" || action in animation)) { 11639 if (action === "complete") { 11640 animation.pause().totalProgress(1); 11641 } else if (action === "reset") { 11642 animation.restart(true).pause(); 11643 } else { 11644 animation[action](); 11645 } 11646 } 11647 11648 onUpdate && onUpdate(self); 11649 } 11650 11651 if (toggled || !_limitCallbacks) { 11652 // on startup, the page could be scrolled and we don't want to fire callbacks that didn't toggle. For example onEnter shouldn't fire if the ScrollTrigger isn't actually entered. 11653 onToggle && toggled && onToggle(self); 11654 callbacks[toggleState] && callbacks[toggleState](self); 11655 once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); // a callback shouldn't be called again if once is true. 11656 11657 if (!toggled) { 11658 // it's possible to go completely past, like from before the start to after the end (or vice-versa) in which case BOTH callbacks should be fired in that order 11659 toggleState = clipped === 1 ? 1 : 3; 11660 callbacks[toggleState] && callbacks[toggleState](self); 11661 } 11662 } 11663 } else if (isToggle && onUpdate && !_refreshing) { 11664 onUpdate(self); 11665 } 11666 } // update absolutely-positioned markers (only if the scroller isn't the viewport) 11667 11668 11669 if (markerEndSetter) { 11670 markerStartSetter(scroll + (markerStartTrigger._isFlipped ? 1 : 0)); 11671 markerEndSetter(scroll); 11672 } 11673 }; 11674 11675 self.enable = function () { 11676 if (!self.enabled) { 11677 self.enabled = true; 11678 11679 _addListener(scroller, "resize", _onResize); 11680 11681 _addListener(scroller, "scroll", _onScroll); 11682 11683 onRefreshInit && _addListener(ScrollTrigger, "refreshInit", onRefreshInit); 11684 !animation || !animation.add ? self.refresh() : gsap.delayedCall(0.01, function () { 11685 return start || end || self.refresh(); 11686 }) && (change = 0.01) && (start = end = 0); // if the animation is a timeline, it may not have been populated yet, so it wouldn't render at the proper place on the first refresh(), thus we should schedule one for the next tick. 11687 } 11688 }; 11689 11690 self.disable = function (reset, allowAnimation) { 11691 if (self.enabled) { 11692 reset !== false && self.revert(); 11693 self.enabled = self.isActive = false;
11694 allowAnimation || scrubTween && scrubTween.pause(); 11695 prevScroll = 0; 11696 pinCache && (pinCache.uncache = 1); 11697 onRefreshInit && _removeListener(ScrollTrigger, "refreshInit", onRefreshInit); 11698 11699 if (snapDelayedCall) { 11700 snapDelayedCall.pause(); 11701 tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0); 11702 } 11703 11704 if (!isViewport) { 11705 var i = _triggers.length; 11706 11707 while (i--) { 11708 if (_triggers[i].scroller === scroller && _triggers[i] !== self) { 11709 return; //don't remove the listeners if there are still other triggers referencing it. 11710 } 11711 } 11712 11713 _removeListener(scroller, "resize", _onResize); 11714 11715 _removeListener(scroller, "scroll", _onScroll); 11716 } 11717 } 11718 }; 11719 11720 self.kill = function (revert, allowAnimation) { 11721 self.disable(revert, allowAnimation); 11722 id && delete _ids[id]; 11723 11724 var i = _triggers.indexOf(self); 11725 11726 _triggers.splice(i, 1); 11727 11728 i === _i && _direction > 0 && _i--; // if we're in the middle of a refresh() or update(), splicing would cause skips in the index, so adjust... 11729 11730 if (animation) { 11731 animation.scrollTrigger = null; 11732 revert && animation.render(-1); 11733 allowAnimation || animation.kill(); 11734 } 11735 11736 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 11737 return m.parentNode.removeChild(m); 11738 }); 11739 11740 if (pin) { 11741 pinCache && (pinCache.uncache = 1); 11742 i = 0; 11743 11744 _triggers.forEach(function (t) { 11745 return t.pin === pin && i++; 11746 }); 11747 11748 i || (pinCache.spacer = 0); // if there aren't any more ScrollTriggers with the same pin, remove the spacer, otherwise it could be contaminated with old/stale values if the user re-creates a ScrollTrigger for the same element. 11749 } 11750 }; 11751 11752 self.enable(); 11753 }; 11754 11755 ScrollTrigger.register = function register(core) { 11756 if (!_coreInitted) { 11757 gsap = core || _getGSAP(); 11758 11759 if (_windowExists() && window.document) { 11760 _win = window; 11761 _doc = document; 11762 _docEl = _doc.documentElement; 11763 _body = _doc.body; 11764 } 11765 11766 if (gsap) { 11767 _toArray = gsap.utils.toArray; 11768 _clamp = gsap.utils.clamp; 11769 _suppressOverwrites = gsap.core.suppressOverwrites || _passThrough; 11770 gsap.core.globals("ScrollTrigger", ScrollTrigger); // must register the global manually because in Internet Explorer, functions (classes) don't have a "name" property. 11771 11772 if (_body) { 11773 _raf = _win.requestAnimationFrame || function (f) { 11774 return setTimeout(f, 16); 11775 }; 11776 11777 _addListener(_win, "mousewheel", _onScroll); 11778 11779 _root = [_win, _doc, _docEl, _body]; 11780 11781 _addListener(_doc, "scroll", _onScroll); // some browsers (like Chrome), the window stops dispatching scroll events on the window if you scroll really fast, but it's consistent on the document! 11782 11783 11784 var bodyStyle = _body.style, 11785 border = bodyStyle.borderTop, 11786 bounds; 11787 bodyStyle.borderTop = "1px solid #000"; // works around an issue where a margin of a child element could throw off the bounds of the _body, making it seem like there's a margin when there actually isn't. The border ensures that the bounds are accurate. 11788 11789 bounds = _getBounds(_body); 11790 _vertical.m = Math.round(bounds.top + _vertical.sc()) || 0; // accommodate the offset of the <body> caused by margins and/or padding 11791 11792 _horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0; 11793 border ? bodyStyle.borderTop = border : bodyStyle.removeProperty("border-top"); 11794 _syncInterval = setInterval(_sync, 200); 11795 gsap.delayedCall(0.5, function () { 11796 return _startup = 0; 11797 }); 11798 11799 _addListener(_doc, "touchcancel", _passThrough); // some older Android devices intermittently stop dispatching "touchmove" events if we don't listen for "touchcancel" on the document. 11800 11801 11802 _addListener(_body, "touchstart", _passThrough); //works around Safari bug: https://greensock.com/forums/topic/21450-draggable-in-iframe-on-mobile-is-buggy/ 11803 11804 11805 _multiListener(_addListener, _doc, "pointerdown,touchstart,mousedown", function () { 11806 return _pointerIsDown = 1; 11807 }); 11808 11809 _multiListener(_addListener, _doc, "pointerup,touchend,mouseup", function () { 11810 return _pointerIsDown = 0; 11811 }); 11812 11813 _transformProp = gsap.utils.checkPrefix("transform"); 11814 11815 _stateProps.push(_transformProp); 11816 11817 _coreInitted = _getTime(); 11818 _resizeDelay = gsap.delayedCall(0.2, _refreshAll).pause(); 11819 _autoRefresh = [_doc, "visibilitychange", function () { 11820 var w = _win.innerWidth, 11821 h = _win.innerHeight; 11822 11823 if (_doc.hidden) { 11824 _prevWidth = w; 11825 _prevHeight = h; 11826 } else if (_prevWidth !== w || _prevHeight !== h) { 11827 _onResize(); 11828 } 11829 }, _doc, "DOMContentLoaded", _refreshAll, _win, "load", function () { 11830 return _lastScrollTime || _refreshAll(); 11831 }, _win, "resize", _onResize]; 11832 11833 _iterateAutoRefresh(_addListener); 11834 } 11835 } 11836 } 11837 11838 return _coreInitted; 11839 }; 11840 11841 ScrollTrigger.defaults = function defaults(config) { 11842 for (var p in config) { 11843 _defaults[p] = config[p]; 11844 } 11845 }; 11846 11847 ScrollTrigger.kill = function kill() { 11848 _enabled = 0; 11849
11850 _triggers.slice(0).forEach(function (trigger) { 11851 return trigger.kill(1); 11852 }); 11853 }; 11854 11855 ScrollTrigger.config = function config(vars) { 11856 "limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks); 11857 var ms = vars.syncInterval; 11858 ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms); 11859 11860 if ("autoRefreshEvents" in vars) { 11861 _iterateAutoRefresh(_removeListener) || _iterateAutoRefresh(_addListener, vars.autoRefreshEvents || "none"); 11862 _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1; 11863 } 11864 }; 11865 11866 ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) { 11867 var t = _toArray(target)[0], 11868 i = _scrollers.indexOf(t), 11869 isViewport = _isViewport(t); 11870 11871 if (~i) { 11872 _scrollers.splice(i, isViewport ? 6 : 2); 11873 } 11874 11875 isViewport ? _proxies.unshift(_win, vars, _body, vars, _docEl, vars) : _proxies.unshift(t, vars); 11876 }; 11877 11878 ScrollTrigger.matchMedia = function matchMedia(vars) { 11879 // _media is populated in the following order: mediaQueryString, onMatch, onUnmatch, isMatched. So if there are two media queries, the Array would have a length of 8 11880 var mq, p, i, func, result; 11881 11882 for (p in vars) { 11883 i = _media.indexOf(p); 11884 func = vars[p]; 11885 _creatingMedia = p; 11886 11887 if (p === "all") { 11888 func(); 11889 } else { 11890 mq = _win.matchMedia(p); 11891 11892 if (mq) { 11893 mq.matches && (result = func()); 11894 11895 if (~i) { 11896 _media[i + 1] = _combineFunc(_media[i + 1], func); 11897 _media[i + 2] = _combineFunc(_media[i + 2], result); 11898 } else { 11899 i = _media.length; 11900 11901 _media.push(p, func, result); 11902 11903 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 11904 } 11905 11906 _media[i + 3] = mq.matches; 11907 } 11908 } 11909 11910 _creatingMedia = 0; 11911 } 11912 11913 return _media; 11914 }; 11915 11916 ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) { 11917 query || (_media.length = 0); 11918 query = _media.indexOf(query); 11919 query >= 0 && _media.splice(query, 4); 11920 }; 11921 11922 return ScrollTrigger; 11923}(); 11924ScrollTrigger.version = "3.6.0"; 11925 11926ScrollTrigger.saveStyles = function (targets) { 11927 return targets ? _toArray(targets).forEach(function (target) { 11928 if (target && target.style) { 11929 var i = _savedStyles.indexOf(target); 11930 11931 i >= 0 && _savedStyles.splice(i, 4); 11932 11933 _savedStyles.push(target, target.style.cssText, gsap.core.getCache(target), _creatingMedia); 11934 } 11935 }) : _savedStyles; 11936}; 11937 11938ScrollTrigger.revert = function (soft, media) { 11939 return _revertAll(!soft, media); 11940}; 11941 11942ScrollTrigger.create = function (vars, animation) { 11943 return new ScrollTrigger(vars, animation); 11944}; 11945 11946ScrollTrigger.refresh = function (safe) { 11947 return safe ? _onResize() : _refreshAll(true); 11948}; 11949 11950ScrollTrigger.update = _updateAll; 11951 11952ScrollTrigger.maxScroll = function (element, horizontal) { 11953 return _maxScroll(element, horizontal ? _horizontal : _vertical); 11954}; 11955 11956ScrollTrigger.getScrollFunc = function (element, horizontal) { 11957 return _getScrollFunc(_toArray(element)[0], horizontal ? _horizontal : _vertical); 11958}; 11959 11960ScrollTrigger.getById = function (id) { 11961 return _ids[id]; 11962}; 11963 11964ScrollTrigger.getAll = function () { 11965 return _triggers.slice(0); 11966}; 11967 11968ScrollTrigger.isScrolling = function () { 11969 return !!_lastScrollTime; 11970}; 11971 11972ScrollTrigger.addEventListener = function (type, callback) { 11973 var a = _listeners[type] || (_listeners[type] = []); 11974 ~a.indexOf(callback) || a.push(callback); 11975}; 11976 11977ScrollTrigger.removeEventListener = function (type, callback) { 11978 var a = _listeners[type], 11979 i = a && a.indexOf(callback); 11980 i >= 0 && a.splice(i, 1); 11981}; 11982 11983ScrollTrigger.batch = function (targets, vars) { 11984 var result = [], 11985 varsCopy = {}, 11986 interval = vars.interval || 0.016, 11987 batchMax = vars.batchMax || 1e9, 11988 proxyCallback = function proxyCallback(type, callback) { 11989 var elements = [], 11990 triggers = [], 11991 delay = gsap.delayedCall(interval, function () { 11992 callback(elements, triggers); 11993 elements = []; 11994 triggers = []; 11995 }).pause(); 11996 return function (self) { 11997 elements.length || delay.restart(true); 11998 elements.push(self.trigger); 11999 triggers.push(self); 12000 batchMax <= elements.length && delay.progress(1); 12001 }; 12002 }, 12003 p; 12004 12005 for (p in vars) { 12006 varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p]; 12007 } 12008 12009 if (_isFunction(batchMax)) { 12010 batchMax = batchMax(); 12011 12012 _addListener(ScrollTrigger, "refresh", function () { 12013 return batchMax = vars.batchMax(); 12014 }); 12015 } 12016
12017 _toArray(targets).forEach(function (target) { 12018 var config = {}; 12019 12020 for (p in varsCopy) { 12021 config[p] = varsCopy[p]; 12022 } 12023 12024 config.trigger = target; 12025 result.push(ScrollTrigger.create(config)); 12026 }); 12027 12028 return result; 12029}; 12030 12031ScrollTrigger.sort = function (func) { 12032 return _triggers.sort(func || function (a, b) { 12033 return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6); 12034 }); 12035}; 12036 12037_getGSAP() && gsap.registerPlugin(ScrollTrigger); 12038 12039 12040/***/ }), 12041/* 22 */ 12042/***/ (function(module, exports, __webpack_require__) { 12043 12044var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* 12045 _ _ _ _ 12046 ___| (_) ___| | __ (_)___ 12047/ __| | |/ __| |/ / | / __| 12048\__ \ | | (__| < _ | \__ \ 12049|___/_|_|\___|_|\_(_)/ |___/ 12050 |__/ 12051 12052 Version: 1.8.1 12053 Author: Ken Wheeler 12054 Website: http://kenwheeler.github.io 12055 Docs: http://kenwheeler.github.io/slick 12056 Repo: http://github.com/kenwheeler/slick 12057 Issues: http://github.com/kenwheeler/slick/issues 12058 12059 */ 12060/* global window, document, define, jQuery, setInterval, clearInterval */ 12061;(function(factory) { 12062 'use strict'; 12063 if (true) { 12064 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 12065 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 12066 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 12067 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 12068 } else if (typeof exports !== 'undefined') { 12069 module.exports = factory(require('jquery')); 12070 } else { 12071 factory(jQuery); 12072 } 12073 12074}(function($) { 12075 'use strict';
vendor: 31,932 bytes, lines 12075-13138
12075 12076 var Slick = window.Slick || {}; 12077 12078 Slick = (function() { 12079 12080 var instanceUid = 0; 12081 12082 function Slick(element, settings) { 12083 12084 var _ = this, dataSettings; 12085 12086 _.defaults = { 12087 accessibility: true, 12088 adaptiveHeight: false, 12089 appendArrows: $(element), 12090 appendDots: $(element), 12091 arrows: true, 12092 asNavFor: null, 12093 prevArrow: '<button class="slick-prev" aria-label="Previous" type="button">Previous</button>', 12094 nextArrow: '<button class="slick-next" aria-label="Next" type="button">Next</button>', 12095 autoplay: false, 12096 autoplaySpeed: 3000, 12097 centerMode: false, 12098 centerPadding: '50px', 12099 cssEase: 'ease', 12100 customPaging: function(slider, i) { 12101 return $('<button type="button" />').text(i + 1); 12102 }, 12103 dots: false, 12104 dotsClass: 'slick-dots', 12105 draggable: true, 12106 easing: 'linear', 12107 edgeFriction: 0.35, 12108 fade: false, 12109 focusOnSelect: false, 12110 focusOnChange: false, 12111 infinite: true, 12112 initialSlide: 0, 12113 lazyLoad: 'ondemand', 12114 mobileFirst: false, 12115 pauseOnHover: true, 12116 pauseOnFocus: true, 12117 pauseOnDotsHover: false, 12118 respondTo: 'window', 12119 responsive: null, 12120 rows: 1, 12121 rtl: false, 12122 slide: '', 12123 slidesPerRow: 1, 12124 slidesToShow: 1, 12125 slidesToScroll: 1, 12126 speed: 500, 12127 swipe: true, 12128 swipeToSlide: false, 12129 touchMove: true, 12130 touchThreshold: 5, 12131 useCSS: true, 12132 useTransform: true, 12133 variableWidth: false, 12134 vertical: false, 12135 verticalSwiping: false, 12136 waitForAnimate: true, 12137 zIndex: 1000 12138 }; 12139 12140 _.initials = { 12141 animating: false, 12142 dragging: false, 12143 autoPlayTimer: null, 12144 currentDirection: 0, 12145 currentLeft: null, 12146 currentSlide: 0, 12147 direction: 1, 12148 $dots: null, 12149 listWidth: null, 12150 listHeight: null, 12151 loadIndex: 0, 12152 $nextArrow: null, 12153 $prevArrow: null, 12154 scrolling: false, 12155 slideCount: null, 12156 slideWidth: null, 12157 $slideTrack: null, 12158 $slides: null, 12159 sliding: false, 12160 slideOffset: 0, 12161 swipeLeft: null, 12162 swiping: false, 12163 $list: null, 12164 touchObject: {}, 12165 transformsEnabled: false, 12166 unslicked: false 12167 }; 12168 12169 $.extend(_, _.initials); 12170 12171 _.activeBreakpoint = null; 12172 _.animType = null; 12173 _.animProp = null; 12174 _.breakpoints = []; 12175 _.breakpointSettings = []; 12176 _.cssTransitions = false; 12177 _.focussed = false; 12178 _.interrupted = false; 12179 _.hidden = 'hidden'; 12180 _.paused = true; 12181 _.positionProp = null; 12182 _.respondTo = null; 12183 _.rowCount = 1; 12184 _.shouldClick = true; 12185 _.$slider = $(element); 12186 _.$slidesCache = null; 12187 _.transformType = null; 12188 _.transitionType = null; 12189 _.visibilityChange = 'visibilitychange'; 12190 _.windowWidth = 0; 12191 _.windowTimer = null; 12192 12193 dataSettings = $(element).data('slick') || {}; 12194 12195 _.options = $.extend({}, _.defaults, settings, dataSettings); 12196 12197 _.currentSlide = _.options.initialSlide; 12198 12199 _.originalSettings = _.options; 12200 12201 if (typeof document.mozHidden !== 'undefined') { 12202 _.hidden = 'mozHidden'; 12203 _.visibilityChange = 'mozvisibilitychange'; 12204 } else if (typeof document.webkitHidden !== 'undefined') { 12205 _.hidden = 'webkitHidden'; 12206 _.visibilityChange = 'webkitvisibilitychange'; 12207 } 12208 12209 _.autoPlay = $.proxy(_.autoPlay, _); 12210 _.autoPlayClear = $.proxy(_.autoPlayClear, _); 12211 _.autoPlayIterator = $.proxy(_.autoPlayIterator, _); 12212 _.changeSlide = $.proxy(_.changeSlide, _); 12213 _.clickHandler = $.proxy(_.clickHandler, _); 12214 _.selectHandler = $.proxy(_.selectHandler, _); 12215 _.setPosition = $.proxy(_.setPosition, _); 12216 _.swipeHandler = $.proxy(_.swipeHandler, _); 12217 _.dragHandler = $.proxy(_.dragHandler, _); 12218 _.keyHandler = $.proxy(_.keyHandler, _); 12219 12220 _.instanceUid = instanceUid++; 12221 12222 // A simple way to check for HTML strings 12223 // Strict HTML recognition (must start with <) 12224 // Extracted from jQuery v1.11 source 12225 _.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/; 12226 12227 12228 _.registerBreakpoints(); 12229 _.init(true); 12230 12231 } 12232 12233 return Slick; 12234 12235 }()); 12236 12237 Slick.prototype.activateADA = function() { 12238 var _ = this; 12239 12240 _.$slideTrack.find('.slick-active').attr({ 12241 'aria-hidden': 'false' 12242 }).find('a, input, button, select').attr({ 12243 'tabindex': '0' 12244 }); 12245 12246 }; 12247 12248 Slick.prototype.addSlide = Slick.prototype.slickAdd = function(markup, index, addBefore) { 12249 12250 var _ = this; 12251 12252 if (typeof(index) === 'boolean') { 12253 addBefore = index; 12254 index = null; 12255 } else if (index < 0 || (index >= _.slideCount)) { 12256 return false; 12257 } 12258 12259 _.unload(); 12260 12261 if (typeof(index) === 'number') { 12262 if (index === 0 && _.$slides.length === 0) { 12263 $(markup).appendTo(_.$slideTrack); 12264 } else if (addBefore) { 12265 $(markup).insertBefore(_.$slides.eq(index)); 12266 } else { 12267 $(markup).insertAfter(_.$slides.eq(index)); 12268 } 12269 } else { 12270 if (addBefore === true) { 12271 $(markup).prependTo(_.$slideTrack); 12272 } else { 12273 $(markup).appendTo(_.$slideTrack); 12274 } 12275 } 12276 12277 _.$slides = _.$slideTrack.children(this.options.slide); 12278 12279 _.$slideTrack.children(this.options.slide).detach(); 12280 12281 _.$slideTrack.append(_.$slides); 12282 12283 _.$slides.each(function(index, element) { 12284 $(element).attr('data-slick-index', index); 12285 }); 12286 12287 _.$slidesCache = _.$slides; 12288 12289 _.reinit(); 12290 12291 }; 12292 12293 Slick.prototype.animateHeight = function() { 12294 var _ = this; 12295 if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) { 12296 var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true); 12297 _.$list.animate({ 12298 height: targetHeight 12299 }, _.options.speed); 12300 } 12301 }; 12302 12303 Slick.prototype.animateSlide = function(targetLeft, callback) { 12304 12305 var animProps = {}, 12306 _ = this; 12307 12308 _.animateHeight(); 12309 12310 if (_.options.rtl === true && _.options.vertical === false) { 12311 targetLeft = -targetLeft; 12312 } 12313 if (_.transformsEnabled === false) { 12314 if (_.options.vertical === false) { 12315 _.$slideTrack.animate({ 12316 left: targetLeft 12317 }, _.options.speed, _.options.easing, callback); 12318 } else { 12319 _.$slideTrack.animate({ 12320 top: targetLeft 12321 }, _.options.speed, _.options.easing, callback); 12322 } 12323 12324 } else { 12325 12326 if (_.cssTransitions === false) { 12327 if (_.options.rtl === true) { 12328 _.currentLeft = -(_.currentLeft); 12329 } 12330 $({ 12331 animStart: _.currentLeft 12332 }).animate({ 12333 animStart: targetLeft 12334 }, { 12335 duration: _.options.speed, 12336 easing: _.options.easing, 12337 step: function(now) { 12338 now = Math.ceil(now); 12339 if (_.options.vertical === false) { 12340 animProps[_.animType] = 'translate(' + 12341 now + 'px, 0px)'; 12342 _.$slideTrack.css(animProps); 12343 } else { 12344 animProps[_.animType] = 'translate(0px,' + 12345 now + 'px)'; 12346 _.$slideTrack.css(animProps); 12347 } 12348 }, 12349 complete: function() { 12350 if (callback) { 12351 callback.call(); 12352 } 12353 } 12354 }); 12355 12356 } else { 12357 12358 _.applyTransition(); 12359 targetLeft = Math.ceil(targetLeft); 12360 12361 if (_.options.vertical === false) { 12362 animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)'; 12363 } else { 12364 animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)'; 12365 } 12366 _.$slideTrack.css(animProps); 12367 12368 if (callback) { 12369 setTimeout(function() { 12370 12371 _.disableTransition(); 12372 12373 callback.call(); 12374 }, _.options.speed); 12375 } 12376 12377 } 12378 12379 } 12380 12381 }; 12382 12383 Slick.prototype.getNavTarget = function() { 12384 12385 var _ = this, 12386 asNavFor = _.options.asNavFor; 12387 12388 if ( asNavFor && asNavFor !== null ) { 12389 asNavFor = $(asNavFor).not(_.$slider); 12390 } 12391 12392 return asNavFor; 12393 12394 }; 12395 12396 Slick.prototype.asNavFor = function(index) { 12397 12398 var _ = this, 12399 asNavFor = _.getNavTarget(); 12400 12401 if ( asNavFor !== null && typeof asNavFor === 'object' ) { 12402 asNavFor.each(function() { 12403 var target = $(this).slick('getSlick'); 12404 if(!target.unslicked) { 12405 target.slideHandler(index, true); 12406 } 12407 }); 12408 } 12409 12410 }; 12411 12412 Slick.prototype.applyTransition = function(slide) { 12413 12414 var _ = this, 12415 transition = {}; 12416 12417 if (_.options.fade === false) { 12418 transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase; 12419 } else { 12420 transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase; 12421 } 12422 12423 if (_.options.fade === false) { 12424 _.$slideTrack.css(transition); 12425 } else { 12426 _.$slides.eq(slide).css(transition); 12427 } 12428 12429 }; 12430 12431 Slick.prototype.autoPlay = function() { 12432 12433 var _ = this; 12434 12435 _.autoPlayClear(); 12436 12437 if ( _.slideCount > _.options.slidesToShow ) { 12438 _.autoPlayTimer = setInterval( _.autoPlayIterator, _.options.autoplaySpeed ); 12439 } 12440 12441 }; 12442 12443 Slick.prototype.autoPlayClear = function() { 12444 12445 var _ = this; 12446 12447 if (_.autoPlayTimer) { 12448 clearInterval(_.autoPlayTimer); 12449 } 12450 12451 }; 12452 12453 Slick.prototype.autoPlayIterator = function() { 12454 12455 var _ = this, 12456 slideTo = _.currentSlide + _.options.slidesToScroll; 12457 12458 if ( !_.paused && !_.interrupted && !_.focussed ) { 12459 12460 if ( _.options.infinite === false ) { 12461 12462 if ( _.direction === 1 && ( _.currentSlide + 1 ) === ( _.slideCount - 1 )) { 12463 _.direction = 0; 12464 } 12465 12466 else if ( _.direction === 0 ) { 12467 12468 slideTo = _.currentSlide - _.options.slidesToScroll; 12469 12470 if ( _.currentSlide - 1 === 0 ) { 12471 _.direction = 1; 12472 } 12473 12474 } 12475 12476 } 12477 12478 _.slideHandler( slideTo ); 12479 12480 } 12481 12482 }; 12483 12484 Slick.prototype.buildArrows = function() { 12485 12486 var _ = this; 12487 12488 if (_.options.arrows === true ) { 12489 12490 _.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow'); 12491 _.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow'); 12492 12493 if( _.slideCount > _.options.slidesToShow ) { 12494 12495 _.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex'); 12496 _.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex'); 12497 12498 if (_.htmlExpr.test(_.options.prevArrow)) { 12499 _.$prevArrow.prependTo(_.options.appendArrows); 12500 } 12501 12502 if (_.htmlExpr.test(_.options.nextArrow)) { 12503 _.$nextArrow.appendTo(_.options.appendArrows); 12504 } 12505 12506 if (_.options.infinite !== true) { 12507 _.$prevArrow 12508 .addClass('slick-disabled') 12509 .attr('aria-disabled', 'true'); 12510 } 12511 12512 } else { 12513 12514 _.$prevArrow.add( _.$nextArrow ) 12515 12516 .addClass('slick-hidden') 12517 .attr({ 12518 'aria-disabled': 'true', 12519 'tabindex': '-1' 12520 }); 12521 12522 } 12523 12524 } 12525 12526 }; 12527 12528 Slick.prototype.buildDots = function() { 12529 12530 var _ = this, 12531 i, dot; 12532 12533 if (_.options.dots === true && _.slideCount > _.options.slidesToShow) { 12534 12535 _.$slider.addClass('slick-dotted'); 12536 12537 dot = $('<ul />').addClass(_.options.dotsClass); 12538 12539 for (i = 0; i <= _.getDotCount(); i += 1) { 12540 dot.append($('<li />').append(_.options.customPaging.call(this, _, i))); 12541 } 12542 12543 _.$dots = dot.appendTo(_.options.appendDots); 12544 12545 _.$dots.find('li').first().addClass('slick-active'); 12546 12547 } 12548 12549 }; 12550 12551 Slick.prototype.buildOut = function() { 12552 12553 var _ = this; 12554 12555 _.$slides = 12556 _.$slider 12557 .children( _.options.slide + ':not(.slick-cloned)') 12558 .addClass('slick-slide'); 12559 12560 _.slideCount = _.$slides.length; 12561 12562 _.$slides.each(function(index, element) { 12563 $(element) 12564 .attr('data-slick-index', index) 12565 .data('originalStyling', $(element).attr('style') || ''); 12566 }); 12567 12568 _.$slider.addClass('slick-slider'); 12569 12570 _.$slideTrack = (_.slideCount === 0) ? 12571 $('<div class="slick-track"/>').appendTo(_.$slider) : 12572 _.$slides.wrapAll('<div class="slick-track"/>').parent(); 12573 12574 _.$list = _.$slideTrack.wrap( 12575 '<div class="slick-list"/>').parent(); 12576 _.$slideTrack.css('opacity', 0); 12577 12578 if (_.options.centerMode === true || _.options.swipeToSlide === true) { 12579 _.options.slidesToScroll = 1; 12580 } 12581 12582 $('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading'); 12583 12584 _.setupInfinite(); 12585 12586 _.buildArrows(); 12587 12588 _.buildDots(); 12589 12590 _.updateDots(); 12591 12592 12593 _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0); 12594 12595 if (_.options.draggable === true) { 12596 _.$list.addClass('draggable'); 12597 } 12598 12599 }; 12600 12601 Slick.prototype.buildRows = function() { 12602 12603 var _ = this, a, b, c, newSlides, numOfSlides, originalSlides,slidesPerSection; 12604 12605 newSlides = document.createDocumentFragment(); 12606 originalSlides = _.$slider.children(); 12607 12608 if(_.options.rows > 0) { 12609 12610 slidesPerSection = _.options.slidesPerRow * _.options.rows; 12611 numOfSlides = Math.ceil( 12612 originalSlides.length / slidesPerSection 12613 ); 12614 12615 for(a = 0; a < numOfSlides; a++){ 12616 var slide = document.createElement('div'); 12617 for(b = 0; b < _.options.rows; b++) { 12618 var row = document.createElement('div'); 12619 for(c = 0; c < _.options.slidesPerRow; c++) { 12620 var target = (a * slidesPerSection + ((b * _.options.slidesPerRow) + c)); 12621 if (originalSlides.get(target)) { 12622 row.appendChild(originalSlides.get(target)); 12623 } 12624 } 12625 slide.appendChild(row); 12626 } 12627 newSlides.appendChild(slide); 12628 } 12629 12630 _.$slider.empty().append(newSlides); 12631 _.$slider.children().children().children() 12632 .css({ 12633 'width':(100 / _.options.slidesPerRow) + '%', 12634 'display': 'inline-block' 12635 }); 12636 12637 } 12638 12639 }; 12640 12641 Slick.prototype.checkResponsive = function(initial, forceUpdate) { 12642 12643 var _ = this, 12644 breakpoint, targetBreakpoint, respondToWidth, triggerBreakpoint = false; 12645 var sliderWidth = _.$slider.width(); 12646 var windowWidth = window.innerWidth || $(window).width(); 12647 12648 if (_.respondTo === 'window') { 12649 respondToWidth = windowWidth; 12650 } else if (_.respondTo === 'slider') { 12651 respondToWidth = sliderWidth; 12652 } else if (_.respondTo === 'min') { 12653 respondToWidth = Math.min(windowWidth, sliderWidth); 12654 } 12655 12656 if ( _.options.responsive && 12657 _.options.responsive.length && 12658 _.options.responsive !== null) { 12659 12660 targetBreakpoint = null; 12661 12662 for (breakpoint in _.breakpoints) { 12663 if (_.breakpoints.hasOwnProperty(breakpoint)) { 12664 if (_.originalSettings.mobileFirst === false) { 12665 if (respondToWidth < _.breakpoints[breakpoint]) { 12666 targetBreakpoint = _.breakpoints[breakpoint]; 12667 } 12668 } else { 12669 if (respondToWidth > _.breakpoints[breakpoint]) { 12670 targetBreakpoint = _.breakpoints[breakpoint]; 12671 } 12672 } 12673 } 12674 } 12675 12676 if (targetBreakpoint !== null) { 12677 if (_.activeBreakpoint !== null) { 12678 if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) { 12679 _.activeBreakpoint = 12680 targetBreakpoint; 12681 if (_.breakpointSettings[targetBreakpoint] === 'unslick') { 12682 _.unslick(targetBreakpoint); 12683 } else { 12684 _.options = $.extend({}, _.originalSettings, 12685 _.breakpointSettings[ 12686 targetBreakpoint]); 12687 if (initial === true) { 12688 _.currentSlide = _.options.initialSlide; 12689 } 12690 _.refresh(initial); 12691 } 12692 triggerBreakpoint = targetBreakpoint; 12693 } 12694 } else { 12695 _.activeBreakpoint = targetBreakpoint; 12696 if (_.breakpointSettings[targetBreakpoint] === 'unslick') { 12697 _.unslick(targetBreakpoint); 12698 } else { 12699 _.options = $.extend({}, _.originalSettings, 12700 _.breakpointSettings[ 12701 targetBreakpoint]); 12702 if (initial === true) { 12703 _.currentSlide = _.options.initialSlide; 12704 } 12705 _.refresh(initial); 12706 } 12707 triggerBreakpoint = targetBreakpoint; 12708 } 12709 } else { 12710 if (_.activeBreakpoint !== null) { 12711 _.activeBreakpoint = null; 12712 _.options = _.originalSettings; 12713 if (initial === true) { 12714 _.currentSlide = _.options.initialSlide; 12715 } 12716 _.refresh(initial); 12717 triggerBreakpoint = targetBreakpoint; 12718 } 12719 } 12720 12721 // only trigger breakpoints during an actual break. not on initialize. 12722 if( !initial && triggerBreakpoint !== false ) { 12723 _.$slider.trigger('breakpoint', [_, triggerBreakpoint]); 12724 } 12725 } 12726 12727 }; 12728 12729 Slick.prototype.changeSlide = function(event, dontAnimate) { 12730 12731 var _ = this, 12732 $target = $(event.currentTarget), 12733 indexOffset, slideOffset, unevenOffset; 12734 12735 // If target is a link, prevent default action. 12736 if($target.is('a')) { 12737 event.preventDefault(); 12738 } 12739 12740 // If target is not the <li> element (ie: a child), find the <li>. 12741 if(!$target.is('li')) { 12742 $target = $target.closest('li'); 12743 } 12744 12745 unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0); 12746 indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll; 12747 12748 switch (event.data.message) { 12749 12750 case 'previous': 12751 slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset; 12752 if (_.slideCount > _.options.slidesToShow) { 12753 _.slideHandler(_.currentSlide - slideOffset, false, dontAnimate); 12754 } 12755 break; 12756 12757 case 'next': 12758 slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset; 12759 if (_.slideCount > _.options.slidesToShow) { 12760 _.slideHandler(_.currentSlide + slideOffset, false, dontAnimate); 12761 } 12762 break; 12763 12764 case 'index': 12765 var index = event.data.index === 0 ? 0 : 12766 event.data.index || $target.index() * _.options.slidesToScroll; 12767 12768 _.slideHandler(_.checkNavigable(index), false, dontAnimate); 12769 $target.children().trigger('focus'); 12770 break; 12771 12772 default: 12773 return; 12774 } 12775 12776 }; 12777 12778 Slick.prototype.checkNavigable = function(index) { 12779 12780 var _ = this, 12781 navigables, prevNavigable; 12782 12783 navigables = _.getNavigableIndexes(); 12784 prevNavigable = 0; 12785 if (index > navigables[navigables.length - 1]) { 12786 index = navigables[navigables.length - 1]; 12787 } else { 12788 for (var n in navigables) { 12789 if (index < navigables[n]) { 12790 index = prevNavigable; 12791 break; 12792 } 12793 prevNavigable = navigables[n]; 12794 } 12795 } 12796 12797 return index; 12798 }; 12799 12800 Slick.prototype.cleanUpEvents = function() { 12801 12802 var _ = this; 12803 12804 if (_.options.dots && _.$dots !== null) { 12805 12806 $('li', _.$dots) 12807 .off('click.slick', _.changeSlide) 12808 .off('mouseenter.slick', $.proxy(_.interrupt, _, true)) 12809 .off('mouseleave.slick', $.proxy(_.interrupt, _, false)); 12810 12811 if (_.options.accessibility === true) { 12812 _.$dots.off('keydown.slick', _.keyHandler); 12813 } 12814 } 12815 12816 _.$slider.off('focus.slick blur.slick'); 12817 12818 if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) { 12819 _.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide); 12820 _.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide); 12821 12822 if (_.options.accessibility === true) { 12823 _.$prevArrow && _.$prevArrow.off('keydown.slick', _.keyHandler); 12824 _.$nextArrow && _.$nextArrow.off('keydown.slick', _.keyHandler); 12825 } 12826 } 12827 12828 _.$list.off('touchstart.slick mousedown.slick', _.swipeHandler); 12829 _.$list.off('touchmove.slick mousemove.slick', _.swipeHandler); 12830 _.$list.off('touchend.slick mouseup.slick', _.swipeHandler); 12831 _.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler); 12832 12833 _.$list.off('click.slick', _.clickHandler); 12834 12835 $(document).off(_.visibilityChange, _.visibility); 12836 12837 _.cleanUpSlideEvents(); 12838 12839 if (_.options.accessibility === true) { 12840 _.$list.off('keydown.slick', _.keyHandler); 12841 } 12842 12843 if (_.options.focusOnSelect === true) { 12844 $(_.$slideTrack).children().off('click.slick', _.selectHandler); 12845 } 12846 12847 $(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange); 12848 12849 $(window).off('resize.slick.slick-' + _.instanceUid, _.resize); 12850 12851 $('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault); 12852 12853 $(window).off('load.slick.slick-' + _.instanceUid, _.setPosition); 12854 12855 }; 12856 12857 Slick.prototype.cleanUpSlideEvents = function() { 12858 12859 var _ = this; 12860 12861 _.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true)); 12862 _.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false)); 12863 12864 }; 12865 12866 Slick.prototype.cleanUpRows = function() { 12867 12868 var _ = this, originalSlides; 12869 12870 if(_.options.rows > 0) { 12871 originalSlides = _.$slides.children().children(); 12872 originalSlides.removeAttr('style'); 12873 _.$slider.empty().append(originalSlides); 12874 } 12875 12876 }; 12877 12878 Slick.prototype.clickHandler = function(event) { 12879 12880 var _ = this; 12881 12882 if (_.shouldClick === false) { 12883 event.stopImmediatePropagation(); 12884 event.stopPropagation(); 12885 event.preventDefault(); 12886 } 12887 12888 }; 12889 12890 Slick.prototype.destroy = function(refresh) { 12891 12892 var _ = this; 12893 12894 _.autoPlayClear(); 12895 12896 _.touchObject = {}; 12897 12898 _.cleanUpEvents(); 12899 12900 $('.slick-cloned', _.$slider).detach(); 12901 12902 if (_.$dots) { 12903 _.$dots.remove(); 12904 } 12905 12906 if ( _.$prevArrow && _.$prevArrow.length ) { 12907 12908 _.$prevArrow 12909 .removeClass('slick-disabled slick-arrow slick-hidden') 12910 .removeAttr('aria-hidden aria-disabled tabindex') 12911 .css('display',''); 12912 12913 if ( _.htmlExpr.test( _.options.prevArrow )) { 12914 _.$prevArrow.remove(); 12915 } 12916 } 12917 12918 if ( _.$nextArrow && _.$nextArrow.length ) { 12919 12920 _.$nextArrow 12921 .removeClass('slick-disabled slick-arrow slick-hidden') 12922 .removeAttr('aria-hidden aria-disabled tabindex') 12923 .css('display',''); 12924 12925 if ( _.htmlExpr.test( _.options.nextArrow )) { 12926 _.$nextArrow.remove(); 12927 } 12928 } 12929 12930 12931 if (_.$slides) { 12932 12933 _.$slides 12934 .removeClass('slick-slide slick-active slick-center slick-visible slick-current') 12935 .removeAttr('aria-hidden') 12936 .removeAttr('data-slick-index') 12937 .each(function(){ 12938 $(this).attr('style', $(this).data('originalStyling')); 12939 }); 12940 12941 _.$slideTrack.children(this.options.slide).detach(); 12942 12943 _.$slideTrack.detach(); 12944 12945 _.$list.detach(); 12946 12947 _.$slider.append(_.$slides); 12948 } 12949 12950 _.cleanUpRows(); 12951 12952 _.$slider.removeClass('slick-slider'); 12953 _.$slider.removeClass('slick-initialized'); 12954 _.$slider.removeClass('slick-dotted'); 12955 12956 _.unslicked = true; 12957 12958 if(!refresh) { 12959 _.$slider.trigger('destroy', [_]); 12960 } 12961 12962 }; 12963 12964 Slick.prototype.disableTransition = function(slide) { 12965 12966 var _ = this, 12967 transition = {}; 12968 12969 transition[_.transitionType] = ''; 12970 12971 if (_.options.fade === false) { 12972 _.$slideTrack.css(transition); 12973 } else { 12974 _.$slides.eq(slide).css(transition); 12975 } 12976 12977 }; 12978 12979 Slick.prototype.fadeSlide = function(slideIndex, callback) { 12980 12981 var _ = this; 12982 12983 if (_.cssTransitions === false) { 12984 12985 _.$slides.eq(slideIndex).css({ 12986 zIndex: _.options.zIndex 12987 }); 12988 12989 _.$slides.eq(slideIndex).animate({ 12990 opacity: 1 12991 }, _.options.speed, _.options.easing, callback); 12992 12993 } else { 12994 12995 _.applyTransition(slideIndex); 12996 12997 _.$slides.eq(slideIndex).css({ 12998 opacity: 1, 12999 zIndex: _.options.zIndex 13000 }); 13001 13002 if (callback) { 13003 setTimeout(function() { 13004 13005 _.disableTransition(slideIndex); 13006 13007 callback.call(); 13008 }, _.options.speed); 13009 } 13010 13011 } 13012 13013 }; 13014 13015 Slick.prototype.fadeSlideOut = function(slideIndex) { 13016 13017 var _ = this; 13018 13019 if (_.cssTransitions === false) { 13020 13021 _.$slides.eq(slideIndex).animate({ 13022 opacity: 0, 13023 zIndex: _.options.zIndex - 2 13024 }, _.options.speed, _.options.easing); 13025 13026 } else { 13027 13028 _.applyTransition(slideIndex); 13029 13030 _.$slides.eq(slideIndex).css({ 13031 opacity: 0, 13032 zIndex: _.options.zIndex - 2 13033 }); 13034 13035 } 13036 13037 }; 13038 13039 Slick.prototype.filterSlides = Slick.prototype.slickFilter = function(filter) { 13040 13041 var _ = this; 13042 13043 if (filter !== null) { 13044 13045 _.$slidesCache = _.$slides; 13046 13047 _.unload(); 13048 13049 _.$slideTrack.children(this.options.slide).detach(); 13050 13051 _.$slidesCache.filter(filter).appendTo(_.$slideTrack); 13052 13053 _.reinit(); 13054 13055 } 13056 13057 }; 13058 13059 Slick.prototype.focusHandler = function() { 13060 13061 var _ = this; 13062 13063 _.$slider 13064 .off('focus.slick blur.slick') 13065 .on('focus.slick blur.slick', '*', function(event) { 13066 13067 event.stopImmediatePropagation(); 13068 var $sf = $(this); 13069 13070 setTimeout(function() { 13071 13072 if( _.options.pauseOnFocus ) { 13073 _.focussed = $sf.is(':focus'); 13074 _.autoPlay(); 13075 } 13076 13077 }, 0); 13078 13079 }); 13080 }; 13081 13082 Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function() { 13083 13084 var _ = this; 13085 return _.currentSlide; 13086 13087 }; 13088 13089 Slick.prototype.getDotCount = function() { 13090 13091 var _ = this; 13092 13093 var breakPoint = 0; 13094 var counter = 0; 13095 var pagerQty = 0; 13096 13097 if (_.options.infinite === true) { 13098 if (_.slideCount <= _.options.slidesToShow) { 13099 ++pagerQty; 13100 } else { 13101 while (breakPoint < _.slideCount) { 13102 ++pagerQty; 13103 breakPoint = counter + _.options.slidesToScroll; 13104 counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow; 13105 } 13106 } 13107 } else if (_.options.centerMode === true) { 13108 pagerQty = _.slideCount; 13109 } else if(!_.options.asNavFor) { 13110 pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll); 13111 }else { 13112 while (breakPoint < _.slideCount) { 13113 ++pagerQty; 13114 breakPoint = counter + _.options.slidesToScroll; 13115 counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow; 13116 } 13117 } 13118 13119 return pagerQty - 1; 13120 13121 }; 13122 13123 Slick.prototype.getLeft = function(slideIndex) { 13124 13125 var _ = this, 13126 targetLeft, 13127 verticalHeight, 13128 verticalOffset = 0, 13129 targetSlide, 13130 coef; 13131 13132 _.slideOffset = 0; 13133 verticalHeight = _.$slides.first().outerHeight(true); 13134 13135 if (_.options.infinite === true) { 13136 if (_.slideCount > _.options.slidesToShow) { 13137 _.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1; 13138 coef = -1
13138 13139 13140 if (_.options.vertical === true && _.options.centerMode === true) { 13141 if (_.options.slidesToShow === 2) { 13142 coef = -1.5; 13143 } else if (_.options.slidesToShow === 1) { 13144 coef = -2
vendor: 47,517 bytes, lines 13144-14747
13144 13145 } 13146 } 13147 verticalOffset = (verticalHeight * _.options.slidesToShow) * coef; 13148 } 13149 if (_.slideCount % _.options.slidesToScroll !== 0) { 13150 if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) { 13151 if (slideIndex > _.slideCount) { 13152 _.slideOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth) * -1; 13153 verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1; 13154 } else { 13155 _.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1; 13156 verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1; 13157 } 13158 } 13159 } 13160 } else { 13161 if (slideIndex + _.options.slidesToShow > _.slideCount) { 13162 _.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth; 13163 verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight; 13164 } 13165 } 13166 13167 if (_.slideCount <= _.options.slidesToShow) { 13168 _.slideOffset = 0; 13169 verticalOffset = 0; 13170 } 13171 13172 if (_.options.centerMode === true && _.slideCount <= _.options.slidesToShow) { 13173 _.slideOffset = ((_.slideWidth * Math.floor(_.options.slidesToShow)) / 2) - ((_.slideWidth * _.slideCount) / 2); 13174 } else if (_.options.centerMode === true && _.options.infinite === true) { 13175 _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth; 13176 } else if (_.options.centerMode === true) { 13177 _.slideOffset = 0; 13178 _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2); 13179 } 13180 13181 if (_.options.vertical === false) { 13182 targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset; 13183 } else { 13184 targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset; 13185 } 13186 13187 if (_.options.variableWidth === true) { 13188 13189 if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) { 13190 targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex); 13191 } else { 13192 targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow); 13193 } 13194 13195 if (_.options.rtl === true) { 13196 if (targetSlide[0]) { 13197 targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1; 13198 } else { 13199 targetLeft = 0; 13200 } 13201 } else { 13202 targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0; 13203 } 13204 13205 if (_.options.centerMode === true) { 13206 if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) { 13207 targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex); 13208 } else { 13209 targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1); 13210 } 13211 13212 if (_.options.rtl === true) { 13213 if (targetSlide[0]) { 13214 targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1; 13215 } else { 13216 targetLeft = 0; 13217 } 13218 } else { 13219 targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0; 13220 } 13221 13222 targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2; 13223 } 13224 } 13225 13226 return targetLeft; 13227 13228 }; 13229 13230 Slick.prototype.getOption = Slick.prototype.slickGetOption = function(option) { 13231 13232 var _ = this; 13233 13234 return _.options[option]; 13235 13236 }; 13237 13238 Slick.prototype.getNavigableIndexes = function() { 13239 13240 var _ = this, 13241 breakPoint = 0, 13242 counter = 0, 13243 indexes = [], 13244 max; 13245 13246 if (_.options.infinite === false) { 13247 max = _.slideCount; 13248 } else { 13249 breakPoint = _.options.slidesToScroll * -1; 13250 counter = _.options.slidesToScroll * -1; 13251 max = _.slideCount * 2; 13252 } 13253 13254 while (breakPoint < max) { 13255 indexes.push(breakPoint); 13256 breakPoint = counter + _.options.slidesToScroll; 13257 counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow; 13258 } 13259 13260 return indexes; 13261 13262 }; 13263 13264 Slick.prototype.getSlick = function() { 13265 13266 return this; 13267 13268 }; 13269 13270 Slick.prototype.getSlideCount = function() { 13271 13272 var _ = this, 13273 slidesTraversed, swipedSlide, centerOffset; 13274 13275 centerOffset = _.options.centerMode === true ? _.slideWidth * Math.floor(_.options.slidesToShow / 2) : 0; 13276 13277 if (_.options.swipeToSlide === true) { 13278 _.$slideTrack.find('.slick-slide').each(function(index, slide) { 13279 if (slide.offsetLeft - centerOffset + ($(slide).outerWidth() / 2) > (_.swipeLeft * -1)) { 13280 swipedSlide = slide; 13281 return false; 13282 } 13283 }); 13284 13285 slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1; 13286 13287 return slidesTraversed; 13288 13289 } else { 13290 return _.options.slidesToScroll; 13291 } 13292 13293 }; 13294 13295 Slick.prototype.goTo = Slick.prototype.slickGoTo = function(slide, dontAnimate) { 13296 13297 var _ = this; 13298 13299 _.changeSlide({ 13300 data: { 13301 message: 'index', 13302 index: parseInt(slide) 13303 } 13304 }, dontAnimate); 13305 13306 }; 13307 13308 Slick.prototype.init = function(creation) { 13309 13310 var _ = this; 13311 13312 if (!$(_.$slider).hasClass('slick-initialized')) { 13313 13314 $(_.$slider).addClass('slick-initialized'); 13315 13316 _.buildRows(); 13317 _.buildOut(); 13318 _.setProps(); 13319 _.startLoad(); 13320 _.loadSlider(); 13321 _.initializeEvents(); 13322 _.updateArrows(); 13323 _.updateDots(); 13324 _.checkResponsive(true); 13325 _.focusHandler(); 13326 13327 } 13328 13329 if (creation) { 13330 _.$slider.trigger('init', [_]); 13331 } 13332 13333 if (_.options.accessibility === true) { 13334 _.initADA(); 13335 } 13336 13337 if ( _.options.autoplay ) { 13338 13339 _.paused = false; 13340 _.autoPlay(); 13341 13342 } 13343 13344 }; 13345 13346 Slick.prototype.initADA = function() { 13347 var _ = this, 13348 numDotGroups = Math.ceil(_.slideCount / _.options.slidesToShow), 13349 tabControlIndexes = _.getNavigableIndexes().filter(function(val) { 13350 return (val >= 0) && (val < _.slideCount); 13351 }); 13352 13353 _.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({ 13354 'aria-hidden': 'true', 13355 'tabindex': '-1' 13356 }).find('a, input, button, select').attr({ 13357 'tabindex': '-1' 13358 }); 13359 13360 if (_.$dots !== null) { 13361 _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function(i) { 13362 var slideControlIndex = tabControlIndexes.indexOf(i); 13363 13364 $(this).attr({ 13365 'role': 'tabpanel', 13366 'id': 'slick-slide' + _.instanceUid + i, 13367 'tabindex': -1 13368 }); 13369 13370 if (slideControlIndex !== -1) { 13371 var ariaButtonControl = 'slick-slide-control' + _.instanceUid + slideControlIndex 13372 if ($('#' + ariaButtonControl).length) { 13373 $(this).attr({ 13374 'aria-describedby': ariaButtonControl 13375 }); 13376 } 13377 } 13378 }); 13379 13380 _.$dots.attr('role', 'tablist').find('li').each(function(i) { 13381 var mappedSlideIndex = tabControlIndexes[i]; 13382 13383 $(this).attr({ 13384 'role': 'presentation' 13385 }); 13386 13387 $(this).find('button').first().attr({ 13388 'role': 'tab', 13389 'id': 'slick-slide-control' + _.instanceUid + i, 13390 'aria-controls': 'slick-slide' + _.instanceUid + mappedSlideIndex, 13391 'aria-label': (i + 1) + ' of ' + numDotGroups, 13392 'aria-selected': null, 13393 'tabindex': '-1' 13394 }); 13395 13396 }).eq(_.currentSlide).find('button').attr({ 13397 'aria-selected': 'true', 13398 'tabindex': '0' 13399 }).end(); 13400 } 13401 13402 for (var i=_.currentSlide, max=i+_.options.slidesToShow; i < max; i++) { 13403 if (_.options.focusOnChange) { 13404 _.$slides.eq(i).attr({'tabindex': '0'}); 13405 } else { 13406 _.$slides.eq(i).removeAttr('tabindex'); 13407 } 13408 } 13409 13410 _.activateADA(); 13411 13412 }; 13413 13414 Slick.prototype.initArrowEvents = function() { 13415 13416 var _ = this; 13417 13418 if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) { 13419 _.$prevArrow 13420 .off('click.slick') 13421 .on('click.slick', { 13422 message: 'previous' 13423 }, _.changeSlide); 13424 _.$nextArrow 13425 .off('click.slick') 13426 .on('click.slick', { 13427 message: 'next' 13428 }, _.changeSlide); 13429 13430 if (_.options.accessibility === true) { 13431 _.$prevArrow.on('keydown.slick', _.keyHandler); 13432 _.$nextArrow.on('keydown.slick', _.keyHandler); 13433 } 13434 } 13435 13436 }; 13437 13438 Slick.prototype.initDotEvents = function() { 13439 13440 var _ = this; 13441 13442 if (_.options.dots === true && _.slideCount > _.options.slidesToShow) { 13443 $('li', _.$dots).on('click.slick', { 13444 message: 'index' 13445 }, _.changeSlide); 13446 13447 if (_.options.accessibility === true) { 13448 _.$dots.on('keydown.slick', _.keyHandler); 13449 } 13450 } 13451 13452 if (_.options.dots === true && _.options.pauseOnDotsHover === true && _.slideCount > _.options.slidesToShow) { 13453 13454 $('li', _.$dots) 13455 .on('mouseenter.slick', $.proxy(_.interrupt, _, true)) 13456 .on('mouseleave.slick', $.proxy(_.interrupt, _, false)); 13457 13458 } 13459 13460 }; 13461 13462 Slick.prototype.initSlideEvents = function() { 13463 13464 var _ = this; 13465 13466 if ( _.options.pauseOnHover ) { 13467 13468 _.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true)); 13469 _.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false)); 13470 13471 } 13472 13473 }; 13474 13475 Slick.prototype.initializeEvents = function() { 13476 13477 var _ = this; 13478 13479 _.initArrowEvents(); 13480 13481 _.initDotEvents(); 13482 _.initSlideEvents(); 13483 13484 _.$list.on('touchstart.slick mousedown.slick', { 13485 action: 'start' 13486 }, _.swipeHandler); 13487 _.$list.on('touchmove.slick mousemove.slick', { 13488 action: 'move' 13489 }, _.swipeHandler); 13490 _.$list.on('touchend.slick mouseup.slick', { 13491 action: 'end' 13492 }, _.swipeHandler); 13493 _.$list.on('touchcancel.slick mouseleave.slick', { 13494 action: 'end' 13495 }, _.swipeHandler); 13496 13497 _.$list.on('click.slick', _.clickHandler); 13498 13499 $(document).on(_.visibilityChange, $.proxy(_.visibility, _)); 13500 13501 if (_.options.accessibility === true) { 13502 _.$list.on('keydown.slick', _.keyHandler); 13503 } 13504 13505 if (_.options.focusOnSelect === true) { 13506 $(_.$slideTrack).children().on('click.slick', _.selectHandler); 13507 } 13508 13509 $(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _)); 13510 13511 $(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _)); 13512 13513 $('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault); 13514 13515 $(window).on('load.slick.slick-' + _.instanceUid, _.setPosition); 13516 $(_.setPosition); 13517 13518 }; 13519 13520 Slick.prototype.initUI = function() { 13521 13522 var _ = this; 13523 13524 if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) { 13525 13526 _.$prevArrow.show(); 13527 _.$nextArrow.show(); 13528 13529 } 13530 13531 if (_.options.dots === true && _.slideCount > _.options.slidesToShow) { 13532 13533 _.$dots.show(); 13534 13535 } 13536 13537 }; 13538 13539 Slick.prototype.keyHandler = function(event) { 13540 13541 var _ = this; 13542 //Dont slide if the cursor is inside the form fields and arrow keys are pressed 13543 if(!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) { 13544 if (event.keyCode === 37 && _.options.accessibility === true) { 13545 _.changeSlide({ 13546 data: { 13547 message: _.options.rtl === true ? 'next' : 'previous' 13548 } 13549 }); 13550 } else if (event.keyCode === 39 && _.options.accessibility === true) { 13551 _.changeSlide({ 13552 data: { 13553 message: _.options.rtl === true ? 'previous' : 'next' 13554 } 13555 }); 13556 } 13557 } 13558 13559 }; 13560 13561 Slick.prototype.lazyLoad = function() { 13562 13563 var _ = this, 13564 loadRange, cloneRange, rangeStart, rangeEnd; 13565 13566 function loadImages(imagesScope) { 13567 13568 $('img[data-lazy]', imagesScope).each(function() { 13569 13570 var image = $(this), 13571 imageSource = $(this).attr('data-lazy'), 13572 imageSrcSet = $(this).attr('data-srcset'), 13573 imageSizes = $(this).attr('data-sizes') || _.$slider.attr('data-sizes'), 13574 imageToLoad = document.createElement('img'); 13575 13576 imageToLoad.onload = function() { 13577 13578 image 13579 .animate({ opacity: 0 }, 100, function() { 13580 13581 if (imageSrcSet) { 13582 image 13583 .attr('srcset', imageSrcSet ); 13584 13585 if (imageSizes) { 13586 image 13587 .attr('sizes', imageSizes ); 13588 } 13589 } 13590 13591 image 13592 .attr('src', imageSource) 13593 .animate({ opacity: 1 }, 200, function() { 13594 image 13595 .removeAttr('data-lazy data-srcset data-sizes') 13596 .removeClass('slick-loading'); 13597 }); 13598 _.$slider.trigger('lazyLoaded', [_, image, imageSource]); 13599 }); 13600 13601 }; 13602 13603 imageToLoad.onerror = function() { 13604 13605 image 13606 .removeAttr( 'data-lazy' ) 13607 .removeClass( 'slick-loading' ) 13608 .addClass( 'slick-lazyload-error' ); 13609 13610 _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]); 13611 13612 }; 13613 13614 imageToLoad.src = imageSource; 13615 13616 }); 13617 13618 } 13619 13620 if (_.options.centerMode === true) { 13621 if (_.options.infinite === true) { 13622 rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1); 13623 rangeEnd = rangeStart + _.options.slidesToShow + 2; 13624 } else { 13625 rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1)); 13626 rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide; 13627 } 13628 } else { 13629 rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide; 13630 rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow); 13631 if (_.options.fade === true) { 13632 if (rangeStart > 0) rangeStart--; 13633 if (rangeEnd <= _.slideCount) rangeEnd++; 13634 } 13635 } 13636 13637 loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd); 13638 13639 if (_.options.lazyLoad === 'anticipated') { 13640 var prevSlide = rangeStart - 1, 13641 nextSlide = rangeEnd, 13642 $slides = _.$slider.find('.slick-slide'); 13643 13644 for (var i = 0; i < _.options.slidesToScroll; i++) { 13645 if (prevSlide < 0) prevSlide = _.slideCount - 1; 13646 loadRange = loadRange.add($slides.eq(prevSlide)); 13647 loadRange = loadRange.add($slides.eq(nextSlide)); 13648 prevSlide--; 13649 nextSlide++; 13650 } 13651 } 13652 13653 loadImages(loadRange); 13654 13655 if (_.slideCount <= _.options.slidesToShow) { 13656 cloneRange = _.$slider.find('.slick-slide'); 13657 loadImages(cloneRange); 13658 } else 13659 if (_.currentSlide >= _.slideCount - _.options.slidesToShow) { 13660 cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow); 13661 loadImages(cloneRange); 13662 } else if (_.currentSlide === 0) { 13663 cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1); 13664 loadImages(cloneRange); 13665 } 13666 13667 }; 13668 13669 Slick.prototype.loadSlider = function() { 13670 13671 var _ = this; 13672 13673 _.setPosition(); 13674 13675 _.$slideTrack.css({ 13676 opacity: 1 13677 }); 13678 13679 _.$slider.removeClass('slick-loading'); 13680 13681 _.initUI(); 13682 13683 if (_.options.lazyLoad === 'progressive') { 13684 _.progressiveLazyLoad(); 13685 } 13686 13687 }; 13688 13689 Slick.prototype.next = Slick.prototype.slickNext = function() { 13690 13691 var _ = this; 13692 13693 _.changeSlide({ 13694 data: { 13695 message: 'next' 13696 } 13697 }); 13698 13699 }; 13700 13701 Slick.prototype.orientationChange = function() { 13702 13703 var _ = this; 13704 13705 _.checkResponsive(); 13706 _.setPosition(); 13707 13708 }; 13709 13710 Slick.prototype.pause = Slick.prototype.slickPause = function() { 13711 13712 var _ = this; 13713 13714 _.autoPlayClear(); 13715 _.paused = true; 13716 13717 }; 13718 13719 Slick.prototype.play = Slick.prototype.slickPlay = function() { 13720 13721 var _ = this; 13722 13723 _.autoPlay(); 13724 _.options.autoplay = true; 13725 _.paused = false; 13726 _.focussed = false; 13727 _.interrupted = false; 13728 13729 }; 13730 13731 Slick.prototype.postSlide = function(index) { 13732 13733 var _ = this; 13734 13735 if( !_.unslicked ) { 13736 13737 _.$slider.trigger('afterChange', [_, index]); 13738 13739 _.animating = false; 13740 13741 if (_.slideCount > _.options.slidesToShow) { 13742 _.setPosition(); 13743 } 13744 13745 _.swipeLeft = null; 13746 13747 if ( _.options.autoplay ) { 13748 _.autoPlay(); 13749 } 13750 13751 if (_.options.accessibility === true) { 13752 _.initADA(); 13753 13754 if (_.options.focusOnChange) { 13755 var $currentSlide = $(_.$slides.get(_.currentSlide)); 13756 $currentSlide.attr('tabindex', 0).focus(); 13757 } 13758 } 13759 13760 } 13761 13762 }; 13763 13764 Slick.prototype.prev = Slick.prototype.slickPrev = function() { 13765 13766 var _ = this; 13767 13768 _.changeSlide({ 13769 data: { 13770 message: 'previous' 13771 } 13772 }); 13773 13774 }; 13775 13776 Slick.prototype.preventDefault = function(event) { 13777 13778 event.preventDefault(); 13779 13780 }; 13781 13782 Slick.prototype.progressiveLazyLoad = function( tryCount ) { 13783 13784 tryCount = tryCount || 1; 13785 13786 var _ = this, 13787 $imgsToLoad = $( 'img[data-lazy]', _.$slider ), 13788 image, 13789 imageSource, 13790 imageSrcSet, 13791 imageSizes, 13792 imageToLoad; 13793 13794 if ( $imgsToLoad.length ) { 13795 13796 image = $imgsToLoad.first(); 13797 imageSource = image.attr('data-lazy'); 13798 imageSrcSet = image.attr('data-srcset'); 13799 imageSizes = image.attr('data-sizes') || _.$slider.attr('data-sizes'); 13800 imageToLoad = document.createElement('img'); 13801 13802 imageToLoad.onload = function() { 13803 13804 if (imageSrcSet) { 13805 image 13806 .attr('srcset', imageSrcSet ); 13807 13808 if (imageSizes) { 13809 image 13810 .attr('sizes', imageSizes ); 13811 } 13812 } 13813 13814 image 13815 .attr( 'src', imageSource ) 13816 .removeAttr('data-lazy data-srcset data-sizes') 13817 .removeClass('slick-loading'); 13818 13819 if ( _.options.adaptiveHeight === true ) { 13820 _.setPosition(); 13821 } 13822 13823 _.$slider.trigger('lazyLoaded', [ _, image, imageSource ]); 13824 _.progressiveLazyLoad(); 13825 13826 }; 13827 13828 imageToLoad.onerror = function() { 13829 13830 if ( tryCount < 3 ) { 13831 13832 /** 13833 * try to load the image 3 times, 13834 * leave a slight delay so we don't get 13835 * servers blocking the request. 13836 */ 13837 setTimeout( function() { 13838 _.progressiveLazyLoad( tryCount + 1 ); 13839 }, 500 ); 13840 13841 } else { 13842 13843 image 13844 .removeAttr( 'data-lazy' ) 13845 .removeClass( 'slick-loading' ) 13846 .addClass( 'slick-lazyload-error' ); 13847 13848 _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]); 13849 13850 _.progressiveLazyLoad(); 13851 13852 } 13853 13854 }; 13855 13856 imageToLoad.src = imageSource; 13857 13858 } else { 13859 13860 _.$slider.trigger('allImagesLoaded', [ _ ]); 13861 13862 } 13863 13864 }; 13865 13866 Slick.prototype.refresh = function( initializing ) { 13867 13868 var _ = this, currentSlide, lastVisibleIndex; 13869 13870 lastVisibleIndex = _.slideCount - _.options.slidesToShow; 13871 13872 // in non-infinite sliders, we don't want to go past the 13873 // last visible index. 13874 if( !_.options.infinite && ( _.currentSlide > lastVisibleIndex )) { 13875 _.currentSlide = lastVisibleIndex; 13876 } 13877 13878 // if less slides than to show, go to start. 13879 if ( _.slideCount <= _.options.slidesToShow ) { 13880 _.currentSlide = 0; 13881 13882 } 13883 13884 currentSlide = _.currentSlide; 13885 13886 _.destroy(true); 13887 13888 $.extend(_, _.initials, { currentSlide: currentSlide }); 13889 13890 _.init(); 13891 13892 if( !initializing ) { 13893 13894 _.changeSlide({ 13895 data: { 13896 message: 'index', 13897 index: currentSlide 13898 } 13899 }, false); 13900 13901 } 13902 13903 }; 13904 13905 Slick.prototype.registerBreakpoints = function() { 13906 13907 var _ = this, breakpoint, currentBreakpoint, l, 13908 responsiveSettings = _.options.responsive || null; 13909 13910 if ( $.type(responsiveSettings) === 'array' && responsiveSettings.length ) { 13911 13912 _.respondTo = _.options.respondTo || 'window'; 13913 13914 for ( breakpoint in responsiveSettings ) { 13915 13916 l = _.breakpoints.length-1; 13917 13918 if (responsiveSettings.hasOwnProperty(breakpoint)) { 13919 currentBreakpoint = responsiveSettings[breakpoint].breakpoint; 13920 13921 // loop through the breakpoints and cut out any existing 13922 // ones with the same breakpoint number, we don't want dupes. 13923 while( l >= 0 ) { 13924 if( _.breakpoints[l] && _.breakpoints[l] === currentBreakpoint ) { 13925 _.breakpoints.splice(l,1); 13926 } 13927 l--; 13928 } 13929 13930 _.breakpoints.push(currentBreakpoint); 13931 _.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings; 13932 13933 } 13934 13935 } 13936 13937 _.breakpoints.sort(function(a, b) { 13938 return ( _.options.mobileFirst ) ? a-b : b-a; 13939 }); 13940 13941 } 13942 13943 }; 13944 13945 Slick.prototype.reinit = function() { 13946 13947 var _ = this; 13948 13949 _.$slides = 13950 _.$slideTrack 13951 .children(_.options.slide) 13952 .addClass('slick-slide'); 13953 13954 _.slideCount = _.$slides.length; 13955 13956 if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) { 13957 _.currentSlide = _.currentSlide - _.options.slidesToScroll; 13958 } 13959 13960 if (_.slideCount <= _.options.slidesToShow) { 13961 _.currentSlide = 0; 13962 } 13963 13964 _.registerBreakpoints(); 13965 13966 _.setProps(); 13967 _.setupInfinite(); 13968 _.buildArrows(); 13969 _.updateArrows(); 13970 _.initArrowEvents(); 13971 _.buildDots(); 13972 _.updateDots(); 13973 _.initDotEvents(); 13974 _.cleanUpSlideEvents(); 13975 _.initSlideEvents(); 13976 13977 _.checkResponsive(false, true); 13978 13979 if (_.options.focusOnSelect === true) { 13980 $(_.$slideTrack).children().on('click.slick', _.selectHandler); 13981 } 13982 13983 _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0); 13984 13985 _.setPosition(); 13986 _.focusHandler(); 13987 13988 _.paused = !_.options.autoplay; 13989 _.autoPlay(); 13990 13991 _.$slider.trigger('reInit', [_]); 13992 13993 }; 13994 13995 Slick.prototype.resize = function() { 13996 13997 var _ = this; 13998 13999 if ($(window).width() !== _.windowWidth) { 14000 clearTimeout(_.windowDelay); 14001 _.windowDelay = window.setTimeout(function() { 14002 _.windowWidth = $(window).width(); 14003 _.checkResponsive(); 14004 if( !_.unslicked ) { _.setPosition(); } 14005 }, 50); 14006 } 14007 }; 14008 14009 Slick.prototype.removeSlide = Slick.prototype.slickRemove = function(index, removeBefore, removeAll) { 14010 14011 var _ = this; 14012 14013 if (typeof(index) === 'boolean') { 14014 removeBefore = index; 14015 index = removeBefore === true ? 0 : _.slideCount - 1; 14016 } else { 14017 index = removeBefore === true ? --index : index; 14018 } 14019 14020 if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) { 14021 return false; 14022 } 14023 14024 _.unload(); 14025 14026 if (removeAll === true) { 14027 _.$slideTrack.children().remove(); 14028 } else { 14029 _.$slideTrack.children(this.options.slide).eq(index).remove(); 14030 } 14031 14032 _.$slides = _.$slideTrack.children(this.options.slide); 14033 14034 _.$slideTrack.children(this.options.slide).detach(); 14035 14036 _.$slideTrack.append(_.$slides); 14037 14038 _.$slidesCache = _.$slides; 14039 14040 _.reinit(); 14041 14042 }; 14043 14044 Slick.prototype.setCSS = function(position) { 14045 14046 var _ = this, 14047 positionProps = {}, 14048 x, y; 14049 14050 if (_.options.rtl === true) { 14051 position = -position; 14052 } 14053 x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px'; 14054 y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px'; 14055 14056 positionProps[_.positionProp] = position; 14057 14058 if (_.transformsEnabled === false) { 14059 _.$slideTrack.css(positionProps); 14060 } else { 14061 positionProps = {}; 14062 if (_.cssTransitions === false) { 14063 positionProps[_.animType] = 'translate(' + x + ', ' + y + ')'; 14064 _.$slideTrack.css(positionProps); 14065 } else { 14066 positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)'; 14067 _.$slideTrack.css(positionProps); 14068 } 14069 } 14070 14071 }; 14072 14073 Slick.prototype.setDimensions = function() { 14074 14075 var _ = this; 14076 14077 if (_.options.vertical === false) { 14078 if (_.options.centerMode === true) { 14079 _.$list.css({ 14080 padding: ('0px ' + _.options.centerPadding) 14081 }); 14082 } 14083 } else { 14084 _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow); 14085 if (_.options.centerMode === true) { 14086 _.$list.css({ 14087 padding: (_.options.centerPadding + ' 0px') 14088 }); 14089 } 14090 } 14091 14092 _.listWidth = _.$list.width(); 14093 _.listHeight = _.$list.height(); 14094 14095 14096 if (_.options.vertical === false && _.options.variableWidth === false) { 14097 _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow); 14098 _.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length))); 14099 14100 } else if (_.options.variableWidth === true) { 14101 _.$slideTrack.width(5000 * _.slideCount); 14102 } else { 14103 _.slideWidth = Math.ceil(_.listWidth); 14104 _.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length))); 14105 } 14106 14107 var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width(); 14108 if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset); 14109 14110 }; 14111 14112 Slick.prototype.setFade = function() { 14113 14114 var _ = this, 14115 targetLeft; 14116 14117 _.$slides.each(function(index, element) { 14118 targetLeft = (_.slideWidth * index) * -1; 14119 if (_.options.rtl === true) { 14120 $(element).css({ 14121 position: 'relative', 14122 right: targetLeft, 14123 top: 0, 14124 zIndex: _.options.zIndex - 2, 14125 opacity: 0 14126 }); 14127 } else { 14128 $(element).css({ 14129 position: 'relative', 14130 left: targetLeft, 14131 top: 0, 14132 zIndex: _.options.zIndex - 2, 14133 opacity: 0 14134 }); 14135 } 14136 }); 14137 14138 _.$slides.eq(_.currentSlide).css({ 14139 zIndex: _.options.zIndex - 1, 14140 opacity: 1 14141 }); 14142 14143 }; 14144 14145 Slick.prototype.setHeight = function() { 14146 14147 var _ = this; 14148 14149 if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) { 14150 var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true); 14151 _.$list.css('height', targetHeight); 14152 } 14153 14154 }; 14155 14156 Slick.prototype.setOption = 14157 Slick.prototype.slickSetOption = function() { 14158 14159 /** 14160 * accepts arguments in format of: 14161 * 14162 * - for changing a single option's value: 14163 * .slick("setOption", option, value, refresh ) 14164 * 14165 * - for changing a set of responsive options: 14166 * .slick("setOption", 'responsive', [{}, ...], refresh ) 14167 * 14168 * - for updating multiple values at once (not responsive) 14169 * .slick("setOption", { 'option': value, ... }, refresh ) 14170 */ 14171 14172 var _ = this, l, item, option, value, refresh = false, type; 14173 14174 if( $.type( arguments[0] ) === 'object' ) { 14175 14176 option = arguments[0]; 14177 refresh = arguments[1]; 14178 type = 'multiple'; 14179 14180 } else if ( $.type( arguments[0] ) === 'string' ) { 14181 14182 option = arguments[0]; 14183 value = arguments[1]; 14184 refresh = arguments[2]; 14185 14186 if ( arguments[0] === 'responsive' && $.type( arguments[1] ) === 'array' ) { 14187 14188 type = 'responsive'; 14189 14190 } else if ( typeof arguments[1] !== 'undefined' ) { 14191 14192 type = 'single'; 14193 14194 } 14195 14196 } 14197 14198 if ( type === 'single' ) { 14199 14200 _.options[option] = value; 14201 14202 14203 } else if ( type === 'multiple' ) { 14204 14205 $.each( option , function( opt, val ) { 14206 14207 _.options[opt] = val; 14208 14209 }); 14210 14211 14212 } else if ( type === 'responsive' ) { 14213 14214 for ( item in value ) { 14215 14216 if( $.type( _.options.responsive ) !== 'array' ) { 14217 14218 _.options.responsive = [ value[item] ]; 14219 14220 } else { 14221 14222 l = _.options.responsive.length-1; 14223 14224 // loop through the responsive object and splice out duplicates. 14225 while( l >= 0 ) { 14226 14227 if( _.options.responsive[l].breakpoint === value[item].breakpoint ) { 14228 14229 _.options.responsive.splice(l,1); 14230 14231 } 14232 14233 l--; 14234 14235 } 14236 14237 _.options.responsive.push( value[item] ); 14238 14239 } 14240 14241 } 14242 14243 } 14244 14245 if ( refresh ) { 14246 14247 _.unload(); 14248 _.reinit(); 14249 14250 } 14251 14252 }; 14253 14254 Slick.prototype.setPosition = function() { 14255 14256 var _ = this; 14257 14258 _.setDimensions(); 14259 14260 _.setHeight(); 14261 14262 if (_.options.fade === false) { 14263 _.setCSS(_.getLeft(_.currentSlide)); 14264 } else { 14265 _.setFade(); 14266 } 14267 14268 _.$slider.trigger('setPosition', [_]); 14269 14270 }; 14271 14272 Slick.prototype.setProps = function() { 14273 14274 var _ = this, 14275 bodyStyle = document.body.style; 14276 14277 _.positionProp = _.options.vertical === true ? 'top' : 'left'; 14278 14279 if (_.positionProp === 'top') { 14280 _.$slider.addClass('slick-vertical'); 14281 } else { 14282 _.$slider.removeClass('slick-vertical'); 14283 } 14284 14285 if (bodyStyle.WebkitTransition !== undefined || 14286 bodyStyle.MozTransition !== undefined || 14287 bodyStyle.msTransition !== undefined) { 14288 if (_.options.useCSS === true) { 14289 _.cssTransitions = true; 14290 } 14291 } 14292 14293 if ( _.options.fade ) { 14294 if ( typeof _.options.zIndex === 'number' ) { 14295 if( _.options.zIndex < 3 ) { 14296 _.options.zIndex = 3; 14297 } 14298 } else { 14299 _.options.zIndex = _.defaults.zIndex; 14300 } 14301 } 14302 14303 if (bodyStyle.OTransform !== undefined) { 14304 _.animType = 'OTransform'; 14305 _.transformType = '-o-transform'; 14306 _.transitionType = 'OTransition'; 14307 if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false; 14308 } 14309 if (bodyStyle.MozTransform !== undefined) { 14310 _.animType = 'MozTransform'; 14311 _.transformType = '-moz-transform'; 14312 _.transitionType = 'MozTransition'; 14313 if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false; 14314 } 14315 if (bodyStyle.webkitTransform !== undefined) { 14316 _.animType = 'webkitTransform'; 14317 _.transformType = '-webkit-transform'; 14318 _.transitionType = 'webkitTransition'; 14319 if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false; 14320 } 14321 if (bodyStyle.msTransform !== undefined) { 14322 _.animType = 'msTransform'; 14323 _.transformType = '-ms-transform'; 14324 _.transitionType = 'msTransition'; 14325 if (bodyStyle.msTransform === undefined) _.animType = false; 14326 } 14327 if (bodyStyle.transform !== undefined && _.animType !== false) { 14328 _.animType = 'transform'; 14329 _.transformType = 'transform'; 14330 _.transitionType = 'transition'; 14331 } 14332 _.transformsEnabled = _.options.useTransform && (_.animType !== null && _.animType !== false); 14333 }; 14334 14335 14336 Slick.prototype.setSlideClasses = function(index) { 14337 14338 var _ = this, 14339 centerOffset, allSlides, indexOffset, remainder; 14340 14341 allSlides = _.$slider 14342 .find('.slick-slide') 14343 .removeClass('slick-active slick-center slick-current') 14344 .attr('aria-hidden', 'true'); 14345 14346 _.$slides 14347 .eq(index) 14348 .addClass('slick-current'); 14349 14350 if (_.options.centerMode === true) { 14351 14352 var evenCoef = _.options.slidesToShow % 2 === 0 ? 1 : 0; 14353 14354 centerOffset = Math.floor(_.options.slidesToShow / 2); 14355 14356 if (_.options.infinite === true) { 14357 14358 if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) { 14359 _.$slides 14360 .slice(index - centerOffset + evenCoef, index + centerOffset + 1) 14361 .addClass('slick-active') 14362 .attr('aria-hidden', 'false'); 14363 14364 } else { 14365 14366 indexOffset = _.options.slidesToShow + index; 14367 allSlides 14368 .slice(indexOffset - centerOffset + 1 + evenCoef, indexOffset + centerOffset + 2) 14369 .addClass('slick-active') 14370 .attr('aria-hidden', 'false'); 14371 14372 } 14373 14374 if (index === 0) { 14375 14376 allSlides 14377 .eq(allSlides.length - 1 - _.options.slidesToShow) 14378 .addClass('slick-center'); 14379 14380 } else if (index === _.slideCount - 1) { 14381 14382 allSlides 14383 .eq(_.options.slidesToShow) 14384 .addClass('slick-center'); 14385 14386 } 14387 14388 } 14389 14390 _.$slides 14391 .eq(index) 14392 .addClass('slick-center'); 14393 14394 } else { 14395 14396 if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) { 14397 14398 _.$slides 14399 .slice(index, index + _.options.slidesToShow) 14400 .addClass('slick-active') 14401 .attr('aria-hidden', 'false'); 14402 14403 } else if (allSlides.length <= _.options.slidesToShow) { 14404 14405 allSlides 14406 .addClass('slick-active') 14407 .attr('aria-hidden', 'false'); 14408 14409 } else { 14410 14411 remainder = _.slideCount % _.options.slidesToShow; 14412 indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index; 14413 14414 if (_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) { 14415 14416 allSlides 14417 .slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder) 14418 .addClass('slick-active') 14419 .attr('aria-hidden', 'false'); 14420 14421 } else { 14422 14423 allSlides 14424 .slice(indexOffset, indexOffset + _.options.slidesToShow) 14425 .addClass('slick-active') 14426 .attr('aria-hidden', 'false'); 14427 14428 } 14429 14430 } 14431 14432 } 14433 14434 if (_.options.lazyLoad === 'ondemand' || _.options.lazyLoad === 'anticipated') { 14435 _.lazyLoad(); 14436 } 14437 }; 14438 14439 Slick.prototype.setupInfinite = function() { 14440 14441 var _ = this, 14442 i, slideIndex, infiniteCount; 14443 14444 if (_.options.fade === true) { 14445 _.options.centerMode = false; 14446 } 14447 14448 if (_.options.infinite === true && _.options.fade === false) { 14449 14450 slideIndex = null; 14451 14452 if (_.slideCount > _.options.slidesToShow) { 14453 14454 if (_.options.centerMode === true) { 14455 infiniteCount = _.options.slidesToShow + 1; 14456 } else { 14457 infiniteCount = _.options.slidesToShow; 14458 } 14459 14460 for (i = _.slideCount; i > (_.slideCount - 14461 infiniteCount); i -= 1) { 14462 slideIndex = i - 1; 14463 $(_.$slides[slideIndex]).clone(true).attr('id', '') 14464 .attr('data-slick-index', slideIndex - _.slideCount) 14465 .prependTo(_.$slideTrack).addClass('slick-cloned'); 14466 } 14467 for (i = 0; i < infiniteCount + _.slideCount; i += 1) { 14468 slideIndex = i; 14469 $(_.$slides[slideIndex]).clone(true).attr('id', '') 14470 .attr('data-slick-index', slideIndex + _.slideCount) 14471 .appendTo(_.$slideTrack).addClass('slick-cloned'); 14472 } 14473 _.$slideTrack.find('.slick-cloned').find('[id]').each(function() { 14474 $(this).attr('id', ''); 14475 }); 14476 14477 } 14478 14479 } 14480 14481 }; 14482 14483 Slick.prototype.interrupt = function( toggle ) { 14484 14485 var _ = this; 14486 14487 if( !toggle ) { 14488 _.autoPlay(); 14489 } 14490 _.interrupted = toggle; 14491 14492 }; 14493 14494 Slick.prototype.selectHandler = function(event) { 14495 14496 var _ = this; 14497 14498 var targetElement = 14499 $(event.target).is('.slick-slide') ? 14500 $(event.target) : 14501 $(event.target).parents('.slick-slide'); 14502 14503 var index = parseInt(targetElement.attr('data-slick-index')); 14504 14505 if (!index) index = 0; 14506 14507 if (_.slideCount <= _.options.slidesToShow) { 14508 14509 _.slideHandler(index, false, true); 14510 return; 14511 14512 } 14513 14514 _.slideHandler(index); 14515 14516 }; 14517 14518 Slick.prototype.slideHandler = function(index, sync, dontAnimate) { 14519 14520 var targetSlide, animSlide, oldSlide, slideLeft, targetLeft = null, 14521 _ = this, navTarget; 14522 14523 sync = sync || false; 14524 14525 if (_.animating === true && _.options.waitForAnimate === true) { 14526 return; 14527 } 14528 14529 if (_.options.fade === true && _.currentSlide === index) { 14530 return; 14531 } 14532 14533 if (sync === false) { 14534 _.asNavFor(index); 14535 } 14536 14537 targetSlide = index; 14538 targetLeft = _.getLeft(targetSlide); 14539 slideLeft = _.getLeft(_.currentSlide); 14540 14541 _.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft; 14542 14543 if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) { 14544 if (_.options.fade === false) { 14545 targetSlide = _.currentSlide; 14546 if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) { 14547 _.animateSlide(slideLeft, function() { 14548 _.postSlide(targetSlide); 14549 }); 14550 } else { 14551 _.postSlide(targetSlide); 14552 } 14553 } 14554 return; 14555 } else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) { 14556 if (_.options.fade === false) { 14557 targetSlide = _.currentSlide; 14558 if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) { 14559 _.animateSlide(slideLeft, function() { 14560 _.postSlide(targetSlide); 14561 }); 14562 } else { 14563 _.postSlide(targetSlide); 14564 } 14565 } 14566 return; 14567 } 14568 14569 if ( _.options.autoplay ) { 14570 clearInterval(_.autoPlayTimer); 14571 } 14572 14573 if (targetSlide < 0) { 14574 if (_.slideCount % _.options.slidesToScroll !== 0) { 14575 animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll); 14576 } else { 14577 animSlide = _.slideCount + targetSlide; 14578 } 14579 } else if (targetSlide >= _.slideCount) { 14580 if (_.slideCount % _.options.slidesToScroll !== 0) { 14581 animSlide = 0; 14582 } else { 14583 animSlide = targetSlide - _.slideCount; 14584 } 14585 } else { 14586 animSlide = targetSlide; 14587 } 14588 14589 _.animating = true; 14590 14591 _.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]); 14592 14593 oldSlide = _.currentSlide; 14594 _.currentSlide = animSlide; 14595 14596 _.setSlideClasses(_.currentSlide); 14597 14598 if ( _.options.asNavFor ) { 14599 14600 navTarget = _.getNavTarget(); 14601 navTarget = navTarget.slick('getSlick'); 14602 14603 if ( navTarget.slideCount <= navTarget.options.slidesToShow ) { 14604 navTarget.setSlideClasses(_.currentSlide); 14605 } 14606 14607 } 14608 14609 _.updateDots(); 14610 _.updateArrows(); 14611 14612 if (_.options.fade === true) { 14613 if (dontAnimate !== true) { 14614 14615 _.fadeSlideOut(oldSlide); 14616 14617 _.fadeSlide(animSlide, function() { 14618 _.postSlide(animSlide); 14619 }); 14620 14621 } else { 14622 _.postSlide(animSlide); 14623 } 14624 _.animateHeight(); 14625 return; 14626 } 14627 14628 if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) { 14629 _.animateSlide(targetLeft, function() { 14630 _.postSlide(animSlide); 14631 }); 14632 } else { 14633 _.postSlide(animSlide); 14634 } 14635 14636 }; 14637 14638 Slick.prototype.startLoad = function() { 14639 14640 var _ = this; 14641 14642 if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) { 14643 14644 _.$prevArrow.hide(); 14645 _.$nextArrow.hide(); 14646 14647 } 14648 14649 if (_.options.dots === true && _.slideCount > _.options.slidesToShow) { 14650 14651 _.$dots.hide(); 14652 14653 } 14654 14655 _.$slider.addClass('slick-loading'); 14656 14657 }; 14658 14659 Slick.prototype.swipeDirection = function() { 14660 14661 var xDist, yDist, r, swipeAngle, _ = this; 14662 14663 xDist = _.touchObject.startX - _.touchObject.curX; 14664 yDist = _.touchObject.startY - _.touchObject.curY; 14665 r = Math.atan2(yDist, xDist); 14666 14667 swipeAngle = Math.round(r * 180 / Math.PI); 14668 if (swipeAngle < 0) { 14669 swipeAngle = 360 - Math.abs(swipeAngle); 14670 } 14671 14672 if ((swipeAngle <= 45) && (swipeAngle >= 0)) { 14673 return (_.options.rtl === false ? 'left' : 'right'); 14674 } 14675 if ((swipeAngle <= 360) && (swipeAngle >= 315)) { 14676 return (_.options.rtl === false ? 'left' : 'right'); 14677 } 14678 if ((swipeAngle >= 135) && (swipeAngle <= 225)) { 14679 return (_.options.rtl === false ? 'right' : 'left'); 14680 } 14681 if (_.options.verticalSwiping === true) { 14682 if ((swipeAngle >= 35) && (swipeAngle <= 135)) { 14683 return 'down'; 14684 } else { 14685 return 'up'; 14686 } 14687 } 14688 14689 return 'vertical'; 14690 14691 }; 14692 14693 Slick.prototype.swipeEnd = function(event) { 14694 14695 var _ = this, 14696 slideCount, 14697 direction; 14698 14699 _.dragging = false; 14700 _.swiping = false; 14701 14702 if (_.scrolling) { 14703 _.scrolling = false; 14704 return false; 14705 } 14706 14707 _.interrupted = false; 14708 _.shouldClick = ( _.touchObject.swipeLength > 10 ) ? false : true; 14709 14710 if ( _.touchObject.curX === undefined ) { 14711 return false; 14712 } 14713 14714 if ( _.touchObject.edgeHit === true ) { 14715 _.$slider.trigger('edge', [_, _.swipeDirection() ]); 14716 } 14717 14718 if ( _.touchObject.swipeLength >= _.touchObject.minSwipe ) { 14719 14720 direction = _.swipeDirection(); 14721 14722 switch ( direction ) { 14723 14724 case 'left': 14725 case 'down': 14726 14727 slideCount = 14728 _.options.swipeToSlide ? 14729 _.checkNavigable( _.currentSlide + _.getSlideCount() ) : 14730 _.currentSlide + _.getSlideCount(); 14731 14732 _.currentDirection = 0; 14733 14734 break; 14735 14736 case 'right': 14737 case 'up': 14738 14739 slideCount = 14740 _.options.swipeToSlide ? 14741 _.checkNavigable( _.currentSlide - _.getSlideCount() ) : 14742 _.currentSlide - _.getSlideCount(); 14743 14744 _.currentDirection = 1; 14745 14746 break; 14747
vendor: 8,748 bytes, lines 14748-15064
14748 default: 14749 14750 14751 } 14752 14753 if( direction != 'vertical' ) { 14754 14755 _.slideHandler( slideCount ); 14756 _.touchObject = {}; 14757 _.$slider.trigger('swipe', [_, direction ]); 14758 14759 } 14760 14761 } else { 14762 14763 if ( _.touchObject.startX !== _.touchObject.curX ) { 14764 14765 _.slideHandler( _.currentSlide ); 14766 _.touchObject = {}; 14767 14768 } 14769 14770 } 14771 14772 }; 14773 14774 Slick.prototype.swipeHandler = function(event) { 14775 14776 var _ = this; 14777 14778 if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) { 14779 return; 14780 } else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) { 14781 return; 14782 } 14783 14784 _.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ? 14785 event.originalEvent.touches.length : 1; 14786 14787 _.touchObject.minSwipe = _.listWidth / _.options 14788 .touchThreshold; 14789 14790 if (_.options.verticalSwiping === true) { 14791 _.touchObject.minSwipe = _.listHeight / _.options 14792 .touchThreshold; 14793 } 14794 14795 switch (event.data.action) { 14796 14797 case 'start': 14798 _.swipeStart(event); 14799 break; 14800 14801 case 'move': 14802 _.swipeMove(event); 14803 break; 14804 14805 case 'end': 14806 _.swipeEnd(event); 14807 break; 14808 14809 } 14810 14811 }; 14812 14813 Slick.prototype.swipeMove = function(event) { 14814 14815 var _ = this, 14816 edgeWasHit = false, 14817 curLeft, swipeDirection, swipeLength, positionOffset, touches, verticalSwipeLength; 14818 14819 touches = event.originalEvent !== undefined ? event.originalEvent.touches : null; 14820 14821 if (!_.dragging || _.scrolling || touches && touches.length !== 1) { 14822 return false; 14823 } 14824 14825 curLeft = _.getLeft(_.currentSlide); 14826 14827 _.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX; 14828 _.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY; 14829 14830 _.touchObject.swipeLength = Math.round(Math.sqrt( 14831 Math.pow(_.touchObject.curX - _.touchObject.startX, 2))); 14832 14833 verticalSwipeLength = Math.round(Math.sqrt( 14834 Math.pow(_.touchObject.curY - _.touchObject.startY, 2))); 14835 14836 if (!_.options.verticalSwiping && !_.swiping && verticalSwipeLength > 4) { 14837 _.scrolling = true; 14838 return false; 14839 } 14840 14841 if (_.options.verticalSwiping === true) { 14842 _.touchObject.swipeLength = verticalSwipeLength; 14843 } 14844 14845 swipeDirection = _.swipeDirection(); 14846 14847 if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) { 14848 _.swiping = true; 14849 event.preventDefault(); 14850 } 14851 14852 positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1); 14853 if (_.options.verticalSwiping === true) { 14854 positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1; 14855 } 14856 14857 14858 swipeLength = _.touchObject.swipeLength; 14859 14860 _.touchObject.edgeHit = false; 14861 14862 if (_.options.infinite === false) { 14863 if ((_.currentSlide === 0 && swipeDirection === 'right') || (_.currentSlide >= _.getDotCount() && swipeDirection === 'left')) { 14864 swipeLength = _.touchObject.swipeLength * _.options.edgeFriction; 14865 _.touchObject.edgeHit = true; 14866 } 14867 } 14868 14869 if (_.options.vertical === false) { 14870 _.swipeLeft = curLeft + swipeLength * positionOffset; 14871 } else { 14872 _.swipeLeft = curLeft + (swipeLength * (_.$list.height() / _.listWidth)) * positionOffset; 14873 } 14874 if (_.options.verticalSwiping === true) { 14875 _.swipeLeft = curLeft + swipeLength * positionOffset; 14876 } 14877 14878 if (_.options.fade === true || _.options.touchMove === false) { 14879 return false; 14880 } 14881 14882 if (_.animating === true) { 14883 _.swipeLeft = null; 14884 return false; 14885 } 14886 14887 _.setCSS(_.swipeLeft); 14888 14889 }; 14890 14891 Slick.prototype.swipeStart = function(event) { 14892 14893 var _ = this, 14894 touches; 14895 14896 _.interrupted = true; 14897 14898 if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) { 14899 _.touchObject = {}; 14900 return false; 14901 } 14902 14903 if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) { 14904 touches = event.originalEvent.touches[0]; 14905 } 14906 14907 _.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX; 14908 _.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY; 14909 14910 _.dragging = true; 14911 14912 }; 14913 14914 Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function() { 14915 14916 var _ = this; 14917 14918 if (_.$slidesCache !== null) { 14919 14920 _.unload(); 14921 14922 _.$slideTrack.children(this.options.slide).detach(); 14923 14924 _.$slidesCache.appendTo(_.$slideTrack); 14925 14926 _.reinit(); 14927 14928 } 14929 14930 }; 14931 14932 Slick.prototype.unload = function() { 14933 14934 var _ = this; 14935 14936 $('.slick-cloned', _.$slider).remove(); 14937 14938 if (_.$dots) { 14939 _.$dots.remove(); 14940 } 14941 14942 if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) { 14943 _.$prevArrow.remove(); 14944 } 14945 14946 if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) { 14947 _.$nextArrow.remove(); 14948 } 14949 14950 _.$slides 14951 .removeClass('slick-slide slick-active slick-visible slick-current') 14952 .attr('aria-hidden', 'true') 14953 .css('width', ''); 14954 14955 }; 14956 14957 Slick.prototype.unslick = function(fromBreakpoint) { 14958 14959 var _ = this; 14960 _.$slider.trigger('unslick', [_, fromBreakpoint]); 14961 _.destroy(); 14962 14963 }; 14964 14965 Slick.prototype.updateArrows = function() { 14966 14967 var _ = this, 14968 centerOffset; 14969 14970 centerOffset = Math.floor(_.options.slidesToShow / 2); 14971 14972 if ( _.options.arrows === true && 14973 _.slideCount > _.options.slidesToShow && 14974 !_.options.infinite ) { 14975 14976 _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 14977 _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 14978 14979 if (_.currentSlide === 0) { 14980 14981 _.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true'); 14982 _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 14983 14984 } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) { 14985 14986 _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true'); 14987 _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 14988 14989 } else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) { 14990 14991 _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true'); 14992 _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 14993 14994 } 14995 14996 } 14997 14998 }; 14999 15000 Slick.prototype.updateDots = function() { 15001 15002 var _ = this; 15003 15004 if (_.$dots !== null) { 15005 15006 _.$dots 15007 .find('li') 15008 .removeClass('slick-active') 15009 .end(); 15010 15011 _.$dots 15012 .find('li') 15013 .eq(Math.floor(_.currentSlide / _.options.slidesToScroll)) 15014 .addClass('slick-active'); 15015 15016 } 15017 15018 }; 15019 15020 Slick.prototype.visibility = function() { 15021 15022 var _ = this; 15023 15024 if ( _.options.autoplay ) { 15025 15026 if ( document[_.hidden] ) { 15027 15028 _.interrupted = true; 15029 15030 } else { 15031 15032 _.interrupted = false; 15033 15034 } 15035 15036 } 15037 15038 }; 15039 15040 $.fn.slick = function() { 15041 var _ = this, 15042 opt = arguments[0], 15043 args = Array.prototype.slice.call(arguments, 1), 15044 l = _.length, 15045 i, 15046 ret; 15047 for (i = 0; i < l; i++) { 15048 if (typeof opt == 'object' || typeof opt == 'undefined') 15049 _[i].slick = new Slick(_[i], opt); 15050 else 15051 ret = _[i].slick[opt].apply(_[i].slick, args); 15052 if (typeof ret != 'undefined') return ret; 15053 } 15054 return _; 15055 }; 15056 15057})); 15058 15059 15060/***/ }), 15061/* 23 */ 15062/***/ (function(module, exports, __webpack_require__) { 15063 15064/* WEBPACK VAR INJECTION */(function(__webpack_provided_window_dot_jQuery) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! Magnific Popup - v1.1.0 - 2016-02-20
vendor: 42,148 bytes, lines 15065-16930
15065* http://dimsemenov.com/plugins/magnific-popup/ 15066* Copyright (c) 2016 Dmitry Semenov; */ 15067;(function (factory) { 15068if (true) { 15069 // AMD. Register as an anonymous module. 15070 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 15071 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 15072 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 15073 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 15074 } else if (typeof exports === 'object') { 15075 // Node/CommonJS 15076 factory(require('jquery')); 15077 } else { 15078 // Browser globals 15079 factory(window.jQuery || window.Zepto); 15080 } 15081 }(function($) { 15082 15083/*>>core*/ 15084/** 15085 * 15086 * Magnific Popup Core JS file 15087 * 15088 */ 15089 15090 15091/** 15092 * Private static constants 15093 */ 15094var CLOSE_EVENT = 'Close', 15095 BEFORE_CLOSE_EVENT = 'BeforeClose', 15096 AFTER_CLOSE_EVENT = 'AfterClose', 15097 BEFORE_APPEND_EVENT = 'BeforeAppend', 15098 MARKUP_PARSE_EVENT = 'MarkupParse', 15099 OPEN_EVENT = 'Open', 15100 CHANGE_EVENT = 'Change', 15101 NS = 'mfp', 15102 EVENT_NS = '.' + NS, 15103 READY_CLASS = 'mfp-ready', 15104 REMOVING_CLASS = 'mfp-removing', 15105 PREVENT_CLOSE_CLASS = 'mfp-prevent-close'; 15106 15107 15108/** 15109 * Private vars 15110 */ 15111/*jshint -W079 */ 15112var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this' 15113 MagnificPopup = function(){}, 15114 _isJQ = !!(__webpack_provided_window_dot_jQuery), 15115 _prevStatus, 15116 _window = $(window), 15117 _document, 15118 _prevContentType, 15119 _wrapClasses, 15120 _currPopupType; 15121 15122 15123/** 15124 * Private functions 15125 */ 15126var _mfpOn = function(name, f) { 15127 mfp.ev.on(NS + name + EVENT_NS, f); 15128 }, 15129 _getEl = function(className, appendTo, html, raw) { 15130 var el = document.createElement('div'); 15131 el.className = 'mfp-'+className; 15132 if(html) { 15133 el.innerHTML = html; 15134 } 15135 if(!raw) { 15136 el = $(el); 15137 if(appendTo) { 15138 el.appendTo(appendTo); 15139 } 15140 } else if(appendTo) { 15141 appendTo.appendChild(el); 15142 } 15143 return el; 15144 }, 15145 _mfpTrigger = function(e, data) { 15146 mfp.ev.triggerHandler(NS + e, data); 15147 15148 if(mfp.st.callbacks) { 15149 // converts "mfpEventName" to "eventName" callback and triggers it if it's present 15150 e = e.charAt(0).toLowerCase() + e.slice(1); 15151 if(mfp.st.callbacks[e]) { 15152 mfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]); 15153 } 15154 } 15155 }, 15156 _getCloseBtn = function(type) { 15157 if(type !== _currPopupType || !mfp.currTemplate.closeBtn) { 15158 mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) ); 15159 _currPopupType = type; 15160 } 15161 return mfp.currTemplate.closeBtn; 15162 }, 15163 // Initialize Magnific Popup only when called at least once 15164 _checkInstance = function() { 15165 if(!$.magnificPopup.instance) { 15166 /*jshint -W020 */ 15167 mfp = new MagnificPopup(); 15168 mfp.init(); 15169 $.magnificPopup.instance = mfp; 15170 } 15171 }, 15172 // CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr 15173 supportsTransitions = function() { 15174 var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist 15175 v = ['ms','O','Moz','Webkit']; // 'v' for vendor 15176 15177 if( s['transition'] !== undefined ) { 15178 return true; 15179 } 15180 15181 while( v.length ) { 15182 if( v.pop() + 'Transition' in s ) { 15183 return true; 15184 } 15185 } 15186 15187 return false; 15188 }; 15189 15190 15191 15192/** 15193 * Public functions 15194 */ 15195MagnificPopup.prototype = { 15196 15197 constructor: MagnificPopup, 15198 15199 /** 15200 * Initializes Magnific Popup plugin. 15201 * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed 15202 */ 15203 init: function() { 15204 var appVersion = navigator.appVersion; 15205 mfp.isLowIE = mfp.isIE8 = document.all && !document.addEventListener; 15206 mfp.isAndroid = (/android/gi).test(appVersion); 15207 mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion); 15208 mfp.supportsTransition = supportsTransitions(); 15209 15210 // We disable fixed positioned lightbox on devices that don't handle it nicely. 15211 // If you know a better way of detecting this - let me know. 15212 mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) ); 15213 _document = $(document); 15214 15215 mfp.popupsCache = {}; 15216 }, 15217 15218 /** 15219 * Opens popup 15220 * @param data [description] 15221 */ 15222 open: function(data) { 15223 15224 var i; 15225 15226 if(data.isObj === false) { 15227 // convert jQuery collection to array to avoid conflicts later 15228 mfp.items = data.items.toArray(); 15229 15230 mfp.index = 0; 15231 var items = data.items, 15232 item; 15233 for(i = 0; i < items.length; i++) { 15234 item = items[i]; 15235 if(item.parsed) { 15236 item = item.el[0]; 15237 } 15238 if(item === data.el[0]) { 15239 mfp.index = i; 15240 break; 15241 } 15242 } 15243 } else { 15244 mfp.items = $.isArray(data.items) ? data.items : [data.items]; 15245 mfp.index = data.index || 0; 15246 } 15247 15248 // if popup is already opened - we just update the content 15249 if(mfp.isOpen) { 15250 mfp.updateItemHTML(); 15251 return; 15252 } 15253 15254 mfp.types = []; 15255 _wrapClasses = ''; 15256 if(data.mainEl && data.mainEl.length) { 15257 mfp.ev = data.mainEl.eq(0); 15258 } else { 15259 mfp.ev = _document; 15260 } 15261 15262 if(data.key) { 15263 if(!mfp.popupsCache[data.key]) { 15264 mfp.popupsCache[data.key] = {}; 15265 } 15266 mfp.currTemplate = mfp.popupsCache[data.key]; 15267 } else { 15268 mfp.currTemplate = {}; 15269 } 15270 15271 15272 15273 mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data ); 15274 mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos; 15275 15276 if(mfp.st.modal) { 15277 mfp.st.closeOnContentClick = false; 15278 mfp.st.closeOnBgClick = false; 15279 mfp.st.showCloseBtn = false; 15280 mfp.st.enableEscapeKey = false; 15281 } 15282 15283 15284 // Building markup 15285 // main containers are created only once 15286 if(!mfp.bgOverlay) { 15287 15288 // Dark overlay 15289 mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() { 15290 mfp.close(); 15291 }); 15292 15293 mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) { 15294 if(mfp._checkIfClose(e.target)) { 15295 mfp.close(); 15296 } 15297 }); 15298 15299 mfp.container = _getEl('container', mfp.wrap); 15300 } 15301 15302 mfp.contentContainer = _getEl('content'); 15303 if(mfp.st.preloader) { 15304 mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading); 15305 } 15306 15307 15308 // Initializing modules 15309 var modules = $.magnificPopup.modules; 15310 for(i = 0; i < modules.length; i++) { 15311 var n = modules[i]; 15312 n = n.charAt(0).toUpperCase() + n.slice(1); 15313 mfp['init'+n].call(mfp); 15314 } 15315 _mfpTrigger('BeforeOpen'); 15316 15317 15318 if(mfp.st.showCloseBtn) { 15319 // Close button 15320 if(!mfp.st.closeBtnInside) { 15321 mfp.wrap.append( _getCloseBtn() ); 15322 } else { 15323 _mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) { 15324 values.close_replaceWith = _getCloseBtn(item.type); 15325 }); 15326 _wrapClasses += ' mfp-close-btn-in'; 15327 } 15328 } 15329 15330 if(mfp.st.alignTop) { 15331 _wrapClasses += ' mfp-align-top'; 15332 } 15333 15334 15335 15336 if(mfp.fixedContentPos) { 15337 mfp.wrap.css({ 15338 overflow: mfp.st.overflowY, 15339 overflowX: 'hidden', 15340 overflowY: mfp.st.overflowY 15341 }); 15342 } else { 15343 mfp.wrap.css({ 15344 top: _window.scrollTop(), 15345 position: 'absolute' 15346 }); 15347 } 15348 if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) { 15349 mfp.bgOverlay.css({ 15350 height: _document.height(), 15351 position: 'absolute' 15352 }); 15353 } 15354 15355 15356 15357 if(mfp.st.enableEscapeKey) { 15358 // Close on ESC key 15359 _document.on('keyup' + EVENT_NS, function(e) { 15360 if(e.keyCode === 27) { 15361 mfp.close(); 15362 } 15363 }); 15364 } 15365 15366 _window.on('resize' + EVENT_NS, function() { 15367 mfp.updateSize(); 15368 }); 15369 15370 15371 if(!mfp.st.closeOnContentClick) { 15372 _wrapClasses += ' mfp-auto-cursor'; 15373 } 15374 15375 if(_wrapClasses) 15376 mfp.wrap.addClass(_wrapClasses); 15377 15378 15379 // this triggers recalculation of layout, so we get it once to not to trigger twice 15380 var windowHeight = mfp.wH = _window.height(); 15381 15382 15383 var windowStyles = {}; 15384 15385 if( mfp.fixedContentPos ) { 15386 if(mfp._hasScrollBar(windowHeight)){ 15387 var s = mfp._getScrollbarSize(); 15388 if(s) { 15389 windowStyles.marginRight = s; 15390 } 15391 } 15392 } 15393 15394 if(mfp.fixedContentPos) { 15395 if(!mfp.isIE7) { 15396 windowStyles.overflow = 'hidden'; 15397 } else { 15398 // ie7 double-scroll bug 15399 $('body, html').css('overflow', 'hidden'); 15400 } 15401 } 15402 15403 15404 15405 var classesToadd = mfp.st.mainClass; 15406 if(mfp.isIE7) { 15407 classesToadd += ' mfp-ie7'; 15408 } 15409 if(classesToadd) { 15410 mfp._addClassToMFP( classesToadd ); 15411 } 15412 15413 // add content 15414 mfp.updateItemHTML(); 15415 15416 _mfpTrigger('BuildControls'); 15417 15418 // remove scrollbar, add margin e.t.c 15419 $('html').css(windowStyles); 15420 15421 // add everything to DOM 15422 mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) ); 15423 15424 // Save last focused element 15425 mfp._lastFocusedEl = document.activeElement; 15426 15427 // Wait for next cycle to allow CSS transition 15428 setTimeout(function() { 15429 15430 if(mfp.content) { 15431 mfp._addClassToMFP(READY_CLASS); 15432 mfp._setFocus(); 15433 } else { 15434 // if content is not defined (not loaded e.t.c) we add class only for BG 15435 mfp.bgOverlay.addClass(READY_CLASS); 15436 } 15437 15438 // Trap the focus in popup 15439 _document.on('focusin' + EVENT_NS, mfp._onFocusIn); 15440 15441 }, 16); 15442 15443 mfp.isOpen = true; 15444 mfp.updateSize(windowHeight); 15445 _mfpTrigger(OPEN_EVENT); 15446 15447 return data; 15448 }, 15449 15450 /** 15451 * Closes the popup 15452 */ 15453 close: function() { 15454 if(!mfp.isOpen) return; 15455 _mfpTrigger(BEFORE_CLOSE_EVENT); 15456 15457 mfp.isOpen = false; 15458 // for CSS3 animation 15459 if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition ) { 15460 mfp._addClassToMFP(REMOVING_CLASS); 15461 setTimeout(function() { 15462 mfp._close(); 15463 }, mfp.st.removalDelay); 15464 } else { 15465 mfp._close(); 15466 } 15467 }, 15468 15469 /** 15470 * Helper for close() function 15471 */ 15472 _close: function() { 15473 _mfpTrigger(CLOSE_EVENT); 15474 15475 var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' '; 15476 15477 mfp.bgOverlay.detach(); 15478 mfp.wrap.detach(); 15479 mfp.container.empty(); 15480 15481 if(mfp.st.mainClass) { 15482 classesToRemove += mfp.st.mainClass + ' '; 15483 } 15484 15485 mfp._removeClassFromMFP(classesToRemove); 15486 15487 if(mfp.fixedContentPos) { 15488 var windowStyles = {marginRight: ''}; 15489 if(mfp.isIE7) { 15490 $('body, html').css('overflow', ''); 15491 } else { 15492 windowStyles.overflow = ''; 15493 } 15494 $('html').css(windowStyles); 15495 } 15496 15497 _document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS); 15498 mfp.ev.off(EVENT_NS); 15499 15500 // clean up DOM elements that aren't removed 15501 mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style'); 15502 mfp.bgOverlay.attr('class', 'mfp-bg'); 15503 mfp.container.attr('class', 'mfp-container'); 15504 15505 // remove close button from target element 15506 if(mfp.st.showCloseBtn && 15507 (!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) { 15508 if(mfp.currTemplate.closeBtn) 15509 mfp.currTemplate.closeBtn.detach(); 15510 } 15511 15512 15513 if(mfp.st.autoFocusLast && mfp._lastFocusedEl) { 15514 $(mfp._lastFocusedEl).focus(); // put tab focus back 15515 } 15516 mfp.currItem = null; 15517 mfp.content = null; 15518 mfp.currTemplate = null; 15519 mfp.prevHeight = 0; 15520 15521 _mfpTrigger(AFTER_CLOSE_EVENT); 15522 }, 15523 15524 updateSize: function(winHeight) { 15525 15526 if(mfp.isIOS) { 15527 // fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2 15528 var zoomLevel = document.documentElement.clientWidth / window.innerWidth; 15529 var height = window.innerHeight * zoomLevel; 15530 mfp.wrap.css('height', height); 15531 mfp.wH = height; 15532 } else { 15533 mfp.wH = winHeight || _window.height(); 15534 } 15535 // Fixes #84: popup incorrectly positioned with position:relative on body 15536 if(!mfp.fixedContentPos) { 15537 mfp.wrap.css('height', mfp.wH); 15538 } 15539 15540 _mfpTrigger('Resize'); 15541 15542 }, 15543 15544 /** 15545 * Set content of popup based on current index 15546 */ 15547 updateItemHTML: function() { 15548 var item = mfp.items[mfp.index]; 15549 15550 // Detach and perform modifications 15551 mfp.contentContainer.detach(); 15552 15553 if(mfp.content) 15554 mfp.content.detach(); 15555 15556 if(!item.parsed) { 15557 item = mfp.parseEl( mfp.index ); 15558 } 15559 15560 var type = item.type; 15561 15562 _mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]); 15563 // BeforeChange event works like so: 15564 // _mfpOn('BeforeChange', function(e, prevType, newType) { }); 15565 15566 mfp.currItem = item; 15567 15568 if(!mfp.currTemplate[type]) { 15569 var markup = mfp.st[type] ? mfp.st[type].markup : false; 15570 15571 // allows to modify markup 15572 _mfpTrigger('FirstMarkupParse', markup); 15573 15574 if(markup) { 15575 mfp.currTemplate[type] = $(markup); 15576 } else { 15577 // if there is no markup found we just define that template is parsed 15578 mfp.currTemplate[type] = true; 15579 } 15580 } 15581 15582 if(_prevContentType && _prevContentType !== item.type) { 15583 mfp.container.removeClass('mfp-'+_prevContentType+'-holder'); 15584 } 15585 15586 var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]); 15587 mfp.appendContent(newContent, type); 15588 15589 item.preloaded = true; 15590 15591 _mfpTrigger(CHANGE_EVENT, item); 15592 _prevContentType = item.type; 15593 15594 // Append container back after its content changed 15595 mfp.container.prepend(mfp.contentContainer); 15596 15597 _mfpTrigger('AfterChange'); 15598 }, 15599 15600 15601 /** 15602 * Set HTML content of popup 15603 */ 15604 appendContent: function(newContent, type) { 15605 mfp.content = newContent; 15606 15607 if(newContent) { 15608 if(mfp.st.showCloseBtn && mfp.st.closeBtnInside && 15609 mfp.currTemplate[type] === true) { 15610 // if there is no markup, we just append close button element inside 15611 if(!mfp.content.find('.mfp-close').length) { 15612 mfp.content.append(_getCloseBtn()); 15613 } 15614 } else { 15615 mfp.content = newContent; 15616 } 15617 } else { 15618 mfp.content = ''; 15619 } 15620 15621 _mfpTrigger(BEFORE_APPEND_EVENT); 15622 mfp.container.addClass('mfp-'+type+'-holder'); 15623 15624 mfp.contentContainer.append(mfp.content); 15625 }, 15626 15627 15628 /** 15629 * Creates Magnific Popup data object based on given data 15630 * @param {int} index Index of item to parse 15631 */ 15632 parseEl: function(index) { 15633 var item = mfp.items[index], 15634 type; 15635 15636 if(item.tagName) { 15637 item = { el: $(item) }; 15638 } else { 15639 type = item.type; 15640 item = { data: item, src: item.src }; 15641 } 15642 15643 if(item.el) { 15644 var types = mfp.types; 15645 15646 // check for 'mfp-TYPE' class 15647 for(var i = 0; i < types.length; i++) { 15648 if( item.el.hasClass('mfp-'+types[i]) ) { 15649 type = types[i]; 15650 break; 15651 } 15652 } 15653 15654 item.src = item.el.attr('data-mfp-src'); 15655 if(!item.src) { 15656 item.src = item.el.attr('href'); 15657 } 15658 } 15659 15660 item.type = type || mfp.st.type || 'inline'; 15661 item.index = index; 15662 item.parsed = true; 15663 mfp.items[index] = item; 15664 _mfpTrigger('ElementParse', item); 15665 15666 return mfp.items[index]; 15667 }, 15668 15669 15670 /** 15671 * Initializes single popup or a group of popups 15672 */ 15673 addGroup: function(el, options) { 15674 var eHandler = function(e) { 15675 e.mfpEl = this; 15676 mfp._openClick(e, el, options); 15677 }; 15678 15679 if(!options) { 15680 options = {}; 15681 } 15682 15683 var eName = 'click.magnificPopup'; 15684 options.mainEl = el; 15685 15686 if(options.items) { 15687 options.isObj = true; 15688 el.off(eName).on(eName, eHandler); 15689 } else { 15690 options.isObj = false; 15691 if(options.delegate) { 15692 el.off(eName).on(eName, options.delegate , eHandler); 15693 } else { 15694 options.items = el; 15695 el.off(eName).on(eName, eHandler); 15696 } 15697 } 15698 }, 15699 _openClick: function(e, el, options) { 15700 var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick; 15701 15702 15703 if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey ) ) { 15704 return; 15705 } 15706 15707 var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn; 15708 15709 if(disableOn) { 15710 if($.isFunction(disableOn)) { 15711 if( !disableOn.call(mfp) ) { 15712 return true; 15713 } 15714 } else { // else it's number 15715 if( _window.width() < disableOn ) { 15716 return true; 15717 } 15718 } 15719 } 15720 15721 if(e.type) { 15722 e.preventDefault(); 15723 15724 // This will prevent popup from closing if element is inside and popup is already opened 15725 if(mfp.isOpen) { 15726 e.stopPropagation(); 15727 } 15728 } 15729 15730 options.el = $(e.mfpEl); 15731 if(options.delegate) { 15732 options.items = el.find(options.delegate); 15733 } 15734 mfp.open(options); 15735 }, 15736 15737 15738 /** 15739 * Updates text on preloader 15740 */ 15741 updateStatus: function(status, text) { 15742 15743 if(mfp.preloader) { 15744 if(_prevStatus !== status) { 15745 mfp.container.removeClass('mfp-s-'+_prevStatus); 15746 } 15747 15748 if(!text && status === 'loading') { 15749 text = mfp.st.tLoading; 15750 } 15751 15752 var data = { 15753 status: status, 15754 text: text 15755 }; 15756 // allows to modify status 15757 _mfpTrigger('UpdateStatus', data); 15758 15759 status = data.status; 15760 text = data.text; 15761 15762 mfp.preloader.html(text); 15763 15764 mfp.preloader.find('a').on('click', function(e) { 15765 e.stopImmediatePropagation(); 15766 }); 15767 15768 mfp.container.addClass('mfp-s-'+status); 15769 _prevStatus = status; 15770 } 15771 }, 15772 15773 15774 /* 15775 "Private" helpers that aren't private at all 15776 */ 15777 // Check to close popup or not 15778 // "target" is an element that was clicked 15779 _checkIfClose: function(target) { 15780 15781 if($(target).hasClass(PREVENT_CLOSE_CLASS)) { 15782 return; 15783 } 15784 15785 var closeOnContent = mfp.st.closeOnContentClick; 15786 var closeOnBg = mfp.st.closeOnBgClick; 15787 15788 if(closeOnContent && closeOnBg) { 15789 return true; 15790 } else { 15791 15792 // We close the popup if click is on close button or on preloader. Or if there is no content. 15793 if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) { 15794 return true; 15795 } 15796 15797 // if click is outside the content 15798 if( (target !== mfp.content[0] && !$.contains(mfp.content[0], target)) ) { 15799 if(closeOnBg) { 15800 // last check, if the clicked element is in DOM, (in case it's removed onclick) 15801 if( $.contains(document, target) ) { 15802 return true; 15803 } 15804 } 15805 } else if(closeOnContent) { 15806 return true; 15807 } 15808 15809 } 15810 return false; 15811 }, 15812 _addClassToMFP: function(cName) { 15813 mfp.bgOverlay.addClass(cName); 15814 mfp.wrap.addClass(cName); 15815 }, 15816 _removeClassFromMFP: function(cName) { 15817 this.bgOverlay.removeClass(cName); 15818 mfp.wrap.removeClass(cName); 15819 }, 15820 _hasScrollBar: function(winHeight) { 15821 return ( (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) ); 15822 }, 15823 _setFocus: function() { 15824 (mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus(); 15825 }, 15826 _onFocusIn: function(e) { 15827 if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) { 15828 mfp._setFocus(); 15829 return false; 15830 } 15831 }, 15832 _parseMarkup: function(template, values, item) { 15833 var arr; 15834 if(item.data) { 15835 values = $.extend(item.data, values); 15836 } 15837 _mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] ); 15838 15839 $.each(values, function(key, value) { 15840 if(value === undefined || value === false) { 15841 return true; 15842 } 15843 arr = key.split('_'); 15844 if(arr.length > 1) { 15845 var el = template.find(EVENT_NS + '-'+arr[0]); 15846 15847 if(el.length > 0) { 15848 var attr = arr[1]; 15849 if(attr === 'replaceWith') { 15850 if(el[0] !== value[0]) { 15851 el.replaceWith(value); 15852 } 15853 } else if(attr === 'img') { 15854 if(el.is('img')) { 15855 el.attr('src', value); 15856 } else { 15857 el.replaceWith( $('<img>').attr('src', value).attr('class', el.attr('class')) ); 15858 } 15859 } else { 15860 el.attr(arr[1], value); 15861 } 15862 } 15863 15864 } else { 15865 template.find(EVENT_NS + '-'+key).html(value); 15866 } 15867 }); 15868 }, 15869 15870 _getScrollbarSize: function() { 15871 // thx David 15872 if(mfp.scrollbarSize === undefined) { 15873 var scrollDiv = document.createElement("div"); 15874 scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;'; 15875 document.body.appendChild(scrollDiv); 15876 mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth; 15877 document.body.removeChild(scrollDiv); 15878 } 15879 return mfp.scrollbarSize; 15880 } 15881 15882}; /* MagnificPopup core prototype end */ 15883 15884 15885 15886 15887/** 15888 * Public static functions 15889 */ 15890$.magnificPopup = { 15891 instance: null, 15892 proto: MagnificPopup.prototype, 15893 modules: [], 15894 15895 open: function(options, index) { 15896 _checkInstance(); 15897 15898 if(!options) { 15899 options = {}; 15900 } else { 15901 options = $.extend(true, {}, options); 15902 } 15903 15904 options.isObj = true; 15905 options.index = index || 0; 15906 return this.instance.open(options); 15907 }, 15908 15909 close: function() { 15910 return $.magnificPopup.instance && $.magnificPopup.instance.close(); 15911 }, 15912 15913 registerModule: function(name, module) { 15914 if(module.options) { 15915 $.magnificPopup.defaults[name] = module.options; 15916 } 15917 $.extend(this.proto, module.proto); 15918 this.modules.push(name); 15919 }, 15920 15921 defaults: { 15922 15923 // Info about options is in docs: 15924 // http://dimsemenov.com/plugins/magnific-popup/documentation.html#options 15925 15926 disableOn: 0, 15927 15928 key: null, 15929 15930 midClick: false, 15931 15932 mainClass: '', 15933 15934 preloader: true, 15935 15936 focus: '', // CSS selector of input to focus after popup is opened 15937 15938 closeOnContentClick: false, 15939 15940 closeOnBgClick: true, 15941 15942 closeBtnInside: true, 15943 15944 showCloseBtn: true, 15945 15946 enableEscapeKey: true, 15947 15948 modal: false, 15949 15950 alignTop: false, 15951 15952 removalDelay: 0, 15953 15954 prependTo: null, 15955 15956 fixedContentPos: 'auto', 15957 15958 fixedBgPos: 'auto', 15959 15960 overflowY: 'auto', 15961 15962 closeMarkup: '<button title="%title%" type="button" class="mfp-close">×</button>', 15963 15964 tClose: 'Close (Esc)', 15965 15966 tLoading: 'Loading...', 15967 15968 autoFocusLast: true 15969 15970 } 15971}; 15972 15973 15974 15975$.fn.magnificPopup = function(options) { 15976 _checkInstance(); 15977 15978 var jqEl = $(this); 15979 15980 // We call some API method of first param is a string 15981 if (typeof options === "string" ) { 15982 15983 if(options === 'open') { 15984 var items, 15985 itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup, 15986 index = parseInt(arguments[1], 10) || 0; 15987 15988 if(itemOpts.items) { 15989 items = itemOpts.items[index]; 15990 } else { 15991 items = jqEl; 15992 if(itemOpts.delegate) { 15993 items = items.find(itemOpts.delegate); 15994 } 15995 items = items.eq( index ); 15996 } 15997 mfp._openClick({mfpEl:items}, jqEl, itemOpts); 15998 } else { 15999 if(mfp.isOpen) 16000 mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1)); 16001 } 16002 16003 } else { 16004 // clone options obj 16005 options = $.extend(true, {}, options); 16006 16007 /* 16008 * As Zepto doesn't support .data() method for objects 16009 * and it works only in normal browsers 16010 * we assign "options" object directly to the DOM element. FTW! 16011 */ 16012 if(_isJQ) { 16013 jqEl.data('magnificPopup', options); 16014 } else { 16015 jqEl[0].magnificPopup = options; 16016 } 16017 16018 mfp.addGroup(jqEl, options); 16019 16020 } 16021 return jqEl; 16022}; 16023 16024/*>>core*/ 16025 16026/*>>inline*/ 16027 16028var INLINE_NS = 'inline', 16029 _hiddenClass, 16030 _inlinePlaceholder, 16031 _lastInlineElement, 16032 _putInlineElementsBack = function() { 16033 if(_lastInlineElement) { 16034 _inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach(); 16035 _lastInlineElement = null; 16036 } 16037 }; 16038 16039$.magnificPopup.registerModule(INLINE_NS, { 16040 options: { 16041 hiddenClass: 'hide', // will be appended with `mfp-` prefix 16042 markup: '', 16043 tNotFound: 'Content not found' 16044 }, 16045 proto: { 16046 16047 initInline: function() { 16048 mfp.types.push(INLINE_NS); 16049 16050 _mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() { 16051 _putInlineElementsBack(); 16052 }); 16053 }, 16054 16055 getInline: function(item, template) { 16056 16057 _putInlineElementsBack(); 16058 16059 if(item.src) { 16060 var inlineSt = mfp.st.inline, 16061 el = $(item.src); 16062 16063 if(el.length) { 16064 16065 // If target element has parent - we replace it with placeholder and put it back after popup is closed 16066 var parent = el[0].parentNode; 16067 if(parent && parent.tagName) { 16068 if(!_inlinePlaceholder) { 16069 _hiddenClass = inlineSt.hiddenClass; 16070 _inlinePlaceholder = _getEl(_hiddenClass); 16071 _hiddenClass = 'mfp-'+_hiddenClass; 16072 } 16073 // replace target inline element with placeholder 16074 _lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass); 16075 } 16076 16077 mfp.updateStatus('ready'); 16078 } else { 16079 mfp.updateStatus('error', inlineSt.tNotFound); 16080 el = $('<div>'); 16081 } 16082 16083 item.inlineElement = el; 16084 return el; 16085 } 16086 16087 mfp.updateStatus('ready'); 16088 mfp._parseMarkup(template, {}, item); 16089 return template; 16090 } 16091 } 16092}); 16093 16094/*>>inline*/ 16095 16096/*>>ajax*/ 16097var AJAX_NS = 'ajax', 16098 _ajaxCur, 16099 _removeAjaxCursor = function() { 16100 if(_ajaxCur) { 16101 $(document.body).removeClass(_ajaxCur); 16102 } 16103 }, 16104 _destroyAjaxRequest = function() { 16105 _removeAjaxCursor(); 16106 if(mfp.req) { 16107 mfp.req.abort(); 16108 } 16109 }; 16110 16111$.magnificPopup.registerModule(AJAX_NS, { 16112 16113 options: { 16114 settings: null, 16115 cursor: 'mfp-ajax-cur', 16116 tError: '<a href="%url%">The content</a> could not be loaded.' 16117 }, 16118 16119 proto: { 16120 initAjax: function() { 16121 mfp.types.push(AJAX_NS); 16122 _ajaxCur = mfp.st.ajax.cursor; 16123 16124 _mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest); 16125 _mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest); 16126 }, 16127 getAjax: function(item) { 16128 16129 if(_ajaxCur) { 16130 $(document.body).addClass(_ajaxCur); 16131 } 16132 16133 mfp.updateStatus('loading'); 16134 16135 var opts = $.extend({ 16136 url: item.src, 16137 success: function(data, textStatus, jqXHR) { 16138 var temp = { 16139 data:data, 16140 xhr:jqXHR 16141 }; 16142 16143 _mfpTrigger('ParseAjax', temp); 16144 16145 mfp.appendContent( $(temp.data), AJAX_NS ); 16146 16147 item.finished = true; 16148 16149 _removeAjaxCursor(); 16150 16151 mfp._setFocus(); 16152 16153 setTimeout(function() { 16154 mfp.wrap.addClass(READY_CLASS); 16155 }, 16); 16156 16157 mfp.updateStatus('ready'); 16158 16159 _mfpTrigger('AjaxContentAdded'); 16160 }, 16161 error: function() { 16162 _removeAjaxCursor(); 16163 item.finished = item.loadError = true; 16164 mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src)); 16165 } 16166 }, mfp.st.ajax.settings); 16167 16168 mfp.req = $.ajax(opts); 16169 16170 return ''; 16171 } 16172 } 16173}); 16174 16175/*>>ajax*/ 16176 16177/*>>image*/ 16178var _imgInterval, 16179 _getTitle = function(item) { 16180 if(item.data && item.data.title !== undefined) 16181 return item.data.title; 16182 16183 var src = mfp.st.image.titleSrc; 16184 16185 if(src) { 16186 if($.isFunction(src)) { 16187 return src.call(mfp, item); 16188 } else if(item.el) { 16189 return item.el.attr(src) || ''; 16190 } 16191 } 16192 return ''; 16193 }; 16194 16195$.magnificPopup.registerModule('image', { 16196 16197 options: { 16198 markup: '<div class="mfp-figure">'+ 16199 '<div class="mfp-close"></div>'+ 16200 '<figure>'+ 16201 '<div class="mfp-img"></div>'+ 16202 '<figcaption>'+ 16203 '<div class="mfp-bottom-bar">'+ 16204 '<div class="mfp-title"></div>'+ 16205 '<div class="mfp-counter"></div>'+ 16206 '</div>'+ 16207 '</figcaption>'+ 16208 '</figure>'+ 16209 '</div>', 16210 cursor: 'mfp-zoom-out-cur', 16211 titleSrc: 'title', 16212 verticalFit: true, 16213 tError: '<a href="%url%">The image</a> could not be loaded.' 16214 }, 16215 16216 proto: { 16217 initImage: function() { 16218 var imgSt = mfp.st.image, 16219 ns = '.image'; 16220 16221 mfp.types.push('image'); 16222 16223 _mfpOn(OPEN_EVENT+ns, function() { 16224 if(mfp.currItem.type === 'image' && imgSt.cursor) { 16225 $(document.body).addClass(imgSt.cursor); 16226 } 16227 }); 16228 16229 _mfpOn(CLOSE_EVENT+ns, function() { 16230 if(imgSt.cursor) { 16231 $(document.body).removeClass(imgSt.cursor); 16232 } 16233 _window.off('resize' + EVENT_NS); 16234 }); 16235 16236 _mfpOn('Resize'+ns, mfp.resizeImage); 16237 if(mfp.isLowIE) { 16238 _mfpOn('AfterChange', mfp.resizeImage); 16239 } 16240 }, 16241 resizeImage: function() { 16242 var item = mfp.currItem; 16243 if(!item || !item.img) return; 16244 16245 if(mfp.st.image.verticalFit) { 16246 var decr = 0; 16247 // fix box-sizing in ie7/8 16248 if(mfp.isLowIE) { 16249 decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10); 16250 } 16251 item.img.css('max-height', mfp.wH-decr); 16252 } 16253 }, 16254 _onImageHasSize: function(item) { 16255 if(item.img) { 16256 16257 item.hasSize = true; 16258 16259 if(_imgInterval) { 16260 clearInterval(_imgInterval); 16261 } 16262 16263 item.isCheckingImgSize = false; 16264 16265 _mfpTrigger('ImageHasSize', item); 16266 16267 if(item.imgHidden) { 16268 if(mfp.content) 16269 mfp.content.removeClass('mfp-loading'); 16270 16271 item.imgHidden = false; 16272 } 16273 16274 } 16275 }, 16276 16277 /** 16278 * Function that loops until the image has size to display elements that rely on it asap 16279 */ 16280 findImageSize: function(item) { 16281 16282 var counter = 0, 16283 img = item.img[0], 16284 mfpSetInterval = function(delay) { 16285 16286 if(_imgInterval) { 16287 clearInterval(_imgInterval); 16288 } 16289 // decelerating interval that checks for size of an image 16290 _imgInterval = setInterval(function() { 16291 if(img.naturalWidth > 0) { 16292 mfp._onImageHasSize(item); 16293 return; 16294 } 16295 16296 if(counter > 200) { 16297 clearInterval(_imgInterval); 16298 } 16299 16300 counter++; 16301 if(counter === 3) { 16302 mfpSetInterval(10); 16303 } else if(counter === 40) { 16304 mfpSetInterval(50); 16305 } else if(counter === 100) { 16306 mfpSetInterval(500); 16307 } 16308 }, delay); 16309 }; 16310 16311 mfpSetInterval(1); 16312 }, 16313 16314 getImage: function(item, template) { 16315 16316 var guard = 0, 16317 16318 // image load complete handler 16319 onLoadComplete = function() { 16320 if(item) { 16321 if (item.img[0].complete) { 16322 item.img.off('.mfploader'); 16323 16324 if(item === mfp.currItem){ 16325 mfp._onImageHasSize(item); 16326 16327 mfp.updateStatus('ready'); 16328 } 16329 16330 item.hasSize = true; 16331 item.loaded = true; 16332 16333 _mfpTrigger('ImageLoadComplete'); 16334 16335 } 16336 else { 16337 // if image complete check fails 200 times (20 sec), we assume that there was an error. 16338 guard++; 16339 if(guard < 200) { 16340 setTimeout(onLoadComplete,100); 16341 } else { 16342 onLoadError(); 16343 } 16344 } 16345 } 16346 }, 16347 16348 // image error handler 16349 onLoadError = function() { 16350 if(item) { 16351 item.img.off('.mfploader'); 16352 if(item === mfp.currItem){ 16353 mfp._onImageHasSize(item); 16354 mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) ); 16355 } 16356 16357 item.hasSize = true; 16358 item.loaded = true; 16359 item.loadError = true; 16360 } 16361 }, 16362 imgSt = mfp.st.image; 16363 16364 16365 var el = template.find('.mfp-img'); 16366 if(el.length) { 16367 var img = document.createElement('img'); 16368 img.className = 'mfp-img'; 16369 if(item.el && item.el.find('img').length) { 16370 img.alt = item.el.find('img').attr('alt'); 16371 } 16372 item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError); 16373 img.src = item.src; 16374 16375 // without clone() "error" event is not firing when IMG is replaced by new IMG 16376 // TODO: find a way to avoid such cloning 16377 if(el.is('img')) { 16378 item.img = item.img.clone(); 16379 } 16380 16381 img = item.img[0]; 16382 if(img.naturalWidth > 0) { 16383 item.hasSize = true; 16384 } else if(!img.width) { 16385 item.hasSize = false; 16386 } 16387 } 16388 16389 mfp._parseMarkup(template, { 16390 title: _getTitle(item), 16391 img_replaceWith: item.img 16392 }, item); 16393 16394 mfp.resizeImage(); 16395 16396 if(item.hasSize) { 16397 if(_imgInterval) clearInterval(_imgInterval); 16398 16399 if(item.loadError) { 16400 template.addClass('mfp-loading'); 16401 mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) ); 16402 } else { 16403 template.removeClass('mfp-loading'); 16404 mfp.updateStatus('ready'); 16405 } 16406 return template; 16407 } 16408 16409 mfp.updateStatus('loading'); 16410 item.loading = true; 16411 16412 if(!item.hasSize) { 16413 item.imgHidden = true; 16414 template.addClass('mfp-loading'); 16415 mfp.findImageSize(item); 16416 } 16417 16418 return template; 16419 } 16420 } 16421}); 16422 16423/*>>image*/ 16424 16425/*>>zoom*/ 16426var hasMozTransform, 16427 getHasMozTransform = function() { 16428 if(hasMozTransform === undefined) { 16429 hasMozTransform = document.createElement('p').style.MozTransform !== undefined; 16430 } 16431 return hasMozTransform; 16432 }; 16433 16434$.magnificPopup.registerModule('zoom', { 16435 16436 options: { 16437 enabled: false, 16438 easing: 'ease-in-out', 16439 duration: 300, 16440 opener: function(element) { 16441 return element.is('img') ? element : element.find('img'); 16442 } 16443 }, 16444 16445 proto: { 16446 16447 initZoom: function() { 16448 var zoomSt = mfp.st.zoom, 16449 ns = '.zoom', 16450 image; 16451 16452 if(!zoomSt.enabled || !mfp.supportsTransition) { 16453 return; 16454 } 16455 16456 var duration = zoomSt.duration, 16457 getElToAnimate = function(image) { 16458 var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'), 16459 transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing, 16460 cssObj = { 16461 position: 'fixed', 16462 zIndex: 9999, 16463 left: 0, 16464 top: 0, 16465 '-webkit-backface-visibility': 'hidden' 16466 }, 16467 t = 'transition'; 16468 16469 cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition; 16470 16471 newImg.css(cssObj); 16472 return newImg; 16473 }, 16474 showMainContent = function() { 16475 mfp.content.css('visibility', 'visible'); 16476 }, 16477 openTimeout, 16478 animatedImg; 16479 16480 _mfpOn('BuildControls'+ns, function() { 16481 if(mfp._allowZoom()) { 16482 16483 clearTimeout(openTimeout); 16484 mfp.content.css('visibility', 'hidden'); 16485 16486 // Basically, all code below does is clones existing image, puts in on top of the current one and animated it 16487 16488 image = mfp._getItemToZoom(); 16489 16490 if(!image) { 16491 showMainContent(); 16492 return; 16493 } 16494 16495 animatedImg = getElToAnimate(image); 16496 16497 animatedImg.css( mfp._getOffset() ); 16498 16499 mfp.wrap.append(animatedImg); 16500 16501 openTimeout = setTimeout(function() { 16502 animatedImg.css( mfp._getOffset( true ) ); 16503 openTimeout = setTimeout(function() { 16504 16505 showMainContent(); 16506 16507 setTimeout(function() { 16508 animatedImg.remove(); 16509 image = animatedImg = null; 16510 _mfpTrigger('ZoomAnimationEnded'); 16511 }, 16); // avoid blink when switching images 16512 16513 }, duration); // this timeout equals animation duration 16514 16515 }, 16); // by adding this timeout we avoid short glitch at the beginning of animation 16516 16517 16518 // Lots of timeouts... 16519 } 16520 }); 16521 _mfpOn(BEFORE_CLOSE_EVENT+ns, function() { 16522 if(mfp._allowZoom()) { 16523 16524 clearTimeout(openTimeout); 16525 16526 mfp.st.removalDelay = duration; 16527 16528 if(!image) { 16529 image = mfp._getItemToZoom(); 16530 if(!image) { 16531 return; 16532 } 16533 animatedImg = getElToAnimate(image); 16534 } 16535 16536 animatedImg.css( mfp._getOffset(true) ); 16537 mfp.wrap.append(animatedImg); 16538 mfp.content.css('visibility', 'hidden'); 16539 16540 setTimeout(function() { 16541 animatedImg.css( mfp._getOffset() ); 16542 }, 16); 16543 } 16544 16545 }); 16546 16547 _mfpOn(CLOSE_EVENT+ns, function() { 16548 if(mfp._allowZoom()) { 16549 showMainContent(); 16550 if(animatedImg) { 16551 animatedImg.remove(); 16552 } 16553 image = null; 16554 } 16555 }); 16556 }, 16557 16558 _allowZoom: function() { 16559 return mfp.currItem.type === 'image'; 16560 }, 16561 16562 _getItemToZoom: function() { 16563 if(mfp.currItem.hasSize) { 16564 return mfp.currItem.img; 16565 } else { 16566 return false; 16567 } 16568 }, 16569 16570 // Get element postion relative to viewport 16571 _getOffset: function(isLarge) { 16572 var el; 16573 if(isLarge) { 16574 el = mfp.currItem.img; 16575 } else { 16576 el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem); 16577 } 16578 16579 var offset = el.offset(); 16580 var paddingTop = parseInt(el.css('padding-top'),10); 16581 var paddingBottom = parseInt(el.css('padding-bottom'),10); 16582 offset.top -= ( $(window).scrollTop() - paddingTop ); 16583 16584 16585 /* 16586 16587 Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa. 16588 16589 */ 16590 var obj = { 16591 width: el.width(), 16592 // fix Zepto height+padding issue 16593 height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop 16594 }; 16595 16596 // I hate to do this, but there is no another option 16597 if( getHasMozTransform() ) { 16598 obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)'; 16599 } else { 16600 obj.left = offset.left; 16601 obj.top = offset.top; 16602 } 16603 return obj; 16604 } 16605 16606 } 16607}); 16608 16609 16610 16611/*>>zoom*/ 16612 16613/*>>iframe*/ 16614 16615var IFRAME_NS = 'iframe', 16616 _emptyPage = '//about:blank', 16617 16618 _fixIframeBugs = function(isShowing) { 16619 if(mfp.currTemplate[IFRAME_NS]) { 16620 var el = mfp.currTemplate[IFRAME_NS].find('iframe'); 16621 if(el.length) { 16622 // reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug 16623 if(!isShowing) { 16624 el[0].src = _emptyPage; 16625 } 16626 16627 // IE8 black screen bug fix 16628 if(mfp.isIE8) { 16629 el.css('display', isShowing ? 'block' : 'none'); 16630 } 16631 } 16632 } 16633 }; 16634 16635$.magnificPopup.registerModule(IFRAME_NS, { 16636 16637 options: { 16638 markup: '<div class="mfp-iframe-scaler">'+ 16639 '<div class="mfp-close"></div>'+ 16640 '<iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe>'+ 16641 '</div>', 16642 16643 srcAction: 'iframe_src', 16644 16645 // we don't care and support only one default type of URL by default 16646 patterns: { 16647 youtube: { 16648 index: 'youtube.com', 16649 id: 'v=', 16650 src: '//www.youtube.com/embed/%id%?autoplay=1' 16651 }, 16652 vimeo: { 16653 index: 'vimeo.com/', 16654 id: '/', 16655 src: '//player.vimeo.com/video/%id%?autoplay=1' 16656 }, 16657 gmaps: { 16658 index: '//maps.google.', 16659 src: '%id%&output=embed' 16660 } 16661 } 16662 }, 16663 16664 proto: { 16665 initIframe: function() { 16666 mfp.types.push(IFRAME_NS); 16667 16668 _mfpOn('BeforeChange', function(e, prevType, newType) { 16669 if(prevType !== newType) { 16670 if(prevType === IFRAME_NS) { 16671 _fixIframeBugs(); // iframe if removed 16672 } else if(newType === IFRAME_NS) { 16673 _fixIframeBugs(true); // iframe is showing 16674 } 16675 }// else { 16676 // iframe source is switched, don't do anything 16677 //} 16678 }); 16679 16680 _mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() { 16681 _fixIframeBugs(); 16682 }); 16683 }, 16684 16685 getIframe: function(item, template) { 16686 var embedSrc = item.src; 16687 var iframeSt = mfp.st.iframe; 16688 16689 $.each(iframeSt.patterns, function() { 16690 if(embedSrc.indexOf( this.index ) > -1) { 16691 if(this.id) { 16692 if(typeof this.id === 'string') { 16693 embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length); 16694 } else { 16695 embedSrc = this.id.call( this, embedSrc ); 16696 } 16697 } 16698 embedSrc = this.src.replace('%id%', embedSrc ); 16699 return false; // break; 16700 } 16701 }); 16702 16703 var dataObj = {}; 16704 if(iframeSt.srcAction) { 16705 dataObj[iframeSt.srcAction] = embedSrc; 16706 } 16707 mfp._parseMarkup(template, dataObj, item); 16708 16709 mfp.updateStatus('ready'); 16710 16711 return template; 16712 } 16713 } 16714}); 16715 16716 16717 16718/*>>iframe*/ 16719 16720/*>>gallery*/ 16721/** 16722 * Get looped index depending on number of slides 16723 */ 16724var _getLoopedId = function(index) { 16725 var numSlides = mfp.items.length; 16726 if(index > numSlides - 1) { 16727 return index - numSlides; 16728 } else if(index < 0) { 16729 return numSlides + index; 16730 } 16731 return index; 16732 }, 16733 _replaceCurrTotal = function(text, curr, total) { 16734 return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total); 16735 }; 16736 16737$.magnificPopup.registerModule('gallery', { 16738 16739 options: { 16740 enabled: false, 16741 arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>', 16742 preload: [0,2], 16743 navigateByImgClick: true, 16744 arrows: true, 16745 16746 tPrev: 'Previous (Left arrow key)', 16747 tNext: 'Next (Right arrow key)', 16748 tCounter: '%curr% of %total%' 16749 }, 16750 16751 proto: { 16752 initGallery: function() { 16753 16754 var gSt = mfp.st.gallery, 16755 ns = '.mfp-gallery'; 16756 16757 mfp.direction = true; // true - next, false - prev 16758 16759 if(!gSt || !gSt.enabled ) return false; 16760 16761 _wrapClasses += ' mfp-gallery'; 16762 16763 _mfpOn(OPEN_EVENT+ns, function() { 16764 16765 if(gSt.navigateByImgClick) { 16766 mfp.wrap.on('click'+ns, '.mfp-img', function() { 16767 if(mfp.items.length > 1) { 16768 mfp.next(); 16769 return false; 16770 } 16771 }); 16772 } 16773 16774 _document.on('keydown'+ns, function(e) { 16775 if (e.keyCode === 37) { 16776 mfp.prev(); 16777 } else if (e.keyCode === 39) { 16778 mfp.next(); 16779 } 16780 }); 16781 }); 16782 16783 _mfpOn('UpdateStatus'+ns, function(e, data) { 16784 if(data.text) { 16785 data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length); 16786 } 16787 }); 16788 16789 _mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) { 16790 var l = mfp.items.length; 16791 values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : ''; 16792 }); 16793 16794 _mfpOn('BuildControls' + ns, function() { 16795 if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) { 16796 var markup = gSt.arrowMarkup, 16797 arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS), 16798 arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS); 16799 16800 arrowLeft.click(function() { 16801 mfp.prev(); 16802 }); 16803 arrowRight.click(function() { 16804 mfp.next(); 16805 }); 16806 16807 mfp.container.append(arrowLeft.add(arrowRight)); 16808 } 16809 }); 16810 16811 _mfpOn(CHANGE_EVENT+ns, function() { 16812 if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout); 16813 16814 mfp._preloadTimeout = setTimeout(function() { 16815 mfp.preloadNearbyImages(); 16816 mfp._preloadTimeout = null; 16817 }, 16); 16818 }); 16819 16820 16821 _mfpOn(CLOSE_EVENT+ns, function() { 16822 _document.off(ns); 16823 mfp.wrap.off('click'+ns); 16824 mfp.arrowRight = mfp.arrowLeft = null; 16825 }); 16826 16827 }, 16828 next: function() { 16829 mfp.direction = true; 16830 mfp.index = _getLoopedId(mfp.index + 1); 16831 mfp.updateItemHTML(); 16832 }, 16833 prev: function() { 16834 mfp.direction = false; 16835 mfp.index = _getLoopedId(mfp.index - 1); 16836 mfp.updateItemHTML(); 16837 }, 16838 goTo: function(newIndex) { 16839 mfp.direction = (newIndex >= mfp.index); 16840 mfp.index = newIndex; 16841 mfp.updateItemHTML(); 16842 }, 16843 preloadNearbyImages: function() { 16844 var p = mfp.st.gallery.preload, 16845 preloadBefore = Math.min(p[0], mfp.items.length), 16846 preloadAfter = Math.min(p[1], mfp.items.length), 16847 i; 16848 16849 for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) { 16850 mfp._preloadItem(mfp.index+i); 16851 } 16852 for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) { 16853 mfp._preloadItem(mfp.index-i); 16854 } 16855 }, 16856 _preloadItem: function(index) { 16857 index = _getLoopedId(index); 16858 16859 if(mfp.items[index].preloaded) { 16860 return; 16861 } 16862 16863 var item = mfp.items[index]; 16864 if(!item.parsed) { 16865 item = mfp.parseEl( index ); 16866 } 16867 16868 _mfpTrigger('LazyLoad', item); 16869 16870 if(item.type === 'image') { 16871 item.img = $('<img class="mfp-img" />').on('load.mfploader', function() { 16872 item.hasSize = true; 16873 }).on('error.mfploader', function() { 16874 item.hasSize = true; 16875 item.loadError = true; 16876 _mfpTrigger('LazyLoadError', item); 16877 }).attr('src', item.src); 16878 } 16879 16880 16881 item.preloaded = true; 16882 } 16883 } 16884}); 16885 16886/*>>gallery*/ 16887 16888/*>>retina*/ 16889 16890var RETINA_NS = 'retina'; 16891 16892$.magnificPopup.registerModule(RETINA_NS, { 16893 options: { 16894 replaceSrc: function(item) { 16895 return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; }); 16896 }, 16897 ratio: 1 // Function or number. Set to 1 to disable. 16898 }, 16899 proto: { 16900 initRetina: function() { 16901 if(window.devicePixelRatio > 1) { 16902 16903 var st = mfp.st.retina, 16904 ratio = st.ratio; 16905 16906 ratio = !isNaN(ratio) ? ratio : ratio(); 16907 16908 if(ratio > 1) { 16909 _mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) { 16910 item.img.css({ 16911 'max-width': item.img[0].naturalWidth / ratio, 16912 'width': '100%' 16913 }); 16914 }); 16915 _mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) { 16916 item.src = st.replaceSrc(item, ratio); 16917 }); 16918 } 16919 } 16920 16921 } 16922 } 16923}); 16924 16925/*>>retina*/ 16926 _checkInstance(); })); 16927/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) 16928 16929/***/ }), 16930/* 24 */
vendor: 3,292 bytes, lines 16931-17054
16931/***/ (function(module, exports) { 16932 16933/** 16934 * EvEmitter v2.1.1 16935 * Lil' event emitter 16936 * MIT License 16937 */ 16938 16939( function( global, factory ) { 16940 // universal module definition 16941 if ( typeof module == 'object' && module.exports ) { 16942 // CommonJS - Browserify, Webpack 16943 module.exports = factory(); 16944 } else { 16945 // Browser globals 16946 global.EvEmitter = factory(); 16947 } 16948 16949}( typeof window != 'undefined' ? window : this, function() { 16950 16951function EvEmitter() {} 16952 16953let proto = EvEmitter.prototype; 16954 16955proto.on = function( eventName, listener ) { 16956 if ( !eventName || !listener ) return this; 16957 16958 // set events hash 16959 let events = this._events = this._events || {}; 16960 // set listeners array 16961 let listeners = events[ eventName ] = events[ eventName ] || []; 16962 // only add once 16963 if ( !listeners.includes( listener ) ) { 16964 listeners.push( listener ); 16965 } 16966 16967 return this; 16968}; 16969 16970proto.once = function( eventName, listener ) { 16971 if ( !eventName || !listener ) return this; 16972 16973 // add event 16974 this.on( eventName, listener ); 16975 // set once flag 16976 // set onceEvents hash 16977 let onceEvents = this._onceEvents = this._onceEvents || {}; 16978 // set onceListeners object 16979 let onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 16980 // set flag 16981 onceListeners[ listener ] = true; 16982 16983 return this; 16984}; 16985 16986proto.off = function( eventName, listener ) { 16987 let listeners = this._events && this._events[ eventName ]; 16988 if ( !listeners || !listeners.length ) return this; 16989 16990 let index = listeners.indexOf( listener ); 16991 if ( index != -1 ) { 16992 listeners.splice( index, 1 ); 16993 } 16994 16995 return this; 16996}; 16997 16998proto.emitEvent = function( eventName, args ) { 16999 let listeners = this._events && this._events[ eventName ]; 17000 if ( !listeners || !listeners.length ) return this; 17001 17002 // copy over to avoid interference if .off() in listener 17003 listeners = listeners.slice( 0 ); 17004 args = args || []; 17005 // once stuff 17006 let onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 17007 17008 for ( let listener of listeners ) { 17009 let isOnce = onceListeners && onceListeners[ listener ]; 17010 if ( isOnce ) { 17011 // remove listener 17012 // remove before trigger to prevent recursion 17013 this.off( eventName, listener ); 17014 // unset once flag 17015 delete onceListeners[ listener ]; 17016 } 17017 // trigger listener 17018 listener.apply( this, args ); 17019 } 17020 17021 return this; 17022}; 17023 17024proto.allOff = function() { 17025 delete this._events; 17026 delete this._onceEvents; 17027 return this; 17028}; 17029 17030return EvEmitter; 17031 17032} ) ); 17033 17034 17035/***/ }), 17036/* 25 */ 17037/***/ (function(module, exports, __webpack_require__) { 17038 17039var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 17040 * Outlayer Item 17041 */ 17042 17043( function( window, factory ) { 17044 // universal module definition 17045 /* jshint strict: false */ /* globals define, module, require */ 17046 if ( true ) { 17047 // AMD - RequireJS 17048 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 17049 __webpack_require__(11), 17050 __webpack_require__(3) 17051 ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 17052 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 17053 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 17054 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)
vendor: 14,212 bytes, lines 17054-17594
17054); 17055 } else if ( typeof module == 'object' && module.exports ) { 17056 // CommonJS - Browserify, Webpack 17057 module.exports = factory( 17058 require('ev-emitter'), 17059 require('get-size') 17060 ); 17061 } else { 17062 // browser global 17063 window.Outlayer = {}; 17064 window.Outlayer.Item = factory( 17065 window.EvEmitter, 17066 window.getSize 17067 ); 17068 } 17069 17070}( window, function factory( EvEmitter, getSize ) { 17071'use strict'; 17072 17073// ----- helpers ----- // 17074 17075function isEmptyObj( obj ) { 17076 for ( var prop in obj ) { 17077 return false; 17078 } 17079 prop = null; 17080 return true; 17081} 17082 17083// -------------------------- CSS3 support -------------------------- // 17084 17085 17086var docElemStyle = document.documentElement.style; 17087 17088var transitionProperty = typeof docElemStyle.transition == 'string' ? 17089 'transition' : 'WebkitTransition'; 17090var transformProperty = typeof docElemStyle.transform == 'string' ? 17091 'transform' : 'WebkitTransform'; 17092 17093var transitionEndEvent = { 17094 WebkitTransition: 'webkitTransitionEnd', 17095 transition: 'transitionend' 17096}[ transitionProperty ]; 17097 17098// cache all vendor properties that could have vendor prefix 17099var vendorProperties = { 17100 transform: transformProperty, 17101 transition: transitionProperty, 17102 transitionDuration: transitionProperty + 'Duration', 17103 transitionProperty: transitionProperty + 'Property', 17104 transitionDelay: transitionProperty + 'Delay' 17105}; 17106 17107// -------------------------- Item -------------------------- // 17108 17109function Item( element, layout ) { 17110 if ( !element ) { 17111 return; 17112 } 17113 17114 this.element = element; 17115 // parent layout class, i.e. Masonry, Isotope, or Packery 17116 this.layout = layout; 17117 this.position = { 17118 x: 0, 17119 y: 0 17120 }; 17121 17122 this._create(); 17123} 17124 17125// inherit EvEmitter 17126var proto = Item.prototype = Object.create( EvEmitter.prototype ); 17127proto.constructor = Item; 17128 17129proto._create = function() { 17130 // transition objects 17131 this._transn = { 17132 ingProperties: {}, 17133 clean: {}, 17134 onEnd: {} 17135 }; 17136 17137 this.css({ 17138 position: 'absolute' 17139 }); 17140}; 17141 17142// trigger specified handler for event type 17143proto.handleEvent = function( event ) { 17144 var method = 'on' + event.type; 17145 if ( this[ method ] ) { 17146 this[ method ]( event ); 17147 } 17148}; 17149 17150proto.getSize = function() { 17151 this.size = getSize( this.element ); 17152}; 17153 17154/** 17155 * apply CSS styles to element 17156 * @param {Object} style 17157 */ 17158proto.css = function( style ) { 17159 var elemStyle = this.element.style; 17160 17161 for ( var prop in style ) { 17162 // use vendor property if available 17163 var supportedProp = vendorProperties[ prop ] || prop; 17164 elemStyle[ supportedProp ] = style[ prop ]; 17165 } 17166}; 17167 17168 // measure position, and sets it 17169proto.getPosition = function() { 17170 var style = getComputedStyle( this.element ); 17171 var isOriginLeft = this.layout._getOption('originLeft'); 17172 var isOriginTop = this.layout._getOption('originTop'); 17173 var xValue = style[ isOriginLeft ? 'left' : 'right' ]; 17174 var yValue = style[ isOriginTop ? 'top' : 'bottom' ]; 17175 var x = parseFloat( xValue ); 17176 var y = parseFloat( yValue ); 17177 // convert percent to pixels 17178 var layoutSize = this.layout.size; 17179 if ( xValue.indexOf('%') != -1 ) { 17180 x = ( x / 100 ) * layoutSize.width; 17181 } 17182 if ( yValue.indexOf('%') != -1 ) { 17183 y = ( y / 100 ) * layoutSize.height; 17184 } 17185 // clean up 'auto' or other non-integer values 17186 x = isNaN( x ) ? 0 : x; 17187 y = isNaN( y ) ? 0 : y; 17188 // remove padding from measurement 17189 x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight; 17190 y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom; 17191 17192 this.position.x = x; 17193 this.position.y = y; 17194}; 17195 17196// set settled position, apply padding 17197proto.layoutPosition = function() { 17198 var layoutSize = this.layout.size; 17199 var style = {}; 17200 var isOriginLeft = this.layout._getOption('originLeft'); 17201 var isOriginTop = this.layout._getOption('originTop'); 17202 17203 // x 17204 var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight'; 17205 var xProperty = isOriginLeft ? 'left' : 'right'; 17206 var xResetProperty = isOriginLeft ? 'right' : 'left'; 17207 17208 var x = this.position.x + layoutSize[ xPadding ]; 17209 // set in percentage or pixels 17210 style[ xProperty ] = this.getXValue( x ); 17211 // reset other property 17212 style[ xResetProperty ] = ''; 17213 17214 // y 17215 var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom'; 17216 var yProperty = isOriginTop ? 'top' : 'bottom'; 17217 var yResetProperty = isOriginTop ? 'bottom' : 'top'; 17218 17219 var y = this.position.y + layoutSize[ yPadding ]; 17220 // set in percentage or pixels 17221 style[ yProperty ] = this.getYValue( y ); 17222 // reset other property 17223 style[ yResetProperty ] = ''; 17224 17225 this.css( style ); 17226 this.emitEvent( 'layout', [ this ] ); 17227}; 17228 17229proto.getXValue = function( x ) { 17230 var isHorizontal = this.layout._getOption('horizontal'); 17231 return this.layout.options.percentPosition && !isHorizontal ? 17232 ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px'; 17233}; 17234 17235proto.getYValue = function( y ) { 17236 var isHorizontal = this.layout._getOption('horizontal'); 17237 return this.layout.options.percentPosition && isHorizontal ? 17238 ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px'; 17239}; 17240 17241proto._transitionTo = function( x, y ) { 17242 this.getPosition(); 17243 // get current x & y from top/left 17244 var curX = this.position.x; 17245 var curY = this.position.y; 17246 17247 var didNotMove = x == this.position.x && y == this.position.y; 17248 17249 // save end position 17250 this.setPosition( x, y ); 17251 17252 // if did not move and not transitioning, just go to layout 17253 if ( didNotMove && !this.isTransitioning ) { 17254 this.layoutPosition(); 17255 return; 17256 } 17257 17258 var transX = x - curX; 17259 var transY = y - curY; 17260 var transitionStyle = {}; 17261 transitionStyle.transform = this.getTranslate( transX, transY ); 17262 17263 this.transition({ 17264 to: transitionStyle, 17265 onTransitionEnd: { 17266 transform: this.layoutPosition 17267 }, 17268 isCleaning: true 17269 }); 17270}; 17271 17272proto.getTranslate = function( x, y ) { 17273 // flip cooridinates if origin on right or bottom 17274 var isOriginLeft = this.layout._getOption('originLeft'); 17275 var isOriginTop = this.layout._getOption('originTop'); 17276 x = isOriginLeft ? x : -x; 17277 y = isOriginTop ? y : -y; 17278 return 'translate3d(' + x + 'px, ' + y + 'px, 0)'; 17279}; 17280 17281// non transition + transform support 17282proto.goTo = function( x, y ) { 17283 this.setPosition( x, y ); 17284 this.layoutPosition(); 17285}; 17286 17287proto.moveTo = proto._transitionTo; 17288 17289proto.setPosition = function( x, y ) { 17290 this.position.x = parseFloat( x ); 17291 this.position.y = parseFloat( y ); 17292}; 17293 17294// ----- transition ----- // 17295 17296/** 17297 * @param {Object} style - CSS 17298 * @param {Function} onTransitionEnd 17299 */ 17300 17301// non transition, just trigger callback 17302proto._nonTransition = function( args ) { 17303 this.css( args.to ); 17304 if ( args.isCleaning ) { 17305 this._removeStyles( args.to ); 17306 } 17307 for ( var prop in args.onTransitionEnd ) { 17308 args.onTransitionEnd[ prop ].call( this ); 17309 } 17310}; 17311 17312/** 17313 * proper transition 17314 * @param {Object} args - arguments 17315 * @param {Object} to - style to transition to 17316 * @param {Object} from - style to start transition from 17317 * @param {Boolean} isCleaning - removes transition styles after transition 17318 * @param {Function} onTransitionEnd - callback 17319 */ 17320proto.transition = function( args ) { 17321 // redirect to nonTransition if no transition duration 17322 if ( !parseFloat( this.layout.options.transitionDuration ) ) { 17323 this._nonTransition( args ); 17324 return; 17325 } 17326 17327 var _transition = this._transn; 17328 // keep track of onTransitionEnd callback by css property 17329 for ( var prop in args.onTransitionEnd ) { 17330 _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ]; 17331 } 17332 // keep track of properties that are transitioning 17333 for ( prop in args.to ) { 17334 _transition.ingProperties[ prop ] = true; 17335 // keep track of properties to clean up when transition is done 17336 if ( args.isCleaning ) { 17337 _transition.clean[ prop ] = true; 17338 } 17339 } 17340 17341 // set from styles 17342 if ( args.from ) { 17343 this.css( args.from ); 17344 // force redraw. http://blog.alexmaccaw.com/css-transitions 17345 var h = this.element.offsetHeight; 17346 // hack for JSHint to hush about unused var 17347 h = null; 17348 } 17349 // enable transition 17350 this.enableTransition( args.to ); 17351 // set styles that are transitioning 17352 this.css( args.to ); 17353 17354 this.isTransitioning = true; 17355 17356}; 17357 17358// dash before all cap letters, including first for 17359// WebkitTransform => -webkit-transform 17360function toDashedAll( str ) { 17361 return str.replace( /([A-Z])/g, function( $1 ) { 17362 return '-' + $1.toLowerCase(); 17363 }); 17364} 17365 17366var transitionProps = 'opacity,' + toDashedAll( transformProperty ); 17367 17368proto.enableTransition = function(/* style */) { 17369 // HACK changing transitionProperty during a transition 17370 // will cause transition to jump 17371 if ( this.isTransitioning ) { 17372 return; 17373 } 17374 17375 // make `transition: foo, bar, baz` from style object 17376 // HACK un-comment this when enableTransition can work 17377 // while a transition is happening 17378 // var transitionValues = []; 17379 // for ( var prop in style ) { 17380 // // dash-ify camelCased properties like WebkitTransition 17381 // prop = vendorProperties[ prop ] || prop; 17382 // transitionValues.push( toDashedAll( prop ) ); 17383 // } 17384 // munge number to millisecond, to match stagger 17385 var duration = this.layout.options.transitionDuration; 17386 duration = typeof duration == 'number' ? duration + 'ms' : duration; 17387 // enable transition styles 17388 this.css({ 17389 transitionProperty: transitionProps, 17390 transitionDuration: duration, 17391 transitionDelay: this.staggerDelay || 0 17392 }); 17393 // listen for transition end event 17394 this.element.addEventListener( transitionEndEvent, this, false ); 17395}; 17396 17397// ----- events ----- // 17398 17399proto.onwebkitTransitionEnd = function( event ) { 17400 this.ontransitionend( event ); 17401}; 17402 17403proto.onotransitionend = function( event ) { 17404 this.ontransitionend( event ); 17405}; 17406 17407// properties that I munge to make my life easier 17408var dashedVendorProperties = { 17409 '-webkit-transform': 'transform' 17410}; 17411 17412proto.ontransitionend = function( event ) { 17413 // disregard bubbled events from children 17414 if ( event.target !== this.element ) { 17415 return; 17416 } 17417 var _transition = this._transn; 17418 // get property name of transitioned property, convert to prefix-free 17419 var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName; 17420 17421 // remove property that has completed transitioning 17422 delete _transition.ingProperties[ propertyName ]; 17423 // check if any properties are still transitioning 17424 if ( isEmptyObj( _transition.ingProperties ) ) { 17425 // all properties have completed transitioning 17426 this.disableTransition(); 17427 } 17428 // clean style 17429 if ( propertyName in _transition.clean ) { 17430 // clean up style 17431 this.element.style[ event.propertyName ] = ''; 17432 delete _transition.clean[ propertyName ]; 17433 } 17434 // trigger onTransitionEnd callback 17435 if ( propertyName in _transition.onEnd ) { 17436 var onTransitionEnd = _transition.onEnd[ propertyName ]; 17437 onTransitionEnd.call( this ); 17438 delete _transition.onEnd[ propertyName ]; 17439 } 17440 17441 this.emitEvent( 'transitionEnd', [ this ] ); 17442}; 17443 17444proto.disableTransition = function() { 17445 this.removeTransitionStyles(); 17446 this.element.removeEventListener( transitionEndEvent, this, false ); 17447 this.isTransitioning = false; 17448}; 17449 17450/** 17451 * removes style property from element 17452 * @param {Object} style 17453**/ 17454proto._removeStyles = function( style ) { 17455 // clean up transition styles 17456 var cleanStyle = {}; 17457 for ( var prop in style ) { 17458 cleanStyle[ prop ] = ''; 17459 } 17460 this.css( cleanStyle ); 17461}; 17462 17463var cleanTransitionStyle = { 17464 transitionProperty: '', 17465 transitionDuration: '', 17466 transitionDelay: '' 17467}; 17468 17469proto.removeTransitionStyles = function() { 17470 // remove transition 17471 this.css( cleanTransitionStyle ); 17472}; 17473 17474// ----- stagger ----- // 17475 17476proto.stagger = function( delay ) { 17477 delay = isNaN( delay ) ? 0 : delay; 17478 this.staggerDelay = delay + 'ms'; 17479}; 17480 17481// ----- show/hide/remove ----- // 17482 17483// remove element from DOM 17484proto.removeElem = function() { 17485 this.element.parentNode.removeChild( this.element ); 17486 // remove display: none 17487 this.css({ display: '' }); 17488 this.emitEvent( 'remove', [ this ] ); 17489}; 17490 17491proto.remove = function() { 17492 // just remove element if no transition support or no transition 17493 if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) { 17494 this.removeElem(); 17495 return; 17496 } 17497 17498 // start transition 17499 this.once( 'transitionEnd', function() { 17500 this.removeElem(); 17501 }); 17502 this.hide(); 17503}; 17504 17505proto.reveal = function() { 17506 delete this.isHidden; 17507 // remove display: none 17508 this.css({ display: '' }); 17509 17510 var options = this.layout.options; 17511 17512 var onTransitionEnd = {}; 17513 var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle'); 17514 onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd; 17515 17516 this.transition({ 17517 from: options.hiddenStyle, 17518 to: options.visibleStyle, 17519 isCleaning: true, 17520 onTransitionEnd: onTransitionEnd 17521 }); 17522}; 17523 17524proto.onRevealTransitionEnd = function() { 17525 // check if still visible 17526 // during transition, item may have been hidden 17527 if ( !this.isHidden ) { 17528 this.emitEvent('reveal'); 17529 } 17530}; 17531 17532/** 17533 * get style property use for hide/reveal transition end 17534 * @param {String} styleProperty - hiddenStyle/visibleStyle 17535 * @returns {String} 17536 */ 17537proto.getHideRevealTransitionEndProperty = function( styleProperty ) { 17538 var optionStyle = this.layout.options[ styleProperty ]; 17539 // use opacity 17540 if ( optionStyle.opacity ) { 17541 return 'opacity'; 17542 } 17543 // get first property 17544 for ( var prop in optionStyle ) { 17545 return prop; 17546 } 17547}; 17548 17549proto.hide = function() { 17550 // set flag 17551 this.isHidden = true; 17552 // remove display: none 17553 this.css({ display: '' }); 17554 17555 var options = this.layout.options; 17556 17557 var onTransitionEnd = {}; 17558 var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle'); 17559 onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd; 17560 17561 this.transition({ 17562 from: options.visibleStyle, 17563 to: options.hiddenStyle, 17564 // keep hidden stuff hidden 17565 isCleaning: true, 17566 onTransitionEnd: onTransitionEnd 17567 }); 17568}; 17569 17570proto.onHideTransitionEnd = function() { 17571 // check if still hidden 17572 // during transition, item may have been un-hidden 17573 if ( this.isHidden ) { 17574 this.css({ display: 'none' }); 17575 this.emitEvent('hide'); 17576 } 17577}; 17578 17579proto.destroy = function() { 17580 this.css({ 17581 position: '', 17582 left: '', 17583 right: '', 17584 top: '', 17585 bottom: '', 17586 transition: '', 17587 transform: '' 17588 }); 17589}; 17590 17591return Item; 17592 17593})); 17594
17595 17596/***/ }), 17597/* 26 */ 17598/***/ (function(module, exports, __webpack_require__) { 17599 17600var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 17601 * Isotope Item 17602**/ 17603 17604( function( window, factory ) { 17605 // universal module definition 17606 /* jshint strict: false */ /*globals define, module, require */ 17607 if ( true ) { 17608 // AMD 17609 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 17610 __webpack_require__(5) 17611 ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 17612 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 17613 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
vendor: 19,595 bytes, lines 17614-18304
17614 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 17615 } else if ( typeof module == 'object' && module.exports ) { 17616 // CommonJS 17617 module.exports = factory( 17618 require('outlayer') 17619 ); 17620 } else { 17621 // browser global 17622 window.Isotope = window.Isotope || {}; 17623 window.Isotope.Item = factory( 17624 window.Outlayer 17625 ); 17626 } 17627 17628}( window, function factory( Outlayer ) { 17629'use strict'; 17630 17631// -------------------------- Item -------------------------- // 17632 17633// sub-class Outlayer Item 17634function Item() { 17635 Outlayer.Item.apply( this, arguments ); 17636} 17637 17638var proto = Item.prototype = Object.create( Outlayer.Item.prototype ); 17639 17640var _create = proto._create; 17641proto._create = function() { 17642 // assign id, used for original-order sorting 17643 this.id = this.layout.itemGUID++; 17644 _create.call( this ); 17645 this.sortData = {}; 17646}; 17647 17648proto.updateSortData = function() { 17649 if ( this.isIgnored ) { 17650 return; 17651 } 17652 // default sorters 17653 this.sortData.id = this.id; 17654 // for backward compatibility 17655 this.sortData['original-order'] = this.id; 17656 this.sortData.random = Math.random(); 17657 // go thru getSortData obj and apply the sorters 17658 var getSortData = this.layout.options.getSortData; 17659 var sorters = this.layout._sorters; 17660 for ( var key in getSortData ) { 17661 var sorter = sorters[ key ]; 17662 this.sortData[ key ] = sorter( this.element, this ); 17663 } 17664}; 17665 17666var _destroy = proto.destroy; 17667proto.destroy = function() { 17668 // call super 17669 _destroy.apply( this, arguments ); 17670 // reset display, #741 17671 this.css({ 17672 display: '' 17673 }); 17674}; 17675 17676return Item; 17677 17678})); 17679 17680 17681/***/ }), 17682/* 27 */ 17683/***/ (function(module, exports, __webpack_require__) { 17684 17685var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 17686 * Masonry layout mode 17687 * sub-classes Masonry 17688 * https://masonry.desandro.com 17689 */ 17690 17691( function( window, factory ) { 17692 // universal module definition 17693 /* jshint strict: false */ /*globals define, module, require */ 17694 if ( true ) { 17695 // AMD 17696 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 17697 __webpack_require__(6), 17698 __webpack_require__(28) 17699 ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 17700 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 17701 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 17702 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 17703 } else if ( typeof module == 'object' && module.exports ) { 17704 // CommonJS 17705 module.exports = factory( 17706 require('../layout-mode'), 17707 require('masonry-layout') 17708 ); 17709 } else { 17710 // browser global 17711 factory( 17712 window.Isotope.LayoutMode, 17713 window.Masonry 17714 ); 17715 } 17716 17717}( window, function factory( LayoutMode, Masonry ) { 17718'use strict'; 17719 17720// -------------------------- masonryDefinition -------------------------- // 17721 17722 // create an Outlayer layout class 17723 var MasonryMode = LayoutMode.create('masonry'); 17724 17725 var proto = MasonryMode.prototype; 17726 17727 var keepModeMethods = { 17728 _getElementOffset: true, 17729 layout: true, 17730 _getMeasurement: true 17731 }; 17732 17733 // inherit Masonry prototype 17734 for ( var method in Masonry.prototype ) { 17735 // do not inherit mode methods 17736 if ( !keepModeMethods[ method ] ) { 17737 proto[ method ] = Masonry.prototype[ method ]; 17738 } 17739 } 17740 17741 var measureColumns = proto.measureColumns; 17742 proto.measureColumns = function() { 17743 // set items, used if measuring first item 17744 this.items = this.isotope.filteredItems; 17745 measureColumns.call( this ); 17746 }; 17747 17748 // point to mode options for fitWidth 17749 var _getOption = proto._getOption; 17750 proto._getOption = function( option ) { 17751 if ( option == 'fitWidth' ) { 17752 return this.options.isFitWidth !== undefined ? 17753 this.options.isFitWidth : this.options.fitWidth; 17754 } 17755 return _getOption.apply( this.isotope, arguments ); 17756 }; 17757 17758 return MasonryMode; 17759 17760})); 17761 17762 17763/***/ }), 17764/* 28 */ 17765/***/ (function(module, exports, __webpack_require__) { 17766 17767var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 17768 * Masonry v4.2.2 17769 * Cascading grid layout library 17770 * https://masonry.desandro.com 17771 * MIT License 17772 * by David DeSandro 17773 */ 17774 17775( function( window, factory ) { 17776 // universal module definition 17777 /* jshint strict: false */ /*globals define, module, require */ 17778 if ( true ) { 17779 // AMD 17780 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 17781 __webpack_require__(5), 17782 __webpack_require__(3) 17783 ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 17784 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 17785 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 17786 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 17787 } else if ( typeof module == 'object' && module.exports ) { 17788 // CommonJS 17789 module.exports = factory( 17790 require('outlayer'), 17791 require('get-size') 17792 ); 17793 } else { 17794 // browser global 17795 window.Masonry = factory( 17796 window.Outlayer, 17797 window.getSize 17798 ); 17799 } 17800 17801}( window, function factory( Outlayer, getSize ) { 17802 17803'use strict'; 17804 17805// -------------------------- masonryDefinition -------------------------- // 17806 17807 // create an Outlayer layout class 17808 var Masonry = Outlayer.create('masonry'); 17809 // isFitWidth -> fitWidth 17810 Masonry.compatOptions.fitWidth = 'isFitWidth'; 17811 17812 var proto = Masonry.prototype; 17813 17814 proto._resetLayout = function() { 17815 this.getSize(); 17816 this._getMeasurement( 'columnWidth', 'outerWidth' ); 17817 this._getMeasurement( 'gutter', 'outerWidth' ); 17818 this.measureColumns(); 17819 17820 // reset column Y 17821 this.colYs = []; 17822 for ( var i=0; i < this.cols; i++ ) { 17823 this.colYs.push( 0 ); 17824 } 17825 17826 this.maxY = 0; 17827 this.horizontalColIndex = 0; 17828 }; 17829 17830 proto.measureColumns = function() { 17831 this.getContainerWidth(); 17832 // if columnWidth is 0, default to outerWidth of first item 17833 if ( !this.columnWidth ) { 17834 var firstItem = this.items[0]; 17835 var firstItemElem = firstItem && firstItem.element; 17836 // columnWidth fall back to item of first element 17837 this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth || 17838 // if first elem has no width, default to size of container 17839 this.containerWidth; 17840 } 17841 17842 var columnWidth = this.columnWidth += this.gutter; 17843 17844 // calculate columns 17845 var containerWidth = this.containerWidth + this.gutter; 17846 var cols = containerWidth / columnWidth; 17847 // fix rounding errors, typically with gutters 17848 var excess = columnWidth - containerWidth % columnWidth; 17849 // if overshoot is less than a pixel, round up, otherwise floor it 17850 var mathMethod = excess && excess < 1 ? 'round' : 'floor'; 17851 cols = Math[ mathMethod ]( cols ); 17852 this.cols = Math.max( cols, 1 ); 17853 }; 17854 17855 proto.getContainerWidth = function() { 17856 // container is parent if fit width 17857 var isFitWidth = this._getOption('fitWidth'); 17858 var container = isFitWidth ? this.element.parentNode : this.element; 17859 // check that this.size and size are there 17860 // IE8 triggers resize on body size change, so they might not be 17861 var size = getSize( container ); 17862 this.containerWidth = size && size.innerWidth; 17863 }; 17864 17865 proto._getItemLayoutPosition = function( item ) { 17866 item.getSize(); 17867 // how many columns does this brick span 17868 var remainder = item.size.outerWidth % this.columnWidth; 17869 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 17870 // round if off by 1 pixel, otherwise use ceil 17871 var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth ); 17872 colSpan = Math.min( colSpan, this.cols ); 17873 // use horizontal or top column position 17874 var colPosMethod = this.options.horizontalOrder ? 17875 '_getHorizontalColPosition' : '_getTopColPosition'; 17876 var colPosition = this[ colPosMethod ]( colSpan, item ); 17877 // position the brick 17878 var position = { 17879 x: this.columnWidth * colPosition.col, 17880 y: colPosition.y 17881 }; 17882 // apply setHeight to necessary columns 17883 var setHeight = colPosition.y + item.size.outerHeight; 17884 var setMax = colSpan + colPosition.col; 17885 for ( var i = colPosition.col; i < setMax; i++ ) { 17886 this.colYs[i] = setHeight; 17887 } 17888 17889 return position; 17890 }; 17891 17892 proto._getTopColPosition = function( colSpan ) { 17893 var colGroup = this._getTopColGroup( colSpan ); 17894 // get the minimum Y value from the columns 17895 var minimumY = Math.min.apply( Math, colGroup ); 17896 17897 return { 17898 col: colGroup.indexOf( minimumY ), 17899 y: minimumY, 17900 }; 17901 }; 17902 17903 /** 17904 * @param {Number} colSpan - number of columns the element spans 17905 * @returns {Array} colGroup 17906 */ 17907 proto._getTopColGroup = function( colSpan ) { 17908 if ( colSpan < 2 ) { 17909 // if brick spans only one column, use all the column Ys 17910 return this.colYs; 17911 } 17912 17913 var colGroup = []; 17914 // how many different places could this brick fit horizontally 17915 var groupCount = this.cols + 1 - colSpan; 17916 // for each group potential horizontal position 17917 for ( var i = 0; i < groupCount; i++ ) { 17918 colGroup[i] = this._getColGroupY( i, colSpan ); 17919 } 17920 return colGroup; 17921 }; 17922 17923 proto._getColGroupY = function( col, colSpan ) { 17924 if ( colSpan < 2 ) { 17925 return this.colYs[ col ]; 17926 } 17927 // make an array of colY values for that one group 17928 var groupColYs = this.colYs.slice( col, col + colSpan ); 17929 // and get the max value of the array 17930 return Math.max.apply( Math, groupColYs ); 17931 }; 17932 17933 // get column position based on horizontal index. #873 17934 proto._getHorizontalColPosition = function( colSpan, item ) { 17935 var col = this.horizontalColIndex % this.cols; 17936 var isOver = colSpan > 1 && col + colSpan > this.cols; 17937 // shift to next row if item can't fit on current row 17938 col = isOver ? 0 : col; 17939 // don't let zero-size items take up space 17940 var hasSize = item.size.outerWidth && item.size.outerHeight; 17941 this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex; 17942 17943 return { 17944 col: col, 17945 y: this._getColGroupY( col, colSpan ), 17946 }; 17947 }; 17948 17949 proto._manageStamp = function( stamp ) { 17950 var stampSize = getSize( stamp ); 17951 var offset = this._getElementOffset( stamp ); 17952 // get the columns that this stamp affects 17953 var isOriginLeft = this._getOption('originLeft'); 17954 var firstX = isOriginLeft ? offset.left : offset.right; 17955 var lastX = firstX + stampSize.outerWidth; 17956 var firstCol = Math.floor( firstX / this.columnWidth ); 17957 firstCol = Math.max( 0, firstCol ); 17958 var lastCol = Math.floor( lastX / this.columnWidth ); 17959 // lastCol should not go over if multiple of columnWidth #425 17960 lastCol -= lastX % this.columnWidth ? 0 : 1; 17961 lastCol = Math.min( this.cols - 1, lastCol ); 17962 // set colYs to bottom of the stamp 17963 17964 var isOriginTop = this._getOption('originTop'); 17965 var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) + 17966 stampSize.outerHeight; 17967 for ( var i = firstCol; i <= lastCol; i++ ) { 17968 this.colYs[i] = Math.max( stampMaxY, this.colYs[i] ); 17969 } 17970 }; 17971 17972 proto._getContainerSize = function() { 17973 this.maxY = Math.max.apply( Math, this.colYs ); 17974 var size = { 17975 height: this.maxY 17976 }; 17977 17978 if ( this._getOption('fitWidth') ) { 17979 size.width = this._getContainerFitWidth(); 17980 } 17981 17982 return size; 17983 }; 17984 17985 proto._getContainerFitWidth = function() { 17986 var unusedCols = 0; 17987 // count unused columns 17988 var i = this.cols; 17989 while ( --i ) { 17990 if ( this.colYs[i] !== 0 ) { 17991 break; 17992 } 17993 unusedCols++; 17994 } 17995 // fit container to columns that have been used 17996 return ( this.cols - unusedCols ) * this.columnWidth - this.gutter; 17997 }; 17998 17999 proto.needsResizeLayout = function() { 18000 var previousWidth = this.containerWidth; 18001 this.getContainerWidth(); 18002 return previousWidth != this.containerWidth; 18003 }; 18004 18005 return Masonry; 18006 18007})); 18008 18009 18010/***/ }), 18011/* 29 */ 18012/***/ (function(module, exports, __webpack_require__) { 18013 18014var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 18015 * fitRows layout mode 18016 */ 18017 18018( function( window, factory ) { 18019 // universal module definition 18020 /* jshint strict: false */ /*globals define, module, require */ 18021 if ( true ) { 18022 // AMD 18023 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 18024 __webpack_require__(6) 18025 ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 18026 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 18027 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 18028 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 18029 } else if ( typeof exports == 'object' ) { 18030 // CommonJS 18031 module.exports = factory( 18032 require('../layout-mode') 18033 ); 18034 } else { 18035 // browser global 18036 factory( 18037 window.Isotope.LayoutMode 18038 ); 18039 } 18040 18041}( window, function factory( LayoutMode ) { 18042'use strict'; 18043 18044var FitRows = LayoutMode.create('fitRows'); 18045 18046var proto = FitRows.prototype; 18047 18048proto._resetLayout = function() { 18049 this.x = 0; 18050 this.y = 0; 18051 this.maxY = 0; 18052 this._getMeasurement( 'gutter', 'outerWidth' ); 18053}; 18054 18055proto._getItemLayoutPosition = function( item ) { 18056 item.getSize(); 18057 18058 var itemWidth = item.size.outerWidth + this.gutter; 18059 // if this element cannot fit in the current row 18060 var containerWidth = this.isotope.size.innerWidth + this.gutter; 18061 if ( this.x !== 0 && itemWidth + this.x > containerWidth ) { 18062 this.x = 0; 18063 this.y = this.maxY; 18064 } 18065 18066 var position = { 18067 x: this.x, 18068 y: this.y 18069 }; 18070 18071 this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight ); 18072 this.x += itemWidth; 18073 18074 return position; 18075}; 18076 18077proto._getContainerSize = function() { 18078 return { height: this.maxY }; 18079}; 18080 18081return FitRows; 18082 18083})); 18084 18085 18086/***/ }), 18087/* 30 */ 18088/***/ (function(module, exports, __webpack_require__) { 18089 18090var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 18091 * vertical layout mode 18092 */ 18093 18094( function( window, factory ) { 18095 // universal module definition 18096 /* jshint strict: false */ /*globals define, module, require */ 18097 if ( true ) { 18098 // AMD 18099 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 18100 __webpack_require__(6) 18101 ], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 18102 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 18103 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 18104 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 18105 } else if ( typeof module == 'object' && module.exports ) { 18106 // CommonJS 18107 module.exports = factory( 18108 require('../layout-mode') 18109 ); 18110 } else { 18111 // browser global 18112 factory( 18113 window.Isotope.LayoutMode 18114 ); 18115 } 18116 18117}( window, function factory( LayoutMode ) { 18118'use strict'; 18119 18120var Vertical = LayoutMode.create( 'vertical', { 18121 horizontalAlignment: 0 18122}); 18123 18124var proto = Vertical.prototype; 18125 18126proto._resetLayout = function() { 18127 this.y = 0; 18128}; 18129 18130proto._getItemLayoutPosition = function( item ) { 18131 item.getSize(); 18132 var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) * 18133 this.options.horizontalAlignment; 18134 var y = this.y; 18135 this.y += item.size.outerHeight; 18136 return { x: x, y: y }; 18137}; 18138 18139proto._getContainerSize = function() { 18140 return { height: this.y }; 18141}; 18142 18143return Vertical; 18144 18145})); 18146 18147 18148/***/ }), 18149/* 31 */ 18150/***/ (function(module, exports, __webpack_require__) { 18151 18152var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 18153 * EvEmitter v1.1.0 18154 * Lil' event emitter 18155 * MIT License 18156 */ 18157 18158/* jshint unused: true, undef: true, strict: true */ 18159 18160( function( global, factory ) { 18161 // universal module definition 18162 /* jshint strict: false */ /* globals define, module, window */ 18163 if ( true ) { 18164 // AMD - RequireJS 18165 !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 18166 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 18167 (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : 18168 __WEBPACK_AMD_DEFINE_FACTORY__), 18169 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 18170 } else if ( typeof module == 'object' && module.exports ) { 18171 // CommonJS - Browserify, Webpack 18172 module.exports = factory(); 18173 } else { 18174 // Browser globals 18175 global.EvEmitter = factory(); 18176 } 18177 18178}( typeof window != 'undefined' ? window : this, function() { 18179 18180"use strict"; 18181 18182function EvEmitter() {} 18183 18184var proto = EvEmitter.prototype; 18185 18186proto.on = function( eventName, listener ) { 18187 if ( !eventName || !listener ) { 18188 return; 18189 } 18190 // set events hash 18191 var events = this._events = this._events || {}; 18192 // set listeners array 18193 var listeners = events[ eventName ] = events[ eventName ] || []; 18194 // only add once 18195 if ( listeners.indexOf( listener ) == -1 ) { 18196 listeners.push( listener ); 18197 } 18198 18199 return this; 18200}; 18201 18202proto.once = function( eventName, listener ) { 18203 if ( !eventName || !listener ) { 18204 return; 18205 } 18206 // add event 18207 this.on( eventName, listener ); 18208 // set once flag 18209 // set onceEvents hash 18210 var onceEvents = this._onceEvents = this._onceEvents || {}; 18211 // set onceListeners object 18212 var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 18213 // set flag 18214 onceListeners[ listener ] = true; 18215 18216 return this; 18217}; 18218 18219proto.off = function( eventName, listener ) { 18220 var listeners = this._events && this._events[ eventName ]; 18221 if ( !listeners || !listeners.length ) { 18222 return; 18223 } 18224 var index = listeners.indexOf( listener ); 18225 if ( index != -1 ) { 18226 listeners.splice( index, 1 ); 18227 } 18228 18229 return this; 18230}; 18231 18232proto.emitEvent = function( eventName, args ) { 18233 var listeners = this._events && this._events[ eventName ]; 18234 if ( !listeners || !listeners.length ) { 18235 return; 18236 } 18237 // copy over to avoid interference if .off() in listener 18238 listeners = listeners.slice(0); 18239 args = args || []; 18240 // once stuff 18241 var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 18242 18243 for ( var i=0; i < listeners.length; i++ ) { 18244 var listener = listeners[i] 18245 var isOnce = onceListeners && onceListeners[ listener ]; 18246 if ( isOnce ) { 18247 // remove listener 18248 // remove before trigger to prevent recursion 18249 this.off( eventName, listener ); 18250 // unset once flag 18251 delete onceListeners[ listener ]; 18252 } 18253 // trigger listener 18254 listener.apply( this, args ); 18255 } 18256 18257 return this; 18258}; 18259 18260proto.allOff = function() { 18261 delete this._events; 18262 delete this._onceEvents; 18263}; 18264 18265return EvEmitter; 18266 18267})); 18268 18269 18270/***/ }), 18271/* 32 */ 18272/***/ (function(module, exports, __webpack_require__) { 18273 18274var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// page-load 18275( function( window, factory ) { 18276 // universal module definition 18277 /* globals define, module, require */ 18278 if ( true ) { 18279 // AMD 18280 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 18281 __webpack_require__(2), 18282 ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( InfiniteScroll ) { 18283 return factory( window, InfiniteScroll ); 18284 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 18285 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 18286 } else if ( typeof module == 'object' && module.exports ) { 18287 // CommonJS 18288 module.exports = factory( 18289 window, 18290 require('./core') 18291 ); 18292 } else { 18293 // browser global 18294 factory( 18295 window, 18296 window.InfiniteScroll 18297 ); 18298 } 18299 18300}( window, function factory( window, InfiniteScroll ) { 18301 18302var proto = InfiniteScroll.prototype; 18303 18304// InfiniteScroll.defaults.append = false;
18305InfiniteScroll.defaults.loadOnScroll = true; 18306InfiniteScroll.defaults.checkLastPage = true; 18307InfiniteScroll.defaults.responseType = 'document'; 18308// InfiniteScroll.defaults.prefill = false; 18309// InfiniteScroll.defaults.outlayer = null; 18310 18311InfiniteScroll.create.pageLoad = function() { 18312 this.canLoad = true; 18313 this.on( 'scrollThreshold', this.onScrollThresholdLoad ); 18314 this.on( 'load', this.checkLastPage ); 18315 if ( this.options.outlayer ) { 18316 this.on( 'append', this.onAppendOutlayer ); 18317 } 18318}; 18319 18320proto.onScrollThresholdLoad = function() { 18321 if ( this.options.loadOnScroll ) { 18322 this.loadNextPage(); 18323 } 18324}; 18325 18326proto.loadNextPage = function() { 18327 if ( this.isLoading || !this.canLoad ) { 18328 return; 18329 } 18330 18331 var path = this.getAbsolutePath(); 18332 this.isLoading = true; 18333 18334 var onLoad = function( response ) { 18335 this.onPageLoad( response, path ); 18336 }.bind( this ); 18337 18338 var onError = function( error ) { 18339 this.onPageError( error, path ); 18340 }.bind( this ); 18341 18342 request( path, this.options.responseType, onLoad, onError ); 18343 this.dispatchEvent( 'request', null, [ path ] ); 18344}; 18345 18346proto.onPageLoad = function( response, path ) { 18347 // done loading if not appending 18348 if ( !this.options.append ) { 18349 this.isLoading = false; 18350 } 18351 this.pageIndex++; 18352 this.loadCount++; 18353 this.dispatchEvent( 'load', null, [ response, path ] ); 18354 this.appendNextPage( response, path ); 18355 return response; 18356}; 18357 18358proto.appendNextPage = function( response, path ) { 18359 var optAppend = this.options.append; 18360 // do not append json 18361 var isDocument = this.options.responseType == 'document'; 18362 if ( !isDocument || !optAppend ) { 18363 return; 18364 } 18365 18366 var items = response.querySelectorAll( optAppend ); 18367 var fragment = getItemsFragment( items ); 18368 var appendReady = function () { 18369 this.appendItems( items, fragment ); 18370 this.isLoading = false; 18371 this.dispatchEvent( 'append', null, [ response, path, items ] ); 18372 }.bind( this ); 18373 18374 // TODO add hook for option to trigger appendReady 18375 if ( this.options.outlayer ) { 18376 this.appendOutlayerItems( fragment, appendReady ); 18377 } else { 18378 appendReady(); 18379 } 18380}; 18381 18382proto.appendItems = function( items, fragment ) { 18383 if ( !items || !items.length ) { 18384 return; 18385 } 18386 // get fragment if not provided 18387 fragment = fragment || getItemsFragment( items ); 18388 refreshScripts( fragment ); 18389 this.element.appendChild( fragment ); 18390}; 18391 18392function getItemsFragment( items ) { 18393 // add items to fragment 18394 var fragment = document.createDocumentFragment(); 18395 for ( var i=0; items && i < items.length; i++ ) { 18396 fragment.appendChild( items[i] ); 18397 } 18398 return fragment; 18399} 18400 18401// replace <script>s with copies so they load 18402// <script>s added by InfiniteScroll will not load 18403// similar to https://stackoverflow.com/questions/610995 18404function refreshScripts( fragment ) { 18405 var scripts = fragment.querySelectorAll('script'); 18406 for ( var i=0; i < scripts.length; i++ ) { 18407 var script = scripts[i]; 18408 var freshScript = document.createElement('script'); 18409 copyAttributes( script, freshScript ); 18410 script.parentNode.replaceChild( freshScript, script ); 18411 } 18412} 18413 18414function copyAttributes( fromNode, toNode ) { 18415 var attrs = fromNode.attributes; 18416 for ( var i=0; i < attrs.length; i++ ) { 18417 var attr = attrs[i]; 18418 toNode.setAttribute( attr.name, attr.value ); 18419 } 18420} 18421 18422// ----- outlayer ----- // 18423 18424proto.appendOutlayerItems = function( fragment, appendReady ) { 18425 var imagesLoaded = InfiniteScroll.imagesLoaded || window.imagesLoaded; 18426 if ( !imagesLoaded ) { 18427 console.error('[InfiniteScroll] imagesLoaded required for outlayer option'); 18428 this.isLoading = false; 18429 return; 18430 } 18431 // append once images loaded 18432 imagesLoaded( fragment, appendReady ); 18433}; 18434 18435proto.onAppendOutlayer = function( response, path, items ) { 18436 this.options.outlayer.appended( items ); 18437}; 18438 18439// ----- checkLastPage ----- // 18440 18441// check response for next element 18442proto.checkLastPage = function( response, path ) { 18443 var checkLastPage = this.options.checkLastPage; 18444 if ( !checkLastPage ) { 18445 return; 18446 } 18447 18448 var pathOpt = this.options.path; 18449 // if path is function, check if next path is truthy 18450 if ( typeof pathOpt == 'function' ) {
18451 var nextPath = this.getPath(); 18452 if ( !nextPath ) { 18453 this.lastPageReached( response, path ); 18454 return; 18455 } 18456 } 18457 // get selector from checkLastPage or path option 18458 var selector; 18459 if ( typeof checkLastPage == 'string' ) { 18460 selector = checkLastPage; 18461 } else if ( this.isPathSelector ) { 18462 // path option is selector string 18463 selector = pathOpt; 18464 } 18465 // check last page for selector 18466 // bail if no selector or not document response 18467 if ( !selector || !response.querySelector ) { 18468 return; 18469 } 18470 // check if response has selector 18471 var nextElem = response.querySelector( selector ); 18472 if ( !nextElem ) { 18473 this.lastPageReached( response, path ); 18474 } 18475}; 18476 18477proto.lastPageReached = function( response, path ) { 18478 this.canLoad = false; 18479 this.dispatchEvent( 'last', null, [ response, path ] ); 18480}; 18481 18482// ----- error ----- // 18483 18484proto.onPageError = function( error, path ) { 18485 this.isLoading = false; 18486 this.canLoad = false; 18487 this.dispatchEvent( 'error', null, [ error, path ] ); 18488 return error; 18489}; 18490 18491// -------------------------- prefill -------------------------- // 18492 18493InfiniteScroll.create.prefill = function() { 18494 if ( !this.options.prefill ) { 18495 return; 18496 } 18497 var append = this.options.append; 18498 if ( !append ) { 18499 console.error( 'append option required for prefill. Set as :' + append ); 18500 return; 18501 } 18502 this.updateMeasurements(); 18503 this.updateScroller(); 18504 this.isPrefilling = true; 18505 this.on( 'append', this.prefill ); 18506 this.once( 'error', this.stopPrefill ); 18507 this.once( 'last', this.stopPrefill ); 18508 this.prefill(); 18509}; 18510 18511proto.prefill = function() { 18512 var distance = this.getPrefillDistance(); 18513 this.isPrefilling = distance >= 0; 18514 if ( this.isPrefilling ) { 18515 this.log('prefill'); 18516 this.loadNextPage(); 18517 } else { 18518 this.stopPrefill(); 18519 } 18520}; 18521 18522proto.getPrefillDistance = function() { 18523 // element scroll 18524 if ( this.options.elementScroll ) { 18525 return this.scroller.clientHeight - this.scroller.scrollHeight; 18526 } 18527 // window 18528 return this.windowHeight - this.element.clientHeight; 18529}; 18530 18531proto.stopPrefill = function() { 18532 console.log('stopping prefill'); 18533 this.off( 'append', this.prefill ); 18534}; 18535 18536// -------------------------- request -------------------------- // 18537 18538function request( url, responseType, onLoad, onError ) { 18539 var req = new XMLHttpRequest(); 18540 req.open( 'GET', url, true ); 18541 // set responseType document to return DOM 18542 req.responseType = responseType || ''; 18543 18544 // set X-Requested-With header to check that is ajax request 18545 req.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 18546 18547 req.onload = function() { 18548 if ( req.status == 200 ) { 18549 onLoad( req.response ); 18550 } else { 18551 // not 200 OK, error 18552 var error = new Error( req.statusText ); 18553 onError( error ); 18554 } 18555 }; 18556 18557 // Handle network errors 18558 req.onerror = function() { 18559 var error = new Error( 'Network error requesting ' + url ); 18560 onError( error ); 18561 }; 18562 18563 req.send(); 18564} 18565 18566// -------------------------- -------------------------- // 18567 18568return InfiniteScroll; 18569 18570})); 18571 18572 18573/***/ }), 18574/* 33 */ 18575/***/ (function(module, exports, __webpack_require__) { 18576 18577var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// scroll-watch 18578( function( window, factory ) { 18579 // universal module definition 18580 /* globals define, module, require */ 18581 if ( true ) { 18582 // AMD 18583 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 18584 __webpack_require__(2), 18585 __webpack_require__(1), 18586 ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( InfiniteScroll, utils ) { 18587 return factory( window, InfiniteScroll, utils ); 18588 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 18589 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 18590 } else if ( typeof module == 'object' && module.exports ) { 18591 // CommonJS 18592 module.exports = factory( 18593 window, 18594 require('./core'), 18595 require('fizzy-ui-utils') 18596 ); 18597 } else { 18598 // browser global 18599 factory( 18600 window, 18601 window.InfiniteScroll, 18602 window.fizzyUIUtils 18603 ); 18604 } 18605 18606}( window, function factory( window, InfiniteScroll, utils ) { 18607 18608var proto = InfiniteScroll.prototype; 18609 18610// default options 18611InfiniteScroll.defaults.scrollThreshold = 400; 18612// InfiniteScroll.defaults.elementScroll = null; 18613 18614InfiniteScroll.create.scrollWatch = function() { 18615 // events 18616 this.pageScrollHandler = this.onPageScroll.bind( this ); 18617 this.resizeHandler = this.onResize.bind( this ); 18618 18619 var scrollThreshold = this.options.scrollThreshold; 18620 var isEnable = scrollThreshold || scrollThreshold === 0; 18621 if ( isEnable ) { 18622 this.enableScrollWatch(); 18623 } 18624}; 18625 18626InfiniteScroll.destroy.scrollWatch = function() { 18627 this.disableScrollWatch(); 18628}; 18629 18630proto.enableScrollWatch = function() { 18631 if ( this.isScrollWatching ) { 18632 return; 18633 } 18634 this.isScrollWatching = true; 18635 this.updateMeasurements(); 18636 this.updateScroller(); 18637 // TODO disable after error? 18638 this.on( 'last', this.disableScrollWatch ); 18639 this.bindScrollWatchEvents( true ); 18640}; 18641 18642proto.disableScrollWatch = function() { 18643 if ( !this.isScrollWatching ) { 18644 return; 18645 } 18646 this.bindScrollWatchEvents( false ); 18647 delete this.isScrollWatching; 18648}; 18649 18650proto.bindScrollWatchEvents = function( isBind ) { 18651 var addRemove = isBind ? 'addEventListener' : 'removeEventListener'; 18652 this.scroller[ addRemove ]( 'scroll', this.pageScrollHandler ); 18653 window[ addRemove ]( 'resize', this.resizeHandler ); 18654}; 18655 18656proto.onPageScroll = InfiniteScroll.throttle( function() { 18657 var distance = this.getBottomDistance(); 18658 if ( distance <= this.options.scrollThreshold ) { 18659 this.dispatchEvent('scrollThreshold'); 18660 } 18661}); 18662 18663proto.getBottomDistance = function() { 18664 if ( this.options.elementScroll ) { 18665 return this.getElementBottomDistance(); 18666 } else { 18667 return this.getWindowBottomDistance(); 18668 } 18669}; 18670 18671proto.getWindowBottomDistance = function() { 18672 var bottom = this.top + this.element.clientHeight; 18673 var scrollY = window.pageYOffset + this.windowHeight; 18674 return bottom - scrollY; 18675}; 18676 18677proto.getElementBottomDistance = function() { 18678 var bottom = this.scroller.scrollHeight; 18679 var scrollY = this.scroller.scrollTop + this.scroller.clientHeight; 18680 return bottom - scrollY; 18681}; 18682 18683proto.onResize = function() { 18684 this.updateMeasurements(); 18685}; 18686 18687utils.debounceMethod( InfiniteScroll, 'onResize', 150 ); 18688 18689// -------------------------- -------------------------- // 18690 18691return InfiniteScroll; 18692 18693})); 18694 18695 18696/***/ }), 18697/* 34 */ 18698/***/ (function(module, exports, __webpack_require__) { 18699 18700var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// history 18701( function( window, factory ) { 18702 // universal module definition 18703 /* globals define, module, require */ 18704 if ( true ) { 18705 // AMD 18706 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 18707 __webpack_require__(2), 18708 __webpack_require__(1), 18709 ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( InfiniteScroll, utils ) { 18710 return factory( window, InfiniteScroll, utils ); 18711 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 18712 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 18713 } else if ( typeof module == 'object' && module.exports ) { 18714 // CommonJS 18715 module.exports = factory( 18716 window, 18717 require('./core'), 18718 require('fizzy-ui-utils') 18719 ); 18720 } else { 18721 // browser global 18722 factory( 18723 window, 18724 window.InfiniteScroll, 18725 window.fizzyUIUtils 18726 ); 18727 } 18728 18729}( window, function factory( window, InfiniteScroll, utils ) { 18730 18731var proto = InfiniteScroll.prototype; 18732 18733InfiniteScroll.defaults.history = 'replace'; 18734// InfiniteScroll.defaults.historyTitle = false;
18735 18736var link = document.createElement('a'); 18737 18738// ----- create/destroy ----- // 18739 18740InfiniteScroll.create.history = function() { 18741 if ( !this.options.history ) { 18742 return; 18743 } 18744 // check for same origin 18745 link.href = this.getAbsolutePath(); 18746 // MS Edge does not have origin on link https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12236493/ 18747 var linkOrigin = link.origin || link.protocol + '//' + link.host; 18748 var isSameOrigin = linkOrigin == location.origin; 18749 if ( !isSameOrigin ) { 18750 console.error( '[InfiniteScroll] cannot set history with different origin: ' + 18751 link.origin + ' on ' + location.origin + 18752 ' . History behavior disabled.' ); 18753 return; 18754 } 18755 18756 // two ways to handle changing history 18757 if ( this.options.append ) { 18758 this.createHistoryAppend(); 18759 } else { 18760 this.createHistoryPageLoad(); 18761 } 18762}; 18763 18764proto.createHistoryAppend = function() { 18765 this.updateMeasurements(); 18766 this.updateScroller(); 18767 // array of scroll positions of appended pages 18768 this.scrollPages = [ 18769 { 18770 // first page 18771 top: 0, 18772 path: location.href, 18773 title: document.title, 18774 } 18775 ]; 18776 this.scrollPageIndex = 0; 18777 // events 18778 this.scrollHistoryHandler = this.onScrollHistory.bind( this ); 18779 this.unloadHandler = this.onUnload.bind( this ); 18780 this.scroller.addEventListener( 'scroll', this.scrollHistoryHandler ); 18781 this.on( 'append', this.onAppendHistory ); 18782 this.bindHistoryAppendEvents( true ); 18783}; 18784 18785proto.bindHistoryAppendEvents = function( isBind ) { 18786 var addRemove = isBind ? 'addEventListener' : 'removeEventListener'; 18787 this.scroller[ addRemove ]( 'scroll', this.scrollHistoryHandler ); 18788 window[ addRemove ]( 'unload', this.unloadHandler ); 18789}; 18790 18791proto.createHistoryPageLoad = function() { 18792 this.on( 'load', this.onPageLoadHistory ); 18793}; 18794 18795InfiniteScroll.destroy.history = 18796proto.destroyHistory = function() { 18797 var isHistoryAppend = this.options.history && this.options.append; 18798 if ( isHistoryAppend ) { 18799 this.bindHistoryAppendEvents( false ); 18800 } 18801}; 18802 18803// ----- append history ----- // 18804 18805proto.onAppendHistory = function( response, path, items ) { 18806 var firstItem = items[0]; 18807 var elemScrollY = this.getElementScrollY( firstItem ); 18808 // resolve path 18809 link.href = path; 18810 // add page data to hash 18811 this.scrollPages.push({ 18812 top: elemScrollY, 18813 path: link.href, 18814 title: response.title, 18815 }); 18816}; 18817 18818proto.getElementScrollY = function( elem ) { 18819 if ( this.options.elementScroll ) { 18820 return this.getElementElementScrollY( elem ); 18821 } else { 18822 return this.getElementWindowScrollY( elem ); 18823 } 18824}; 18825 18826proto.getElementWindowScrollY = function( elem ) { 18827 var rect = elem.getBoundingClientRect(); 18828 return rect.top + window.pageYOffset; 18829}; 18830 18831// wow, stupid name 18832proto.getElementElementScrollY = function( elem ) { 18833 return elem.offsetTop - this.top; 18834}; 18835 18836proto.onScrollHistory = function() { 18837 // cycle through positions, find biggest without going over 18838 var scrollViewY = this.getScrollViewY(); 18839 var pageIndex, page; 18840 for ( var i=0; i < this.scrollPages.length; i++ ) { 18841 var scrollPage = this.scrollPages[i]; 18842 if ( scrollPage.top >= scrollViewY ) { 18843 break; 18844 } 18845 pageIndex = i; 18846 page = scrollPage; 18847 } 18848 // set history if changed 18849 if ( pageIndex != this.scrollPageIndex ) { 18850 this.scrollPageIndex = pageIndex; 18851 this.setHistory( page.title, page.path ); 18852 } 18853}; 18854 18855utils.debounceMethod( InfiniteScroll, 'onScrollHistory', 150 ); 18856 18857proto.getScrollViewY = function() { 18858 if ( this.options.elementScroll ) { 18859 return this.scroller.scrollTop + this.scroller.clientHeight/2; 18860 } else { 18861 return window.pageYOffset + this.windowHeight/2; 18862 } 18863}; 18864 18865proto.setHistory = function( title, path ) { 18866 var optHistory = this.options.history; 18867 var historyMethod = optHistory && history[ optHistory + 'State' ]; 18868 if ( !historyMethod ) { 18869 return; 18870 } 18871 18872 history[ optHistory + 'State' ]( null, title, path ); 18873 18874 if ( this.options.historyTitle ) { 18875 document.title = title; 18876 } 18877 18878 this.dispatchEvent( 'history', null, [ title, path ] ); 18879}; 18880 18881// scroll to top to prevent initial scroll-reset after page refresh 18882// http://stackoverflow.com/a/18633915/182183 18883proto.onUnload = function() { 18884 var pageIndex = this.scrollPageIndex; 18885 if ( pageIndex === 0 ) { 18886 return; 18887 } 18888 // calculate where scroll position would be on refresh 18889 var scrollPage = this.scrollPages[ pageIndex ]; 18890 var scrollY = window.pageYOffset - scrollPage.top + this.top; 18891 // disable scroll event before setting scroll #679 18892 this.destroyHistory(); 18893 scrollTo( 0, scrollY ); 18894}; 18895 18896// ----- load history ----- // 18897 18898// update URL 18899proto.onPageLoadHistory = function( response, path ) { 18900 this.setHistory( response.title, path ); 18901}; 18902 18903// -------------------------- -------------------------- // 18904 18905return InfiniteScroll; 18906 18907})); 18908 18909 18910/***/ }), 18911/* 35 */ 18912/***/ (function(module, exports, __webpack_require__) { 18913 18914var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// button 18915( function( window, factory ) { 18916 // universal module definition 18917 /* globals define, module, require */ 18918 if ( true ) { 18919 // AMD 18920 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 18921 __webpack_require__(2), 18922 __webpack_require__(1), 18923 ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( InfiniteScroll, utils ) { 18924 return factory( window, InfiniteScroll, utils ); 18925 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 18926 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 18927 } else if ( typeof module == 'object' && module.exports ) { 18928 // CommonJS 18929 module.exports = factory( 18930 window, 18931 require('./core'), 18932 require('fizzy-ui-utils') 18933 ); 18934 } else { 18935 // browser global 18936 factory( 18937 window, 18938 window.InfiniteScroll, 18939 window.fizzyUIUtils 18940 ); 18941 } 18942 18943}( window, function factory( window, InfiniteScroll, utils ) { 18944 18945// InfiniteScroll.defaults.button = null; 18946 18947InfiniteScroll.create.button = function() { 18948 var buttonElem = utils.getQueryElement( this.options.button ); 18949 if ( buttonElem ) { 18950 this.button = new InfiniteScrollButton( buttonElem, this ); 18951 return; 18952 } 18953}; 18954 18955InfiniteScroll.destroy.button = function() { 18956 if ( this.button ) { 18957 this.button.destroy(); 18958 } 18959}; 18960 18961// -------------------------- InfiniteScrollButton -------------------------- // 18962 18963function InfiniteScrollButton( element, infScroll ) { 18964 this.element = element; 18965 this.infScroll = infScroll; 18966 // events 18967 this.clickHandler = this.onClick.bind( this ); 18968 this.element.addEventListener( 'click', this.clickHandler ); 18969 infScroll.on( 'request', this.disable.bind( this ) ); 18970 infScroll.on( 'load', this.enable.bind( this ) ); 18971 infScroll.on( 'error', this.hide.bind( this ) ); 18972 infScroll.on( 'last', this.hide.bind( this ) ); 18973} 18974 18975InfiniteScrollButton.prototype.onClick = function( event ) { 18976 event.preventDefault(); 18977 this.infScroll.loadNextPage(); 18978}; 18979 18980InfiniteScrollButton.prototype.enable = function() { 18981 this.element.removeAttribute('disabled'); 18982}; 18983 18984InfiniteScrollButton.prototype.disable = function() { 18985 this.element.disabled = 'disabled'; 18986}; 18987 18988InfiniteScrollButton.prototype.hide = function() { 18989 this.element.style.display = 'none'; 18990}; 18991 18992InfiniteScrollButton.prototype.destroy = function() { 18993 this.element.removeEventListener( 'click', this.clickHandler ); 18994}; 18995 18996// -------------------------- -------------------------- // 18997 18998InfiniteScroll.Button = InfiniteScrollButton; 18999 19000return InfiniteScroll; 19001 19002})); 19003 19004 19005/***/ }), 19006/* 36 */ 19007/***/ (function(module, exports, __webpack_require__) { 19008 19009var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// status 19010( function( window, factory ) { 19011 // universal module definition 19012 /* globals define, module, require */ 19013 if ( true ) { 19014 // AMD 19015 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 19016 __webpack_require__(2), 19017 __webpack_require__(1), 19018 ], __WEBPACK_AMD_DEFINE_RESULT__ = (function( InfiniteScroll, utils ) { 19019 return factory( window, InfiniteScroll, utils ); 19020 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 19021 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 19022 } else if ( typeof module == 'object' && module.exports ) { 19023 // CommonJS 19024 module.exports = factory( 19025 window, 19026 require('./core'), 19027 require('fizzy-ui-utils') 19028 ); 19029 } else { 19030 // browser global 19031 factory( 19032 window, 19033 window.InfiniteScroll, 19034 window.fizzyUIUtils 19035 ); 19036 } 19037 19038}( window, function factory( window, InfiniteScroll, utils ) { 19039 19040var proto = InfiniteScroll.prototype; 19041 19042// InfiniteScroll.defaults.status = null; 19043 19044InfiniteScroll.create.status = function() { 19045 var statusElem = utils.getQueryElement( this.options.status ); 19046 if ( !statusElem ) { 19047 return; 19048 } 19049 // elements 19050 this.statusElement = statusElem; 19051 this.statusEventElements = { 19052 request: statusElem.querySelector('.infinite-scroll-request'), 19053 error: statusElem.querySelector('.infinite-scroll-error'), 19054 last: statusElem.querySelector('.infinite-scroll-last'), 19055 }; 19056 // events 19057 this.on( 'request', this.showRequestStatus ); 19058 this.on( 'error', this.showErrorStatus ); 19059 this.on( 'last', this.showLastStatus ); 19060 this.bindHideStatus('on'); 19061}; 19062 19063proto.bindHideStatus = function( bindMethod ) { 19064 var hideEvent = this.options.append ? 'append' : 'load'; 19065 this[ bindMethod ]( hideEvent, this.hideAllStatus ); 19066}; 19067 19068proto.showRequestStatus = function() { 19069 this.showStatus('request'); 19070}; 19071 19072proto.showErrorStatus = function() { 19073 this.showStatus('error'); 19074}; 19075 19076proto.showLastStatus = function() { 19077 this.showStatus('last'); 19078 // prevent last then append event race condition from showing last status #706 19079 this.bindHideStatus('off'); 19080}; 19081 19082proto.showStatus = function( eventName ) { 19083 show( this.statusElement ); 19084 this.hideStatusEventElements(); 19085 var eventElem = this.statusEventElements[ eventName ]; 19086 show( eventElem ); 19087}; 19088 19089proto.hideAllStatus = function() { 19090 hide( this.statusElement ); 19091 this.hideStatusEventElements(); 19092}; 19093 19094proto.hideStatusEventElements = function() { 19095 for ( var type in this.statusEventElements ) { 19096 var eventElem = this.statusEventElements[ type ]; 19097 hide( eventElem ); 19098 } 19099}; 19100 19101// -------------------------- -------------------------- // 19102 19103function hide( elem ) { 19104 setDisplay( elem, 'none' ); 19105} 19106 19107function show( elem ) { 19108 setDisplay( elem, 'block' ); 19109} 19110 19111function setDisplay( elem, value ) { 19112 if ( elem ) { 19113 elem.style.display = value; 19114 } 19115} 19116 19117// -------------------------- -------------------------- // 19118 19119return InfiniteScroll; 19120 19121})); 19122 19123 19124/***/ }), 19125/* 37 */ 19126/***/ (function(module, exports, __webpack_require__) { 19127 19128var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 19129 * selectize.js (v0.13.6) 19130 * Copyright (c) 2013â2015 Brian Reavis & contributors 19131 * Copyright (c) 2020-2022 Selectize Team & contributors 19132 * 19133 * Licensed under the Apache License, Version 2.0 (the "License");
19133 you may not use this 19134 * file except in compliance with the License. You may obtain a copy of the License at: 19135 * http://www.apache.org/licenses/LICENSE-2.0 19136 * 19137 * Unless required by applicable law or agreed to in writing, software distributed under 19138 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 19139 * ANY KIND, either express or implied. See the License for the specific language 19140 * governing permissions and limitations under the License. 19141 * 19142 * @author Brian Reavis <[email protected]> 19143 * @author Ris Adams <[email protected]> 19144 */ 19145 19146/*jshint curly:false */ 19147/*jshint browser:true */ 19148 19149(function(root, factory) { 19150 if (true) { 19151 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0),__webpack_require__(38),__webpack_require__(39)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 19152 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 19153 (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), 19154 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 19155 } else if (typeof module === 'object' && typeof module.exports === 'object') { 19156 module.exports = factory(require('jquery'), require('sifter'), require('microplugin')); 19157 } else { 19158 root.Selectize = factory(root.jQuery, root.Sifter, root.MicroPlugin); 19159 } 19160}(this, function($, Sifter, MicroPlugin) { 19161 'use strict'; 19162 19163 var highlight = function($element, pattern) { 19164 if (typeof pattern === 'string' && !pattern.length) return; 19165 var regex = (typeof pattern === 'string') ? new RegExp(pattern, 'i') : pattern; 19166 19167 var highlight = function(node) { 19168 var skip = 0; 19169 // Wrap matching part of text node with highlighting <span>, e.g. 19170 // Soccer -> <span class="highlight">Soc</span>cer for regex = /soc/i 19171 if (node.nodeType === 3) { 19172 var pos = node.data.search(regex); 19173 if (pos >= 0 && node.data.length > 0) { 19174 var match = node.data.match(regex); 19175 var spannode = document.createElement('span'); 19176 spannode.className = 'highlight'; 19177 var middlebit = node.splitText(pos); 19178 var endbit = middlebit.splitText(match[0].length); 19179 var middleclone = middlebit.cloneNode(true); 19180 spannode.appendChild(middleclone); 19181 middlebit.parentNode.replaceChild(spannode, middlebit); 19182 skip = 1; 19183 } 19184 } 19185 // Recurse element node, looking for child text nodes to highlight, unless element 19186 // is childless, <script>, <style>, or already highlighted: <span class="highlight"> 19187 else if (node.nodeType === 1 && node.childNodes && !/(script|style)/i.test(node.tagName) && ( node.className !== 'highlight' || node.tagName !== 'SPAN' )) { 19188 for (var i = 0; i < node.childNodes.length; ++i) { 19189 i += highlight(node.childNodes[i]); 19190 } 19191 } 19192 return skip; 19193 }; 19194 19195 return $element.each(function() { 19196 highlight(this); 19197 }); 19198 }; 19199 19200 /** 19201 * removeHighlight fn copied from highlight v5 and 19202 * edited to remove with() and pass js strict mode 19203 */ 19204 $.fn.removeHighlight = function() { 19205 return this.find("span.highlight").each(function() { 19206 this.parentNode.firstChild.nodeName; 19207 var parent = this.parentNode; 19208 parent.replaceChild(this.firstChild, this); 19209 parent.normalize(); 19210 }).end(); 19211 }; 19212 19213 19214 var MicroEvent = function() {}; 19215 MicroEvent.prototype = { 19216 on: function(event, fct){ 19217 this._events = this._events || {}; 19218 this._events[event] = this._events[event] || []; 19219 this._events[event].push(fct); 19220 }, 19221 off: function(event, fct){ 19222 var n = arguments.length; 19223 if (n === 0) return delete this._events; 19224 if (n === 1) return delete this._events[event]; 19225 19226 this._events = this._events || {}; 19227 if (event in this._events === false) return; 19228 this._events[event].splice(this._events[event].indexOf(fct), 1); 19229 }, 19230 trigger: function(event /* , args... */){ 19231 this._events = this._events || {}; 19232 if (event in this._events === false) return; 19233 for (var i = 0; i < this._events[event].length; i++){ 19234 this._events[event][i].apply(this, Array.prototype.slice.call(arguments, 1)); 19235 } 19236 } 19237 }; 19238 19239 /** 19240 * Mixin will delegate all MicroEvent.js function in the destination object. 19241 * 19242 * - MicroEvent.mixin(Foobar) will make Foobar able to use MicroEvent 19243 * 19244 * @param {object} the object which will support MicroEvent 19245 */ 19246 MicroEvent.mixin = function(destObject){ 19247 var props = ['on', 'off', 'trigger']; 19248 for (var i = 0; i < props.length; i++){ 19249 destObject.prototype[props[i]] = MicroEvent.prototype[props[i]]; 19250 } 19251 }; 19252 19253 function uaDetect(platform, re) { 19254 if (navigator.userAgentData) { 19255 return platform === navigator.userAgentData.platform; 19256 } 19257 19258 return re.test(navigator.userAgent); 19259 } 19260 19261 var IS_MAC = uaDetect("macOS", /Mac/); 19262 19263 var KEY_A = 65; 19264 var KEY_COMMA = 188; 19265 var KEY_RETURN = 13; 19266 var KEY_ESC = 27; 19267 var KEY_LEFT = 37; 19268 var KEY_UP = 38; 19269 var KEY_P = 80; 19270 var KEY_RIGHT = 39; 19271 var KEY_DOWN = 40; 19272 var KEY_N = 78; 19273 var KEY_BACKSPACE = 8; 19274 var KEY_DELETE = 46; 19275 var KEY_SHIFT = 16; 19276 var KEY_CMD = IS_MAC ? 91 : 17; 19277 var KEY_CTRL = IS_MAC ? 18 : 17; 19278 var KEY_TAB = 9; 19279 19280 var TAG_SELECT = 1; 19281 var TAG_INPUT = 2; 19282 19283 // for now, android support in general is too spotty to support validity 19284 var SUPPORTS_VALIDITY_API = !uaDetect("Android", /android/i
vendor: 4,206 bytes, lines 19284-19472
19284) && !!document.createElement('input').validity; 19285 19286 19287 var isset = function(object) { 19288 return typeof object !== 'undefined'; 19289 }; 19290 19291 /** 19292 * Converts a scalar to its best string representation 19293 * for hash keys and HTML attribute values. 19294 * 19295 * Transformations: 19296 * 'str' -> 'str' 19297 * null -> '' 19298 * undefined -> '' 19299 * true -> '1' 19300 * false -> '0' 19301 * 0 -> '0' 19302 * 1 -> '1' 19303 * 19304 * @param {string} value 19305 * @returns {string|null} 19306 */ 19307 var hash_key = function(value) { 19308 if (typeof value === 'undefined' || value === null) return null; 19309 if (typeof value === 'boolean') return value ? '1' : '0'; 19310 return value + ''; 19311 }; 19312 19313 /** 19314 * Escapes a string for use within HTML. 19315 * 19316 * @param {string} str 19317 * @returns {string} 19318 */ 19319 var escape_html = function(str) { 19320 return (str + '') 19321 .replace(/&/g, '&') 19322 .replace(/</g, '<') 19323 .replace(/>/g, '>') 19324 .replace(/"/g, '"'); 19325 }; 19326 19327 /** 19328 * Escapes "$" characters in replacement strings. 19329 * 19330 * @param {string} str 19331 * @returns {string} 19332 */ 19333 var escape_replace = function(str) { 19334 return (str + '').replace(/\$/g, '$$$$'); 19335 }; 19336 19337 var hook = {}; 19338 19339 /** 19340 * Wraps `method` on `self` so that `fn` 19341 * is invoked before the original method. 19342 * 19343 * @param {object} self 19344 * @param {string} method 19345 * @param {function} fn 19346 */ 19347 hook.before = function(self, method, fn) { 19348 var original = self[method]; 19349 self[method] = function() { 19350 fn.apply(self, arguments); 19351 return original.apply(self, arguments); 19352 }; 19353 }; 19354 19355 /** 19356 * Wraps `method` on `self` so that `fn` 19357 * is invoked after the original method. 19358 * 19359 * @param {object} self 19360 * @param {string} method 19361 * @param {function} fn 19362 */ 19363 hook.after = function(self, method, fn) { 19364 var original = self[method]; 19365 self[method] = function() { 19366 var result = original.apply(self, arguments); 19367 fn.apply(self, arguments); 19368 return result; 19369 }; 19370 }; 19371 19372 /** 19373 * Wraps `fn` so that it can only be invoked once. 19374 * 19375 * @param {function} fn 19376 * @returns {function} 19377 */ 19378 var once = function(fn) { 19379 var called = false; 19380 return function() { 19381 if (called) return; 19382 called = true; 19383 fn.apply(this, arguments); 19384 }; 19385 }; 19386 19387 /** 19388 * Wraps `fn` so that it can only be called once 19389 * every `delay` milliseconds (invoked on the falling edge). 19390 * 19391 * @param {function} fn 19392 * @param {int} delay 19393 * @returns {function} 19394 */ 19395 var debounce = function(fn, delay) { 19396 var timeout; 19397 return function() { 19398 var self = this; 19399 var args = arguments; 19400 window.clearTimeout(timeout); 19401 timeout = window.setTimeout(function() { 19402 fn.apply(self, args); 19403 }, delay); 19404 }; 19405 }; 19406 19407 /** 19408 * Debounce all fired events types listed in `types` 19409 * while executing the provided `fn`. 19410 * 19411 * @param {object} self 19412 * @param {array} types 19413 * @param {function} fn 19414 */ 19415 var debounce_events = function(self, types, fn) { 19416 var type; 19417 var trigger = self.trigger; 19418 var event_args = {}; 19419 19420 // override trigger method 19421 self.trigger = function() { 19422 var type = arguments[0]; 19423 if (types.indexOf(type) !== -1) { 19424 event_args[type] = arguments; 19425 } else { 19426 return trigger.apply(self, arguments); 19427 } 19428 }; 19429 19430 // invoke provided function 19431 fn.apply(self, []); 19432 self.trigger = trigger; 19433 19434 // trigger queued events 19435 for (type in event_args) { 19436 if (event_args.hasOwnProperty(type)) { 19437 trigger.apply(self, event_args[type]); 19438 } 19439 } 19440 }; 19441 19442 /** 19443 * A workaround for http://bugs.jquery.com/ticket/6696 19444 * 19445 * @param {object} $parent - Parent element to listen on. 19446 * @param {string} event - Event name. 19447 * @param {string} selector - Descendant selector to filter by. 19448 * @param {function} fn - Event handler. 19449 */ 19450 var watchChildEvent = function($parent, event, selector, fn) { 19451 $parent.on(event, selector, function(e) { 19452 var child = e.target; 19453 while (child && child.parentNode !== $parent[0]) { 19454 child = child.parentNode; 19455 } 19456 e.currentTarget = child; 19457 return fn.apply(this, [e]); 19458 }); 19459 }; 19460 19461 /** 19462 * Determines the current selection within a text input control. 19463 * Returns an object containing: 19464 * - start 19465 * - length 19466 * 19467 * @param {object} input 19468 * @returns {object} 19469 */ 19470 var getSelection = function(input) { 19471 var result = {}; 19472
vendor: 8,540 bytes, lines 19472-19779
19472 if(input === undefined) { 19473 console.warn('WARN getSelection cannot locate input control'); 19474 return result; 19475 } 19476 if ('selectionStart' in input) { 19477 result.start = input.selectionStart; 19478 result.length = input.selectionEnd - result.start; 19479 } else if (document.selection) { 19480 input.focus(); 19481 var sel = document.selection.createRange(); 19482 var selLen = document.selection.createRange().text.length; 19483 sel.moveStart('character', -input.value.length); 19484 result.start = sel.text.length - selLen; 19485 result.length = selLen; 19486 } 19487 return result; 19488 }; 19489 19490 /** 19491 * Copies CSS properties from one element to another. 19492 * 19493 * @param {object} $from 19494 * @param {object} $to 19495 * @param {array} properties 19496 */ 19497 var transferStyles = function($from, $to, properties) { 19498 var i, n, styles = {}; 19499 if (properties) { 19500 for (i = 0, n = properties.length; i < n; i++) { 19501 styles[properties[i]] = $from.css(properties[i]); 19502 } 19503 } else { 19504 styles = $from.css(); 19505 } 19506 $to.css(styles); 19507 }; 19508 19509 /** 19510 * Measures the width of a string within a 19511 * parent element (in pixels). 19512 * 19513 * @param {string} str 19514 * @param {object} $parent 19515 * @returns {int} 19516 */ 19517 var measureString = function(str, $parent) { 19518 if (!str) { 19519 return 0; 19520 } 19521 19522 if (!Selectize.$testInput) { 19523 Selectize.$testInput = $('<span />').css({ 19524 position: 'absolute', 19525 width: 'auto', 19526 padding: 0, 19527 whiteSpace: 'pre' 19528 }); 19529 19530 $('<div />').css({ 19531 position: 'absolute', 19532 width: 0, 19533 height: 0, 19534 overflow: 'hidden' 19535 }).append(Selectize.$testInput).appendTo('body'); 19536 } 19537 19538 Selectize.$testInput.text(str); 19539 19540 transferStyles($parent, Selectize.$testInput, [ 19541 'letterSpacing', 19542 'fontSize', 19543 'fontFamily', 19544 'fontWeight', 19545 'textTransform' 19546 ]); 19547 19548 return Selectize.$testInput.width(); 19549 }; 19550 19551 /** 19552 * Sets up an input to grow horizontally as the user 19553 * types. If the value is changed manually, you can 19554 * trigger the "update" handler to resize: 19555 * 19556 * $input.trigger('update'); 19557 * 19558 * @param {object} $input 19559 */ 19560 var autoGrow = function($input) { 19561 var currentWidth = null; 19562 19563 var update = function(e, options) { 19564 var value, keyCode, printable, width; 19565 var placeholder, placeholderWidth; 19566 var shift, character, selection; 19567 e = e || window.event || {}; 19568 options = options || {}; 19569 19570 if (e.metaKey || e.altKey) return; 19571 if (!options.force && $input.data('grow') === false) return; 19572 19573 value = $input.val(); 19574 if (e.type && e.type.toLowerCase() === 'keydown') { 19575 keyCode = e.keyCode; 19576 printable = ( 19577 (keyCode >= 48 && keyCode <= 57) || // 0-9 19578 (keyCode >= 65 && keyCode <= 90) || // a-z 19579 (keyCode >= 96 && keyCode <= 111) || // numpad 0-9, numeric operators 19580 (keyCode >= 186 && keyCode <= 222) || // semicolon, equal, comma, dash, etc. 19581 keyCode === 32 // space 19582 ); 19583 19584 if (keyCode === KEY_DELETE || keyCode === KEY_BACKSPACE) { 19585 selection = getSelection($input[0]); 19586 if (selection.length) { 19587 value = value.substring(0, selection.start) + value.substring(selection.start + selection.length); 19588 } else if (keyCode === KEY_BACKSPACE && selection.start) { 19589 value = value.substring(0, selection.start - 1) + value.substring(selection.start + 1); 19590 } else if (keyCode === KEY_DELETE && typeof selection.start !== 'undefined') { 19591 value = value.substring(0, selection.start) + value.substring(selection.start + 1); 19592 } 19593 } else if (printable) { 19594 shift = e.shiftKey; 19595 character = String.fromCharCode(e.keyCode); 19596 if (shift) character = character.toUpperCase(); 19597 else character = character.toLowerCase(); 19598 value += character; 19599 } 19600 } 19601 19602 placeholder = $input.attr('placeholder'); 19603 if (placeholder) { 19604 placeholderWidth = measureString(placeholder, $input) + 4; 19605 } else { 19606 placeholderWidth = 0; 19607 } 19608 19609 width = Math.max(measureString(value, $input), placeholderWidth) + 4; 19610 if (width !== currentWidth) { 19611 currentWidth = width; 19612 $input.width(width); 19613 $input.triggerHandler('resize'); 19614 } 19615 }; 19616 19617 $input.on('keydown keyup update blur', update); 19618 update(); 19619 }; 19620 19621 var domToString = function(d) { 19622 var tmp = document.createElement('div'); 19623 19624 tmp.appendChild(d.cloneNode(true)); 19625 19626 return tmp.innerHTML; 19627 }; 19628 19629 var logError = function(message, options){ 19630 if(!options) options = {}; 19631 var component = "Selectize"; 19632 19633 console.error(component + ": " + message) 19634 19635 if(options.explanation){ 19636 // console.group is undefined in <IE11 19637 if(console.group) console.group(); 19638 console.error(options.explanation); 19639 if(console.group) console.groupEnd(); 19640 } 19641 } 19642 19643 19644 var Selectize = function($input, settings) { 19645 var key, i, n, dir, input, self = this; 19646 input = $input[0]; 19647 input.selectize = self; 19648 19649 // detect rtl environment 19650 var computedStyle = window.getComputedStyle && window.getComputedStyle(input, null); 19651 dir = computedStyle ? computedStyle.getPropertyValue('direction') : input.currentStyle && input.currentStyle.direction; 19652 dir = dir || $input.parents('[dir]:first').attr('dir') || ''; 19653 19654 // setup default state 19655 $.extend(self, { 19656 order : 0, 19657 settings : settings, 19658 $input : $input, 19659 tabIndex : $input.attr('tabindex') || '', 19660 tagType : input.tagName.toLowerCase() === 'select' ? TAG_SELECT : TAG_INPUT, 19661 rtl : /rtl/i.test(dir), 19662 19663 eventNS : '.selectize' + (++Selectize.count), 19664 highlightedValue : null, 19665 isBlurring : false, 19666 isOpen : false, 19667 isDisabled : false, 19668 isRequired : $input.is('[required]'), 19669 isInvalid : false, 19670 isLocked : false, 19671 isFocused : false, 19672 isInputHidden : false, 19673 isSetup : false, 19674 isShiftDown : false, 19675 isCmdDown : false, 19676 isCtrlDown : false, 19677 ignoreFocus : false, 19678 ignoreBlur : false, 19679 ignoreHover : false, 19680 hasOptions : false, 19681 currentResults : null, 19682 lastValue : '', 19683 lastValidValue : '', 19684 caretPos : 0, 19685 loading : 0, 19686 loadedSearches : {}, 19687 19688 $activeOption : null, 19689 $activeItems : [], 19690 19691 optgroups : {}, 19692 options : {}, 19693 userOptions : {}, 19694 items : [], 19695 renderCache : {}, 19696 onSearchChange : settings.loadThrottle === null ? self.onSearchChange : debounce(self.onSearchChange, settings.loadThrottle) 19697 }); 19698 19699 // search system 19700 self.sifter = new Sifter(this.options, {diacritics: settings.diacritics}); 19701 19702 // build options table 19703 if (self.settings.options) { 19704 for (i = 0, n = self.settings.options.length; i < n; i++) { 19705 self.registerOption(self.settings.options[i]); 19706 } 19707 delete self.settings.options; 19708 } 19709 19710 // build optgroup table 19711 if (self.settings.optgroups) { 19712 for (i = 0, n = self.settings.optgroups.length; i < n; i++) { 19713 self.registerOptionGroup(self.settings.optgroups[i]); 19714 } 19715 delete self.settings.optgroups; 19716 } 19717 19718 // option-dependent defaults 19719 self.settings.mode = self.settings.mode || (self.settings.maxItems === 1 ? 'single' : 'multi'); 19720 if (typeof self.settings.hideSelected !== 'boolean') { 19721 self.settings.hideSelected = self.settings.mode === 'multi'; 19722 } 19723 19724 self.initializePlugins(self.settings.plugins); 19725 self.setupCallbacks(); 19726 self.setupTemplates(); 19727 self.setup(); 19728 }; 19729 19730 // mixins 19731 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 19732 19733 MicroEvent.mixin(Selectize); 19734 19735 if(typeof MicroPlugin !== "undefined"){ 19736 MicroPlugin.mixin(Selectize); 19737 }else{ 19738 logError("Dependency MicroPlugin is missing", 19739 {explanation: 19740 "Make sure you either: (1) are using the \"standalone\" "+ 19741 "version of Selectize, or (2) require MicroPlugin before you "+ 19742 "load Selectize."} 19743 ); 19744 } 19745 19746 19747 // methods 19748 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 19749 19750 $.extend(Selectize.prototype, { 19751 19752 /** 19753 * Creates all elements and sets up event bindings. 19754 */ 19755 setup: function() { 19756 var self = this; 19757 var settings = self.settings; 19758 var eventNS = self.eventNS; 19759 var $window = $(window); 19760 var $document = $(document); 19761 var $input = self.$input; 19762 19763 var $wrapper; 19764 var $control; 19765 var $control_input; 19766 var $dropdown; 19767 var $dropdown_content; 19768 var $dropdown_parent; 19769 var inputMode; 19770 var timeout_blur; 19771 var timeout_focus; 19772 var classes; 19773 var classes_plugins; 19774 var inputId; 19775 19776 inputMode = self.settings.mode; 19777 classes = $input.attr('class') || ''; 19778 19779 $wrapper = $('<div>
vendor: 18,854 bytes, lines 19779-20446
19779').addClass(settings.wrapperClass).addClass(classes).addClass(inputMode); 19780 $control = $('<div>').addClass(settings.inputClass).addClass('items').appendTo($wrapper); 19781 $control_input = $('<input type="text" autocomplete="new-password" autofill="no" />').appendTo($control).attr('tabindex', $input.is(':disabled') ? '-1' : self.tabIndex); 19782 $dropdown_parent = $(settings.dropdownParent || $wrapper); 19783 $dropdown = $('<div>').addClass(settings.dropdownClass).addClass(inputMode).hide().appendTo($dropdown_parent); 19784 $dropdown_content = $('<div>').addClass(settings.dropdownContentClass).attr('tabindex', '-1').appendTo($dropdown); 19785 19786 if(inputId = $input.attr('id')) { 19787 $control_input.attr('id', inputId + '-selectized'); 19788 $("label[for='"+inputId+"']").attr('for', inputId + '-selectized'); 19789 } 19790 19791 if(self.settings.copyClassesToDropdown) { 19792 $dropdown.addClass(classes); 19793 } 19794 19795 $wrapper.css({ 19796 width: $input[0].style.width 19797 }); 19798 19799 if (self.plugins.names.length) { 19800 classes_plugins = 'plugin-' + self.plugins.names.join(' plugin-'); 19801 $wrapper.addClass(classes_plugins); 19802 $dropdown.addClass(classes_plugins); 19803 } 19804 19805 if ((settings.maxItems === null || settings.maxItems > 1) && self.tagType === TAG_SELECT) { 19806 $input.attr('multiple', 'multiple'); 19807 } 19808 19809 if (self.settings.placeholder) { 19810 $control_input.attr('placeholder', settings.placeholder); 19811 } 19812 19813 // if splitOn was not passed in, construct it from the delimiter to allow pasting universally 19814 if (!self.settings.splitOn && self.settings.delimiter) { 19815 var delimiterEscaped = self.settings.delimiter.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); 19816 self.settings.splitOn = new RegExp('\\s*' + delimiterEscaped + '+\\s*'); 19817 } 19818 19819 if ($input.attr('autocorrect')) { 19820 $control_input.attr('autocorrect', $input.attr('autocorrect')); 19821 } 19822 19823 if ($input.attr('autocapitalize')) { 19824 $control_input.attr('autocapitalize', $input.attr('autocapitalize')); 19825 } 19826 if ($input.is('input')) { 19827 $control_input[0].type = $input[0].type; 19828 } 19829 19830 self.$wrapper = $wrapper; 19831 self.$control = $control; 19832 self.$control_input = $control_input; 19833 self.$dropdown = $dropdown; 19834 self.$dropdown_content = $dropdown_content; 19835 19836 $dropdown.on('mouseenter mousedown click', '[data-disabled]>[data-selectable]', function(e) { e.stopImmediatePropagation(); }); 19837 $dropdown.on('mouseenter', '[data-selectable]', function() { return self.onOptionHover.apply(self, arguments); }); 19838 $dropdown.on('mousedown click', '[data-selectable]', function() { return self.onOptionSelect.apply(self, arguments); }); 19839 watchChildEvent($control, 'mousedown', '*:not(input)', function() { return self.onItemSelect.apply(self, arguments); }); 19840 autoGrow($control_input); 19841 19842 $control.on({ 19843 mousedown : function() { return self.onMouseDown.apply(self, arguments); }, 19844 click : function() { return self.onClick.apply(self, arguments); } 19845 }); 19846 19847 $control_input.on({ 19848 mousedown : function(e) { e.stopPropagation(); }, 19849 keydown : function() { return self.onKeyDown.apply(self, arguments); }, 19850 keypress : function() { return self.onKeyPress.apply(self, arguments); }, 19851 input : function() { return self.onInput.apply(self, arguments); }, 19852 resize : function() { self.positionDropdown.apply(self, []); }, 19853 blur : function() { return self.onBlur.apply(self, arguments); }, 19854 focus : function() { self.ignoreBlur = false; return self.onFocus.apply(self, arguments); }, 19855 paste : function() { return self.onPaste.apply(self, arguments); } 19856 }); 19857 19858 $document.on('keydown' + eventNS, function(e) { 19859 self.isCmdDown = e[IS_MAC ? 'metaKey' : 'ctrlKey']; 19860 self.isCtrlDown = e[IS_MAC ? 'altKey' : 'ctrlKey']; 19861 self.isShiftDown = e.shiftKey; 19862 }); 19863 19864 $document.on('keyup' + eventNS, function(e) { 19865 if (e.keyCode === KEY_CTRL) self.isCtrlDown = false; 19866 if (e.keyCode === KEY_SHIFT) self.isShiftDown = false; 19867 if (e.keyCode === KEY_CMD) self.isCmdDown = false; 19868 }); 19869 19870 $document.on('mousedown' + eventNS, function(e) { 19871 if (self.isFocused) { 19872 // prevent events on the dropdown scrollbar from causing the control to blur 19873 if (e.target === self.$dropdown[0] || e.target.parentNode === self.$dropdown[0]) { 19874 return false; 19875 } 19876 // blur on click outside 19877 if (!self.$control.has(e.target).length && e.target !== self.$control[0]) { 19878 self.blur(e.target); 19879 } 19880 } 19881 }); 19882 19883 $window.on(['scroll' + eventNS, 'resize' + eventNS].join(' '), function() { 19884 if (self.isOpen) { 19885 self.positionDropdown.apply(self, arguments); 19886 } 19887 }); 19888 $window.on('mousemove' + eventNS, function() { 19889 self.ignoreHover = false; 19890 }); 19891 19892 // store original children and tab index so that they can be 19893 // restored when the destroy() method is called. 19894 this.revertSettings = { 19895 $children : $input.children().detach(), 19896 tabindex : $input.attr('tabindex') 19897 }; 19898 19899 $input.attr('tabindex', -1).hide().after(self.$wrapper); 19900 19901 if (Array.isArray(settings.items)) { 19902 self.lastValidValue = settings.items; 19903 self.setValue(settings.items); 19904 delete settings.items; 19905 } 19906 19907 // feature detect for the validation API 19908 if (SUPPORTS_VALIDITY_API) { 19909 $input.on('invalid' + eventNS, function(e) { 19910 e.preventDefault(); 19911 self.isInvalid = true; 19912 self.refreshState(); 19913 }); 19914 } 19915 19916 self.updateOriginalInput(); 19917 self.refreshItems(); 19918 self.refreshState(); 19919 self.updatePlaceholder(); 19920 self.isSetup = true; 19921 19922 if ($input.is(':disabled')) { 19923 self.disable(); 19924 } 19925 19926 self.on('change', this.onChange); 19927 19928 $input.data('selectize', self); 19929 $input.addClass('selectized'); 19930 self.trigger('initialize'); 19931 19932 // preload options 19933 if (settings.preload === true) { 19934 self.onSearchChange(''); 19935 } 19936 19937 }, 19938 19939 /** 19940 * Sets up default rendering functions. 19941 */ 19942 setupTemplates: function() { 19943 var self = this; 19944 var field_label = self.settings.labelField; 19945 var field_value = self.settings.valueField; 19946 var field_optgroup = self.settings.optgroupLabelField; 19947 19948 var templates = { 19949 'optgroup': function(data) { 19950 return '<div class="optgroup">' + data.html + '</div>'; 19951 }, 19952 'optgroup_header': function(data, escape) { 19953 return '<div class="optgroup-header">' + escape(data[field_optgroup]) + '</div>'; 19954 }, 19955 'option': function(data, escape) { 19956 return '<div class="option '+( data[field_value] === '' ? 'selectize-dropdown-emptyoptionlabel' : '')+'">' + escape(data[field_label]) + '</div>'; 19957 }, 19958 'item': function(data, escape) { 19959 return '<div class="item">' + escape(data[field_label]) + '</div>'; 19960 }, 19961 'option_create': function(data, escape) { 19962 return '<div class="create">Add <strong>' + escape(data.input) + '</strong>…</div>'; 19963 } 19964 }; 19965 19966 self.settings.render = $.extend({}, templates, self.settings.render); 19967 }, 19968 19969 /** 19970 * Maps fired events to callbacks provided 19971 * in the settings used when creating the control. 19972 */ 19973 setupCallbacks: function() { 19974 var key, fn, callbacks = { 19975 'initialize' : 'onInitialize', 19976 'change' : 'onChange', 19977 'item_add' : 'onItemAdd', 19978 'item_remove' : 'onItemRemove', 19979 'clear' : 'onClear', 19980 'option_add' : 'onOptionAdd', 19981 'option_remove' : 'onOptionRemove', 19982 'option_clear' : 'onOptionClear', 19983 'optgroup_add' : 'onOptionGroupAdd', 19984 'optgroup_remove' : 'onOptionGroupRemove', 19985 'optgroup_clear' : 'onOptionGroupClear', 19986 'dropdown_open' : 'onDropdownOpen', 19987 'dropdown_close' : 'onDropdownClose', 19988 'type' : 'onType', 19989 'load' : 'onLoad', 19990 'focus' : 'onFocus', 19991 'blur' : 'onBlur', 19992 'dropdown_item_activate' : 'onDropdownItemActivate', 19993 'dropdown_item_deactivate' : 'onDropdownItemDeactivate' 19994 }; 19995 19996 for (key in callbacks) { 19997 if (callbacks.hasOwnProperty(key)) { 19998 fn = this.settings[callbacks[key]]; 19999 if (fn) this.on(key, fn); 20000 } 20001 } 20002 }, 20003 20004 /** 20005 * Triggered when the main control element 20006 * has a click event. 20007 * 20008 * @param {object} e 20009 * @return {boolean} 20010 */ 20011 onClick: function(e) { 20012 var self = this; 20013 20014 // necessary for mobile webkit devices (manual focus triggering 20015 // is ignored unless invoked within a click event) 20016 // also necessary to reopen a dropdown that has been closed by 20017 // closeAfterSelect 20018 if (!self.isFocused || !self.isOpen) { 20019 self.focus(); 20020 e.preventDefault(); 20021 } 20022 }, 20023 20024 /** 20025 * Triggered when the main control element 20026 * has a mouse down event. 20027 * 20028 * @param {object} e 20029 * @return {boolean} 20030 */ 20031 onMouseDown: function(e) { 20032 var self = this; 20033 var defaultPrevented = e.isDefaultPrevented(); 20034 var $target = $(e.target); 20035 20036 if (self.isFocused) { 20037 // retain focus by preventing native handling. if the 20038 // event target is the input it should not be modified. 20039 // otherwise, text selection within the input won't work. 20040 if (e.target !== self.$control_input[0]) { 20041 if (self.settings.mode === 'single') { 20042 // toggle dropdown 20043 self.isOpen ? self.close() : self.open(); 20044 } else if (!defaultPrevented) { 20045 self.setActiveItem(null); 20046 } 20047 return false; 20048 } 20049 } else { 20050 // give control focus 20051 if (!defaultPrevented) { 20052 window.setTimeout(function() { 20053 self.focus(); 20054 }, 0); 20055 } 20056 } 20057 }, 20058 20059 /** 20060 * Triggered when the value of the control has been changed. 20061 * This should propagate the event to the original DOM 20062 * input / select element. 20063 */ 20064 onChange: function() { 20065 var self = this; 20066 if (self.getValue() !== "") { 20067 self.lastValidValue = self.getValue(); 20068 } 20069 this.$input.trigger('input'); 20070 this.$input.trigger('change'); 20071 }, 20072 20073 /** 20074 * Triggered on <input> paste. 20075 * 20076 * @param {object} e 20077 * @returns {boolean} 20078 */ 20079 onPaste: function(e) { 20080 var self = this; 20081 20082 if (self.isFull() || self.isInputHidden || self.isLocked) { 20083 e.preventDefault(); 20084 return; 20085 } 20086 20087 // If a regex or string is included, this will split the pasted 20088 // input and create Items for each separate value 20089 if (self.settings.splitOn) { 20090 20091 // Wait for pasted text to be recognized in value 20092 setTimeout(function() { 20093 var pastedText = self.$control_input.val(); 20094 if(!pastedText.match(self.settings.splitOn)){ return } 20095 20096 var splitInput = pastedText 20097 .trim() 20098 .split(self.settings.splitOn); 20099 for (var i = 0, n = splitInput.length; i < n; i++) { 20100 self.createItem(splitInput[i]); 20101 } 20102 }, 0); 20103 } 20104 }, 20105 20106 /** 20107 * Triggered on <input> keypress. 20108 * 20109 * @param {object} e 20110 * @returns {boolean} 20111 */ 20112 onKeyPress: function(e) { 20113 if (this.isLocked) return e && e.preventDefault(); 20114 var character = String.fromCharCode(e.keyCode || e.which); 20115 if (this.settings.create && this.settings.mode === 'multi' && character === this.settings.delimiter) { 20116 this.createItem(); 20117 e.preventDefault(); 20118 return false; 20119 } 20120 }, 20121 20122 /** 20123 * Triggered on <input> keydown. 20124 * 20125 * @param {object} e 20126 * @returns {boolean} 20127 */ 20128 onKeyDown: function(e) { 20129 var isInput = e.target === this.$control_input[0]; 20130 var self = this; 20131 20132 if (self.isLocked) { 20133 if (e.keyCode !== KEY_TAB) { 20134 e.preventDefault(); 20135 } 20136 return; 20137 } 20138 20139 switch (e.keyCode) { 20140 case KEY_A: 20141 if (self.isCmdDown) { 20142 self.selectAll(); 20143 return; 20144 } 20145 break; 20146 case KEY_ESC: 20147 if (self.isOpen) { 20148 e.preventDefault(); 20149 e.stopPropagation(); 20150 self.close(); 20151 } 20152 return; 20153 case KEY_N: 20154 if (!e.ctrlKey || e.altKey) break; 20155 case KEY_DOWN: 20156 if (!self.isOpen && self.hasOptions) { 20157 self.open(); 20158 } else if (self.$activeOption) { 20159 self.ignoreHover = true; 20160 var $next = self.getAdjacentOption(self.$activeOption, 1); 20161 if ($next.length) self.setActiveOption($next, true, true); 20162 } 20163 e.preventDefault(); 20164 return; 20165 case KEY_P: 20166 if (!e.ctrlKey || e.altKey) break; 20167 case KEY_UP: 20168 if (self.$activeOption) { 20169 self.ignoreHover = true; 20170 var $prev = self.getAdjacentOption(self.$activeOption, -1); 20171 if ($prev.length) self.setActiveOption($prev, true, true); 20172 } 20173 e.preventDefault(); 20174 return; 20175 case KEY_RETURN: 20176 if (self.isOpen && self.$activeOption) { 20177 self.onOptionSelect({currentTarget: self.$activeOption}); 20178 e.preventDefault(); 20179 } 20180 return; 20181 case KEY_LEFT: 20182 self.advanceSelection(-1, e); 20183 return; 20184 case KEY_RIGHT: 20185 self.advanceSelection(1, e); 20186 return; 20187 case KEY_TAB: 20188 if (self.settings.selectOnTab && self.isOpen && self.$activeOption) { 20189 self.onOptionSelect({currentTarget: self.$activeOption}); 20190 20191 // Default behaviour is to jump to the next field, we only want this 20192 // if the current field doesn't accept any more entries 20193 if (!self.isFull()) { 20194 e.preventDefault(); 20195 } 20196 } 20197 if (self.settings.create && self.createItem() && self.settings.showAddOptionOnCreate) { 20198 e.preventDefault(); 20199 } 20200 return; 20201 case KEY_BACKSPACE: 20202 case KEY_DELETE: 20203 self.deleteSelection(e); 20204 return; 20205 } 20206 20207 if ((self.isFull() || self.isInputHidden) && !(IS_MAC ? e.metaKey : e.ctrlKey)) { 20208 e.preventDefault(); 20209 return; 20210 } 20211 }, 20212 20213 /** 20214 * Triggered on <input> input. 20215 * 20216 * @param {object} e 20217 * @returns {boolean} 20218 */ 20219 onInput: function(e) { 20220 var self = this; 20221 20222 var value = self.$control_input.val() || ''; 20223 if (self.lastValue !== value) { 20224 self.lastValue = value; 20225 self.onSearchChange(value); 20226 self.refreshOptions(); 20227 self.trigger('type', value); 20228 } 20229 }, 20230 20231 /** 20232 * Invokes the user-provide option provider / loader. 20233 * 20234 * Note: this function is debounced in the Selectize 20235 * constructor (by `settings.loadThrottle` milliseconds) 20236 * 20237 * @param {string} value 20238 */ 20239 onSearchChange: function(value) { 20240 var self = this; 20241 var fn = self.settings.load; 20242 if (!fn) return; 20243 if (self.loadedSearches.hasOwnProperty(value)) return; 20244 self.loadedSearches[value] = true; 20245 self.load(function(callback) { 20246 fn.apply(self, [value, callback]); 20247 }); 20248 }, 20249 20250 /** 20251 * Triggered on <input> focus. 20252 * 20253 * @param {object} e (optional) 20254 * @returns {boolean} 20255 */ 20256 onFocus: function(e) { 20257 var self = this; 20258 var wasFocused = self.isFocused; 20259 20260 if (self.isDisabled) { 20261 self.blur(); 20262 e && e.preventDefault(); 20263 return false; 20264 } 20265 20266 if (self.ignoreFocus) return; 20267 self.isFocused = true; 20268 if (self.settings.preload === 'focus') self.onSearchChange(''); 20269 20270 if (!wasFocused) self.trigger('focus'); 20271 20272 if (!self.$activeItems.length) { 20273 self.showInput(); 20274 self.setActiveItem(null); 20275 self.refreshOptions(!!self.settings.openOnFocus); 20276 } 20277 20278 self.refreshState(); 20279 }, 20280 20281 /** 20282 * Triggered on <input> blur. 20283 * 20284 * @param {object} e 20285 * @param {Element} dest 20286 */ 20287 onBlur: function(e, dest) { 20288 var self = this; 20289 if (!self.isFocused) return; 20290 self.isFocused = false; 20291 20292 if (self.ignoreFocus) { 20293 return; 20294 } else if (!self.ignoreBlur && document.activeElement === self.$dropdown_content[0]) { 20295 // necessary to prevent IE closing the dropdown when the scrollbar is clicked 20296 self.ignoreBlur = true; 20297 self.onFocus(e); 20298 return; 20299 } 20300 20301 var deactivate = function() { 20302 self.close(); 20303 self.setTextboxValue(''); 20304 self.setActiveItem(null); 20305 self.setActiveOption(null); 20306 self.setCaret(self.items.length); 20307 self.refreshState(); 20308 20309 // IE11 bug: element still marked as active 20310 dest && dest.focus && dest.focus(); 20311 20312 self.isBlurring = false; 20313 self.ignoreFocus = false; 20314 self.trigger('blur'); 20315 }; 20316 20317 self.isBlurring = true; 20318 self.ignoreFocus = true; 20319 if (self.settings.create && self.settings.createOnBlur) { 20320 self.createItem(null, false, deactivate); 20321 } else { 20322 deactivate(); 20323 } 20324 }, 20325 20326 /** 20327 * Triggered when the user rolls over 20328 * an option in the autocomplete dropdown menu. 20329 * 20330 * @param {object} e 20331 * @returns {boolean} 20332 */ 20333 onOptionHover: function(e) { 20334 if (this.ignoreHover) return; 20335 this.setActiveOption(e.currentTarget, false); 20336 }, 20337 20338 /** 20339 * Triggered when the user clicks on an option 20340 * in the autocomplete dropdown menu. 20341 * 20342 * @param {object} e 20343 * @returns {boolean} 20344 */ 20345 onOptionSelect: function(e) { 20346 var value, $target, $option, self = this; 20347 20348 if (e.preventDefault) { 20349 e.preventDefault(); 20350 e.stopPropagation(); 20351 } 20352 20353 $target = $(e.currentTarget); 20354 if ($target.hasClass('create')) { 20355 self.createItem(null, function() { 20356 if (self.settings.closeAfterSelect) { 20357 self.close(); 20358 } 20359 }); 20360 } else { 20361 value = $target.attr('data-value'); 20362 if (typeof value !== 'undefined') { 20363 self.lastQuery = null; 20364 self.setTextboxValue(''); 20365 self.addItem(value); 20366 if (self.settings.closeAfterSelect) { 20367 self.close(); 20368 } else if (!self.settings.hideSelected && e.type && /mouse/.test(e.type)) { 20369 self.setActiveOption(self.getOption(value)); 20370 } 20371 } 20372 } 20373 }, 20374 20375 /** 20376 * Triggered when the user clicks on an item 20377 * that has been selected. 20378 * 20379 * @param {object} e 20380 * @returns {boolean} 20381 */ 20382 onItemSelect: function(e) { 20383 var self = this; 20384 20385 if (self.isLocked) return; 20386 if (self.settings.mode === 'multi') { 20387 e.preventDefault(); 20388 self.setActiveItem(e.currentTarget, e); 20389 } 20390 }, 20391 20392 /** 20393 * Invokes the provided method that provides 20394 * results to a callback---which are then added 20395 * as options to the control. 20396 * 20397 * @param {function} fn 20398 */ 20399 load: function(fn) { 20400 var self = this; 20401 var $wrapper = self.$wrapper.addClass(self.settings.loadingClass); 20402 20403 self.loading++; 20404 fn.apply(self, [function(results) { 20405 self.loading = Math.max(self.loading - 1, 0); 20406 if (results && results.length) { 20407 self.addOption(results); 20408 self.refreshOptions(self.isFocused && !self.isInputHidden); 20409 } 20410 if (!self.loading) { 20411 $wrapper.removeClass(self.settings.loadingClass); 20412 } 20413 self.trigger('load', results); 20414 }]); 20415 }, 20416 20417 /** 20418 * Gets the value of input field of the control. 20419 * 20420 * @returns {string} value 20421 */ 20422 getTextboxValue: function() { 20423 var $input = this.$control_input; 20424 return $input.val(); 20425 }, 20426 20427 /** 20428 * Sets the input field of the control to the specified value. 20429 * 20430 * @param {string} value 20431 */ 20432 setTextboxValue: function(value) { 20433 var $input = this.$control_input; 20434 var changed = $input.val() !== value; 20435 if (changed) { 20436 $input.val(value).triggerHandler('update'); 20437 this.lastValue = value; 20438 } 20439 }, 20440 20441 /** 20442 * Returns the value of the control. If multiple items 20443 * can be selected (e.g. <select multiple>), this returns 20444 * an array. If only one item can be selected, this 20445 * returns a string. 20446 *
vendor: 27,147 bytes, lines 20447-21434
20447 * @returns {mixed} 20448 */ 20449 getValue: function() { 20450 if (this.tagType === TAG_SELECT && this.$input.attr('multiple')) { 20451 return this.items; 20452 } else { 20453 return this.items.join(this.settings.delimiter); 20454 } 20455 }, 20456 20457 /** 20458 * Resets the selected items to the given value. 20459 * 20460 * @param {mixed} value 20461 */ 20462 setValue: function(value, silent) { 20463 var events = silent ? [] : ['change']; 20464 20465 debounce_events(this, events, function() { 20466 this.clear(silent); 20467 this.addItems(value, silent); 20468 }); 20469 }, 20470 20471 /** 20472 * Resets the number of max items to the given value 20473 * 20474 * @param {number} value 20475 */ 20476 setMaxItems: function(value){ 20477 if(value === 0) value = null; //reset to unlimited items. 20478 this.settings.maxItems = value; 20479 this.settings.mode = this.settings.mode || (this.settings.maxItems === 1 ? 'single' : 'multi'); 20480 this.refreshState(); 20481 }, 20482 20483 /** 20484 * Sets the selected item. 20485 * 20486 * @param {object} $item 20487 * @param {object} e (optional) 20488 */ 20489 setActiveItem: function($item, e) { 20490 var self = this; 20491 var eventName; 20492 var i, idx, begin, end, item, swap; 20493 var $last; 20494 20495 if (self.settings.mode === 'single') return; 20496 $item = $($item); 20497 20498 // clear the active selection 20499 if (!$item.length) { 20500 $(self.$activeItems).removeClass('active'); 20501 self.$activeItems = []; 20502 if (self.isFocused) { 20503 self.showInput(); 20504 } 20505 return; 20506 } 20507 20508 // modify selection 20509 eventName = e && e.type.toLowerCase(); 20510 20511 if (eventName === 'mousedown' && self.isShiftDown && self.$activeItems.length) { 20512 $last = self.$control.children('.active:last'); 20513 begin = Array.prototype.indexOf.apply(self.$control[0].childNodes, [$last[0]]); 20514 end = Array.prototype.indexOf.apply(self.$control[0].childNodes, [$item[0]]); 20515 if (begin > end) { 20516 swap = begin; 20517 begin = end; 20518 end = swap; 20519 } 20520 for (i = begin; i <= end; i++) { 20521 item = self.$control[0].childNodes[i]; 20522 if (self.$activeItems.indexOf(item) === -1) { 20523 $(item).addClass('active'); 20524 self.$activeItems.push(item); 20525 } 20526 } 20527 e.preventDefault(); 20528 } else if ((eventName === 'mousedown' && self.isCtrlDown) || (eventName === 'keydown' && this.isShiftDown)) { 20529 if ($item.hasClass('active')) { 20530 idx = self.$activeItems.indexOf($item[0]); 20531 self.$activeItems.splice(idx, 1); 20532 $item.removeClass('active'); 20533 } else { 20534 self.$activeItems.push($item.addClass('active')[0]); 20535 } 20536 } else { 20537 $(self.$activeItems).removeClass('active'); 20538 self.$activeItems = [$item.addClass('active')[0]]; 20539 } 20540 20541 // ensure control has focus 20542 self.hideInput(); 20543 if (!this.isFocused) { 20544 self.focus(); 20545 } 20546 }, 20547 20548 /** 20549 * Sets the selected item in the dropdown menu 20550 * of available options. 20551 * 20552 * @param {object} $object 20553 * @param {boolean} scroll 20554 * @param {boolean} animate 20555 */ 20556 setActiveOption: function($option, scroll, animate) { 20557 var height_menu, height_item, y; 20558 var scroll_top, scroll_bottom; 20559 var self = this; 20560 20561 if (self.$activeOption) { 20562 self.$activeOption.removeClass('active'); 20563 self.trigger('dropdown_item_deactivate', self.$activeOption.attr('data-value')); 20564 } 20565 self.$activeOption = null; 20566 20567 $option = $($option); 20568 if (!$option.length) return; 20569 20570 self.$activeOption = $option.addClass('active'); 20571 if (self.isOpen) self.trigger('dropdown_item_activate', self.$activeOption.attr('data-value')); 20572 20573 if (scroll || !isset(scroll)) { 20574 20575 height_menu = self.$dropdown_content.height(); 20576 height_item = self.$activeOption.outerHeight(true); 20577 scroll = self.$dropdown_content.scrollTop() || 0; 20578 y = self.$activeOption.offset().top - self.$dropdown_content.offset().top + scroll; 20579 scroll_top = y; 20580 scroll_bottom = y - height_menu + height_item; 20581 20582 if (y + height_item > height_menu + scroll) { 20583 self.$dropdown_content.stop().animate({scrollTop: scroll_bottom}, animate ? self.settings.scrollDuration : 0); 20584 } else if (y < scroll) { 20585 self.$dropdown_content.stop().animate({scrollTop: scroll_top}, animate ? self.settings.scrollDuration : 0); 20586 } 20587 20588 } 20589 }, 20590 20591 /** 20592 * Selects all items (CTRL + A). 20593 */ 20594 selectAll: function() { 20595 var self = this; 20596 if (self.settings.mode === 'single') return; 20597 20598 self.$activeItems = Array.prototype.slice.apply(self.$control.children(':not(input)').addClass('active')); 20599 if (self.$activeItems.length) { 20600 self.hideInput(); 20601 self.close(); 20602 } 20603 self.focus(); 20604 }, 20605 20606 /** 20607 * Hides the input element out of view, while 20608 * retaining its focus. 20609 */ 20610 hideInput: function() { 20611 var self = this; 20612 20613 self.setTextboxValue(''); 20614 self.$control_input.css({opacity: 0, position: 'absolute', left: self.rtl ? 10000 : -10000}); 20615 self.isInputHidden = true; 20616 }, 20617 20618 /** 20619 * Restores input visibility. 20620 */ 20621 showInput: function() { 20622 this.$control_input.css({opacity: 1, position: 'relative', left: 0}); 20623 this.isInputHidden = false; 20624 }, 20625 20626 /** 20627 * Gives the control focus. 20628 */ 20629 focus: function() { 20630 var self = this; 20631 if (self.isDisabled) return self; 20632 20633 self.ignoreFocus = true; 20634 self.$control_input[0].focus(); 20635 window.setTimeout(function() { 20636 self.ignoreFocus = false; 20637 self.onFocus(); 20638 }, 0); 20639 return self; 20640 }, 20641 20642 /** 20643 * Forces the control out of focus. 20644 * 20645 * @param {Element} dest 20646 */ 20647 blur: function(dest) { 20648 this.$control_input[0].blur(); 20649 this.onBlur(null, dest); 20650 return this; 20651 }, 20652 20653 /** 20654 * Returns a function that scores an object 20655 * to show how good of a match it is to the 20656 * provided query. 20657 * 20658 * @param {string} query 20659 * @param {object} options 20660 * @return {function} 20661 */ 20662 getScoreFunction: function(query) { 20663 return this.sifter.getScoreFunction(query, this.getSearchOptions()); 20664 }, 20665 20666 /** 20667 * Returns search options for sifter (the system 20668 * for scoring and sorting results). 20669 * 20670 * @see https://github.com/brianreavis/sifter.js 20671 * @return {object} 20672 */ 20673 getSearchOptions: function() { 20674 var settings = this.settings; 20675 var sort = settings.sortField; 20676 if (typeof sort === 'string') { 20677 sort = [{field: sort}]; 20678 } 20679 20680 return { 20681 fields : settings.searchField, 20682 conjunction : settings.searchConjunction, 20683 sort : sort, 20684 nesting : settings.nesting 20685 }; 20686 }, 20687 20688 /** 20689 * Searches through available options and returns 20690 * a sorted array of matches. 20691 * 20692 * Returns an object containing: 20693 * 20694 * - query {string} 20695 * - tokens {array} 20696 * - total {int} 20697 * - items {array} 20698 * 20699 * @param {string} query 20700 * @returns {object} 20701 */ 20702 search: function(query) { 20703 var i, value, score, result, calculateScore; 20704 var self = this; 20705 var settings = self.settings; 20706 var options = this.getSearchOptions(); 20707 20708 // validate user-provided result scoring function 20709 if (settings.score) { 20710 calculateScore = self.settings.score.apply(this, [query]); 20711 if (typeof calculateScore !== 'function') { 20712 throw new Error('Selectize "score" setting must be a function that returns a function'); 20713 } 20714 } 20715 20716 // perform search 20717 if (query !== self.lastQuery) { 20718 self.lastQuery = query; 20719 result = self.sifter.search(query, $.extend(options, {score: calculateScore})); 20720 self.currentResults = result; 20721 } else { 20722 result = $.extend(true, {}, self.currentResults); 20723 } 20724 20725 // filter out selected items 20726 if (settings.hideSelected) { 20727 for (i = result.items.length - 1; i >= 0; i--) { 20728 if (self.items.indexOf(hash_key(result.items[i].id)) !== -1) { 20729 result.items.splice(i, 1); 20730 } 20731 } 20732 } 20733 20734 return result; 20735 }, 20736 20737 /** 20738 * Refreshes the list of available options shown 20739 * in the autocomplete dropdown menu. 20740 * 20741 * @param {boolean} triggerDropdown 20742 */ 20743 refreshOptions: function(triggerDropdown) { 20744 var i, j, k, n, groups, groups_order, option, option_html, optgroup, optgroups, html, html_children, has_create_option; 20745 var $active, $active_before, $create; 20746 20747 if (typeof triggerDropdown === 'undefined') { 20748 triggerDropdown = true; 20749 } 20750 20751 var self = this; 20752 var query = (self.$control_input.val()).trim(); 20753 var results = self.search(query); 20754 var $dropdown_content = self.$dropdown_content; 20755 var active_before = self.$activeOption && hash_key(self.$activeOption.attr('data-value')); 20756 20757 // build markup 20758 n = results.items.length; 20759 if (typeof self.settings.maxOptions === 'number') { 20760 n = Math.min(n, self.settings.maxOptions); 20761 } 20762 20763 // render and group available options individually 20764 groups = {}; 20765 groups_order = []; 20766 20767 for (i = 0; i < n; i++) { 20768 option = self.options[results.items[i].id]; 20769 option_html = self.render('option', option); 20770 optgroup = option[self.settings.optgroupField] || ''; 20771 optgroups = Array.isArray(optgroup) ? optgroup : [optgroup]; 20772 20773 for (j = 0, k = optgroups && optgroups.length; j < k; j++) { 20774 optgroup = optgroups[j]; 20775 if (!self.optgroups.hasOwnProperty(optgroup)) { 20776 optgroup = ''; 20777 } 20778 if (!groups.hasOwnProperty(optgroup)) { 20779 groups[optgroup] = document.createDocumentFragment(); 20780 groups_order.push(optgroup); 20781 } 20782 groups[optgroup].appendChild(option_html); 20783 } 20784 } 20785 20786 // sort optgroups 20787 if (this.settings.lockOptgroupOrder) { 20788 groups_order.sort(function(a, b) { 20789 var a_order = self.optgroups[a] && self.optgroups[a].$order || 0; 20790 var b_order = self.optgroups[b] && self.optgroups[b].$order || 0; 20791 return a_order - b_order; 20792 }); 20793 } 20794 20795 // render optgroup headers & join groups 20796 html = document.createDocumentFragment(); 20797 for (i = 0, n = groups_order.length; i < n; i++) { 20798 optgroup = groups_order[i]; 20799 if (self.optgroups.hasOwnProperty(optgroup) && groups[optgroup].childNodes.length) { 20800 // render the optgroup header and options within it, 20801 // then pass it to the wrapper template 20802 html_children = document.createDocumentFragment(); 20803 html_children.appendChild(self.render('optgroup_header', self.optgroups[optgroup])); 20804 html_children.appendChild(groups[optgroup]); 20805 20806 html.appendChild(self.render('optgroup', $.extend({}, self.optgroups[optgroup], { 20807 html: domToString(html_children), 20808 dom: html_children 20809 }))); 20810 } else { 20811 html.appendChild(groups[optgroup]); 20812 } 20813 } 20814 20815 $dropdown_content.html(html); 20816 20817 // highlight matching terms inline 20818 if (self.settings.highlight) { 20819 $dropdown_content.removeHighlight(); 20820 if (results.query.length && results.tokens.length) { 20821 for (i = 0, n = results.tokens.length; i < n; i++) { 20822 highlight($dropdown_content, results.tokens[i].regex); 20823 } 20824 } 20825 } 20826 20827 // add "selected" class to selected options 20828 if (!self.settings.hideSelected) { 20829 // clear selection on all previously selected elements first 20830 self.$dropdown.find('.selected').removeClass('selected'); 20831 20832 for (i = 0, n = self.items.length; i < n; i++) { 20833 self.getOption(self.items[i]).addClass('selected'); 20834 } 20835 } 20836 20837 // add create option 20838 has_create_option = self.canCreate(query); 20839 if (has_create_option) { 20840 if(self.settings.showAddOptionOnCreate) { 20841 $dropdown_content.prepend(self.render('option_create', {input: query})); 20842 $create = $($dropdown_content[0].childNodes[0]); 20843 } 20844 } 20845 20846 // activate 20847 self.hasOptions = results.items.length > 0 || ( has_create_option && self.settings.showAddOptionOnCreate ); 20848 if (self.hasOptions) { 20849 if (results.items.length > 0) { 20850 $active_before = active_before && self.getOption(active_before); 20851 if (results.query !== "" && $active_before && $active_before.length) { 20852 $active = $active_before; 20853 } else if (self.settings.mode === 'single' && self.items.length) { 20854 $active = self.getOption(self.items[0]); 20855 } 20856 if (!$active || !$active.length) { 20857 if ($create && !self.settings.addPrecedence) { 20858 $active = self.getAdjacentOption($create, 1); 20859 } else { 20860 $active = $dropdown_content.find('[data-selectable]:first'); 20861 } 20862 } 20863 } else { 20864 $active = $create; 20865 } 20866 self.setActiveOption($active); 20867 if (triggerDropdown && !self.isOpen) { self.open(); } 20868 } else { 20869 self.setActiveOption(null); 20870 if (triggerDropdown && self.isOpen) { self.close(); } 20871 } 20872 }, 20873 20874 /** 20875 * Adds an available option. If it already exists, 20876 * nothing will happen. Note: this does not refresh 20877 * the options list dropdown (use `refreshOptions` 20878 * for that). 20879 * 20880 * Usage: 20881 * 20882 * this.addOption(data) 20883 * 20884 * @param {object|array} data 20885 */ 20886 addOption: function(data) { 20887 var i, n, value, self = this; 20888 20889 if (Array.isArray(data)) { 20890 for (i = 0, n = data.length; i < n; i++) { 20891 self.addOption(data[i]); 20892 } 20893 return; 20894 } 20895 20896 if (value = self.registerOption(data)) { 20897 self.userOptions[value] = true; 20898 self.lastQuery = null; 20899 self.trigger('option_add', value, data); 20900 } 20901 }, 20902 20903 /** 20904 * Registers an option to the pool of options. 20905 * 20906 * @param {object} data 20907 * @return {boolean|string} 20908 */ 20909 registerOption: function(data) { 20910 var key = hash_key(data[this.settings.valueField]); 20911 if (typeof key === 'undefined' || key === null || this.options.hasOwnProperty(key)) return false; 20912 data.$order = data.$order || ++this.order; 20913 this.options[key] = data; 20914 return key; 20915 }, 20916 20917 /** 20918 * Registers an option group to the pool of option groups. 20919 * 20920 * @param {object} data 20921 * @return {boolean|string} 20922 */ 20923 registerOptionGroup: function(data) { 20924 var key = hash_key(data[this.settings.optgroupValueField]); 20925 if (!key) return false; 20926 20927 data.$order = data.$order || ++this.order; 20928 this.optgroups[key] = data; 20929 return key; 20930 }, 20931 20932 /** 20933 * Registers a new optgroup for options 20934 * to be bucketed into. 20935 * 20936 * @param {string} id 20937 * @param {object} data 20938 */ 20939 addOptionGroup: function(id, data) { 20940 data[this.settings.optgroupValueField] = id; 20941 if (id = this.registerOptionGroup(data)) { 20942 this.trigger('optgroup_add', id, data); 20943 } 20944 }, 20945 20946 /** 20947 * Removes an existing option group. 20948 * 20949 * @param {string} id 20950 */ 20951 removeOptionGroup: function(id) { 20952 if (this.optgroups.hasOwnProperty(id)) { 20953 delete this.optgroups[id]; 20954 this.renderCache = {}; 20955 this.trigger('optgroup_remove', id); 20956 } 20957 }, 20958 20959 /** 20960 * Clears all existing option groups. 20961 */ 20962 clearOptionGroups: function() { 20963 this.optgroups = {}; 20964 this.renderCache = {}; 20965 this.trigger('optgroup_clear'); 20966 }, 20967 20968 /** 20969 * Updates an option available for selection. If 20970 * it is visible in the selected items or options 20971 * dropdown, it will be re-rendered automatically. 20972 * 20973 * @param {string} value 20974 * @param {object} data 20975 */ 20976 updateOption: function(value, data) { 20977 var self = this; 20978 var $item, $item_new; 20979 var value_new, index_item, cache_items, cache_options, order_old; 20980 20981 value = hash_key(value); 20982 value_new = hash_key(data[self.settings.valueField]); 20983 20984 // sanity checks 20985 if (value === null) return; 20986 if (!self.options.hasOwnProperty(value)) return; 20987 if (typeof value_new !== 'string') throw new Error('Value must be set in option data'); 20988 20989 order_old = self.options[value].$order; 20990 20991 // update references 20992 if (value_new !== value) { 20993 delete self.options[value]; 20994 index_item = self.items.indexOf(value); 20995 if (index_item !== -1) { 20996 self.items.splice(index_item, 1, value_new); 20997 } 20998 } 20999 data.$order = data.$order || order_old; 21000 self.options[value_new] = data; 21001 21002 // invalidate render cache 21003 cache_items = self.renderCache['item']; 21004 cache_options = self.renderCache['option']; 21005 21006 if (cache_items) { 21007 delete cache_items[value]; 21008 delete cache_items[value_new]; 21009 } 21010 if (cache_options) { 21011 delete cache_options[value]; 21012 delete cache_options[value_new]; 21013 } 21014 21015 // update the item if it's selected 21016 if (self.items.indexOf(value_new) !== -1) { 21017 $item = self.getItem(value); 21018 $item_new = $(self.render('item', data)); 21019 if ($item.hasClass('active')) $item_new.addClass('active'); 21020 $item.replaceWith($item_new); 21021 } 21022 21023 // invalidate last query because we might have updated the sortField 21024 self.lastQuery = null; 21025 21026 // update dropdown contents 21027 if (self.isOpen) { 21028 self.refreshOptions(false); 21029 } 21030 }, 21031 21032 /** 21033 * Removes a single option. 21034 * 21035 * @param {string} value 21036 * @param {boolean} silent 21037 */ 21038 removeOption: function(value, silent) { 21039 var self = this; 21040 value = hash_key(value); 21041 21042 var cache_items = self.renderCache['item']; 21043 var cache_options = self.renderCache['option']; 21044 if (cache_items) delete cache_items[value]; 21045 if (cache_options) delete cache_options[value]; 21046 21047 delete self.userOptions[value]; 21048 delete self.options[value]; 21049 self.lastQuery = null; 21050 self.trigger('option_remove', value); 21051 self.removeItem(value, silent); 21052 }, 21053 21054 /** 21055 * Clears all options. 21056 * 21057 * @param {boolean} silent 21058 */ 21059 clearOptions: function(silent) { 21060 var self = this; 21061 21062 self.loadedSearches = {}; 21063 self.userOptions = {}; 21064 self.renderCache = {}; 21065 var options = self.options; 21066 $.each(self.options, function(key, value) { 21067 if(self.items.indexOf(key) == -1) { 21068 delete options[key]; 21069 } 21070 }); 21071 self.options = self.sifter.items = options; 21072 self.lastQuery = null; 21073 self.trigger('option_clear'); 21074 self.clear(silent); 21075 }, 21076 21077 /** 21078 * Returns the jQuery element of the option 21079 * matching the given value. 21080 * 21081 * @param {string} value 21082 * @returns {object} 21083 */ 21084 getOption: function(value) { 21085 return this.getElementWithValue(value, this.$dropdown_content.find('[data-selectable]')); 21086 }, 21087 21088 /** 21089 * Returns the jQuery element of the first 21090 * selectable option. 21091 * 21092 * @return {object} 21093 */ 21094 getFirstOption: function() { 21095 var $options = this.$dropdown.find('[data-selectable]'); 21096 return $options.length > 0 ? $options.eq(0) : $(); 21097 }, 21098 21099 /** 21100 * Returns the jQuery element of the next or 21101 * previous selectable option. 21102 * 21103 * @param {object} $option 21104 * @param {int} direction can be 1 for next or -1 for previous 21105 * @return {object} 21106 */ 21107 getAdjacentOption: function($option, direction) { 21108 var $options = this.$dropdown.find('[data-selectable]'); 21109 var index = $options.index($option) + direction; 21110 21111 return index >= 0 && index < $options.length ? $options.eq(index) : $(); 21112 }, 21113 21114 /** 21115 * Finds the first element with a "data-value" attribute 21116 * that matches the given value. 21117 * 21118 * @param {mixed} value 21119 * @param {object} $els 21120 * @return {object} 21121 */ 21122 getElementWithValue: function(value, $els) { 21123 value = hash_key(value); 21124 21125 if (typeof value !== 'undefined' && value !== null) { 21126 for (var i = 0, n = $els.length; i < n; i++) { 21127 if ($els[i].getAttribute('data-value') === value) { 21128 return $($els[i]); 21129 } 21130 } 21131 } 21132 21133 return $(); 21134 }, 21135 21136 /** 21137 * Finds the first element with a "textContent" property 21138 * that matches the given textContent value. 21139 * 21140 * @param {mixed} textContent 21141 * @param {boolean} ignoreCase 21142 * @param {object} $els 21143 * @return {object} 21144 */ 21145 getElementWithTextContent: function(textContent, ignoreCase ,$els) { 21146 textContent = hash_key(textContent); 21147 21148 if (typeof textContent !== 'undefined' && textContent !== null) { 21149 for (var i = 0, n = $els.length; i < n; i++) { 21150 var eleTextContent = $els[i].textContent 21151 if (ignoreCase == true) { 21152 eleTextContent = (eleTextContent !== null) ? eleTextContent.toLowerCase() : null; 21153 textContent = textContent.toLowerCase(); 21154 } 21155 if (eleTextContent === textContent) { 21156 return $($els[i]); 21157 } 21158 } 21159 } 21160 21161 return $(); 21162 }, 21163 21164 /** 21165 * Returns the jQuery element of the item 21166 * matching the given value. 21167 * 21168 * @param {string} value 21169 * @returns {object} 21170 */ 21171 getItem: function(value) { 21172 return this.getElementWithValue(value, this.$control.children()); 21173 }, 21174 21175 /** 21176 * Returns the jQuery element of the item 21177 * matching the given textContent. 21178 * 21179 * @param {string} value 21180 * @param {boolean} ignoreCase 21181 * @returns {object} 21182 */ 21183 getFirstItemMatchedByTextContent: function(textContent, ignoreCase) { 21184 ignoreCase = (ignoreCase !== null && ignoreCase === true) ? true : false; 21185 return this.getElementWithTextContent(textContent, ignoreCase, this.$dropdown_content.find('[data-selectable]')); 21186 }, 21187 21188 /** 21189 * "Selects" multiple items at once. Adds them to the list 21190 * at the current caret position. 21191 * 21192 * @param {string} value 21193 * @param {boolean} silent 21194 */ 21195 addItems: function(values, silent) { 21196 this.buffer = document.createDocumentFragment(); 21197 21198 var childNodes = this.$control[0].childNodes; 21199 for (var i = 0; i < childNodes.length; i++) { 21200 this.buffer.appendChild(childNodes[i]); 21201 } 21202 21203 var items = Array.isArray(values) ? values : [values]; 21204 for (var i = 0, n = items.length; i < n; i++) { 21205 this.isPending = (i < n - 1); 21206 this.addItem(items[i], silent); 21207 } 21208 21209 var control = this.$control[0]; 21210 control.insertBefore(this.buffer, control.firstChild); 21211 21212 this.buffer = null; 21213 }, 21214 21215 /** 21216 * "Selects" an item. Adds it to the list 21217 * at the current caret position. 21218 * 21219 * @param {string} value 21220 * @param {boolean} silent 21221 */ 21222 addItem: function(value, silent) { 21223 var events = silent ? [] : ['change']; 21224 21225 debounce_events(this, events, function() { 21226 var $item, $option, $options; 21227 var self = this; 21228 var inputMode = self.settings.mode; 21229 var i, active, value_next, wasFull; 21230 value = hash_key(value); 21231 21232 if (self.items.indexOf(value) !== -1) { 21233 if (inputMode === 'single') self.close(); 21234 return; 21235 } 21236 21237 if (!self.options.hasOwnProperty(value)) return; 21238 if (inputMode === 'single') self.clear(silent); 21239 if (inputMode === 'multi' && self.isFull()) return; 21240 21241 $item = $(self.render('item', self.options[value])); 21242 wasFull = self.isFull(); 21243 self.items.splice(self.caretPos, 0, value); 21244 self.insertAtCaret($item); 21245 if (!self.isPending || (!wasFull && self.isFull())) { 21246 self.refreshState(); 21247 } 21248 21249 if (self.isSetup) { 21250 $options = self.$dropdown_content.find('[data-selectable]'); 21251 21252 // update menu / remove the option (if this is not one item being added as part of series) 21253 if (!self.isPending) { 21254 $option = self.getOption(value); 21255 value_next = self.getAdjacentOption($option, 1).attr('data-value'); 21256 self.refreshOptions(self.isFocused && inputMode !== 'single'); 21257 if (value_next) { 21258 self.setActiveOption(self.getOption(value_next)); 21259 } 21260 } 21261 21262 // hide the menu if the maximum number of items have been selected or no options are left 21263 if (!$options.length || self.isFull()) { 21264 self.close(); 21265 } else if (!self.isPending) { 21266 self.positionDropdown(); 21267 } 21268 21269 self.updatePlaceholder(); 21270 self.trigger('item_add', value, $item); 21271 21272 if (!self.isPending) { 21273 self.updateOriginalInput({silent: silent}); 21274 } 21275 } 21276 }); 21277 }, 21278 21279 /** 21280 * Removes the selected item matching 21281 * the provided value. 21282 * 21283 * @param {string} value 21284 */ 21285 removeItem: function(value, silent) { 21286 var self = this; 21287 var $item, i, idx; 21288 21289 $item = (value instanceof $) ? value : self.getItem(value); 21290 value = hash_key($item.attr('data-value')); 21291 i = self.items.indexOf(value); 21292 21293 if (i !== -1) { 21294 self.trigger('item_before_remove', value, $item); 21295 $item.remove(); 21296 if ($item.hasClass('active')) { 21297 idx = self.$activeItems.indexOf($item[0]); 21298 self.$activeItems.splice(idx, 1); 21299 } 21300 21301 self.items.splice(i, 1); 21302 self.lastQuery = null; 21303 if (!self.settings.persist && self.userOptions.hasOwnProperty(value)) { 21304 self.removeOption(value, silent); 21305 } 21306 21307 if (i < self.caretPos) { 21308 self.setCaret(self.caretPos - 1); 21309 } 21310 21311 self.refreshState(); 21312 self.updatePlaceholder(); 21313 self.updateOriginalInput({silent: silent}); 21314 self.positionDropdown(); 21315 self.trigger('item_remove', value, $item); 21316 } 21317 }, 21318 21319 /** 21320 * Invokes the `create` method provided in the 21321 * selectize options that should provide the data 21322 * for the new item, given the user input. 21323 * 21324 * Once this completes, it will be added 21325 * to the item list. 21326 * 21327 * @param {string} value 21328 * @param {boolean} [triggerDropdown] 21329 * @param {function} [callback] 21330 * @return {boolean} 21331 */ 21332 createItem: function(input, triggerDropdown) { 21333 var self = this; 21334 var caret = self.caretPos; 21335 input = input || (self.$control_input.val() || '').trim(); 21336 21337 var callback = arguments[arguments.length - 1]; 21338 if (typeof callback !== 'function') callback = function() {}; 21339 21340 if (typeof triggerDropdown !== 'boolean') { 21341 triggerDropdown = true; 21342 } 21343 21344 if (!self.canCreate(input)) { 21345 callback(); 21346 return false; 21347 } 21348 21349 self.lock(); 21350 21351 var setup = (typeof self.settings.create === 'function') ? this.settings.create : function(input) { 21352 var data = {}; 21353 data[self.settings.labelField] = input; 21354 var key = input; 21355 if ( self.settings.formatValueToKey && typeof self.settings.formatValueToKey === 'function' ) { 21356 key = self.settings.formatValueToKey.apply(this, [key]); 21357 if (key === null || typeof key === 'undefined' || typeof key === 'object' || typeof key === 'function') { 21358 throw new Error('Selectize "formatValueToKey" setting must be a function that returns a value other than object or function.'); 21359 } 21360 } 21361 data[self.settings.valueField] = key; 21362 return data; 21363 }; 21364 21365 var create = once(function(data) { 21366 self.unlock(); 21367 21368 if (!data || typeof data !== 'object') return callback(); 21369 var value = hash_key(data[self.settings.valueField]); 21370 if (typeof value !== 'string') return callback(); 21371 21372 self.setTextboxValue(''); 21373 self.addOption(data); 21374 self.setCaret(caret); 21375 self.addItem(value); 21376 self.refreshOptions(triggerDropdown && self.settings.mode !== 'single'); 21377 callback(data); 21378 }); 21379 21380 var output = setup.apply(this, [input, create]); 21381 if (typeof output !== 'undefined') { 21382 create(output); 21383 } 21384 21385 return true; 21386 }, 21387 21388 /** 21389 * Re-renders the selected item lists. 21390 */ 21391 refreshItems: function() { 21392 this.lastQuery = null; 21393 21394 if (this.isSetup) { 21395 this.addItem(this.items); 21396 } 21397 21398 this.refreshState(); 21399 this.updateOriginalInput(); 21400 }, 21401 21402 /** 21403 * Updates all state-dependent attributes 21404 * and CSS classes. 21405 */ 21406 refreshState: function() { 21407 this.refreshValidityState(); 21408 this.refreshClasses(); 21409 }, 21410 21411 /** 21412 * Update the `required` attribute of both input and control input. 21413 * 21414 * The `required` property needs to be activated on the control input 21415 * for the error to be displayed at the right place. `required` also 21416 * needs to be temporarily deactivated on the input since the input is 21417 * hidden and can't show errors. 21418 */ 21419 refreshValidityState: function() { 21420 if (!this.isRequired) return false; 21421 21422 var invalid = !this.items.length; 21423 21424 this.isInvalid = invalid; 21425 this.$control_input.prop('required', invalid); 21426 this.$input.prop('required', !invalid); 21427 }, 21428 21429 /** 21430 * Updates all state-dependent CSS classes. 21431 */ 21432 refreshClasses: function() { 21433 var self = this; 21434 var isFull = self.isFull();
vendor: 5,543 bytes, lines 21435-21630
21435 var isLocked = self.isLocked; 21436 21437 self.$wrapper 21438 .toggleClass('rtl', self.rtl); 21439 21440 self.$control 21441 .toggleClass('focus', self.isFocused) 21442 .toggleClass('disabled', self.isDisabled) 21443 .toggleClass('required', self.isRequired) 21444 .toggleClass('invalid', self.isInvalid) 21445 .toggleClass('locked', isLocked) 21446 .toggleClass('full', isFull).toggleClass('not-full', !isFull) 21447 .toggleClass('input-active', self.isFocused && !self.isInputHidden) 21448 .toggleClass('dropdown-active', self.isOpen) 21449 .toggleClass('has-options', !$.isEmptyObject(self.options)) 21450 .toggleClass('has-items', self.items.length > 0); 21451 21452 self.$control_input.data('grow', !isFull && !isLocked); 21453 }, 21454 21455 /** 21456 * Determines whether or not more items can be added 21457 * to the control without exceeding the user-defined maximum. 21458 * 21459 * @returns {boolean} 21460 */ 21461 isFull: function() { 21462 return this.settings.maxItems !== null && this.items.length >= this.settings.maxItems; 21463 }, 21464 21465 /** 21466 * Refreshes the original <select> or <input> 21467 * element to reflect the current state. 21468 */ 21469 updateOriginalInput: function(opts) { 21470 var i, n, options, label, self = this; 21471 opts = opts || {}; 21472 21473 if (self.tagType === TAG_SELECT) { 21474 options = []; 21475 for (i = 0, n = self.items.length; i < n; i++) { 21476 label = self.options[self.items[i]][self.settings.labelField] || ''; 21477 options.push('<option value="' + escape_html(self.items[i]) + '" selected="selected">' + escape_html(label) + '</option>'); 21478 } 21479 if (!options.length && !this.$input.attr('multiple')) { 21480 options.push('<option value="" selected="selected"></option>'); 21481 } 21482 self.$input.html(options.join('')); 21483 } else { 21484 self.$input.val(self.getValue()); 21485 self.$input.attr('value',self.$input.val()); 21486 } 21487 21488 if (self.isSetup) { 21489 if (!opts.silent) { 21490 self.trigger('change', self.$input.val()); 21491 } 21492 } 21493 }, 21494 21495 /** 21496 * Shows/hide the input placeholder depending 21497 * on if there items in the list already. 21498 */ 21499 updatePlaceholder: function() { 21500 if (!this.settings.placeholder) return; 21501 var $input = this.$control_input; 21502 21503 if (this.items.length) { 21504 $input.removeAttr('placeholder'); 21505 } else { 21506 $input.attr('placeholder', this.settings.placeholder); 21507 } 21508 $input.triggerHandler('update', {force: true}); 21509 }, 21510 21511 /** 21512 * Shows the autocomplete dropdown containing 21513 * the available options. 21514 */ 21515 open: function() { 21516 var self = this; 21517 21518 if (self.isLocked || self.isOpen || (self.settings.mode === 'multi' && self.isFull())) return; 21519 self.focus(); 21520 self.isOpen = true; 21521 self.refreshState(); 21522 self.$dropdown.css({visibility: 'hidden', display: 'block'}); 21523 self.positionDropdown(); 21524 self.$dropdown.css({visibility: 'visible'}); 21525 self.trigger('dropdown_open', self.$dropdown); 21526 }, 21527 21528 /** 21529 * Closes the autocomplete dropdown menu. 21530 */ 21531 close: function() { 21532 var self = this; 21533 var trigger = self.isOpen; 21534 21535 if (self.settings.mode === 'single' && self.items.length) { 21536 self.hideInput(); 21537 21538 // Do not trigger blur while inside a blur event, 21539 // this fixes some weird tabbing behavior in FF and IE. 21540 // See #1164 21541 if (self.isBlurring) { 21542 self.$control_input.blur(); // close keyboard on iOS 21543 } 21544 } 21545 21546 self.isOpen = false; 21547 self.$dropdown.hide(); 21548 self.setActiveOption(null); 21549 self.refreshState(); 21550 21551 if (trigger) self.trigger('dropdown_close', self.$dropdown); 21552 }, 21553 21554 /** 21555 * Calculates and applies the appropriate 21556 * position of the dropdown. 21557 */ 21558 positionDropdown: function() { 21559 var $control = this.$control; 21560 var offset = this.settings.dropdownParent === 'body' ? $control.offset() : $control.position(); 21561 offset.top += $control.outerHeight(true); 21562 21563 this.$dropdown.css({ 21564 width : $control[0].getBoundingClientRect().width, 21565 top : offset.top, 21566 left : offset.left 21567 }); 21568 }, 21569 21570 /** 21571 * Resets / clears all selected items 21572 * from the control. 21573 * 21574 * @param {boolean} silent 21575 */ 21576 clear: function(silent) { 21577 var self = this; 21578 21579 if (!self.items.length) return; 21580 self.$control.children(':not(input)').remove(); 21581 self.items = []; 21582 self.lastQuery = null; 21583 self.setCaret(0); 21584 self.setActiveItem(null); 21585 self.updatePlaceholder(); 21586 self.updateOriginalInput({silent: silent}); 21587 self.refreshState(); 21588 self.showInput(); 21589 self.trigger('clear'); 21590 }, 21591 21592 /** 21593 * A helper method for inserting an element 21594 * at the current caret position. 21595 * 21596 * @param {object} $el 21597 */ 21598 insertAtCaret: function($el) { 21599 var caret = Math.min(this.caretPos, this.items.length); 21600 var el = $el[0]; 21601 var target = this.buffer || this.$control[0]; 21602 21603 if (caret === 0) { 21604 target.insertBefore(el, target.firstChild); 21605 } else { 21606 target.insertBefore(el, target.childNodes[caret]); 21607 } 21608 21609 this.setCaret(caret + 1); 21610 }, 21611 21612 /** 21613 * Removes the current selected item(s). 21614 * 21615 * @param {object} e (optional) 21616 * @returns {boolean} 21617 */ 21618 deleteSelection: function(e) { 21619 var i, n, direction, selection, values, caret, option_select, $option_select, $tail; 21620 var self = this; 21621 21622 direction = (e && e.keyCode === KEY_BACKSPACE) ? -1 : 1; 21623 selection = getSelection(self.$control_input[0]); 21624 21625 if (self.$activeOption && !self.settings.hideSelected) { 21626 if (typeof self.settings.deselectBehavior === 'string' && self.settings.deselectBehavior === 'top') { 21627 option_select = self.getFirstOption().attr('data-value'); 21628 } else { 21629 option_select = self.getAdjacentOption(self.$activeOption, -1).attr('data-value'); 21630 }
vendor: 8,464 bytes, lines 21630-21965
21630 21631 } 21632 21633 // determine items that will be removed 21634 values = []; 21635 21636 if (self.$activeItems.length) { 21637 $tail = self.$control.children('.active:' + (direction > 0 ? 'last' : 'first')); 21638 caret = self.$control.children(':not(input)').index($tail); 21639 if (direction > 0) { caret++; } 21640 21641 for (i = 0, n = self.$activeItems.length; i < n; i++) { 21642 values.push($(self.$activeItems[i]).attr('data-value')); 21643 } 21644 if (e) { 21645 e.preventDefault(); 21646 e.stopPropagation(); 21647 } 21648 } else if ((self.isFocused || self.settings.mode === 'single') && self.items.length) { 21649 if (direction < 0 && selection.start === 0 && selection.length === 0) { 21650 values.push(self.items[self.caretPos - 1]); 21651 } else if (direction > 0 && selection.start === self.$control_input.val().length) { 21652 values.push(self.items[self.caretPos]); 21653 } 21654 } 21655 21656 // allow the callback to abort 21657 if (!values.length || (typeof self.settings.onDelete === 'function' && self.settings.onDelete.apply(self, [values]) === false)) { 21658 return false; 21659 } 21660 21661 // perform removal 21662 if (typeof caret !== 'undefined') { 21663 self.setCaret(caret); 21664 } 21665 while (values.length) { 21666 self.removeItem(values.pop()); 21667 } 21668 21669 self.showInput(); 21670 self.positionDropdown(); 21671 self.refreshOptions(true); 21672 21673 // select previous option 21674 if (option_select) { 21675 $option_select = self.getOption(option_select); 21676 if ($option_select.length) { 21677 self.setActiveOption($option_select); 21678 } 21679 } 21680 21681 return true; 21682 }, 21683 21684 /** 21685 * Selects the previous / next item (depending 21686 * on the `direction` argument). 21687 * 21688 * > 0 - right 21689 * < 0 - left 21690 * 21691 * @param {int} direction 21692 * @param {object} e (optional) 21693 */ 21694 advanceSelection: function(direction, e) { 21695 var tail, selection, idx, valueLength, cursorAtEdge, $tail; 21696 var self = this; 21697 21698 if (direction === 0) return; 21699 if (self.rtl) direction *= -1; 21700 21701 tail = direction > 0 ? 'last' : 'first'; 21702 selection = getSelection(self.$control_input[0]); 21703 21704 if (self.isFocused && !self.isInputHidden) { 21705 valueLength = self.$control_input.val().length; 21706 cursorAtEdge = direction < 0 21707 ? selection.start === 0 && selection.length === 0 21708 : selection.start === valueLength; 21709 21710 if (cursorAtEdge && !valueLength) { 21711 self.advanceCaret(direction, e); 21712 } 21713 } else { 21714 $tail = self.$control.children('.active:' + tail); 21715 if ($tail.length) { 21716 idx = self.$control.children(':not(input)').index($tail); 21717 self.setActiveItem(null); 21718 self.setCaret(direction > 0 ? idx + 1 : idx); 21719 } 21720 } 21721 }, 21722 21723 /** 21724 * Moves the caret left / right. 21725 * 21726 * @param {int} direction 21727 * @param {object} e (optional) 21728 */ 21729 advanceCaret: function(direction, e) { 21730 var self = this, fn, $adj; 21731 21732 if (direction === 0) return; 21733 21734 fn = direction > 0 ? 'next' : 'prev'; 21735 if (self.isShiftDown) { 21736 $adj = self.$control_input[fn](); 21737 if ($adj.length) { 21738 self.hideInput(); 21739 self.setActiveItem($adj); 21740 e && e.preventDefault(); 21741 } 21742 } else { 21743 self.setCaret(self.caretPos + direction); 21744 } 21745 }, 21746 21747 /** 21748 * Moves the caret to the specified index. 21749 * 21750 * @param {int} i 21751 */ 21752 setCaret: function(i) { 21753 var self = this; 21754 21755 if (self.settings.mode === 'single') { 21756 i = self.items.length; 21757 } else { 21758 i = Math.max(0, Math.min(self.items.length, i)); 21759 } 21760 21761 if(!self.isPending) { 21762 // the input must be moved by leaving it in place and moving the 21763 // siblings, due to the fact that focus cannot be restored once lost 21764 // on mobile webkit devices 21765 var j, n, fn, $children, $child; 21766 $children = self.$control.children(':not(input)'); 21767 for (j = 0, n = $children.length; j < n; j++) { 21768 $child = $($children[j]).detach(); 21769 if (j < i) { 21770 self.$control_input.before($child); 21771 } else { 21772 self.$control.append($child); 21773 } 21774 } 21775 } 21776 21777 self.caretPos = i; 21778 }, 21779 21780 /** 21781 * Disables user input on the control. Used while 21782 * items are being asynchronously created. 21783 */ 21784 lock: function() { 21785 this.close(); 21786 this.isLocked = true; 21787 this.refreshState(); 21788 }, 21789 21790 /** 21791 * Re-enables user input on the control. 21792 */ 21793 unlock: function() { 21794 this.isLocked = false; 21795 this.refreshState(); 21796 }, 21797 21798 /** 21799 * Disables user input on the control completely. 21800 * While disabled, it cannot receive focus. 21801 */ 21802 disable: function() { 21803 var self = this; 21804 self.$input.prop('disabled', true); 21805 self.$control_input.prop('disabled', true).prop('tabindex', -1); 21806 self.isDisabled = true; 21807 self.lock(); 21808 }, 21809 21810 /** 21811 * Enables the control so that it can respond 21812 * to focus and user input. 21813 */ 21814 enable: function() { 21815 var self = this; 21816 self.$input.prop('disabled', false); 21817 self.$control_input.prop('disabled', false).prop('tabindex', self.tabIndex); 21818 self.isDisabled = false; 21819 self.unlock(); 21820 }, 21821 21822 /** 21823 * Completely destroys the control and 21824 * unbinds all event listeners so that it can 21825 * be garbage collected. 21826 */ 21827 destroy: function() { 21828 var self = this; 21829 var eventNS = self.eventNS; 21830 var revertSettings = self.revertSettings; 21831 21832 self.trigger('destroy'); 21833 self.off(); 21834 self.$wrapper.remove(); 21835 self.$dropdown.remove(); 21836 21837 self.$input 21838 .html('') 21839 .append(revertSettings.$children) 21840 .removeAttr('tabindex') 21841 .removeClass('selectized') 21842 .attr({tabindex: revertSettings.tabindex}) 21843 .show(); 21844 21845 self.$control_input.removeData('grow'); 21846 self.$input.removeData('selectize'); 21847 21848 if (--Selectize.count == 0 && Selectize.$testInput) { 21849 Selectize.$testInput.remove(); 21850 Selectize.$testInput = undefined; 21851 } 21852 21853 $(window).off(eventNS); 21854 $(document).off(eventNS); 21855 $(document.body).off(eventNS); 21856 21857 delete self.$input[0].selectize; 21858 }, 21859 21860 /** 21861 * A helper method for rendering "item" and 21862 * "option" templates, given the data. 21863 * 21864 * @param {string} templateName 21865 * @param {object} data 21866 * @returns {string} 21867 */ 21868 render: function(templateName, data) { 21869 var value, id, label; 21870 var html = ''; 21871 var cache = false; 21872 var self = this; 21873 var regex_tag = /^[\t \r\n]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i; 21874 21875 if (templateName === 'option' || templateName === 'item') { 21876 value = hash_key(data[self.settings.valueField]); 21877 cache = !!value; 21878 } 21879 21880 // pull markup from cache if it exists 21881 if (cache) { 21882 if (!isset(self.renderCache[templateName])) { 21883 self.renderCache[templateName] = {}; 21884 } 21885 if (self.renderCache[templateName].hasOwnProperty(value)) { 21886 return self.renderCache[templateName][value]; 21887 } 21888 } 21889 21890 // render markup 21891 html = $(self.settings.render[templateName].apply(this, [data, escape_html])); 21892 21893 // add mandatory attributes 21894 if (templateName === 'option' || templateName === 'option_create') { 21895 if (!data[self.settings.disabledField]) { 21896 html.attr('data-selectable', ''); 21897 } 21898 } 21899 else if (templateName === 'optgroup') { 21900 id = data[self.settings.optgroupValueField] || ''; 21901 html.attr('data-group', id); 21902 if(data[self.settings.disabledField]) { 21903 html.attr('data-disabled', ''); 21904 } 21905 } 21906 if (templateName === 'option' || templateName === 'item') { 21907 html.attr('data-value', value || ''); 21908 } 21909 21910 // update cache 21911 if (cache) { 21912 self.renderCache[templateName][value] = html[0]; 21913 } 21914 21915 return html[0]; 21916 }, 21917 21918 /** 21919 * Clears the render cache for a template. If 21920 * no template is given, clears all render 21921 * caches. 21922 * 21923 * @param {string} templateName 21924 */ 21925 clearCache: function(templateName) { 21926 var self = this; 21927 if (typeof templateName === 'undefined') { 21928 self.renderCache = {}; 21929 } else { 21930 delete self.renderCache[templateName]; 21931 } 21932 }, 21933 21934 /** 21935 * Determines whether or not to display the 21936 * create item prompt, given a user input. 21937 * 21938 * @param {string} input 21939 * @return {boolean} 21940 */ 21941 canCreate: function(input) { 21942 var self = this; 21943 if (!self.settings.create) return false; 21944 var filter = self.settings.createFilter; 21945 return input.length 21946 && (typeof filter !== 'function' || filter.apply(self, [input])) 21947 && (typeof filter !== 'string' || new RegExp(filter).test(input)) 21948 && (!(filter instanceof RegExp) || filter.test(input)); 21949 } 21950 21951 }); 21952 21953 21954 Selectize.count = 0; 21955 Selectize.defaults = { 21956 options: [], 21957 optgroups: [], 21958 21959 plugins: [], 21960 delimiter: ',', 21961 splitOn: null, // regexp or string for splitting up values from a paste command 21962 persist: true, 21963 diacritics: true, 21964 create: false, 21965
vendor: 4,271 bytes, lines 21965-22105
21965showAddOptionOnCreate: true, 21966 createOnBlur: false, 21967 createFilter: null, 21968 highlight: true, 21969 openOnFocus: true, 21970 maxOptions: 1000, 21971 maxItems: null, 21972 hideSelected: null, 21973 addPrecedence: false, 21974 selectOnTab: true, 21975 preload: false, 21976 allowEmptyOption: false, 21977 showEmptyOptionInDropdown: false, 21978 emptyOptionLabel: '--', 21979 closeAfterSelect: false, 21980 21981 scrollDuration: 60, 21982 deselectBehavior: 'previous', //top, previous 21983 loadThrottle: 300, 21984 loadingClass: 'loading', 21985 21986 dataAttr: 'data-data', 21987 optgroupField: 'optgroup', 21988 valueField: 'value', 21989 labelField: 'text', 21990 disabledField: 'disabled', 21991 optgroupLabelField: 'label', 21992 optgroupValueField: 'value', 21993 lockOptgroupOrder: false, 21994 21995 sortField: '$order', 21996 searchField: ['text'], 21997 searchConjunction: 'and', 21998 21999 mode: null, 22000 wrapperClass: 'selectize-control', 22001 inputClass: 'selectize-input', 22002 dropdownClass: 'selectize-dropdown', 22003 dropdownContentClass: 'selectize-dropdown-content', 22004 22005 dropdownParent: null, 22006 22007 copyClassesToDropdown: true, 22008 22009 /* 22010 load : null, // function(query, callback) { ... } 22011 score : null, // function(search) { ... } 22012 formatValueToKey : null, // function(key) { ... } 22013 onInitialize : null, // function() { ... } 22014 onChange : null, // function(value) { ... } 22015 onItemAdd : null, // function(value, $item) { ... } 22016 onItemRemove : null, // function(value) { ... } 22017 onClear : null, // function() { ... } 22018 onOptionAdd : null, // function(value, data) { ... } 22019 onOptionRemove : null, // function(value) { ... } 22020 onOptionClear : null, // function() { ... } 22021 onOptionGroupAdd : null, // function(id, data) { ... } 22022 onOptionGroupRemove : null, // function(id) { ... } 22023 onOptionGroupClear : null, // function() { ... } 22024 onDropdownOpen : null, // function($dropdown) { ... } 22025 onDropdownClose : null, // function($dropdown) { ... } 22026 onType : null, // function(str) { ... } 22027 onDelete : null, // function(values) { ... } 22028 */ 22029 22030 render: { 22031 /* 22032 item: null, 22033 optgroup: null, 22034 optgroup_header: null, 22035 option: null, 22036 option_create: null 22037 */ 22038 } 22039 }; 22040 22041 22042 $.fn.selectize = function(settings_user) { 22043 var defaults = $.fn.selectize.defaults; 22044 var settings = $.extend({}, defaults, settings_user); 22045 var attr_data = settings.dataAttr; 22046 var field_label = settings.labelField; 22047 var field_value = settings.valueField; 22048 var field_disabled = settings.disabledField; 22049 var field_optgroup = settings.optgroupField; 22050 var field_optgroup_label = settings.optgroupLabelField; 22051 var field_optgroup_value = settings.optgroupValueField; 22052 22053 /** 22054 * Initializes selectize from a <input type="text"> element. 22055 * 22056 * @param {object} $input 22057 * @param {object} settings_element 22058 */ 22059 var init_textbox = function($input, settings_element) { 22060 var i, n, values, option; 22061 22062 var data_raw = $input.attr(attr_data); 22063 22064 if (!data_raw) { 22065 var value = $.trim($input.val() || ''); 22066 if (!settings.allowEmptyOption && !value.length) return; 22067 values = value.split(settings.delimiter); 22068 for (i = 0, n = values.length; i < n; i++) { 22069 option = {}; 22070 option[field_label] = values[i]; 22071 option[field_value] = values[i]; 22072 settings_element.options.push(option); 22073 } 22074 settings_element.items = values; 22075 } else { 22076 settings_element.options = JSON.parse(data_raw); 22077 for (i = 0, n = settings_element.options.length; i < n; i++) { 22078 settings_element.items.push(settings_element.options[i][field_value]); 22079 } 22080 } 22081 }; 22082 22083 /** 22084 * Initializes selectize from a <select> element. 22085 * 22086 * @param {object} $input 22087 * @param {object} settings_element 22088 */ 22089 var init_select = function($input, settings_element) { 22090 var i, n, tagName, $children, order = 0; 22091 var options = settings_element.options; 22092 var optionsMap = {}; 22093 22094 var readData = function($el) { 22095 var data = attr_data && $el.attr(attr_data); 22096 if (typeof data === 'string' && data.length) { 22097 return JSON.parse(data); 22098 } 22099 return null; 22100 }; 22101 22102 var addOption = function($option, group) { 22103 $option = $($option); 22104 22105 var value = hash_key($option.val());
vendor: 6,158 bytes, lines 22106-22308
22106 if (!value && !settings.allowEmptyOption) return; 22107 22108 // if the option already exists, it's probably been 22109 // duplicated in another optgroup. in this case, push 22110 // the current group to the "optgroup" property on the 22111 // existing option so that it's rendered in both places. 22112 if (optionsMap.hasOwnProperty(value)) { 22113 if (group) { 22114 var arr = optionsMap[value][field_optgroup]; 22115 if (!arr) { 22116 optionsMap[value][field_optgroup] = group; 22117 } else if (!$.isArray(arr)) { 22118 optionsMap[value][field_optgroup] = [arr, group]; 22119 } else { 22120 arr.push(group); 22121 } 22122 } 22123 return; 22124 } 22125 22126 var option = readData($option) || {}; 22127 option[field_label] = option[field_label] || $option.text(); 22128 option[field_value] = option[field_value] || value; 22129 option[field_disabled] = option[field_disabled] || $option.prop('disabled'); 22130 option[field_optgroup] = option[field_optgroup] || group; 22131 22132 optionsMap[value] = option; 22133 options.push(option); 22134 22135 if ($option.is(':selected')) { 22136 settings_element.items.push(value); 22137 } 22138 }; 22139 22140 var addGroup = function($optgroup) { 22141 var i, n, id, optgroup, $options; 22142 22143 $optgroup = $($optgroup); 22144 id = $optgroup.attr('label'); 22145 22146 if (id) { 22147 optgroup = readData($optgroup) || {}; 22148 optgroup[field_optgroup_label] = id; 22149 optgroup[field_optgroup_value] = id; 22150 optgroup[field_disabled] = $optgroup.prop('disabled'); 22151 settings_element.optgroups.push(optgroup); 22152 } 22153 22154 $options = $('option', $optgroup); 22155 for (i = 0, n = $options.length; i < n; i++) { 22156 addOption($options[i], id); 22157 } 22158 }; 22159 22160 settings_element.maxItems = $input.attr('multiple') ? null : 1; 22161 22162 $children = $input.children(); 22163 for (i = 0, n = $children.length; i < n; i++) { 22164 tagName = $children[i].tagName.toLowerCase(); 22165 if (tagName === 'optgroup') { 22166 addGroup($children[i]); 22167 } else if (tagName === 'option') { 22168 addOption($children[i]); 22169 } 22170 } 22171 }; 22172 22173 return this.each(function() { 22174 if (this.selectize) return; 22175 22176 var instance; 22177 var $input = $(this); 22178 var tag_name = this.tagName.toLowerCase(); 22179 var placeholder = $input.attr('placeholder') || $input.attr('data-placeholder'); 22180 if (!placeholder && !settings.allowEmptyOption) { 22181 placeholder = $input.children('option[value=""]').text(); 22182 } 22183 if (settings.allowEmptyOption && settings.showEmptyOptionInDropdown && !$input.children('option[value=""]').length) { 22184 var input_html = $input.html(); 22185 $input.html('<option value="">'+settings.emptyOptionLabel+'</option>'+input_html); 22186 } 22187 22188 var settings_element = { 22189 'placeholder' : placeholder, 22190 'options' : [], 22191 'optgroups' : [], 22192 'items' : [] 22193 }; 22194 22195 if (tag_name === 'select') { 22196 init_select($input, settings_element); 22197 } else { 22198 init_textbox($input, settings_element); 22199 } 22200 22201 instance = new Selectize($input, $.extend(true, {}, defaults, settings_element, settings_user)); 22202 instance.settings_user = settings_user; 22203 }); 22204 }; 22205 22206 $.fn.selectize.defaults = Selectize.defaults; 22207 $.fn.selectize.support = { 22208 validity: SUPPORTS_VALIDITY_API 22209 }; 22210 22211 22212 Selectize.define("auto_position", function () { 22213 var self = this; 22214 22215 const POSITION = { 22216 top: 'top', 22217 bottom: 'bottom', 22218 }; 22219 22220 self.positionDropdown = (function() { 22221 return function() { 22222 const $control = this.$control; 22223 const offset = this.settings.dropdownParent === 'body' ? $control.offset() : $control.position(); 22224 offset.top += $control.outerHeight(true); 22225 22226 const dropdownHeight = this.$dropdown.prop('scrollHeight') + 5; // 5 - padding value; 22227 const controlPosTop = this.$control.get(0).getBoundingClientRect().top; 22228 const wrapperHeight = this.$wrapper.height(); 22229 const position = controlPosTop + dropdownHeight + wrapperHeight > window.innerHeight ? POSITION.top : POSITION.bottom; 22230 const styles = { 22231 width: $control.outerWidth(), 22232 left: offset.left 22233 }; 22234 22235 if (position === POSITION.top) { 22236 Object.assign(styles, {bottom: offset.top, top: 'unset', margin: '0 0 5px 0'}); 22237 this.$dropdown.addClass('selectize-position-top'); 22238 } else { 22239 Object.assign(styles, {top: offset.top, bottom: 'unset', margin: '5px 0 0 0'}); 22240 this.$dropdown.removeClass('selectize-position-top'); 22241 } 22242 22243 this.$dropdown.css(styles); 22244 } 22245 }()); 22246 }); 22247 22248 22249 Selectize.define('auto_select_on_type', function(options) { 22250 var self = this; 22251 22252 self.onBlur = (function() { 22253 var originalBlur = self.onBlur; 22254 return function(e) { 22255 var $matchedItem = self.getFirstItemMatchedByTextContent(self.lastValue, true); 22256 if (typeof $matchedItem.attr('data-value') !== 'undefined' && self.getValue() !== $matchedItem.attr('data-value')) 22257 { 22258 self.setValue($matchedItem.attr('data-value')); 22259 } 22260 return originalBlur.apply(this, arguments); 22261 } 22262 }()); 22263 }); 22264 22265 22266 Selectize.define("autofill_disable", function (options) { 22267 var self = this; 22268 22269 self.setup = (function () { 22270 var original = self.setup; 22271 return function () { 22272 original.apply(self, arguments); 22273 22274 // https://stackoverflow.com/questions/30053167/autocomplete-off-vs-false 22275 self.$control_input.attr({ autocomplete: "new-password", autofill: "no" }); 22276 }; 22277 })(); 22278 }); 22279 22280 22281 Selectize.define('drag_drop', function(options) { 22282 if (!$.fn.sortable) throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".'); 22283 if (this.settings.mode !== 'multi') return; 22284 var self = this; 22285 22286 self.lock = (function() { 22287 var original = self.lock; 22288 return function() { 22289 var sortable = self.$control.data('sortable'); 22290 if (sortable) sortable.disable(); 22291 return original.apply(self, arguments); 22292 }; 22293 })(); 22294 22295 self.unlock = (function() { 22296 var original = self.unlock; 22297 return function() { 22298 var sortable = self.$control.data('sortable'); 22299 if (sortable) sortable.enable(); 22300 return original.apply(self, arguments); 22301 }; 22302 })(); 22303 22304 self.setup = (function() { 22305 var original = self.setup; 22306 return function() { 22307 original.apply(this, arguments); 22308
vendor: 7,492 bytes, lines 22309-22562
22309 var $control = self.$control.sortable({ 22310 items: '[data-value]', 22311 forcePlaceholderSize: true, 22312 disabled: self.isLocked, 22313 start: function(e, ui) { 22314 ui.placeholder.css('width', ui.helper.css('width')); 22315 // $control.css({overflow: 'visible'}); 22316 $control.addClass('dragging'); 22317 }, 22318 stop: function() { 22319 // $control.css({overflow: 'hidden'}); 22320 $control.removeClass('dragging'); 22321 var active = self.$activeItems ? self.$activeItems.slice() : null; 22322 var values = []; 22323 $control.children('[data-value]').each(function() { 22324 values.push($(this).attr('data-value')); 22325 }); 22326 self.isFocused = false; 22327 self.setValue(values); 22328 self.isFocused = true; 22329 self.setActiveItem(active); 22330 self.positionDropdown(); 22331 } 22332 }); 22333 }; 22334 })(); 22335 22336 }); 22337 22338 22339 Selectize.define('dropdown_header', function(options) { 22340 var self = this; 22341 22342 options = $.extend({ 22343 title : 'Untitled', 22344 headerClass : 'selectize-dropdown-header', 22345 titleRowClass : 'selectize-dropdown-header-title', 22346 labelClass : 'selectize-dropdown-header-label', 22347 closeClass : 'selectize-dropdown-header-close', 22348 22349 html: function(data) { 22350 return ( 22351 '<div class="' + data.headerClass + '">' + 22352 '<div class="' + data.titleRowClass + '">' + 22353 '<span class="' + data.labelClass + '">' + data.title + '</span>' + 22354 '<a href="javascript:void(0)" class="' + data.closeClass + '">×</a>' + 22355 '</div>' + 22356 '</div>' 22357 ); 22358 } 22359 }, options); 22360 22361 self.setup = (function() { 22362 var original = self.setup; 22363 return function() { 22364 original.apply(self, arguments); 22365 self.$dropdown_header = $(options.html(options)); 22366 self.$dropdown.prepend(self.$dropdown_header); 22367 }; 22368 })(); 22369 22370 }); 22371 22372 22373 Selectize.define('optgroup_columns', function(options) { 22374 var self = this; 22375 22376 options = $.extend({ 22377 equalizeWidth : true, 22378 equalizeHeight : true 22379 }, options); 22380 22381 this.getAdjacentOption = function($option, direction) { 22382 var $options = $option.closest('[data-group]').find('[data-selectable]'); 22383 var index = $options.index($option) + direction; 22384 22385 return index >= 0 && index < $options.length ? $options.eq(index) : $(); 22386 }; 22387 22388 this.onKeyDown = (function() { 22389 var original = self.onKeyDown; 22390 return function(e) { 22391 var index, $option, $options, $optgroup; 22392 22393 if (this.isOpen && (e.keyCode === KEY_LEFT || e.keyCode === KEY_RIGHT)) { 22394 self.ignoreHover = true; 22395 $optgroup = this.$activeOption.closest('[data-group]'); 22396 index = $optgroup.find('[data-selectable]').index(this.$activeOption); 22397 22398 if(e.keyCode === KEY_LEFT) { 22399 $optgroup = $optgroup.prev('[data-group]'); 22400 } else { 22401 $optgroup = $optgroup.next('[data-group]'); 22402 } 22403 22404 $options = $optgroup.find('[data-selectable]'); 22405 $option = $options.eq(Math.min($options.length - 1, index)); 22406 if ($option.length) { 22407 this.setActiveOption($option); 22408 } 22409 return; 22410 } 22411 22412 return original.apply(this, arguments); 22413 }; 22414 })(); 22415 22416 var getScrollbarWidth = function() { 22417 var div; 22418 var width = getScrollbarWidth.width; 22419 var doc = document; 22420 22421 if (typeof width === 'undefined') { 22422 div = doc.createElement('div'); 22423 div.innerHTML = '<div style="width:50px;height:50px;position:absolute;left:-50px;top:-50px;overflow:auto;"><div style="width:1px;height:100px;"></div></div>'; 22424 div = div.firstChild; 22425 doc.body.appendChild(div); 22426 width = getScrollbarWidth.width = div.offsetWidth - div.clientWidth; 22427 doc.body.removeChild(div); 22428 } 22429 return width; 22430 }; 22431 22432 var equalizeSizes = function() { 22433 var i, n, height_max, width, width_last, width_parent, $optgroups; 22434 22435 $optgroups = $('[data-group]', self.$dropdown_content); 22436 n = $optgroups.length; 22437 if (!n || !self.$dropdown_content.width()) return; 22438 22439 if (options.equalizeHeight) { 22440 height_max = 0; 22441 for (i = 0; i < n; i++) { 22442 height_max = Math.max(height_max, $optgroups.eq(i).height()); 22443 } 22444 $optgroups.css({height: height_max}); 22445 } 22446 22447 if (options.equalizeWidth) { 22448 width_parent = self.$dropdown_content.innerWidth() - getScrollbarWidth(); 22449 width = Math.round(width_parent / n); 22450 $optgroups.css({width: width}); 22451 if (n > 1) { 22452 width_last = width_parent - width * (n - 1); 22453 $optgroups.eq(n - 1).css({width: width_last}); 22454 } 22455 } 22456 }; 22457 22458 if (options.equalizeHeight || options.equalizeWidth) { 22459 hook.after(this, 'positionDropdown', equalizeSizes); 22460 hook.after(this, 'refreshOptions', equalizeSizes); 22461 } 22462 22463 22464 }); 22465 22466 22467 Selectize.define('remove_button', function(options) { 22468 options = $.extend({ 22469 label : '×', 22470 title : 'Remove', 22471 className : 'remove', 22472 append : true 22473 }, options); 22474 22475 var singleClose = function(thisRef, options) { 22476 22477 options.className = 'remove-single'; 22478 22479 var self = thisRef; 22480 var html = '<a href="javascript:void(0)" class="' + options.className + '" tabindex="-1" title="' + escape_html(options.title) + '">' + options.label + '</a>'; 22481 22482 /** 22483 * Appends an element as a child (with raw HTML). 22484 * 22485 * @param {string} html_container 22486 * @param {string} html_element 22487 * @return {string} 22488 */ 22489 var append = function(html_container, html_element) { 22490 return $('<span>').append(html_container) 22491 .append(html_element); 22492 }; 22493 22494 thisRef.setup = (function() { 22495 var original = self.setup; 22496 return function() { 22497 // override the item rendering method to add the button to each 22498 if (options.append) { 22499 var id = $(self.$input.context).attr('id'); 22500 var selectizer = $('#'+id); 22501 22502 var render_item = self.settings.render.item; 22503 self.settings.render.item = function(data) { 22504 return append(render_item.apply(thisRef, arguments), html); 22505 }; 22506 } 22507 22508 original.apply(thisRef, arguments); 22509 22510 // add event listener 22511 thisRef.$control.on('click', '.' + options.className, function(e) { 22512 e.preventDefault(); 22513 if (self.isLocked) return; 22514 22515 self.clear(); 22516 }); 22517 22518 }; 22519 })(); 22520 }; 22521 22522 var multiClose = function(thisRef, options) { 22523 22524 var self = thisRef; 22525 var html = '<a href="javascript:void(0)" class="' + options.className + '" tabindex="-1" title="' + escape_html(options.title) + '">' + options.label + '</a>'; 22526 22527 /** 22528 * Appends an element as a child (with raw HTML). 22529 * 22530 * @param {string} html_container 22531 * @param {string} html_element 22532 * @return {string} 22533 */ 22534 var append = function(html_container, html_element) { 22535 var pos = html_container.search(/(<\/[^>]+>\s*)$/); 22536 return html_container.substring(0, pos) + html_element + html_container.substring(pos); 22537 }; 22538 22539 thisRef.setup = (function() { 22540 var original = self.setup; 22541 return function() { 22542 // override the item rendering method to add the button to each 22543 if (options.append) { 22544 var render_item = self.settings.render.item; 22545 self.settings.render.item = function(data) { 22546 return append(render_item.apply(thisRef, arguments), html); 22547 }; 22548 } 22549 22550 original.apply(thisRef, arguments); 22551 22552 // add event listener 22553 thisRef.$control.on('click', '.' + options.className, function(e) { 22554 e.preventDefault(); 22555 if (self.isLocked) return; 22556 22557 var $item = $(e.currentTarget).parent(); 22558 self.setActiveItem($item); 22559 if (self.deleteSelection()) { 22560 self.setCaret(self.items.length); 22561 } 22562 return false;
vendor: 4,446 bytes, lines 22563-22722
22563 }); 22564 22565 }; 22566 })(); 22567 }; 22568 22569 if (this.settings.mode === 'single') { 22570 singleClose(this, options); 22571 return; 22572 } else { 22573 multiClose(this, options); 22574 } 22575 }); 22576 22577 22578 Selectize.define('restore_on_backspace', function(options) { 22579 var self = this; 22580 22581 options.text = options.text || function(option) { 22582 return option[this.settings.labelField]; 22583 }; 22584 22585 this.onKeyDown = (function() { 22586 var original = self.onKeyDown; 22587 return function(e) { 22588 var index, option; 22589 if (e.keyCode === KEY_BACKSPACE && this.$control_input.val() === '' && !this.$activeItems.length) { 22590 index = this.caretPos - 1; 22591 if (index >= 0 && index < this.items.length) { 22592 option = this.options[this.items[index]]; 22593 if (this.deleteSelection(e)) { 22594 this.setTextboxValue(options.text.apply(this, [option])); 22595 this.refreshOptions(true); 22596 } 22597 e.preventDefault(); 22598 return; 22599 } 22600 } 22601 return original.apply(this, arguments); 22602 }; 22603 })(); 22604 }); 22605 22606 22607 Selectize.define('select_on_focus', function(options) { 22608 var self = this; 22609 22610 self.on('focus', function() { 22611 var originalFocus = self.onFocus; 22612 return function(e) { 22613 var value = self.getItem(self.getValue()).text(); 22614 self.clear(); 22615 self.setTextboxValue(value); 22616 self.$control_input.select(); 22617 setTimeout( function () { 22618 if (self.settings.selectOnTab) { 22619 self.setActiveOption(self.getFirstItemMatchedByTextContent(value)); 22620 } 22621 self.settings.score = null; 22622 },0); 22623 return originalFocus.apply(this, arguments); 22624 }; 22625 }()); 22626 22627 self.onBlur = (function() { 22628 var originalBlur = self.onBlur; 22629 return function(e) { 22630 if (self.getValue() === "" && self.lastValidValue !== self.getValue()) { 22631 self.setValue(self.lastValidValue); 22632 } 22633 setTimeout( function () { 22634 self.settings.score = function() { 22635 return function() { 22636 return 1; 22637 }; 22638 }; 22639 }, 0 ); 22640 return originalBlur.apply(this, arguments); 22641 } 22642 }()); 22643 self.settings.score = function() { 22644 return function() { return 1; }; 22645 }; 22646 22647 }); 22648 22649 22650 Selectize.define('tag_limit', function (options) { 22651 const self = this 22652 options.tagLimit = options.tagLimit 22653 this.onBlur = (function (e) { 22654 const original = self.onBlur 22655 22656 return function (e) { 22657 original.apply(this, e); 22658 if (!e) 22659 return 22660 const $control = this.$control 22661 const $items = $control.find('.item') 22662 const limit = options.tagLimit 22663 if (limit === undefined || $items.length <= limit) 22664 return 22665 22666 $items.toArray().forEach(function(item, index) { 22667 if (index < limit) 22668 return 22669 $(item).hide() 22670 }); 22671 22672 $control.append('<span><b>' + ($items.length - limit) + '</b></span>') 22673 }; 22674 })() 22675 22676 this.onFocus = (function (e) { 22677 const original = self.onFocus 22678 22679 return function (e) { 22680 original.apply(this, e); 22681 if (!e) 22682 return 22683 const $control = this.$control 22684 const $items = $control.find('.item') 22685 $items.show() 22686 $control.find('span').remove() 22687 22688 }; 22689 })() 22690 }); 22691 22692 22693 return Selectize; 22694})); 22695 22696 22697/***/ }), 22698/* 38 */ 22699/***/ (function(module, exports, __webpack_require__) { 22700 22701/* WEBPACK VAR INJECTION */(function($) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 22702 * sifter.js 22703 * Copyright (c) 2013 Brian Reavis & contributors 22704 * 22705 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this 22706 * file except in compliance with the License. You may obtain a copy of the License at: 22707 * http://www.apache.org/licenses/LICENSE-2.0 22708 * 22709 * Unless required by applicable law or agreed to in writing, software distributed under 22710 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 22711 * ANY KIND, either express or implied. See the License for the specific language 22712 * governing permissions and limitations under the License. 22713 * 22714 * @author Brian Reavis <[email protected]> 22715 */ 22716 22717(function(root, factory) { 22718 if (true) { 22719 !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 22720 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 22721 (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : 22722 __WEBPACK_AMD_DEFINE_FACTORY__),
22723 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)
vendor: 12,838 bytes, lines 22723-23203
22723); 22724 } else if (typeof exports === 'object') { 22725 module.exports = factory(); 22726 } else { 22727 root.Sifter = factory(); 22728 } 22729}(this, function() { 22730 22731 /** 22732 * Textually searches arrays and hashes of objects 22733 * by property (or multiple properties). Designed 22734 * specifically for autocomplete. 22735 * 22736 * @constructor 22737 * @param {array|object} items 22738 * @param {object} items 22739 */ 22740 var Sifter = function(items, settings) { 22741 this.items = items; 22742 this.settings = settings || {diacritics: true}; 22743 }; 22744 22745 /** 22746 * Splits a search string into an array of individual 22747 * regexps to be used to match results. 22748 * 22749 * @param {string} query 22750 * @returns {array} 22751 */ 22752 Sifter.prototype.tokenize = function(query) { 22753 query = trim(String(query || '').toLowerCase()); 22754 if (!query || !query.length) return []; 22755 22756 var i, n, regex, letter; 22757 var tokens = []; 22758 var words = query.split(/ +/); 22759 22760 for (i = 0, n = words.length; i < n; i++) { 22761 regex = escape_regex(words[i]); 22762 if (this.settings.diacritics) { 22763 for (letter in DIACRITICS) { 22764 if (DIACRITICS.hasOwnProperty(letter)) { 22765 regex = regex.replace(new RegExp(letter, 'g'), DIACRITICS[letter]); 22766 } 22767 } 22768 } 22769 tokens.push({ 22770 string : words[i], 22771 regex : new RegExp(regex, 'i') 22772 }); 22773 } 22774 22775 return tokens; 22776 }; 22777 22778 /** 22779 * Iterates over arrays and hashes. 22780 * 22781 * ``` 22782 * this.iterator(this.items, function(item, id) { 22783 * // invoked for each item 22784 * }); 22785 * ``` 22786 * 22787 * @param {array|object} object 22788 */ 22789 Sifter.prototype.iterator = function(object, callback) { 22790 var iterator; 22791 if (is_array(object)) { 22792 iterator = Array.prototype.forEach || function(callback) { 22793 for (var i = 0, n = this.length; i < n; i++) { 22794 callback(this[i], i, this); 22795 } 22796 }; 22797 } else { 22798 iterator = function(callback) { 22799 for (var key in this) { 22800 if (this.hasOwnProperty(key)) { 22801 callback(this[key], key, this); 22802 } 22803 } 22804 }; 22805 } 22806 22807 iterator.apply(object, [callback]); 22808 }; 22809 22810 /** 22811 * Returns a function to be used to score individual results. 22812 * 22813 * Good matches will have a higher score than poor matches. 22814 * If an item is not a match, 0 will be returned by the function. 22815 * 22816 * @param {object|string} search 22817 * @param {object} options (optional) 22818 * @returns {function} 22819 */ 22820 Sifter.prototype.getScoreFunction = function(search, options) { 22821 var self, fields, tokens, token_count, nesting; 22822 22823 self = this; 22824 search = self.prepareSearch(search, options); 22825 tokens = search.tokens; 22826 fields = search.options.fields; 22827 token_count = tokens.length; 22828 nesting = search.options.nesting; 22829 22830 /** 22831 * Calculates how close of a match the 22832 * given value is against a search token. 22833 * 22834 * @param {mixed} value 22835 * @param {object} token 22836 * @return {number} 22837 */ 22838 var scoreValue = function(value, token) { 22839 var score, pos; 22840 22841 if (!value) return 0; 22842 value = String(value || ''); 22843 pos = value.search(token.regex); 22844 if (pos === -1) return 0; 22845 score = token.string.length / value.length; 22846 if (pos === 0) score += 0.5; 22847 return score; 22848 }; 22849 22850 /** 22851 * Calculates the score of an object 22852 * against the search query. 22853 * 22854 * @param {object} token 22855 * @param {object} data 22856 * @return {number} 22857 */ 22858 var scoreObject = (function() { 22859 var field_count = fields.length; 22860 if (!field_count) { 22861 return function() { return 0; }; 22862 } 22863 if (field_count === 1) { 22864 return function(token, data) { 22865 return scoreValue(getattr(data, fields[0], nesting), token); 22866 }; 22867 } 22868 return function(token, data) { 22869 for (var i = 0, sum = 0; i < field_count; i++) { 22870 sum += scoreValue(getattr(data, fields[i], nesting), token); 22871 } 22872 return sum / field_count; 22873 }; 22874 })(); 22875 22876 if (!token_count) { 22877 return function() { return 0; }; 22878 } 22879 if (token_count === 1) { 22880 return function(data) { 22881 return scoreObject(tokens[0], data); 22882 }; 22883 } 22884 22885 if (search.options.conjunction === 'and') { 22886 return function(data) { 22887 var score; 22888 for (var i = 0, sum = 0; i < token_count; i++) { 22889 score = scoreObject(tokens[i], data); 22890 if (score <= 0) return 0; 22891 sum += score; 22892 } 22893 return sum / token_count; 22894 }; 22895 } else { 22896 return function(data) { 22897 for (var i = 0, sum = 0; i < token_count; i++) { 22898 sum += scoreObject(tokens[i], data); 22899 } 22900 return sum / token_count; 22901 }; 22902 } 22903 }; 22904 22905 /** 22906 * Returns a function that can be used to compare two 22907 * results, for sorting purposes. If no sorting should 22908 * be performed, `null` will be returned. 22909 * 22910 * @param {string|object} search 22911 * @param {object} options 22912 * @return function(a,b) 22913 */ 22914 Sifter.prototype.getSortFunction = function(search, options) { 22915 var i, n, self, field, fields, fields_count, multiplier, multipliers, get_field, implicit_score, sort; 22916 22917 self = this; 22918 search = self.prepareSearch(search, options); 22919 sort = (!search.query && options.sort_empty) || options.sort; 22920 22921 /** 22922 * Fetches the specified sort field value 22923 * from a search result item. 22924 * 22925 * @param {string} name 22926 * @param {object} result 22927 * @return {mixed} 22928 */ 22929 get_field = function(name, result) { 22930 if (name === '$score') return result.score; 22931 return getattr(self.items[result.id], name, options.nesting); 22932 }; 22933 22934 // parse options 22935 fields = []; 22936 if (sort) { 22937 for (i = 0, n = sort.length; i < n; i++) { 22938 if (search.query || sort[i].field !== '$score') { 22939 fields.push(sort[i]); 22940 } 22941 } 22942 } 22943 22944 // the "$score" field is implied to be the primary 22945 // sort field, unless it's manually specified 22946 if (search.query) { 22947 implicit_score = true; 22948 for (i = 0, n = fields.length; i < n; i++) { 22949 if (fields[i].field === '$score') { 22950 implicit_score = false; 22951 break; 22952 } 22953 } 22954 if (implicit_score) { 22955 fields.unshift({field: '$score', direction: 'desc'}); 22956 } 22957 } else { 22958 for (i = 0, n = fields.length; i < n; i++) { 22959 if (fields[i].field === '$score') { 22960 fields.splice(i, 1); 22961 break; 22962 } 22963 } 22964 } 22965 22966 multipliers = []; 22967 for (i = 0, n = fields.length; i < n; i++) { 22968 multipliers.push(fields[i].direction === 'desc' ? -1 : 1); 22969 } 22970 22971 // build function 22972 fields_count = fields.length; 22973 if (!fields_count) { 22974 return null; 22975 } else if (fields_count === 1) { 22976 field = fields[0].field; 22977 multiplier = multipliers[0]; 22978 return function(a, b) { 22979 return multiplier * cmp( 22980 get_field(field, a), 22981 get_field(field, b) 22982 ); 22983 }; 22984 } else { 22985 return function(a, b) { 22986 var i, result, a_value, b_value, field; 22987 for (i = 0; i < fields_count; i++) { 22988 field = fields[i].field; 22989 result = multipliers[i] * cmp( 22990 get_field(field, a), 22991 get_field(field, b) 22992 ); 22993 if (result) return result; 22994 } 22995 return 0; 22996 }; 22997 } 22998 }; 22999 23000 /** 23001 * Parses a search query and returns an object 23002 * with tokens and fields ready to be populated 23003 * with results. 23004 * 23005 * @param {string} query 23006 * @param {object} options 23007 * @returns {object} 23008 */ 23009 Sifter.prototype.prepareSearch = function(query, options) { 23010 if (typeof query === 'object') return query; 23011 23012 options = extend({}, options); 23013 23014 var option_fields = options.fields; 23015 var option_sort = options.sort; 23016 var option_sort_empty = options.sort_empty; 23017 23018 if (option_fields && !is_array(option_fields)) options.fields = [option_fields]; 23019 if (option_sort && !is_array(option_sort)) options.sort = [option_sort]; 23020 if (option_sort_empty && !is_array(option_sort_empty)) options.sort_empty = [option_sort_empty]; 23021 23022 return { 23023 options : options, 23024 query : String(query || '').toLowerCase(), 23025 tokens : this.tokenize(query), 23026 total : 0, 23027 items : [] 23028 }; 23029 }; 23030 23031 /** 23032 * Searches through all items and returns a sorted array of matches. 23033 * 23034 * The `options` parameter can contain: 23035 * 23036 * - fields {string|array} 23037 * - sort {array} 23038 * - score {function} 23039 * - filter {bool} 23040 * - limit {integer} 23041 * 23042 * Returns an object containing: 23043 * 23044 * - options {object} 23045 * - query {string} 23046 * - tokens {array} 23047 * - total {int} 23048 * - items {array} 23049 * 23050 * @param {string} query 23051 * @param {object} options 23052 * @returns {object} 23053 */ 23054 Sifter.prototype.search = function(query, options) { 23055 var self = this, value, score, search, calculateScore; 23056 var fn_sort; 23057 var fn_score; 23058 23059 search = this.prepareSearch(query, options); 23060 options = search.options; 23061 query = search.query; 23062 23063 // generate result scoring function 23064 fn_score = options.score || self.getScoreFunction(search); 23065 23066 // perform search and sort 23067 if (query.length) { 23068 self.iterator(self.items, function(item, id) { 23069 score = fn_score(item); 23070 if (options.filter === false || score > 0) { 23071 search.items.push({'score': score, 'id': id}); 23072 } 23073 }); 23074 } else { 23075 self.iterator(self.items, function(item, id) { 23076 search.items.push({'score': 1, 'id': id}); 23077 }); 23078 } 23079 23080 fn_sort = self.getSortFunction(search, options); 23081 if (fn_sort) search.items.sort(fn_sort); 23082 23083 // apply limits 23084 search.total = search.items.length; 23085 if (typeof options.limit === 'number') { 23086 search.items = search.items.slice(0, options.limit); 23087 } 23088 23089 return search; 23090 }; 23091 23092 // utilities 23093 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 23094 23095 var cmp = function(a, b) { 23096 if (typeof a === 'number' && typeof b === 'number') { 23097 return a > b ? 1 : (a < b ? -1 : 0); 23098 } 23099 a = asciifold(String(a || '')); 23100 b = asciifold(String(b || '')); 23101 if (a > b) return 1; 23102 if (b > a) return -1; 23103 return 0; 23104 }; 23105 23106 var extend = function(a, b) { 23107 var i, n, k, object; 23108 for (i = 1, n = arguments.length; i < n; i++) { 23109 object = arguments[i]; 23110 if (!object) continue; 23111 for (k in object) { 23112 if (object.hasOwnProperty(k)) { 23113 a[k] = object[k]; 23114 } 23115 } 23116 } 23117 return a; 23118 }; 23119 23120 /** 23121 * A property getter resolving dot-notation 23122 * @param {Object} obj The root object to fetch property on 23123 * @param {String} name The optionally dotted property name to fetch 23124 * @param {Boolean} nesting Handle nesting or not 23125 * @return {Object} The resolved property value 23126 */ 23127 var getattr = function(obj, name, nesting) { 23128 if (!obj || !name) return; 23129 if (!nesting) return obj[name]; 23130 var names = name.split("."); 23131 while(names.length && (obj = obj[names.shift()])); 23132 return obj; 23133 }; 23134 23135 var trim = function(str) { 23136 return (str + '').replace(/^\s+|\s+$|/g, ''); 23137 }; 23138 23139 var escape_regex = function(str) { 23140 return (str + '').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1'); 23141 }; 23142 23143 var is_array = Array.isArray || (typeof $ !== 'undefined' && $.isArray) || function(object) { 23144 return Object.prototype.toString.call(object) === '[object Array]'; 23145 }; 23146 23147 var DIACRITICS = { 23148 'a': '[aá¸á¸ÄÄÃâÇÇȺⱥȦȧẠạÃäÃà ÃáÄÄÃÃ£Ã Ã¥Ä ÄÃÄ Ä]', 23149 'b': '[bâ¢Î²ÎB฿ðá]', 23150 'c': '[cÄÄÄÄÄÄÄÄCÌcÌÃçá¸á¸È»È¼ÆÆÉá´ï¼£ï½]', 23151 'd': '[dÄÄá¸á¸á¸á¸á¸á¸á¸á¸á¸á¸ÄÄD̦d̦ÆÉÆÉÆÆáµá¶á¶È¡á´ Dï½Ã°]', 23152 'e': '[eÃéÃèÃêá¸á¸ÄÄÄÄẼẽá¸á¸áººáº»ÄÄÃëÄÄȨȩÄÄá¶ÉÉÈÈ áº¾áº¿á»á»á»á» á»á»á¸á¸á¸á¸á¸á¸ÈÈẸẹá»á»â±¸á´ï¼¥ï½ ÉÇÆÆÎµ]', 23153 'f': '[fÆÆá¸á¸]', 23154 'g': '[gÉ¢â²Ç¤Ç¥ÄÄÄÄĢģÆÉ Ä Ä¡]', 23155 'h': '[hĤĥĦħḨḩáºáºá¸¤á¸¥á¸¢á¸£É¦Ê°Ç¶Æ]', 23156 'i': '[iÃÃÃìĬÄÃîÇÇÃïḮḯĨĩĮįĪīá»á»ÈÈÈÈá»á»á¸¬á¸ÆÉ¨É¨Ìáµ»á¶Ä°iIıɪIï½]', 23157 'j': '[jȷĴĵÉÉÊÉʲ]', 23158 'k': '[kÆÆêêḰḱǨǩḲḳḴḵκϰâ]', 23159 'l': '[lÅÅĽľĻļĹĺḶḷḸḹḼḽḺḻĿÅȽÆâ± ⱡⱢɫɬᶠÉÈ´ÊLï½]', 23160 'n': '[nÅÅǸǹÅÅÃñá¹á¹ Å Åá¹á¹á¹á¹á¹á¹NÌnÌÆÉ²È Æáµ°á¶É³ÈµÉ´ï¼®ï½ÅÅ]', 23161 'o': '[oÃøÃöÃóÃòÃôÇÇÅÅÅÅȮȯá»á»ÆÉµÆ Æ¡á»á»ÅÅÃõǪǫÈÈÕÖ ]', 23162 'p': '[pá¹á¹á¹á¹â±£áµ½Æ¤Æ¥áµ±]', 23163 'q': '[qêêÊ ÉÉêêqÌ]', 23164 'r': '[rÅÅÉÉÅÅÅÅá¹á¹ÈÈÈÈá¹á¹â±¤É½]', 23165 's': '[sÅÅṠṡṢṣê¨ê©ÅÅÅ Å¡ÅÅÈÈSÌsÌ]', 23166 't': '[tÅ¤Å¥á¹ªá¹«Å¢Å£á¹¬á¹Æ®ÊÈÈṰṱṮṯƬÆ]', 23167 'u': '[uŬÅÉÊỤụÃüÃúÃùÃûÇÇŰűŬů¯Æ°á»¦á»§ÅªÅ«Å¨Å©Å²Å³ÈÈâª]', 23168 'v': '[vṼṽṾṿƲÊêêâ±±Ê]', 23169 'w': '[wáºáºáºáºÅ´Åµáºáº áºáºáºáº]', 23170 'x': '[xáºáºáºáºÏ]', 23171 'y': '[yÃýỲỳŶŷŸÿỸỹáºáºá»´á»µÉÉÆ³Æ´]', 23172 'z': '[zŹźáºáºÅ½Å¾Å»Å¼áºáºáºáºÆµÆ¶]' 23173 }; 23174 23175 var asciifold = (function() { 23176 var i, n, k, chunk; 23177 var foreignletters = ''; 23178 var lookup = {}; 23179 for (k in DIACRITICS) { 23180 if (DIACRITICS.hasOwnProperty(k)) { 23181 chunk = DIACRITICS[k].substring(2, DIACRITICS[k].length - 1); 23182 foreignletters += chunk; 23183 for (i = 0, n = chunk.length; i < n; i++) { 23184 lookup[chunk.charAt(i)] = k; 23185 } 23186 } 23187 } 23188 var regexp = new RegExp('[' + foreignletters + ']', 'g'); 23189 return function(str) { 23190 return str.replace(regexp, function(foreignletter) { 23191 return lookup[foreignletter]; 23192 }).toLowerCase(); 23193 }; 23194 })(); 23195 23196 23197 // export 23198 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 23199 23200 return Sifter; 23201})); 23202 23203
23204/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) 23205 23206/***/ }), 23207/* 39 */ 23208/***/ (function(module, exports, __webpack_require__) { 23209 23210var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/** 23211 * microplugin.js 23212 * Copyright (c) 2013 Brian Reavis & contributors 23213 * 23214 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this 23215 * file except in compliance with the License. You may obtain a copy of the License at: 23216 * http://www.apache.org/licenses/LICENSE-2.0 23217 * 23218 * Unless required by applicable law or agreed to in writing, software distributed under 23219 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 23220 * ANY KIND, either express or implied. See the License for the specific language 23221 * governing permissions and limitations under the License. 23222 * 23223 * @author Brian Reavis <[email protected]> 23224 */ 23225 23226(function(root, factory) { 23227 if (true) { 23228 !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory), 23229 __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? 23230 (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : 23231 __WEBPACK_AMD_DEFINE_FACTORY__), 23232 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 23233 } else if (typeof exports === 'object') { 23234 module.exports = factory(); 23235 } else { 23236 root.MicroPlugin = factory(); 23237 } 23238}(this, function() { 23239 var MicroPlugin = {}; 23240 23241 MicroPlugin.mixin = function(Interface) { 23242 Interface.plugins = {}; 23243 23244 /** 23245 * Initializes the listed plugins (with options). 23246 * Acceptable formats: 23247 * 23248 * List (without options): 23249 * ['a', 'b', 'c'] 23250 * 23251 * List (with options): 23252 * [{'name': 'a', options: {}}, {'name': 'b', options: {}}] 23253 * 23254 * Hash (with options): 23255 * {'a': { ... }, 'b': { ... }, 'c': { ... }} 23256 * 23257 * @param {mixed} plugins 23258 */ 23259 Interface.prototype.initializePlugins = function(plugins) { 23260 var i, n, key; 23261 var self = this; 23262 var queue = []; 23263 23264 self.plugins = { 23265 names : [], 23266 settings : {}, 23267 requested : {}, 23268 loaded : {} 23269 }; 23270 23271 if (utils.isArray(plugins)) { 23272 for (i = 0, n = plugins.length; i < n; i++) { 23273 if (typeof plugins[i] === 'string') { 23274 queue.push(plugins[i]); 23275 } else { 23276 self.plugins.settings[plugins[i].name] = plugins[i].options; 23277 queue.push(plugins[i].name); 23278 } 23279 } 23280 } else if (plugins) { 23281 for (key in plugins) { 23282 if (plugins.hasOwnProperty(key)) { 23283 self.plugins.settings[key] = plugins[key]; 23284 queue.push(key); 23285 } 23286 } 23287 } 23288 23289 while (queue.length) { 23290 self.require(queue.shift()); 23291 } 23292 }; 23293 23294 Interface.prototype.loadPlugin = function(name) { 23295 var self = this; 23296 var plugins = self.plugins; 23297 var plugin = Interface.plugins[name]; 23298 23299 if (!Interface.plugins.hasOwnProperty(name)) { 23300 throw new Error('Unable to find "' + name + '" plugin'); 23301 } 23302 23303 plugins.requested[name] = true; 23304 plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]); 23305 plugins.names.push(name); 23306 }; 23307 23308 /** 23309 * Initializes a plugin. 23310 * 23311 * @param {string} name 23312 */ 23313 Interface.prototype.require = function(name) { 23314 var self = this; 23315 var plugins = self.plugins; 23316 23317 if (!self.plugins.loaded.hasOwnProperty(name)) { 23318 if (plugins.requested[name]) { 23319 throw new Error('Plugin has circular dependency ("' + name + '")'); 23320 } 23321 self.loadPlugin(name); 23322 } 23323 23324 return plugins.loaded[name]; 23325 }; 23326 23327 /** 23328 * Registers a plugin. 23329 * 23330 * @param {string} name 23331 * @param {function} fn 23332 */ 23333 Interface.define = function(name, fn) { 23334 Interface.plugins[name] = { 23335 'name' : name, 23336 'fn' : fn 23337 }; 23338 }; 23339 }; 23340 23341 var utils = { 23342 isArray: Array.isArray || function(vArg) { 23343 return Object.prototype.toString.call(vArg) === '[object Array]'; 23344 } 23345 }; 23346 23347 return MicroPlugin; 23348})); 23349 23350/***/ }), 23351/* 40 */ 23352/***/ (function(module, __webpack_exports__, __webpack_require__) { 23353 23354"use strict"; 23355/* WEBPACK VAR INJECTION */(function($) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_playerLoader__ = __webpack_require__(4); 23356 23357 23358/* harmony default export */ __webpack_exports__["a"] = ({ 23359 kalturaSession: function kalturaSession(videoPlayerId) { 23360 var partnerId = '1529571'; 23361 var playerId = '49927973'; 23362 var videoPlayer = document.getElementById(videoPlayerId); 23363 var videoId = videoPlayer.dataset.video; 23364 var body = document.querySelector('body'); 23365 23366 // https://github.com/kaltura/kaltura-player-js 23367 // config options: https://developer.kaltura.com/player/web/configuration-web 23368 if (videoId) { 23369 try { 23370 var kalturaPlayer = KalturaPlayer.setup({ // eslint-disable-line no-undef 23371 targetId: videoPlayerId, 23372 provider: { 23373 partnerId: partnerId, 23374 uiConfId: playerId, 23375 }, 23376 playback: { 23377 autoplay: true, 23378 loop: true, 23379 muted: true, 23380 }, 23381 }); 23382 kalturaPlayer.loadMedia({ 23383 entryId: videoId, 23384 }); 23385 23386 // player events: https://github.com/kaltura/playkit-js/blob/master/src/event/event-type.js 23387 kalturaPlayer.ready().then(function () { 23388 setTimeout(function () { 23389 body.classList.add('loaded'); 23390 }, 500); 23391 }); 23392 23393 } catch (e) { 23394 console.error(e.message) 23395 } 23396 } 23397 }, 23398 loadScript: function loadScript(src, callback) { 23399 var loaded = false;
23400 var tag = document.createElement('script'); 23401 var firstScriptTag = document.getElementsByTagName('script')[0]; 23402 if (!firstScriptTag) { 23403 // when loaded in jest without jsdom setup it doesn't get any element. 23404 // In jest it doesn't really make sense to do anything, because no one is watching youtube in jest 23405 return; 23406 } 23407 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 23408 tag.onload = function () { 23409 if (!loaded) { 23410 loaded = true; 23411 callback(); 23412 } 23413 }; 23414 tag.onreadystatechange = function () { 23415 if (!loaded && (this.readyState === 'complete' || this.readyState === 'loaded')) { 23416 loaded = true; 23417 callback(); 23418 } 23419 }; 23420 tag.src = src; 23421 }, 23422 slick: function slick() { 23423 // TODO: https://codepen.io/tommydunn/pen/rNxQLNq?editors=1010 23424 var body = document.querySelector('body'); 23425 23426 var slideWrapper = $('.masthead-carousel'); 23427 // iframes = slideWrapper.find('.player--masthead iframe'), 23428 // lazyImages = slideWrapper.find('.masthead-carousel__slide'), 23429 // lazyCounter = 0; 23430 23431 // POST commands to YouTube 23432 function postMessageToPlayer(player, command) { 23433 // console.log(player); 23434 if (player == null || command == null) { return; } 23435 player.contentWindow.postMessage(JSON.stringify(command), '*'); 23436 } 23437 23438 // When the slide is changing 23439 function playPauseVideo(slick, control) { 23440 var currentSlide, slideType, player; 23441 23442 currentSlide = slick.find('.slick-current'); 23443 slideType = currentSlide.data('video-type'); 23444 23445 if (slideType === 'youtube') { 23446 player = currentSlide.find('iframe').get(0); 23447 switch (control) { 23448 case 'play': 23449 postMessageToPlayer(player, { 23450 'event': 'command', 23451 'func': 'mute', 23452 }); 23453 postMessageToPlayer(player, { 23454 'event': 'command', 23455 'func': 'playVideo', 23456 }); 23457 break; 23458 case 'pause': 23459 postMessageToPlayer(player, { 23460 'event': 'command', 23461 'func': 'stopVideo', 23462 }); 23463 break; 23464 } 23465 } 23466 23467 if (slideType === 'native') { 23468 player = currentSlide.find('video').get(0); 23469 player.currentTime = 0; 23470 switch (control) { 23471 case 'play': 23472 player.play(); 23473 break; 23474 case 'pause': 23475 player.pause(); 23476 break; 23477 } 23478 } 23479 } 23480 23481 // Resize player 23482 // function resizePlayer(iframes, ratio) { 23483 // if (!iframes[0]) return; 23484 // var win = $('.masthead-carousel'), 23485 // width = win.width(), 23486 // playerWidth, 23487 // height = win.height(), 23488 // playerHeight; 23489 // // ratio = ratio || 16 / 9; 23490 23491 // iframes.each(function () { 23492 // var current = $(this); 23493 // if (width / ratio < height) { 23494 // playerWidth = Math.ceil(height * ratio); 23495 // current.width(playerWidth).height(height).css({ 23496 // left: (width - playerWidth) / 2, 23497 // top: 0, 23498 // }); 23499 // } else { 23500 // playerHeight = Math.ceil(width / ratio); 23501 // current.width(width).height(playerHeight).css({ 23502 // left: 0, 23503 // top: (height - playerHeight) / 2, 23504 // }); 23505 // } 23506 // }); 23507 // } 23508 23509 // Initialize 23510 slideWrapper.on('init', function (slick) { 23511 // setTimeout(() => { 23512 body.classList.add('loaded'); 23513 // }, 500); 23514 23515 // $(slick) = slick.currentTarget 23516 // console.log($(slick.currentTarget)); 23517 playPauseVideo($(slick.currentTarget), 'play'); 23518 23519 // resizePlayer(iframes, 16 / 9); 23520 }); 23521 23522 // JavaScript to be fired on the home page 23523 slideWrapper.slick({ 23524 dots: true,
23525 arrows: false, 23526 rows: 0, 23527 fade: true, 23528 autoplay: true, 23529 autoplaySpeed: 14000, 23530 speed: 800, 23531 pauseOnHover: false, 23532 slide: '.masthead-carousel__slide', 23533 customPaging: function (slider, i) { 23534 var title = $(slider.$slides[i]).data('title'); 23535 return '<span class="dots__item"><span class="dots__title">' + title + '</span><span class="dots__number">0' + Number(i + 1) + '</span></span>'; 23536 }, 23537 dotsClass: 'slider-dots', 23538 }); 23539 23540 slideWrapper.on('beforeChange', function (event, slick) { 23541 slick = $(slick.$slider); 23542 playPauseVideo(slick, 'pause'); 23543 }); 23544 23545 slideWrapper.on('afterChange', function (event, slick) { 23546 slick = $(slick.$slider); 23547 playPauseVideo(slick, 'play'); 23548 }); 23549 23550 // slideWrapper.on('lazyLoaded', function () { 23551 // lazyCounter++; 23552 // if (lazyCounter === lazyImages.length) { 23553 // lazyImages.addClass('show'); 23554 // slideWrapper.slick("slickPlay"); 23555 // } 23556 // }); 23557 23558 // Resize event 23559 // $(window).on('resize.slickVideoPlayer', function () { 23560 // resizePlayer(iframes, 16 / 9); 23561 // }); 23562 }, 23563 onYouTubeIframeAPIReady: function onYouTubeIframeAPIReady(playerId) { 23564 // This function creates an <iframe> (and YouTube player) after the API code downloads. 23565 // Video player output 23566 var player; 23567 var videoPlayer = document.getElementById(playerId); 23568 var videoUrl = videoPlayer.dataset.video; 23569 var body = document.querySelector('body'); 23570 23571 // Get the video ID 23572 var regex = /(https?:\/\/)?((www\.)?(youtube(-nocookie)?|youtube.googleapis)\.com.*(v\/|v=|vi=|vi\/|e\/|embed\/|user\/.*\/u\/\d+\/)|youtu\.be\/)([_0-9a-z-]+)/i; 23573 var videoId = videoUrl.match(regex); 23574 23575 window.YT.ready(function () { 23576 player = new window.YT.Player(videoPlayer, { // eslint-disable-line no-undef 23577 height: '390', 23578 width: '640', 23579 videoId: videoId[7], 23580 playerVars: { 23581 'playsinline': 1, 23582 'autoplay': 1, 23583 'controls': 0, 23584 'disablekb': 1, 23585 'enablejsapi': 1, 23586 'fs': 0, 23587 'loop': 1, 23588 'modestbranding': 1, 23589 }, 23590 events: { 23591 'onReady': onPlayerReady, 23592 onStateChange: 23593 function (e) { 23594 // console.log(window.YT.PlayerState); 23595 if (e.data === window.YT.PlayerState.CUED || e.data === window.YT.PlayerState.UNSTARTED || e.data === window.YT.PlayerState.ENDED || e.data === window.YT.PlayerState.PAUSED) { 23596 player.playVideo(); 23597 } 23598 }, 23599 }, 23600 }); 23601 }); 23602 23603 // Called when the player's state changes 23604 // Available states: buffering, unstarted, cued, playing, paused, ended 23605 function onPlayerReady() { 23606 player.playVideo(); 23607 player.mute(); 23608 23609 setTimeout(function () { 23610 body.classList.add('loaded'); 23611 }, 500); 23612 } 23613 }, 23614 init: function init() { 23615 var this$1 = this; 23616 23617 // Masthead carousel 23618 this.slick(); 23619 23620 // Masthead videos 23621 var videoPlayers = document.querySelectorAll('.player--masthead'); 23622 if (videoPlayers) { 23623 videoPlayers.forEach(function (videoPlayer) { 23624 var videoPlayerId = videoPlayer.id; 23625 var videoId = videoPlayer.dataset.video; 23626 var source = videoPlayer.dataset.source; 23627 // data-source resolves the platform; fall back to legacy detection. 23628 if (source === 'youtube' || (!source && videoId && videoId.indexOf('youtube') > -1)) { 23629 // Loads the IFrame Player API code asynchronously. 23630 this$1.onYouTubeIframeAPIReady(videoPlayerId); 23631 } else if (source === 'bunny') { 23632 // Bunny Stream background video (muted, looping autoplay) 23633 Object(__WEBPACK_IMPORTED_MODULE_0__util_playerLoader__["a" /* loadBunnyPlayer */])(videoPlayer, { background: true }); 23634 } else if (videoId) { // Kaltura Web Player 23635 // Utilizes the TV Studio Player (V7) in Kaltura Management Console (KMC) 23636 // https://developer.kaltura.com/player/web/getting-started-web 23637 this$1.kalturaSession(videoPlayerId); 23638 } 23639 }); 23640 } 23641 }, 23642 finalize: function finalize() { 23643 // JavaScript to be fired on the home page, after the init JS 23644 }, 23645}); 23646 23647/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(0))) 23648 23649/***/ }), 23650/* 41 */ 23651/***/ (function(module, __webpack_exports__, __webpack_require__) { 23652 23653"use strict"; 23654/* harmony default export */ __webpack_exports__["a"] = ({
23655 init: function init() { 23656 // JavaScript to be fired on the about us page 23657 }, 23658}); 23659 23660 23661/***/ }), 23662/* 42 */ 23663/***/ (function(module, __webpack_exports__, __webpack_require__) { 23664 23665"use strict"; 23666/* WEBPACK VAR INJECTION */(function($) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_isotope_layout__ = __webpack_require__(8); 23667/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_isotope_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_isotope_layout__); 23668/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_infinite_scroll__ = __webpack_require__(9); 23669/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_infinite_scroll___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_infinite_scroll__); 23670/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_imagesloaded__ = __webpack_require__(7); 23671/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_imagesloaded___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_imagesloaded__); 23672 23673 23674 23675 23676/* harmony default export */ __webpack_exports__["a"] = ({ 23677 iso: function iso() { 23678 var elem = document.querySelector('.listing--contributors'); 23679 23680 if (elem) { 23681 var iso; 23682 var $select = $('.input-iso-select'); 23683 var $selectize; 23684 var $filterCount = $('.total-posts-filtered'); 23685 23686 // Instantiate selectize to use in conjunction 23687 if ($select) { 23688 $selectize = $select.selectize({ 23689 closeAfterSelect: true, 23690 }); 23691 23692 $selectize.on('click', function () { 23693 var $active = $selectize.find('.selectize-input'); 23694 if ($active.hasClass('input-active')) { 23695 $selectize.close(); 23696 } 23697 }); 23698 } 23699 23700 // Infinite scroll 23701 __WEBPACK_IMPORTED_MODULE_2_imagesloaded___default()(elem, function () { 23702 if ($select) { 23703 iso = new __WEBPACK_IMPORTED_MODULE_0_isotope_layout___default.a(elem, { 23704 itemSelector: '.col', 23705 layoutMode: 'fitRows', 23706 percentPosition: true, 23707 // stagger: 50, 23708 fitRows: { 23709 // set to the element 23710 gutter: 16, 23711 columnWidth: '.col', 23712 }, 23713 hiddenStyle: { 23714 opacity: 0, 23715 // transform: 'translateY(10px)', 23716 }, 23717 visibleStyle: { 23718 opacity: 1, 23719 // transform: 'translateY(0px)', 23720 }, 23721 }); 23722 23723 // set up URL params 23724 var url = new URL(window.location.href); 23725 var params = new URLSearchParams(url.searchParams); 23726 23727 // First get searchparams on init 23728 if (params.get('expertise') || params.get('initial')) { 23729 var filters$1 = {}; 23730 23731 filters$1['expertise'] = params.get('expertise') ? params.get('expertise') : ''; 23732 filters$1['initial'] = params.get('initial') ? params.get('initial') : ''; 23733 23734 console.log(concatValues(filters$1)); 23735 iso.arrange({ 23736 filter: concatValues(filters$1), 23737 }); 23738 23739 if ($selectize && filters$1['expertise']) { 23740 var expertise$1 = $selectize[0].selectize; 23741 expertise$1.setValue(params.get('expertise')); 23742 } 23743 23744 if ($selectize && filters$1['initial']) { 23745 var initial = $selectize[1].selectize; 23746 initial.setValue(params.get('initial')); 23747 } 23748 } 23749 23750 // Filter on selection 23751 // check if selectize is active, and use that as a trigger if so 23752 if ($selectize) { 23753 // fetch the instance 23754 var expertise = $selectize[0].selectize; 23755 23756 // store filter for each group 23757 var filters = {}; 23758 23759 expertise.on('change', function (e) { 23760 filters['expertise'] = e; 23761 var filterValue = concatValues(filters); 23762 iso.arrange({ 23763 filter: filterValue, 23764 }); 23765 23766 // set filter in hash 23767 params.set('expertise', e); 23768 23769 // change the search property of the main url 23770 url.search = params.toString(); 23771 23772 // Replace current querystring with the new one 23773 history.pushState(null, null, '?' + params.toString()); 23774 23775 updateFilterCount(); 23776 }); 23777 23778 var selectizeName = $selectize[1].selectize; 23779 23780 selectizeName.on('change', function (e) { 23781 filters['name'] = e; 23782 var filterValue = concatValues(filters); 23783 iso.arrange({ 23784 filter: filterValue, 23785 }); 23786 23787 params.set('initial', e); 23788 23789 // change the search property of the main url 23790 url.search = params.toString(); 23791 23792 // Replace current querystring with the new one 23793 history.pushState(null, null, '?' + params.toString()); 23794 23795 updateFilterCount(); 23796 }); 23797 } else { // otherwise, use the <select> 23798 // bind filter on select change 23799 $select.on('change', function () { 23800 // get filter value from option value 23801 var filterValue = $(this).value; 23802 23803 iso.arrange({ 23804 filter: filterValue, 23805 }); 23806 23807 updateFilterCount(); 23808 }); 23809 } 23810 23811 // flatten object by concatting values 23812 function concatValues(obj) { // eslint-disable-line no-inner-declarations 23813 var value = ''; 23814 for (var prop in obj) { 23815 value += obj[prop]; 23816 } 23817 return value; 23818 } 23819 23820 function updateFilterCount() { // eslint-disable-line no-inner-declarations 23821 $filterCount.text(iso.filteredItems.length); 23822 } 23823 } 23824 23825 // make imagesLoaded available for InfiniteScroll 23826 __WEBPACK_IMPORTED_MODULE_1_infinite_scroll___default.a.imagesLoaded = __WEBPACK_IMPORTED_MODULE_2_imagesloaded___default.a; 23827 23828 var infScroll = new __WEBPACK_IMPORTED_MODULE_1_infinite_scroll___default.a(elem, { // eslint-disable-line no-unused-vars 23829 path: '.next', 23830 append: '.inf-post', 23831 history: 'push', 23832 outlayer: iso, 23833 // debug: true, 23834 scrollThreshold: 700, 23835 hideNav: '.pagination', 23836 status: '.page-load-status', 23837 }); 23838 }); 23839 23840 // imagesloaded(elem).on('progress', function () { 23841 // iso.layout(); 23842 // }); 23843 } 23844 },
23845 init: function init() { 23846 // JavaScript to be fired on the contributors page 23847 this.iso(); 23848 }, 23849}); 23850 23851/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(0))) 23852 23853/***/ }), 23854/* 43 */ 23855/***/ (function(module, __webpack_exports__, __webpack_require__) { 23856 23857"use strict"; 23858/* harmony default export */ __webpack_exports__["a"] = ({ 23859 init: function init() { 23860 // JavaScript to be fired on the topic guide page 23861 var el = document.querySelector('.sticky-labels'); 23862 var pillars = document.querySelectorAll('.pillar-sticky__scrolly'); 23863 var observer = new IntersectionObserver(function (ref) { 23864 var e = ref[0]; 23865 23866 return e.target.classList.toggle('is-pinned', e.intersectionRatio < 1); 23867 }, 23868 { threshold: [1] } 23869 ); 23870 23871 observer.observe(el); 23872 pillars.forEach(function (pillar) { 23873 observer.observe(pillar); 23874 }) 23875 }, 23876}); 23877 23878 23879/***/ }), 23880/* 44 */ 23881/***/ (function(module, __webpack_exports__, __webpack_require__) { 23882 23883"use strict"; 23884/* WEBPACK VAR INJECTION */(function($) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_imagesloaded__ = __webpack_require__(7); 23885/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_imagesloaded___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_imagesloaded__); 23886/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_isotope_layout__ = __webpack_require__(8); 23887/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_isotope_layout___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_isotope_layout__); 23888/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_infinite_scroll__ = __webpack_require__(9); 23889/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_infinite_scroll___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_infinite_scroll__); 23890 23891 23892 23893 23894/* harmony default export */ __webpack_exports__["a"] = ({ 23895 isotope: function isotope() { 23896 // Set up isotope options 23897 var isoOptions = { 23898 itemSelector: '.col', 23899 layoutMode: 'fitRows', 23900 percentPosition: true, 23901 stagger: 100, 23902 fitRows: { 23903 // set to the element 23904 gutter: 16, 23905 columnWidth: '.col', 23906 }, 23907 hiddenStyle: { 23908 opacity: 0, 23909 transform: 'translateY(10px)', 23910 }, 23911 visibleStyle: { 23912 opacity: 1, 23913 transform: 'translateY(0px)', 23914 }, 23915 }; 23916 23917 // Instantiate selectize to use in conjunction 23918 var select = document.querySelector('.input-iso-select'); 23919 if (select) { 23920 var $selectize = $('.input-iso-select').selectize({ 23921 create: true, 23922 sortField: 'text', 23923 }); 23924 } 23925 23926 23927 var iso; 23928 23929 // initialize Isotope 23930 function episodesIso() { 23931 var grid = document.querySelector('.listing--videos-episodes'); 23932 23933 if (grid) { 23934 __WEBPACK_IMPORTED_MODULE_0_imagesloaded___default()(grid, function () { 23935 if (select) { 23936 // images have loaded 23937 iso = new __WEBPACK_IMPORTED_MODULE_1_isotope_layout___default.a(grid, isoOptions); 23938 23939 // Filter on selection 23940 // check if selectize is active, and use that as a trigger if so 23941 if ($selectize) { 23942 // fetch the instance 23943 var selectize = $selectize[0].selectize; 23944 23945 selectize.on('change', function (e) { 23946 console.log(e); 23947 iso.arrange({ 23948 filter: e, 23949 }); 23950 }); 23951 } else { // otherwise, use the <select> 23952 // bind filter on select change 23953 select.addEventListener('change', function () { 23954 // get filter value from option value 23955 var filterValue = this.value; 23956 // console.log(filterValue); 23957 23958 iso.arrange({ 23959 filter: filterValue, 23960 }); 23961 }); 23962 } 23963 } 23964 23965 // make imagesLoaded available for InfiniteScroll 23966 __WEBPACK_IMPORTED_MODULE_2_infinite_scroll___default.a.imagesLoaded = __WEBPACK_IMPORTED_MODULE_0_imagesloaded___default.a; 23967 23968 // Infinite scroll 23969 var infScroll = new __WEBPACK_IMPORTED_MODULE_2_infinite_scroll___default.a(grid, { // eslint-disable-line no-unused-vars 23970 path: '.next', 23971 append: '.inf-post', 23972 history: 'push', 23973 outlayer: iso, 23974 // debug: true, 23975 scrollThreshold: 450, 23976 hideNav: '.pagination', 23977 status: '.page-load-status', 23978 }); 23979 }); 23980 } 23981 } 23982 23983 // On sub-nav item click, check if Episodes wrapper has class active
23984 var subNav = document.querySelectorAll('.sub-nav__item'); 23985 var episodes = document.querySelector('#episodes'); 23986 23987 subNav.forEach(function (item) { 23988 item.addEventListener('click', function () { 23989 if (episodes.classList.contains('active')) { 23990 episodesIso(); 23991 } else { 23992 console.log('destroyed'); 23993 iso.destroy(); 23994 } 23995 // set flag 23996 // isActive = !isActive; 23997 }); 23998 }); 23999 24000 24001 }, 24002 init: function init() { 24003 this.isotope(); 24004 24005 // JavaScript to be fired on the episodes page 24006 var toggleLink = document.querySelectorAll('.tab-toggle__link'); 24007 var toggleContent = document.querySelectorAll('.tab-toggle__content'); 24008 24009 toggleLink.forEach(function (link) { 24010 link.addEventListener('click', function (e) { 24011 e.preventDefault(); 24012 var id = this.getAttribute('href'); 24013 24014 [].forEach.call(toggleLink, function (el) { 24015 el.classList.remove('active'); 24016 }); 24017 24018 // find corresponding content 24019 var content = document.querySelector(id); 24020 if (content) { 24021 link.classList.add('active'); 24022 24023 [].forEach.call(toggleContent, function (el) { 24024 el.classList.remove('active'); 24025 }); 24026 24027 content.classList.add('active'); 24028 } 24029 }); 24030 }); 24031 }, 24032}); 24033 24034/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(0))) 24035 24036/***/ }), 24037/* 45 */ 24038/***/ (function(module, __webpack_exports__, __webpack_require__) { 24039 24040"use strict"; 24041/* WEBPACK VAR INJECTION */(function(jQuery) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_playerLoader__ = __webpack_require__(4); 24042// import kaltura from 'kaltura-client'; 24043 24044 24045// Holds the active YouTube player so the format toggle can switch the video 24046// in-place (preserving its state/event handlers) rather than recreating it. 24047var ytPlayer = null; 24048
24049// The platform last mounted in #video-player. Set in init() and at mount time on 24050// each cross-platform switch; used by replacePlayerEl to know which player to tear 24051// down. (The same-vs-cross decision in switchPlayer uses live-player checks, not 24052// this, because this value lags during an async SDK load.) 24053var currentSource = null; 24054 24055// YouTube watch-URL â 11-char video id (mirrors the legacy toggle regex). 24056var YT_ID_REGEX = /(?:youtube(?:-nocookie)?\.com.*(?:v=|embed\/|v\/)|youtu\.be\/)([_0-9a-z-]{11})/i; 24057 24058// Monotonic token for cross-platform switches. Incremented at the start of each 24059// switch; deferred SDK-load callbacks bail if a newer switch has superseded them 24060// (prevents a slow script load from mounting a player the user already left). 24061var switchToken = 0; 24062 24063// The YouTube session registers a window 'unload' progress-write. Bind it only 24064// once per page (it reads the module-scoped current ytPlayer) so repeated 24065// cross-platform returns to YouTube don't accumulate duplicate unload handlers. 24066var ytUnloadBound = false; 24067 24068// Flushes the current YouTube player's watch position to the tracker. Set by the 24069// YouTube session when it mounts (closes over its tracker context); called before 24070// the player is destroyed on a source switch so "Continue Watching" isn't lost. 24071var ytFlushProgress = null; 24072 24073// Tear down whatever player currently occupies #video-player and replace it with 24074// a fresh empty container carrying the new id/source. Required because 24075// new YT.Player()/KalturaPlayer.setup() replace or mutate the node, so loading a 24076// different platform needs a clean div to mount into. Captures the parent before 24077// teardown so it works whether the old player removed the node (YouTube) or left 24078// it in place (Kaltura/Bunny). 24079function replacePlayerEl(id, source) { 24080 var old = document.getElementById('video-player'); 24081 var parent = old ? old.parentNode : null; 24082 var anchor = old ? old.nextSibling : null; 24083 try { 24084 if (currentSource === 'youtube' && ytPlayer && typeof ytPlayer.destroy === 'function') { 24085 // Capture the watch position BEFORE destroying â the YouTube tracker 24086 // otherwise only writes on pause/ended/unload, and destroy() + null 24087 // would drop the current position on a source switch. 24088 if (ytFlushProgress) { ytFlushProgress(); } 24089 ytPlayer.destroy(); 24090 } else if (currentSource === 'kaltura' && window.KalturaPlayer && typeof window.KalturaPlayer.getPlayer === 'function') { 24091 var kp = window.KalturaPlayer.getPlayer('video-player'); 24092 if (kp) { kp.destroy(); } 24093 } 24094 } catch (e) { 24095 // Best-effort teardown; rebuild the container regardless. 24096 } 24097 ytPlayer = null; 24098 var leftover = document.getElementById('video-player'); 24099 if (leftover && leftover.parentNode) { 24100 leftover.parentNode.removeChild(leftover); 24101 } 24102 var fresh = document.createElement('div'); 24103 fresh.id = 'video-player'; 24104 fresh.className = 'player'; 24105 fresh.style.cssText = 'width: 770px;height: 360px'; 24106 fresh.dataset.video = id; 24107 fresh.dataset.source = source; 24108 if (parent) { 24109 parent.insertBefore(fresh, anchor); 24110 } 24111 return fresh; 24112} 24113 24114// Switch the single-video player to (id, source) from a format-toggle click. 24115// Same platform â fast in-place switch (preserves the loaded player + its 24116// tracking/auto-advance handlers). Different platform â rebuild the container and 24117// load the target platform fresh, with autoplay (the click is a user gesture) and 24118// the cover overlay hidden. `self` is the route object (for loadScript + sessions). 24119function switchPlayer(self, id, source) { 24120 // Every click bumps the token, so any in-flight cross-platform load is 24121 // cancelled (its mount() bails). This must happen on EVERY click â including 24122 // ones that look "same-platform" â or a pending load could still mount a 24123 // player the user has since clicked away from. 24124 var token = ++switchToken; 24125 24126 // Decide in-place vs rebuild from the ACTUALLY-LIVE player, not from 24127 // currentSource (which lags during an async load). If the requested 24128 // platform's player isn't live right now, fall through to a fresh rebuild. 24129 var kalturaLive = window.KalturaPlayer && typeof window.KalturaPlayer.getPlayer === 'function' && window.KalturaPlayer.getPlayer('video-player'); 24130 var playerEl = document.getElementById('video-player'); 24131 var bunnyIframe = playerEl ? playerEl.querySelector('iframe') : null; 24132 var bunnyLive = bunnyIframe && bunnyIframe.src.indexOf('mediadelivery.net') > -1; 24133 24134 if (source === 'youtube' && ytPlayer && typeof ytPlayer.loadVideoById === 'function') { 24135 var m = id.match(YT_ID_REGEX); 24136 if (m) { ytPlayer.loadVideoById(m[1]); } 24137 return; 24138 } 24139 if (source === 'bunny' && bunnyLive) { 24140 Object(__WEBPACK_IMPORTED_MODULE_0__util_playerLoader__["b" /* swapBunnyVideo */])(playerEl, id, { background: false }); 24141 return; 24142 } 24143 if (source === 'kaltura' && kalturaLive) { 24144 try { 24145 // Tear down the existing Kaltura player before recreating so a 24146 // Short/Long switch can't double-instantiate. 24147 var existing = window.KalturaPlayer.getPlayer('video-player'); 24148 if (existing) { existing.destroy(); } 24149 var kalturaPlayer = KalturaPlayer.setup({ // eslint-disable-line no-undef 24150 targetId: 'video-player', 24151 provider: { partnerId: '1529571', uiConfId: '49927973' }, 24152 playback: { autoplay: true }, 24153 }); 24154 kalturaPlayer.loadMedia({ entryId: id }); 24155 } catch (err) { 24156 console.error(err.message); // eslint-disable-line no-console 24157 } 24158 return; 24159 } 24160
24161 // Cross-platform (or the target isn't live yet): clean container, then load 24162 // the target platform. The `token` captured above guards the async SDK-load 24163 // callbacks below â a stale callback bails instead of mounting the wrong 24164 // player. currentSource is set only at mount time, so a failed/blocked script 24165 // load doesn't strand the toggle treating the same target as "same-platform". 24166 replacePlayerEl(id, source); 24167 var overlay = document.querySelector('.video-player-wrap__image'); 24168 if (overlay) { overlay.style.display = 'none'; } 24169 24170 var mount = function () { 24171 if (token !== switchToken) { 24172 return; // a newer switch superseded this one 24173 } 24174 currentSource = source; 24175 if (source === 'youtube') { 24176 self.onYouTubeIframeAPIReady({ autoplay: true }); 24177 } else if (source === 'bunny') { 24178 self.bunnySession({ autoplay: true }); 24179 } else if (source === 'kaltura') { 24180 self.kalturaSession({ autoplay: true }); 24181 } 24182 }; 24183 24184 if (source === 'youtube' && !(window.YT && typeof window.YT.ready === 'function')) { 24185 self.loadScript('https://www.youtube.com/iframe_api', mount); 24186 } else if (source === 'kaltura' && !window.KalturaPlayer) { 24187 self.loadScript('https://cdnapisec.kaltura.com/p/1529571/embedPlaykitJs/flavorId/861301/uiconf_id/49927973', mount); 24188 } else { 24189 // SDK already present (or Bunny, which lazy-loads Player.js inside bunnySession). 24190 mount(); 24191 } 24192} 24193 24194/* harmony default export */ __webpack_exports__["a"] = ({ 24195 contentToggle: function contentToggle() { 24196 var toggle = document.querySelectorAll('.tab-toggle'); 24197 24198 if (toggle) { 24199 toggle.forEach(function (item) { 24200 var toggleLink = item.querySelectorAll('.tab-toggle__link'); 24201 var toggleContent = item.querySelectorAll('.tab-toggle__content'); 24202 24203 toggleLink.forEach(function (link) { 24204 link.addEventListener('click', function (e) { 24205 e.preventDefault(); 24206 var id = this.getAttribute('href'); 24207 24208 [].forEach.call(toggleLink, function (el) { 24209 el.classList.remove('active'); 24210 }); 24211 24212 // find corresponding content 24213 var content = document.querySelector(id); 24214 if (content) { 24215 link.classList.add('active'); 24216 24217 [].forEach.call(toggleContent, function (el) { 24218 el.classList.remove('active'); 24219 }); 24220 24221 content.classList.add('active'); 24222 } 24223 }); 24224 }); 24225 }); 24226 } 24227 }, 24228 loadScript: function loadScript(src, callback) { 24229 var loaded = false; 24230 var tag = document.createElement('script'); 24231 var firstScriptTag = document.getElementsByTagName('script')[0]; 24232 if (!firstScriptTag) { 24233 // when loaded in jest without jsdom setup it doesn't get any element. 24234 // In jest it doesn't really make sense to do anything, because no one is watching youtube in jest 24235 return; 24236 } 24237 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 24238 tag.onload = function () { 24239 if (!loaded) { 24240 loaded = true; 24241 callback(); 24242 } 24243 }; 24244 tag.onreadystatechange = function () { 24245 if (!loaded && (this.readyState === 'complete' || this.readyState === 'loaded')) { 24246 loaded = true; 24247 callback(); 24248 } 24249 }; 24250 tag.src = src; 24251 }, 24252 onYouTubeIframeAPIReady: function onYouTubeIframeAPIReady(ref) { 24253 if ( ref === void 0 ) ref = {}; 24254 var autoplay = ref.autoplay; if ( autoplay === void 0 ) autoplay = false; 24255 24256 // This function creates an <iframe> (and YouTube player) 24257 // after the API code downloads. `autoplay` is set when a cross-platform 24258 // format-toggle click recreates the player (a user gesture); the initial
24259 // page load calls this with no args (autoplay off, overlay-driven). 24260 24261 // Video player output 24262 var player; 24263 var videoPlayer = document.getElementById('video-player'); 24264 var videoUrl = videoPlayer.dataset.video; 24265 var article = document.querySelector('article.single-video'); 24266 var userId = article.dataset.uid; 24267 var postId = article.dataset.pid; 24268 var videoImage = document.querySelector('.video-player-wrap__image'); 24269 24270 // Get the video ID 24271 var regex = /(https?:\/\/)?((www\.)?(youtube(-nocookie)?|youtube.googleapis)\.com.*(v\/|v=|vi=|vi\/|e\/|embed\/|user\/.*\/u\/\d+\/)|youtu\.be\/)([_0-9a-z-]+)/i; 24272 var videoId = videoUrl.match(regex); 24273 24274 // Set duration 24275 var params = new URLSearchParams(window.location.search); 24276 var watched = params.get('watched'); 24277 var seconds = watched ? watched : 0; 24278 24279 window.YT.ready(function () { 24280 player = new window.YT.Player(videoPlayer, { // eslint-disable-line no-undef 24281 height: '390', 24282 width: '640', 24283 videoId: videoId[7], 24284 startSeconds: seconds, 24285 playerVars: { 24286 'playsinline': 1, 24287 'rel': 0, 24288 'color': 'white', 24289 'autoplay': autoplay ? 1 : 0, 24290 }, 24291 events: { 24292 // 'onReady': onPlayerReady, 24293 'onStateChange': onPlayerStateChange, 24294 }, 24295 }); 24296 // Expose for in-place video switching from the format toggle. 24297 ytPlayer = player; 24298 }); 24299 24300 // If a video exists, we'll use it as an initial "play" button, on click the video will play and the image will be hidden 24301 if (videoImage) { 24302 videoImage.addEventListener('click', function () { 24303 player.playVideo(); 24304 videoImage.style.display = 'none'; 24305 }); 24306 } 24307 24308 // Redirect to next video in playlist, if it exists 24309 function redirectNext() { 24310 var nextVideo = false, 24311 playlist = document.querySelector('#current-playlist'); 24312 24313 if (playlist) { 24314 var currentVideo = playlist.querySelector('.list-item--playing'); 24315 var sibling = currentVideo.nextElementSibling; 24316 if (sibling) { 24317 nextVideo = sibling.querySelector('a'); 24318 location.assign(nextVideo.href); 24319 } 24320 } 24321 } 24322 24323 // Called when the player's state changes 24324 // Available states: buffering, unstarted, cued, playing, paused, ended 24325 function onPlayerStateChange() { 24326 var state = player.getPlayerState(); 24327 24328 if (state == 2) { // Paused 24329 var totalTime = player.getDuration(); // Total video length (in seconds) 24330 var currentTime = player.getCurrentTime(); // Current elasped time (in seconds) 24331 var percentage = (currentTime / totalTime) * 100; // Percentage of video watched 24332 percentage = Math.round(percentage); 24333 24334 // Add video data to custom user meta 24335 UpdateVideoTracker(currentTime, percentage); // This is only used for front-end display so a rounded number is fine 24336 } 24337 24338 // Completed 24339 if (state == 0) { // Ended 24340 UpdateVideoTracker(player.getCurrentTime(), 100); 24341 24342 redirectNext(); 24343 } 24344 } 24345 24346 // Add percentage to video tracker 24347 function UpdateVideoTracker(duration, percentage) { 24348 jQuery.ajax({ 24349 type: 'post', 24350 dataType: 'json', 24351 url: ajax_obj.ajax_url, // eslint-disable-line no-undef 24352 data: { // TODO: Should this be stored as postmeta instead? We will need to query this meta data throughout 24353 action: 'video_tracker', 24354 post_id: postId, 24355 user_id: userId, 24356 percentage: percentage, 24357 duration: duration, 24358 _ajax_nonce: ajax_obj.nonce, // eslint-disable-line no-undef 24359 }, 24360 success: function (response) { 24361 if (response.type != 'success') { 24362 alert('Sorry, an error occured. Please try again.'); 24363 } 24364 }, 24365 }); 24366 } 24367
24368 // Expose a progress flush so a cross-platform source switch can capture the 24369 // current watch position before this player is destroyed (replacePlayerEl 24370 // calls this before ytPlayer.destroy()). Reads the module-scoped ytPlayer. 24371 ytFlushProgress = function () { 24372 if (!ytPlayer || typeof ytPlayer.getPlayerState !== 'function') { 24373 return; 24374 } 24375 var state = ytPlayer.getPlayerState(); 24376 if (state === 1 || state === 2) { // playing or paused 24377 var totalTime = ytPlayer.getDuration(); 24378 var currentTime = ytPlayer.getCurrentTime(); 24379 var percentage = Math.round((currentTime / totalTime) * 100); 24380 UpdateVideoTracker(currentTime, percentage); 24381 } 24382 }; 24383 24384 // On page close, if video is playing or paused, mark as Watched or Continue 24385 // Watching. Bind ONCE per page and read the module-scoped current ytPlayer, 24386 // so repeated cross-platform returns to YouTube don't stack duplicate unload 24387 // handlers (which would write skewed progress and read destroyed players). 24388 // postId/userId are page-constant, so the first binding's closure is correct. 24389 if (!ytUnloadBound) { 24390 ytUnloadBound = true; 24391 window.addEventListener('unload', function () { 24392 if (!ytPlayer || typeof ytPlayer.getPlayerState !== 'function') { 24393 return; // no live YouTube player (e.g. switched to another source) 24394 } 24395 if (ytPlayer.getPlayerState() == (1 || 2)) { // Playing or paused 24396 var totalTime = ytPlayer.getDuration(); // Total video length (in seconds) 24397 var currentTime = ytPlayer.getCurrentTime(); // Current elasped time (in seconds) 24398 var percentage = (currentTime / totalTime) * 100; // Percentage of video watched 24399 percentage = Math.round(percentage); // This is only used for front-end display so a rounded number is fine 24400 24401 console.log(percentage); 24402 // Add video data to custom user meta 24403 UpdateVideoTracker(currentTime, percentage); 24404 } 24405 }); 24406 } 24407 }, 24408 bunnySession: function bunnySession(ref) { 24409 if ( ref === void 0 ) ref = {}; 24410 var autoplay = ref.autoplay; if ( autoplay === void 0 ) autoplay = false; 24411 24412 // Bunny Stream player on a single video page, with progress tracking. 24413 // `autoplay` is set when a cross-platform format-toggle click recreates 24414 // the player; the initial page load passes no args (overlay-driven). 24415 var videoPlayer = document.getElementById('video-player'); 24416 if (!videoPlayer) { 24417 return; 24418 } 24419 24420 // Custom overlay image (custom_overlay_image), sits above the player. 24421 var videoImage = document.querySelector('.video-player-wrap__image'); 24422 24423 var article = document.querySelector('article.single-video'); 24424 var userId = article ? article.dataset.uid : null; 24425 var postId = article ? article.dataset.pid : null; 24426 24427 // Resume from the watched position when present â mirrors the YouTube 24428 // (startSeconds) and Kaltura (startTime) paths so "Continue Watching" 24429 // links restore the same place on Bunny. 24430 var params = new URLSearchParams(window.location.search); 24431 var watched = params.get('watched'); 24432 var startSeconds = watched ? parseInt(watched, 10) : 0; 24433 24434 function BunnyUpdateVideoTracker(duration, percentage) { 24435 jQuery.ajax({ 24436 type: 'post', 24437 dataType: 'json', 24438 url: ajax_obj.ajax_url, // eslint-disable-line no-undef 24439 data: { 24440 action: 'video_tracker', 24441 post_id: postId, 24442 user_id: userId, 24443 percentage: percentage, 24444 duration: duration, 24445 _ajax_nonce: ajax_obj.nonce, // eslint-disable-line no-undef 24446 }, 24447 }); 24448 } 24449 24450 // Cache the latest position from the high-frequency timeupdate event 24451 // (no network here), and only write progress on the coarse pause/ended 24452 // events â matching the YouTube (state 2 / 0) and Kaltura tracker cadence 24453 // so we don't flood admin-ajax / wp_ctt_video_tracker. 24454 var lastSeconds = 0; 24455 var lastDuration = 0; 24456 24457 var onTimeUpdate = function (data) { 24458 var d = (typeof data === 'string') ? JSON.parse(data) : data; 24459 lastSeconds = d.seconds || 0; 24460 lastDuration = d.duration || 0; 24461 }; 24462 24463 var onPause = function () { 24464 if (!userId) { 24465 return; 24466 } 24467 var percentage = lastDuration ? Math.round((lastSeconds / lastDuration) * 100) : 0; 24468 BunnyUpdateVideoTracker(Math.round(lastSeconds), percentage); 24469 }; 24470 24471 var onEnded = function () { 24472 if (userId) { 24473 BunnyUpdateVideoTracker(Math.round(lastSeconds || lastDuration), 100); 24474 } 24475 // Auto-advance to the next playlist item on completion, mirroring the 24476 // YouTube (redirectNext) and Kaltura ('idle' state) behaviour. 24477 var playlist = document.querySelector('#current-playlist'); 24478 if (playlist) { 24479 var currentVideo = playlist.querySelector('.list-item--playing'); 24480 var sibling = currentVideo ? currentVideo.nextElementSibling : null; 24481 if (sibling) { 24482 var nextVideo = sibling.querySelector('a'); 24483 if (nextVideo) { 24484 location.assign(nextVideo.href); 24485 } 24486 } 24487 } 24488 }; 24489 24490 var render = function () { 24491 // Don't autoplay â mirror the YouTube path: the custom overlay (if 24492 // present) is the play affordance; otherwise the iframe's own 24493 // controls start playback. 24494 var player = Object(__WEBPACK_IMPORTED_MODULE_0__util_playerLoader__["a" /* loadBunnyPlayer */])(videoPlayer, { 24495 background: false, 24496 autoplay: autoplay, 24497 start: startSeconds, 24498 onTimeUpdate: onTimeUpdate, 24499 onPause: onPause, 24500 onEnded: onEnded, 24501 }); 24502 24503 // Overlay click â start playback and hide the overlay (mirrors YouTube). 24504 if (videoImage) { 24505 videoImage.addEventListener('click', function () { 24506 if (player && typeof player.play === 'function') { 24507 player.play(); 24508 } 24509 videoImage.style.display = 'none'; 24510 }); 24511 } 24512 }; 24513 24514 // Player.js powers the events; load it on demand if not already present. 24515 if (window.playerjs) { 24516 render(); 24517 } else { 24518 this.loadScript('https://assets.mediadelivery.net/playerjs/playerjs-latest.min.js', render); 24519 } 24520 }, 24521 loadFormats: function loadFormats() { 24522 // Short/Long format toggle â platform-aware (YouTube / Bunny / Kaltura). 24523 var formats = document.querySelectorAll('.video-format'); 24524 var videoPlayer = document.getElementById('video-player'); 24525 if (!formats.length || !videoPlayer) { 24526 return; 24527 } 24528 24529 var self = this;
24530 formats.forEach(function (link) { 24531 link.addEventListener('click', function (e) { 24532 e.preventDefault(); 24533 var id = link.dataset.videoId; 24534 var source = link.dataset.source; 24535 // switchPlayer decides same-platform (in-place) vs cross-platform 24536 // (rebuild + load the other platform). Each format link carries its 24537 // own data-source, so Short and Long can live on different platforms. 24538 switchPlayer(self, id, source); 24539 }); 24540 }); 24541 }, 24542 kalturaSession: function kalturaSession(ref) { 24543 if ( ref === void 0 ) ref = {}; 24544 var autoplay = ref.autoplay; if ( autoplay === void 0 ) autoplay = false; 24545 24546 // `autoplay` is set when a cross-platform format-toggle click recreates 24547 // the player; the initial page load passes no args (autoplay off). 24548 var partnerId = '1529571', 24549 playerId = '49927973', 24550 videoPlayer = document.getElementById('video-player'), 24551 videoId = videoPlayer.dataset.video, 24552 nextVideo = false, 24553 playlist = document.querySelector('#current-playlist'); 24554 24555 var article = document.querySelector('article.single-video'); 24556 var userId = article.dataset.uid; 24557 var postId = article.dataset.pid; 24558 24559 // Set duration 24560 var params = new URLSearchParams(window.location.search); 24561 var watched = params.get('watched'); 24562 var seconds = watched ? parseInt(watched) : 0; 24563 24564 function KalturaUpdateVideoTracker(duration, percentage, userId, postId) { 24565 jQuery.ajax({ 24566 type: 'post', 24567 dataType: 'json', 24568 url: ajax_obj.ajax_url, // eslint-disable-line no-undef 24569 data: { 24570 action: 'video_tracker', 24571 post_id: postId, 24572 user_id: userId, 24573 percentage: percentage, 24574 duration: duration, 24575 _ajax_nonce: ajax_obj.nonce, // eslint-disable-line no-undef 24576 }, 24577 success: function (response) { 24578 if (response.type != 'success') { 24579 alert('Sorry, an error occured. Please try again.'); 24580 } 24581 }, 24582 }); 24583 } 24584 24585 if (playlist) { 24586 var currentVideo = playlist.querySelector('.list-item--playing'); 24587 var sibling = currentVideo.nextElementSibling; 24588 if (sibling) { 24589 nextVideo = sibling.querySelector('a'); 24590 } 24591 } 24592 24593 // config options: https://developer.kaltura.com/player/web/configuration-web 24594 // repo: https://github.com/kaltura/kaltura-player-js 24595 try { 24596 var kalturaPlayer = KalturaPlayer.setup({ // eslint-disable-line no-undef 24597 targetId: 'video-player', 24598 provider: { 24599 partnerId: partnerId, 24600 uiConfId: playerId, 24601 }, 24602 playback: { 24603 autoplay: autoplay, 24604 }, 24605 sources: { 24606 startTime: seconds, 24607 }, 24608 }); 24609 24610 kalturaPlayer.loadMedia({ entryId: videoId }); 24611 24612 // let player = kalturaPlayer; 24613 24614 // var videoTracks = player.getTracks(player.Track.VIDEO); 24615 // var lowBandwidthTrack; 24616 // var lowBandwidth = 725624; 24617 // for (var i = 0; i < videoTracks.length; i++) { 24618 // if (videoTracks[i].bandwidth < lowBandwidth) { 24619 // lowBandwidthTrack = videoTracks[i]; 24620 // lowBandwidth = lowBandwidthTrack.bandwidth; 24621 // } 24622 // } 24623 // player.selectTrack(lowBandwidthTrack); 24624 24625 // player.addEventListener(player.Event.VIDEO_TRACK_CHANGED, function (event) { 24626 // console.log('The new bitrate is: ' + event.payload.selectedVideoTrack.bandwidth); 24627 // }); 24628 24629 // TODO: Figure out how tf to adjust bitrate to load audio version 24630 // kalturaPlayer.ready().then(function () { 24631 // console.log(kalturaPlayer.isAdaptiveBitrateEnabled()); 24632 // let tracks = kalturaPlayer.getTracks(); 24633 // let activeTracks = kalturaPlayer.getActiveTracks(); 24634 // console.log('This source has ' + tracks.length + ' tracks'); 24635 // console.log('The active video track is: ' + JSON.stringify(activeTracks.video)); 24636 // let videoTracks = kalturaPlayer.getTracks(); 24637 // for (var i = 0; i < videoTracks.length; i++) { 24638 // console.log(videoTracks[i].bandwidth); 24639 // console.log('Track ' + [i] + ': ' + JSON.stringify(videoTracks[i])); 24640 // }); 24641 24642 // Redirect to next video in playlist, if it exists 24643 24644 kalturaPlayer.addEventListener(kalturaPlayer.Event.PLAYER_STATE_CHANGED, function (event) { 24645 var newState = event.payload.newState.type; 24646 if (newState == 'paused') { // Paused 24647 var totalTime = Math.round(kalturaPlayer.duration); // Total video length (in seconds) 24648 var currentTime = Math.round(kalturaPlayer.currentTime); // Current elasped time (in seconds) 24649 var percentage = (currentTime / totalTime) * 100; // Percentage of video watched 24650 percentage = Math.round(percentage); 24651 24652 // Add video data to custom user meta 24653 KalturaUpdateVideoTracker(currentTime, percentage, userId, postId); 24654 } 24655 24656 if (newState == 'idle' && nextVideo) { // Complete 24657 location.assign(nextVideo.href); 24658 } 24659 24660 if (newState == 'idle') { // Complete 24661 var totalTime$1 = Math.round(kalturaPlayer.duration); // Total video length (in seconds) 24662 var currentTime$1 = Math.round(kalturaPlayer.currentTime); // Current elasped time (in seconds) 24663 var percentage$1 = (currentTime$1 / totalTime$1) * 100; // Percentage of video watched 24664 percentage$1 = Math.round(percentage$1); 24665 24666 // Add video data to custom user meta 24667 KalturaUpdateVideoTracker(currentTime$1, percentage$1, userId, postId); 24668 } 24669 }); 24670 24671 // Add percentage to video tracker 24672 24673 24674 // Short/Long format switching is owned by loadFormats() (single 24675 // handler for all platforms) â no per-player format binding here. 24676 } catch (e) { 24677 console.error(e.message) 24678 } 24679 }, 24680 playlists: function playlists() { 24681 var currentPlaylist = document.querySelector('#current-playlist'); 24682 24683 if (currentPlaylist) { 24684 var titles = currentPlaylist.querySelectorAll('.list-item__title'); 24685 var titleCounts = {}; 24686 24687 // First pass: count occurrences of each title
24688 titles.forEach(function(title) { 24689 var titleText = title.innerText; 24690 titleCounts[titleText] = (titleCounts[titleText] || 0) + 1; 24691 }); 24692 24693 // Second pass: add numbers to duplicate titles 24694 titles.forEach(function(title) { 24695 var titleText = title.innerText; 24696 if (titleCounts[titleText] > 1) { 24697 // Create a counter for this specific title 24698 titleCounts[titleText + '_counter'] = (titleCounts[titleText + '_counter'] || 0) + 1; 24699 title.innerText = titleText + ' #' + titleCounts[titleText + '_counter']; 24700 } 24701 }); 24702 } 24703 }, 24704 transcripts: function transcripts() { 24705 // Long 24706 var btnLong = document.querySelector('.transcript--long .transcript__copy-btn'); 24707 var transcriptLong = document.querySelector('.transcript--long .transcript__content'); 24708 24709 if (btnLong && transcriptLong) { 24710 btnLong.addEventListener('click', function (e) { 24711 e.preventDefault(); 24712 24713 /* Select the text field */ 24714 navigator.clipboard.writeText(transcriptLong.textContent).then(function () { 24715 // Alert the user that the action took place. 24716 // Nobody likes hidden stuff being done under the hood! 24717 console.log('Copied to clipboard'); 24718 }); 24719 24720 }); 24721 } 24722 }, 24723 init: function init() { 24724 // Video player output 24725 var videoPlayer = document.getElementById('video-player'); 24726 24727 if (videoPlayer) { 24728 var videoId = videoPlayer.dataset.video; 24729 var source = videoPlayer.dataset.source; 24730 24731 // Record the platform initially mounted so the format toggle can detect 24732 // same- vs cross-platform switches (see switchPlayer / currentSource). 24733 currentSource = source || (videoId.indexOf('youtube') > -1 ? 'youtube' : 'kaltura'); 24734 24735 // Priority chain is resolved server-side; data-source tells us which 24736 // player to load. Fall back to the legacy youtube/kaltura detection 24737 // if data-source is somehow absent. 24738 if (source === 'youtube' || (!source && videoId.indexOf('youtube') > -1)) { 24739 // Loads the IFrame Player API code asynchronously. 24740 this.loadScript('https://www.youtube.com/iframe_api', this.onYouTubeIframeAPIReady); 24741 } else if (source === 'bunny') { 24742 // Bunny Stream player (iframe + Player.js for tracking) 24743 this.bunnySession(); 24744 } else { 24745 // Kaltura Web Player 24746 // Utilizes the TV Studio Player (V7) in Kaltura Management Console (KMC) 24747 // https://developer.kaltura.com/player/web/getting-started-web 24748 var partnerId = '1529571'; 24749 var playerId = '49927973'; 24750 this.loadScript('https://cdnapisec.kaltura.com/p/' + partnerId + '/embedPlaykitJs/flavorId/861301/uiconf_id/' + playerId, this.kalturaSession); 24751 } 24752 } 24753 24754 this.playlists(); 24755 24756 this.transcripts(); 24757 24758 // Short/Long format toggle (platform-aware: YouTube / Bunny / Kaltura) 24759 this.loadFormats(); 24760 24761 this.contentToggle(); 24762 }, 24763 finalize: function finalize() { 24764 // JavaScript to be fired on the home page, after the init JS 24765 }, 24766}); 24767 24768/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(0))) 24769 24770/***/ }), 24771/* 46 */ 24772/***/ (function(module, __webpack_exports__, __webpack_require__) { 24773 24774"use strict"; 24775/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__util_playerLoader__ = __webpack_require__(4); 24776// import kaltura from 'kaltura-client'; 24777 24778 24779/* harmony default export */ __webpack_exports__["a"] = ({ 24780 loadScript: function loadScript(src, callback) { 24781 var loaded = false; 24782 var tag = document.createElement('script'); 24783 var firstScriptTag = document.getElementsByTagName('script')[0]; 24784 if (!firstScriptTag) { 24785 // when loaded in jest without jsdom setup it doesn't get any element. 24786 // In jest it doesn't really make sense to do anything, because no one is watching youtube in jest 24787 return; 24788 } 24789 firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 24790 tag.onload = function () { 24791 if (!loaded) { 24792 loaded = true; 24793 callback(); 24794 } 24795 }; 24796 tag.onreadystatechange = function () { 24797 if (!loaded && (this.readyState === 'complete' || this.readyState === 'loaded')) { 24798 loaded = true; 24799 callback(); 24800 } 24801 }; 24802 tag.src = src; 24803 }, 24804 onYouTubeIframeAPIReady: function onYouTubeIframeAPIReady() { 24805 // This function creates an <iframe> (and YouTube player) 24806 // after the API code downloads. 24807 24808 // Video player output 24809 var player; 24810 var videoPlayer = document.getElementById('video-player'); 24811 var videoUrl = videoPlayer.dataset.video; 24812 24813 // Get the video ID 24814 var regex = /(https?:\/\/)?((www\.)?(youtube(-nocookie)?|youtube.googleapis)\.com.*(v\/|v=|vi=|vi\/|e\/|embed\/|user\/.*\/u\/\d+\/)|youtu\.be\/)([_0-9a-z-]+)/i; 24815 var videoId = videoUrl.match(regex); 24816 24817 window.YT.ready(function () { 24818 player = new window.YT.Player(videoPlayer, { // eslint-disable-line no-undef 24819 height: '390', 24820 width: '640', 24821 videoId: videoId[7], 24822 playerVars: { 24823 'playsinline': 1, 24824 'autoplay': 1, 24825 'controls': 0, 24826 'disablekb': 1, 24827 'fs': 0, 24828 'loop': 1, 24829 'modestbranding': 1, 24830 }, 24831 events: { 24832 'onReady': onPlayerReady, 24833 onStateChange: 24834 function (e) { 24835 if (e.data === window.YT.PlayerState.ENDED) { 24836 player.playVideo(); 24837 } 24838 }, 24839 }, 24840 }); 24841 }); 24842
24843 // Called when the player's state changes 24844 // Available states: buffering, unstarted, cued, playing, paused, ended 24845 function onPlayerReady() { 24846 player.playVideo(); 24847 player.mute(); 24848 } 24849 }, 24850 kalturaSession: function kalturaSession() { 24851 var partnerId = '1529571'; 24852 var playerId = '49927973'; 24853 var videoPlayer = document.getElementById('video-player'); 24854 var videoId = videoPlayer.dataset.video; 24855 24856 // config options: https://developer.kaltura.com/player/web/configuration-web 24857 try { 24858 var kalturaPlayer = KalturaPlayer.setup({ // eslint-disable-line no-undef 24859 targetId: 'video-player', 24860 provider: { 24861 partnerId: partnerId, 24862 uiConfId: playerId, 24863 }, 24864 }); 24865 kalturaPlayer.loadMedia({ entryId: videoId }); 24866 } catch (e) { 24867 console.error(e.message) 24868 } 24869 }, 24870 init: function init() { 24871 // Video player output 24872 var videoPlayer = document.getElementById('video-player'); 24873 24874 if (videoPlayer) { 24875 var videoId = videoPlayer.dataset.video; 24876 var source = videoPlayer.dataset.source; 24877 // data-source resolves the platform; fall back to legacy detection. 24878 if (source === 'youtube' || (!source && videoId.indexOf('youtube') > -1)) { 24879 // Loads the IFrame Player API code asynchronously. 24880 this.loadScript('https://www.youtube.com/iframe_api', this.onYouTubeIframeAPIReady); 24881 } else if (source === 'bunny') { 24882 // Bunny Stream player 24883 Object(__WEBPACK_IMPORTED_MODULE_0__util_playerLoader__["a" /* loadBunnyPlayer */])(videoPlayer, { background: false }); 24884 } else { 24885 // Kaltura Web Player 24886 // Utilizes the TV Studio Player (V7) in Kaltura Management Console (KMC) 24887 // https://developer.kaltura.com/player/web/getting-started-web 24888 var partnerId = '1529571'; 24889 var playerId = '49927973'; 24890 this.loadScript('https://cdnapisec.kaltura.com/p/' + partnerId + '/embedPlaykitJs/uiconf_id/' + playerId, this.kalturaSession); 24891 } 24892 } 24893 }, 24894 finalize: function finalize() { 24895 // JavaScript to be fired on the home page, after the init JS 24896 }, 24897}); 24898 24899 24900/***/ }), 24901/* 47 */ 24902/***/ (function(module, exports) { 24903 24904// removed by extract-text-webpack-plugin 24905 24906/***/ }) 24907/******/ ]); 24908//# sourceMappingURL=main.js.map
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.