PageSourceSearch

https://www.istanbulplak.com.tr/js/jquery.queryloader2.js

js istanbulplak.com.tr collected 2026-10-03 18:14:46 UTC 36,410 bytes, 1,271 lines download raw bytes

1/*
2 * QueryLoader v2 - A simple script to create a preloader for images
3 *
4 * For instructions read the original post:
5 * http://www.gayadesign.com/diy/queryloader2-preload-your-images-with-ease/
6 *
7 * Copyright (c) 2011 - Gaya Kessler
8 *
9 * Licensed under the MIT license:
10 *   http://www.opensource.org/licenses/mit-license.php
11 *
12 * Version:  2.9.0
13 * Last update: 2014-01-31
14 */
15(function($){/*!
16 * eventie v1.0.5
17 * event binding helper
18 *   eventie.bind( elem, 'click', myFn )
19 *   eventie.unbind( elem, 'click', myFn )
20 * MIT license
21 */
22
23/*jshint browser: true, undef: true, unused: true */
24/*global define: false, module: false */
25
26( function( window ) {
27
28'use strict';
29
30var docElem = document.documentElement;
31
32var bind = function() {};
33
34function getIEEvent( obj ) {
35  var event = window.event;
36  // add event.target
37  event.target = event.target || event.srcElement || obj;
38  return event;
39}
40
41if ( docElem.addEventListener ) {
42  bind = function( obj, type, fn ) {
43    obj.addEventListener( type, fn, false );
44  };
45} else if ( docElem.attachEvent ) {
46  bind = function( obj, type, fn ) {
47    obj[ type + fn ] = fn.handleEvent ?
48      function() {
49        var event = getIEEvent( obj );
50        fn.handleEvent.call( fn, event );
51      } :
52      function() {
53        var event = getIEEvent( obj );
54        fn.call( obj, event );
55      };
56    obj.attachEvent( "on" + type, obj[ type + fn ] );
57  };
58}
59
60var unbind = function() {};
61
62if ( docElem.removeEventListener ) {
63  unbind = function( obj, type, fn ) {
64    obj.removeEventListener( type, fn, false );
65  };
66} else if ( docElem.detachEvent ) {
67  unbind = function( obj, type, fn ) {
68    obj.detachEvent( "on" + type, obj[ type + fn ] );
69    try {
70      delete obj[ type + fn ];
71    } catch ( err ) {
72      // can't delete window object properties
73      obj[ type + fn ] = undefined;
74    }
75  };
76}
77
78var eventie = {
79  bind: bind,
80  unbind: unbind
81};
82
83// ----- module definition ----- //
84
85if ( typeof define === 'function' && define.amd ) {
86  // AMD
87  define( eventie );
88} else if ( typeof exports === 'object' ) {
89  // CommonJS
90  module.exports = eventie;
91} else {
92  // browser global
93  window.eventie = eventie;
94}
95
96})( this );
97
98/*!
99 * EventEmitter v4.2.7 - git.io/ee
100 * Oliver Caldwell
101 * MIT license
102 * @preserve
103 */
104
105(function () {
106	'use strict';
107
108	/**
109	 * Class for managing events.
110	 * Can be extended to provide event functionality in other classes.
111	 *
112	 * @class EventEmitter Manages event registering and emitting.
113	 */
114	function EventEmitter() {}
115
116	// Shortcuts to improve speed and size
117	var proto = EventEmitter.prototype;
118	var exports = this;
119	var originalGlobalValue = exports.EventEmitter;
vendor: 15,308 bytes, lines 119-557
119
120
121	/**
122	 * Finds the index of the listener for the event in it's storage array.
123	 *
124	 * @param {Function[]} listeners Array of listeners to search through.
125	 * @param {Function} listener Method to look for.
126	 * @return {Number} Index of the specified listener, -1 if not found
127	 * @api private
128	 */
129	function indexOfListener(listeners, listener) {
130		var i = listeners.length;
131		while (i--) {
132			if (listeners[i].listener === listener) {
133				return i;
134			}
135		}
136
137		return -1;
138	}
139
140	/**
141	 * Alias a method while keeping the context correct, to allow for overwriting of target method.
142	 *
143	 * @param {String} name The name of the target method.
144	 * @return {Function} The aliased method
145	 * @api private
146	 */
147	function alias(name) {
148		return function aliasClosure() {
149			return this[name].apply(this, arguments);
150		};
151	}
152
153	/**
154	 * Returns the listener array for the specified event.
155	 * Will initialise the event object and listener arrays if required.
156	 * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
157	 * Each property in the object response is an array of listener functions.
158	 *
159	 * @param {String|RegExp} evt Name of the event to return the listeners from.
160	 * @return {Function[]|Object} All listener functions for the event.
161	 */
162	proto.getListeners = function getListeners(evt) {
163		var events = this._getEvents();
164		var response;
165		var key;
166
167		// Return a concatenated array of all matching events if
168		// the selector is a regular expression.
169		if (evt instanceof RegExp) {
170			response = {};
171			for (key in events) {
172				if (events.hasOwnProperty(key) && evt.test(key)) {
173					response[key] = events[key];
174				}
175			}
176		}
177		else {
178			response = events[evt] || (events[evt] = []);
179		}
180
181		return response;
182	};
183
184	/**
185	 * Takes a list of listener objects and flattens it into a list of listener functions.
186	 *
187	 * @param {Object[]} listeners Raw listener objects.
188	 * @return {Function[]} Just the listener functions.
189	 */
190	proto.flattenListeners = function flattenListeners(listeners) {
191		var flatListeners = [];
192		var i;
193
194		for (i = 0; i < listeners.length; i += 1) {
195			flatListeners.push(listeners[i].listener);
196		}
197
198		return flatListeners;
199	};
200
201	/**
202	 * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
203	 *
204	 * @param {String|RegExp} evt Name of the event to return the listeners from.
205	 * @return {Object} All listener functions for an event in an object.
206	 */
207	proto.getListenersAsObject = function getListenersAsObject(evt) {
208		var listeners = this.getListeners(evt);
209		var response;
210
211		if (listeners instanceof Array) {
212			response = {};
213			response[evt] = listeners;
214		}
215
216		return response || listeners;
217	};
218
219	/**
220	 * Adds a listener function to the specified event.
221	 * The listener will not be added if it is a duplicate.
222	 * If the listener returns true then it will be removed after it is called.
223	 * If you pass a regular expression as the event name then the listener will be added to all events that match it.
224	 *
225	 * @param {String|RegExp} evt Name of the event to attach the listener to.
226	 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
227	 * @return {Object} Current instance of EventEmitter for chaining.
228	 */
229	proto.addListener = function addListener(evt, listener) {
230		var listeners = this.getListenersAsObject(evt);
231		var listenerIsWrapped = typeof listener === 'object';
232		var key;
233
234		for (key in listeners) {
235			if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
236				listeners[key].push(listenerIsWrapped ? listener : {
237					listener: listener,
238					once: false
239				});
240			}
241		}
242
243		return this;
244	};
245
246	/**
247	 * Alias of addListener
248	 */
249	proto.on = alias('addListener');
250
251	/**
252	 * Semi-alias of addListener. It will add a listener that will be
253	 * automatically removed after it's first execution.
254	 *
255	 * @param {String|RegExp} evt Name of the event to attach the listener to.
256	 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
257	 * @return {Object} Current instance of EventEmitter for chaining.
258	 */
259	proto.addOnceListener = function addOnceListener(evt, listener) {
260		return this.addListener(evt, {
261			listener: listener,
262			once: true
263		});
264	};
265
266	/**
267	 * Alias of addOnceListener.
268	 */
269	proto.once = alias('addOnceListener');
270
271	/**
272	 * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
273	 * You need to tell it what event names should be matched by a regex.
274	 *
275	 * @param {String} evt Name of the event to create.
276	 * @return {Object} Current instance of EventEmitter for chaining.
277	 */
278	proto.defineEvent = function defineEvent(evt) {
279		this.getListeners(evt);
280		return this;
281	};
282
283	/**
284	 * Uses defineEvent to define multiple events.
285	 *
286	 * @param {String[]} evts An array of event names to define.
287	 * @return {Object} Current instance of EventEmitter for chaining.
288	 */
289	proto.defineEvents = function defineEvents(evts) {
290		for (var i = 0; i < evts.length; i += 1) {
291			this.defineEvent(evts[i]);
292		}
293		return this;
294	};
295
296	/**
297	 * Removes a listener function from the specified event.
298	 * When passed a regular expression as the event name, it will remove the listener from all events that match it.
299	 *
300	 * @param {String|RegExp} evt Name of the event to remove the listener from.
301	 * @param {Function} listener Method to remove from the event.
302	 * @return {Object} Current instance of EventEmitter for chaining.
303	 */
304	proto.removeListener = function removeListener(evt, listener) {
305		var listeners = this.getListenersAsObject(evt);
306		var index;
307		var key;
308
309		for (key in listeners) {
310			if (listeners.hasOwnProperty(key)) {
311				index = indexOfListener(listeners[key], listener);
312
313				if (index !== -1) {
314					listeners[key].splice(index, 1);
315				}
316			}
317		}
318
319		return this;
320	};
321
322	/**
323	 * Alias of removeListener
324	 */
325	proto.off = alias('removeListener');
326
327	/**
328	 * Adds listeners in bulk using the manipulateListeners method.
329	 * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
330	 * You can also pass it a regular expression to add the array of listeners to all events that match it.
331	 * Yeah, this function does quite a bit. That's probably a bad thing.
332	 *
333	 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
334	 * @param {Function[]} [listeners] An optional array of listener functions to add.
335	 * @return {Object} Current instance of EventEmitter for chaining.
336	 */
337	proto.addListeners = function addListeners(evt, listeners) {
338		// Pass through to manipulateListeners
339		return this.manipulateListeners(false, evt, listeners);
340	};
341
342	/**
343	 * Removes listeners in bulk using the manipulateListeners method.
344	 * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
345	 * You can also pass it an event name and an array of listeners to be removed.
346	 * You can also pass it a regular expression to remove the listeners from all events that match it.
347	 *
348	 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
349	 * @param {Function[]} [listeners] An optional array of listener functions to remove.
350	 * @return {Object} Current instance of EventEmitter for chaining.
351	 */
352	proto.removeListeners = function removeListeners(evt, listeners) {
353		// Pass through to manipulateListeners
354		return this.manipulateListeners(true, evt, listeners);
355	};
356
357	/**
358	 * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
359	 * The first argument will determine if the listeners are removed (true) or added (false).
360	 * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
361	 * You can also pass it an event name and an array of listeners to be added/removed.
362	 * You can also pass it a regular expression to manipulate the listeners of all events that match it.
363	 *
364	 * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
365	 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
366	 * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
367	 * @return {Object} Current instance of EventEmitter for chaining.
368	 */
369	proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
370		var i;
371		var value;
372		var single = remove ? this.removeListener : this.addListener;
373		var multiple = remove ? this.removeListeners : this.addListeners;
374
375		// If evt is an object then pass each of it's properties to this method
376		if (typeof evt === 'object' && !(evt instanceof RegExp)) {
377			for (i in evt) {
378				if (evt.hasOwnProperty(i) && (value = evt[i])) {
379					// Pass the single listener straight through to the singular method
380					if (typeof value === 'function') {
381						single.call(this, i, value);
382					}
383					else {
384						// Otherwise pass back to the multiple function
385						multiple.call(this, i, value);
386					}
387				}
388			}
389		}
390		else {
391			// So evt must be a string
392			// And listeners must be an array of listeners
393			// Loop over it and pass each one to the multiple method
394			i = listeners.length;
395			while (i--) {
396				single.call(this, evt, listeners[i]);
397			}
398		}
399
400		return this;
401	};
402
403	/**
404	 * Removes all listeners from a specified event.
405	 * If you do not specify an event then all listeners will be removed.
406	 * That means every event will be emptied.
407	 * You can also pass a regex to remove all events that match it.
408	 *
409	 * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
410	 * @return {Object} Current instance of EventEmitter for chaining.
411	 */
412	proto.removeEvent = function removeEvent(evt) {
413		var type = typeof evt;
414		var events = this._getEvents();
415		var key;
416
417		// Remove different things depending on the state of evt
418		if (type === 'string') {
419			// Remove all listeners for the specified event
420			delete events[evt];
421		}
422		else if (evt instanceof RegExp) {
423			// Remove all events matching the regex.
424			for (key in events) {
425				if (events.hasOwnProperty(key) && evt.test(key)) {
426					delete events[key];
427				}
428			}
429		}
430		else {
431			// Remove all listeners in all events
432			delete this._events;
433		}
434
435		return this;
436	};
437
438	/**
439	 * Alias of removeEvent.
440	 *
441	 * Added to mirror the node API.
442	 */
443	proto.removeAllListeners = alias('removeEvent');
444
445	/**
446	 * Emits an event of your choice.
447	 * When emitted, every listener attached to that event will be executed.
448	 * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
449	 * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
450	 * So they will not arrive within the array on the other side, they will be separate.
451	 * You can also pass a regular expression to emit to all events that match it.
452	 *
453	 * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
454	 * @param {Array} [args] Optional array of arguments to be passed to each listener.
455	 * @return {Object} Current instance of EventEmitter for chaining.
456	 */
457	proto.emitEvent = function emitEvent(evt, args) {
458		var listeners = this.getListenersAsObject(evt);
459		var listener;
460		var i;
461		var key;
462		var response;
463
464		for (key in listeners) {
465			if (listeners.hasOwnProperty(key)) {
466				i = listeners[key].length;
467
468				while (i--) {
469					// If the listener returns true then it shall be removed from the event
470					// The function is executed either with a basic call or an apply if there is an args array
471					listener = listeners[key][i];
472
473					if (listener.once === true) {
474						this.removeListener(evt, listener.listener);
475					}
476
477					response = listener.listener.apply(this, args || []);
478
479					if (response === this._getOnceReturnValue()) {
480						this.removeListener(evt, listener.listener);
481					}
482				}
483			}
484		}
485
486		return this;
487	};
488
489	/**
490	 * Alias of emitEvent
491	 */
492	proto.trigger = alias('emitEvent');
493
494	/**
495	 * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
496	 * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
497	 *
498	 * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
499	 * @param {...*} Optional additional arguments to be passed to each listener.
500	 * @return {Object} Current instance of EventEmitter for chaining.
501	 */
502	proto.emit = function emit(evt) {
503		var args = Array.prototype.slice.call(arguments, 1);
504		return this.emitEvent(evt, args);
505	};
506
507	/**
508	 * Sets the current value to check against when executing listeners. If a
509	 * listeners return value matches the one set here then it will be removed
510	 * after execution. This value defaults to true.
511	 *
512	 * @param {*} value The new value to check for when executing listeners.
513	 * @return {Object} Current instance of EventEmitter for chaining.
514	 */
515	proto.setOnceReturnValue = function setOnceReturnValue(value) {
516		this._onceReturnValue = value;
517		return this;
518	};
519
520	/**
521	 * Fetches the current value to check against when executing listeners. If
522	 * the listeners return value matches this one then it should be removed
523	 * automatically. It will return true by default.
524	 *
525	 * @return {*|Boolean} The current value to check for or the default, true.
526	 * @api private
527	 */
528	proto._getOnceReturnValue = function _getOnceReturnValue() {
529		if (this.hasOwnProperty('_onceReturnValue')) {
530			return this._onceReturnValue;
531		}
532		else {
533			return true;
534		}
535	};
536
537	/**
538	 * Fetches the events object and creates one if required.
539	 *
540	 * @return {Object} The events storage object.
541	 * @api private
542	 */
543	proto._getEvents = function _getEvents() {
544		return this._events || (this._events = {});
545	};
546
547	/**
548	 * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
549	 *
550	 * @return {Function} Non conflicting EventEmitter class.
551	 */
552	EventEmitter.noConflict = function noConflict() {
553		exports.EventEmitter = originalGlobalValue;
554		return EventEmitter;
555	};
556
557	
557// Expose the class either via AMD, CommonJS or the global object
558	if (typeof define === 'function' && define.amd) {
559		define(function () {
560			return EventEmitter;
561		});
562	}
563	else if (typeof module === 'object' && module.exports){
564		module.exports = EventEmitter;
565	}
566	else {
567		this.EventEmitter = EventEmitter;
568	}
569}.call(this));
570
571/*!
572 * imagesLoaded v3.1.4
573 * JavaScript is all like "You images are done yet or what?"
574 * MIT License
575 */
576
577( function( window, factory ) { 'use strict';
578  // universal module definition
579
580  /*global define: false, module: false, require: false */
581
582  if ( typeof define === 'function' && define.amd ) {
583    // AMD
584    define( [
585      'eventEmitter/EventEmitter',
586      'eventie/eventie'
587    ], function( EventEmitter, eventie ) {
588      return factory( window, EventEmitter, eventie );
589    });
590  } else if ( typeof exports === 'object' ) {
591    // CommonJS
592    module.exports = factory(
593      window,
594      require('eventEmitter'),
595      require('eventie')
596    );
597  } else {
598    // browser global
599    window.imagesLoaded = factory(
600      window,
601      window.EventEmitter,
602      window.eventie
603    );
604  }
605
606})( this,
607
608// --------------------------  factory -------------------------- //
609
610function factory( window, EventEmitter, eventie ) {
611
612'use strict';
613
614var $ = window.jQuery;
615var console = window.console;
616var hasConsole = typeof console !== 'undefined';
617
618// -------------------------- helpers -------------------------- //
619
620// extend objects
621function extend( a, b ) {
622  for ( var prop in b ) {
623    a[ prop ] = b[ prop ];
624  }
625  return a;
626}
627
628var objToString = Object.prototype.toString;
629function isArray( obj ) {
630  return objToString.call( obj ) === '[object Array]';
631}
632
633// turn element or nodeList into an array
634function makeArray( obj ) {
635  var ary = [];
636  if ( isArray( obj ) ) {
637    // use object if already an array
638    ary = obj;
639  } else if ( typeof obj.length === 'number' ) {
640    // convert nodeList to array
641    for ( var i=0, len = obj.length; i < len; i++ ) {
642      ary.push( obj[i] );
643    }
644  } else {
645    // array of single index
646    ary.push( obj );
647  }
648  return ary;
649}
650
651  // -------------------------- imagesLoaded -------------------------- //
652
653  /**
654   * @param {Array, Element, NodeList, String} elem
655   * @param {Object or Function} options - if function, use as callback
656   * @param {Function} onAlways - callback function
657   */
658  function ImagesLoaded( elem, options, onAlways ) {
659    // coerce ImagesLoaded() without new, to be new ImagesLoaded()
660    if ( !( this instanceof ImagesLoaded ) ) {
661      return new ImagesLoaded( elem, options );
662    }
663    // use elem as selector string
664    if ( typeof elem === 'string' ) {
665      elem = document.querySelectorAll( elem );
666    }
667
668    this.elements = makeArray( elem );
669    this.options = extend( {}, this.options );
670
671    if ( typeof options === 'function' ) {
672      onAlways = options;
673    } else {
674      extend( this.options, options );
675    }
676
677    if ( onAlways ) {
678      this.on( 'always', onAlways );
679    }
680
681    this.getImages();
682
683    if ( $ ) {
684      // add jQuery Deferred object
685      this.jqDeferred = new $.Deferred();
686    }
687
688    // HACK check async to allow time to bind listeners
689    var _this = this;
690    setTimeout( function() {
691      _this.check();
692    });
693  }
694
695  ImagesLoaded.prototype = new EventEmitter();
696
697  ImagesLoaded.prototype.options = {};
698
699  ImagesLoaded.prototype.getImages = function() {
700    this.images = [];
701
702    // filter & find items if we have an item selector
703    for ( var i=0, len = this.elements.length; i < len; i++ ) {
704      var elem = this.elements[i];
705      // filter siblings
706      if ( elem.nodeName === 'IMG' ) {
707        this.addImage( elem );
708      }
709      // find children
710      var childElems = elem.querySelectorAll('img');
711      // concat childElems to filterFound array
712      for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
713        var img = childElems[j];
714        this.addImage( img );
715      }
716    }
717  };
718
719  /**
720   * @param {Image} img
721   */
722  ImagesLoaded.prototype.addImage = function( img ) {
723    var loadingImage = new LoadingImage( img );
724    this.images.push( loadingImage );
725  };
726
727  ImagesLoaded.prototype.check = function() {
728    var _this = this;
729    var checkedCount = 0;
730    var length = this.images.length;
731    this.hasAnyBroken = false;
732    // complete if no images
733    if ( !length ) {
734      this.complete();
735      return;
736    }
737
738    function onConfirm( image, message ) {
739      if ( _this.options.debug && hasConsole ) {
740        
741      }
742
743      _this.progress( image );
744      checkedCount++;
745      if ( checkedCount === length ) {
746        _this.complete();
747      }
748      return true; // bind once
749    }
750
751    for ( var i=0; i < length; i++ ) {
752      var loadingImage = this.images[i];
753      loadingImage.on( 'confirm', onConfirm );
754      loadingImage.check();
755    }
756  };
757
758  ImagesLoaded.prototype.progress = function( image ) {
759    this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
760    // HACK - Chrome triggers event before object properties have changed. #83
761    var _this = this;
762    setTimeout( function() {
763      _this.emit( 'progress', _this, image );
764      if ( _this.jqDeferred && _this.jqDeferred.notify ) {
765        _this.jqDeferred.notify( _this, image );
766      }
767    });
768  };
769
770  ImagesLoaded.prototype.complete = function() {
771    var eventName = this.hasAnyBroken ? 'fail' : 'done';
772    this.isComplete = true;
773    var _this = this;
774    // HACK - another setTimeout so that confirm happens after progress
775    setTimeout( function() {
776      _this.emit( eventName, _this );
777      _this.emit( 'always', _this );
778      if ( _this.jqDeferred ) {
779        var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve';
780        _this.jqDeferred[ jqMethod ]( _this );
781      }
782    });
783  };
784
785  // -------------------------- jquery -------------------------- //
786
787  if ( $ ) {
788    $.fn.imagesLoaded = function( options, callback ) {
789      var instance = new ImagesLoaded( this, options, callback );
790      return instance.jqDeferred.promise( $(this) );
791    };
792  }
793
794
795  // --------------------------  -------------------------- //
796
797  function LoadingImage( img ) {
798    this.img = img;
799  }
800
801  LoadingImage.prototype = new EventEmitter();
802
803  LoadingImage.prototype.check = function() {
804    // first check cached any previous images that have same src
805    var resource = cache[ this.img.src ] || new Resource( this.img.src );
806    if ( resource.isConfirmed ) {
807      this.confirm( resource.isLoaded, 'cached was confirmed' );
808      return;
809    }
810
811    // If complete is true and browser supports natural sizes,
812    // try to check for image status manually.
813    if ( this.img.complete && this.img.naturalWidth !== undefined ) {
814      // report based on naturalWidth
815      this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
816      return;
817    }
818
819    // If none of the checks above matched, simulate loading on detached element.
820    var _this = this;
821    resource.on( 'confirm', function( resrc, message ) {
822      _this.confirm( resrc.isLoaded, message );
823      return true;
824    });
825
826    resource.check();
827  };
828
829  LoadingImage.prototype.confirm = function( isLoaded, message ) {
830    this.isLoaded = isLoaded;
831    this.emit( 'confirm', this, message );
832  };
833
834  // -------------------------- Resource -------------------------- //
835
836  // Resource checks each src, only once
837  // separate class from LoadingImage to prevent memory leaks. See #115
838
839  var cache = {};
840
841  function Resource( src ) {
842    this.src = src;
843    // add to cache
844    cache[ src ] = this;
845  }
846
847  Resource.prototype = new EventEmitter();
848
849  Resource.prototype.check = function() {
850    // only trigger checking once
851    if ( this.isChecked ) {
852      return;
853    }
854    // simulate loading on detached element
855    var proxyImage = new Image();
856    eventie.bind( proxyImage, 'load', this );
857    eventie.bind( proxyImage, 'error', this );
858    proxyImage.src = this.src;
859    // set flag
860    this.isChecked = true;
861  };
862
863  // ----- events ----- //
864
865  // trigger specified handler for event type
866  Resource.prototype.handleEvent = function( event ) {
867    var method = 'on' + event.type;
868    if ( this[ method ] ) {
869      this[ method ]( event );
870    }
871  };
872
873  Resource.prototype.onload = function( event ) {
874    this.confirm( true, 'onload' );
875    this.unbindProxyEvents( event );
876  };
877
878  Resource.prototype.onerror = function( event ) {
879    this.confirm( false, 'onerror' );
880    this.unbindProxyEvents( event );
881  };
882
883  // ----- confirm ----- //
884
885  Resource.prototype.confirm = function( isLoaded, message ) {
886    this.isConfirmed = true;
887    this.isLoaded = isLoaded;
888    this.emit( 'confirm', this, message );
889  };
890
891  Resource.prototype.unbindProxyEvents = function( event ) {
892    eventie.unbind( event.target, 'load', this );
893    eventie.unbind( event.target, 'error', this );
894  };
895
896  // -----  ----- //
897
898  return ImagesLoaded;
899
900});
901
902function OverlayLoader(parent) {
903	this.parent = parent;
904	this.container;
905	this.loadbar;
906	this.percentageContainer;
907};
908
909OverlayLoader.prototype.createOverlay = function () {
910	
911
912	//determine postion of overlay and set parent position
913	var overlayPosition = "absolute";
914
915	if (this.parent.element.tagName.toLowerCase() == "body") {
916		overlayPosition = "fixed";
917	} else {
918		var pos = this.parent.$element.css("position");
919		if (pos != "fixed" || pos != "absolute") {
920			this.parent.$element.css("position", "relative");
921		}
922	}
923
924	//create the overlay container
925	this.container = $("<div id='" + this.parent.options.overlayId + "'></div>").css({
926		width: "100%",
927		height: "100%",
928		backgroundColor: this.parent.options.backgroundColor,
929		backgroundPosition: "fixed",
930		position: overlayPosition,
931		zIndex: 666999, //very high!
932		top: 0,
933		left: 0
934	}).appendTo(this.parent.$element);
935
936	//create the loading bar
937	this.loadbar = $("<div id='qLbar'></div>").css({
938		height: this.parent.options.barHeight + "px",
939		marginTop: "-" + (this.parent.options.barHeight / 2) + "px",
940		backgroundColor: this.parent.options.barColor,
941		width: "0%",
942		position: "absolute",
943		top: "50%"
944	}).appendTo(this.container);
945
946	//if percentage is on
947	if (this.parent.options.percentage == true) {
948		this.percentageContainer = $("<div id='qLpercentage'></div>").text("0%").css({
949			height: "40px",
950			width: "100px",
951			position: "absolute",
952			fontSize: "3em",
953			top: "50%",
954			left: "50%",
955			marginTop: "-" + (59 + this.parent.options.barHeight) + "px",
956			textAlign: "center",
957			marginLeft: "-50px",
958			color: this.parent.options.barColor
959		}).appendTo(this.container);
960	}
961
962	//if no images... destroy
963	if (!this.parent.preloadContainer.toPreload.length || this.parent.alreadyLoaded == true) {
964		this.parent.destroyContainers();
965	}
966};
967
968OverlayLoader.prototype.updatePercentage = function (percentage) {
969	this.loadbar.stop().animate({
970		width: percentage + "%",
971		minWidth: percentage + "%"
972	}, 200);
973
974	//update textual percentage
975	if (this.parent.options.percentage == true) {
976		this.percentageContainer.text(Math.ceil(percentage) + "%");
977	}
978};
979function PreloadContainer(parent) {
980    this.toPreload = [];
981    this.parent = parent;
982    this.container;
983};
984
985PreloadContainer.prototype.create = function () {
986    this.container = $("<div></div>").appendTo("body").css({
987        display: "none",
988        width: 0,
989        height: 0,
990        overflow: "hidden"
991    });
992
993    //process the image queue
994    this.processQueue();
995};
996
997PreloadContainer.prototype.processQueue = function () {
998    //add background images for loading
999    for (var i = 0; this.toPreload.length > i; i++) {
1000		if (!this.parent.destroyed) {
1001			this.preloadImage(this.toPreload[i]);
1002		}
1003    }
1004};
1005
1006PreloadContainer.prototype.addImage = function (src) {
1007    
1008    this.toPreload.push(src);
1009};
1010
1011PreloadContainer.prototype.preloadImage = function (url) {
1012    
1013    var image = new PreloadImage();
1014    image.addToPreloader(this, url);
1015    image.bindLoadEvent();
1016};
1017function PreloadImage(parent) {
1018    this.element;
1019    this.parent = parent;
1020};
1021
1022PreloadImage.prototype.addToPreloader = function (preloader, url) {
1023	
1024    this.element = $("<img />").attr("src", url);
1025    this.element.appendTo(preloader.container);
1026    this.parent = preloader.parent;
1027};
1028
1029PreloadImage.prototype.bindLoadEvent = function () {
1030    this.parent.imageCounter++;
1031
1032    //binding
1033    this.element[0].ref = this;
1034
1035    new imagesLoaded(this.element, function (e) {
1036        e.elements[0].ref.completeLoading();
1037    });
1038};
1039
1040PreloadImage.prototype.completeLoading = function () {
1041    this.parent.imageDone++;
1042
1043    var percentage = (this.parent.imageDone / this.parent.imageCounter) * 100;
1044
1045    
1046
1047	//update the percentage of the loader
1048	this.parent.overlayLoader.updatePercentage(percentage);
1049
1050	//all images done!
1051    if (this.parent.imageDone == this.parent.imageCounter || percentage >= 100) {
1052		this.parent.endLoader();
1053    }
1054};
1055function QueryLoader2(element, options) {
1056	this.element = element;
1057    this.$element = $(element);
1058	this.options = options;
1059    this.foundUrls = [];
1060    this.destroyed = false;
1061    this.imageCounter = 0;
1062    this.imageDone = 0;
1063	this.alreadyLoaded = false;
1064
1065	//create objects
1066    this.preloadContainer = new PreloadContainer(this);
1067	this.overlayLoader = new OverlayLoader(this);
1068
1069	//The default options
1070    this.defaultOptions = {
1071        onComplete: function() {},
1072		onLoadComplete: function() {},
1073        backgroundColor: "#000",
1074        barColor: "#fff",
1075        overlayId: 'qLoverlay',
1076        barHeight: 1,
1077        percentage: false,
1078        deepSearch: true,
1079        completeAnimation: "fade",
1080        minimumTime: 500
1081    };
1082
1083	//run the init
1084	this.init();
1085};
1086
1087QueryLoader2.prototype.init = function() {
1088	
1089
1090	
1091	this.options = $.extend({}, this.defaultOptions, this.options);
1092
1093    
1094    var images = this.findImageInElement(this.element);
1095    if (this.options.deepSearch == true) {
1096        
1097        var elements = this.$element.find("*:not(script)");
1098        for (var i = 0; i < elements.length; i++) {
1099            this.findImageInElement(elements[i]);
1100        }
1101    }
1102
1103    //create containers
1104    this.preloadContainer.create();
1105	this.overlayLoader.createOverlay();
1106};
1107
1108QueryLoader2.prototype.findImageInElement = function (element) {
1109    var url = "";
1110    var obj = $(element);
1111    var type = "normal";
1112
1113    if (obj.css("background-image") != "none") {
1114        //if object has background image
1115        url = obj.css("background-image");
1116        type = "background";
1117    } else if (typeof(obj.attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") {
1118        //if is img and has src
1119        url = obj.attr("src");
1120    }
1121
1122    //skip if gradient
1123    if (!this.hasGradient(url)) {
1124        //remove unwanted chars
1125        url = this.stripUrl(url);
1126
1127        //split urls
1128        var urls = url.split(", ");
1129
1130        for (var i = 0; i < urls.length; i++) {
1131            if (this.validUrl(urls[i]) && this.urlIsNew(urls[i])) {
1132                
1133                var extra = "";
1134
1135                if (this.isIE() || this.isOpera()){
1136                    //filthy always no cache for IE, sorry peeps!
1137                    extra = "?rand=" + Math.random();
1138
1139                    //add to preloader
1140                    this.preloadContainer.addImage(urls[i] + extra);
1141                } else {
1142                    if (type == "background") {
1143                        //add to preloader
1144                        this.preloadContainer.addImage(urls[i] + extra);
1145                    } else {
1146                        var image = new PreloadImage(this);
1147                        image.element = obj;
1148                        image.bindLoadEvent();
1149                    }
1150                }
1151
1152                //add image to found list
1153                this.foundUrls.push(urls[i]);
1154            }
1155        }
1156    }
1157};
1158
1159QueryLoader2.prototype.hasGradient = function (url) {
1160    if (url.indexOf("gradient") == -1) {
1161        return false;
1162    } else {
1163        return true;
1164    }
1165};
1166
1167QueryLoader2.prototype.stripUrl = function (url) {
1168    url = url.replace(/url\(\"/g, "");
1169    url = url.replace(/url\(/g, "");
1170    url = url.replace(/\"\)/g, "");
1171    url = url.replace(/\)/g, "");
1172
1173    return url;
1174};
1175
1176QueryLoader2.prototype.isIE = function () {
1177    return navigator.userAgent.match(/msie/i);
1178};
1179
1180QueryLoader2.prototype.isOpera = function () {
1181    return navigator.userAgent.match(/Opera/i);
1182};
1183
1184QueryLoader2.prototype.validUrl = function (url) {
1185    if (url.length > 0 && !url.match(/^(data:)/i)) {
1186        return true;
1187    } else {
1188        return false;
1189    }
1190};
1191
1192QueryLoader2.prototype.urlIsNew = function (url) {
1193    if (this.foundUrls.indexOf(url) == -1) {
1194        return true;
1195    } else {
1196        return false;
1197    }
1198};
1199
1200QueryLoader2.prototype.destroyContainers = function () {
1201	this.destroyed = true;
1202	this.preloadContainer.container.remove();
1203	this.overlayLoader.container.remove();
1204};
1205
1206QueryLoader2.prototype.endLoader = function () {
1207	
1208
1209	this.destroyed = true;
1210	this.onLoadComplete();
1211};
1212
1213QueryLoader2.prototype.onLoadComplete = function() {
1214	//fire the event before end animation
1215	this.options.onLoadComplete();
1216
1217	if (this.options.completeAnimation == "grow") {
1218		var animationTime = this.options.minimumTime;
1219
1220		this.overlayLoader.loadbar[0].parent = this; //put object in DOM element
1221		this.overlayLoader.loadbar.stop().animate({
1222			"width": "100%"
1223		}, animationTime, function () {
1224			$(this).animate({
1225				top: "0%",
1226				width: "100%",
1227				height: "100%"
1228			}, 500, function () {
1229				this.parent.overlayLoader.container[0].parent = this.parent; //once again...
1230				this.parent.overlayLoader.container.fadeOut(500, function () {
1231					this.parent.destroyContainers();
1232					this.parent.options.onComplete();
1233				});
1234			});
1235		});
1236	} else {
1237        var animationTime = this.options.minimumTime;
1238
1239		this.overlayLoader.container[0].parent = this;
1240		this.overlayLoader.container.fadeOut(animationTime, function () {
1241			this.parent.destroyContainers();
1242			this.parent.options.onComplete();
1243		});
1244	}
1245};
1246//HERE COMES THE IE SHITSTORM
1247if (!Array.prototype.indexOf) {
1248	Array.prototype.indexOf = function (elt /*, from*/) {
1249		var len = this.length >>> 0;
1250		var from = Number(arguments[1]) || 0;
1251		from = (from < 0)
1252			? Math.ceil(from)
1253			: Math.floor(from);
1254		if (from < 0)
1255			from += len;
1256
1257		for (; from < len; from++) {
1258			if (from in this &&
1259				this[from] === elt)
1260				return from;
1261		}
1262		return -1;
1263	};
1264}
1265//function binder
1266$.fn.queryLoader2 = function(options){
1267    return this.each(function(){
1268        (new QueryLoader2(this, options));
1269    });
1270};
1271})(jQuery);

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.