PageSourceSearch

https://www.vividcandi.com/wp-content/plugins/infinite-timeline/js/infinite-scroll.pkgd.js

js vividcandi.com collected 2026-09-29 08:45:13 UTC 57,560 bytes, 2,222 lines download raw bytes

vendor: 3,856 bytes, lines 1-154
1/*!
2 * Infinite Scroll PACKAGED v3.0.6
3 * Automatically add next page
4 *
5 * Licensed GPLv3 for open source use
6 * or Infinite Scroll Commercial License for commercial use
7 *
8 * https://infinite-scroll.com
9 * Copyright 2018 Metafizzy
10 */
11
12/**
13 * Bridget makes jQuery widgets
14 * v2.0.1
15 * MIT license
16 */
17
18/* jshint browser: true, strict: true, undef: true, unused: true */
19
20( function( window, factory ) {
21  // universal module definition
22  /*jshint strict: false */ /* globals define, module, require */
23  if ( typeof define == 'function' && define.amd ) {
24    // AMD
25    define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
26      return factory( window, jQuery );
27    });
28  } else if ( typeof module == 'object' && module.exports ) {
29    // CommonJS
30    module.exports = factory(
31      window,
32      require('jquery')
33    );
34  } else {
35    // browser global
36    window.jQueryBridget = factory(
37      window,
38      window.jQuery
39    );
40  }
41
42}( window, function factory( window, jQuery ) {
43'use strict';
44
45// ----- utils ----- //
46
47var arraySlice = Array.prototype.slice;
48
49// helper function for logging errors
50// $.error breaks jQuery chaining
51var console = window.console;
52var logError = typeof console == 'undefined' ? function() {} :
53  function( message ) {
54    console.error( message );
55  };
56
57// ----- jQueryBridget ----- //
58
59function jQueryBridget( namespace, PluginClass, $ ) {
60  $ = $ || jQuery || window.jQuery;
61  if ( !$ ) {
62    return;
63  }
64
65  // add option method -> $().plugin('option', {...})
66  if ( !PluginClass.prototype.option ) {
67    // option setter
68    PluginClass.prototype.option = function( opts ) {
69      // bail out if not an object
70      if ( !$.isPlainObject( opts ) ){
71        return;
72      }
73      this.options = $.extend( true, this.options, opts );
74    };
75  }
76
77  // make jQuery plugin
78  $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
79    if ( typeof arg0 == 'string' ) {
80      // method call $().plugin( 'methodName', { options } )
81      // shift arguments by 1
82      var args = arraySlice.call( arguments, 1 );
83      return methodCall( this, arg0, args );
84    }
85    // just $().plugin({ options })
86    plainCall( this, arg0 );
87    return this;
88  };
89
90  // $().plugin('methodName')
91  function methodCall( $elems, methodName, args ) {
92    var returnValue;
93    var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';
94
95    $elems.each( function( i, elem ) {
96      // get instance
97      var instance = $.data( elem, namespace );
98      if ( !instance ) {
99        logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
100          pluginMethodStr );
101        return;
102      }
103
104      var method = instance[ methodName ];
105      if ( !method || methodName.charAt(0) == '_' ) {
106        logError( pluginMethodStr + ' is not a valid method' );
107        return;
108      }
109
110      // apply method, get return value
111      var value = method.apply( instance, args );
112      // set return value if value is returned, use only first value
113      returnValue = returnValue === undefined ? value : returnValue;
114    });
115
116    return returnValue !== undefined ? returnValue : $elems;
117  }
118
119  function plainCall( $elems, options ) {
120    $elems.each( function( i, elem ) {
121      var instance = $.data( elem, namespace );
122      if ( instance ) {
123        // set options & init
124        instance.option( options );
125        instance._init();
126      } else {
127        // initialize new instance
128        instance = new PluginClass( elem, options );
129        $.data( elem, namespace, instance );
130      }
131    });
132  }
133
134  updateJQuery( $ );
135
136}
137
138// ----- updateJQuery ----- //
139
140// set $.bridget for v1 backwards compatibility
141function updateJQuery( $ ) {
142  if ( !$ || ( $ && $.bridget ) ) {
143    return;
144  }
145  $.bridget = jQueryBridget;
146}
147
148updateJQuery( jQuery || window.jQuery );
149
150// -----  ----- //
151
152return jQueryBridget;
153
154})
vendor: 10,089 bytes, lines 154-565
154);
155
156/**
157 * EvEmitter v1.1.0
158 * Lil' event emitter
159 * MIT License
160 */
161
162/* jshint unused: true, undef: true, strict: true */
163
164( function( global, factory ) {
165  // universal module definition
166  /* jshint strict: false */ /* globals define, module, window */
167  if ( typeof define == 'function' && define.amd ) {
168    // AMD - RequireJS
169    define( 'ev-emitter/ev-emitter',factory );
170  } else if ( typeof module == 'object' && module.exports ) {
171    // CommonJS - Browserify, Webpack
172    module.exports = factory();
173  } else {
174    // Browser globals
175    global.EvEmitter = factory();
176  }
177
178}( typeof window != 'undefined' ? window : this, function() {
179
180
181
182function EvEmitter() {}
183
184var proto = EvEmitter.prototype;
185
186proto.on = function( eventName, listener ) {
187  if ( !eventName || !listener ) {
188    return;
189  }
190  // set events hash
191  var events = this._events = this._events || {};
192  // set listeners array
193  var listeners = events[ eventName ] = events[ eventName ] || [];
194  // only add once
195  if ( listeners.indexOf( listener ) == -1 ) {
196    listeners.push( listener );
197  }
198
199  return this;
200};
201
202proto.once = function( eventName, listener ) {
203  if ( !eventName || !listener ) {
204    return;
205  }
206  // add event
207  this.on( eventName, listener );
208  // set once flag
209  // set onceEvents hash
210  var onceEvents = this._onceEvents = this._onceEvents || {};
211  // set onceListeners object
212  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
213  // set flag
214  onceListeners[ listener ] = true;
215
216  return this;
217};
218
219proto.off = function( eventName, listener ) {
220  var listeners = this._events && this._events[ eventName ];
221  if ( !listeners || !listeners.length ) {
222    return;
223  }
224  var index = listeners.indexOf( listener );
225  if ( index != -1 ) {
226    listeners.splice( index, 1 );
227  }
228
229  return this;
230};
231
232proto.emitEvent = function( eventName, args ) {
233  var listeners = this._events && this._events[ eventName ];
234  if ( !listeners || !listeners.length ) {
235    return;
236  }
237  // copy over to avoid interference if .off() in listener
238  listeners = listeners.slice(0);
239  args = args || [];
240  // once stuff
241  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
242
243  for ( var i=0; i < listeners.length; i++ ) {
244    var listener = listeners[i]
245    var isOnce = onceListeners && onceListeners[ listener ];
246    if ( isOnce ) {
247      // remove listener
248      // remove before trigger to prevent recursion
249      this.off( eventName, listener );
250      // unset once flag
251      delete onceListeners[ listener ];
252    }
253    // trigger listener
254    listener.apply( this, args );
255  }
256
257  return this;
258};
259
260proto.allOff = function() {
261  delete this._events;
262  delete this._onceEvents;
263};
264
265return EvEmitter;
266
267}));
268
269/**
270 * matchesSelector v2.0.2
271 * matchesSelector( element, '.selector' )
272 * MIT license
273 */
274
275/*jshint browser: true, strict: true, undef: true, unused: true */
276
277( function( window, factory ) {
278  /*global define: false, module: false */
279  'use strict';
280  // universal module definition
281  if ( typeof define == 'function' && define.amd ) {
282    // AMD
283    define( 'desandro-matches-selector/matches-selector',factory );
284  } else if ( typeof module == 'object' && module.exports ) {
285    // CommonJS
286    module.exports = factory();
287  } else {
288    // browser global
289    window.matchesSelector = factory();
290  }
291
292}( window, function factory() {
293  'use strict';
294
295  var matchesMethod = ( function() {
296    var ElemProto = window.Element.prototype;
297    // check for the standard method name first
298    if ( ElemProto.matches ) {
299      return 'matches';
300    }
301    // check un-prefixed
302    if ( ElemProto.matchesSelector ) {
303      return 'matchesSelector';
304    }
305    // check vendor prefixes
306    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
307
308    for ( var i=0; i < prefixes.length; i++ ) {
309      var prefix = prefixes[i];
310      var method = prefix + 'MatchesSelector';
311      if ( ElemProto[ method ] ) {
312        return method;
313      }
314    }
315  })();
316
317  return function matchesSelector( elem, selector ) {
318    return elem[ matchesMethod ]( selector );
319  };
320
321}));
322
323/**
324 * Fizzy UI utils v2.0.7
325 * MIT license
326 */
327
328/*jshint browser: true, undef: true, unused: true, strict: true */
329
330( function( window, factory ) {
331  // universal module definition
332  /*jshint strict: false */ /*globals define, module, require */
333
334  if ( typeof define == 'function' && define.amd ) {
335    // AMD
336    define( 'fizzy-ui-utils/utils',[
337      'desandro-matches-selector/matches-selector'
338    ], function( matchesSelector ) {
339      return factory( window, matchesSelector );
340    });
341  } else if ( typeof module == 'object' && module.exports ) {
342    // CommonJS
343    module.exports = factory(
344      window,
345      require('desandro-matches-selector')
346    );
347  } else {
348    // browser global
349    window.fizzyUIUtils = factory(
350      window,
351      window.matchesSelector
352    );
353  }
354
355}( window, function factory( window, matchesSelector ) {
356
357
358
359var utils = {};
360
361// ----- extend ----- //
362
363// extends objects
364utils.extend = function( a, b ) {
365  for ( var prop in b ) {
366    a[ prop ] = b[ prop ];
367  }
368  return a;
369};
370
371// ----- modulo ----- //
372
373utils.modulo = function( num, div ) {
374  return ( ( num % div ) + div ) % div;
375};
376
377// ----- makeArray ----- //
378
379var arraySlice = Array.prototype.slice;
380
381// turn element or nodeList into an array
382utils.makeArray = function( obj ) {
383  if ( Array.isArray( obj ) ) {
384    // use object if already an array
385    return obj;
386  }
387  // return empty array if undefined or null. #6
388  if ( obj === null || obj === undefined ) {
389    return [];
390  }
391
392  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
393  if ( isArrayLike ) {
394    // convert nodeList to array
395    return arraySlice.call( obj );
396  }
397
398  // array of single index
399  return [ obj ];
400};
401
402// ----- removeFrom ----- //
403
404utils.removeFrom = function( ary, obj ) {
405  var index = ary.indexOf( obj );
406  if ( index != -1 ) {
407    ary.splice( index, 1 );
408  }
409};
410
411// ----- getParent ----- //
412
413utils.getParent = function( elem, selector ) {
414  while ( elem.parentNode && elem != document.body ) {
415    elem = elem.parentNode;
416    if ( matchesSelector( elem, selector ) ) {
417      return elem;
418    }
419  }
420};
421
422// ----- getQueryElement ----- //
423
424// use element as selector string
425utils.getQueryElement = function( elem ) {
426  if ( typeof elem == 'string' ) {
427    return document.querySelector( elem );
428  }
429  return elem;
430};
431
432// ----- handleEvent ----- //
433
434// enable .ontype to trigger from .addEventListener( elem, 'type' )
435utils.handleEvent = function( event ) {
436  var method = 'on' + event.type;
437  if ( this[ method ] ) {
438    this[ method ]( event );
439  }
440};
441
442// ----- filterFindElements ----- //
443
444utils.filterFindElements = function( elems, selector ) {
445  // make array of elems
446  elems = utils.makeArray( elems );
447  var ffElems = [];
448
449  elems.forEach( function( elem ) {
450    // check that elem is an actual element
451    if ( !( elem instanceof HTMLElement ) ) {
452      return;
453    }
454    // add elem if no selector
455    if ( !selector ) {
456      ffElems.push( elem );
457      return;
458    }
459    // filter & find items if we have a selector
460    // filter
461    if ( matchesSelector( elem, selector ) ) {
462      ffElems.push( elem );
463    }
464    // find children
465    var childElems = elem.querySelectorAll( selector );
466    // concat childElems to filterFound array
467    for ( var i=0; i < childElems.length; i++ ) {
468      ffElems.push( childElems[i] );
469    }
470  });
471
472  return ffElems;
473};
474
475// ----- debounceMethod ----- //
476
477utils.debounceMethod = function( _class, methodName, threshold ) {
478  threshold = threshold || 100;
479  // original method
480  var method = _class.prototype[ methodName ];
481  var timeoutName = methodName + 'Timeout';
482
483  _class.prototype[ methodName ] = function() {
484    var timeout = this[ timeoutName ];
485    clearTimeout( timeout );
486
487    var args = arguments;
488    var _this = this;
489    this[ timeoutName ] = setTimeout( function() {
490      method.apply( _this, args );
491      delete _this[ timeoutName ];
492    }, threshold );
493  };
494};
495
496// ----- docReady ----- //
497
498utils.docReady = function( callback ) {
499  var readyState = document.readyState;
500  if ( readyState == 'complete' || readyState == 'interactive' ) {
501    // do async to allow for other scripts to run. metafizzy/flickity#441
502    setTimeout( callback );
503  } else {
504    document.addEventListener( 'DOMContentLoaded', callback );
505  }
506};
507
508// ----- htmlInit ----- //
509
510// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
511utils.toDashed = function( str ) {
512  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
513    return $1 + '-' + $2;
514  }).toLowerCase();
515};
516
517var console = window.console;
518/**
519 * allow user to initialize classes via [data-namespace] or .js-namespace class
520 * htmlInit( Widget, 'widgetName' )
521 * options are parsed from data-namespace-options
522 */
523utils.htmlInit = function( WidgetClass, namespace ) {
524  utils.docReady( function() {
525    var dashedNamespace = utils.toDashed( namespace );
526    var dataAttr = 'data-' + dashedNamespace;
527    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
528    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
529    var elems = utils.makeArray( dataAttrElems )
530      .concat( utils.makeArray( jsDashElems ) );
531    var dataOptionsAttr = dataAttr + '-options';
532    var jQuery = window.jQuery;
533
534    elems.forEach( function( elem ) {
535      var attr = elem.getAttribute( dataAttr ) ||
536        elem.getAttribute( dataOptionsAttr );
537      var options;
538      try {
539        options = attr && JSON.parse( attr );
540      } catch ( error ) {
541        // log error, do not initialize
542        if ( console ) {
543          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
544          ': ' + error );
545        }
546        return;
547      }
548      // initialize
549      var instance = new WidgetClass( elem, options );
550      // make available via $().data('namespace')
551      if ( jQuery ) {
552        jQuery.data( elem, namespace, instance );
553      }
554    });
555
556  });
557};
558
559// -----  ----- //
560
561return utils;
562
563}));
564
565/
565/ core
566( function( window, factory ) {
567  // universal module definition
568  /* globals define, module, require */
569  if ( typeof define == 'function' && define.amd ) {
570    // AMD
571    define( 'infinite-scroll/js/core',[
572      'ev-emitter/ev-emitter',
573      'fizzy-ui-utils/utils',
574    ], function( EvEmitter, utils) {
575      return factory( window, EvEmitter, utils );
576    });
577  } else if ( typeof module == 'object' && module.exports ) {
578    // CommonJS
579    module.exports = factory(
580      window,
581      require('ev-emitter'),
582      require('fizzy-ui-utils')
583    );
584  } else {
585    // browser global
586    window.InfiniteScroll = factory(
587      window,
588      window.EvEmitter,
589      window.fizzyUIUtils
590    );
591  }
592
593}( window, function factory( window, EvEmitter, utils ) {
594
595var jQuery = window.jQuery;
596// internal store of all InfiniteScroll intances
597var instances = {};
598
599function InfiniteScroll( element, options ) {
600  var queryElem = utils.getQueryElement( element );
601
602  if ( !queryElem ) {
603    console.error( 'Bad element for InfiniteScroll: ' + ( queryElem || element ) );
604    return;
605  }
606  element = queryElem;
607  // do not initialize twice on same element
608  if ( element.infiniteScrollGUID ) {
609    var instance = instances[ element.infiniteScrollGUID ];
610    instance.option( options );
611    return instance;
612  }
613
614  this.element = element;
615  // options
616  this.options = utils.extend( {}, InfiniteScroll.defaults );
617  this.option( options );
618  // add jQuery
619  if ( jQuery ) {
620    this.$element = jQuery( this.element );
621  }
622
623  this.create();
624}
625
626// defaults
627InfiniteScroll.defaults = {
628  // path: null,
629  // hideNav: null,
630  // debug: false,
631};
632
633// create & destroy methods
634InfiniteScroll.create = {};
635InfiniteScroll.destroy = {};
636
637var proto = InfiniteScroll.prototype;
638// inherit EvEmitter
639utils.extend( proto, EvEmitter.prototype );
640
641// --------------------------  -------------------------- //
642
643// globally unique identifiers
644var GUID = 0;
645
646proto.create = function() {
647  // create core
648  // add id for InfiniteScroll.data
649  var id = this.guid = ++GUID;
650  this.element.infiniteScrollGUID = id; // expando
651  instances[ id ] = this; // associate via id
652  // properties
653  this.pageIndex = 1; // default to first page
654  this.loadCount = 0;
655  this.updateGetPath();
656  // bail if getPath not set, or returns falsey #776
657  var hasPath = this.getPath && this.getPath();
658  if ( !hasPath ) {
659    console.error('Disabling InfiniteScroll');
660    return;
661  }
662  this.updateGetAbsolutePath();
663  this.log( 'initialized', [ this.element.className ] );
664  this.callOnInit();
665  // create features
666  for ( var method in InfiniteScroll.create ) {
667    InfiniteScroll.create[ method ].call( this );
668  }
669};
670
671proto.option = function( opts ) {
672  utils.extend( this.options, opts );
673};
674
675// call onInit option, used for binding events on init
676proto.callOnInit = function() {
677  var onInit = this.options.onInit;
678  if ( onInit ) {
679    onInit.call( this, this );
680  }
681};
682
683// ----- events ----- //
684
685proto.dispatchEvent = function( type, event, args ) {
686  this.log( type, args );
687  var emitArgs = event ? [ event ].concat( args ) : args;
688  this.emitEvent( type, emitArgs );
689  // trigger jQuery event
690  if ( !jQuery || !this.$element ) {
691    return;
692  }
693  // namespace jQuery event
694  type += '.infiniteScroll';
695  var $event = type;
696  if ( event ) {
697    // create jQuery event
698    var jQEvent = jQuery.Event( event );
699    jQEvent.type = type;
700    $event = jQEvent;
701  }
702  this.$element.trigger( $event, args );
703};
704
705var loggers = {
706  initialized: function( className ) {
707    return 'on ' + className;
708  },
709  request: function( path ) {
710    return 'URL: ' + path;
711  },
712  load: function( response, path ) {
713    return ( response.title || '' ) + '. URL: ' + path;
714  },
715  error: function( error, path ) {
716    return error + '. URL: ' + path;
717  },
718  append: function( response, path, items ) {
719    return items.length + ' items. URL: ' + path;
720  },
721  last: function( response, path ) {
722    return 'URL: ' + path;
723  },
724  history: function( title, path ) {
725    return 'URL: ' + path;
726  },
727  pageIndex: function( index, origin ) {
728    return 'current page determined to be: ' + index + ' from ' + origin;
729  },
730};
731
732// log events
733proto.log = function( type, args ) {
734  if ( !this.options.debug ) {
735    return;
736  }
737  var message = '[InfiniteScroll] ' + type;
738  var logger = loggers[ type ];
739  if ( logger ) {
740    message += '. ' + logger.apply( this, args );
741  }
742  console.log( message );
743};
744
745// -------------------------- methods used amoung features -------------------------- //
746
747proto.updateMeasurements = function() {
748  this.windowHeight = window.innerHeight;
749  var rect = this.element.getBoundingClientRect();
750  this.top = rect.top + window.pageYOffset;
751};
752
753proto.updateScroller = function() {
754  var elementScroll = this.options.elementScroll;
755  if ( !elementScroll ) {
756    // default, use window
757    this.scroller = window;
758    return;
759  }
760  // if true, set to element, otherwise use option
761  this.scroller = elementScroll === true ? this.element :
762    utils.getQueryElement( elementScroll );
763  if ( !this.scroller ) {
764    throw 'Unable to find elementScroll: ' + elementScroll;
765  }
766};
767
768// -------------------------- page path -------------------------- //
769
770proto.updateGetPath = function() {
771  var optPath = this.options.path;
772  if ( !optPath ) {
773    console.error( 'InfiniteScroll path option required. Set as: ' + optPath );
774    return;
775  }
776  // function
777  var type = typeof optPath;
778  if ( type == 'function' ) {
779    this.getPath = optPath;
780    return;
781  }
782  // template string: '/pages/{{#}}.html'
783  var templateMatch = type == 'string' && optPath.match('{{#}}');
784  if ( templateMatch ) {
785    this.updateGetPathTemplate( optPath );
786    return;
787  }
788  // selector: '.next-page-selector'
789  this.updateGetPathSelector( optPath );
790};
791
792proto.updateGetPathTemplate = function( optPath ) {
793  // set getPath with template string
794  this.getPath = function() {
795    var nextIndex = this.pageIndex + 1;
796    return optPath.replace( '{{#}}', nextIndex );
797  }.bind( this );
798  // get pageIndex from location
799  // convert path option into regex to look for pattern in location
800  // escape query (?) in url, allows for parsing GET parameters 
801  var regexString = optPath
802    .replace( /(\\\?|\?)/, '\\?' )
803    .replace( '{{#}}', '(\\d\\d?\\d?)' );
804  var templateRe = new RegExp( regexString );
805  var match = location.href.match( templateRe );
806
807  if ( match ) {
808    this.pageIndex = parseInt( match[1], 10 );
809    this.log( 'pageIndex', [ this.pageIndex, 'template string' ] );
810  }
811};
812
813var pathRegexes = [
814  // WordPress & Tumblr - example.com/page/2
815  // Jekyll - example.com/page2
816  /^(.*?\/?page\/?)(\d\d?\d?)(.*?$)/,
817  // Drupal - example.com/?page=1
818  /^(.*?\/?\?page=)(\d\d?\d?)(.*?$)/,
819  // catch all, last occurence of a number
820  /(.*?)(\d\d?\d?)(?!.*\d)(.*?$)/,
821];
822
823proto.updateGetPathSelector = function( optPath ) {
824  // parse href of link: '.next-page-link'
825  var hrefElem = document.querySelector( optPath );
826  if ( !hrefElem ) {
827    console.error( 'Bad InfiniteScroll path option. Next link not found: ' +
828      optPath );
829    return;
830  }
831  var href = hrefElem.getAttribute('href');
832  // try matching href to pathRegexes patterns
833  var pathParts, regex;
834  for ( var i=0; href && i < pathRegexes.length; i++ ) {
835    regex = pathRegexes[i];
836    var match = href.match( regex );
837    if ( match ) {
838      pathParts = match.slice(1); // remove first part
839      break;
840    }
841  }
842  if ( !pathParts ) {
843    console.error( 'InfiniteScroll unable to parse next link href: ' + href );
844    return;
845  }
846  this.isPathSelector = true; // flag for checkLastPage()
847  this.getPath = function() {
848    var nextIndex = this.pageIndex + 1;
849    return pathParts[0] + nextIndex + pathParts[2];
850  }.bind( this );
851  // get pageIndex from href
852  this.pageIndex = parseInt( pathParts[1], 10 ) - 1;
853  this.log( 'pageIndex', [ this.pageIndex, 'next link' ] );
854};
855
856proto.updateGetAbsolutePath = function() {
857  var path = this.getPath();
858  // path doesn't start with http or /
859  var isAbsolute = path.match( /^http/ ) || path.match( /^\// );
860  if ( isAbsolute ) {
861    this.getAbsolutePath = this.getPath;
862    return;
863  }
864
865  var pathname = location.pathname;
866  // query parameter #829. example.com/?pg=2
867  var isQuery = path.match( /^\?/ );
868  if ( isQuery ) {
869    this.getAbsolutePath = function() {
870      return pathname + this.getPath();
871    };
872    return;
873  }
874
875  // /foo/bar/index.html => /foo/bar
876  var directory = pathname.substring( 0, pathname.lastIndexOf('/') );
877  this.getAbsolutePath = function() {
878    return directory + '/' + this.getPath();
879  };
880};
881
882// -------------------------- nav -------------------------- //
883
884// hide navigation
885InfiniteScroll.create.hideNav = function() {
886  var nav = utils.getQueryElement( this.options.hideNav );
887  if ( !nav ) {
888    return;
889  }
890  nav.style.display = 'none';
891  this.nav = nav;
892};
893
894InfiniteScroll.destroy.hideNav = function() {
895  if ( this.nav ) {
896    this.nav.style.display = '';
897  }
898};
899
900// -------------------------- destroy -------------------------- //
901
902proto.destroy = function() {
903  this.allOff(); // remove all event listeners
904  // call destroy methods
905  for ( var method in InfiniteScroll.destroy ) {
906    InfiniteScroll.destroy[ method ].call( this );
907  }
908
909  delete this.element.infiniteScrollGUID;
910  delete instances[ this.guid ];
911  // remove jQuery data. #807
912  if ( jQuery && this.$element ) {
913    jQuery.removeData( this.element, 'infiniteScroll' );
914  }
915};
916
917// -------------------------- utilities -------------------------- //
918
919// https://remysharp.com/2010/07/21/throttling-function-calls
920InfiniteScroll.throttle = function( fn, threshold ) {
921  threshold = threshold || 200;
922  var last, timeout;
923
924  return function() {
925    var now = +new Date();
926    var args = arguments;
927    var trigger = function() {
928      last = now;
929      fn.apply( this, args );
930    }.bind( this );
931    if ( last && now < last + threshold ) {
932      // hold on to it
933      clearTimeout( timeout );
934      timeout = setTimeout( trigger, threshold );
935    } else {
936      trigger();
937    }
938  };
939};
940
941InfiniteScroll.data = function( elem ) {
942  elem = utils.getQueryElement( elem );
943  var id = elem && elem.infiniteScrollGUID;
944  return id && instances[ id ];
945};
946
947// set internal jQuery, for Webpack + jQuery v3
948InfiniteScroll.setJQuery = function( $ ) {
949  jQuery = $;
950};
951
952// -------------------------- setup -------------------------- //
953
954utils.htmlInit( InfiniteScroll, 'infinite-scroll' );
955
956// add noop _init method for jQuery Bridget. #768
957proto._init = function() {};
958
959if ( jQuery && jQuery.bridget ) {
960  jQuery.bridget( 'infiniteScroll', InfiniteScroll );
961}
962
963// --------------------------  -------------------------- //
964
965return InfiniteScroll;
966
967}));
968
969// page-load
970( function( window, factory ) {
971  // universal module definition
972  /* globals define, module, require */
973  if ( typeof define == 'function' && define.amd ) {
974    // AMD
975    define( 'infinite-scroll/js/page-load',[
976      './core',
977    ], function( InfiniteScroll ) {
978      return factory( window, InfiniteScroll );
979    });
980  } else if ( typeof module == 'object' && module.exports ) {
981    // CommonJS
982    module.exports = factory(
983      window,
984      require('./core')
985    );
986  } else {
987    // browser global
988    factory(
989      window,
990      window.InfiniteScroll
991    );
992  }
993
994}( window, function factory( window, InfiniteScroll ) {
995
996var proto = InfiniteScroll.prototype;
997
998// InfiniteScroll.defaults.append = false;
999InfiniteScroll.defaults.loadOnScroll = true;
1000InfiniteScroll.defaults.checkLastPage = true;
1001InfiniteScroll.defaults.responseType = 'document';
1002// InfiniteScroll.defaults.prefill = false;
1003// InfiniteScroll.defaults.outlayer = null;
1004
1005InfiniteScroll.create.pageLoad = function() {
1006  this.canLoad = true;
1007  this.on( 'scrollThreshold', this.onScrollThresholdLoad );
1008  this.on( 'load', this.checkLastPage );
1009  if ( this.options.outlayer ) {
1010    this.on( 'append', this.onAppendOutlayer );
1011  }
1012};
1013
1014proto.onScrollThresholdLoad = function() {
1015  if ( this.options.loadOnScroll ) {
1016    this.loadNextPage();
1017  }
1018};
1019
1020proto.loadNextPage = function() {
1021  if ( this.isLoading || !this.canLoad ) {
1022    return;
1023  }
1024
1025  var path = this.getAbsolutePath();
1026  this.isLoading = true;
1027
1028  var onLoad = function( response ) {
1029    this.onPageLoad( response, path );
1030  }.bind( this );
1031
1032  var onError = function( error ) {
1033    this.onPageError( error, path );
1034  }.bind( this );
1035
1036  var onLast = function( response ) {
1037    this.lastPageReached( response, path );
1038  }.bind( this );
1039
1040  request( path, this.options.responseType, onLoad, onError, onLast );
1041  this.dispatchEvent( 'request', null, [ path ] );
1042};
1043
1044proto.onPageLoad = function( response, path ) {
1045  // done loading if not appending
1046  if ( !this.options.append ) {
1047    this.isLoading = false;
1048  }
1049  this.pageIndex++;
1050  this.loadCount++;
1051  this.dispatchEvent( 'load', null, [ response, path ] );
1052  this.appendNextPage( response, path );
1053  return response;
1054};
1055
1056proto.appendNextPage = function( response, path ) {
1057  var optAppend = this.options.append;
1058  // do not append json
1059  var isDocument = this.options.responseType == 'document';
1060  if ( !isDocument || !optAppend ) {
1061    return;
1062  }
1063
1064  var items = response.querySelectorAll( optAppend );
1065  var fragment = getItemsFragment( items );
1066  var appendReady = function () {
1067    this.appendItems( items, fragment );
1068    this.isLoading = false;
1069    this.dispatchEvent( 'append', null, [ response, path, items ] );
1070  }.bind( this );
1071
1072  // TODO add hook for option to trigger appendReady
1073  if ( this.options.outlayer ) {
1074    this.appendOutlayerItems( fragment, appendReady );
1075  } else {
1076    appendReady();
1077  }
1078};
1079
1080proto.appendItems = function( items, fragment ) {
1081  if ( !items || !items.length ) {
1082    return;
1083  }
1084  // get fragment if not provided
1085  fragment = fragment || getItemsFragment( items );
1086  refreshScripts( fragment );
1087  this.element.appendChild( fragment );
1088};
1089
1090function getItemsFragment( items ) {
1091  // add items to fragment
1092  var fragment = document.createDocumentFragment();
1093  for ( var i=0; items && i < items.length; i++ ) {
1094    fragment.appendChild( items[i] );
1095  }
1096  return fragment;
1097}
1098
1099// replace <script>s with copies so they load
1100// <script>s added by InfiniteScroll will not load
1101// similar to https://stackoverflow.com/questions/610995
1102function refreshScripts( fragment ) {
1103  var scripts = fragment.querySelectorAll('script');
1104  for ( var i=0; i < scripts.length; i++ ) {
1105    var script = scripts[i];
1106    var freshScript = document.createElement('script');
1107    copyAttributes( script, freshScript );
1108    // copy inner script code. #718, #782
1109    freshScript.innerHTML = script.innerHTML;
1110    script.parentNode.replaceChild( freshScript, script );
1111  }
1112}
1113
1114function copyAttributes( fromNode, toNode ) {
1115  var attrs = fromNode.attributes;
1116  for ( var i=0; i < attrs.length; i++ ) {
1117    var attr = attrs[i];
1118    toNode.setAttribute( attr.name, attr.value );
1119  }
1120}
1121
1122// ----- outlayer ----- //
1123
1124proto.appendOutlayerItems = function( fragment, appendReady ) {
1125  var imagesLoaded = InfiniteScroll.imagesLoaded || window.imagesLoaded;
1126  if ( !imagesLoaded ) {
1127    console.error('[InfiniteScroll] imagesLoaded required for outlayer option');
1128    this.isLoading = false;
1129    return;
1130  }
1131  // append once images loaded
1132  imagesLoaded( fragment, appendReady );
1133};
1134
1135proto.onAppendOutlayer = function( response, path, items ) {
1136  this.options.outlayer.appended( items );
1137};
1138
1139// ----- checkLastPage ----- //
1140
1141// check response for next element
1142proto.checkLastPage = function( response, path ) {
1143  var checkLastPage = this.options.checkLastPage;
1144  if ( !checkLastPage ) {
1145    return;
1146  }
1147
1148  var pathOpt = this.options.path;
1149  // if path is function, check if next path is truthy
1150  if ( typeof pathOpt == 'function' ) {
1151    var nextPath = this.getPath();
1152    if ( !nextPath ) {
1153      this.lastPageReached( response, path );
1154      return;
1155    }
1156  }
1157  // get selector from checkLastPage or path option
1158  var selector;
1159  if ( typeof checkLastPage == 'string' ) {
1160    selector = checkLastPage;
1161  } else if ( this.isPathSelector ) {
1162    // path option is selector string
1163    selector = pathOpt;
1164  }
1165  // check last page for selector
1166  // bail if no selector or not document response
1167  if ( !selector || !response.querySelector ) {
1168    return;
1169  }
1170  // check if response has selector
1171  var nextElem = response.querySelector( selector );
1172  if ( !nextElem ) {
1173    this.lastPageReached( response, path );
1174  }
1175};
1176
1177proto.lastPageReached = function( response, path ) {
1178  this.canLoad = false;
1179  this.dispatchEvent( 'last', null, [ response, path ] );
1180};
1181
1182// ----- error ----- //
1183
1184proto.onPageError = function( error, path ) {
1185  this.isLoading = false;
1186  this.canLoad = false;
1187  this.dispatchEvent( 'error', null, [ error, path ] );
1188  return error;
1189};
1190
1191// -------------------------- prefill -------------------------- //
1192
1193InfiniteScroll.create.prefill = function() {
1194  if ( !this.options.prefill ) {
1195    return;
1196  }
1197  var append = this.options.append;
1198  if ( !append ) {
1199    console.error( 'append option required for prefill. Set as :' + append );
1200    return;
1201  }
1202  this.updateMeasurements();
1203  this.updateScroller();
1204  this.isPrefilling = true;
1205  this.on( 'append', this.prefill );
1206  this.once( 'error', this.stopPrefill );
1207  this.once( 'last', this.stopPrefill );
1208  this.prefill();
1209};
1210
1211proto.prefill = function() {
1212  var distance = this.getPrefillDistance();
1213  this.isPrefilling = distance >= 0;
1214  if ( this.isPrefilling ) {
1215    this.log('prefill');
1216    this.loadNextPage();
1217  } else {
1218    this.stopPrefill();
1219  }
1220};
1221
1222proto.getPrefillDistance = function() {
1223  // element scroll
1224  if ( this.options.elementScroll ) {
1225    return this.scroller.clientHeight - this.scroller.scrollHeight;
1226  }
1227  // window
1228  return this.windowHeight - this.element.clientHeight;
1229};
1230
1231proto.stopPrefill = function() {
1232  this.log('stopPrefill');
1233  this.off( 'append', this.prefill );
1234};
1235
1236// -------------------------- request -------------------------- //
1237
1238function request( url, responseType, onLoad, onError, onLast ) {
1239  var req = new XMLHttpRequest();
1240  req.open( 'GET', url, true );
1241  // set responseType document to return DOM
1242  req.responseType = responseType || '';
1243
1244  // set X-Requested-With header to check that is ajax request
1245  req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
1246
1247  req.onload = function() {
1248    if ( req.status == 200 ) {
1249      onLoad( req.response );
1250    } else if ( req.status == 204 ) {
1251      onLast( req.response );
1252    } else {
1253      // not 200 OK, error
1254      var error = new Error( req.statusText );
1255      onError( error );
1256    }
1257  };
1258
1259  // Handle network errors
1260  req.onerror = function() {
1261    var error = new Error( 'Network error requesting ' + url );
1262    onError( error );
1263  };
1264
1265  req.send();
1266}
1267
1268// --------------------------  -------------------------- //
1269
1270return InfiniteScroll;
1271
1272}));
1273
1274// scroll-watch
1275( function( window, factory ) {
1276  // universal module definition
1277  /* globals define, module, require */
1278  if ( typeof define == 'function' && define.amd ) {
1279    // AMD
1280    define( 'infinite-scroll/js/scroll-watch',[
1281      './core',
1282      'fizzy-ui-utils/utils',
1283    ], function( InfiniteScroll, utils ) {
1284      return factory( window, InfiniteScroll, utils );
1285    });
1286  } else if ( typeof module == 'object' && module.exports ) {
1287    // CommonJS
1288    module.exports = factory(
1289      window,
1290      require('./core'),
1291      require('fizzy-ui-utils')
1292    );
1293  } else {
1294    // browser global
1295    factory(
1296      window,
1297      window.InfiniteScroll,
1298      window.fizzyUIUtils
1299    );
1300  }
1301
1302}( window, function factory( window, InfiniteScroll, utils ) {
1303
1304var proto = InfiniteScroll.prototype;
1305
1306// default options
1307InfiniteScroll.defaults.scrollThreshold = 400;
1308// InfiniteScroll.defaults.elementScroll = null;
1309
1310InfiniteScroll.create.scrollWatch = function() {
1311  // events
1312  this.pageScrollHandler = this.onPageScroll.bind( this );
1313  this.resizeHandler = this.onResize.bind( this );
1314
1315  var scrollThreshold = this.options.scrollThreshold;
1316  var isEnable = scrollThreshold || scrollThreshold === 0;
1317  if ( isEnable ) {
1318    this.enableScrollWatch();
1319  }
1320};
1321
1322InfiniteScroll.destroy.scrollWatch = function() {
1323  this.disableScrollWatch();
1324};
1325
1326proto.enableScrollWatch = function() {
1327  if ( this.isScrollWatching ) {
1328    return;
1329  }
1330  this.isScrollWatching = true;
1331  this.updateMeasurements();
1332  this.updateScroller();
1333  // TODO disable after error?
1334  this.on( 'last', this.disableScrollWatch );
1335  this.bindScrollWatchEvents( true );
1336};
1337
1338proto.disableScrollWatch = function() {
1339  if ( !this.isScrollWatching ) {
1340    return;
1341  }
1342  this.bindScrollWatchEvents( false );
1343  delete this.isScrollWatching;
1344};
1345
1346proto.bindScrollWatchEvents = function( isBind ) {
1347  var addRemove = isBind ? 'addEventListener' : 'removeEventListener';
1348  this.scroller[ addRemove ]( 'scroll', this.pageScrollHandler );
1349  window[ addRemove ]( 'resize', this.resizeHandler );
1350};
1351
1352proto.onPageScroll = InfiniteScroll.throttle( function() {
1353  var distance = this.getBottomDistance();
1354  if ( distance <= this.options.scrollThreshold ) {
1355    this.dispatchEvent('scrollThreshold');
1356  }
1357});
1358
1359proto.getBottomDistance = function() {
1360  if ( this.options.elementScroll ) {
1361    return this.getElementBottomDistance();
1362  } else {
1363    return this.getWindowBottomDistance();
1364  }
1365};
1366
1367proto.getWindowBottomDistance = function() {
1368  var bottom = this.top + this.element.clientHeight;
1369  var scrollY = window.pageYOffset + this.windowHeight;
1370  return bottom - scrollY;
1371};
1372
1373proto.getElementBottomDistance = function() {
1374  var bottom = this.scroller.scrollHeight;
1375  var scrollY = this.scroller.scrollTop + this.scroller.clientHeight;
1376  return bottom - scrollY;
1377};
1378
1379proto.onResize = function() {
1380  this.updateMeasurements();
1381};
1382
1383utils.debounceMethod( InfiniteScroll, 'onResize', 150 );
1384
1385// --------------------------  -------------------------- //
1386
1387return InfiniteScroll;
1388
1389}));
1390
1391// history
1392( function( window, factory ) {
1393  // universal module definition
1394  /* globals define, module, require */
1395  if ( typeof define == 'function' && define.amd ) {
1396    // AMD
1397    define( 'infinite-scroll/js/history',[
1398      './core',
1399      'fizzy-ui-utils/utils',
1400    ], function( InfiniteScroll, utils ) {
1401      return factory( window, InfiniteScroll, utils );
1402    });
1403  } else if ( typeof module == 'object' && module.exports ) {
1404    // CommonJS
1405    module.exports = factory(
1406      window,
1407      require('./core'),
1408      require('fizzy-ui-utils')
1409    );
1410  } else {
1411    // browser global
1412    factory(
1413      window,
1414      window.InfiniteScroll,
1415      window.fizzyUIUtils
1416    );
1417  }
1418
1419}( window, function factory( window, InfiniteScroll, utils ) {
1420
1421var proto = InfiniteScroll.prototype;
1422
1423InfiniteScroll.defaults.history = 'replace';
1424// InfiniteScroll.defaults.historyTitle = false;
1425
1426var link = document.createElement('a');
1427
1428// ----- create/destroy ----- //
1429
1430InfiniteScroll.create.history = function() {
1431  if ( !this.options.history ) {
1432    return;
1433  }
1434  // check for same origin
1435  link.href = this.getAbsolutePath();
1436  // MS Edge does not have origin on link https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12236493/
1437  var linkOrigin = link.origin || link.protocol + '//' + link.host;
1438  var isSameOrigin = linkOrigin == location.origin;
1439  if ( !isSameOrigin ) {
1440    console.error( '[InfiniteScroll] cannot set history with different origin: ' +
1441      link.origin + ' on ' + location.origin +
1442      ' . History behavior disabled.' );
1443    return;
1444  }
1445
1446  // two ways to handle changing history
1447  if ( this.options.append ) {
1448    this.createHistoryAppend();
1449  } else {
1450    this.createHistoryPageLoad();
1451  }
1452};
1453
1454proto.createHistoryAppend = function() {
1455  this.updateMeasurements();
1456  this.updateScroller();
1457  // array of scroll positions of appended pages
1458  this.scrollPages = [
1459    {
1460      // first page
1461      top: 0,
1462      path: location.href,
1463      title: document.title,
1464    }
1465  ];
1466  this.scrollPageIndex = 0;
1467  // events
1468  this.scrollHistoryHandler = this.onScrollHistory.bind( this );
1469  this.unloadHandler = this.onUnload.bind( this );
1470  this.scroller.addEventListener( 'scroll', this.scrollHistoryHandler );
1471  this.on( 'append', this.onAppendHistory );
1472  this.bindHistoryAppendEvents( true );
1473};
1474
1475proto.bindHistoryAppendEvents = function( isBind ) {
1476  var addRemove = isBind ? 'addEventListener' : 'removeEventListener';
1477  this.scroller[ addRemove ]( 'scroll', this.scrollHistoryHandler );
1478  window[ addRemove ]( 'unload', this.unloadHandler );
1479};
1480
1481proto.createHistoryPageLoad = function() {
1482  this.on( 'load', this.onPageLoadHistory );
1483};
1484
1485InfiniteScroll.destroy.history =
1486proto.destroyHistory = function() {
1487  var isHistoryAppend = this.options.history && this.options.append;
1488  if ( isHistoryAppend ) {
1489    this.bindHistoryAppendEvents( false );
1490  }
1491};
1492
1493// ----- append history ----- //
1494
1495proto.onAppendHistory = function( response, path, items ) {
1496  // do not proceed if no items. #779
1497  if ( !items || !items.length ) {
1498    return;
1499  }
1500  var firstItem = items[0];
1501  var elemScrollY = this.getElementScrollY( firstItem );
1502  // resolve path
1503  link.href = path;
1504  // add page data to hash
1505  this.scrollPages.push({
1506    top: elemScrollY,
1507    path: link.href,
1508    title: response.title,
1509  });
1510};
1511
1512proto.getElementScrollY = function( elem ) {
1513  if ( this.options.elementScroll ) {
1514    return this.getElementElementScrollY( elem );
1515  } else {
1516    return this.getElementWindowScrollY( elem );
1517  }
1518};
1519
1520proto.getElementWindowScrollY = function( elem ) {
1521  var rect = elem.getBoundingClientRect();
1522  return rect.top + window.pageYOffset;
1523};
1524
1525// wow, stupid name
1526proto.getElementElementScrollY = function( elem ) {
1527  return elem.offsetTop - this.top;
1528};
1529
1530proto.onScrollHistory = function() {
1531  // cycle through positions, find biggest without going over
1532  var scrollViewY = this.getScrollViewY();
1533  var pageIndex, page;
1534  for ( var i=0; i < this.scrollPages.length; i++ ) {
1535    var scrollPage = this.scrollPages[i];
1536    if ( scrollPage.top >= scrollViewY ) {
1537      break;
1538    }
1539    pageIndex = i;
1540    page = scrollPage;
1541  }
1542  // set history if changed
1543  if ( pageIndex != this.scrollPageIndex ) {
1544    this.scrollPageIndex = pageIndex;
1545    this.setHistory( page.title, page.path );
1546  }
1547};
1548
1549utils.debounceMethod( InfiniteScroll, 'onScrollHistory', 150 );
1550
1551proto.getScrollViewY = function() {
1552  if ( this.options.elementScroll ) {
1553    return this.scroller.scrollTop + this.scroller.clientHeight/2;
1554  } else {
1555    return window.pageYOffset + this.windowHeight/2;
1556  }
1557};
1558
1559proto.setHistory = function( title, path ) {
1560  var optHistory = this.options.history;
1561  var historyMethod = optHistory && history[ optHistory + 'State' ];
1562  if ( !historyMethod ) {
1563    return;
1564  }
1565
1566  history[ optHistory + 'State' ]( null, title, path );
1567
1568  if ( this.options.historyTitle ) {
1569    document.title = title;
1570  }
1571
1572  this.dispatchEvent( 'history', null, [ title, path ] );
1573};
1574
1575// scroll to top to prevent initial scroll-reset after page refresh
1576// https://stackoverflow.com/a/18633915/182183
1577proto.onUnload = function() {
1578  var pageIndex = this.scrollPageIndex;
1579  if ( pageIndex === 0 ) {
1580    return;
1581  }
1582  // calculate where scroll position would be on refresh
1583  var scrollPage = this.scrollPages[ pageIndex ];
1584  var scrollY = window.pageYOffset - scrollPage.top + this.top;
1585  // disable scroll event before setting scroll #679
1586  this.destroyHistory();
1587  scrollTo( 0, scrollY );
1588};
1589
1590// ----- load history ----- //
1591
1592// update URL
1593proto.onPageLoadHistory = function( response, path ) {
1594  this.setHistory( response.title, path );
1595};
1596
1597// --------------------------  -------------------------- //
1598
1599return InfiniteScroll;
1600
1601}));
1602
1603// button
1604( function( window, factory ) {
1605  // universal module definition
1606  /* globals define, module, require */
1607  if ( typeof define == 'function' && define.amd ) {
1608    // AMD
1609    define( 'infinite-scroll/js/button',[
1610      './core',
1611      'fizzy-ui-utils/utils',
1612    ], function( InfiniteScroll, utils ) {
1613      return factory( window, InfiniteScroll, utils );
1614    });
1615  } else if ( typeof module == 'object' && module.exports ) {
1616    // CommonJS
1617    module.exports = factory(
1618      window,
1619      require('./core'),
1620      require('fizzy-ui-utils')
1621    );
1622  } else {
1623    // browser global
1624    factory(
1625      window,
1626      window.InfiniteScroll,
1627      window.fizzyUIUtils
1628    );
1629  }
1630
1631}( window, function factory( window, InfiniteScroll, utils ) {
1632
1633// InfiniteScroll.defaults.button = null;
1634
1635InfiniteScroll.create.button = function() {
1636  var buttonElem = utils.getQueryElement( this.options.button );
1637  if ( buttonElem ) {
1638    this.button = new InfiniteScrollButton( buttonElem, this );
1639    return;
1640  }
1641};
1642
1643InfiniteScroll.destroy.button = function() {
1644  if ( this.button ) {
1645    this.button.destroy();
1646  }
1647};
1648
1649// -------------------------- InfiniteScrollButton -------------------------- //
1650
1651function InfiniteScrollButton( element, infScroll ) {
1652  this.element = element;
1653  this.infScroll = infScroll;
1654  // events
1655  this.clickHandler = this.onClick.bind( this );
1656  this.element.addEventListener( 'click', this.clickHandler );
1657  infScroll.on( 'request', this.disable.bind( this ) );
1658  infScroll.on( 'load', this.enable.bind( this ) );
1659  infScroll.on( 'error', this.hide.bind( this ) );
1660  infScroll.on( 'last', this.hide.bind( this ) );
1661}
1662
1663InfiniteScrollButton.prototype.onClick = function( event ) {
1664  event.preventDefault();
1665  this.infScroll.loadNextPage();
1666};
1667
1668InfiniteScrollButton.prototype.enable = function() {
1669  this.element.removeAttribute('disabled');
1670};
1671
1672InfiniteScrollButton.prototype.disable = function() {
1673  this.element.disabled = 'disabled';
1674};
1675
1676InfiniteScrollButton.prototype.hide = function() {
1677  this.element.style.display = 'none';
1678};
1679
1680InfiniteScrollButton.prototype.destroy = function() {
1681  this.element.removeEventListener( 'click', this.clickHandler );
1682};
1683
1684// --------------------------  -------------------------- //
1685
1686InfiniteScroll.Button = InfiniteScrollButton;
1687
1688return InfiniteScroll;
1689
1690}));
1691
1692// status
1693( function( window, factory ) {
1694  // universal module definition
1695  /* globals define, module, require */
1696  if ( typeof define == 'function' && define.amd ) {
1697    // AMD
1698    define( 'infinite-scroll/js/status',[
1699      './core',
1700      'fizzy-ui-utils/utils',
1701    ], function( InfiniteScroll, utils ) {
1702      return factory( window, InfiniteScroll, utils );
1703    });
1704  } else if ( typeof module == 'object' && module.exports ) {
1705    // CommonJS
1706    module.exports = factory(
1707      window,
1708      require('./core'),
1709      require('fizzy-ui-utils')
1710    );
1711  } else {
1712    // browser global
1713    factory(
1714      window,
1715      window.InfiniteScroll,
1716      window.fizzyUIUtils
1717    );
1718  }
1719
1720}( window, function factory( window, InfiniteScroll, utils ) { 
1721
1722var proto = InfiniteScroll.prototype;
1723
1724// InfiniteScroll.defaults.status = null;
1725
1726InfiniteScroll.create.status = function() {
1727  var statusElem = utils.getQueryElement( this.options.status );
1728  if ( !statusElem ) {
1729    return;
1730  }
1731  // elements
1732  this.statusElement = statusElem;
1733  this.statusEventElements = {
1734    request: statusElem.querySelector('.infinite-scroll-request'),
1735    error: statusElem.querySelector('.infinite-scroll-error'),
1736    last: statusElem.querySelector('.infinite-scroll-last'),
1737  };
1738  // events
1739  this.on( 'request', this.showRequestStatus );
1740  this.on( 'error', this.showErrorStatus );
1741  this.on( 'last', this.showLastStatus );
1742  this.bindHideStatus('on');
1743};
1744
1745proto.bindHideStatus = function( bindMethod ) {
1746  var hideEvent = this.options.append ? 'append' : 'load';
1747  this[ bindMethod ]( hideEvent, this.hideAllStatus );
1748};
1749
1750proto.showRequestStatus = function() {
1751  this.showStatus('request');
1752};
1753
1754proto.showErrorStatus = function() {
1755  this.showStatus('error');
1756};
1757
1758proto.showLastStatus = function() {
1759  this.showStatus('last');
1760  // prevent last then append event race condition from showing last status #706
1761  this.bindHideStatus('off');
1762};
1763
1764proto.showStatus = function( eventName ) {
1765  show( this.statusElement );
1766  this.hideStatusEventElements();
1767  var eventElem = this.statusEventElements[ eventName ];
1768  show( eventElem );
1769};
1770
1771proto.hideAllStatus = function() {
1772  hide( this.statusElement );
1773  this.hideStatusEventElements();
1774};
1775
1776proto.hideStatusEventElements = function() {
1777  for ( var type in this.statusEventElements ) {
1778    var eventElem = this.statusEventElements[ type ];
1779    hide( eventElem );
1780  }
1781};
1782
1783// --------------------------  -------------------------- //
1784
1785function hide( elem ) {
1786  setDisplay( elem, 'none' );
1787}
1788
1789function show( elem ) {
1790  setDisplay( elem, 'block' );
1791}
1792
1793function setDisplay( elem, value ) {
1794  if ( elem ) {
1795    elem.style.display = value;
1796  }
1797}
1798
1799// --------------------------  -------------------------- //
1800
1801return InfiniteScroll;
1802
1803}));
1804
1805/*!
1806 * Infinite Scroll v3.0.6
1807 * Automatically add next page
1808 *
1809 * Licensed GPLv3 for open source use
1810 * or Infinite Scroll Commercial License for commercial use
1811 *
1812 * https://infinite-scroll.com
1813 * Copyright 2018 Metafizzy
1814 */
1815
1816( function( window, factory ) {
1817  // universal module definition
1818  /* globals define, module, require */
1819  if ( typeof define == 'function' && define.amd ) {
1820    // AMD
1821    define( [
1822      'infinite-scroll/js/core',
1823      'infinite-scroll/js/page-load',
1824      'infinite-scroll/js/scroll-watch',
1825      'infinite-scroll/js/history',
1826      'infinite-scroll/js/button',
1827      'infinite-scroll/js/status',
1828    ], factory );
1829  } else if ( typeof module == 'object' && module.exports ) {
1830    // CommonJS
1831    module.exports = factory(
1832      require('./core'),
1833      require('./page-load'),
1834      require('./scroll-watch'),
1835      require('./history'),
1836      require('./button'),
1837      require('./status')
1838    );
1839  }
1840
1841})( window, function factory( InfiniteScroll ) {
1842  return InfiniteScroll;
1843});
1844
1845/*!
1846 * imagesLoaded v4.1.4
1847 * JavaScript is all like "You images are done yet or what?"
1848 * MIT License
1849 */
1850
1851( function( window, factory ) { 'use strict';
1852  // universal module definition
1853
1854  /*global define: false, module: false, require: false */
1855
1856  if ( typeof define == 'function' && define.amd ) {
1857    // AMD
1858    define( 'imagesloaded/imagesloaded',[
1859      'ev-emitter/ev-emitter'
1860    ], function( EvEmitter ) {
1861      return factory( window, EvEmitter );
1862    });
1863  } else if ( typeof module == 'object' && module.exports ) {
1864    // CommonJS
1865    module.exports = factory(
1866      window,
1867      require('ev-emitter')
1868    );
1869  } else {
1870    // browser global
1871    window.imagesLoaded = factory(
1872      window,
1873      window.EvEmitter
1874    );
1875  }
1876
1877})( typeof window !== 'undefined' ? window : this,
1878
vendor: 8,206 bytes, lines 1879-2183
1879// --------------------------  factory -------------------------- //
1880
1881function factory( window, EvEmitter ) {
1882
1883
1884
1885var $ = window.jQuery;
1886var console = window.console;
1887
1888// -------------------------- helpers -------------------------- //
1889
1890// extend objects
1891function extend( a, b ) {
1892  for ( var prop in b ) {
1893    a[ prop ] = b[ prop ];
1894  }
1895  return a;
1896}
1897
1898var arraySlice = Array.prototype.slice;
1899
1900// turn element or nodeList into an array
1901function makeArray( obj ) {
1902  if ( Array.isArray( obj ) ) {
1903    // use object if already an array
1904    return obj;
1905  }
1906
1907  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
1908  if ( isArrayLike ) {
1909    // convert nodeList to array
1910    return arraySlice.call( obj );
1911  }
1912
1913  // array of single index
1914  return [ obj ];
1915}
1916
1917// -------------------------- imagesLoaded -------------------------- //
1918
1919/**
1920 * @param {Array, Element, NodeList, String} elem
1921 * @param {Object or Function} options - if function, use as callback
1922 * @param {Function} onAlways - callback function
1923 */
1924function ImagesLoaded( elem, options, onAlways ) {
1925  // coerce ImagesLoaded() without new, to be new ImagesLoaded()
1926  if ( !( this instanceof ImagesLoaded ) ) {
1927    return new ImagesLoaded( elem, options, onAlways );
1928  }
1929  // use elem as selector string
1930  var queryElem = elem;
1931  if ( typeof elem == 'string' ) {
1932    queryElem = document.querySelectorAll( elem );
1933  }
1934  // bail if bad element
1935  if ( !queryElem ) {
1936    console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
1937    return;
1938  }
1939
1940  this.elements = makeArray( queryElem );
1941  this.options = extend( {}, this.options );
1942  // shift arguments if no options set
1943  if ( typeof options == 'function' ) {
1944    onAlways = options;
1945  } else {
1946    extend( this.options, options );
1947  }
1948
1949  if ( onAlways ) {
1950    this.on( 'always', onAlways );
1951  }
1952
1953  this.getImages();
1954
1955  if ( $ ) {
1956    // add jQuery Deferred object
1957    this.jqDeferred = new $.Deferred();
1958  }
1959
1960  // HACK check async to allow time to bind listeners
1961  setTimeout( this.check.bind( this ) );
1962}
1963
1964ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
1965
1966ImagesLoaded.prototype.options = {};
1967
1968ImagesLoaded.prototype.getImages = function() {
1969  this.images = [];
1970
1971  // filter & find items if we have an item selector
1972  this.elements.forEach( this.addElementImages, this );
1973};
1974
1975/**
1976 * @param {Node} element
1977 */
1978ImagesLoaded.prototype.addElementImages = function( elem ) {
1979  // filter siblings
1980  if ( elem.nodeName == 'IMG' ) {
1981    this.addImage( elem );
1982  }
1983  // get background image on element
1984  if ( this.options.background === true ) {
1985    this.addElementBackgroundImages( elem );
1986  }
1987
1988  // find children
1989  // no non-element nodes, #143
1990  var nodeType = elem.nodeType;
1991  if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
1992    return;
1993  }
1994  var childImgs = elem.querySelectorAll('img');
1995  // concat childElems to filterFound array
1996  for ( var i=0; i < childImgs.length; i++ ) {
1997    var img = childImgs[i];
1998    this.addImage( img );
1999  }
2000
2001  // get child background images
2002  if ( typeof this.options.background == 'string' ) {
2003    var children = elem.querySelectorAll( this.options.background );
2004    for ( i=0; i < children.length; i++ ) {
2005      var child = children[i];
2006      this.addElementBackgroundImages( child );
2007    }
2008  }
2009};
2010
2011var elementNodeTypes = {
2012  1: true,
2013  9: true,
2014  11: true
2015};
2016
2017ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
2018  var style = getComputedStyle( elem );
2019  if ( !style ) {
2020    // Firefox returns null if in a hidden iframe https://bugzil.la/548397
2021    return;
2022  }
2023  // get url inside url("...")
2024  var reURL = /url\((['"])?(.*?)\1\)/gi;
2025  var matches = reURL.exec( style.backgroundImage );
2026  while ( matches !== null ) {
2027    var url = matches && matches[2];
2028    if ( url ) {
2029      this.addBackground( url, elem );
2030    }
2031    matches = reURL.exec( style.backgroundImage );
2032  }
2033};
2034
2035/**
2036 * @param {Image} img
2037 */
2038ImagesLoaded.prototype.addImage = function( img ) {
2039  var loadingImage = new LoadingImage( img );
2040  this.images.push( loadingImage );
2041};
2042
2043ImagesLoaded.prototype.addBackground = function( url, elem ) {
2044  var background = new Background( url, elem );
2045  this.images.push( background );
2046};
2047
2048ImagesLoaded.prototype.check = function() {
2049  var _this = this;
2050  this.progressedCount = 0;
2051  this.hasAnyBroken = false;
2052  // complete if no images
2053  if ( !this.images.length ) {
2054    this.complete();
2055    return;
2056  }
2057
2058  function onProgress( image, elem, message ) {
2059    // HACK - Chrome triggers event before object properties have changed. #83
2060    setTimeout( function() {
2061      _this.progress( image, elem, message );
2062    });
2063  }
2064
2065  this.images.forEach( function( loadingImage ) {
2066    loadingImage.once( 'progress', onProgress );
2067    loadingImage.check();
2068  });
2069};
2070
2071ImagesLoaded.prototype.progress = function( image, elem, message ) {
2072  this.progressedCount++;
2073  this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
2074  // progress event
2075  this.emitEvent( 'progress', [ this, image, elem ] );
2076  if ( this.jqDeferred && this.jqDeferred.notify ) {
2077    this.jqDeferred.notify( this, image );
2078  }
2079  // check if completed
2080  if ( this.progressedCount == this.images.length ) {
2081    this.complete();
2082  }
2083
2084  if ( this.options.debug && console ) {
2085    console.log( 'progress: ' + message, image, elem );
2086  }
2087};
2088
2089ImagesLoaded.prototype.complete = function() {
2090  var eventName = this.hasAnyBroken ? 'fail' : 'done';
2091  this.isComplete = true;
2092  this.emitEvent( eventName, [ this ] );
2093  this.emitEvent( 'always', [ this ] );
2094  if ( this.jqDeferred ) {
2095    var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
2096    this.jqDeferred[ jqMethod ]( this );
2097  }
2098};
2099
2100// --------------------------  -------------------------- //
2101
2102function LoadingImage( img ) {
2103  this.img = img;
2104}
2105
2106LoadingImage.prototype = Object.create( EvEmitter.prototype );
2107
2108LoadingImage.prototype.check = function() {
2109  // If complete is true and browser supports natural sizes,
2110  // try to check for image status manually.
2111  var isComplete = this.getIsImageComplete();
2112  if ( isComplete ) {
2113    // report based on naturalWidth
2114    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
2115    return;
2116  }
2117
2118  // If none of the checks above matched, simulate loading on detached element.
2119  this.proxyImage = new Image();
2120  this.proxyImage.addEventListener( 'load', this );
2121  this.proxyImage.addEventListener( 'error', this );
2122  // bind to image as well for Firefox. #191
2123  this.img.addEventListener( 'load', this );
2124  this.img.addEventListener( 'error', this );
2125  this.proxyImage.src = this.img.src;
2126};
2127
2128LoadingImage.prototype.getIsImageComplete = function() {
2129  // check for non-zero, non-undefined naturalWidth
2130  // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
2131  return this.img.complete && this.img.naturalWidth;
2132};
2133
2134LoadingImage.prototype.confirm = function( isLoaded, message ) {
2135  this.isLoaded = isLoaded;
2136  this.emitEvent( 'progress', [ this, this.img, message ] );
2137};
2138
2139// ----- events ----- //
2140
2141// trigger specified handler for event type
2142LoadingImage.prototype.handleEvent = function( event ) {
2143  var method = 'on' + event.type;
2144  if ( this[ method ] ) {
2145    this[ method ]( event );
2146  }
2147};
2148
2149LoadingImage.prototype.onload = function() {
2150  this.confirm( true, 'onload' );
2151  this.unbindEvents();
2152};
2153
2154LoadingImage.prototype.onerror = function() {
2155  this.confirm( false, 'onerror' );
2156  this.unbindEvents();
2157};
2158
2159LoadingImage.prototype.unbindEvents = function() {
2160  this.proxyImage.removeEventListener( 'load', this );
2161  this.proxyImage.removeEventListener( 'error', this );
2162  this.img.removeEventListener( 'load', this );
2163  this.img.removeEventListener( 'error', this );
2164};
2165
2166// -------------------------- Background -------------------------- //
2167
2168function Background( url, element ) {
2169  this.url = url;
2170  this.element = element;
2171  this.img = new Image();
2172}
2173
2174// inherit LoadingImage prototype
2175Background.prototype = Object.create( LoadingImage.prototype );
2176
2177Background.prototype.check = function() {
2178  this.img.addEventListener( 'load', this );
2179  this.img.addEventListener( 'error', this );
2180  this.img.src = this.url;
2181  // check if image is already complete
2182  var isComplete = this.getIsImageComplete();
2183  if ( isComplete ) {
vendor: 983 bytes, lines 2184-2222
2184    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
2185    this.unbindEvents();
2186  }
2187};
2188
2189Background.prototype.unbindEvents = function() {
2190  this.img.removeEventListener( 'load', this );
2191  this.img.removeEventListener( 'error', this );
2192};
2193
2194Background.prototype.confirm = function( isLoaded, message ) {
2195  this.isLoaded = isLoaded;
2196  this.emitEvent( 'progress', [ this, this.element, message ] );
2197};
2198
2199// -------------------------- jQuery -------------------------- //
2200
2201ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
2202  jQuery = jQuery || window.jQuery;
2203  if ( !jQuery ) {
2204    return;
2205  }
2206  // set local variable
2207  $ = jQuery;
2208  // $().imagesLoaded()
2209  $.fn.imagesLoaded = function( options, callback ) {
2210    var instance = new ImagesLoaded( this, options, callback );
2211    return instance.jqDeferred.promise( $(this) );
2212  };
2213};
2214// try making plugin
2215ImagesLoaded.makeJQueryPlugin();
2216
2217// --------------------------  -------------------------- //
2218
2219return ImagesLoaded;
2220
2221});
2222

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.