PageSourceSearch

https://www.mandurahestateagency.com.au/wp-content/plugins/rexsoft…/lib/masonry/masonry.js?ver=1684192007475

js mandurahestateagency.com.au collected 2026-10-09 00:56:37 UTC 89,531 bytes, 3,186 lines download raw bytes

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

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.