PageSourceSearch

https://www.ville-roquefort-les-pins.fr/js/isotope/isotope.pkgd.js

js ville-roquefort-les-pins.fr collected 2026-10-02 17:55:41 UTC 107,401 bytes, 3,925 lines download raw bytes

1/*!
2 * Isotope PACKAGED v2.0.1
3 * Filter & sort magical layouts
4 * http://isotope.metafizzy.co
5 */
6
7/**
8 * Bridget makes jQuery widgets
9 * v1.0.1
10 */
11
12( function( window ) {
13
14
15
16// -------------------------- utils -------------------------- //
17
18var slice = Array.prototype.slice;
19
20function noop() {}
21
22// -------------------------- definition -------------------------- //
23
24function defineBridget( $ ) {
25
26// bail if no jQuery
27if ( !$ ) {
28  return;
29}
30
31// -------------------------- addOptionMethod -------------------------- //
32
33/**
34 * adds option method -> $().plugin('option', {...})
35 * @param {Function} PluginClass - constructor class
36 */
37function addOptionMethod( PluginClass ) {
38  // don't overwrite original option method
39  if ( PluginClass.prototype.option ) {
40    return;
41  }
42
43  // option setter
44  PluginClass.prototype.option = function( opts ) {
45    // bail out if not an object
46    if ( !$.isPlainObject( opts ) ){
47      return;
48    }
49    this.options = $.extend( true, this.options, opts );
50  };
51}
52
53
54// -------------------------- plugin bridge -------------------------- //
55
56// helper function for logging errors
57// $.error breaks jQuery chaining
58var logError = typeof console === 'undefined' ? noop :
59  function( message ) {
60    console.error( message );
61  };
62
63/**
64 * jQuery plugin bridge, access methods like $elem.plugin('method')
65 * @param {String} namespace - plugin name
66 * @param {Function} PluginClass - constructor class
67 */
68function bridge( namespace, PluginClass ) {
69  // add to jQuery fn namespace
70  $.fn[ namespace ] = function( options ) {
71    if ( typeof options === 'string' ) {
72      // call plugin method when first argument is a string
73      // get arguments for method
74      var args = slice.call( arguments, 1 );
75
76      for ( var i=0, len = this.length; i < len; i++ ) {
77        var elem = this[i];
78        var instance = $.data( elem, namespace );
79        if ( !instance ) {
80          logError( "cannot call methods on " + namespace + " prior to initialization; " +
81            "attempted to call '" + options + "'" );
82          continue;
83        }
84        if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) {
85          logError( "no such method '" + options + "' for " + namespace + " instance" );
86          continue;
87        }
88
89        // trigger method with arguments
90        var returnValue = instance[ options ].apply( instance, args );
91
92        // break look and return first value if provided
93        if ( returnValue !== undefined ) {
94          return returnValue;
95        }
96      }
97      // return this if no return value
98      return this;
99    } else {
100      return this.each( function() {
101        var instance = $.data( this, namespace );
102        if ( instance ) {
103          // apply options & init
104          instance.option( options );
105          instance._init();
106        } else {
107          // initialize new instance
108          instance = new PluginClass( this, options );
109          $.data( this, namespace, instance );
110        }
111      });
112    }
113  };
114
115}
116
117// -------------------------- bridget -------------------------- //
118
119/**
120 * converts a Prototypical class into a proper jQuery plugin
121 *   the class must have a ._init method
122 * @param {String} namespace - plugin name, used in $().pluginName
123 * @param {Function} PluginClass - constructor class
124 */
125$.bridget = function( namespace, PluginClass ) {
126  addOptionMethod( PluginClass );
127  bridge( namespace, PluginClass );
128};
129
130return $.bridget;
131
132}
133
134// transport
135if ( typeof define === 'function' && define.amd ) {
136  // AMD
137  define( 'jquery-bridget/jquery.bridget',[ 'jquery' ], defineBridget );
138} else {
139  // get jquery from browser global
140  defineBridget( window.jQuery );
141}
142
143})( window );
144
145/*!
146 * eventie v1.0.5
147 * event binding helper
148 *   eventie.bind( elem, 'click', myFn )
149 *   eventie.unbind( elem, 'click', myFn )
150 * MIT license
151 */
152
153/*jshint browser: true, undef: true, unused: true */
154/*global define: false, module: false */
155
156( function( window ) {
157
158
159
160var docElem = document.documentElement;
161
162var bind = function() {};
163
164function getIEEvent( obj ) {
165  var event = window.event;
166  // add event.target
167  event.target = event.target || event.srcElement || obj;
168  return event;
169}
170
171if ( docElem.addEventListener ) {
172  bind = function( obj, type, fn ) {
173    obj.addEventListener( type, fn, false );
174  };
175} else if ( docElem.attachEvent ) {
176  bind = function( obj, type, fn ) {
177    obj[ type + fn ] = fn.handleEvent ?
178      function() {
179        var event = getIEEvent( obj );
180        fn.handleEvent.call( fn, event );
181      } :
182      function() {
183        var event = getIEEvent( obj );
184        fn.call( obj, event );
185      };
186    obj.attachEvent( "on" + type, obj[ type + fn ] );
187  };
188}
189
190var unbind = function() {};
191
192if ( docElem.removeEventListener ) {
193  unbind = function( obj, type, fn ) {
194    obj.removeEventListener( type, fn, false );
195  };
196} else if ( docElem.detachEvent ) {
197  unbind = function( obj, type, fn ) {
198    obj.detachEvent( "on" + type, obj[ type + fn ] );
199    try {
200      delete obj[ type + fn ];
201    } catch ( err ) {
202      // can't delete window object properties
203      obj[ type + fn ] = undefined;
204    }
205  };
206}
207
208var eventie = {
209  bind: bind,
210  unbind: unbind
211};
212
213// ----- module definition ----- //
214
215if ( typeof define === 'function' && define.amd ) {
216  // AMD
217  define( 'eventie/eventie',eventie );
218} else if ( typeof exports === 'object' ) {
219  // CommonJS
220  module.exports = eventie;
221} else {
222  // browser global
223  window.eventie = eventie;
224}
225
226})( this );
227
228/*!
229 * docReady
230 * Cross browser DOMContentLoaded event emitter
231 */
232
233/*jshint browser: true, strict: true, undef: true, unused: true*/
234/*global define: false */
235
236( function( window ) {
237
238
239
240var document = window.document;
241// collection of functions to be triggered on ready
242var queue = [];
243
244function docReady( fn ) {
245  // throw out non-functions
246  if ( typeof fn !== 'function' ) {
247    return;
248  }
249
250  if ( docReady.isReady ) {
251    // ready now, hit it
252    fn();
253  } else {
254    // queue function when ready
255    queue.push( fn );
256  }
257}
258
259docReady.isReady = false;
260
261// triggered on various doc ready events
262function init( event ) {
263  // bail if IE8 document is not ready just yet
264  var isIE8NotReady = event.type === 'readystatechange' && document.readyState !== 'complete';
265  if ( docReady.isReady || isIE8NotReady ) {
266    return;
267  }
268  docReady.isReady = true;
269
270  // process queue
271  for ( var i=0, len = queue.length; i < len; i++ ) {
272    var fn = queue[i];
273    fn();
274  }
275}
276
277function defineDocReady( eventie ) {
278  eventie.bind( document, 'DOMContentLoaded', init );
279  eventie.bind( document, 'readystatechange', init );
280  eventie.bind( window, 'load', init );
281
282  return docReady;
283}
284
285// transport
286if ( typeof define === 'function' && define.amd ) {
287  // AMD
288  // if RequireJS, then doc is already ready
289  docReady.isReady = typeof requirejs === 'function';
290  define( 'doc-ready/doc-ready',[ 'eventie/eventie' ], defineDocReady );
291} else {
292  // browser global
293  window.docReady = defineDocReady( window.eventie );
294}
295
296})( this );
297
298/*!
299 * EventEmitter v4.2.7 - git.io/ee
300 * Oliver Caldwell
301 * MIT license
302 * @preserve
303 */
304
305(function () {
306	
307
308	/**
309	 * Class for managing events.
310	 * Can be extended to provide event functionality in other classes.
311	 *
312	 * @class EventEmitter Manages event registering and emitting.
313	 */
314	function EventEmitter() {}
315
316	// Shortcuts to improve speed and size
317	var proto = EventEmitter.prototype;
318	var exports = this;
319	var originalGlobalValue = exports.EventEmitter;
320
321	/**
322	 * Finds the index of the listener for the event in it's storage array.
323	 *
324	 * @param {Function[]} listeners Array of listeners to search through.
325	 * @param {Function} listener Method to look for.
326	 * @return {Number} Index of the specified listener, -1 if not found
327	 * @api private
328	 */
329	function indexOfListener(listeners, listener) {
330		var i = listeners.length;
331		while (i--) {
332			if (listeners[i].listener === listener) {
333				return i;
334			}
335		}
336
337		return -1;
338	}
339
340	/**
341	 * Alias a method while keeping the context correct, to allow for over
vendor: 11,657 bytes, lines 341-649
341writing of target method.
342	 *
343	 * @param {String} name The name of the target method.
344	 * @return {Function} The aliased method
345	 * @api private
346	 */
347	function alias(name) {
348		return function aliasClosure() {
349			return this[name].apply(this, arguments);
350		};
351	}
352
353	/**
354	 * Returns the listener array for the specified event.
355	 * Will initialise the event object and listener arrays if required.
356	 * 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.
357	 * Each property in the object response is an array of listener functions.
358	 *
359	 * @param {String|RegExp} evt Name of the event to return the listeners from.
360	 * @return {Function[]|Object} All listener functions for the event.
361	 */
362	proto.getListeners = function getListeners(evt) {
363		var events = this._getEvents();
364		var response;
365		var key;
366
367		// Return a concatenated array of all matching events if
368		// the selector is a regular expression.
369		if (evt instanceof RegExp) {
370			response = {};
371			for (key in events) {
372				if (events.hasOwnProperty(key) && evt.test(key)) {
373					response[key] = events[key];
374				}
375			}
376		}
377		else {
378			response = events[evt] || (events[evt] = []);
379		}
380
381		return response;
382	};
383
384	/**
385	 * Takes a list of listener objects and flattens it into a list of listener functions.
386	 *
387	 * @param {Object[]} listeners Raw listener objects.
388	 * @return {Function[]} Just the listener functions.
389	 */
390	proto.flattenListeners = function flattenListeners(listeners) {
391		var flatListeners = [];
392		var i;
393
394		for (i = 0; i < listeners.length; i += 1) {
395			flatListeners.push(listeners[i].listener);
396		}
397
398		return flatListeners;
399	};
400
401	/**
402	 * 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.
403	 *
404	 * @param {String|RegExp} evt Name of the event to return the listeners from.
405	 * @return {Object} All listener functions for an event in an object.
406	 */
407	proto.getListenersAsObject = function getListenersAsObject(evt) {
408		var listeners = this.getListeners(evt);
409		var response;
410
411		if (listeners instanceof Array) {
412			response = {};
413			response[evt] = listeners;
414		}
415
416		return response || listeners;
417	};
418
419	/**
420	 * Adds a listener function to the specified event.
421	 * The listener will not be added if it is a duplicate.
422	 * If the listener returns true then it will be removed after it is called.
423	 * If you pass a regular expression as the event name then the listener will be added to all events that match it.
424	 *
425	 * @param {String|RegExp} evt Name of the event to attach the listener to.
426	 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
427	 * @return {Object} Current instance of EventEmitter for chaining.
428	 */
429	proto.addListener = function addListener(evt, listener) {
430		var listeners = this.getListenersAsObject(evt);
431		var listenerIsWrapped = typeof listener === 'object';
432		var key;
433
434		for (key in listeners) {
435			if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
436				listeners[key].push(listenerIsWrapped ? listener : {
437					listener: listener,
438					once: false
439				});
440			}
441		}
442
443		return this;
444	};
445
446	/**
447	 * Alias of addListener
448	 */
449	proto.on = alias('addListener');
450
451	/**
452	 * Semi-alias of addListener. It will add a listener that will be
453	 * automatically removed after it's first execution.
454	 *
455	 * @param {String|RegExp} evt Name of the event to attach the listener to.
456	 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
457	 * @return {Object} Current instance of EventEmitter for chaining.
458	 */
459	proto.addOnceListener = function addOnceListener(evt, listener) {
460		return this.addListener(evt, {
461			listener: listener,
462			once: true
463		});
464	};
465
466	/**
467	 * Alias of addOnceListener.
468	 */
469	proto.once = alias('addOnceListener');
470
471	/**
472	 * 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.
473	 * You need to tell it what event names should be matched by a regex.
474	 *
475	 * @param {String} evt Name of the event to create.
476	 * @return {Object} Current instance of EventEmitter for chaining.
477	 */
478	proto.defineEvent = function defineEvent(evt) {
479		this.getListeners(evt);
480		return this;
481	};
482
483	/**
484	 * Uses defineEvent to define multiple events.
485	 *
486	 * @param {String[]} evts An array of event names to define.
487	 * @return {Object} Current instance of EventEmitter for chaining.
488	 */
489	proto.defineEvents = function defineEvents(evts) {
490		for (var i = 0; i < evts.length; i += 1) {
491			this.defineEvent(evts[i]);
492		}
493		return this;
494	};
495
496	/**
497	 * Removes a listener function from the specified event.
498	 * When passed a regular expression as the event name, it will remove the listener from all events that match it.
499	 *
500	 * @param {String|RegExp} evt Name of the event to remove the listener from.
501	 * @param {Function} listener Method to remove from the event.
502	 * @return {Object} Current instance of EventEmitter for chaining.
503	 */
504	proto.removeListener = function removeListener(evt, listener) {
505		var listeners = this.getListenersAsObject(evt);
506		var index;
507		var key;
508
509		for (key in listeners) {
510			if (listeners.hasOwnProperty(key)) {
511				index = indexOfListener(listeners[key], listener);
512
513				if (index !== -1) {
514					listeners[key].splice(index, 1);
515				}
516			}
517		}
518
519		return this;
520	};
521
522	/**
523	 * Alias of removeListener
524	 */
525	proto.off = alias('removeListener');
526
527	/**
528	 * Adds listeners in bulk using the manipulateListeners method.
529	 * 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.
530	 * You can also pass it a regular expression to add the array of listeners to all events that match it.
531	 * Yeah, this function does quite a bit. That's probably a bad thing.
532	 *
533	 * @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.
534	 * @param {Function[]} [listeners] An optional array of listener functions to add.
535	 * @return {Object} Current instance of EventEmitter for chaining.
536	 */
537	proto.addListeners = function addListeners(evt, listeners) {
538		// Pass through to manipulateListeners
539		return this.manipulateListeners(false, evt, listeners);
540	};
541
542	/**
543	 * Removes listeners in bulk using the manipulateListeners method.
544	 * 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.
545	 * You can also pass it an event name and an array of listeners to be removed.
546	 * You can also pass it a regular expression to remove the listeners from all events that match it.
547	 *
548	 * @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.
549	 * @param {Function[]} [listeners] An optional array of listener functions to remove.
550	 * @return {Object} Current instance of EventEmitter for chaining.
551	 */
552	proto.removeListeners = function removeListeners(evt, listeners) {
553		// Pass through to manipulateListeners
554		return this.manipulateListeners(true, evt, listeners);
555	};
556
557	/**
558	 * 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.
559	 * The first argument will determine if the listeners are removed (true) or added (false).
560	 * 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.
561	 * You can also pass it an event name and an array of listeners to be added/removed.
562	 * You can also pass it a regular expression to manipulate the listeners of all events that match it.
563	 *
564	 * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
565	 * @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.
566	 * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
567	 * @return {Object} Current instance of EventEmitter for chaining.
568	 */
569	proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
570		var i;
571		var value;
572		var single = remove ? this.removeListener : this.addListener;
573		var multiple = remove ? this.removeListeners : this.addListeners;
574
575		// If evt is an object then pass each of it's properties to this method
576		if (typeof evt === 'object' && !(evt instanceof RegExp)) {
577			for (i in evt) {
578				if (evt.hasOwnProperty(i) && (value = evt[i])) {
579					// Pass the single listener straight through to the singular method
580					if (typeof value === 'function') {
581						single.call(this, i, value);
582					}
583					else {
584						// Otherwise pass back to the multiple function
585						multiple.call(this, i, value);
586					}
587				}
588			}
589		}
590		else {
591			// So evt must be a string
592			// And listeners must be an array of listeners
593			// Loop over it and pass each one to the multiple method
594			i = listeners.length;
595			while (i--) {
596				single.call(this, evt, listeners[i]);
597			}
598		}
599
600		return this;
601	};
602
603	/**
604	 * Removes all listeners from a specified event.
605	 * If you do not specify an event then all listeners will be removed.
606	 * That means every event will be emptied.
607	 * You can also pass a regex to remove all events that match it.
608	 *
609	 * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
610	 * @return {Object} Current instance of EventEmitter for chaining.
611	 */
612	proto.removeEvent = function removeEvent(evt) {
613		var type = typeof evt;
614		var events = this._getEvents();
615		var key;
616
617		// Remove different things depending on the state of evt
618		if (type === 'string') {
619			// Remove all listeners for the specified event
620			delete events[evt];
621		}
622		else if (evt instanceof RegExp) {
623			// Remove all events matching the regex.
624			for (key in events) {
625				if (events.hasOwnProperty(key) && evt.test(key)) {
626					delete events[key];
627				}
628			}
629		}
630		else {
631			// Remove all listeners in all events
632			delete this._events;
633		}
634
635		return this;
636	};
637
638	/**
639	 * Alias of removeEvent.
640	 *
641	 * Added to mirror the node API.
642	 */
643	proto.removeAllListeners = alias('removeEvent');
644
645	/**
646	 * Emits an event of your choice.
647	 * When emitted, every listener attached to that event will be executed.
648	 * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
649	 * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
650	 * So they will not arrive within the array on the other side, they will be separate.
651	 * You can also pass a regular expression to emit to all events that match it.
652	 *
653	 * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
654	 * @param {Array} [args] Optional array of arguments to be passed to each listener.
655	 * @return {Object} Current instance of EventEmitter for chaining.
656	 */
657	proto.emitEvent = function emitEvent(evt, args) {
658		var listeners = this.getListenersAsObject(evt);
659		var listener;
660		var i;
661		var key;
662		var response;
663
664		for (key in listeners) {
665			if (listeners.hasOwnProperty(key)) {
666				i = listeners[key].length;
667
668				while (i--) {
669					// If the listener returns true then it shall be removed from the event
670					// The function is executed either with a basic call or an apply if there is an args array
671					listener = listeners[key][i];
672
673					if (listener.once === true) {
674						this.removeListener(evt, listener.listener);
675					}
676
677					response = listener.listener.apply(this, args || []);
678
679					if (response === this._getOnceReturnValue()) {
680						this.removeListener(evt, listener.listener);
681					}
682				}
683			}
684		}
685
686		return this;
687	};
688
689	/**
690	 * Alias of emitEvent
691	 */
692	proto.trigger = alias('emitEvent');
693
694	/**
695	 * 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.
696	 * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
697	 *
698	 * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
699	 * @param {...*} Optional additional arguments to be passed to each listener.
700	 * @return {Object} Current instance of EventEmitter for chaining.
701	 */
702	proto.emit = function emit(evt) {
703		var args = Array.prototype.slice.call(arguments, 1);
704		return this.emitEvent(evt, args);
705	};
706
707	/**
708	 * Sets the current value to check against when executing listeners. If a
709	 * listeners return value matches the one set here then it will be removed
710	 * after execution. This value defaults to true.
711	 *
712	 * @param {*} value The new value to check for when executing listeners.
713	 * @return {Object} Current instance of EventEmitter for chaining.
714	 */
715	proto.setOnceReturnValue = function setOnceReturnValue(value) {
716		this._onceReturnValue = value;
717		return this;
718	};
719
720	/**
721	 * Fetches the current value to check against when executing listeners. If
722	 * the listeners return value matches this one then it should be removed
723	 * automatically. It will return true by default.
724	 *
725	 * @return {*|Boolean} The current value to check for or the default, true.
726	 * @api private
727	 */
728	proto._getOnceReturnValue = function _getOnceReturnValue() {
729		if (this.hasOwnProperty('_onceReturnValue')) {
730			return this._onceReturnValue;
731		}
732		else {
733			return true;
734		}
735	};
736
737	/**
738	 * Fetches the events object and creates one if required.
739	 *
740	 * @return {Object} The events storage object.
741	 * @api private
742	 */
743	proto._getEvents = function _getEvents() {
744		return this._events || (this._events = {});
745	};
746
747	/**
748	 * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
749	 *
750	 * @return {Function} Non conflicting EventEmitter class.
751	 */
752	EventEmitter.noConflict = function noConflict() {
753		exports.EventEmitter = originalGlobalValue;
754		return EventEmitter;
755	};
756
757	// Expose the class either via AMD, CommonJS or the global object
758	if (typeof define === 'function' && define.amd) {
759		define('eventEmitter/EventEmitter',[],function () {
760			return EventEmitter;
761		});
762	}
763	else if (typeof module === 'object' && module.exports){
764		module.exports = EventEmitter;
765	}
766	else {
767		this.EventEmitter = EventEmitter;
768	}
769}.call(this));
770
771/*!
772 * getStyleProperty v1.0.3
773 * original by kangax
774 * http://perfectionkills.com/feature-testing-css-properties/
775 */
776
777/*jshint browser: true, strict: true, undef: true */
778/*global define: false, exports: false, module: false */
779
780( function( window ) {
781
782
783
784var prefixes = 'Webkit Moz ms Ms O'.split(' ');
785var docElemStyle = document.documentElement.style;
786
787function getStyleProperty( propName ) {
788  if ( !propName ) {
789    return;
790  }
791
792  // test standard property first
793  if ( typeof docElemStyle[ propName ] === 'string' ) {
794    return propName;
795  }
796
797  // capitalize
798  propName = propName.charAt(0).toUpperCase() + propName.slice(1);
799
800  // test vendor specific properties
801  var prefixed;
802  for ( var i=0, len = prefixes.length; i < len; i++ ) {
803    prefixed = prefixes[i] + propName;
804    if ( typeof docElemStyle[ prefixed ] === 'string' ) {
805      return prefixed;
806    }
807  }
808}
809
810// transport
811if ( typeof define === 'function' && define.amd ) {
812  // AMD
813  define( 'get-style-property/get-style-property',[],function() {
814    return getStyleProperty;
815  });
816} else if ( typeof exports === 'object' ) {
817  // CommonJS for Component
818  module.exports = getStyleProperty;
819} else {
820  // browser global
821  window.getStyleProperty = getStyleProperty;
822}
823
824})( window );
825
826/**
827 * getSize v1.1.7
828 * measure size of elements
829 */
830
831/*jshint browser: true, strict: true, undef: true, unused: true */
832/*global define: false, exports: false, require: false, module: false */
833
834( function( window, undefined ) {
835
836
837
838// -------------------------- helpers -------------------------- //
839
840var getComputedStyle = window.getComputedStyle;
841var getStyle = getComputedStyle ?
842  function( elem ) {
843    return getComputedStyle( elem, null );
844  } :
845  function( elem ) {
846    return elem.currentStyle;
847  };
848
849// get a number from a string, not a percentage
850function getStyleSize( value ) {
851  var num = parseFloat( value );
852  // not a percent like '100%', and a number
853  var isValid = value.indexOf('%') === -1 && !isNaN( num );
854  return isValid && num;
855}
856
857// -------------------------- measurements -------------------------- //
858
859var measurements = [
860  'paddingLeft',
861  'paddingRight',
862  'paddingTop',
863  'paddingBottom',
864  'marginLeft',
865  'marginRight',
866  'marginTop',
867  'marginBottom',
868  'borderLeftWidth',
869  'borderRightWidth',
870  'borderTopWidth',
871  'borderBottomWidth'
872];
873
874function getZeroSize() {
875  var size = {
876    width: 0,
877    height: 0,
878    innerWidth: 0,
879    innerHeight: 0,
880    outerWidth: 0,
881    outerHeight: 0
882  };
883  for ( var i=0, len = measurements.length; i < len; i++ ) {
884    var measurement = measurements[i];
885    size[ measurement ] = 0;
886  }
887  return size;
888}
889
890
891
892function defineGetSize( getStyleProperty ) {
893
894// -------------------------- box sizing -------------------------- //
895
896var boxSizingProp = getStyleProperty('boxSizing');
897var isBoxSizeOuter;
898
899/**
900 * WebKit measures the outer-width on style.width on border-box elems
901 * IE & Firefox measures the inner-width
902 */
903( function() {
904  if ( !boxSizingProp ) {
905    return;
906  }
907
908  var div = document.createElement('div');
909  div.style.width = '200px';
910  div.style.padding = '1px 2px 3px 4px';
911  div.style.borderStyle = 'solid';
912  div.style.borderWidth = '1px 2px 3px 4px';
913  div.style[ boxSizingProp ] = 'border-box';
914
915  var body = document.body || document.documentElement;
916  body.appendChild( div );
917  var style = getStyle( div );
918
919  isBoxSizeOuter = getStyleSize( style.width ) === 200;
920  body.removeChild( div );
921})();
922
923
924// -------------------------- getSize -------------------------- //
925
926function getSize( elem ) {
927  // use querySeletor if elem is string
928  if ( typeof elem === 'string' ) {
929    elem = document.querySelector( elem );
930  }
931
932  // do not proceed on non-objects
933  if ( !elem || typeof elem !== 'object' || !elem.nodeType ) {
934    return;
935  }
936
937  var style = getStyle( elem );
938
939  // if hidden, everything is 0
940  if ( style.display === 'none' ) {
941    return getZeroSize();
942  }
943
944  var size = {};
945  size.width = elem.offsetWidth;
946  size.height = elem.offsetHeight;
947
948  var isBorderBox = size.isBorderBox = !!( boxSizingProp &&
949    style[ boxSizingProp ] && style[ boxSizingProp ] === 'border-box' );
950
951  // get all measurements
952  for ( var i=0, len = measurements.length; i < len; i++ ) {
953    var measurement = measurements[i];
954    var value = style[ measurement ];
955    value = mungeNonPixel( elem, value );
956    var num = parseFloat( value );
957    // any 'auto', 'medium' value will be 0
958    size[ measurement ] = !isNaN( num ) ? num : 0;
959  }
960
961  var paddingWidth = size.paddingLeft + size.paddingRight;
962  var paddingHeight = size.paddingTop + size.paddingBottom;
963  var marginWidth = size.marginLeft + size.marginRight;
964  var marginHeight = size.marginTop + size.marginBottom;
965  var borderWidth = size.borderLeftWidth + size.borderRightWidth;
966  var borderHeight = size.borderTopWidth + size.borderBottomWidth;
967
968  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
969
970  // overwrite width and height if we can get it from style
971  var styleWidth = getStyleSize( style.width );
972  if ( styleWidth !== false ) {
973    size.width = styleWidth +
974      // add padding and border unless it's already including it
975      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
976  }
977
978  var styleHeight = getStyleSize( style.height );
979  if ( styleHeight !== false ) {
980    size.height = styleHeight +
981      // add padding and border unless it's already including it
982      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
983  }
984
985  size.innerWidth = size.width - ( paddingWidth + borderWidth );
986  size.innerHeight = size.height - ( paddingHeight + borderHeight );
987
988  size.outerWidth = size.width + marginWidth;
989  size.outerHeight = size.height + marginHeight;
990
991  return size;
992}
993
994// IE8 returns percent values, not pixels
995// taken from jQuery's curCSS
996function mungeNonPixel( elem, value ) {
997  // IE8 and has percent value
998  if ( getComputedStyle || value.indexOf('%') === -1 ) {
999    return value;
1000  }
1001  var style = elem.style;
1002  // Remember the original values
1003  var left = style.left;
1004  var rs = elem.runtimeStyle;
1005  var rsLeft = rs && rs.left;
1006
1007  // Put in the new values to get a computed value out
1008  if ( rsLeft ) {
1009    rs.left = elem.currentStyle.left;
1010  }
1011  style.left = value;
1012  value = style.pixelLeft;
1013
1014  // Revert the changed values
1015  style.left = left;
1016  if ( rsLeft ) {
1017    rs.left = rsLeft;
1018  }
1019
1020  return value;
1021}
1022
1023return getSize;
1024
1025}
1026
1027// transport
1028if ( typeof define === 'function' && define.amd ) {
1029  // AMD for RequireJS
1030  define( 'get-size/get-size',[ 'get-style-property/get-style-property' ], defineGetSize );
1031} else if ( typeof exports === 'object' ) {
1032  // CommonJS for Component
1033  module.exports = defineGetSize( require('get-style-property') );
1034} else {
1035  // browser global
1036  window.getSize = defineGetSize( window.getStyleProperty );
1037}
1038
1039})( window );
1040
1041/**
1042 * matchesSelector helper v1.0.1
1043 *
1044 * @name matchesSelector
1045 *   @param {Element} elem
1046 *   @param {String} selector
1047 */
1048
1049/*jshint browser: true, strict: true, undef: true, unused: true */
1050/*global define: false */
1051
1052( function( global, ElemProto ) {
1053
1054  
1055
1056  var matchesMethod = ( function() {
1057    // check un-prefixed
1058    if ( ElemProto.matchesSelector ) {
1059      return 'matchesSelector';
1060    }
1061    // check vendor prefixes
1062    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
1063
1064    for ( var i=0, len = prefixes.length; i < len; i++ ) {
1065      var prefix = prefixes[i];
1066      var method = prefix + 'MatchesSelector';
1067      if ( ElemProto[ method ] ) {
1068        return method;
1069      }
1070    }
1071  })();
1072
1073  // ----- match ----- //
1074
1075  function match( elem, selector ) {
1076    return elem[ matchesMethod ]( selector );
1077  }
1078
1079  // ----- appendToFragment ----- //
1080
1081  function checkParent( elem ) {
1082    // not needed if already has parent
1083    if ( elem.parentNode ) {
1084      return;
1085    }
1086    var fragment = document.createDocumentFragment();
1087    fragment.appendChild( elem );
1088  }
1089
1090  // ----- query ----- //
1091
1092  // fall back to using QSA
1093  // thx @jonathantneal https://gist.github.com/3062955
1094  function query( elem, selector ) {
1095    // append to fragment if no parent
1096    checkParent( elem );
1097
1098    // match elem with all selected elems of parent
1099    var elems = elem.parentNode.querySelectorAll( selector );
1100    for ( var i=0, len = elems.length; i < len; i++ ) {
1101      // return true if match
1102      if ( elems[i] === elem ) {
1103        return true;
1104      }
1105    }
1106    // otherwise return false
1107    return false;
1108  }
1109
1110  // ----- matchChild ----- //
1111
1112  function matchChild( elem, selector ) {
1113    checkParent( elem );
1114    return match( elem, selector );
1115  }
1116
1117  // ----- matchesSelector ----- //
1118
1119  var matchesSelector;
1120
1121  if ( matchesMethod ) {
1122    // IE9 supports matchesSelector, but doesn't work on orphaned elems
1123    // check for that
1124    var div = document.createElement('div');
1125    var supportsOrphans = match( div, 'div' );
1126    matchesSelector = supportsOrphans ? match : matchChild;
1127  } else {
1128    matchesSelector = query;
1129  }
1130
1131  // transport
1132  if ( typeof define === 'function' && define.amd ) {
1133    // AMD
1134    define( 'matches-selector/matches-selector',[],function() {
1135      return matchesSelector;
1136    });
1137  } else {
1138    // browser global
1139    window.matchesSelector = matchesSelector;
1140  }
1141
1142})( this, Element.prototype );
1143
1144/**
1145 * Outlayer Item
1146 */
1147
1148( function( window ) {
1149
1150
1151
1152// ----- get style ----- //
1153
1154var getComputedStyle = window.getComputedStyle;
1155var getStyle = getComputedStyle ?
1156  function( elem ) {
1157    return getComputedStyle( elem, null );
1158  } :
1159  function( elem ) {
1160    return elem.currentStyle;
1161  };
1162
1163
1164// extend objects
1165function extend( a, b ) {
1166  for ( var prop in b ) {
1167    a[ prop ] = b[ prop ];
1168  }
1169  return a;
1170}
1171
1172function isEmptyObj( obj ) {
1173  for ( var prop in obj ) {
1174    return false;
1175  }
1176  prop = null;
1177  return true;
1178}
1179
1180// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
1181function toDash( str ) {
1182  return str.replace( /([A-Z])/g, function( $1 ){
1183    return '-' + $1.toLowerCase();
1184  });
1185}
1186
1187// -------------------------- Outlayer definition -------------------------- //
1188
1189function outlayerItemDefinition( EventEmitter, getSize, getStyleProperty ) {
1190
1191// -------------------------- CSS3 support -------------------------- //
1192
1193var transitionProperty = getStyleProperty('transition');
1194var transformProperty = getStyleProperty('transform');
1195var supportsCSS3 = transitionProperty && transformProperty;
1196var is3d = !!getStyleProperty('perspective');
1197
1198var transitionEndEvent = {
1199  WebkitTransition: 'webkitTransitionEnd',
1200  MozTransition: 'transitionend',
1201  OTransition: 'otransitionend',
1202  transition: 'transitionend'
1203}[ transitionProperty ];
1204
1205// properties that could have vendor prefix
1206var prefixableProperties = [
1207  'transform',
1208  'transition',
1209  'transitionDuration',
1210  'transitionProperty'
1211];
1212
1213// cache all vendor properties
1214var vendorProperties = ( function() {
1215  var cache = {};
1216  for ( var i=0, len = prefixableProperties.length; i < len; i++ ) {
1217    var prop = prefixableProperties[i];
1218    var supportedProp = getStyleProperty( prop );
1219    if ( supportedProp && supportedProp !== prop ) {
1220      cache[ prop ] = supportedProp;
1221    }
1222  }
1223  return cache;
1224})();
1225
1226// -------------------------- Item -------------------------- //
1227
1228function Item( element, layout ) {
1229  if ( !element ) {
1230    return;
1231  }
1232
1233  this.element = element;
1234  // parent layout class, i.e. Masonry, Isotope, or Packery
1235  this.layout = layout;
1236  this.position = {
1237    x: 0,
1238    y: 0
1239  };
1240
1241  this._create();
1242}
1243
1244// inherit EventEmitter
1245extend( Item.prototype, EventEmitter.prototype );
1246
1247Item.prototype._create = function() {
1248  // transition objects
1249  this._transn = {
1250    ingProperties: {},
1251    clean: {},
1252    onEnd: {}
1253  };
1254
1255  this.css({
1256    position: 'absolute'
1257  });
1258};
1259
1260// trigger specified handler for event type
1261Item.prototype.handleEvent = function( event ) {
1262  var method = 'on' + event.type;
1263  if ( this[ method ] ) {
1264    this[ method ]( event );
1265  }
1266};
1267
1268Item.prototype.getSize = function() {
1269  this.size = getSize( this.element );
1270};
1271
1272/**
1273 * apply CSS styles to element
1274 * @param {Object} style
1275 */
1276Item.prototype.css = function( style ) {
1277  var elemStyle = this.element.style;
1278
1279  for ( var prop in style ) {
1280    // use vendor property if available
1281    var supportedProp = vendorProperties[ prop ] || prop;
1282    elemStyle[ supportedProp ] = style[ prop ];
1283  }
1284};
1285
1286 // measure position, and sets it
1287Item.prototype.getPosition = function() {
1288  var style = getStyle( this.element );
1289  var layoutOptions = this.layout.options;
1290  var isOriginLeft = layoutOptions.isOriginLeft;
1291  var isOriginTop = layoutOptions.isOriginTop;
1292  var x = parseInt( style[ isOriginLeft ? 'left' : 'right' ], 10 );
1293  var y = parseInt( style[ isOriginTop ? 'top' : 'bottom' ], 10 );
1294
1295  // clean up 'auto' or other non-integer values
1296  x = isNaN( x ) ? 0 : x;
1297  y = isNaN( y ) ? 0 : y;
1298  // remove padding from measurement
1299  var layoutSize = this.layout.size;
1300  x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
1301  y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
1302
1303  this.position.x = x;
1304  this.position.y = y;
1305};
1306
1307// set settled position, apply padding
1308Item.prototype.layoutPosition = function() {
1309  var layoutSize = this.layout.size;
1310  var layoutOptions = this.layout.options;
1311  var style = {};
1312
1313  if ( layoutOptions.isOriginLeft ) {
1314    style.left = ( this.position.x + layoutSize.paddingLeft ) + 'px';
1315    // reset other property
1316    style.right = '';
1317  } else {
1318    style.right = ( this.position.x + layoutSize.paddingRight ) + 'px';
1319    style.left = '';
1320  }
1321
1322  if ( layoutOptions.isOriginTop ) {
1323    style.top = ( this.position.y + layoutSize.paddingTop ) + 'px';
1324    style.bottom = '';
1325  } else {
1326    style.bottom = ( this.position.y + layoutSize.paddingBottom ) + 'px';
1327    style.top = '';
1328  }
1329
1330  this.css( style );
1331  this.emitEvent( 'layout', [ this ] );
1332};
1333
1334
1335// transform translate function
1336var translate = is3d ?
1337  function( x, y ) {
1338    return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
1339  } :
1340  function( x, y ) {
1341    return 'translate(' + x + 'px, ' + y + 'px)';
1342  };
1343
1344
1345Item.prototype._transitionTo = function( x, y ) {
1346  this.getPosition();
1347  // get current x & y from top/left
1348  var curX = this.position.x;
1349  var curY = this.position.y;
1350
1351  var compareX = parseInt( x, 10 );
1352  var compareY = parseInt( y, 10 );
1353  var didNotMove = compareX === this.position.x && compareY === this.position.y;
1354
1355  // save end position
1356  this.setPosition( x, y );
1357
1358  // if did not move and not transitioning, just go to layout
1359  if ( didNotMove && !this.isTransitioning ) {
1360    this.layoutPosition();
1361    return;
1362  }
1363
1364  var transX = x - curX;
1365  var transY = y - curY;
1366  var transitionStyle = {};
1367  // flip cooridinates if origin on right or bottom
1368  var layoutOptions = this.layout.options;
1369  transX = layoutOptions.isOriginLeft ? transX : -transX;
1370  transY = layoutOptions.isOriginTop ? transY : -transY;
1371  transitionStyle.transform = translate( transX, transY );
1372
1373  this.transition({
1374    to: transitionStyle,
1375    onTransitionEnd: {
1376      transform: this.layoutPosition
1377    },
1378    isCleaning: true
1379  });
1380};
1381
1382// non transition + transform support
1383Item.prototype.goTo = function( x, y ) {
1384  this.setPosition( x, y );
1385  this.layoutPosition();
1386};
1387
1388// use transition and transforms if supported
1389Item.prototype.moveTo = supportsCSS3 ?
1390  Item.prototype._transitionTo : Item.prototype.goTo;
1391
1392Item.prototype.setPosition = function( x, y ) {
1393  this.position.x = parseInt( x, 10 );
1394  this.position.y = parseInt( y, 10 );
1395};
vendor: 4,507 bytes, lines 1396-1538
1396
1397// ----- transition ----- //
1398
1399/**
1400 * @param {Object} style - CSS
1401 * @param {Function} onTransitionEnd
1402 */
1403
1404// non transition, just trigger callback
1405Item.prototype._nonTransition = function( args ) {
1406  this.css( args.to );
1407  if ( args.isCleaning ) {
1408    this._removeStyles( args.to );
1409  }
1410  for ( var prop in args.onTransitionEnd ) {
1411    args.onTransitionEnd[ prop ].call( this );
1412  }
1413};
1414
1415/**
1416 * proper transition
1417 * @param {Object} args - arguments
1418 *   @param {Object} to - style to transition to
1419 *   @param {Object} from - style to start transition from
1420 *   @param {Boolean} isCleaning - removes transition styles after transition
1421 *   @param {Function} onTransitionEnd - callback
1422 */
1423Item.prototype._transition = function( args ) {
1424  // redirect to nonTransition if no transition duration
1425  if ( !parseFloat( this.layout.options.transitionDuration ) ) {
1426    this._nonTransition( args );
1427    return;
1428  }
1429
1430  var _transition = this._transn;
1431  // keep track of onTransitionEnd callback by css property
1432  for ( var prop in args.onTransitionEnd ) {
1433    _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
1434  }
1435  // keep track of properties that are transitioning
1436  for ( prop in args.to ) {
1437    _transition.ingProperties[ prop ] = true;
1438    // keep track of properties to clean up when transition is done
1439    if ( args.isCleaning ) {
1440      _transition.clean[ prop ] = true;
1441    }
1442  }
1443
1444  // set from styles
1445  if ( args.from ) {
1446    this.css( args.from );
1447    // force redraw. http://blog.alexmaccaw.com/css-transitions
1448    var h = this.element.offsetHeight;
1449    // hack for JSHint to hush about unused var
1450    h = null;
1451  }
1452  // enable transition
1453  this.enableTransition( args.to );
1454  // set styles that are transitioning
1455  this.css( args.to );
1456
1457  this.isTransitioning = true;
1458
1459};
1460
1461var itemTransitionProperties = transformProperty && ( toDash( transformProperty ) +
1462  ',opacity' );
1463
1464Item.prototype.enableTransition = function(/* style */) {
1465  // only enable if not already transitioning
1466  // bug in IE10 were re-setting transition style will prevent
1467  // transitionend event from triggering
1468  if ( this.isTransitioning ) {
1469    return;
1470  }
1471
1472  // make transition: foo, bar, baz from style object
1473  // TODO uncomment this bit when IE10 bug is resolved
1474  // var transitionValue = [];
1475  // for ( var prop in style ) {
1476  //   // dash-ify camelCased properties like WebkitTransition
1477  //   transitionValue.push( toDash( prop ) );
1478  // }
1479  // enable transition styles
1480  // HACK always enable transform,opacity for IE10
1481  this.css({
1482    transitionProperty: itemTransitionProperties,
1483    transitionDuration: this.layout.options.transitionDuration
1484  });
1485  // listen for transition end event
1486  this.element.addEventListener( transitionEndEvent, this, false );
1487};
1488
1489Item.prototype.transition = Item.prototype[ transitionProperty ? '_transition' : '_nonTransition' ];
1490
1491// ----- events ----- //
1492
1493Item.prototype.onwebkitTransitionEnd = function( event ) {
1494  this.ontransitionend( event );
1495};
1496
1497Item.prototype.onotransitionend = function( event ) {
1498  this.ontransitionend( event );
1499};
1500
1501// properties that I munge to make my life easier
1502var dashedVendorProperties = {
1503  '-webkit-transform': 'transform',
1504  '-moz-transform': 'transform',
1505  '-o-transform': 'transform'
1506};
1507
1508Item.prototype.ontransitionend = function( event ) {
1509  // disregard bubbled events from children
1510  if ( event.target !== this.element ) {
1511    return;
1512  }
1513  var _transition = this._transn;
1514  // get property name of transitioned property, convert to prefix-free
1515  var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
1516
1517  // remove property that has completed transitioning
1518  delete _transition.ingProperties[ propertyName ];
1519  // check if any properties are still transitioning
1520  if ( isEmptyObj( _transition.ingProperties ) ) {
1521    // all properties have completed transitioning
1522    this.disableTransition();
1523  }
1524  // clean style
1525  if ( propertyName in _transition.clean ) {
1526    // clean up style
1527    this.element.style[ event.propertyName ] = '';
1528    delete _transition.clean[ propertyName ];
1529  }
1530  // trigger onTransitionEnd callback
1531  if ( propertyName in _transition.onEnd ) {
1532    var onTransitionEnd = _transition.onEnd[ propertyName ];
1533    onTransitionEnd.call( this );
1534    delete _transition.onEnd[ propertyName ];
1535  }
1536
1537  this.emitEvent( 'transitionEnd', [ this ] );
1538};
1539
1540Item.prototype.disableTransition = function() {
1541  this.removeTransitionStyles();
1542  this.element.removeEventListener( transitionEndEvent, this, false );
1543  this.isTransitioning = false;
1544};
1545
1546/**
1547 * removes style property from element
1548 * @param {Object} style
1549**/
1550Item.prototype._removeStyles = function( style ) {
1551  // clean up transition styles
1552  var cleanStyle = {};
1553  for ( var prop in style ) {
1554    cleanStyle[ prop ] = '';
1555  }
1556  this.css( cleanStyle );
1557};
1558
1559var cleanTransitionStyle = {
1560  transitionProperty: '',
1561  transitionDuration: ''
1562};
1563
1564Item.prototype.removeTransitionStyles = function() {
1565  // remove transition
1566  this.css( cleanTransitionStyle );
1567};
1568
1569// ----- show/hide/remove ----- //
1570
1571// remove element from DOM
1572Item.prototype.removeElem = function() {
1573  this.element.parentNode.removeChild( this.element );
1574  this.emitEvent( 'remove', [ this ] );
1575};
1576
1577Item.prototype.remove = function() {
1578  // just remove element if no transition support or no transition
1579  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
1580    this.removeElem();
1581    return;
1582  }
1583
1584  // start transition
1585  var _this = this;
1586  this.on( 'transitionEnd', function() {
1587    _this.removeElem();
1588    return true; // bind once
1589  });
1590  this.hide();
1591};
1592
1593Item.prototype.reveal = function() {
1594  delete this.isHidden;
1595  // remove display: none
1596  this.css({ display: '' });
1597
1598  var options = this.layout.options;
1599  this.transition({
1600    from: options.hiddenStyle,
1601    to: options.visibleStyle,
1602    isCleaning: true
1603  });
1604};
1605
1606Item.prototype.hide = function() {
1607  // set flag
1608  this.isHidden = true;
1609  // remove display: none
1610  this.css({ display: '' });
1611
1612  var options = this.layout.options;
1613  this.transition({
1614    from: options.visibleStyle,
1615    to: options.hiddenStyle,
1616    // keep hidden stuff hidden
1617    isCleaning: true,
1618    onTransitionEnd: {
1619      opacity: function() {
1620        // check if still hidden
1621        // during transition, item may have been un-hidden
1622        if ( this.isHidden ) {
1623          this.css({ display: 'none' });
1624        }
1625      }
1626    }
1627  });
1628};
1629
1630Item.prototype.destroy = function() {
1631  this.css({
1632    position: '',
1633    left: '',
1634    right: '',
1635    top: '',
1636    bottom: '',
1637    transition: '',
1638    transform: ''
1639  });
1640};
1641
1642return Item;
1643
1644}
1645
1646// -------------------------- transport -------------------------- //
1647
1648if ( typeof define === 'function' && define.amd ) {
1649  // AMD
1650  define( 'outlayer/item',[
1651      'eventEmitter/EventEmitter',
1652      'get-size/get-size',
1653      'get-style-property/get-style-property'
1654    ],
1655    outlayerItemDefinition );
1656} else {
1657  // browser global
1658  window.Outlayer = {};
1659  window.Outlayer.Item = outlayerItemDefinition(
1660    window.EventEmitter,
1661    window.getSize,
1662    window.getStyleProperty
1663  );
1664}
1665
1666})( window );
1667
1668/*!
1669 * Outlayer v1.2.0
1670 * the brains and guts of a layout library
1671 * MIT license
1672 */
1673
1674( function( window ) {
1675
1676
1677
1678// ----- vars ----- //
1679
1680var document = window.document;
1681var console = window.console;
1682var jQuery = window.jQuery;
1683
1684var noop = function() {};
1685
1686// -------------------------- helpers -------------------------- //
1687
1688// extend objects
1689function extend( a, b ) {
1690  for ( var prop in b ) {
1691    a[ prop ] = b[ prop ];
1692  }
1693  return a;
1694}
1695
1696
1697var objToString = Object.prototype.toString;
1698function isArray( obj ) {
1699  return objToString.call( obj ) === '[object Array]';
1700}
1701
1702// turn element or nodeList into an array
1703function makeArray( obj ) {
1704  var ary = [];
1705  if ( isArray( obj ) ) {
1706    // use object if already an array
1707    ary = obj;
1708  } else if ( obj && typeof obj.length === 'number' ) {
1709    // convert nodeList to array
1710    for ( var i=0, len = obj.length; i < len; i++ ) {
1711      ary.push( obj[i] );
1712    }
1713  } else {
1714    // array of single index
1715    ary.push( obj );
1716  }
1717  return ary;
1718}
1719
1720// http://stackoverflow.com/a/384380/182183
1721var isElement = ( typeof HTMLElement === 'object' ) ?
1722  function isElementDOM2( obj ) {
1723    return obj instanceof HTMLElement;
1724  }
1724 :
1725  function isElementQuirky( obj ) {
1726    return obj && typeof obj === 'object' &&
1727      obj.nodeType === 1 && typeof obj.nodeName === 'string';
1728  };
1729
1730// index of helper cause IE8
1731var indexOf = Array.prototype.indexOf ? function( ary, obj ) {
1732    return ary.indexOf( obj );
1733  } : function( ary, obj ) {
1734    for ( var i=0, len = ary.length; i < len; i++ ) {
1735      if ( ary[i] === obj ) {
1736        return i;
1737      }
1738    }
1739    return -1;
1740  };
1741
1742function removeFrom( obj, ary ) {
1743  var index = indexOf( ary, obj );
1744  if ( index !== -1 ) {
1745    ary.splice( index, 1 );
1746  }
1747}
1748
1749// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
1750function toDashed( str ) {
1751  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
1752    return $1 + '-' + $2;
1753  }).toLowerCase();
1754}
1755
1756
1757function outlayerDefinition( eventie, docReady, EventEmitter, getSize, matchesSelector, Item ) {
1758
1759// -------------------------- Outlayer -------------------------- //
1760
1761// globally unique identifiers
1762var GUID = 0;
1763// internal store of all Outlayer intances
1764var instances = {};
1765
1766
1767/**
1768 * @param {Element, String} element
1769 * @param {Object} options
1770 * @constructor
1771 */
1772function Outlayer( element, options ) {
1773  // use element as selector string
1774  if ( typeof element === 'string' ) {
1775    element = document.querySelector( element );
1776  }
1777
1778  // bail out if not proper element
1779  if ( !element || !isElement( element ) ) {
1780    if ( console ) {
1781      console.error( 'Bad ' + this.constructor.namespace + ' element: ' + element );
1782    }
1783    return;
1784  }
1785
1786  this.element = element;
1787
1788  // options
1789  this.options = extend( {}, this.constructor.defaults );
1790  this.option( options );
1791
1792  // add id for Outlayer.getFromElement
1793  var id = ++GUID;
1794  this.element.outlayerGUID = id; // expando
1795  instances[ id ] = this; // associate via id
1796
1797  // kick it off
1798  this._create();
1799
1800  if ( this.options.isInitLayout ) {
1801    this.layout();
1802  }
1803}
1804
1805// settings are for internal use only
1806Outlayer.namespace = 'outlayer';
1807Outlayer.Item = Item;
1808
1809// default options
1810Outlayer.defaults = {
1811  containerStyle: {
1812    position: 'relative'
1813  },
1814  isInitLayout: true,
1815  isOriginLeft: true,
1816  isOriginTop: true,
1817  isResizeBound: true,
1818  isResizingContainer: true,
1819  // item options
1820  transitionDuration: '0.4s',
1821  hiddenStyle: {
1822    opacity: 0,
1823    transform: 'scale(0.001)'
1824  },
1825  visibleStyle: {
1826    opacity: 1,
1827    transform: 'scale(1)'
1828  }
1829};
1830
1831// inherit EventEmitter
1832extend( Outlayer.prototype, EventEmitter.prototype );
1833
1834/**
1835 * set options
1836 * @param {Object} opts
1837 */
1838Outlayer.prototype.option = function( opts ) {
1839  extend( this.options, opts );
1840};
1841
1842Outlayer.prototype._create = function() {
1843  // get items from children
1844  this.reloadItems();
1845  // elements that affect layout, but are not laid out
1846  this.stamps = [];
1847  this.stamp( this.options.stamp );
1848  // set container style
1849  extend( this.element.style, this.options.containerStyle );
1850
1851  // bind resize method
1852  if ( this.options.isResizeBound ) {
1853    this.bindResize();
1854  }
1855};
1856
1857// goes through all children again and gets bricks in proper order
1858Outlayer.prototype.reloadItems = function() {
1859  // collection of item elements
1860  this.items = this._itemize( this.element.children );
1861};
1862
1863
1864/**
1865 * turn elements into Outlayer.Items to be used in layout
1866 * @param {Array or NodeList or HTMLElement} elems
1867 * @returns {Array} items - collection of new Outlayer Items
1868 */
1869Outlayer.prototype._itemize = function( elems ) {
1870
1871  var itemElems = this._filterFindItemElements( elems );
1872  var Item = this.constructor.Item;
1873
1874  // create new Outlayer Items for collection
1875  var items = [];
1876  for ( var i=0, len = itemElems.length; i < len; i++ ) {
1877    var elem = itemElems[i];
1878    var item = new Item( elem, this );
1879    items.push( item );
1880  }
1881
1882  return items;
1883};
1884
1885/**
1886 * get item elements to be used in layout
1887 * @param {Array or NodeList or HTMLElement} elems
1888 * @returns {Array} items - item elements
1889 */
1890Outlayer.prototype._filterFindItemElements = function( elems ) {
1891  // make array of elems
1892  elems = makeArray( elems );
1893  var itemSelector = this.options.itemSelector;
1894  var itemElems = [];
1895
1896  for ( var i=0, len = elems.length; i < len; i++ ) {
1897    var elem = elems[i];
1898    // check that elem is an actual element
1899    if ( !isElement( elem ) ) {
1900      continue;
1901    }
1902    // filter & find items if we have an item selector
1903    if ( itemSelector ) {
1904      // filter siblings
1905      if ( matchesSelector( elem, itemSelector ) ) {
1906        itemElems.push( elem );
1907      }
1908      // find children
1909      var childElems = elem.querySelectorAll( itemSelector );
1910      // concat childElems to filterFound array
1911      for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
1912        itemElems.push( childElems[j] );
1913      }
1914    } else {
1915      itemElems.push( elem );
1916    }
1917  }
1918
1919  return itemElems;
1920};
1921
1922/**
1923 * getter method for getting item elements
1924 * @returns {Array} elems - collection of item elements
1925 */
1926Outlayer.prototype.getItemElements = function() {
1927  var elems = [];
1928  for ( var i=0, len = this.items.length; i < len; i++ ) {
1929    elems.push( this.items[i].element );
1930  }
1931  return elems;
1932};
1933
1934// ----- init & layout ----- //
1935
1936/**
1937 * lays out all items
1938 */
1939Outlayer.prototype.layout = function() {
1940  this._resetLayout();
1941  this._manageStamps();
1942
1943  // don't animate first layout
1944  var isInstant = this.options.isLayoutInstant !== undefined ?
1945    this.options.isLayoutInstant : !this._isLayoutInited;
1946  this.layoutItems( this.items, isInstant );
1947
1948  // flag for initalized
1949  this._isLayoutInited = true;
1950};
1951
1952// _init is alias for layout
1953Outlayer.prototype._init = Outlayer.prototype.layout;
1954
1955/**
1956 * logic before any new layout
1957 */
1958Outlayer.prototype._resetLayout = function() {
1959  this.getSize();
1960};
1961
1962
1963Outlayer.prototype.getSize = function() {
1964  this.size = getSize( this.element );
1965};
1966
1967/**
1968 * get measurement from option, for columnWidth, rowHeight, gutter
1969 * if option is String -> get element from selector string, & get size of element
1970 * if option is Element -> get size of element
1971 * else use option as a number
1972 *
1973 * @param {String} measurement
1974 * @param {String} size - width or height
1975 * @private
1976 */
1977Outlayer.prototype._getMeasurement = function( measurement, size ) {
1978  var option = this.options[ measurement ];
1979  var elem;
1980  if ( !option ) {
1981    // default to 0
1982    this[ measurement ] = 0;
1983  } else {
1984    // use option as an element
1985    if ( typeof option === 'string' ) {
1986      elem = this.element.querySelector( option );
1987    } else if ( isElement( option ) ) {
1988      elem = option;
1989    }
1990    // use size of element, if element
1991    this[ measurement ] = elem ? getSize( elem )[ size ] : option;
1992  }
1993};
1994
1995/**
1996 * layout a collection of item elements
1997 * @api public
1998 */
1999Outlayer.prototype.layoutItems = function( items, isInstant ) {
2000  items = this._getItemsForLayout( items );
2001
2002  this._layoutItems( items, isInstant );
2003
2004  this._postLayout();
2005};
2006
2007/**
2008 * get the items to be laid out
2009 * you may want to skip over some items
2010 * @param {Array} items
2011 * @returns {Array} items
2012 */
2013Outlayer.prototype._getItemsForLayout = function( items ) {
2014  var layoutItems = [];
2015  for ( var i=0, len = items.length; i < len; i++ ) {
2016    var item = items[i];
2017    if ( !item.isIgnored ) {
2018      layoutItems.push( item );
2019    }
2020  }
2021  return layoutItems;
2022};
2023
2024/**
2025 * layout items
2026 * @param {Array} items
2027 * @param {Boolean} isInstant
2028 */
2029Outlayer.prototype._layoutItems = function( items, isInstant ) {
2030  var _this = this;
2031  function onItemsLayout() {
2032    _this.emitEvent( 'layoutComplete', [ _this, items ] );
2033  }
2034
2035  if ( !items || !items.length ) {
2036    // no items, emit event with empty array
2037    onItemsLayout();
2038    return;
2039  }
2040
2041  // emit layoutComplete when done
2042  this._itemsOn( items, 'layout', onItemsLayout );
2043
2044  var queue = [];
2045
2046  for ( var i=0, len = items.length; i < len; i++ ) {
2047    var item = items[i];
2048    // get x/y object from method
2049    var position = this._getItemLayoutPosition( item );
2050    // enqueue
2051    position.item = item;
2052    position.isInstant = isInstant || item.isLayoutInstant;
2053    queue.push( position );
2054  }
2055
2056  this._processLayoutQueue( queue );
2057};
2058
2059/**
2060 * get item layout position
2061 * @param {Outlayer.Item} item
2062 * @returns {Object} x and y position
2063 */
2064Outlayer.prototype._getItemLayoutPosition = function( /* item */ ) {
2065  return {
2066    x: 0,
2067    y: 0
2068  };
2069};
2070
2071/**
2072 * iterate over array and position each item
2073 * Reason being - separating this logic prevents 'layout invalidation'
2074 * thx @paul_irish
2075 * @param {Array} queue
2076 */
2077Outlayer.prototype._processLayoutQueue = function( queue ) {
2078  for ( var i=0, len = queue.length; i < len; i++ ) {
2079    var obj = queue[i];
2080    this._positionItem( obj.item, obj.x, obj.y, obj.isInstant );
2081  }
2082};
2083
2084/**
2085 * Sets position of item in DOM
2086 * @param {Outlayer.Item} item
2087 * @param {Number} x - horizontal position
2088 * @param {Number} y - vertical position
2089 * @param {Boolean} isInstant - disables transitions
2090 */
2091Outlayer.prototype._positionItem = function( item, x, y, isInstant ) {
2092  if ( isInstant ) {
2093    // if not transition, just set CSS
2094    item.goTo( x, y );
2095  } else {
2096    item.moveTo( x, y );
2097  }
2098};
2099
2100/**
2101 * Any logic you want to do after each layout,
2102 * i.e. size the container
2103 */
2104Outlayer.prototype._postLayout = function() {
2105  this.resizeContainer();
2106};
2107
2108Outlayer.prototype.resizeContainer = function() {
2109  if ( !this.options.isResizingContainer ) {
2110    return;
2111  }
2112  var size = this._getContainerSize();
2113  if ( size ) {
2114    this._setContainerMeasure( size.width, true );
2115    this._setContainerMeasure( size.height, false );
2116  }
2117};
2118
2119/**
2120 * Sets width or height of container if returned
2121 * @returns {Object} size
2122 *   @param {Number} width
2123 *   @param {Number} height
2124 */
2125Outlayer.prototype._getContainerSize = noop;
2126
2127/**
2128 * @param {Number} measure - size of width or height
2129 * @param {Boolean} isWidth
2130 */
2131Outlayer.prototype._setContainerMeasure = function( measure, isWidth ) {
2132  if ( measure === undefined ) {
2133    return;
2134  }
2135
2136  var elemSize = this.size;
2137  // add padding and border width if border box
2138  if ( elemSize.isBorderBox ) {
2139    measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
2140      elemSize.borderLeftWidth + elemSize.borderRightWidth :
2141      elemSize.paddingBottom + elemSize.paddingTop +
2142      elemSize.borderTopWidth + elemSize.borderBottomWidth;
2143  }
2144
2145  measure = Math.max( measure, 0 );
2146  this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
2147};
2148
2149/**
2150 * trigger a callback for a collection of items events
2151 * @param {Array} items - Outlayer.Items
2152 * @param {String} eventName
2153 * @param {Function} callback
2154 */
2155Outlayer.prototype._itemsOn = function( items, eventName, callback ) {
2156  var doneCount = 0;
2157  var count = items.length;
2158  // event callback
2159  var _this = this;
2160  function tick() {
2161    doneCount++;
2162    if ( doneCount === count ) {
2163      callback.call( _this );
2164    }
2165    return true; // bind once
2166  }
2167  // bind callback
2168  for ( var i=0, len = items.length; i < len; i++ ) {
2169    var item = items[i];
2170    item.on( eventName, tick );
2171  }
2172};
2173
2174// -------------------------- ignore & stamps -------------------------- //
2175
2176
2177/**
2178 * keep item in collection, but do not lay it out
2179 * ignored items do not get skipped in layout
2180 * @param {Element} elem
2181 */
2182Outlayer.prototype.ignore = function( elem ) {
2183  var item = this.getItem( elem );
2184  if ( item ) {
2185    item.isIgnored = true;
2186  }
2187};
2188
2189/**
2190 * return item to layout collection
2191 * @param {Element} elem
2192 */
2193Outlayer.prototype.unignore = function( elem ) {
2194  var item = this.getItem( elem );
2195  if ( item ) {
2196    delete item.isIgnored;
2197  }
2198};
2199
2200/**
2201 * adds elements to stamps
2202 * @param {NodeList, Array, Element, or String} elems
2203 */
2204Outlayer.prototype.stamp = function( elems ) {
2205  elems = this._find( elems );
2206  if ( !elems ) {
2207    return;
2208  }
2209
2210  this.stamps = this.stamps.concat( elems );
2211  // ignore
2212  for ( var i=0, len = elems.length; i < len; i++ ) {
2213    var elem = elems[i];
2214    this.ignore( elem );
2215  }
2216};
2217
2218/**
2219 * removes elements to stamps
2220 * @param {NodeList, Array, or Element} elems
2221 */
2222Outlayer.prototype.unstamp = function( elems ) {
2223  elems = this._find( elems );
2224  if ( !elems ){
2225    return;
2226  }
2227
2228  for ( var i=0, len = elems.length; i < len; i++ ) {
2229    var elem = elems[i];
2230    // filter out removed stamp elements
2231    removeFrom( elem, this.stamps );
2232    this.unignore( elem );
2233  }
2234
2235};
2236
2237/**
2238 * finds child elements
2239 * @param {NodeList, Array, Element, or String} elems
2240 * @returns {Array} elems
2241 */
2242Outlayer.prototype._find = function( elems ) {
2243  if ( !elems ) {
2244    return;
2245  }
2246  // if string, use argument as selector string
2247  if ( typeof elems === 'string' ) {
2248    elems = this.element.querySelectorAll( elems );
2249  }
2250  elems = makeArray( elems );
2251  return elems;
2252};
2253
2254Outlayer.prototype._manageStamps = function() {
2255  if ( !this.stamps || !this.stamps.length ) {
2256    return;
2257  }
2258
2259  this._getBoundingRect();
2260
2261  for ( var i=0, len = this.stamps.length; i < len; i++ ) {
2262    var stamp = this.stamps[i];
2263    this._manageStamp( stamp );
2264  }
2265};
2266
2267// update boundingLeft / Top
2268Outlayer.prototype._getBoundingRect = function() {
2269  // get bounding rect for container element
2270  var boundingRect = this.element.getBoundingClientRect();
2271  var size = this.size;
2272  this._boundingRect = {
2273    left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
2274    top: boundingRect.top + size.paddingTop + size.borderTopWidth,
2275    right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
2276    bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
2277  };
2278};
2279
2280/**
2281 * @param {Element} stamp
2282**/
2283Outlayer.prototype._manageStamp = noop;
2284
2285/**
2286 * get x/y position of element relative to container element
2287 * @param {Element} elem
2288 * @returns {Object} offset - has left, top, right, bottom
2289 */
2290Outlayer.prototype._getElementOffset = function( elem ) {
2291  var boundingRect = elem.getBoundingClientRect();
2292  var thisRect = this._boundingRect;
2293  var size = getSize( elem );
2294  var offset = {
2295    left: boundingRect.left - thisRect.left - size.marginLeft,
2296    top: boundingRect.top - thisRect.top - size.marginTop,
2297    right: thisRect.right - boundingRect.right - size.marginRight,
2298    bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
2299  };
2300  return offset;
2301};
2302
2303// -------------------------- resize -------------------------- //
2304
2305// enable event handlers for listeners
2306// i.e. resize -> onresize
2307Outlayer.prototype.handleEvent = function( event ) {
2308  var method = 'on' + event.type;
2309  if ( this[ method ] ) {
2310    this[ method ]( event );
2311  }
2312};
2313
2314/**
2315 * Bind layout to window resizing
2316 */
2317Outlayer.prototype.bindResize = function() {
2318  // bind just one listener
2319  if ( this.isResizeBound ) {
2320    return;
2321  }
2322  eventie.bind( window, 'resize', this );
2323  this.isResizeBound = true;
2324};
2325
2326/**
2327 * Unbind layout to window resizing
2328 */
2329Outlayer.prototype.unbindResize = function() {
2330  if ( this.isResizeBound ) {
2331    eventie.unbind( window, 'resize', this );
2332  }
2333  this.isResizeBound = false;
2334};
2335
2336// original debounce by John Hann
2337// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
2338
2339// this fires every resize
2340Outlayer.prototype.onresize = function() {
2341  if ( this.resizeTimeout ) {
2342    clearTimeout( this.resizeTimeout );
2343  }
2344
2345  var _this = this;
2346  function delayed() {
2347    _this.resize();
2348    delete _this.resizeTimeout;
2349  }
2350
2351  this.resizeTimeout = setTimeout( delayed, 100 );
2352};
2353
2354// debounced, layout on resize
2355Outlayer.prototype.resize = function() {
2356  // don't trigger if size did not change
2357  // or if resize was unbound. See #9
2358  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
2359    return;
2360  }
2361
2362  this.layout();
2363};
2364
2365/**
2366 * check if layout is needed post layout
2367 * @returns Boolean
2368 */
2369Outlayer.prototype.needsResizeLayout = function() {
2370  var size = getSize( this.element );
2371  // check that this.size and size are there
2372  // IE8 triggers resize on body size change, so they might not be
2373  var hasSizes = this.size && size;
2374  return hasSizes && size.innerWidth !== this.size.innerWidth;
2375};
2376
2377// -------------------------- methods -------------------------- //
2378
2379/**
2380 * add items to Outlayer instance
2381 * @param {Array or NodeList or Element} elems
2382 * @returns {Array} items - Outlayer.Items
2383**/
2384Outlayer.prototype.addItems = function( elems ) {
2385  var items = this._itemize( elems );
2386  // add items to collection
2387  if ( items.length ) {
2388    this.items = this.items.concat( items );
2389  }
2390  return items;
2391};
2392
2393/**
2394 * Layout newly-appended item elements
2395 * @param {Array or NodeList or Element} elems
2396 */
2397Outlayer.prototype.appended = function( elems ) {
2398  var items = this.addItems( elems );
2399  if ( !items.length ) {
2400    return;
2401  }
2402  // layout and reveal just the new items
2403  this.layoutItems( items, true );
2404  this.reveal( items );
2405};
2406
2407/**
2408 * Layout prepended elements
2409 * @param {Array or NodeList or Element} elems
2410 */
2411Outlayer.prototype.prepended = function( elems ) {
2412  var items = this._itemize( elems );
2413  if ( !items.length ) {
2414    return;
2415  }
2416  // add items to beginning of collection
2417  var previousItems = this.items.slice(0);
2418  this.items = items.concat( previousItems );
2419  // start new layout
2420  this._resetLayout();
2421  this._manageStamps();
2422  // layout new stuff without transition
2423  this.layoutItems( items, true );
2424  this.reveal( items );
2425  // layout previous items
2426  this.layoutItems( previousItems );
2427};
2428
2429/**
2430 * reveal a collection of items
2431 * @param {Array of Outlayer.Items} items
2432 */
2433Outlayer.prototype.reveal = function( items ) {
2434  var len = items && items.length;
2435  if ( !len ) {
2436    return;
2437  }
2438  for ( var i=0; i < len; i++ ) {
2439    var item = items[i];
2440    item.reveal();
2441  }
2442};
2443
2444/**
2445 * hide a collection of items
2446 * @param {Array of Outlayer.Items} items
2447 */
2448Outlayer.prototype.hide = function( items ) {
2449  var len = items && items.length;
2450  if ( !len ) {
2451    return;
2452  }
2453  for ( var i=0; i < len; i++ ) {
2454    var item = items[i];
2455    item.hide();
2456  }
2457};
2458
2459/**
2460 * get Outlayer.Item, given an Element
2461 * @param {Element} elem
2462 * @param {Function} callback
2463 * @returns {Outlayer.Item} item
2464 */
2465Outlayer.prototype.getItem = function( elem ) {
2466  // loop through items to get the one that matches
2467  for ( var i=0, len = this.items.length; i < len; i++ ) {
2468    var item = this.items[i];
2469    if ( item.element === elem ) {
2470      // return item
2471      return item;
2472    }
2473  }
2474};
2475
2476/**
2477 * get collection of Outlayer.Items, given Elements
2478 * @param {Array} elems
2479 * @returns {Array} items - Outlayer.Items
2480 */
2481Outlayer.prototype.getItems = function( elems ) {
2482  if ( !elems || !elems.length ) {
2483    return;
2484  }
2485  var items = [];
2486  for ( var i=0, len = elems.length; i < len; i++ ) {
2487    var elem = elems[i];
2488    var item = this.getItem( elem );
2489    if ( item ) {
2490      items.push( item );
2491    }
2492  }
2493
2494  return items;
2495};
2496
2497/**
2498 * remove element(s) from instance and DOM
2499 * @param {Array or NodeList or Element} elems
2500 */
2501Outlayer.prototype.remove = function( elems ) {
2502  elems = makeArray( elems );
2503
2504  var removeItems = this.getItems( elems );
2505  // bail if no items to remove
2506  if ( !removeItems || !removeItems.length ) {
2507    return;
2508  }
2509
2510  this._itemsOn( removeItems, 'remove', function() {
2511    this.emitEvent( 'removeComplete', [ this, removeItems ] );
2512  });
2513
2514  for ( var i=0, len = removeItems.length; i < len; i++ ) {
2515    var item = removeItems[i];
2516    item.remove();
2517    // remove item from collection
2518    removeFrom( item, this.items );
2519  }
2520};
2521
2522// ----- destroy ----- //
2523
2524// remove and disable Outlayer instance
2525Outlayer.prototype.destroy = function() {
2526  // clean up dynamic styles
2527  var style = this.element.style;
2528  style.height = '';
2529  style.position = '';
2530  style.width = '';
2531  // destroy items
2532  for ( var i=0, len = this.items.length; i < len; i++ ) {
2533    var item = this.items[i];
2534    item.destroy();
2535  }
2536
2537  this.unbindResize();
2538
2539  delete this.element.outlayerGUID;
2540  // remove data for jQuery
2541  if ( jQuery ) {
2542    jQuery.removeData( this.element, this.constructor.namespace );
2543  }
2544
2545};
2546
2547// -------------------------- data -------------------------- //
2548
2549/**
2550 * get Outlayer instance from element
2551 * @param {Element} elem
2552 * @returns {Outlayer}
2553 */
2554Outlayer.data = function( elem ) {
2555  var id = elem && elem.outlayerGUID;
2556  return id && instances[ id ];
2557};
2558
2559
2560// -------------------------- create Outlayer class -------------------------- //
2561
2562/**
2563 * create a layout class
2564 * @param {String} namespace
2565 */
2566Outlayer.create = function( namespace, options ) {
2567  // sub-class Outlayer
2568  function Layout() {
2569    Outlayer.apply( this, arguments );
2570  }
2571  // inherit Outlayer prototype, use Object.create if there
2572  if ( Object.create ) {
2573    Layout.prototype = Object.create( Outlayer.prototype );
2574  } else {
2575    extend( Layout.prototype, Outlayer.prototype );
2576  }
2577  // set contructor, used for namespace and Item
2578  Layout.prototype.constructor = Layout;
2579
2580  Layout.defaults = extend( {}, Outlayer.defaults );
2581  // apply new options
2582  extend( Layout.defaults, options );
2583  // keep prototype.settings for backwards compatibility (Packery v1.2.0)
2584  Layout.prototype.settings = {};
2585
2586  Layout.namespace = namespace;
2587
2588  Layout.data = Outlayer.data;
2589
2590  // sub-class Item
2591  Layout.Item = function LayoutItem() {
2592    Item.apply( this, arguments );
2593  };
2594
2595  Layout.Item.prototype = new Item();
2596
2597  // -------------------------- declarative -------------------------- //
2598
2599  /**
2600   * allow user to initialize Outlayer via .js-namespace class
2601   * options are parsed from data-namespace-option attribute
2602   */
2603  docReady( function() {
2604    var dashedNamespace = toDashed( namespace );
2605    var elems = document.querySelectorAll( '.js-' + dashedNamespace );
2606    var dataAttr = 'data-' + dashedNamespace + '-options';
2607
2608    for ( var i=0, len = elems.length; i < len; i++ ) {
2609      var elem = elems[i];
2610      var attr = elem.getAttribute( dataAttr );
2611      var options;
2612      try {
2613        options = attr && JSON.parse( attr );
2614      } catch ( error ) {
2615        // log error, do not initialize
2616        if ( console ) {
2617          console.error( 'Error parsing ' + dataAttr + ' on ' +
2618            elem.nodeName.toLowerCase() + ( elem.id ? '#' + elem.id : '' ) + ': ' +
2619            error );
2620        }
2621        continue;
2622      }
2623      // initialize
2624      var instance = new Layout( elem, options );
2625      // make available via $().data('layoutname')
2626      if ( jQuery ) {
2627        jQuery.data( elem, namespace, instance );
2628      }
2629    }
2630  });
2631
2632  // -------------------------- jQuery bridge -------------------------- //
2633
2634  // make into jQuery plugin
2635  if ( jQuery && jQuery.bridget ) {
2636    jQuery.bridget( namespace, Layout );
2637  }
2638
2639  return Layout;
2640};
2641
2642// ----- fin ----- //
2643
2644// back in global
2645Outlayer.Item = Item;
2646
2647return Outlayer;
2648
2649}
2650
2651// -------------------------- transport -------------------------- //
2652
2653if ( typeof define === 'function' && define.amd ) {
2654  // AMD
2655  define( 'outlayer/outlayer',[
2656      'eventie/eventie',
2657      'doc-ready/doc-ready',
2658      'eventEmitter/EventEmitter',
2659      'get-size/get-size',
2660      'matches-selector/matches-selector',
2661      './item'
2662    ],
2663    outlayerDefinition );
2664} else {
2665  // browser global
2666  window.Outlayer = outlayerDefinition(
2667    window.eventie,
2668    window.docReady,
2669    window.EventEmitter,
2670    window.getSize,
2671    window.matchesSelector,
2672    window.Outlayer.Item
2673  );
2674}
2675
2676})( window );
2677
2678/**
2679 * Isotope Item
2680**/
2681
2682( function( window ) {
2683
2684
2685
2686// -------------------------- Item -------------------------- //
2687
2688function itemDefinition( Outlayer ) {
2689
2690// sub-class Outlayer Item
2691function Item() {
2692  Outlayer.Item.apply( this, arguments );
2693}
2694
2695Item.prototype = new Outlayer.Item();
2696
2697Item.prototype._create = function() {
2698  // assign id, used for original-order sorting
2699  this.id = this.layout.itemGUID++;
2700  Outlayer.Item.prototype._create.call( this );
2701  this.sortData = {};
2702};
2703
2704Item.prototype.updateSortData = function() {
2705  if ( this.isIgnored ) {
2706    return;
2707  }
2708  // default sorters
2709  this.sortData.id = this.id;
2710  // for backward compatibility
2711  this.sortData['original-order'] = this.id;
2712  this.sortData.random = Math.random();
2713  // go thru getSortData obj and apply the sorters
2714  var getSortData = this.layout.options.getSortData;
2715  var sorters = this.layout._sorters;
2716  for ( var key in getSortData ) {
2717    var sorter = sorters[ key ];
2718    this.sortData[ key ] = sorter( this.element, this );
2719  }
2720};
2721
2722var _destroy = Item.prototype.destroy;
2723Item.prototype.destroy = function() {
2724  // call super
2725  _destroy.apply( this, arguments );
2726  // reset display, #741
2727  this.css({
2728    display: ''
2729  });
2730};
2731
2732return Item;
2733
2734}
2735
2736// -------------------------- transport -------------------------- //
2737
2738if ( typeof define === 'function' && define.amd ) {
2739  // AMD
2740  define( 'isotope/js/item',[
2741      'outlayer/outlayer'
2742    ],
2743    itemDefinition );
2744} else {
2745  // browser global
2746  window.Isotope = window.Isotope || {};
2747  window.Isotope.Item = itemDefinition(
2748    window.Outlayer
2749  );
2750}
2751
2752})( window );
2753
2754( function( window ) {
2755
2756
2757
2758// --------------------------  -------------------------- //
2759
2760function layoutModeDefinition( getSize, Outlayer ) {
2761
2762  // layout mode class
2763  function LayoutMode( isotope ) {
2764    this.isotope = isotope;
2765    // link properties
2766    if ( isotope ) {
2767      this.options = isotope.options[ this.namespace ];
2768      this.element = isotope.element;
2769      this.items = isotope.filteredItems;
2770      this.size = isotope.size;
2771    }
2772  }
2773
2774  /**
2775   * some methods should just defer to default Outlayer method
2776   * and reference the Isotope instance as `this`
2777  **/
2778  ( function() {
2779    var facadeMethods = [
2780      '_resetLayout',
2781      '_getItemLayoutPosition',
2782      '_manageStamp',
2783      '_getContainerSize',
2784      '_getElementOffset',
2785      'needsResizeLayout'
2786    ];
2787
2788    for ( var i=0, len = facadeMethods.length; i < len; i++ ) {
2789      var methodName = facadeMethods[i];
2790      LayoutMode.prototype[ methodName ] = getOutlayerMethod( methodName );
2791    }
2792
2793    function getOutlayerMethod( methodName ) {
2794      return function() {
2795        return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
2796      };
2797    }
2798  })();
vendor: 9,866 bytes, lines 2799-3141
2799
2800  // -----  ----- //
2801
2802  // for horizontal layout modes, check vertical size
2803  LayoutMode.prototype.needsVerticalResizeLayout = function() {
2804    // don't trigger if size did not change
2805    var size = getSize( this.isotope.element );
2806    // check that this.size and size are there
2807    // IE8 triggers resize on body size change, so they might not be
2808    var hasSizes = this.isotope.size && size;
2809    return hasSizes && size.innerHeight !== this.isotope.size.innerHeight;
2810  };
2811
2812  // ----- measurements ----- //
2813
2814  LayoutMode.prototype._getMeasurement = function() {
2815    this.isotope._getMeasurement.apply( this, arguments );
2816  };
2817
2818  LayoutMode.prototype.getColumnWidth = function() {
2819    this.getSegmentSize( 'column', 'Width' );
2820  };
2821
2822  LayoutMode.prototype.getRowHeight = function() {
2823    this.getSegmentSize( 'row', 'Height' );
2824  };
2825
2826  /**
2827   * get columnWidth or rowHeight
2828   * segment: 'column' or 'row'
2829   * size 'Width' or 'Height'
2830  **/
2831  LayoutMode.prototype.getSegmentSize = function( segment, size ) {
2832    var segmentName = segment + size;
2833    var outerSize = 'outer' + size;
2834    // columnWidth / outerWidth // rowHeight / outerHeight
2835    this._getMeasurement( segmentName, outerSize );
2836    // got rowHeight or columnWidth, we can chill
2837    if ( this[ segmentName ] ) {
2838      return;
2839    }
2840    // fall back to item of first element
2841    var firstItemSize = this.getFirstItemSize();
2842    this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
2843      // or size of container
2844      this.isotope.size[ 'inner' + size ];
2845  };
2846
2847  LayoutMode.prototype.getFirstItemSize = function() {
2848    var firstItem = this.isotope.filteredItems[0];
2849    return firstItem && firstItem.element && getSize( firstItem.element );
2850  };
2851
2852  // ----- methods that should reference isotope ----- //
2853
2854  LayoutMode.prototype.layout = function() {
2855    this.isotope.layout.apply( this.isotope, arguments );
2856  };
2857
2858  LayoutMode.prototype.getSize = function() {
2859    this.isotope.getSize();
2860    this.size = this.isotope.size;
2861  };
2862
2863  // -------------------------- create -------------------------- //
2864
2865  LayoutMode.modes = {};
2866
2867  LayoutMode.create = function( namespace, options ) {
2868
2869    function Mode() {
2870      LayoutMode.apply( this, arguments );
2871    }
2872
2873    Mode.prototype = new LayoutMode();
2874
2875    // default options
2876    if ( options ) {
2877      Mode.options = options;
2878    }
2879
2880    Mode.prototype.namespace = namespace;
2881    // register in Isotope
2882    LayoutMode.modes[ namespace ] = Mode;
2883
2884    return Mode;
2885  };
2886
2887
2888  return LayoutMode;
2889
2890}
2891
2892if ( typeof define === 'function' && define.amd ) {
2893  // AMD
2894  define( 'isotope/js/layout-mode',[
2895      'get-size/get-size',
2896      'outlayer/outlayer'
2897    ],
2898    layoutModeDefinition );
2899} else {
2900  // browser global
2901  window.Isotope = window.Isotope || {};
2902  window.Isotope.LayoutMode = layoutModeDefinition(
2903    window.getSize,
2904    window.Outlayer
2905  );
2906}
2907
2908
2909})( window );
2910
2911/*!
2912 * Masonry v3.1.5
2913 * Cascading grid layout library
2914 * http://masonry.desandro.com
2915 * MIT License
2916 * by David DeSandro
2917 */
2918
2919( function( window ) {
2920
2921
2922
2923// -------------------------- helpers -------------------------- //
2924
2925var indexOf = Array.prototype.indexOf ?
2926  function( items, value ) {
2927    return items.indexOf( value );
2928  } :
2929  function ( items, value ) {
2930    for ( var i=0, len = items.length; i < len; i++ ) {
2931      var item = items[i];
2932      if ( item === value ) {
2933        return i;
2934      }
2935    }
2936    return -1;
2937  };
2938
2939// -------------------------- masonryDefinition -------------------------- //
2940
2941// used for AMD definition and requires
2942function masonryDefinition( Outlayer, getSize ) {
2943  // create an Outlayer layout class
2944  var Masonry = Outlayer.create('masonry');
2945
2946  Masonry.prototype._resetLayout = function() {
2947    this.getSize();
2948    this._getMeasurement( 'columnWidth', 'outerWidth' );
2949    this._getMeasurement( 'gutter', 'outerWidth' );
2950    this.measureColumns();
2951
2952    // reset column Y
2953    var i = this.cols;
2954    this.colYs = [];
2955    while (i--) {
2956      this.colYs.push( 0 );
2957    }
2958
2959    this.maxY = 0;
2960  };
2961
2962  Masonry.prototype.measureColumns = function() {
2963    this.getContainerWidth();
2964    // if columnWidth is 0, default to outerWidth of first item
2965    if ( !this.columnWidth ) {
2966      var firstItem = this.items[0];
2967      var firstItemElem = firstItem && firstItem.element;
2968      // columnWidth fall back to item of first element
2969      this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
2970        // if first elem has no width, default to size of container
2971        this.containerWidth;
2972    }
2973
2974    this.columnWidth += this.gutter;
2975
2976    this.cols = Math.floor( ( this.containerWidth + this.gutter ) / this.columnWidth );
2977    this.cols = Math.max( this.cols, 1 );
2978  };
2979
2980  Masonry.prototype.getContainerWidth = function() {
2981    // container is parent if fit width
2982    var container = this.options.isFitWidth ? this.element.parentNode : this.element;
2983    // check that this.size and size are there
2984    // IE8 triggers resize on body size change, so they might not be
2985    var size = getSize( container );
2986    this.containerWidth = size && size.innerWidth;
2987  };
2988
2989  Masonry.prototype._getItemLayoutPosition = function( item ) {
2990    item.getSize();
2991    // how many columns does this brick span
2992    var remainder = item.size.outerWidth % this.columnWidth;
2993    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
2994    // round if off by 1 pixel, otherwise use ceil
2995    var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
2996    colSpan = Math.min( colSpan, this.cols );
2997
2998    var colGroup = this._getColGroup( colSpan );
2999    // get the minimum Y value from the columns
3000    var minimumY = Math.min.apply( Math, colGroup );
3001    var shortColIndex = indexOf( colGroup, minimumY );
3002
3003    // position the brick
3004    var position = {
3005      x: this.columnWidth * shortColIndex,
3006      y: minimumY
3007    };
3008
3009    // apply setHeight to necessary columns
3010    var setHeight = minimumY + item.size.outerHeight;
3011    var setSpan = this.cols + 1 - colGroup.length;
3012    for ( var i = 0; i < setSpan; i++ ) {
3013      this.colYs[ shortColIndex + i ] = setHeight;
3014    }
3015
3016    return position;
3017  };
3018
3019  /**
3020   * @param {Number} colSpan - number of columns the element spans
3021   * @returns {Array} colGroup
3022   */
3023  Masonry.prototype._getColGroup = function( colSpan ) {
3024    if ( colSpan < 2 ) {
3025      // if brick spans only one column, use all the column Ys
3026      return this.colYs;
3027    }
3028
3029    var colGroup = [];
3030    // how many different places could this brick fit horizontally
3031    var groupCount = this.cols + 1 - colSpan;
3032    // for each group potential horizontal position
3033    for ( var i = 0; i < groupCount; i++ ) {
3034      // make an array of colY values for that one group
3035      var groupColYs = this.colYs.slice( i, i + colSpan );
3036      // and get the max value of the array
3037      colGroup[i] = Math.max.apply( Math, groupColYs );
3038    }
3039    return colGroup;
3040  };
3041
3042  Masonry.prototype._manageStamp = function( stamp ) {
3043    var stampSize = getSize( stamp );
3044    var offset = this._getElementOffset( stamp );
3045    // get the columns that this stamp affects
3046    var firstX = this.options.isOriginLeft ? offset.left : offset.right;
3047    var lastX = firstX + stampSize.outerWidth;
3048    var firstCol = Math.floor( firstX / this.columnWidth );
3049    firstCol = Math.max( 0, firstCol );
3050    var lastCol = Math.floor( lastX / this.columnWidth );
3051    // lastCol should not go over if multiple of columnWidth #425
3052    lastCol -= lastX % this.columnWidth ? 0 : 1;
3053    lastCol = Math.min( this.cols - 1, lastCol );
3054    // set colYs to bottom of the stamp
3055    var stampMaxY = ( this.options.isOriginTop ? offset.top : offset.bottom ) +
3056      stampSize.outerHeight;
3057    for ( var i = firstCol; i <= lastCol; i++ ) {
3058      this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
3059    }
3060  };
3061
3062  Masonry.prototype._getContainerSize = function() {
3063    this.maxY = Math.max.apply( Math, this.colYs );
3064    var size = {
3065      height: this.maxY
3066    };
3067
3068    if ( this.options.isFitWidth ) {
3069      size.width = this._getContainerFitWidth();
3070    }
3071
3072    return size;
3073  };
3074
3075  Masonry.prototype._getContainerFitWidth = function() {
3076    var unusedCols = 0;
3077    // count unused columns
3078    var i = this.cols;
3079    while ( --i ) {
3080      if ( this.colYs[i] !== 0 ) {
3081        break;
3082      }
3083      unusedCols++;
3084    }
3085    // fit container to columns that have been used
3086    return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
3087  };
3088
3089  Masonry.prototype.needsResizeLayout = function() {
3090    var previousWidth = this.containerWidth;
3091    this.getContainerWidth();
3092    return previousWidth !== this.containerWidth;
3093  };
3094
3095  return Masonry;
3096}
3097
3098// -------------------------- transport -------------------------- //
3099
3100if ( typeof define === 'function' && define.amd ) {
3101  // AMD
3102  define( 'masonry/masonry',[
3103      'outlayer/outlayer',
3104      'get-size/get-size'
3105    ],
3106    masonryDefinition );
3107} else {
3108  // browser global
3109  window.Masonry = masonryDefinition(
3110    window.Outlayer,
3111    window.getSize
3112  );
3113}
3114
3115})( window );
3116
3117/*!
3118 * Masonry layout mode
3119 * sub-classes Masonry
3120 * http://masonry.desandro.com
3121 */
3122
3123( function( window ) {
3124
3125
3126
3127// -------------------------- helpers -------------------------- //
3128
3129// extend objects
3130function extend( a, b ) {
3131  for ( var prop in b ) {
3132    a[ prop ] = b[ prop ];
3133  }
3134  return a;
3135}
3136
3137// -------------------------- masonryDefinition -------------------------- //
3138
3139// used for AMD definition and requires
3140function masonryDefinition( LayoutMode, Masonry ) {
3141  // create an Outlayer layout class
3142  var MasonryMode = LayoutMode.create('masonry');
3143
3144  // save on to these methods
3145  var _getElementOffset = MasonryMode.prototype._getElementOffset;
3146  var layout = MasonryMode.prototype.layout;
3147  var _getMeasurement = MasonryMode.prototype._getMeasurement;
3148
3149  // sub-class Masonry
3150  extend( MasonryMode.prototype, Masonry.prototype );
3151
3152  // set back, as it was overwritten by Masonry
3153  MasonryMode.prototype._getElementOffset = _getElementOffset;
3154  MasonryMode.prototype.layout = layout;
3155  MasonryMode.prototype._getMeasurement = _getMeasurement;
3156
3157  var measureColumns = MasonryMode.prototype.measureColumns;
3158  MasonryMode.prototype.measureColumns = function() {
3159    // set items, used if measuring first item
3160    this.items = this.isotope.filteredItems;
3161    measureColumns.call( this );
3162  };
3163
3164  // HACK copy over isOriginLeft/Top options
3165  var _manageStamp = MasonryMode.prototype._manageStamp;
3166  MasonryMode.prototype._manageStamp = function() {
3167    this.options.isOriginLeft = this.isotope.options.isOriginLeft;
3168    this.options.isOriginTop = this.isotope.options.isOriginTop;
3169    _manageStamp.apply( this, arguments );
3170  };
3171
3172  return MasonryMode;
3173}
3174
3175// -------------------------- transport -------------------------- //
3176
3177if ( typeof define === 'function' && define.amd ) {
3178  // AMD
3179  define( 'isotope/js/layout-modes/masonry',[
3180      '../layout-mode',
3181      'masonry/masonry'
3182    ],
3183    masonryDefinition );
3184} else {
3185  // browser global
3186  masonryDefinition(
3187    window.Isotope.LayoutMode,
3188    window.Masonry
3189  );
3190}
3191
3192})( window );
3193
3194( function( window ) {
3195
3196
3197
3198function fitRowsDefinition( LayoutMode ) {
3199
3200var FitRows = LayoutMode.create('fitRows');
3201
3202FitRows.prototype._resetLayout = function() {
3203  this.x = 0;
3204  this.y = 0;
3205  this.maxY = 0;
3206};
3207
3208FitRows.prototype._getItemLayoutPosition = function( item ) {
3209  item.getSize();
3210
3211  // if this element cannot fit in the current row
3212  if ( this.x !== 0 && item.size.outerWidth + this.x > this.isotope.size.innerWidth ) {
3213    this.x = 0;
3214    this.y = this.maxY;
3215  }
3216
3217  var position = {
3218    x: this.x,
3219    y: this.y
3220  };
3221
3222  this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
3223  this.x += item.size.outerWidth;
3224
3225  return position;
3226};
3227
3228FitRows.prototype._getContainerSize = function() {
3229  return { height: this.maxY };
3230};
3231
3232return FitRows;
3233
3234}
3235
3236if ( typeof define === 'function' && define.amd ) {
3237  // AMD
3238  define( 'isotope/js/layout-modes/fit-rows',[
3239      '../layout-mode'
3240    ],
3241    fitRowsDefinition );
3242} else {
3243  // browser global
3244  fitRowsDefinition(
3245    window.Isotope.LayoutMode
3246  );
3247}
3248
3249})( window );
3250
3251( function( window ) {
3252
3253
3254
3255function verticalDefinition( LayoutMode ) {
3256
3257var Vertical = LayoutMode.create( 'vertical', {
3258  horizontalAlignment: 0
3259});
3260
3261Vertical.prototype._resetLayout = function() {
3262  this.y = 0;
3263};
3264
3265Vertical.prototype._getItemLayoutPosition = function( item ) {
3266  item.getSize();
3267  var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *
3268    this.options.horizontalAlignment;
3269  var y = this.y;
3270  this.y += item.size.outerHeight;
3271  return { x: x, y: y };
3272};
3273
3274Vertical.prototype._getContainerSize = function() {
3275  return { height: this.y };
3276};
3277
3278return Vertical;
3279
3280}
3281
3282if ( typeof define === 'function' && define.amd ) {
3283  // AMD
3284  define( 'isotope/js/layout-modes/vertical',[
3285      '../layout-mode'
3286    ],
3287    verticalDefinition );
3288} else {
3289  // browser global
3290  verticalDefinition(
3291    window.Isotope.LayoutMode
3292  );
3293}
3294
3295})( window );
3296
3297/*!
3298 * Isotope v2.0.1
3299 * Filter & sort magical layouts
3300 * http://isotope.metafizzy.co
3301 */
3302
3303( function( window ) {
3304
3305
3306
3307// -------------------------- vars -------------------------- //
3308
3309var jQuery = window.jQuery;
3310
3311// -------------------------- helpers -------------------------- //
3312
3313// extend objects
3314function extend( a, b ) {
3315  for ( var prop in b ) {
3316    a[ prop ] = b[ prop ];
3317  }
3318  return a;
3319}
3320
3321var trim = String.prototype.trim ?
3322  function( str ) {
3323    return str.trim();
3324  } :
3325  function( str ) {
3326    return str.replace( /^\s+|\s+$/g, '' );
3327  };
3328
3329var docElem = document.documentElement;
3330
3331var getText = docElem.textContent ?
3332  function( elem ) {
3333    return elem.textContent;
3334  }
3334 :
3335  function( elem ) {
3336    return elem.innerText;
3337  };
3338
3339var objToString = Object.prototype.toString;
3340function isArray( obj ) {
3341  return objToString.call( obj ) === '[object Array]';
3342}
3343
3344// index of helper cause IE8
3345var indexOf = Array.prototype.indexOf ? function( ary, obj ) {
3346    return ary.indexOf( obj );
3347  } : function( ary, obj ) {
3348    for ( var i=0, len = ary.length; i < len; i++ ) {
3349      if ( ary[i] === obj ) {
3350        return i;
3351      }
3352    }
3353    return -1;
3354  };
3355
3356// turn element or nodeList into an array
3357function makeArray( obj ) {
3358  var ary = [];
3359  if ( isArray( obj ) ) {
3360    // use object if already an array
3361    ary = obj;
3362  } else if ( obj && typeof obj.length === 'number' ) {
3363    // convert nodeList to array
3364    for ( var i=0, len = obj.length; i < len; i++ ) {
3365      ary.push( obj[i] );
3366    }
3367  } else {
3368    // array of single index
3369    ary.push( obj );
3370  }
3371  return ary;
3372}
3373
3374function removeFrom( obj, ary ) {
3375  var index = indexOf( ary, obj );
3376  if ( index !== -1 ) {
3377    ary.splice( index, 1 );
3378  }
3379}
3380
3381// -------------------------- isotopeDefinition -------------------------- //
3382
3383// used for AMD definition and requires
3384function isotopeDefinition( Outlayer, getSize, matchesSelector, Item, LayoutMode ) {
3385  // create an Outlayer layout class
3386  var Isotope = Outlayer.create( 'isotope', {
3387    layoutMode: "masonry",
3388    isJQueryFiltering: true,
3389    sortAscending: true
3390  });
3391
3392  Isotope.Item = Item;
3393  Isotope.LayoutMode = LayoutMode;
3394
3395  Isotope.prototype._create = function() {
3396    this.itemGUID = 0;
3397    // functions that sort items
3398    this._sorters = {};
3399    this._getSorters();
3400    // call super
3401    Outlayer.prototype._create.call( this );
3402
3403    // create layout modes
3404    this.modes = {};
3405    // start filteredItems with all items
3406    this.filteredItems = this.items;
3407    // keep of track of sortBys
3408    this.sortHistory = [ 'original-order' ];
3409    // create from registered layout modes
3410    for ( var name in LayoutMode.modes ) {
3411      this._initLayoutMode( name );
3412    }
3413  };
3414
3415  Isotope.prototype.reloadItems = function() {
3416    // reset item ID counter
3417    this.itemGUID = 0;
3418    // call super
3419    Outlayer.prototype.reloadItems.call( this );
3420  };
3421
3422  Isotope.prototype._itemize = function() {
3423    var items = Outlayer.prototype._itemize.apply( this, arguments );
3424    // assign ID for original-order
3425    for ( var i=0, len = items.length; i < len; i++ ) {
3426      var item = items[i];
3427      item.id = this.itemGUID++;
3428    }
3429    this._updateItemsSortData( items );
3430    return items;
3431  };
3432
3433
3434  // -------------------------- layout -------------------------- //
3435
3436  Isotope.prototype._initLayoutMode = function( name ) {
3437    var Mode = LayoutMode.modes[ name ];
3438    // set mode options
3439    // HACK extend initial options, back-fill in default options
3440    var initialOpts = this.options[ name ] || {};
3441    this.options[ name ] = Mode.options ?
3442      extend( Mode.options, initialOpts ) : initialOpts;
3443    // init layout mode instance
3444    this.modes[ name ] = new Mode( this );
3445  };
3446
3447
3448  Isotope.prototype.layout = function() {
3449    // if first time doing layout, do all magic
3450    if ( !this._isLayoutInited && this.options.isInitLayout ) {
3451      this.arrange();
3452      return;
3453    }
3454    this._layout();
3455  };
3456
3457  // private method to be used in layout() & magic()
3458  Isotope.prototype._layout = function() {
3459    // don't animate first layout
3460    var isInstant = this._getIsInstant();
3461    // layout flow
3462    this._resetLayout();
3463    this._manageStamps();
3464    this.layoutItems( this.filteredItems, isInstant );
3465
3466    // flag for initalized
3467    this._isLayoutInited = true;
3468  };
3469
3470  // filter + sort + layout
3471  Isotope.prototype.arrange = function( opts ) {
3472    // set any options pass
3473    this.option( opts );
3474    this._getIsInstant();
3475    // filter, sort, and layout
3476    this.filteredItems = this._filter( this.items );
3477    this._sort();
3478    this._layout();
3479  };
3480  // alias to _init for main plugin method
3481  Isotope.prototype._init = Isotope.prototype.arrange;
3482
3483  // HACK
3484  // Don't animate/transition first layout
3485  // Or don't animate/transition other layouts
3486  Isotope.prototype._getIsInstant = function() {
3487    var isInstant = this.options.isLayoutInstant !== undefined ?
3488      this.options.isLayoutInstant : !this._isLayoutInited;
3489    this._isInstant = isInstant;
3490    return isInstant;
3491  };
3492
3493  // -------------------------- filter -------------------------- //
3494
3495  Isotope.prototype._filter = function( items ) {
3496    var filter = this.options.filter;
3497    filter = filter || '*';
3498    var matches = [];
3499    var hiddenMatched = [];
3500    var visibleUnmatched = [];
3501
3502    var test = this._getFilterTest( filter );
3503
3504    // test each item
3505    for ( var i=0, len = items.length; i < len; i++ ) {
3506      var item = items[i];
3507      if ( item.isIgnored ) {
3508        continue;
3509      }
3510      // add item to either matched or unmatched group
3511      var isMatched = test( item );
3512      // item.isFilterMatched = isMatched;
3513      // add to matches if its a match
3514      if ( isMatched ) {
3515        matches.push( item );
3516      }
3517      // add to additional group if item needs to be hidden or revealed
3518      if ( isMatched && item.isHidden ) {
3519        hiddenMatched.push( item );
3520      } else if ( !isMatched && !item.isHidden ) {
3521        visibleUnmatched.push( item );
3522      }
3523    }
3524
3525    var _this = this;
3526    function hideReveal() {
3527      _this.reveal( hiddenMatched );
3528      _this.hide( visibleUnmatched );
3529    }
3530
3531    if ( this._isInstant ) {
3532      this._noTransition( hideReveal );
3533    } else {
3534      hideReveal();
3535    }
3536
3537    return matches;
3538  };
3539
3540  // get a jQuery, function, or a matchesSelector test given the filter
3541  Isotope.prototype._getFilterTest = function( filter ) {
3542    if ( jQuery && this.options.isJQueryFiltering ) {
3543      // use jQuery
3544      return function( item ) {
3545        return jQuery( item.element ).is( filter );
3546      };
3547    }
3548    if ( typeof filter === 'function' ) {
3549      // use filter as function
3550      return function( item ) {
3551        return filter( item.element );
3552      };
3553    }
3554    // default, use filter as selector string
3555    return function( item ) {
3556      return matchesSelector( item.element, filter );
3557    };
3558  };
3559
3560  // -------------------------- sorting -------------------------- //
3561
3562  /**
3563   * @params {Array} elems
3564   * @public
3565   */
3566  Isotope.prototype.updateSortData = function( elems ) {
3567    this._getSorters();
3568    // update item sort data
3569    // default to all items if none are passed in
3570    elems = makeArray( elems );
3571    var items = this.getItems( elems );
3572    // if no items found, update all items
3573    items = items.length ? items : this.items;
3574    this._updateItemsSortData( items );
3575  };
3576
3577  Isotope.prototype._getSorters = function() {
3578    var getSortData = this.options.getSortData;
3579    for ( var key in getSortData ) {
3580      var sorter = getSortData[ key ];
3581      this._sorters[ key ] = mungeSorter( sorter );
3582    }
3583  };
3584
3585  /**
3586   * @params {Array} items - of Isotope.Items
3587   * @private
3588   */
3589  Isotope.prototype._updateItemsSortData = function( items ) {
3590    for ( var i=0, len = items.length; i < len; i++ ) {
3591      var item = items[i];
3592      item.updateSortData();
3593    }
3594  };
3595
3596  // ----- munge sorter ----- //
3597
3598  // encapsulate this, as we just need mungeSorter
3599  // other functions in here are just for munging
3600  var mungeSorter = ( function() {
3601    // add a magic layer to sorters for convienent shorthands
3602    // `.foo-bar` will use the text of .foo-bar querySelector
3603    // `[foo-bar]` will use attribute
3604    // you can also add parser
3605    // `.foo-bar parseInt` will parse that as a number
3606    function mungeSorter( sorter ) {
3607      // if not a string, return function or whatever it is
3608      if ( typeof sorter !== 'string' ) {
3609        return sorter;
3610      }
3611      // parse the sorter string
3612      var args = trim( sorter ).split(' ');
3613      var query = args[0];
3614      // check if query looks like [an-attribute]
3615      var attrMatch = query.match( /^\[(.+)\]$/ );
3616      var attr = attrMatch && attrMatch[1];
3617      var getValue = getValueGetter( attr, query );
3618      // use second argument as a parser
3619      var parser = Isotope.sortDataParsers[ args[1] ];
3620      // parse the value, if there was a parser
3621      sorter = parser ? function( elem ) {
3622        return elem && parser( getValue( elem ) );
3623      } :
3624      // otherwise just return value
3625      function( elem ) {
3626        return elem && getValue( elem );
3627      };
3628
3629      return sorter;
3630    }
3631
3632    // get an attribute getter, or get text of the querySelector
3633    function getValueGetter( attr, query ) {
3634      var getValue;
3635      // if query looks like [foo-bar], get attribute
3636      if ( attr ) {
3637        getValue = function( elem ) {
3638          return elem.getAttribute( attr );
3639        };
3640      } else {
3641        // otherwise, assume its a querySelector, and get its text
3642        getValue = function( elem ) {
3643          var child = elem.querySelector( query );
3644          return child && getText( child );
3645        };
3646      }
3647      return getValue;
3648    }
3649
3650    return mungeSorter;
3651  })();
vendor: 5,011 bytes, lines 3652-3808
3652
3653  // parsers used in getSortData shortcut strings
3654  Isotope.sortDataParsers = {
3655    'parseInt': function( val ) {
3656      return parseInt( val, 10 );
3657    },
3658    'parseFloat': function( val ) {
3659      return parseFloat( val );
3660    }
3661  };
3662
3663  // ----- sort method ----- //
3664
3665  // sort filteredItem order
3666  Isotope.prototype._sort = function() {
3667    var sortByOpt = this.options.sortBy;
3668    if ( !sortByOpt ) {
3669      return;
3670    }
3671    // concat all sortBy and sortHistory
3672    var sortBys = [].concat.apply( sortByOpt, this.sortHistory );
3673    // sort magic
3674    var itemSorter = getItemSorter( sortBys, this.options.sortAscending );
3675    this.filteredItems.sort( itemSorter );
3676    // keep track of sortBy History
3677    if ( sortByOpt !== this.sortHistory[0] ) {
3678      // add to front, oldest goes in last
3679      this.sortHistory.unshift( sortByOpt );
3680    }
3681  };
3682
3683  // returns a function used for sorting
3684  function getItemSorter( sortBys, sortAsc ) {
3685    return function sorter( itemA, itemB ) {
3686      // cycle through all sortKeys
3687      for ( var i = 0, len = sortBys.length; i < len; i++ ) {
3688        var sortBy = sortBys[i];
3689        var a = itemA.sortData[ sortBy ];
3690        var b = itemB.sortData[ sortBy ];
3691        if ( a > b || a < b ) {
3692          // if sortAsc is an object, use the value given the sortBy key
3693          var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
3694          var direction = isAscending ? 1 : -1;
3695          return ( a > b ? 1 : -1 ) * direction;
3696        }
3697      }
3698      return 0;
3699    };
3700  }
3701
3702  // -------------------------- methods -------------------------- //
3703
3704  // get layout mode
3705  Isotope.prototype._mode = function() {
3706    var layoutMode = this.options.layoutMode;
3707    var mode = this.modes[ layoutMode ];
3708    if ( !mode ) {
3709      // TODO console.error
3710      throw new Error( 'No layout mode: ' + layoutMode );
3711    }
3712    // HACK sync mode's options
3713    // any options set after init for layout mode need to be synced
3714    mode.options = this.options[ layoutMode ];
3715    return mode;
3716  };
3717
3718  Isotope.prototype._resetLayout = function() {
3719    // trigger original reset layout
3720    Outlayer.prototype._resetLayout.call( this );
3721    this._mode()._resetLayout();
3722  };
3723
3724  Isotope.prototype._getItemLayoutPosition = function( item  ) {
3725    return this._mode()._getItemLayoutPosition( item );
3726  };
3727
3728  Isotope.prototype._manageStamp = function( stamp ) {
3729    this._mode()._manageStamp( stamp );
3730  };
3731
3732  Isotope.prototype._getContainerSize = function() {
3733    return this._mode()._getContainerSize();
3734  };
3735
3736  Isotope.prototype.needsResizeLayout = function() {
3737    return this._mode().needsResizeLayout();
3738  };
3739
3740  // -------------------------- adding & removing -------------------------- //
3741
3742  // HEADS UP overwrites default Outlayer appended
3743  Isotope.prototype.appended = function( elems ) {
3744    var items = this.addItems( elems );
3745    if ( !items.length ) {
3746      return;
3747    }
3748    var filteredItems = this._filterRevealAdded( items );
3749    // add to filteredItems
3750    this.filteredItems = this.filteredItems.concat( filteredItems );
3751  };
3752
3753  // HEADS UP overwrites default Outlayer prepended
3754  Isotope.prototype.prepended = function( elems ) {
3755    var items = this._itemize( elems );
3756    if ( !items.length ) {
3757      return;
3758    }
3759    // add items to beginning of collection
3760    var previousItems = this.items.slice(0);
3761    this.items = items.concat( previousItems );
3762    // start new layout
3763    this._resetLayout();
3764    this._manageStamps();
3765    // layout new stuff without transition
3766    var filteredItems = this._filterRevealAdded( items );
3767    // layout previous items
3768    this.layoutItems( previousItems );
3769    // add to filteredItems
3770    this.filteredItems = filteredItems.concat( this.filteredItems );
3771  };
3772
3773  Isotope.prototype._filterRevealAdded = function( items ) {
3774    var filteredItems = this._noTransition( function() {
3775      return this._filter( items );
3776    });
3777    // layout and reveal just the new items
3778    this.layoutItems( filteredItems, true );
3779    this.reveal( filteredItems );
3780    return items;
3781  };
3782
3783  /**
3784   * Filter, sort, and layout newly-appended item elements
3785   * @param {Array or NodeList or Element} elems
3786   */
3787  Isotope.prototype.insert = function( elems ) {
3788    var items = this.addItems( elems );
3789    if ( !items.length ) {
3790      return;
3791    }
3792    // append item elements
3793    var i, item;
3794    var len = items.length;
3795    for ( i=0; i < len; i++ ) {
3796      item = items[i];
3797      this.element.appendChild( item.element );
3798    }
3799    // filter new stuff
3800    /*
3801    // this way adds hides new filtered items with NO transition
3802    // so user can't see if new hidden items have been inserted
3803    var filteredInsertItems;
3804    this._noTransition( function() {
3805      filteredInsertItems = this._filter( items );
3806      // hide all new items
3807      this.hide( filteredInsertItems );
3808    });
3809    // */
3810    // this way hides new filtered items with transition
3811    // so user at least sees that something has been added
3812    var filteredInsertItems = this._filter( items );
3813    // hide all newitems
3814    this._noTransition( function() {
3815      this.hide( filteredInsertItems );
3816    });
3817    // */
3818    // set flag
3819    for ( i=0; i < len; i++ ) {
3820      items[i].isLayoutInstant = true;
3821    }
3822    this.arrange();
3823    // reset flag
3824    for ( i=0; i < len; i++ ) {
3825      delete items[i].isLayoutInstant;
3826    }
3827    this.reveal( filteredInsertItems );
3828  };
3829
3830  var _remove = Isotope.prototype.remove;
3831  Isotope.prototype.remove = function( elems ) {
3832    elems = makeArray( elems );
3833    var removeItems = this.getItems( elems );
3834    // do regular thing
3835    _remove.call( this, elems );
3836    // bail if no items to remove
3837    if ( !removeItems || !removeItems.length ) {
3838      return;
3839    }
3840    // remove elems from filteredItems
3841    for ( var i=0, len = removeItems.length; i < len; i++ ) {
3842      var item = removeItems[i];
3843      // remove item from collection
3844      removeFrom( item, this.filteredItems );
3845    }
3846  };
3847
3848  Isotope.prototype.shuffle = function() {
3849    // update random sortData
3850    for ( var i=0, len = this.items.length; i < len; i++ ) {
3851      var item = this.items[i];
3852      item.sortData.random = Math.random();
3853    }
3854    this.options.sortBy = 'random';
3855    this._sort();
3856    this._layout();
3857  };
3858
3859  /**
3860   * trigger fn without transition
3861   * kind of hacky to have this in the first place
3862   * @param {Function} fn
3863   * @returns ret
3864   * @private
3865   */
3866  Isotope.prototype._noTransition = function( fn ) {
3867    // save transitionDuration before disabling
3868    var transitionDuration = this.options.transitionDuration;
3869    // disable transition
3870    this.options.transitionDuration = 0;
3871    // do it
3872    var returnValue = fn.call( this );
3873    // re-enable transition for reveal
3874    this.options.transitionDuration = transitionDuration;
3875    return returnValue;
3876  };
3877
3878  // ----- helper methods ----- //
3879
3880  /**
3881   * getter method for getting filtered item elements
3882   * @returns {Array} elems - collection of item elements
3883   */
3884  Isotope.prototype.getFilteredItemElements = function() {
3885    var elems = [];
3886    for ( var i=0, len = this.filteredItems.length; i < len; i++ ) {
3887      elems.push( this.filteredItems[i].element );
3888    }
3889    return elems;
3890  };
3891
3892  // -----  ----- //
3893
3894  return Isotope;
3895}
3896
3897// -------------------------- transport -------------------------- //
3898
3899if ( typeof define === 'function' && define.amd ) {
3900  // AMD
3901  define( [
3902      'outlayer/outlayer',
3903      'get-size/get-size',
3904      'matches-selector/matches-selector',
3905      'isotope/js/item',
3906      'isotope/js/layout-mode',
3907      // include default layout modes
3908      'isotope/js/layout-modes/masonry',
3909      'isotope/js/layout-modes/fit-rows',
3910      'isotope/js/layout-modes/vertical'
3911    ],
3912    isotopeDefinition );
3913} else {
3914  // browser global
3915  window.Isotope = isotopeDefinition(
3916    window.Outlayer,
3917    window.getSize,
3918    window.matchesSelector,
3919    window.Isotope.Item,
3920    window.Isotope.LayoutMode
3921  );
3922}
3923
3924})( window );
3925

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.