diff --git a/dist/shuffle.js b/dist/shuffle.js index bfe6551..8fdec40 100644 --- a/dist/shuffle.js +++ b/dist/shuffle.js @@ -1,108 +1,9 @@ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : - (global = global || self, global.Shuffle = factory()); + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Shuffle = factory()); }(this, (function () { 'use strict'; - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } - - function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - return Constructor; - } - - function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function"); - } - - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - writable: true, - configurable: true - } - }); - if (superClass) _setPrototypeOf(subClass, superClass); - } - - function _getPrototypeOf(o) { - _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { - return o.__proto__ || Object.getPrototypeOf(o); - }; - return _getPrototypeOf(o); - } - - function _setPrototypeOf(o, p) { - _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; - - return _setPrototypeOf(o, p); - } - - function _isNativeReflectConstruct() { - if (typeof Reflect === "undefined" || !Reflect.construct) return false; - if (Reflect.construct.sham) return false; - if (typeof Proxy === "function") return true; - - try { - Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); - return true; - } catch (e) { - return false; - } - } - - function _assertThisInitialized(self) { - if (self === void 0) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } - - return self; - } - - function _possibleConstructorReturn(self, call) { - if (call && (typeof call === "object" || typeof call === "function")) { - return call; - } - - return _assertThisInitialized(self); - } - - function _createSuper(Derived) { - return function () { - var Super = _getPrototypeOf(Derived), - result; - - if (_isNativeReflectConstruct()) { - var NewTarget = _getPrototypeOf(this).constructor; - - result = Reflect.construct(Super, arguments, NewTarget); - } else { - result = Super.apply(this, arguments); - } - - return _possibleConstructorReturn(this, result); - }; - } - function E () { // Keep this empty so it's easier to inherit from // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) @@ -283,15 +184,13 @@ return parseFloat(value) || 0; } - var Point = /*#__PURE__*/function () { + class Point { /** * Represents a coordinate pair. * @param {number} [x=0] X. * @param {number} [y=0] Y. */ - function Point(x, y) { - _classCallCheck(this, Point); - + constructor(x, y) { this.x = getNumber(x); this.y = getNumber(y); } @@ -303,17 +202,13 @@ */ - _createClass(Point, null, [{ - key: "equals", - value: function equals(a, b) { - return a.x === b.x && a.y === b.y; - } - }]); + static equals(a, b) { + return a.x === b.x && a.y === b.y; + } - return Point; - }(); + } - var Rect = /*#__PURE__*/function () { + class Rect { /** * Class for representing rectangular regions. * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js @@ -324,9 +219,7 @@ * @param {number} id Identifier * @constructor */ - function Rect(x, y, w, h, id) { - _classCallCheck(this, Rect); - + constructor(x, y, w, h, id) { this.id = id; /** @type {number} */ @@ -349,15 +242,11 @@ */ - _createClass(Rect, null, [{ - key: "intersects", - value: function intersects(a, b) { - return a.left < b.left + b.width && b.left < a.left + a.width && a.top < b.top + b.height && b.top < a.top + a.height; - } - }]); + static intersects(a, b) { + return a.left < b.left + b.width && b.left < a.left + a.width && a.top < b.top + b.height && b.top < a.top + a.height; + } - return Rect; - }(); + } var Classes = { BASE: 'shuffle', @@ -366,15 +255,18 @@ HIDDEN: 'shuffle-item--hidden' }; - var id = 0; + let id$1 = 0; - var ShuffleItem = /*#__PURE__*/function () { - function ShuffleItem(element) { - _classCallCheck(this, ShuffleItem); - - id += 1; - this.id = id; + class ShuffleItem { + constructor(element, isRTL) { + id$1 += 1; + this.id = id$1; this.element = element; + /** + * Set correct direction of item + */ + + this.isRTL = isRTL; /** * Used to separate items for layout and shrink. */ @@ -390,77 +282,69 @@ this.isHidden = false; } - _createClass(ShuffleItem, [{ - key: "show", - value: function show() { - this.isVisible = true; - this.element.classList.remove(Classes.HIDDEN); - this.element.classList.add(Classes.VISIBLE); - this.element.removeAttribute('aria-hidden'); - } - }, { - key: "hide", - value: function hide() { - this.isVisible = false; - this.element.classList.remove(Classes.VISIBLE); - this.element.classList.add(Classes.HIDDEN); - this.element.setAttribute('aria-hidden', true); - } - }, { - key: "init", - value: function init() { - this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]); - this.applyCss(ShuffleItem.Css.INITIAL); - this.scale = ShuffleItem.Scale.VISIBLE; - this.point = new Point(); - } - }, { - key: "addClasses", - value: function addClasses(classes) { - var _this = this; + show() { + this.isVisible = true; + this.element.classList.remove(Classes.HIDDEN); + this.element.classList.add(Classes.VISIBLE); + this.element.removeAttribute('aria-hidden'); + } - classes.forEach(function (className) { - _this.element.classList.add(className); - }); - } - }, { - key: "removeClasses", - value: function removeClasses(classes) { - var _this2 = this; + hide() { + this.isVisible = false; + this.element.classList.remove(Classes.VISIBLE); + this.element.classList.add(Classes.HIDDEN); + this.element.setAttribute('aria-hidden', true); + } - classes.forEach(function (className) { - _this2.element.classList.remove(className); - }); - } - }, { - key: "applyCss", - value: function applyCss(obj) { - var _this3 = this; + init() { + this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]); + this.applyCss(ShuffleItem.Css.INITIAL); + this.applyCss(this.isRTL ? ShuffleItem.Css.DIRECTION.rtl : ShuffleItem.Css.DIRECTION.ltr); + this.scale = ShuffleItem.Scale.VISIBLE; + this.point = new Point(); + } - Object.keys(obj).forEach(function (key) { - _this3.element.style[key] = obj[key]; - }); - } - }, { - key: "dispose", - value: function dispose() { - this.removeClasses([Classes.HIDDEN, Classes.VISIBLE, Classes.SHUFFLE_ITEM]); - this.element.removeAttribute('style'); - this.element = null; - } - }]); + addClasses(classes) { + classes.forEach(className => { + this.element.classList.add(className); + }); + } + + removeClasses(classes) { + classes.forEach(className => { + this.element.classList.remove(className); + }); + } + + applyCss(obj) { + Object.keys(obj).forEach(key => { + this.element.style[key] = obj[key]; + }); + } + + dispose() { + this.removeClasses([Classes.HIDDEN, Classes.VISIBLE, Classes.SHUFFLE_ITEM]); + this.element.removeAttribute('style'); + this.element = null; + } - return ShuffleItem; - }(); + } ShuffleItem.Css = { INITIAL: { position: 'absolute', top: 0, - left: 0, visibility: 'visible', willChange: 'transform' }, + DIRECTION: { + ltr: { + left: 0 + }, + rtl: { + right: 0 + } + }, VISIBLE: { before: { opacity: 1, @@ -485,14 +369,14 @@ HIDDEN: 0.001 }; - var value = null; - var testComputedSize = (function () { + let value = null; + var testComputedSize = (() => { if (value !== null) { return value; } - var element = document.body || document.documentElement; - var e = document.createElement('div'); + const element = document.body || document.documentElement; + const e = document.createElement('div'); e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;'; element.appendChild(e); value = window.getComputedStyle(e, null).width === '10px'; @@ -511,9 +395,8 @@ * the computed style. */ - function getNumberStyle(element, style) { - var styles = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : window.getComputedStyle(element, null); - var value = getNumber(styles[style]); // Support IE<=11 and W3C spec. + function getNumberStyle(element, style, styles = window.getComputedStyle(element, null)) { + let value = getNumber(styles[style]); // Support IE<=11 and W3C spec. if (!testComputedSize() && style === 'width') { value += getNumber(styles.paddingLeft) + getNumber(styles.paddingRight) + getNumber(styles.borderLeftWidth) + getNumber(styles.borderRightWidth); @@ -532,12 +415,12 @@ * @return {Array} Randomly sorted array. */ function randomize(array) { - var n = array.length; + let n = array.length; while (n) { n -= 1; - var i = Math.floor(Math.random() * (n + 1)); - var temp = array[i]; + const i = Math.floor(Math.random() * (n + 1)); + const temp = array[i]; array[i] = array[n]; array[n] = temp; } @@ -545,7 +428,7 @@ return array; } - var defaults = { + const defaults = { // Use array.reverse() to reverse the results reverse: false, // Sorting function @@ -567,9 +450,9 @@ function sorter(arr, options) { // eslint-disable-next-line prefer-object-spread - var opts = Object.assign({}, defaults, options); - var original = Array.from(arr); - var revert = false; + const opts = Object.assign({}, defaults, options); + const original = Array.from(arr); + let revert = false; if (!arr.length) { return []; @@ -582,14 +465,14 @@ if (typeof opts.by === 'function') { - arr.sort(function (a, b) { + arr.sort((a, b) => { // Exit early if we already know we want to revert if (revert) { return 0; } - var valA = opts.by(a[opts.key]); - var valB = opts.by(b[opts.key]); // If both values are undefined, use the DOM order + const valA = opts.by(a[opts.key]); + const valB = opts.by(b[opts.key]); // If both values are undefined, use the DOM order if (valA === undefined && valB === undefined) { revert = true; @@ -622,9 +505,9 @@ return arr; } - var transitions = {}; - var eventName = 'transitionend'; - var count = 0; + const transitions = {}; + const eventName = 'transitionend'; + let count = 0; function uniqueId() { count += 1; @@ -641,9 +524,9 @@ return false; } function onTransitionEnd(element, callback) { - var id = uniqueId(); + const id = uniqueId(); - var listener = function listener(evt) { + const listener = evt => { if (evt.currentTarget === evt.target) { cancelTransitionEnd(id); callback(evt); @@ -652,8 +535,8 @@ element.addEventListener(eventName, listener); transitions[id] = { - element: element, - listener: listener + element, + listener }; return id; } @@ -676,7 +559,7 @@ */ function getColumnSpan(itemWidth, columnWidth, columns, threshold) { - var columnSpan = itemWidth / columnWidth; // If the difference between the rounded column span number and the + let columnSpan = itemWidth / columnWidth; // If the difference between the rounded column span number and the // calculated column span number is really small, round the number to // make it fit. @@ -723,9 +606,9 @@ // [10, 20, 10, 0] => [20, 20, 10] => 10 - var available = []; // For how many possible positions for this item there are. + const available = []; // For how many possible positions for this item there are. - for (var i = 0; i <= columns - columnSpan; i++) { + for (let i = 0; i <= columns - columnSpan; i++) { // Find the bigger value for each place it could fit. available.push(arrayMax(positions.slice(i, i + columnSpan))); } @@ -742,9 +625,9 @@ */ function getShortColumn(positions, buffer) { - var minPosition = arrayMin(positions); + const minPosition = arrayMin(positions); - for (var i = 0, len = positions.length; i < len; i++) { + for (let i = 0, len = positions.length; i < len; i++) { if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) { return i; } @@ -763,24 +646,25 @@ * @return {Point} */ - function getItemPosition(_ref) { - var itemSize = _ref.itemSize, - positions = _ref.positions, - gridSize = _ref.gridSize, - total = _ref.total, - threshold = _ref.threshold, - buffer = _ref.buffer; - var span = getColumnSpan(itemSize.width, gridSize, total, threshold); - var setY = getAvailablePositions(positions, span, total); - var shortColumnIndex = getShortColumn(setY, buffer); // Position the item - - var point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]); // Update the columns array with the new values for each column. + function getItemPosition({ + itemSize, + positions, + gridSize, + total, + threshold, + buffer + }) { + const span = getColumnSpan(itemSize.width, gridSize, total, threshold); + const setY = getAvailablePositions(positions, span, total); + const shortColumnIndex = getShortColumn(setY, buffer); // Position the item + + const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]); // Update the columns array with the new values for each column. // e.g. before the update the columns could be [250, 0, 0, 0] for an item // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0]. - var setHeight = setY[shortColumnIndex] + itemSize.height; + const setHeight = setY[shortColumnIndex] + itemSize.height; - for (var i = 0; i < span; i++) { + for (let i = 0; i < span; i++) { positions[shortColumnIndex + i] = setHeight; } @@ -796,11 +680,11 @@ */ function getCenteredPositions(itemRects, containerWidth) { - var rowMap = {}; // Populate rows by their offset because items could jump between rows like: + const rowMap = {}; // Populate rows by their offset because items could jump between rows like: // a c // bbb - itemRects.forEach(function (itemRect) { + itemRects.forEach(itemRect => { if (rowMap[itemRect.top]) { // Push the point to the last row array. rowMap[itemRect.top].push(itemRect); @@ -812,26 +696,24 @@ // the remaining space by dividing it by 2. Then add that // offset to the x position of each point. - var rects = []; - var rows = []; - var centeredRows = []; - Object.keys(rowMap).forEach(function (key) { - var itemRects = rowMap[key]; + let rects = []; + const rows = []; + const centeredRows = []; + Object.keys(rowMap).forEach(key => { + const itemRects = rowMap[key]; rows.push(itemRects); - var lastItem = itemRects[itemRects.length - 1]; - var end = lastItem.left + lastItem.width; - var offset = Math.round((containerWidth - end) / 2); - var finalRects = itemRects; - var canMove = false; + const lastItem = itemRects[itemRects.length - 1]; + const end = lastItem.left + lastItem.width; + const offset = Math.round((containerWidth - end) / 2); + let finalRects = itemRects; + let canMove = false; if (offset > 0) { - var newRects = []; - canMove = itemRects.every(function (r) { - var newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id); // Check all current rects to make sure none overlap. + const newRects = []; + canMove = itemRects.every(r => { + const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id); // Check all current rects to make sure none overlap. - var noOverlap = !rects.some(function (r) { - return Rect.intersects(newRect, r); - }); + const noOverlap = !rects.some(r => Rect.intersects(newRect, r)); newRects.push(newRect); return noOverlap; }); // If none of the rectangles overlapped, the whole group can be centered. @@ -845,23 +727,19 @@ if (!canMove) { - var intersectingRect; - var hasOverlap = itemRects.some(function (itemRect) { - return rects.some(function (r) { - var intersects = Rect.intersects(itemRect, r); + let intersectingRect; + const hasOverlap = itemRects.some(itemRect => rects.some(r => { + const intersects = Rect.intersects(itemRect, r); - if (intersects) { - intersectingRect = r; - } + if (intersects) { + intersectingRect = r; + } - return intersects; - }); - }); // If there is any overlap, replace the overlapping row with the original. + return intersects; + })); // If there is any overlap, replace the overlapping row with the original. if (hasOverlap) { - var rowIndex = centeredRows.findIndex(function (items) { - return items.includes(intersectingRect); - }); + const rowIndex = centeredRows.findIndex(items => items.includes(intersectingRect)); centeredRows.splice(rowIndex, 1, rows[rowIndex]); } } @@ -874,11 +752,7 @@ // Remove the wrapper object with index, map to a Point. return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread - .sort(function (a, b) { - return a.id - b.id; - }).map(function (itemRect) { - return new Point(itemRect.left, itemRect.top); - }); + .sort((a, b) => a.id - b.id).map(itemRect => new Point(itemRect.left, itemRect.top)); } /** @@ -888,9 +762,7 @@ * @return {string} The hyphenated string. */ function hyphenate(str) { - return str.replace(/([A-Z])/g, function (str, m1) { - return "-".concat(m1.toLowerCase()); - }); + return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`); } function arrayUnique(x) { @@ -898,13 +770,9 @@ } // Used for unique instance variables - var id$1 = 0; - - var Shuffle = /*#__PURE__*/function (_TinyEmitter) { - _inherits(Shuffle, _TinyEmitter); - - var _super = _createSuper(Shuffle); + let id = 0; + class Shuffle extends tinyEmitter { /** * Categorize, sort, and filter a responsive grid of items. * @@ -912,1225 +780,1109 @@ * @param {Object} [options=Shuffle.options] Options object. * @constructor */ - function Shuffle(element) { - var _this; - - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - _classCallCheck(this, Shuffle); - - _this = _super.call(this); // eslint-disable-next-line prefer-object-spread + constructor(element, options = {}) { + super(); // eslint-disable-next-line prefer-object-spread - _this.options = Object.assign({}, Shuffle.options, options); // Allow misspelling of delimiter since that's how it used to be. + this.options = Object.assign({}, Shuffle.options, options); // Allow misspelling of delimiter since that's how it used to be. // Remove in v6. - if (_this.options.delimeter) { - _this.options.delimiter = _this.options.delimeter; + if (this.options.delimeter) { + this.options.delimiter = this.options.delimeter; } - _this.lastSort = {}; - _this.group = Shuffle.ALL_ITEMS; - _this.lastFilter = Shuffle.ALL_ITEMS; - _this.isEnabled = true; - _this.isDestroyed = false; - _this.isInitialized = false; - _this._transitions = []; - _this.isTransitioning = false; - _this._queue = []; + this.lastSort = {}; + this.group = Shuffle.ALL_ITEMS; + this.lastFilter = Shuffle.ALL_ITEMS; + this.isEnabled = true; + this.isDestroyed = false; + this.isInitialized = false; + this._transitions = []; + this.isTransitioning = false; + this._queue = []; - var el = _this._getElementOption(element); + const el = this._getElementOption(element); if (!el) { throw new TypeError('Shuffle needs to be initialized with an element.'); } - _this.element = el; - _this.id = 'shuffle_' + id$1; - id$1 += 1; + this.element = el; + this.id = 'shuffle_' + id; + id += 1; - _this._init(); + this._init(); - _this.isInitialized = true; - return _this; + this.isInitialized = true; } - _createClass(Shuffle, [{ - key: "_init", - value: function _init() { - this.items = this._getItems(); - this.options.sizer = this._getElementOption(this.options.sizer); // Add class and invalidate styles - - this.element.classList.add(Shuffle.Classes.BASE); // Set initial css for each item - - this._initItems(this.items); // Bind resize events + _init() { + this.items = this._getItems(); + this.options.sizer = this._getElementOption(this.options.sizer); // Add class and invalidate styles + this.element.classList.add(Shuffle.Classes.BASE); // Set initial css for each item - this._onResize = this._getResizeFunction(); - window.addEventListener('resize', this._onResize); // If the page has not already emitted the `load` event, call layout on load. - // This avoids layout issues caused by images and fonts loading after the - // instance has been initialized. + this._initItems(this.items); // Bind resize events - if (document.readyState !== 'complete') { - var layout = this.layout.bind(this); - window.addEventListener('load', function onLoad() { - window.removeEventListener('load', onLoad); - layout(); - }); - } // Get container css all in one request. Causes reflow + this._onResize = this._getResizeFunction(); + window.addEventListener('resize', this._onResize); // If the page has not already emitted the `load` event, call layout on load. + // This avoids layout issues caused by images and fonts loading after the + // instance has been initialized. - var containerCss = window.getComputedStyle(this.element, null); - var containerWidth = Shuffle.getSize(this.element).width; // Add styles to the container if it doesn't have them. + if (document.readyState !== 'complete') { + const layout = this.layout.bind(this); + window.addEventListener('load', function onLoad() { + window.removeEventListener('load', onLoad); + layout(); + }); + } // Get container css all in one request. Causes reflow - this._validateStyles(containerCss); // We already got the container's width above, no need to cause another - // reflow getting it again... Calculate the number of columns there will be + const containerCss = window.getComputedStyle(this.element, null); + const containerWidth = Shuffle.getSize(this.element).width; // Add styles to the container if it doesn't have them. - this._setColumns(containerWidth); // Kick off! + this._validateStyles(containerCss); // We already got the container's width above, no need to cause another + // reflow getting it again... Calculate the number of columns there will be - this.filter(this.options.group, this.options.initialSort); // The shuffle items haven't had transitions set on them yet so the user - // doesn't see the first layout. Set them now that the first layout is done. - // First, however, a synchronous layout must be caused for the previous - // styles to be applied without transitions. + this._setColumns(containerWidth); // Kick off! - this.element.offsetWidth; // eslint-disable-line no-unused-expressions - this.setItemTransitions(this.items); - this.element.style.transition = "height ".concat(this.options.speed, "ms ").concat(this.options.easing); - } - /** - * Returns a throttled and proxied function for the resize handler. - * @return {function} - * @private - */ + this.filter(this.options.group, this.options.initialSort); // The shuffle items haven't had transitions set on them yet so the user + // doesn't see the first layout. Set them now that the first layout is done. + // First, however, a synchronous layout must be caused for the previous + // styles to be applied without transitions. - }, { - key: "_getResizeFunction", - value: function _getResizeFunction() { - var resizeFunction = this._handleResize.bind(this); + this.element.offsetWidth; // eslint-disable-line no-unused-expressions - return this.options.throttle ? this.options.throttle(resizeFunction, this.options.throttleTime) : resizeFunction; - } - /** - * Retrieve an element from an option. - * @param {string|jQuery|Element} option The option to check. - * @return {?Element} The plain element or null. - * @private - */ + this.setItemTransitions(this.items); + this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`; + } + /** + * Returns a throttled and proxied function for the resize handler. + * @return {function} + * @private + */ - }, { - key: "_getElementOption", - value: function _getElementOption(option) { - // If column width is a string, treat is as a selector and search for the - // sizer element within the outermost container - if (typeof option === 'string') { - return this.element.querySelector(option); - } // Check for an element + _getResizeFunction() { + const resizeFunction = this._handleResize.bind(this); - if (option && option.nodeType && option.nodeType === 1) { - return option; - } // Check for jQuery object + return this.options.throttle ? this.options.throttle(resizeFunction, this.options.throttleTime) : resizeFunction; + } + /** + * Retrieve an element from an option. + * @param {string|jQuery|Element} option The option to check. + * @return {?Element} The plain element or null. + * @private + */ - if (option && option.jquery) { - return option[0]; - } + _getElementOption(option) { + // If column width is a string, treat is as a selector and search for the + // sizer element within the outermost container + if (typeof option === 'string') { + return this.element.querySelector(option); + } // Check for an element - return null; - } - /** - * Ensures the shuffle container has the css styles it needs applied to it. - * @param {Object} styles Key value pairs for position and overflow. - * @private - */ - }, { - key: "_validateStyles", - value: function _validateStyles(styles) { - // Position cannot be static. - if (styles.position === 'static') { - this.element.style.position = 'relative'; - } // Overflow has to be hidden. + if (option && option.nodeType && option.nodeType === 1) { + return option; + } // Check for jQuery object - if (styles.overflow !== 'hidden') { - this.element.style.overflow = 'hidden'; - } + if (option && option.jquery) { + return option[0]; } - /** - * Filter the elements by a category. - * @param {string|string[]|function(Element):boolean} [category] Category to - * filter by. If it's given, the last category will be used to filter the items. - * @param {Array} [collection] Optionally filter a collection. Defaults to - * all the items. - * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}} - * @private - */ - }, { - key: "_filter", - value: function _filter() { - var category = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.lastFilter; - var collection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.items; + return null; + } + /** + * Ensures the shuffle container has the css styles it needs applied to it. + * @param {Object} styles Key value pairs for position and overflow. + * @private + */ - var set = this._getFilteredSets(category, collection); // Individually add/remove hidden/visible classes + _validateStyles(styles) { + // Position cannot be static. + if (styles.position === 'static') { + this.element.style.position = 'relative'; + } // Overflow has to be hidden. - this._toggleFilterClasses(set); // Save the last filter in case elements are appended. + if (styles.overflow !== 'hidden') { + this.element.style.overflow = 'hidden'; + } + } + /** + * Filter the elements by a category. + * @param {string|string[]|function(Element):boolean} [category] Category to + * filter by. If it's given, the last category will be used to filter the items. + * @param {Array} [collection] Optionally filter a collection. Defaults to + * all the items. + * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}} + * @private + */ - this.lastFilter = category; // This is saved mainly because providing a filter function (like searching) - // will overwrite the `lastFilter` property every time its called. - if (typeof category === 'string') { - this.group = category; - } + _filter(category = this.lastFilter, collection = this.items) { + const set = this._getFilteredSets(category, collection); // Individually add/remove hidden/visible classes - return set; - } - /** - * Returns an object containing the visible and hidden elements. - * @param {string|string[]|function(Element):boolean} category Category or function to filter by. - * @param {ShuffleItem[]} items A collection of items to filter. - * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}} - * @private - */ - }, { - key: "_getFilteredSets", - value: function _getFilteredSets(category, items) { - var _this2 = this; + this._toggleFilterClasses(set); // Save the last filter in case elements are appended. - var visible = []; - var hidden = []; // category === 'all', add visible class to everything - if (category === Shuffle.ALL_ITEMS) { - visible = items; // Loop through each item and use provided function to determine - // whether to hide it or not. - } else { - items.forEach(function (item) { - if (_this2._doesPassFilter(category, item.element)) { - visible.push(item); - } else { - hidden.push(item); - } - }); - } + this.lastFilter = category; // This is saved mainly because providing a filter function (like searching) + // will overwrite the `lastFilter` property every time its called. - return { - visible: visible, - hidden: hidden - }; + if (typeof category === 'string') { + this.group = category; } - /** - * Test an item to see if it passes a category. - * @param {string|string[]|function():boolean} category Category or function to filter by. - * @param {Element} element An element to test. - * @return {boolean} Whether it passes the category/filter. - * @private - */ - - }, { - key: "_doesPassFilter", - value: function _doesPassFilter(category, element) { - if (typeof category === 'function') { - return category.call(element, element, this); - } // Check each element's data-groups attribute against the given category. + return set; + } + /** + * Returns an object containing the visible and hidden elements. + * @param {string|string[]|function(Element):boolean} category Category or function to filter by. + * @param {ShuffleItem[]} items A collection of items to filter. + * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}} + * @private + */ - var attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY); - var keys = this.options.delimiter ? attr.split(this.options.delimiter) : JSON.parse(attr); - function testCategory(category) { - return keys.includes(category); - } + _getFilteredSets(category, items) { + let visible = []; + const hidden = []; // category === 'all', add visible class to everything - if (Array.isArray(category)) { - if (this.options.filterMode === Shuffle.FilterMode.ANY) { - return category.some(testCategory); + if (category === Shuffle.ALL_ITEMS) { + visible = items; // Loop through each item and use provided function to determine + // whether to hide it or not. + } else { + items.forEach(item => { + if (this._doesPassFilter(category, item.element)) { + visible.push(item); + } else { + hidden.push(item); } - - return category.every(testCategory); - } - - return keys.includes(category); - } - /** - * Toggles the visible and hidden class names. - * @param {{visible, hidden}} Object with visible and hidden arrays. - * @private - */ - - }, { - key: "_toggleFilterClasses", - value: function _toggleFilterClasses(_ref) { - var visible = _ref.visible, - hidden = _ref.hidden; - visible.forEach(function (item) { - item.show(); - }); - hidden.forEach(function (item) { - item.hide(); - }); - } - /** - * Set the initial css for each item - * @param {ShuffleItem[]} items Set to initialize. - * @private - */ - - }, { - key: "_initItems", - value: function _initItems(items) { - items.forEach(function (item) { - item.init(); }); } - /** - * Remove element reference and styles. - * @param {ShuffleItem[]} items Set to dispose. - * @private - */ - }, { - key: "_disposeItems", - value: function _disposeItems(items) { - items.forEach(function (item) { - item.dispose(); - }); - } - /** - * Updates the visible item count. - * @private - */ + return { + visible, + hidden + }; + } + /** + * Test an item to see if it passes a category. + * @param {string|string[]|function():boolean} category Category or function to filter by. + * @param {Element} element An element to test. + * @return {boolean} Whether it passes the category/filter. + * @private + */ - }, { - key: "_updateItemCount", - value: function _updateItemCount() { - this.visibleItems = this._getFilteredItems().length; - } - /** - * Sets css transform transition on a group of elements. This is not executed - * at the same time as `item.init` so that transitions don't occur upon - * initialization of a new Shuffle instance. - * @param {ShuffleItem[]} items Shuffle items to set transitions on. - * @protected - */ - }, { - key: "setItemTransitions", - value: function setItemTransitions(items) { - var _this$options = this.options, - speed = _this$options.speed, - easing = _this$options.easing; - var positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left']; // Allow users to transtion other properties if they exist in the `before` - // css mapping of the shuffle item. - - var cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(function (k) { - return hyphenate(k); - }); - var properties = positionProps.concat(cssProps).join(); - items.forEach(function (item) { - item.element.style.transitionDuration = speed + 'ms'; - item.element.style.transitionTimingFunction = easing; - item.element.style.transitionProperty = properties; - }); - } - }, { - key: "_getItems", - value: function _getItems() { - var _this3 = this; - - return Array.from(this.element.children).filter(function (el) { - return matchesSelector(el, _this3.options.itemSelector); - }).map(function (el) { - return new ShuffleItem(el); - }); - } - /** - * Combine the current items array with a new one and sort it by DOM order. - * @param {ShuffleItem[]} items Items to track. - * @return {ShuffleItem[]} - */ + _doesPassFilter(category, element) { + if (typeof category === 'function') { + return category.call(element, element, this); + } // Check each element's data-groups attribute against the given category. - }, { - key: "_mergeNewItems", - value: function _mergeNewItems(items) { - var children = Array.from(this.element.children); - return sorter(this.items.concat(items), { - by: function by(element) { - return children.indexOf(element); - } - }); - } - }, { - key: "_getFilteredItems", - value: function _getFilteredItems() { - return this.items.filter(function (item) { - return item.isVisible; - }); - } - }, { - key: "_getConcealedItems", - value: function _getConcealedItems() { - return this.items.filter(function (item) { - return !item.isVisible; - }); - } - /** - * Returns the column size, based on column width and sizer options. - * @param {number} containerWidth Size of the parent container. - * @param {number} gutterSize Size of the gutters. - * @return {number} - * @private - */ - }, { - key: "_getColumnSize", - value: function _getColumnSize(containerWidth, gutterSize) { - var size; // If the columnWidth property is a function, then the grid is fluid - - if (typeof this.options.columnWidth === 'function') { - size = this.options.columnWidth(containerWidth); // columnWidth option isn't a function, are they using a sizing element? - } else if (this.options.sizer) { - size = Shuffle.getSize(this.options.sizer).width; // if not, how about the explicitly set option? - } else if (this.options.columnWidth) { - size = this.options.columnWidth; // or use the size of the first item - } else if (this.items.length > 0) { - size = Shuffle.getSize(this.items[0].element, true).width; // if there's no items, use size of container - } else { - size = containerWidth; - } // Don't let them set a column width of zero. + const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY); + const keys = this.options.delimiter ? attr.split(this.options.delimiter) : JSON.parse(attr); + function testCategory(category) { + return keys.includes(category); + } - if (size === 0) { - size = containerWidth; + if (Array.isArray(category)) { + if (this.options.filterMode === Shuffle.FilterMode.ANY) { + return category.some(testCategory); } - return size + gutterSize; + return category.every(testCategory); } - /** - * Returns the gutter size, based on gutter width and sizer options. - * @param {number} containerWidth Size of the parent container. - * @return {number} - * @private - */ - }, { - key: "_getGutterSize", - value: function _getGutterSize(containerWidth) { - var size; + return keys.includes(category); + } + /** + * Toggles the visible and hidden class names. + * @param {{visible, hidden}} Object with visible and hidden arrays. + * @private + */ - if (typeof this.options.gutterWidth === 'function') { - size = this.options.gutterWidth(containerWidth); - } else if (this.options.sizer) { - size = getNumberStyle(this.options.sizer, 'marginLeft'); - } else { - size = this.options.gutterWidth; - } - return size; - } - /** - * Calculate the number of columns to be used. Gets css if using sizer element. - * @param {number} [containerWidth] Optionally specify a container width if - * it's already available. - */ + _toggleFilterClasses({ + visible, + hidden + }) { + visible.forEach(item => { + item.show(); + }); + hidden.forEach(item => { + item.hide(); + }); + } + /** + * Set the initial css for each item + * @param {ShuffleItem[]} items Set to initialize. + * @private + */ - }, { - key: "_setColumns", - value: function _setColumns() { - var containerWidth = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Shuffle.getSize(this.element).width; - var gutter = this._getGutterSize(containerWidth); + _initItems(items) { + items.forEach(item => { + item.init(); + }); + } + /** + * Remove element reference and styles. + * @param {ShuffleItem[]} items Set to dispose. + * @private + */ - var columnWidth = this._getColumnSize(containerWidth, gutter); - var calculatedColumns = (containerWidth + gutter) / columnWidth; // Widths given from getStyles are not precise enough... + _disposeItems(items) { + items.forEach(item => { + item.dispose(); + }); + } + /** + * Updates the visible item count. + * @private + */ - if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) < this.options.columnThreshold) { - // e.g. calculatedColumns = 11.998876 - calculatedColumns = Math.round(calculatedColumns); - } - this.cols = Math.max(Math.floor(calculatedColumns || 0), 1); - this.containerWidth = containerWidth; - this.colWidth = columnWidth; - } - /** - * Adjust the height of the grid - */ + _updateItemCount() { + this.visibleItems = this._getFilteredItems().length; + } + /** + * Sets css transform transition on a group of elements. This is not executed + * at the same time as `item.init` so that transitions don't occur upon + * initialization of a new Shuffle instance. + * @param {ShuffleItem[]} items Shuffle items to set transitions on. + * @protected + */ - }, { - key: "_setContainerSize", - value: function _setContainerSize() { - this.element.style.height = this._getContainerSize() + 'px'; - } - /** - * Based on the column heights, it returns the biggest one. - * @return {number} - * @private - */ - }, { - key: "_getContainerSize", - value: function _getContainerSize() { - return arrayMax(this.positions); - } - /** - * Get the clamped stagger amount. - * @param {number} index Index of the item to be staggered. - * @return {number} - */ + setItemTransitions(items) { + const { + speed, + easing + } = this.options; + const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left']; // Allow users to transtion other properties if they exist in the `before` + // css mapping of the shuffle item. + + const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map(k => hyphenate(k)); + const properties = positionProps.concat(cssProps).join(); + items.forEach(item => { + item.element.style.transitionDuration = speed + 'ms'; + item.element.style.transitionTimingFunction = easing; + item.element.style.transitionProperty = properties; + }); + } - }, { - key: "_getStaggerAmount", - value: function _getStaggerAmount(index) { - return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax); - } - /** - * Emit an event from this instance. - * @param {string} name Event name. - * @param {Object} [data={}] Optional object data. - */ + _getItems() { + return Array.from(this.element.children).filter(el => matchesSelector(el, this.options.itemSelector)).map(el => new ShuffleItem(el, this.options)); + } + /** + * Combine the current items array with a new one and sort it by DOM order. + * @param {ShuffleItem[]} items Items to track. + * @return {ShuffleItem[]} + */ - }, { - key: "_dispatch", - value: function _dispatch(name) { - var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - if (this.isDestroyed) { - return; + _mergeNewItems(items) { + const children = Array.from(this.element.children); + return sorter(this.items.concat(items), { + by(element) { + return children.indexOf(element); } - data.shuffle = this; - this.emit(name, data); - } - /** - * Zeros out the y columns array, which is used to determine item placement. - * @private - */ + }); + } - }, { - key: "_resetCols", - value: function _resetCols() { - var i = this.cols; - this.positions = []; + _getFilteredItems() { + return this.items.filter(item => item.isVisible); + } - while (i) { - i -= 1; - this.positions.push(0); - } - } - /** - * Loops through each item that should be shown and calculates the x, y position. - * @param {ShuffleItem[]} items Array of items that will be shown/layed - * out in order in their array. - */ + _getConcealedItems() { + return this.items.filter(item => !item.isVisible); + } + /** + * Returns the column size, based on column width and sizer options. + * @param {number} containerWidth Size of the parent container. + * @param {number} gutterSize Size of the gutters. + * @return {number} + * @private + */ - }, { - key: "_layout", - value: function _layout(items) { - var _this4 = this; - var itemPositions = this._getNextPositions(items); + _getColumnSize(containerWidth, gutterSize) { + let size; // If the columnWidth property is a function, then the grid is fluid - var count = 0; - items.forEach(function (item, i) { - function callback() { - item.applyCss(ShuffleItem.Css.VISIBLE.after); - } // If the item will not change its position, do not add it to the render - // queue. Transitions don't fire when setting a property to the same value. + if (typeof this.options.columnWidth === 'function') { + size = this.options.columnWidth(containerWidth); // columnWidth option isn't a function, are they using a sizing element? + } else if (this.options.sizer) { + size = Shuffle.getSize(this.options.sizer).width; // if not, how about the explicitly set option? + } else if (this.options.columnWidth) { + size = this.options.columnWidth; // or use the size of the first item + } else if (this.items.length > 0) { + size = Shuffle.getSize(this.items[0].element, true).width; // if there's no items, use size of container + } else { + size = containerWidth; + } // Don't let them set a column width of zero. - if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) { - item.applyCss(ShuffleItem.Css.VISIBLE.before); - callback(); - return; - } + if (size === 0) { + size = containerWidth; + } - item.point = itemPositions[i]; - item.scale = ShuffleItem.Scale.VISIBLE; - item.isHidden = false; // Clone the object so that the `before` object isn't modified when the - // transition delay is added. + return size + gutterSize; + } + /** + * Returns the gutter size, based on gutter width and sizer options. + * @param {number} containerWidth Size of the parent container. + * @return {number} + * @private + */ - var styles = _this4.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before); - styles.transitionDelay = _this4._getStaggerAmount(count) + 'ms'; + _getGutterSize(containerWidth) { + let size; - _this4._queue.push({ - item: item, - styles: styles, - callback: callback - }); - - count += 1; - }); + if (typeof this.options.gutterWidth === 'function') { + size = this.options.gutterWidth(containerWidth); + } else if (this.options.sizer) { + size = getNumberStyle(this.options.sizer, 'marginLeft'); + } else { + size = this.options.gutterWidth; } - /** - * Return an array of Point instances representing the future positions of - * each item. - * @param {ShuffleItem[]} items Array of sorted shuffle items. - * @return {Point[]} - * @private - */ - }, { - key: "_getNextPositions", - value: function _getNextPositions(items) { - var _this5 = this; + return size; + } + /** + * Calculate the number of columns to be used. Gets css if using sizer element. + * @param {number} [containerWidth] Optionally specify a container width if + * it's already available. + */ - // If position data is going to be changed, add the item's size to the - // transformer to allow for calculations. - if (this.options.isCentered) { - var itemsData = items.map(function (item, i) { - var itemSize = Shuffle.getSize(item.element, true); - var point = _this5._getItemPosition(itemSize); + _setColumns(containerWidth = Shuffle.getSize(this.element).width) { + const gutter = this._getGutterSize(containerWidth); - return new Rect(point.x, point.y, itemSize.width, itemSize.height, i); - }); - return this.getTransformedPositions(itemsData, this.containerWidth); - } // If no transforms are going to happen, simply return an array of the - // future points of each item. + const columnWidth = this._getColumnSize(containerWidth, gutter); + let calculatedColumns = (containerWidth + gutter) / columnWidth; // Widths given from getStyles are not precise enough... - return items.map(function (item) { - return _this5._getItemPosition(Shuffle.getSize(item.element, true)); - }); + if (Math.abs(Math.round(calculatedColumns) - calculatedColumns) < this.options.columnThreshold) { + // e.g. calculatedColumns = 11.998876 + calculatedColumns = Math.round(calculatedColumns); } - /** - * Determine the location of the next item, based on its size. - * @param {{width: number, height: number}} itemSize Object with width and height. - * @return {Point} - * @private - */ - }, { - key: "_getItemPosition", - value: function _getItemPosition(itemSize) { - return getItemPosition({ - itemSize: itemSize, - positions: this.positions, - gridSize: this.colWidth, - total: this.cols, - threshold: this.options.columnThreshold, - buffer: this.options.buffer - }); + this.cols = Math.max(Math.floor(calculatedColumns || 0), 1); + this.containerWidth = containerWidth; + this.colWidth = columnWidth; + } + /** + * Adjust the height of the grid + */ + + + _setContainerSize() { + this.element.style.height = this._getContainerSize() + 'px'; + } + /** + * Based on the column heights, it returns the biggest one. + * @return {number} + * @private + */ + + + _getContainerSize() { + return arrayMax(this.positions); + } + /** + * Get the clamped stagger amount. + * @param {number} index Index of the item to be staggered. + * @return {number} + */ + + + _getStaggerAmount(index) { + return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax); + } + /** + * Emit an event from this instance. + * @param {string} name Event name. + * @param {Object} [data={}] Optional object data. + */ + + + _dispatch(name, data = {}) { + if (this.isDestroyed) { + return; } - /** - * Mutate positions before they're applied. - * @param {Rect[]} itemRects Item data objects. - * @param {number} containerWidth Width of the containing element. - * @return {Point[]} - * @protected - */ - }, { - key: "getTransformedPositions", - value: function getTransformedPositions(itemRects, containerWidth) { - return getCenteredPositions(itemRects, containerWidth); + data.shuffle = this; + this.emit(name, data); + } + /** + * Zeros out the y columns array, which is used to determine item placement. + * @private + */ + + + _resetCols() { + let i = this.cols; + this.positions = []; + + while (i) { + i -= 1; + this.positions.push(0); } - /** - * Hides the elements that don't match our filter. - * @param {ShuffleItem[]} collection Collection to shrink. - * @private - */ + } + /** + * Loops through each item that should be shown and calculates the x, y position. + * @param {ShuffleItem[]} items Array of items that will be shown/layed + * out in order in their array. + */ - }, { - key: "_shrink", - value: function _shrink() { - var _this6 = this; - - var collection = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._getConcealedItems(); - var count = 0; - collection.forEach(function (item) { - function callback() { - item.applyCss(ShuffleItem.Css.HIDDEN.after); - } // Continuing would add a transitionend event listener to the element, but - // that listener would not execute because the transform and opacity would - // stay the same. - // The callback is executed here because it is not guaranteed to be called - // after the transitionend event because the transitionend could be - // canceled if another animation starts. - - - if (item.isHidden) { - item.applyCss(ShuffleItem.Css.HIDDEN.before); - callback(); - return; - } - item.scale = ShuffleItem.Scale.HIDDEN; - item.isHidden = true; + _layout(items) { + const itemPositions = this._getNextPositions(items); - var styles = _this6.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before); + let count = 0; + items.forEach((item, i) => { + function callback() { + item.applyCss(ShuffleItem.Css.VISIBLE.after); + } // If the item will not change its position, do not add it to the render + // queue. Transitions don't fire when setting a property to the same value. - styles.transitionDelay = _this6._getStaggerAmount(count) + 'ms'; - _this6._queue.push({ - item: item, - styles: styles, - callback: callback - }); + if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) { + item.applyCss(ShuffleItem.Css.VISIBLE.before); + callback(); + return; + } + + item.point = itemPositions[i]; + item.scale = ShuffleItem.Scale.VISIBLE; + item.isHidden = false; // Clone the object so that the `before` object isn't modified when the + // transition delay is added. - count += 1; + const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before); + styles.transitionDelay = this._getStaggerAmount(count) + 'ms'; + + this._queue.push({ + item, + styles, + callback }); - } - /** - * Resize handler. - * @private - */ - }, { - key: "_handleResize", - value: function _handleResize() { - // If shuffle is disabled, destroyed, don't do anything - if (!this.isEnabled || this.isDestroyed) { + count += 1; + }); + } + /** + * Return an array of Point instances representing the future positions of + * each item. + * @param {ShuffleItem[]} items Array of sorted shuffle items. + * @return {Point[]} + * @private + */ + + + _getNextPositions(items) { + // If position data is going to be changed, add the item's size to the + // transformer to allow for calculations. + if (this.options.isCentered) { + const itemsData = items.map((item, i) => { + const itemSize = Shuffle.getSize(item.element, true); + + const point = this._getItemPosition(itemSize); + + return new Rect(point.x, point.y, itemSize.width, itemSize.height, i); + }); + return this.getTransformedPositions(itemsData, this.containerWidth); + } // If no transforms are going to happen, simply return an array of the + // future points of each item. + + + return items.map(item => this._getItemPosition(Shuffle.getSize(item.element, true))); + } + /** + * Determine the location of the next item, based on its size. + * @param {{width: number, height: number}} itemSize Object with width and height. + * @return {Point} + * @private + */ + + + _getItemPosition(itemSize) { + return getItemPosition({ + itemSize, + positions: this.positions, + gridSize: this.colWidth, + total: this.cols, + threshold: this.options.columnThreshold, + buffer: this.options.buffer + }); + } + /** + * Mutate positions before they're applied. + * @param {Rect[]} itemRects Item data objects. + * @param {number} containerWidth Width of the containing element. + * @return {Point[]} + * @protected + */ + + + getTransformedPositions(itemRects, containerWidth) { + return getCenteredPositions(itemRects, containerWidth); + } + /** + * Hides the elements that don't match our filter. + * @param {ShuffleItem[]} collection Collection to shrink. + * @private + */ + + + _shrink(collection = this._getConcealedItems()) { + let count = 0; + collection.forEach(item => { + function callback() { + item.applyCss(ShuffleItem.Css.HIDDEN.after); + } // Continuing would add a transitionend event listener to the element, but + // that listener would not execute because the transform and opacity would + // stay the same. + // The callback is executed here because it is not guaranteed to be called + // after the transitionend event because the transitionend could be + // canceled if another animation starts. + + + if (item.isHidden) { + item.applyCss(ShuffleItem.Css.HIDDEN.before); + callback(); return; } - this.update(); + item.scale = ShuffleItem.Scale.HIDDEN; + item.isHidden = true; + const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before); + styles.transitionDelay = this._getStaggerAmount(count) + 'ms'; + + this._queue.push({ + item, + styles, + callback + }); + + count += 1; + }); + } + /** + * Resize handler. + * @private + */ + + + _handleResize() { + // If shuffle is disabled, destroyed, don't do anything + if (!this.isEnabled || this.isDestroyed) { + return; } - /** - * Returns styles which will be applied to the an item for a transition. - * @param {ShuffleItem} item Item to get styles for. Should have updated - * scale and point properties. - * @param {Object} styleObject Extra styles that will be used in the transition. - * @return {!Object} Transforms for transitions, left/top for animate. - * @protected - */ - }, { - key: "getStylesForTransition", - value: function getStylesForTransition(item, styleObject) { - // Clone the object to avoid mutating the original. - // eslint-disable-next-line prefer-object-spread - var styles = Object.assign({}, styleObject); - - if (this.options.useTransforms) { - var x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x; - var y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y; - styles.transform = "translate(".concat(x, "px, ").concat(y, "px) scale(").concat(item.scale, ")"); + this.update(); + } + /** + * Returns styles which will be applied to the an item for a transition. + * @param {ShuffleItem} item Item to get styles for. Should have updated + * scale and point properties. + * @param {Object} styleObject Extra styles that will be used in the transition. + * @return {!Object} Transforms for transitions, left/top for animate. + * @protected + */ + + + getStylesForTransition(item, styleObject) { + // Clone the object to avoid mutating the original. + // eslint-disable-next-line prefer-object-spread + const styles = Object.assign({}, styleObject); + + if (this.options.useTransforms) { + const sign = this.options.isRTL ? '-' : ''; + const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x; + const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y; + styles.transform = `translate(${sign}${x}px, ${y}px) scale(${item.scale})`; + } else { + if (this.options.isRTL) { + styles.right = item.point.x + 'px'; } else { styles.left = item.point.x + 'px'; - styles.top = item.point.y + 'px'; } - return styles; + styles.top = item.point.y + 'px'; } - /** - * Listen for the transition end on an element and execute the itemCallback - * when it finishes. - * @param {Element} element Element to listen on. - * @param {function} itemCallback Callback for the item. - * @param {function} done Callback to notify `parallel` that this one is done. - */ - }, { - key: "_whenTransitionDone", - value: function _whenTransitionDone(element, itemCallback, done) { - var id = onTransitionEnd(element, function (evt) { - itemCallback(); - done(null, evt); - }); + return styles; + } + /** + * Listen for the transition end on an element and execute the itemCallback + * when it finishes. + * @param {Element} element Element to listen on. + * @param {function} itemCallback Callback for the item. + * @param {function} done Callback to notify `parallel` that this one is done. + */ - this._transitions.push(id); - } - /** - * Return a function which will set CSS styles and call the `done` function - * when (if) the transition finishes. - * @param {Object} opts Transition object. - * @return {function} A function to be called with a `done` function. - */ - }, { - key: "_getTransitionFunction", - value: function _getTransitionFunction(opts) { - var _this7 = this; + _whenTransitionDone(element, itemCallback, done) { + const id = onTransitionEnd(element, evt => { + itemCallback(); + done(null, evt); + }); + + this._transitions.push(id); + } + /** + * Return a function which will set CSS styles and call the `done` function + * when (if) the transition finishes. + * @param {Object} opts Transition object. + * @return {function} A function to be called with a `done` function. + */ - return function (done) { - opts.item.applyCss(opts.styles); - _this7._whenTransitionDone(opts.item.element, opts.callback, done); - }; + _getTransitionFunction(opts) { + return done => { + opts.item.applyCss(opts.styles); + + this._whenTransitionDone(opts.item.element, opts.callback, done); + }; + } + /** + * Execute the styles gathered in the style queue. This applies styles to elements, + * triggering transitions. + * @private + */ + + + _processQueue() { + if (this.isTransitioning) { + this._cancelMovement(); } - /** - * Execute the styles gathered in the style queue. This applies styles to elements, - * triggering transitions. - * @private - */ - }, { - key: "_processQueue", - value: function _processQueue() { - if (this.isTransitioning) { - this._cancelMovement(); - } + const hasSpeed = this.options.speed > 0; + const hasQueue = this._queue.length > 0; - var hasSpeed = this.options.speed > 0; - var hasQueue = this._queue.length > 0; + if (hasQueue && hasSpeed && this.isInitialized) { + this._startTransitions(this._queue); + } else if (hasQueue) { + this._styleImmediately(this._queue); - if (hasQueue && hasSpeed && this.isInitialized) { - this._startTransitions(this._queue); - } else if (hasQueue) { - this._styleImmediately(this._queue); + this._dispatch(Shuffle.EventType.LAYOUT); // A call to layout happened, but none of the newly visible items will + // change position or the transition duration is zero, which will not trigger + // the transitionend event. - this._dispatch(Shuffle.EventType.LAYOUT); // A call to layout happened, but none of the newly visible items will - // change position or the transition duration is zero, which will not trigger - // the transitionend event. + } else { + this._dispatch(Shuffle.EventType.LAYOUT); + } // Remove everything in the style queue - } else { - this._dispatch(Shuffle.EventType.LAYOUT); - } // Remove everything in the style queue + this._queue.length = 0; + } + /** + * Wait for each transition to finish, the emit the layout event. + * @param {Object[]} transitions Array of transition objects. + */ - this._queue.length = 0; - } - /** - * Wait for each transition to finish, the emit the layout event. - * @param {Object[]} transitions Array of transition objects. - */ - }, { - key: "_startTransitions", - value: function _startTransitions(transitions) { - var _this8 = this; + _startTransitions(transitions) { + // Set flag that shuffle is currently in motion. + this.isTransitioning = true; // Create an array of functions to be called. - // Set flag that shuffle is currently in motion. - this.isTransitioning = true; // Create an array of functions to be called. + const callbacks = transitions.map(obj => this._getTransitionFunction(obj)); + arrayParallel(callbacks, this._movementFinished.bind(this)); + } - var callbacks = transitions.map(function (obj) { - return _this8._getTransitionFunction(obj); - }); - arrayParallel(callbacks, this._movementFinished.bind(this)); - } - }, { - key: "_cancelMovement", - value: function _cancelMovement() { - // Remove the transition end event for each listener. - this._transitions.forEach(cancelTransitionEnd); // Reset the array. + _cancelMovement() { + // Remove the transition end event for each listener. + this._transitions.forEach(cancelTransitionEnd); // Reset the array. - this._transitions.length = 0; // Show it's no longer active. + this._transitions.length = 0; // Show it's no longer active. - this.isTransitioning = false; - } - /** - * Apply styles without a transition. - * @param {Object[]} objects Array of transition objects. - * @private - */ + this.isTransitioning = false; + } + /** + * Apply styles without a transition. + * @param {Object[]} objects Array of transition objects. + * @private + */ - }, { - key: "_styleImmediately", - value: function _styleImmediately(objects) { - if (objects.length) { - var elements = objects.map(function (obj) { - return obj.item.element; - }); - Shuffle._skipTransitions(elements, function () { - objects.forEach(function (obj) { - obj.item.applyCss(obj.styles); - obj.callback(); - }); + _styleImmediately(objects) { + if (objects.length) { + const elements = objects.map(obj => obj.item.element); + + Shuffle._skipTransitions(elements, () => { + objects.forEach(obj => { + obj.item.applyCss(obj.styles); + obj.callback(); }); - } + }); } - }, { - key: "_movementFinished", - value: function _movementFinished() { - this._transitions.length = 0; - this.isTransitioning = false; + } - this._dispatch(Shuffle.EventType.LAYOUT); + _movementFinished() { + this._transitions.length = 0; + this.isTransitioning = false; + + this._dispatch(Shuffle.EventType.LAYOUT); + } + /** + * The magic. This is what makes the plugin 'shuffle' + * @param {string|string[]|function(Element):boolean} [category] Category to filter by. + * Can be a function, string, or array of strings. + * @param {SortOptions} [sortOptions] A sort object which can sort the visible set + */ + + + filter(category, sortOptions) { + if (!this.isEnabled) { + return; } - /** - * The magic. This is what makes the plugin 'shuffle' - * @param {string|string[]|function(Element):boolean} [category] Category to filter by. - * Can be a function, string, or array of strings. - * @param {SortOptions} [sortOptions] A sort object which can sort the visible set - */ - }, { - key: "filter", - value: function filter(category, sortOptions) { - if (!this.isEnabled) { - return; - } + if (!category || category && category.length === 0) { + category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign + } - if (!category || category && category.length === 0) { - category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign - } + this._filter(category); // Shrink each hidden item - this._filter(category); // Shrink each hidden item + this._shrink(); // How many visible elements? - this._shrink(); // How many visible elements? + this._updateItemCount(); // Update transforms on visible elements so they will animate to their new positions. - this._updateItemCount(); // Update transforms on visible elements so they will animate to their new positions. + + this.sort(sortOptions); + } + /** + * Gets the visible elements, sorts them, and passes them to layout. + * @param {SortOptions} [sortOptions] The options object to pass to `sorter`. + */ - this.sort(sortOptions); + sort(sortOptions = this.lastSort) { + if (!this.isEnabled) { + return; } - /** - * Gets the visible elements, sorts them, and passes them to layout. - * @param {SortOptions} [sortOptions] The options object to pass to `sorter`. - */ - }, { - key: "sort", - value: function sort() { - var sortOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.lastSort; + this._resetCols(); - if (!this.isEnabled) { - return; - } + const items = sorter(this._getFilteredItems(), sortOptions); - this._resetCols(); + this._layout(items); // `_layout` always happens after `_shrink`, so it's safe to process the style + // queue here with styles from the shrink method. - var items = sorter(this._getFilteredItems(), sortOptions); - this._layout(items); // `_layout` always happens after `_shrink`, so it's safe to process the style - // queue here with styles from the shrink method. + this._processQueue(); // Adjust the height of the container. - this._processQueue(); // Adjust the height of the container. + this._setContainerSize(); + this.lastSort = sortOptions; + } + /** + * Reposition everything. + * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated. + */ - this._setContainerSize(); - this.lastSort = sortOptions; + update(isOnlyLayout = false) { + if (this.isEnabled) { + if (!isOnlyLayout) { + // Get updated colCount + this._setColumns(); + } // Layout items + + + this.sort(); } - /** - * Reposition everything. - * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated. - */ + } + /** + * Use this instead of `update()` if you don't need the columns and gutters updated + * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations + * could be off. + */ - }, { - key: "update", - value: function update() { - var isOnlyLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - if (this.isEnabled) { - if (!isOnlyLayout) { - // Get updated colCount - this._setColumns(); - } // Layout items + layout() { + this.update(true); + } + /** + * New items have been appended to shuffle. Mix them in with the current + * filter or sort status. + * @param {Element[]} newItems Collection of new items. + */ - this.sort(); - } - } - /** - * Use this instead of `update()` if you don't need the columns and gutters updated - * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations - * could be off. - */ + add(newItems) { + const items = arrayUnique(newItems).map(el => new ShuffleItem(el, this.options)); // Add classes and set initial positions. - }, { - key: "layout", - value: function layout() { - this.update(true); - } - /** - * New items have been appended to shuffle. Mix them in with the current - * filter or sort status. - * @param {Element[]} newItems Collection of new items. - */ + this._initItems(items); // Determine which items will go with the current filter. - }, { - key: "add", - value: function add(newItems) { - var _this9 = this; - var items = arrayUnique(newItems).map(function (el) { - return new ShuffleItem(el); - }); // Add classes and set initial positions. + this._resetCols(); - this._initItems(items); // Determine which items will go with the current filter. + const allItems = this._mergeNewItems(items); + const sortedItems = sorter(allItems, this.lastSort); - this._resetCols(); + const allSortedItemsSet = this._filter(this.lastFilter, sortedItems); - var allItems = this._mergeNewItems(items); + const isNewItem = item => items.includes(item); - var sortedItems = sorter(allItems, this.lastSort); + const applyHiddenState = item => { + item.scale = ShuffleItem.Scale.HIDDEN; + item.isHidden = true; + item.applyCss(ShuffleItem.Css.HIDDEN.before); + item.applyCss(ShuffleItem.Css.HIDDEN.after); + }; // Layout all items again so that new items get positions. + // Synchonously apply positions. - var allSortedItemsSet = this._filter(this.lastFilter, sortedItems); - var isNewItem = function isNewItem(item) { - return items.includes(item); - }; + const itemPositions = this._getNextPositions(allSortedItemsSet.visible); - var applyHiddenState = function applyHiddenState(item) { - item.scale = ShuffleItem.Scale.HIDDEN; - item.isHidden = true; - item.applyCss(ShuffleItem.Css.HIDDEN.before); - item.applyCss(ShuffleItem.Css.HIDDEN.after); - }; // Layout all items again so that new items get positions. - // Synchonously apply positions. + allSortedItemsSet.visible.forEach((item, i) => { + if (isNewItem(item)) { + item.point = itemPositions[i]; + applyHiddenState(item); + item.applyCss(this.getStylesForTransition(item, {})); + } + }); + allSortedItemsSet.hidden.forEach(item => { + if (isNewItem(item)) { + applyHiddenState(item); + } + }); // Cause layout so that the styles above are applied. + this.element.offsetWidth; // eslint-disable-line no-unused-expressions + // Add transition to each item. - var itemPositions = this._getNextPositions(allSortedItemsSet.visible); + this.setItemTransitions(items); // Update the list of items. - allSortedItemsSet.visible.forEach(function (item, i) { - if (isNewItem(item)) { - item.point = itemPositions[i]; - applyHiddenState(item); - item.applyCss(_this9.getStylesForTransition(item, {})); - } - }); - allSortedItemsSet.hidden.forEach(function (item) { - if (isNewItem(item)) { - applyHiddenState(item); - } - }); // Cause layout so that the styles above are applied. + this.items = this._mergeNewItems(items); // Update layout/visibility of new and old items. - this.element.offsetWidth; // eslint-disable-line no-unused-expressions - // Add transition to each item. + this.filter(this.lastFilter); + } + /** + * Disables shuffle from updating dimensions and layout on resize + */ - this.setItemTransitions(items); // Update the list of items. - this.items = this._mergeNewItems(items); // Update layout/visibility of new and old items. + disable() { + this.isEnabled = false; + } + /** + * Enables shuffle again + * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters + */ - this.filter(this.lastFilter); - } - /** - * Disables shuffle from updating dimensions and layout on resize - */ - }, { - key: "disable", - value: function disable() { - this.isEnabled = false; + enable(isUpdateLayout = true) { + this.isEnabled = true; + + if (isUpdateLayout) { + this.update(); } - /** - * Enables shuffle again - * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters - */ + } + /** + * Remove 1 or more shuffle items. + * @param {Element[]} elements An array containing one or more + * elements in shuffle + * @return {Shuffle} The shuffle instance. + */ - }, { - key: "enable", - value: function enable() { - var isUpdateLayout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - this.isEnabled = true; - if (isUpdateLayout) { - this.update(); - } + remove(elements) { + if (!elements.length) { + return; } - /** - * Remove 1 or more shuffle items. - * @param {Element[]} elements An array containing one or more - * elements in shuffle - * @return {Shuffle} The shuffle instance. - */ - }, { - key: "remove", - value: function remove(elements) { - var _this10 = this; + const collection = arrayUnique(elements); + const oldItems = collection.map(element => this.getItemByElement(element)).filter(item => !!item); - if (!elements.length) { - return; - } + const handleLayout = () => { + this._disposeItems(oldItems); // Remove the collection in the callback - var collection = arrayUnique(elements); - var oldItems = collection.map(function (element) { - return _this10.getItemByElement(element); - }).filter(function (item) { - return !!item; + + collection.forEach(element => { + element.parentNode.removeChild(element); }); - var handleLayout = function handleLayout() { - _this10._disposeItems(oldItems); // Remove the collection in the callback + this._dispatch(Shuffle.EventType.REMOVED, { + collection + }); + }; // Hide collection first. - collection.forEach(function (element) { - element.parentNode.removeChild(element); - }); + this._toggleFilterClasses({ + visible: [], + hidden: oldItems + }); - _this10._dispatch(Shuffle.EventType.REMOVED, { - collection: collection - }); - }; // Hide collection first. + this._shrink(oldItems); + this.sort(); // Update the list of items here because `remove` could be called again + // with an item that is in the process of being removed. - this._toggleFilterClasses({ - visible: [], - hidden: oldItems - }); + this.items = this.items.filter(item => !oldItems.includes(item)); - this._shrink(oldItems); + this._updateItemCount(); - this.sort(); // Update the list of items here because `remove` could be called again - // with an item that is in the process of being removed. + this.once(Shuffle.EventType.LAYOUT, handleLayout); + } + /** + * Retrieve a shuffle item by its element. + * @param {Element} element Element to look for. + * @return {?ShuffleItem} A shuffle item or undefined if it's not found. + */ - this.items = this.items.filter(function (item) { - return !oldItems.includes(item); - }); - this._updateItemCount(); + getItemByElement(element) { + return this.items.find(item => item.element === element); + } + /** + * Dump the elements currently stored and reinitialize all child elements which + * match the `itemSelector`. + */ - this.once(Shuffle.EventType.LAYOUT, handleLayout); - } - /** - * Retrieve a shuffle item by its element. - * @param {Element} element Element to look for. - * @return {?ShuffleItem} A shuffle item or undefined if it's not found. - */ - }, { - key: "getItemByElement", - value: function getItemByElement(element) { - return this.items.find(function (item) { - return item.element === element; - }); - } - /** - * Dump the elements currently stored and reinitialize all child elements which - * match the `itemSelector`. - */ + resetItems() { + // Remove refs to current items. + this._disposeItems(this.items); + + this.isInitialized = false; // Find new items in the DOM. - }, { - key: "resetItems", - value: function resetItems() { - var _this11 = this; + this.items = this._getItems(); // Set initial styles on the new items. - // Remove refs to current items. - this._disposeItems(this.items); + this._initItems(this.items); - this.isInitialized = false; // Find new items in the DOM. + this.once(Shuffle.EventType.LAYOUT, () => { + // Add transition to each item. + this.setItemTransitions(this.items); + this.isInitialized = true; + }); // Lay out all items. - this.items = this._getItems(); // Set initial styles on the new items. + this.filter(this.lastFilter); + } + /** + * Destroys shuffle, removes events, styles, and classes + */ - this._initItems(this.items); - this.once(Shuffle.EventType.LAYOUT, function () { - // Add transition to each item. - _this11.setItemTransitions(_this11.items); + destroy() { + this._cancelMovement(); - _this11.isInitialized = true; - }); // Lay out all items. + window.removeEventListener('resize', this._onResize); // Reset container styles - this.filter(this.lastFilter); - } - /** - * Destroys shuffle, removes events, styles, and classes - */ + this.element.classList.remove('shuffle'); + this.element.removeAttribute('style'); // Reset individual item styles - }, { - key: "destroy", - value: function destroy() { - this._cancelMovement(); + this._disposeItems(this.items); - window.removeEventListener('resize', this._onResize); // Reset container styles + this.items.length = 0; + this._transitions.length = 0; // Null DOM references - this.element.classList.remove('shuffle'); - this.element.removeAttribute('style'); // Reset individual item styles + this.options.sizer = null; + this.element = null; // Set a flag so if a debounced resize has been triggered, + // it can first check if it is actually isDestroyed and not doing anything - this._disposeItems(this.items); + this.isDestroyed = true; + this.isEnabled = false; + } + /** + * Returns the outer width of an element, optionally including its margins. + * + * There are a few different methods for getting the width of an element, none of + * which work perfectly for all Shuffle's use cases. + * + * 1. getBoundingClientRect() `left` and `right` properties. + * - Accounts for transform scaled elements, making it useless for Shuffle + * elements which have shrunk. + * 2. The `offsetWidth` property. + * - This value stays the same regardless of the elements transform property, + * however, it does not return subpixel values. + * 3. getComputedStyle() + * - This works great Chrome, Firefox, Safari, but IE<=11 does not include + * padding and border when box-sizing: border-box is set, requiring a feature + * test and extra work to add the padding back for IE and other browsers which + * follow the W3C spec here. + * + * @param {Element} element The element. + * @param {boolean} [includeMargins=false] Whether to include margins. + * @return {{width: number, height: number}} The width and height. + */ - this.items.length = 0; - this._transitions.length = 0; // Null DOM references - this.options.sizer = null; - this.element = null; // Set a flag so if a debounced resize has been triggered, - // it can first check if it is actually isDestroyed and not doing anything + static getSize(element, includeMargins = false) { + // Store the styles so that they can be used by others without asking for it again. + const styles = window.getComputedStyle(element, null); + let width = getNumberStyle(element, 'width', styles); + let height = getNumberStyle(element, 'height', styles); - this.isDestroyed = true; - this.isEnabled = false; + if (includeMargins) { + const marginLeft = getNumberStyle(element, 'marginLeft', styles); + const marginRight = getNumberStyle(element, 'marginRight', styles); + const marginTop = getNumberStyle(element, 'marginTop', styles); + const marginBottom = getNumberStyle(element, 'marginBottom', styles); + width += marginLeft + marginRight; + height += marginTop + marginBottom; } - /** - * Returns the outer width of an element, optionally including its margins. - * - * There are a few different methods for getting the width of an element, none of - * which work perfectly for all Shuffle's use cases. - * - * 1. getBoundingClientRect() `left` and `right` properties. - * - Accounts for transform scaled elements, making it useless for Shuffle - * elements which have shrunk. - * 2. The `offsetWidth` property. - * - This value stays the same regardless of the elements transform property, - * however, it does not return subpixel values. - * 3. getComputedStyle() - * - This works great Chrome, Firefox, Safari, but IE<=11 does not include - * padding and border when box-sizing: border-box is set, requiring a feature - * test and extra work to add the padding back for IE and other browsers which - * follow the W3C spec here. - * - * @param {Element} element The element. - * @param {boolean} [includeMargins=false] Whether to include margins. - * @return {{width: number, height: number}} The width and height. - */ - }], [{ - key: "getSize", - value: function getSize(element) { - var includeMargins = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - // Store the styles so that they can be used by others without asking for it again. - var styles = window.getComputedStyle(element, null); - var width = getNumberStyle(element, 'width', styles); - var height = getNumberStyle(element, 'height', styles); - - if (includeMargins) { - var marginLeft = getNumberStyle(element, 'marginLeft', styles); - var marginRight = getNumberStyle(element, 'marginRight', styles); - var marginTop = getNumberStyle(element, 'marginTop', styles); - var marginBottom = getNumberStyle(element, 'marginBottom', styles); - width += marginLeft + marginRight; - height += marginTop + marginBottom; - } + return { + width, + height + }; + } + /** + * Change a property or execute a function which will not have a transition + * @param {Element[]} elements DOM elements that won't be transitioned. + * @param {function} callback A function which will be called while transition + * is set to 0ms. + * @private + */ + + + static _skipTransitions(elements, callback) { + const zero = '0ms'; // Save current duration and delay. + const data = elements.map(element => { + const { + style + } = element; + const duration = style.transitionDuration; + const delay = style.transitionDelay; // Set the duration to zero so it happens immediately + + style.transitionDuration = zero; + style.transitionDelay = zero; return { - width: width, - height: height + duration, + delay }; - } - /** - * Change a property or execute a function which will not have a transition - * @param {Element[]} elements DOM elements that won't be transitioned. - * @param {function} callback A function which will be called while transition - * is set to 0ms. - * @private - */ - - }, { - key: "_skipTransitions", - value: function _skipTransitions(elements, callback) { - var zero = '0ms'; // Save current duration and delay. - - var data = elements.map(function (element) { - var style = element.style; - var duration = style.transitionDuration; - var delay = style.transitionDelay; // Set the duration to zero so it happens immediately - - style.transitionDuration = zero; - style.transitionDelay = zero; - return { - duration: duration, - delay: delay - }; - }); - callback(); // Cause forced synchronous layout. + }); + callback(); // Cause forced synchronous layout. - elements[0].offsetWidth; // eslint-disable-line no-unused-expressions - // Put the duration back + elements[0].offsetWidth; // eslint-disable-line no-unused-expressions + // Put the duration back - elements.forEach(function (element, i) { - element.style.transitionDuration = data[i].duration; - element.style.transitionDelay = data[i].delay; - }); - } - }]); + elements.forEach((element, i) => { + element.style.transitionDuration = data[i].duration; + element.style.transitionDelay = data[i].delay; + }); + } - return Shuffle; - }(tinyEmitter); + } Shuffle.ShuffleItem = ShuffleItem; Shuffle.ALL_ITEMS = 'all'; @@ -2198,6 +1950,8 @@ filterMode: Shuffle.FilterMode.ANY, // Attempt to center grid items in each row. isCentered: false, + // Attempt to align grid items to right. + isRTL: false, // Whether to round pixel values used in translate(x, y). This usually avoids // blurriness. roundTransforms: true diff --git a/dist/shuffle.js.map b/dist/shuffle.js.map index 38ab889..f87ccf3 100644 --- a/dist/shuffle.js.map +++ b/dist/shuffle.js.map @@ -1 +1 @@ -{"version":3,"file":"shuffle.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/matches-selector/index.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/rect.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/array-min.js","../src/layout.js","../src/hyphenate.js","../src/shuffle.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n","'use strict';\n\nvar proto = typeof Element !== 'undefined' ? Element.prototype : {};\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (!el || el.nodeType !== 1) return false;\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default class Rect {\n /**\n * Class for representing rectangular regions.\n * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js\n * @param {number} x Left.\n * @param {number} y Top.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} id Identifier\n * @constructor\n */\n constructor(x, y, w, h, id) {\n this.id = id;\n\n /** @type {number} */\n this.left = x;\n\n /** @type {number} */\n this.top = y;\n\n /** @type {number} */\n this.width = w;\n\n /** @type {number} */\n this.height = h;\n }\n\n /**\n * Returns whether two rectangles intersect.\n * @param {Rect} a A Rectangle.\n * @param {Rect} b A Rectangle.\n * @return {boolean} Whether a and b intersect.\n */\n static intersects(a, b) {\n return (\n a.left < b.left + b.width && b.left < a.left + a.width\n && a.top < b.top + b.height && b.top < a.top + a.height);\n }\n}\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Used to separate items for layout and shrink.\n */\n this.isVisible = true;\n\n /**\n * Used to determine if a transition will happen. By the time the _layout\n * and _shrink methods get the ShuffleItem instances, the `isVisible` value\n * has already been changed by the separation methods, so this property is\n * needed to know if the item was visible/hidden before the shrink/layout.\n */\n this.isHidden = false;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n this.element.removeAttribute('aria-hidden');\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n this.element.setAttribute('aria-hidden', true);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n willChange: 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {\n transitionDelay: '',\n },\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n transitionDelay: '',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","let value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n value = window.getComputedStyle(e, null).width === '10px';\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft)\n + getNumber(styles.paddingRight)\n + getNumber(styles.borderLeftWidth)\n + getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop)\n + getNumber(styles.paddingBottom)\n + getNumber(styles.borderTopWidth)\n + getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n/**\n * You can return `undefined` from the `by` function to revert to DOM order.\n * @param {Array} arr Array to sort.\n * @param {SortOptions} options Sorting options.\n * @return {Array}\n */\nexport default function sorter(arr, options) {\n // eslint-disable-next-line prefer-object-spread\n const opts = Object.assign({}, defaults, options);\n const original = Array.from(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n } else if (typeof opts.compare === 'function') {\n arr.sort(opts.compare);\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport Rect from './rect';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 10]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 10]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({\n itemSize, positions, gridSize, total, threshold, buffer,\n}) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]);\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n\n/**\n * This method attempts to center items. This method could potentially be slow\n * with a large number of items because it must place items, then check every\n * previous item to ensure there is no overlap.\n * @param {Array.} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Array.}\n */\nexport function getCenteredPositions(itemRects, containerWidth) {\n const rowMap = {};\n\n // Populate rows by their offset because items could jump between rows like:\n // a c\n // bbb\n itemRects.forEach((itemRect) => {\n if (rowMap[itemRect.top]) {\n // Push the point to the last row array.\n rowMap[itemRect.top].push(itemRect);\n } else {\n // Start of a new row.\n rowMap[itemRect.top] = [itemRect];\n }\n });\n\n // For each row, find the end of the last item, then calculate\n // the remaining space by dividing it by 2. Then add that\n // offset to the x position of each point.\n let rects = [];\n const rows = [];\n const centeredRows = [];\n Object.keys(rowMap).forEach((key) => {\n const itemRects = rowMap[key];\n rows.push(itemRects);\n const lastItem = itemRects[itemRects.length - 1];\n const end = lastItem.left + lastItem.width;\n const offset = Math.round((containerWidth - end) / 2);\n\n let finalRects = itemRects;\n let canMove = false;\n if (offset > 0) {\n const newRects = [];\n canMove = itemRects.every((r) => {\n const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id);\n\n // Check all current rects to make sure none overlap.\n const noOverlap = !rects.some((r) => Rect.intersects(newRect, r));\n\n newRects.push(newRect);\n return noOverlap;\n });\n\n // If none of the rectangles overlapped, the whole group can be centered.\n if (canMove) {\n finalRects = newRects;\n }\n }\n\n // If the items are not going to be offset, ensure that the original\n // placement for this row will not overlap previous rows (row-spanning\n // elements could be in the way).\n if (!canMove) {\n let intersectingRect;\n const hasOverlap = itemRects.some((itemRect) => rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }));\n\n // If there is any overlap, replace the overlapping row with the original.\n if (hasOverlap) {\n const rowIndex = centeredRows.findIndex((items) => items.includes(intersectingRect));\n centeredRows.splice(rowIndex, 1, rows[rowIndex]);\n }\n }\n\n rects = rects.concat(finalRects);\n centeredRows.push(finalRects);\n });\n\n // Reduce array of arrays to a single array of points.\n // https://stackoverflow.com/a/10865042/373422\n // Then reset sort back to how the items were passed to this method.\n // Remove the wrapper object with index, map to a Point.\n return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread\n .sort((a, b) => (a.id - b.id))\n .map((itemRect) => new Point(itemRect.left, itemRect.top));\n}\n","/**\n * Hyphenates a javascript style string to a css one. For example:\n * MozBoxSizing -> -moz-box-sizing.\n * @param {string} str The string to hyphenate.\n * @return {string} The hyphenated string.\n */\nexport default function hyphenate(str) {\n return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`);\n}\n","import TinyEmitter from 'tiny-emitter';\nimport matches from 'matches-selector';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\n\nimport Point from './point';\nimport Rect from './rect';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport {\n getItemPosition,\n getColumnSpan,\n getAvailablePositions,\n getShortColumn,\n getCenteredPositions,\n} from './layout';\nimport arrayMax from './array-max';\nimport hyphenate from './hyphenate';\n\nfunction arrayUnique(x) {\n return Array.from(new Set(x));\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle extends TinyEmitter {\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n super();\n // eslint-disable-next-line prefer-object-spread\n this.options = Object.assign({}, Shuffle.options, options);\n\n // Allow misspelling of delimiter since that's how it used to be.\n // Remove in v6.\n if (this.options.delimeter) {\n this.options.delimiter = this.options.delimeter;\n }\n\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems(this.items);\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // If the page has not already emitted the `load` event, call layout on load.\n // This avoids layout issues caused by images and fonts loading after the\n // instance has been initialized.\n if (document.readyState !== 'complete') {\n const layout = this.layout.bind(this);\n window.addEventListener('load', function onLoad() {\n window.removeEventListener('load', onLoad);\n layout();\n });\n }\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this.setItemTransitions(this.items);\n this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle\n ? this.options.throttle(resizeFunction, this.options.throttleTime)\n : resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n }\n\n // Check for an element\n if (option && option.nodeType && option.nodeType === 1) {\n return option;\n }\n\n // Check for jQuery object\n if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string|string[]|function(Element):boolean} [category] Category to\n * filter by. If it's given, the last category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|string[]|function(Element):boolean} category Category or function to filter by.\n * @param {ShuffleItem[]} items A collection of items to filter.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|string[]|function():boolean} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n }\n\n // Check each element's data-groups attribute against the given category.\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimiter\n ? attr.split(this.options.delimiter)\n : JSON.parse(attr);\n\n function testCategory(category) {\n return keys.includes(category);\n }\n\n if (Array.isArray(category)) {\n if (this.options.filterMode === Shuffle.FilterMode.ANY) {\n return category.some(testCategory);\n }\n return category.every(testCategory);\n }\n\n return keys.includes(category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {ShuffleItem[]} items Set to initialize.\n * @private\n */\n _initItems(items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @param {ShuffleItem[]} items Set to dispose.\n * @private\n */\n _disposeItems(items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of a new Shuffle instance.\n * @param {ShuffleItem[]} items Shuffle items to set transitions on.\n * @protected\n */\n setItemTransitions(items) {\n const { speed, easing } = this.options;\n const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left'];\n\n // Allow users to transtion other properties if they exist in the `before`\n // css mapping of the shuffle item.\n const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map((k) => hyphenate(k));\n const properties = positionProps.concat(cssProps).join();\n\n items.forEach((item) => {\n item.element.style.transitionDuration = speed + 'ms';\n item.element.style.transitionTimingFunction = easing;\n item.element.style.transitionProperty = properties;\n });\n }\n\n _getItems() {\n return Array.from(this.element.children)\n .filter((el) => matches(el, this.options.itemSelector))\n .map((el) => new ShuffleItem(el));\n }\n\n /**\n * Combine the current items array with a new one and sort it by DOM order.\n * @param {ShuffleItem[]} items Items to track.\n * @return {ShuffleItem[]}\n */\n _mergeNewItems(items) {\n const children = Array.from(this.element.children);\n return sorter(this.items.concat(items), {\n by(element) {\n return children.indexOf(element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter((item) => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter((item) => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.options.sizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.options.sizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns)\n < this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns || 0), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * Emit an event from this instance.\n * @param {string} name Event name.\n * @param {Object} [data={}] Optional object data.\n */\n _dispatch(name, data = {}) {\n if (this.isDestroyed) {\n return;\n }\n\n data.shuffle = this;\n this.emit(name, data);\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {ShuffleItem[]} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n const itemPositions = this._getNextPositions(items);\n\n let count = 0;\n items.forEach((item, i) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = itemPositions[i];\n item.scale = ShuffleItem.Scale.VISIBLE;\n item.isHidden = false;\n\n // Clone the object so that the `before` object isn't modified when the\n // transition delay is added.\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Return an array of Point instances representing the future positions of\n * each item.\n * @param {ShuffleItem[]} items Array of sorted shuffle items.\n * @return {Point[]}\n * @private\n */\n _getNextPositions(items) {\n // If position data is going to be changed, add the item's size to the\n // transformer to allow for calculations.\n if (this.options.isCentered) {\n const itemsData = items.map((item, i) => {\n const itemSize = Shuffle.getSize(item.element, true);\n const point = this._getItemPosition(itemSize);\n return new Rect(point.x, point.y, itemSize.width, itemSize.height, i);\n });\n\n return this.getTransformedPositions(itemsData, this.containerWidth);\n }\n\n // If no transforms are going to happen, simply return an array of the\n // future points of each item.\n return items.map((item) => this._getItemPosition(Shuffle.getSize(item.element, true)));\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Mutate positions before they're applied.\n * @param {Rect[]} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Point[]}\n * @protected\n */\n getTransformedPositions(itemRects, containerWidth) {\n return getCenteredPositions(itemRects, containerWidth);\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {ShuffleItem[]} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.isHidden) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {ShuffleItem} item Item to get styles for. Should have updated\n * scale and point properties.\n * @param {Object} styleObject Extra styles that will be used in the transition.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @protected\n */\n getStylesForTransition(item, styleObject) {\n // Clone the object to avoid mutating the original.\n // eslint-disable-next-line prefer-object-spread\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x;\n const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y;\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = item.point.x + 'px';\n styles.top = item.point.y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {function} itemCallback Callback for the item.\n * @param {function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(opts.styles);\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatch(Shuffle.EventType.LAYOUT);\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Object[]} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map((obj) => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Object[]} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map((obj) => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(obj.styles);\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|string[]|function(Element):boolean} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {SortOptions} [sortOptions] A sort object which can sort the visible set\n */\n filter(category, sortOptions) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortOptions);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {SortOptions} [sortOptions] The options object to pass to `sorter`.\n */\n sort(sortOptions = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n const items = sorter(this._getFilteredItems(), sortOptions);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = sortOptions;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated.\n */\n update(isOnlyLayout = false) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Element[]} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map((el) => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Determine which items will go with the current filter.\n this._resetCols();\n\n const allItems = this._mergeNewItems(items);\n const sortedItems = sorter(allItems, this.lastSort);\n const allSortedItemsSet = this._filter(this.lastFilter, sortedItems);\n\n const isNewItem = (item) => items.includes(item);\n const applyHiddenState = (item) => {\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n };\n\n // Layout all items again so that new items get positions.\n // Synchonously apply positions.\n const itemPositions = this._getNextPositions(allSortedItemsSet.visible);\n allSortedItemsSet.visible.forEach((item, i) => {\n if (isNewItem(item)) {\n item.point = itemPositions[i];\n applyHiddenState(item);\n item.applyCss(this.getStylesForTransition(item, {}));\n }\n });\n\n allSortedItemsSet.hidden.forEach((item) => {\n if (isNewItem(item)) {\n applyHiddenState(item);\n }\n });\n\n // Cause layout so that the styles above are applied.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Add transition to each item.\n this.setItemTransitions(items);\n\n // Update the list of items.\n this.items = this._mergeNewItems(items);\n\n // Update layout/visibility of new and old items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout = true) {\n this.isEnabled = true;\n if (isUpdateLayout) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items.\n * @param {Element[]} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle instance.\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map((element) => this.getItemByElement(element))\n .filter((item) => !!item);\n\n const handleLayout = () => {\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter((item) => !oldItems.includes(item));\n this._updateItemCount();\n\n this.once(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or undefined if it's not found.\n */\n getItemByElement(element) {\n return this.items.find((item) => item.element === element);\n }\n\n /**\n * Dump the elements currently stored and reinitialize all child elements which\n * match the `itemSelector`.\n */\n resetItems() {\n // Remove refs to current items.\n this._disposeItems(this.items);\n this.isInitialized = false;\n\n // Find new items in the DOM.\n this.items = this._getItems();\n\n // Set initial styles on the new items.\n this._initItems(this.items);\n\n this.once(Shuffle.EventType.LAYOUT, () => {\n // Add transition to each item.\n this.setItemTransitions(this.items);\n this.isInitialized = true;\n });\n\n // Lay out all items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems(this.items);\n\n this.items.length = 0;\n this._transitions.length = 0;\n\n // Null DOM references\n this.options.sizer = null;\n this.element = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n this.isEnabled = false;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins=false] Whether to include margins.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins = false) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Element[]} elements DOM elements that won't be transitioned.\n * @param {function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const { style } = element;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause forced synchronous layout.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/** @enum {string} */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/** @enum {string} */\nShuffle.FilterMode = {\n ANY: 'any',\n ALL: 'all',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimiter\n // to ','.\n delimiter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 150,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With \"any\",\n // the element passes the test if any of its groups are in the array. With \"all\",\n // the element only passes if all groups are in the array.\n filterMode: Shuffle.FilterMode.ANY,\n\n // Attempt to center grid items in each row.\n isCentered: false,\n\n // Whether to round pixel values used in translate(x, y). This usually avoids\n // blurriness.\n roundTransforms: true,\n};\n\nShuffle.Point = Point;\nShuffle.Rect = Rect;\n\n// Expose for testing. Hack at your own risk.\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\nShuffle.__getCenteredPositions = getCenteredPositions;\n\nexport default Shuffle;\n"],"names":["getNumber","value","parseFloat","Point","x","y","a","b","Rect","w","h","id","left","top","width","height","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isVisible","isHidden","classList","remove","Classes","add","removeAttribute","setAttribute","addClasses","applyCss","Css","INITIAL","scale","Scale","point","classes","forEach","className","obj","Object","keys","key","style","removeClasses","position","visibility","willChange","before","opacity","after","transitionDelay","document","body","documentElement","e","createElement","cssText","appendChild","window","getComputedStyle","removeChild","getNumberStyle","styles","testComputedSize","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","Math","floor","random","temp","defaults","reverse","by","compare","sorter","arr","options","opts","assign","original","Array","from","revert","sort","valA","valB","undefined","transitions","eventName","count","uniqueId","cancelTransitionEnd","removeEventListener","listener","onTransitionEnd","callback","evt","currentTarget","target","addEventListener","arrayMax","max","apply","arrayMin","min","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","ceil","getAvailablePositions","positions","available","push","slice","getShortColumn","buffer","minPosition","len","getItemPosition","itemSize","gridSize","total","span","setY","shortColumnIndex","setHeight","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersects","intersectingRect","hasOverlap","rowIndex","findIndex","items","includes","splice","concat","map","hyphenate","str","replace","m1","toLowerCase","arrayUnique","Set","Shuffle","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","el","_getElementOption","TypeError","_init","_getItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","nodeType","jquery","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","call","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","matches","itemSelector","indexOf","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","name","data","shuffle","emit","itemPositions","_getNextPositions","equals","getStylesForTransition","_getStaggerAmount","isCentered","itemsData","_getItemPosition","getTransformedPositions","_getConcealedItems","update","styleObject","roundTransforms","transform","itemCallback","done","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","callbacks","_getTransitionFunction","parallel","_movementFinished","objects","elements","_skipTransitions","sortOptions","_filter","_shrink","_updateItemCount","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","allItems","_mergeNewItems","sortedItems","allSortedItemsSet","isNewItem","applyHiddenState","isUpdateLayout","oldItems","getItemByElement","handleLayout","_disposeItems","parentNode","REMOVED","once","find","includeMargins","marginLeft","marginRight","marginTop","marginBottom","zero","duration","delay","TinyEmitter","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"shuffle.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/matches-selector/index.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/rect.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/array-min.js","../src/layout.js","../src/hyphenate.js","../src/shuffle.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n","'use strict';\n\nvar proto = typeof Element !== 'undefined' ? Element.prototype : {};\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (!el || el.nodeType !== 1) return false;\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default class Rect {\n /**\n * Class for representing rectangular regions.\n * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js\n * @param {number} x Left.\n * @param {number} y Top.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} id Identifier\n * @constructor\n */\n constructor(x, y, w, h, id) {\n this.id = id;\n\n /** @type {number} */\n this.left = x;\n\n /** @type {number} */\n this.top = y;\n\n /** @type {number} */\n this.width = w;\n\n /** @type {number} */\n this.height = h;\n }\n\n /**\n * Returns whether two rectangles intersect.\n * @param {Rect} a A Rectangle.\n * @param {Rect} b A Rectangle.\n * @return {boolean} Whether a and b intersect.\n */\n static intersects(a, b) {\n return (\n a.left < b.left + b.width && b.left < a.left + a.width\n && a.top < b.top + b.height && b.top < a.top + a.height);\n }\n}\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element, isRTL) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Set correct direction of item\n */\n this.isRTL = isRTL;\n\n /**\n * Used to separate items for layout and shrink.\n */\n this.isVisible = true;\n\n /**\n * Used to determine if a transition will happen. By the time the _layout\n * and _shrink methods get the ShuffleItem instances, the `isVisible` value\n * has already been changed by the separation methods, so this property is\n * needed to know if the item was visible/hidden before the shrink/layout.\n */\n this.isHidden = false;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n this.element.removeAttribute('aria-hidden');\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n this.element.setAttribute('aria-hidden', true);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.applyCss(this.isRTL ? ShuffleItem.Css.DIRECTION.rtl : ShuffleItem.Css.DIRECTION.ltr);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n visibility: 'visible',\n willChange: 'transform',\n },\n DIRECTION: {\n ltr: {\n left: 0,\n },\n rtl: {\n right: 0,\n },\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {\n transitionDelay: '',\n },\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n transitionDelay: '',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","let value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n value = window.getComputedStyle(e, null).width === '10px';\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft)\n + getNumber(styles.paddingRight)\n + getNumber(styles.borderLeftWidth)\n + getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop)\n + getNumber(styles.paddingBottom)\n + getNumber(styles.borderTopWidth)\n + getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n/**\n * You can return `undefined` from the `by` function to revert to DOM order.\n * @param {Array} arr Array to sort.\n * @param {SortOptions} options Sorting options.\n * @return {Array}\n */\nexport default function sorter(arr, options) {\n // eslint-disable-next-line prefer-object-spread\n const opts = Object.assign({}, defaults, options);\n const original = Array.from(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n } else if (typeof opts.compare === 'function') {\n arr.sort(opts.compare);\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport Rect from './rect';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 10]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 10]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({\n itemSize, positions, gridSize, total, threshold, buffer,\n}) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]);\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n\n/**\n * This method attempts to center items. This method could potentially be slow\n * with a large number of items because it must place items, then check every\n * previous item to ensure there is no overlap.\n * @param {Array.} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Array.}\n */\nexport function getCenteredPositions(itemRects, containerWidth) {\n const rowMap = {};\n\n // Populate rows by their offset because items could jump between rows like:\n // a c\n // bbb\n itemRects.forEach((itemRect) => {\n if (rowMap[itemRect.top]) {\n // Push the point to the last row array.\n rowMap[itemRect.top].push(itemRect);\n } else {\n // Start of a new row.\n rowMap[itemRect.top] = [itemRect];\n }\n });\n\n // For each row, find the end of the last item, then calculate\n // the remaining space by dividing it by 2. Then add that\n // offset to the x position of each point.\n let rects = [];\n const rows = [];\n const centeredRows = [];\n Object.keys(rowMap).forEach((key) => {\n const itemRects = rowMap[key];\n rows.push(itemRects);\n const lastItem = itemRects[itemRects.length - 1];\n const end = lastItem.left + lastItem.width;\n const offset = Math.round((containerWidth - end) / 2);\n\n let finalRects = itemRects;\n let canMove = false;\n if (offset > 0) {\n const newRects = [];\n canMove = itemRects.every((r) => {\n const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id);\n\n // Check all current rects to make sure none overlap.\n const noOverlap = !rects.some((r) => Rect.intersects(newRect, r));\n\n newRects.push(newRect);\n return noOverlap;\n });\n\n // If none of the rectangles overlapped, the whole group can be centered.\n if (canMove) {\n finalRects = newRects;\n }\n }\n\n // If the items are not going to be offset, ensure that the original\n // placement for this row will not overlap previous rows (row-spanning\n // elements could be in the way).\n if (!canMove) {\n let intersectingRect;\n const hasOverlap = itemRects.some((itemRect) => rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }));\n\n // If there is any overlap, replace the overlapping row with the original.\n if (hasOverlap) {\n const rowIndex = centeredRows.findIndex((items) => items.includes(intersectingRect));\n centeredRows.splice(rowIndex, 1, rows[rowIndex]);\n }\n }\n\n rects = rects.concat(finalRects);\n centeredRows.push(finalRects);\n });\n\n // Reduce array of arrays to a single array of points.\n // https://stackoverflow.com/a/10865042/373422\n // Then reset sort back to how the items were passed to this method.\n // Remove the wrapper object with index, map to a Point.\n return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread\n .sort((a, b) => (a.id - b.id))\n .map((itemRect) => new Point(itemRect.left, itemRect.top));\n}\n","/**\n * Hyphenates a javascript style string to a css one. For example:\n * MozBoxSizing -> -moz-box-sizing.\n * @param {string} str The string to hyphenate.\n * @return {string} The hyphenated string.\n */\nexport default function hyphenate(str) {\n return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`);\n}\n","import TinyEmitter from 'tiny-emitter';\nimport matches from 'matches-selector';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\n\nimport Point from './point';\nimport Rect from './rect';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport {\n getItemPosition,\n getColumnSpan,\n getAvailablePositions,\n getShortColumn,\n getCenteredPositions,\n} from './layout';\nimport arrayMax from './array-max';\nimport hyphenate from './hyphenate';\n\nfunction arrayUnique(x) {\n return Array.from(new Set(x));\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle extends TinyEmitter {\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n super();\n // eslint-disable-next-line prefer-object-spread\n this.options = Object.assign({}, Shuffle.options, options);\n\n // Allow misspelling of delimiter since that's how it used to be.\n // Remove in v6.\n if (this.options.delimeter) {\n this.options.delimiter = this.options.delimeter;\n }\n\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems(this.items);\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // If the page has not already emitted the `load` event, call layout on load.\n // This avoids layout issues caused by images and fonts loading after the\n // instance has been initialized.\n if (document.readyState !== 'complete') {\n const layout = this.layout.bind(this);\n window.addEventListener('load', function onLoad() {\n window.removeEventListener('load', onLoad);\n layout();\n });\n }\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this.setItemTransitions(this.items);\n this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle\n ? this.options.throttle(resizeFunction, this.options.throttleTime)\n : resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n }\n\n // Check for an element\n if (option && option.nodeType && option.nodeType === 1) {\n return option;\n }\n\n // Check for jQuery object\n if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string|string[]|function(Element):boolean} [category] Category to\n * filter by. If it's given, the last category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|string[]|function(Element):boolean} category Category or function to filter by.\n * @param {ShuffleItem[]} items A collection of items to filter.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|string[]|function():boolean} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n }\n\n // Check each element's data-groups attribute against the given category.\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimiter\n ? attr.split(this.options.delimiter)\n : JSON.parse(attr);\n\n function testCategory(category) {\n return keys.includes(category);\n }\n\n if (Array.isArray(category)) {\n if (this.options.filterMode === Shuffle.FilterMode.ANY) {\n return category.some(testCategory);\n }\n return category.every(testCategory);\n }\n\n return keys.includes(category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {ShuffleItem[]} items Set to initialize.\n * @private\n */\n _initItems(items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @param {ShuffleItem[]} items Set to dispose.\n * @private\n */\n _disposeItems(items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of a new Shuffle instance.\n * @param {ShuffleItem[]} items Shuffle items to set transitions on.\n * @protected\n */\n setItemTransitions(items) {\n const { speed, easing } = this.options;\n const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left'];\n\n // Allow users to transtion other properties if they exist in the `before`\n // css mapping of the shuffle item.\n const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map((k) => hyphenate(k));\n const properties = positionProps.concat(cssProps).join();\n\n items.forEach((item) => {\n item.element.style.transitionDuration = speed + 'ms';\n item.element.style.transitionTimingFunction = easing;\n item.element.style.transitionProperty = properties;\n });\n }\n\n _getItems() {\n return Array.from(this.element.children)\n .filter((el) => matches(el, this.options.itemSelector))\n .map((el) => new ShuffleItem(el, this.options));\n }\n\n /**\n * Combine the current items array with a new one and sort it by DOM order.\n * @param {ShuffleItem[]} items Items to track.\n * @return {ShuffleItem[]}\n */\n _mergeNewItems(items) {\n const children = Array.from(this.element.children);\n return sorter(this.items.concat(items), {\n by(element) {\n return children.indexOf(element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter((item) => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter((item) => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.options.sizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.options.sizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns)\n < this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns || 0), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * Emit an event from this instance.\n * @param {string} name Event name.\n * @param {Object} [data={}] Optional object data.\n */\n _dispatch(name, data = {}) {\n if (this.isDestroyed) {\n return;\n }\n\n data.shuffle = this;\n this.emit(name, data);\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {ShuffleItem[]} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n const itemPositions = this._getNextPositions(items);\n\n let count = 0;\n items.forEach((item, i) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = itemPositions[i];\n item.scale = ShuffleItem.Scale.VISIBLE;\n item.isHidden = false;\n\n // Clone the object so that the `before` object isn't modified when the\n // transition delay is added.\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Return an array of Point instances representing the future positions of\n * each item.\n * @param {ShuffleItem[]} items Array of sorted shuffle items.\n * @return {Point[]}\n * @private\n */\n _getNextPositions(items) {\n // If position data is going to be changed, add the item's size to the\n // transformer to allow for calculations.\n if (this.options.isCentered) {\n const itemsData = items.map((item, i) => {\n const itemSize = Shuffle.getSize(item.element, true);\n const point = this._getItemPosition(itemSize);\n return new Rect(point.x, point.y, itemSize.width, itemSize.height, i);\n });\n\n return this.getTransformedPositions(itemsData, this.containerWidth);\n }\n\n // If no transforms are going to happen, simply return an array of the\n // future points of each item.\n return items.map((item) => this._getItemPosition(Shuffle.getSize(item.element, true)));\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Mutate positions before they're applied.\n * @param {Rect[]} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Point[]}\n * @protected\n */\n getTransformedPositions(itemRects, containerWidth) {\n return getCenteredPositions(itemRects, containerWidth);\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {ShuffleItem[]} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.isHidden) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {ShuffleItem} item Item to get styles for. Should have updated\n * scale and point properties.\n * @param {Object} styleObject Extra styles that will be used in the transition.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @protected\n */\n getStylesForTransition(item, styleObject) {\n // Clone the object to avoid mutating the original.\n // eslint-disable-next-line prefer-object-spread\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const sign = this.options.isRTL ? '-' : '';\n const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x;\n const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y;\n styles.transform = `translate(${sign}${x}px, ${y}px) scale(${item.scale})`;\n } else {\n if (this.options.isRTL) {\n styles.right = item.point.x + 'px';\n } else {\n styles.left = item.point.x + 'px';\n }\n styles.top = item.point.y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {function} itemCallback Callback for the item.\n * @param {function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(opts.styles);\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatch(Shuffle.EventType.LAYOUT);\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Object[]} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map((obj) => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Object[]} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map((obj) => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(obj.styles);\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|string[]|function(Element):boolean} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {SortOptions} [sortOptions] A sort object which can sort the visible set\n */\n filter(category, sortOptions) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortOptions);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {SortOptions} [sortOptions] The options object to pass to `sorter`.\n */\n sort(sortOptions = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n const items = sorter(this._getFilteredItems(), sortOptions);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = sortOptions;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated.\n */\n update(isOnlyLayout = false) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Element[]} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map((el) => new ShuffleItem(el, this.options));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Determine which items will go with the current filter.\n this._resetCols();\n\n const allItems = this._mergeNewItems(items);\n const sortedItems = sorter(allItems, this.lastSort);\n const allSortedItemsSet = this._filter(this.lastFilter, sortedItems);\n\n const isNewItem = (item) => items.includes(item);\n const applyHiddenState = (item) => {\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n };\n\n // Layout all items again so that new items get positions.\n // Synchonously apply positions.\n const itemPositions = this._getNextPositions(allSortedItemsSet.visible);\n allSortedItemsSet.visible.forEach((item, i) => {\n if (isNewItem(item)) {\n item.point = itemPositions[i];\n applyHiddenState(item);\n item.applyCss(this.getStylesForTransition(item, {}));\n }\n });\n\n allSortedItemsSet.hidden.forEach((item) => {\n if (isNewItem(item)) {\n applyHiddenState(item);\n }\n });\n\n // Cause layout so that the styles above are applied.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Add transition to each item.\n this.setItemTransitions(items);\n\n // Update the list of items.\n this.items = this._mergeNewItems(items);\n\n // Update layout/visibility of new and old items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout = true) {\n this.isEnabled = true;\n if (isUpdateLayout) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items.\n * @param {Element[]} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle instance.\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map((element) => this.getItemByElement(element))\n .filter((item) => !!item);\n\n const handleLayout = () => {\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter((item) => !oldItems.includes(item));\n this._updateItemCount();\n\n this.once(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or undefined if it's not found.\n */\n getItemByElement(element) {\n return this.items.find((item) => item.element === element);\n }\n\n /**\n * Dump the elements currently stored and reinitialize all child elements which\n * match the `itemSelector`.\n */\n resetItems() {\n // Remove refs to current items.\n this._disposeItems(this.items);\n this.isInitialized = false;\n\n // Find new items in the DOM.\n this.items = this._getItems();\n\n // Set initial styles on the new items.\n this._initItems(this.items);\n\n this.once(Shuffle.EventType.LAYOUT, () => {\n // Add transition to each item.\n this.setItemTransitions(this.items);\n this.isInitialized = true;\n });\n\n // Lay out all items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems(this.items);\n\n this.items.length = 0;\n this._transitions.length = 0;\n\n // Null DOM references\n this.options.sizer = null;\n this.element = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n this.isEnabled = false;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins=false] Whether to include margins.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins = false) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Element[]} elements DOM elements that won't be transitioned.\n * @param {function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const { style } = element;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause forced synchronous layout.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/** @enum {string} */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/** @enum {string} */\nShuffle.FilterMode = {\n ANY: 'any',\n ALL: 'all',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimiter\n // to ','.\n delimiter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 150,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With \"any\",\n // the element passes the test if any of its groups are in the array. With \"all\",\n // the element only passes if all groups are in the array.\n filterMode: Shuffle.FilterMode.ANY,\n\n // Attempt to center grid items in each row.\n isCentered: false,\n\n // Attempt to align grid items to right.\n isRTL: false,\n\n // Whether to round pixel values used in translate(x, y). This usually avoids\n // blurriness.\n roundTransforms: true,\n};\n\nShuffle.Point = Point;\nShuffle.Rect = Rect;\n\n// Expose for testing. Hack at your own risk.\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\nShuffle.__getCenteredPositions = getCenteredPositions;\n\nexport default Shuffle;\n"],"names":["getNumber","value","parseFloat","Point","constructor","x","y","equals","a","b","Rect","w","h","id","left","top","width","height","intersects","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isRTL","isVisible","isHidden","show","classList","remove","Classes","add","removeAttribute","hide","setAttribute","init","addClasses","applyCss","Css","INITIAL","DIRECTION","rtl","ltr","scale","Scale","point","classes","forEach","className","removeClasses","obj","Object","keys","key","style","dispose","position","visibility","willChange","right","before","opacity","after","transitionDelay","document","body","documentElement","e","createElement","cssText","appendChild","window","getComputedStyle","removeChild","getNumberStyle","styles","testComputedSize","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","randomize","array","n","length","i","Math","floor","random","temp","defaults","reverse","by","compare","sorter","arr","options","opts","assign","original","Array","from","revert","sort","valA","valB","undefined","transitions","eventName","count","uniqueId","cancelTransitionEnd","removeEventListener","listener","onTransitionEnd","callback","evt","currentTarget","target","addEventListener","arrayMax","max","apply","arrayMin","min","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","ceil","getAvailablePositions","positions","available","push","slice","getShortColumn","buffer","minPosition","len","getItemPosition","itemSize","gridSize","total","span","setY","shortColumnIndex","setHeight","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersectingRect","hasOverlap","rowIndex","findIndex","items","includes","splice","concat","map","hyphenate","str","replace","m1","toLowerCase","arrayUnique","Set","Shuffle","TinyEmitter","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","el","_getElementOption","TypeError","_init","_getItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","nodeType","jquery","overflow","_filter","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","call","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","_disposeItems","_updateItemCount","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","matches","itemSelector","_mergeNewItems","indexOf","_getConcealedItems","_getColumnSize","gutterSize","size","_getGutterSize","gutterWidth","gutter","calculatedColumns","columnThreshold","cols","colWidth","_setContainerSize","_getContainerSize","_getStaggerAmount","index","staggerAmount","staggerAmountMax","_dispatch","name","data","shuffle","emit","_resetCols","_layout","itemPositions","_getNextPositions","getStylesForTransition","isCentered","itemsData","_getItemPosition","getTransformedPositions","_shrink","update","styleObject","sign","roundTransforms","transform","_whenTransitionDone","itemCallback","done","_getTransitionFunction","_processQueue","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","EventType","LAYOUT","callbacks","parallel","_movementFinished","objects","elements","_skipTransitions","sortOptions","isOnlyLayout","newItems","allItems","sortedItems","allSortedItemsSet","isNewItem","applyHiddenState","disable","enable","isUpdateLayout","oldItems","getItemByElement","handleLayout","parentNode","REMOVED","once","find","resetItems","destroy","includeMargins","marginLeft","marginRight","marginTop","marginBottom","zero","duration","delay","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"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"} \ No newline at end of file diff --git a/dist/shuffle.min.js b/dist/shuffle.min.js index 8cfd196..07af319 100644 --- a/dist/shuffle.min.js +++ b/dist/shuffle.min.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Shuffle=e()}(this,(function(){"use strict";function t(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function e(t,e){for(var i=0;i=e?l():o=setTimeout(l,e-t)),s};function l(){o=0,r=+new Date,s=t.apply(i,n),i=null,n=null}};function p(){}function m(t){return parseFloat(t)||0}var v=function(){function e(i,n){t(this,e),this.x=m(i),this.y=m(n)}return i(e,null,[{key:"equals",value:function(t,e){return t.x===e.x&&t.y===e.y}}]),e}(),y=function(){function e(i,n,s,o,r){t(this,e),this.id=r,this.left=i,this.top=n,this.width=s,this.height=o}return i(e,null,[{key:"intersects",value:function(t,e){return t.left2&&void 0!==arguments[2]?arguments[2]:window.getComputedStyle(t,null),n=m(i[e]);return b()||"width"!==e?b()||"height"!==e||(n+=m(i.paddingTop)+m(i.paddingBottom)+m(i.borderTopWidth)+m(i.borderBottomWidth)):n+=m(i.paddingLeft)+m(i.paddingRight)+m(i.borderLeftWidth)+m(i.borderRightWidth),n}var T={reverse:!1,by:null,compare:null,randomize:!1,key:"element"};function k(t,e){var i=Object.assign({},T,e),n=Array.from(t),s=!1;return t.length?i.randomize?function(t){for(var e=t.length;e;){e-=1;var i=Math.floor(Math.random()*(e+1)),n=t[i];t[i]=t[e],t[e]=n}return t}(t):("function"==typeof i.by?t.sort((function(t,e){if(s)return 0;var n=i.by(t[i.key]),o=i.by(e[i.key]);return void 0===n&&void 0===o?(s=!0,0):no||"sortLast"===n||"sortFirst"===o?1:0})):"function"==typeof i.compare&&t.sort(i.compare),s?n:(i.reverse&&t.reverse(),t)):[]}var w={},C=0;function L(t){return!!w[t]&&(w[t].element.removeEventListener("transitionend",w[t].listener),w[t]=null,!0)}function D(t,e){var i="transitionend"+(C+=1),n=function(t){t.currentTarget===t.target&&(L(i),e(t))};return t.addEventListener("transitionend",n),w[i]={element:t,listener:n},i}function z(t){return Math.max.apply(Math,t)}function M(t,e,i,n){var s=t/e;return Math.abs(Math.round(s)-s)=n-e&&t[s]<=n+e)return s;return 0}function x(t,e){var i={};t.forEach((function(t){i[t.top]?i[t.top].push(t):i[t.top]=[t]}));var n=[],s=[],o=[];return Object.keys(i).forEach((function(t){var r=i[t];s.push(r);var l,a=r[r.length-1],u=a.left+a.width,h=Math.round((e-u)/2),f=r,c=!1;if(h>0){var d=[];(c=r.every((function(t){var e=new y(t.left+h,t.top,t.width,t.height,t.id),i=!n.some((function(t){return y.intersects(e,t)}));return d.push(e),i})))&&(f=d)}if(!c&&r.some((function(t){return n.some((function(e){var i=y.intersects(t,e);return i&&(l=e),i}))}))){var p=o.findIndex((function(t){return t.includes(l)}));o.splice(p,1,s[p])}n=n.concat(f),o.push(f)})),[].concat.apply([],o).sort((function(t,e){return t.id-e.id})).map((function(t){return new v(t.left,t.top)}))}function O(t){return Array.from(new Set(t))}var N=0,H=function(e){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&s(t,e)}(u,e);var l,a=(l=u,function(){var t,e=n(l);if(o()){var i=n(this).constructor;t=Reflect.construct(e,arguments,i)}else t=e.apply(this,arguments);return r(this,t)});function u(e){var i,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t(this,u),(i=a.call(this)).options=Object.assign({},u.options,n),i.options.delimeter&&(i.options.delimiter=i.options.delimeter),i.lastSort={},i.group=u.ALL_ITEMS,i.lastFilter=u.ALL_ITEMS,i.isEnabled=!0,i.isDestroyed=!1,i.isInitialized=!1,i._transitions=[],i.isTransitioning=!1,i._queue=[];var s=i._getElementOption(e);if(!s)throw new TypeError("Shuffle needs to be initialized with an element.");return i.element=s,i.id="shuffle_"+N,N+=1,i._init(),i.isInitialized=!0,i}return i(u,[{key:"_init",value:function(){if(this.items=this._getItems(),this.options.sizer=this._getElementOption(this.options.sizer),this.element.classList.add(u.Classes.BASE),this._initItems(this.items),this._onResize=this._getResizeFunction(),window.addEventListener("resize",this._onResize),"complete"!==document.readyState){var t=this.layout.bind(this);window.addEventListener("load",(function e(){window.removeEventListener("load",e),t()}))}var e=window.getComputedStyle(this.element,null),i=u.getSize(this.element).width;this._validateStyles(e),this._setColumns(i),this.filter(this.options.group,this.options.initialSort),this.element.offsetWidth,this.setItemTransitions(this.items),this.element.style.transition="height ".concat(this.options.speed,"ms ").concat(this.options.easing)}},{key:"_getResizeFunction",value:function(){var t=this._handleResize.bind(this);return this.options.throttle?this.options.throttle(t,this.options.throttleTime):t}},{key:"_getElementOption",value:function(t){return"string"==typeof t?this.element.querySelector(t):t&&t.nodeType&&1===t.nodeType?t:t&&t.jquery?t[0]:null}},{key:"_validateStyles",value:function(t){"static"===t.position&&(this.element.style.position="relative"),"hidden"!==t.overflow&&(this.element.style.overflow="hidden")}},{key:"_filter",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastFilter,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.items,i=this._getFilteredSets(t,e);return this._toggleFilterClasses(i),this.lastFilter=t,"string"==typeof t&&(this.group=t),i}},{key:"_getFilteredSets",value:function(t,e){var i=this,n=[],s=[];return t===u.ALL_ITEMS?n=e:e.forEach((function(e){i._doesPassFilter(t,e.element)?n.push(e):s.push(e)})),{visible:n,hidden:s}}},{key:"_doesPassFilter",value:function(t,e){if("function"==typeof t)return t.call(e,e,this);var i=e.getAttribute("data-"+u.FILTER_ATTRIBUTE_KEY),n=this.options.delimiter?i.split(this.options.delimiter):JSON.parse(i);function s(t){return n.includes(t)}return Array.isArray(t)?this.options.filterMode===u.FilterMode.ANY?t.some(s):t.every(s):n.includes(t)}},{key:"_toggleFilterClasses",value:function(t){var e=t.visible,i=t.hidden;e.forEach((function(t){t.show()})),i.forEach((function(t){t.hide()}))}},{key:"_initItems",value:function(t){t.forEach((function(t){t.init()}))}},{key:"_disposeItems",value:function(t){t.forEach((function(t){t.dispose()}))}},{key:"_updateItemCount",value:function(){this.visibleItems=this._getFilteredItems().length}},{key:"setItemTransitions",value:function(t){var e=this.options,i=e.speed,n=e.easing,s=this.options.useTransforms?["transform"]:["top","left"],o=Object.keys(E.Css.HIDDEN.before).map((function(t){return t.replace(/([A-Z])/g,(function(t,e){return"-".concat(e.toLowerCase())}))})),r=s.concat(o).join();t.forEach((function(t){t.element.style.transitionDuration=i+"ms",t.element.style.transitionTimingFunction=n,t.element.style.transitionProperty=r}))}},{key:"_getItems",value:function(){var t=this;return Array.from(this.element.children).filter((function(e){return c(e,t.options.itemSelector)})).map((function(t){return new E(t)}))}},{key:"_mergeNewItems",value:function(t){var e=Array.from(this.element.children);return k(this.items.concat(t),{by:function(t){return e.indexOf(t)}})}},{key:"_getFilteredItems",value:function(){return this.items.filter((function(t){return t.isVisible}))}},{key:"_getConcealedItems",value:function(){return this.items.filter((function(t){return!t.isVisible}))}},{key:"_getColumnSize",value:function(t,e){var i;return 0===(i="function"==typeof this.options.columnWidth?this.options.columnWidth(t):this.options.sizer?u.getSize(this.options.sizer).width:this.options.columnWidth?this.options.columnWidth:this.items.length>0?u.getSize(this.items[0].element,!0).width:t)&&(i=t),i+e}},{key:"_getGutterSize",value:function(t){return"function"==typeof this.options.gutterWidth?this.options.gutterWidth(t):this.options.sizer?S(this.options.sizer,"marginLeft"):this.options.gutterWidth}},{key:"_setColumns",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:u.getSize(this.element).width,e=this._getGutterSize(t),i=this._getColumnSize(t,e),n=(t+e)/i;Math.abs(Math.round(n)-n)1&&void 0!==arguments[1]?arguments[1]:{};this.isDestroyed||(e.shuffle=this,this.emit(t,e))}},{key:"_resetCols",value:function(){var t=this.cols;for(this.positions=[];t;)t-=1,this.positions.push(0)}},{key:"_layout",value:function(t){var e=this,i=this._getNextPositions(t),n=0;t.forEach((function(t,s){function o(){t.applyCss(E.Css.VISIBLE.after)}if(v.equals(t.point,i[s])&&!t.isHidden)return t.applyCss(E.Css.VISIBLE.before),void o();t.point=i[s],t.scale=E.Scale.VISIBLE,t.isHidden=!1;var r=e.getStylesForTransition(t,E.Css.VISIBLE.before);r.transitionDelay=e._getStaggerAmount(n)+"ms",e._queue.push({item:t,styles:r,callback:o}),n+=1}))}},{key:"_getNextPositions",value:function(t){var e=this;if(this.options.isCentered){var i=t.map((function(t,i){var n=u.getSize(t.element,!0),s=e._getItemPosition(n);return new y(s.x,s.y,n.width,n.height,i)}));return this.getTransformedPositions(i,this.containerWidth)}return t.map((function(t){return e._getItemPosition(u.getSize(t.element,!0))}))}},{key:"_getItemPosition",value:function(t){return function(t){for(var e=t.itemSize,i=t.positions,n=t.gridSize,s=t.total,o=t.threshold,r=t.buffer,l=M(e.width,n,s,o),a=A(i,l,s),u=F(a,r),h=new v(n*u,a[u]),f=a[u]+e.height,c=0;c0&&void 0!==arguments[0]?arguments[0]:this._getConcealedItems(),i=0;e.forEach((function(e){function n(){e.applyCss(E.Css.HIDDEN.after)}if(e.isHidden)return e.applyCss(E.Css.HIDDEN.before),void n();e.scale=E.Scale.HIDDEN,e.isHidden=!0;var s=t.getStylesForTransition(e,E.Css.HIDDEN.before);s.transitionDelay=t._getStaggerAmount(i)+"ms",t._queue.push({item:e,styles:s,callback:n}),i+=1}))}},{key:"_handleResize",value:function(){this.isEnabled&&!this.isDestroyed&&this.update()}},{key:"getStylesForTransition",value:function(t,e){var i=Object.assign({},e);if(this.options.useTransforms){var n=this.options.roundTransforms?Math.round(t.point.x):t.point.x,s=this.options.roundTransforms?Math.round(t.point.y):t.point.y;i.transform="translate(".concat(n,"px, ").concat(s,"px) scale(").concat(t.scale,")")}else i.left=t.point.x+"px",i.top=t.point.y+"px";return i}},{key:"_whenTransitionDone",value:function(t,e,i){var n=D(t,(function(t){e(),i(null,t)}));this._transitions.push(n)}},{key:"_getTransitionFunction",value:function(t){var e=this;return function(i){t.item.applyCss(t.styles),e._whenTransitionDone(t.item.element,t.callback,i)}}},{key:"_processQueue",value:function(){this.isTransitioning&&this._cancelMovement();var t=this.options.speed>0,e=this._queue.length>0;e&&t&&this.isInitialized?this._startTransitions(this._queue):e?(this._styleImmediately(this._queue),this._dispatch(u.EventType.LAYOUT)):this._dispatch(u.EventType.LAYOUT),this._queue.length=0}},{key:"_startTransitions",value:function(t){var e=this;this.isTransitioning=!0,function(t,e,i){i||("function"==typeof e?(i=e,e=null):i=p);var n=t&&t.length;if(!n)return i(null,[]);var s=!1,o=new Array(n);function r(t){return function(e,r){if(!s){if(e)return i(e,o),void(s=!0);o[t]=r,--n||i(null,o)}}}t.forEach(e?function(t,i){t.call(e,r(i))}:function(t,e){t(r(e))})}(t.map((function(t){return e._getTransitionFunction(t)})),this._movementFinished.bind(this))}},{key:"_cancelMovement",value:function(){this._transitions.forEach(L),this._transitions.length=0,this.isTransitioning=!1}},{key:"_styleImmediately",value:function(t){if(t.length){var e=t.map((function(t){return t.item.element}));u._skipTransitions(e,(function(){t.forEach((function(t){t.item.applyCss(t.styles),t.callback()}))}))}}},{key:"_movementFinished",value:function(){this._transitions.length=0,this.isTransitioning=!1,this._dispatch(u.EventType.LAYOUT)}},{key:"filter",value:function(t,e){this.isEnabled&&((!t||t&&0===t.length)&&(t=u.ALL_ITEMS),this._filter(t),this._shrink(),this._updateItemCount(),this.sort(e))}},{key:"sort",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.lastSort;if(this.isEnabled){this._resetCols();var e=k(this._getFilteredItems(),t);this._layout(e),this._processQueue(),this._setContainerSize(),this.lastSort=t}}},{key:"update",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.isEnabled&&(t||this._setColumns(),this.sort())}},{key:"layout",value:function(){this.update(!0)}},{key:"add",value:function(t){var e=this,i=O(t).map((function(t){return new E(t)}));this._initItems(i),this._resetCols();var n=k(this._mergeNewItems(i),this.lastSort),s=this._filter(this.lastFilter,n),o=function(t){return i.includes(t)},r=function(t){t.scale=E.Scale.HIDDEN,t.isHidden=!0,t.applyCss(E.Css.HIDDEN.before),t.applyCss(E.Css.HIDDEN.after)},l=this._getNextPositions(s.visible);s.visible.forEach((function(t,i){o(t)&&(t.point=l[i],r(t),t.applyCss(e.getStylesForTransition(t,{})))})),s.hidden.forEach((function(t){o(t)&&r(t)})),this.element.offsetWidth,this.setItemTransitions(i),this.items=this._mergeNewItems(i),this.filter(this.lastFilter)}},{key:"disable",value:function(){this.isEnabled=!1}},{key:"enable",value:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.isEnabled=!0,t&&this.update()}},{key:"remove",value:function(t){var e=this;if(t.length){var i=O(t),n=i.map((function(t){return e.getItemByElement(t)})).filter((function(t){return!!t}));this._toggleFilterClasses({visible:[],hidden:n}),this._shrink(n),this.sort(),this.items=this.items.filter((function(t){return!n.includes(t)})),this._updateItemCount(),this.once(u.EventType.LAYOUT,(function(){e._disposeItems(n),i.forEach((function(t){t.parentNode.removeChild(t)})),e._dispatch(u.EventType.REMOVED,{collection:i})}))}}},{key:"getItemByElement",value:function(t){return this.items.find((function(e){return e.element===t}))}},{key:"resetItems",value:function(){var t=this;this._disposeItems(this.items),this.isInitialized=!1,this.items=this._getItems(),this._initItems(this.items),this.once(u.EventType.LAYOUT,(function(){t.setItemTransitions(t.items),t.isInitialized=!0})),this.filter(this.lastFilter)}},{key:"destroy",value:function(){this._cancelMovement(),window.removeEventListener("resize",this._onResize),this.element.classList.remove("shuffle"),this.element.removeAttribute("style"),this._disposeItems(this.items),this.items.length=0,this._transitions.length=0,this.options.sizer=null,this.element=null,this.isDestroyed=!0,this.isEnabled=!1}}],[{key:"getSize",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=window.getComputedStyle(t,null),n=S(t,"width",i),s=S(t,"height",i);if(e){var o=S(t,"marginLeft",i),r=S(t,"marginRight",i),l=S(t,"marginTop",i),a=S(t,"marginBottom",i);n+=o+r,s+=l+a}return{width:n,height:s}}},{key:"_skipTransitions",value:function(t,e){var i=t.map((function(t){var e=t.style,i=e.transitionDuration,n=e.transitionDelay;return e.transitionDuration="0ms",e.transitionDelay="0ms",{duration:i,delay:n}}));e(),t[0].offsetWidth,t.forEach((function(t,e){t.style.transitionDuration=i[e].duration,t.style.transitionDelay=i[e].delay}))}}]),u}(a);return H.ShuffleItem=E,H.ALL_ITEMS="all",H.FILTER_ATTRIBUTE_KEY="groups",H.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},H.Classes=g,H.FilterMode={ANY:"any",ALL:"all"},H.options={group:H.ALL_ITEMS,speed:250,easing:"cubic-bezier(0.4, 0.0, 0.2, 1)",itemSelector:"*",sizer:null,gutterWidth:0,columnWidth:0,delimiter:null,buffer:0,columnThreshold:.01,initialSort:null,throttle:d,throttleTime:300,staggerAmount:15,staggerAmountMax:150,useTransforms:!0,filterMode:H.FilterMode.ANY,isCentered:!1,roundTransforms:!0},H.Point=v,H.Rect=y,H.__sorter=k,H.__getColumnSpan=M,H.__getAvailablePositions=A,H.__getShortColumn=F,H.__getCenteredPositions=x,H})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Shuffle=e()}(this,(function(){"use strict";function t(){}t.prototype={on:function(t,e,i){var s=this.e||(this.e={});return(s[t]||(s[t]=[])).push({fn:e,ctx:i}),this},once:function(t,e,i){var s=this;function n(){s.off(t,n),e.apply(i,arguments)}return n._=e,this.on(t,n,i)},emit:function(t){for(var e=[].slice.call(arguments,1),i=((this.e||(this.e={}))[t]||[]).slice(),s=0,n=i.length;s=e?h():o=setTimeout(h,e-t)),n};function h(){o=0,r=+new Date,n=t.apply(i,s),i=null,s=null}};function h(){}function l(t){return parseFloat(t)||0}class a{constructor(t,e){this.x=l(t),this.y=l(e)}static equals(t,e){return t.x===e.x&&t.y===e.y}}class u{constructor(t,e,i,s,n){this.id=n,this.left=t,this.top=e,this.width=i,this.height=s}static intersects(t,e){return t.left{this.element.classList.add(t)}))}removeClasses(t){t.forEach((t=>{this.element.classList.remove(t)}))}applyCss(t){Object.keys(t).forEach((e=>{this.element.style[e]=t[e]}))}dispose(){this.removeClasses([d.HIDDEN,d.VISIBLE,d.SHUFFLE_ITEM]),this.element.removeAttribute("style"),this.element=null}}m.Css={INITIAL:{position:"absolute",top:0,visibility:"visible",willChange:"transform"},DIRECTION:{ltr:{left:0},rtl:{right:0}},VISIBLE:{before:{opacity:1,visibility:"visible"},after:{transitionDelay:""}},HIDDEN:{before:{opacity:0},after:{visibility:"hidden",transitionDelay:""}}},m.Scale={VISIBLE:1,HIDDEN:.001};let p=null;var f=()=>{if(null!==p)return p;const t=document.body||document.documentElement,e=document.createElement("div");return e.style.cssText="width:10px;padding:2px;box-sizing:border-box;",t.appendChild(e),p="10px"===window.getComputedStyle(e,null).width,t.removeChild(e),p};function g(t,e,i=window.getComputedStyle(t,null)){let s=l(i[e]);return f()||"width"!==e?f()||"height"!==e||(s+=l(i.paddingTop)+l(i.paddingBottom)+l(i.borderTopWidth)+l(i.borderBottomWidth)):s+=l(i.paddingLeft)+l(i.paddingRight)+l(i.borderLeftWidth)+l(i.borderRightWidth),s}const y={reverse:!1,by:null,compare:null,randomize:!1,key:"element"};function _(t,e){const i=Object.assign({},y,e),s=Array.from(t);let n=!1;return t.length?i.randomize?function(t){let e=t.length;for(;e;){e-=1;const i=Math.floor(Math.random()*(e+1)),s=t[i];t[i]=t[e],t[e]=s}return t}(t):("function"==typeof i.by?t.sort(((t,e)=>{if(n)return 0;const s=i.by(t[i.key]),o=i.by(e[i.key]);return void 0===s&&void 0===o?(n=!0,0):so||"sortLast"===s||"sortFirst"===o?1:0})):"function"==typeof i.compare&&t.sort(i.compare),n?s:(i.reverse&&t.reverse(),t)):[]}const E={},I="transitionend";let T=0;function S(t){return!!E[t]&&(E[t].element.removeEventListener(I,E[t].listener),E[t]=null,!0)}function b(t,e){const i=(T+=1,I+T),s=t=>{t.currentTarget===t.target&&(S(i),e(t))};return t.addEventListener(I,s),E[i]={element:t,listener:s},i}function v(t){return Math.max.apply(Math,t)}function C(t,e,i,s){let n=t/e;return Math.abs(Math.round(n)-n)=i-e&&t[s]<=i+e)return s;return 0}function D(t,e){const i={};t.forEach((t=>{i[t.top]?i[t.top].push(t):i[t.top]=[t]}));let s=[];const n=[],o=[];return Object.keys(i).forEach((t=>{const r=i[t];n.push(r);const h=r[r.length-1],l=h.left+h.width,a=Math.round((e-l)/2);let d=r,c=!1;if(a>0){const t=[];c=r.every((e=>{const i=new u(e.left+a,e.top,e.width,e.height,e.id),n=!s.some((t=>u.intersects(i,t)));return t.push(i),n})),c&&(d=t)}if(!c){let t;if(r.some((e=>s.some((i=>{const s=u.intersects(e,i);return s&&(t=i),s}))))){const e=o.findIndex((e=>e.includes(t)));o.splice(e,1,n[e])}}s=s.concat(d),o.push(d)})),[].concat.apply([],o).sort(((t,e)=>t.id-e.id)).map((t=>new a(t.left,t.top)))}function z(t){return Array.from(new Set(t))}let M=0;class A extends e{constructor(t,e={}){super(),this.options=Object.assign({},A.options,e),this.options.delimeter&&(this.options.delimiter=this.options.delimeter),this.lastSort={},this.group=A.ALL_ITEMS,this.lastFilter=A.ALL_ITEMS,this.isEnabled=!0,this.isDestroyed=!1,this.isInitialized=!1,this._transitions=[],this.isTransitioning=!1,this._queue=[];const i=this._getElementOption(t);if(!i)throw new TypeError("Shuffle needs to be initialized with an element.");this.element=i,this.id="shuffle_"+M,M+=1,this._init(),this.isInitialized=!0}_init(){if(this.items=this._getItems(),this.options.sizer=this._getElementOption(this.options.sizer),this.element.classList.add(A.Classes.BASE),this._initItems(this.items),this._onResize=this._getResizeFunction(),window.addEventListener("resize",this._onResize),"complete"!==document.readyState){const t=this.layout.bind(this);window.addEventListener("load",(function e(){window.removeEventListener("load",e),t()}))}const t=window.getComputedStyle(this.element,null),e=A.getSize(this.element).width;this._validateStyles(t),this._setColumns(e),this.filter(this.options.group,this.options.initialSort),this.element.offsetWidth,this.setItemTransitions(this.items),this.element.style.transition=`height ${this.options.speed}ms ${this.options.easing}`}_getResizeFunction(){const t=this._handleResize.bind(this);return this.options.throttle?this.options.throttle(t,this.options.throttleTime):t}_getElementOption(t){return"string"==typeof t?this.element.querySelector(t):t&&t.nodeType&&1===t.nodeType?t:t&&t.jquery?t[0]:null}_validateStyles(t){"static"===t.position&&(this.element.style.position="relative"),"hidden"!==t.overflow&&(this.element.style.overflow="hidden")}_filter(t=this.lastFilter,e=this.items){const i=this._getFilteredSets(t,e);return this._toggleFilterClasses(i),this.lastFilter=t,"string"==typeof t&&(this.group=t),i}_getFilteredSets(t,e){let i=[];const s=[];return t===A.ALL_ITEMS?i=e:e.forEach((e=>{this._doesPassFilter(t,e.element)?i.push(e):s.push(e)})),{visible:i,hidden:s}}_doesPassFilter(t,e){if("function"==typeof t)return t.call(e,e,this);const i=e.getAttribute("data-"+A.FILTER_ATTRIBUTE_KEY),s=this.options.delimiter?i.split(this.options.delimiter):JSON.parse(i);function n(t){return s.includes(t)}return Array.isArray(t)?this.options.filterMode===A.FilterMode.ANY?t.some(n):t.every(n):s.includes(t)}_toggleFilterClasses({visible:t,hidden:e}){t.forEach((t=>{t.show()})),e.forEach((t=>{t.hide()}))}_initItems(t){t.forEach((t=>{t.init()}))}_disposeItems(t){t.forEach((t=>{t.dispose()}))}_updateItemCount(){this.visibleItems=this._getFilteredItems().length}setItemTransitions(t){const{speed:e,easing:i}=this.options,s=this.options.useTransforms?["transform"]:["top","left"],n=Object.keys(m.Css.HIDDEN.before).map((t=>t.replace(/([A-Z])/g,((t,e)=>`-${e.toLowerCase()}`)))),o=s.concat(n).join();t.forEach((t=>{t.element.style.transitionDuration=e+"ms",t.element.style.transitionTimingFunction=i,t.element.style.transitionProperty=o}))}_getItems(){return Array.from(this.element.children).filter((t=>o(t,this.options.itemSelector))).map((t=>new m(t,this.options)))}_mergeNewItems(t){const e=Array.from(this.element.children);return _(this.items.concat(t),{by:t=>e.indexOf(t)})}_getFilteredItems(){return this.items.filter((t=>t.isVisible))}_getConcealedItems(){return this.items.filter((t=>!t.isVisible))}_getColumnSize(t,e){let i;return i="function"==typeof this.options.columnWidth?this.options.columnWidth(t):this.options.sizer?A.getSize(this.options.sizer).width:this.options.columnWidth?this.options.columnWidth:this.items.length>0?A.getSize(this.items[0].element,!0).width:t,0===i&&(i=t),i+e}_getGutterSize(t){let e;return e="function"==typeof this.options.gutterWidth?this.options.gutterWidth(t):this.options.sizer?g(this.options.sizer,"marginLeft"):this.options.gutterWidth,e}_setColumns(t=A.getSize(this.element).width){const e=this._getGutterSize(t),i=this._getColumnSize(t,e);let s=(t+e)/i;Math.abs(Math.round(s)-s){function n(){t.applyCss(m.Css.VISIBLE.after)}if(a.equals(t.point,e[s])&&!t.isHidden)return t.applyCss(m.Css.VISIBLE.before),void n();t.point=e[s],t.scale=m.Scale.VISIBLE,t.isHidden=!1;const o=this.getStylesForTransition(t,m.Css.VISIBLE.before);o.transitionDelay=this._getStaggerAmount(i)+"ms",this._queue.push({item:t,styles:o,callback:n}),i+=1}))}_getNextPositions(t){if(this.options.isCentered){const e=t.map(((t,e)=>{const i=A.getSize(t.element,!0),s=this._getItemPosition(i);return new u(s.x,s.y,i.width,i.height,e)}));return this.getTransformedPositions(e,this.containerWidth)}return t.map((t=>this._getItemPosition(A.getSize(t.element,!0))))}_getItemPosition(t){return function({itemSize:t,positions:e,gridSize:i,total:s,threshold:n,buffer:o}){const r=C(t.width,i,s,n),h=L(e,r,s),l=w(h,o),u=new a(i*l,h[l]),d=h[l]+t.height;for(let t=0;t{function i(){t.applyCss(m.Css.HIDDEN.after)}if(t.isHidden)return t.applyCss(m.Css.HIDDEN.before),void i();t.scale=m.Scale.HIDDEN,t.isHidden=!0;const s=this.getStylesForTransition(t,m.Css.HIDDEN.before);s.transitionDelay=this._getStaggerAmount(e)+"ms",this._queue.push({item:t,styles:s,callback:i}),e+=1}))}_handleResize(){this.isEnabled&&!this.isDestroyed&&this.update()}getStylesForTransition(t,e){const i=Object.assign({},e);if(this.options.useTransforms){const e=this.options.isRTL?"-":"",s=this.options.roundTransforms?Math.round(t.point.x):t.point.x,n=this.options.roundTransforms?Math.round(t.point.y):t.point.y;i.transform=`translate(${e}${s}px, ${n}px) scale(${t.scale})`}else this.options.isRTL?i.right=t.point.x+"px":i.left=t.point.x+"px",i.top=t.point.y+"px";return i}_whenTransitionDone(t,e,i){const s=b(t,(t=>{e(),i(null,t)}));this._transitions.push(s)}_getTransitionFunction(t){return e=>{t.item.applyCss(t.styles),this._whenTransitionDone(t.item.element,t.callback,e)}}_processQueue(){this.isTransitioning&&this._cancelMovement();const t=this.options.speed>0,e=this._queue.length>0;e&&t&&this.isInitialized?this._startTransitions(this._queue):e?(this._styleImmediately(this._queue),this._dispatch(A.EventType.LAYOUT)):this._dispatch(A.EventType.LAYOUT),this._queue.length=0}_startTransitions(t){this.isTransitioning=!0;!function(t,e,i){i||("function"==typeof e?(i=e,e=null):i=h);var s=t&&t.length;if(!s)return i(null,[]);var n=!1,o=new Array(s);function r(t){return function(e,r){if(!n){if(e)return i(e,o),void(n=!0);o[t]=r,--s||i(null,o)}}}t.forEach(e?function(t,i){t.call(e,r(i))}:function(t,e){t(r(e))})}(t.map((t=>this._getTransitionFunction(t))),this._movementFinished.bind(this))}_cancelMovement(){this._transitions.forEach(S),this._transitions.length=0,this.isTransitioning=!1}_styleImmediately(t){if(t.length){const e=t.map((t=>t.item.element));A._skipTransitions(e,(()=>{t.forEach((t=>{t.item.applyCss(t.styles),t.callback()}))}))}}_movementFinished(){this._transitions.length=0,this.isTransitioning=!1,this._dispatch(A.EventType.LAYOUT)}filter(t,e){this.isEnabled&&((!t||t&&0===t.length)&&(t=A.ALL_ITEMS),this._filter(t),this._shrink(),this._updateItemCount(),this.sort(e))}sort(t=this.lastSort){if(!this.isEnabled)return;this._resetCols();const e=_(this._getFilteredItems(),t);this._layout(e),this._processQueue(),this._setContainerSize(),this.lastSort=t}update(t=!1){this.isEnabled&&(t||this._setColumns(),this.sort())}layout(){this.update(!0)}add(t){const e=z(t).map((t=>new m(t,this.options)));this._initItems(e),this._resetCols();const i=_(this._mergeNewItems(e),this.lastSort),s=this._filter(this.lastFilter,i),n=t=>e.includes(t),o=t=>{t.scale=m.Scale.HIDDEN,t.isHidden=!0,t.applyCss(m.Css.HIDDEN.before),t.applyCss(m.Css.HIDDEN.after)},r=this._getNextPositions(s.visible);s.visible.forEach(((t,e)=>{n(t)&&(t.point=r[e],o(t),t.applyCss(this.getStylesForTransition(t,{})))})),s.hidden.forEach((t=>{n(t)&&o(t)})),this.element.offsetWidth,this.setItemTransitions(e),this.items=this._mergeNewItems(e),this.filter(this.lastFilter)}disable(){this.isEnabled=!1}enable(t=!0){this.isEnabled=!0,t&&this.update()}remove(t){if(!t.length)return;const e=z(t),i=e.map((t=>this.getItemByElement(t))).filter((t=>!!t));this._toggleFilterClasses({visible:[],hidden:i}),this._shrink(i),this.sort(),this.items=this.items.filter((t=>!i.includes(t))),this._updateItemCount(),this.once(A.EventType.LAYOUT,(()=>{this._disposeItems(i),e.forEach((t=>{t.parentNode.removeChild(t)})),this._dispatch(A.EventType.REMOVED,{collection:e})}))}getItemByElement(t){return this.items.find((e=>e.element===t))}resetItems(){this._disposeItems(this.items),this.isInitialized=!1,this.items=this._getItems(),this._initItems(this.items),this.once(A.EventType.LAYOUT,(()=>{this.setItemTransitions(this.items),this.isInitialized=!0})),this.filter(this.lastFilter)}destroy(){this._cancelMovement(),window.removeEventListener("resize",this._onResize),this.element.classList.remove("shuffle"),this.element.removeAttribute("style"),this._disposeItems(this.items),this.items.length=0,this._transitions.length=0,this.options.sizer=null,this.element=null,this.isDestroyed=!0,this.isEnabled=!1}static getSize(t,e=!1){const i=window.getComputedStyle(t,null);let s=g(t,"width",i),n=g(t,"height",i);if(e){s+=g(t,"marginLeft",i)+g(t,"marginRight",i),n+=g(t,"marginTop",i)+g(t,"marginBottom",i)}return{width:s,height:n}}static _skipTransitions(t,e){const i=t.map((t=>{const{style:e}=t,i=e.transitionDuration,s=e.transitionDelay;return e.transitionDuration="0ms",e.transitionDelay="0ms",{duration:i,delay:s}}));e(),t[0].offsetWidth,t.forEach(((t,e)=>{t.style.transitionDuration=i[e].duration,t.style.transitionDelay=i[e].delay}))}}return A.ShuffleItem=m,A.ALL_ITEMS="all",A.FILTER_ATTRIBUTE_KEY="groups",A.EventType={LAYOUT:"shuffle:layout",REMOVED:"shuffle:removed"},A.Classes=d,A.FilterMode={ANY:"any",ALL:"all"},A.options={group:A.ALL_ITEMS,speed:250,easing:"cubic-bezier(0.4, 0.0, 0.2, 1)",itemSelector:"*",sizer:null,gutterWidth:0,columnWidth:0,delimiter:null,buffer:0,columnThreshold:.01,initialSort:null,throttle:r,throttleTime:300,staggerAmount:15,staggerAmountMax:150,useTransforms:!0,filterMode:A.FilterMode.ANY,isCentered:!1,isRTL:!1,roundTransforms:!0},A.Point=a,A.Rect=u,A.__sorter=_,A.__getColumnSpan=C,A.__getAvailablePositions=L,A.__getShortColumn=w,A.__getCenteredPositions=D,A})); //# sourceMappingURL=shuffle.min.js.map diff --git a/dist/shuffle.min.js.map b/dist/shuffle.min.js.map index 97bb8dd..bf0706d 100644 --- a/dist/shuffle.min.js.map +++ b/dist/shuffle.min.js.map @@ -1 +1 @@ -{"version":3,"file":"shuffle.min.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/matches-selector/index.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/rect.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/layout.js","../src/array-min.js","../src/shuffle.js","../src/hyphenate.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n","'use strict';\n\nvar proto = typeof Element !== 'undefined' ? Element.prototype : {};\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (!el || el.nodeType !== 1) return false;\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default class Rect {\n /**\n * Class for representing rectangular regions.\n * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js\n * @param {number} x Left.\n * @param {number} y Top.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} id Identifier\n * @constructor\n */\n constructor(x, y, w, h, id) {\n this.id = id;\n\n /** @type {number} */\n this.left = x;\n\n /** @type {number} */\n this.top = y;\n\n /** @type {number} */\n this.width = w;\n\n /** @type {number} */\n this.height = h;\n }\n\n /**\n * Returns whether two rectangles intersect.\n * @param {Rect} a A Rectangle.\n * @param {Rect} b A Rectangle.\n * @return {boolean} Whether a and b intersect.\n */\n static intersects(a, b) {\n return (\n a.left < b.left + b.width && b.left < a.left + a.width\n && a.top < b.top + b.height && b.top < a.top + a.height);\n }\n}\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Used to separate items for layout and shrink.\n */\n this.isVisible = true;\n\n /**\n * Used to determine if a transition will happen. By the time the _layout\n * and _shrink methods get the ShuffleItem instances, the `isVisible` value\n * has already been changed by the separation methods, so this property is\n * needed to know if the item was visible/hidden before the shrink/layout.\n */\n this.isHidden = false;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n this.element.removeAttribute('aria-hidden');\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n this.element.setAttribute('aria-hidden', true);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n left: 0,\n visibility: 'visible',\n willChange: 'transform',\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {\n transitionDelay: '',\n },\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n transitionDelay: '',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","let value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n value = window.getComputedStyle(e, null).width === '10px';\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft)\n + getNumber(styles.paddingRight)\n + getNumber(styles.borderLeftWidth)\n + getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop)\n + getNumber(styles.paddingBottom)\n + getNumber(styles.borderTopWidth)\n + getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n/**\n * You can return `undefined` from the `by` function to revert to DOM order.\n * @param {Array} arr Array to sort.\n * @param {SortOptions} options Sorting options.\n * @return {Array}\n */\nexport default function sorter(arr, options) {\n // eslint-disable-next-line prefer-object-spread\n const opts = Object.assign({}, defaults, options);\n const original = Array.from(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n } else if (typeof opts.compare === 'function') {\n arr.sort(opts.compare);\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport Rect from './rect';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 10]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 10]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({\n itemSize, positions, gridSize, total, threshold, buffer,\n}) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]);\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n\n/**\n * This method attempts to center items. This method could potentially be slow\n * with a large number of items because it must place items, then check every\n * previous item to ensure there is no overlap.\n * @param {Array.} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Array.}\n */\nexport function getCenteredPositions(itemRects, containerWidth) {\n const rowMap = {};\n\n // Populate rows by their offset because items could jump between rows like:\n // a c\n // bbb\n itemRects.forEach((itemRect) => {\n if (rowMap[itemRect.top]) {\n // Push the point to the last row array.\n rowMap[itemRect.top].push(itemRect);\n } else {\n // Start of a new row.\n rowMap[itemRect.top] = [itemRect];\n }\n });\n\n // For each row, find the end of the last item, then calculate\n // the remaining space by dividing it by 2. Then add that\n // offset to the x position of each point.\n let rects = [];\n const rows = [];\n const centeredRows = [];\n Object.keys(rowMap).forEach((key) => {\n const itemRects = rowMap[key];\n rows.push(itemRects);\n const lastItem = itemRects[itemRects.length - 1];\n const end = lastItem.left + lastItem.width;\n const offset = Math.round((containerWidth - end) / 2);\n\n let finalRects = itemRects;\n let canMove = false;\n if (offset > 0) {\n const newRects = [];\n canMove = itemRects.every((r) => {\n const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id);\n\n // Check all current rects to make sure none overlap.\n const noOverlap = !rects.some((r) => Rect.intersects(newRect, r));\n\n newRects.push(newRect);\n return noOverlap;\n });\n\n // If none of the rectangles overlapped, the whole group can be centered.\n if (canMove) {\n finalRects = newRects;\n }\n }\n\n // If the items are not going to be offset, ensure that the original\n // placement for this row will not overlap previous rows (row-spanning\n // elements could be in the way).\n if (!canMove) {\n let intersectingRect;\n const hasOverlap = itemRects.some((itemRect) => rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }));\n\n // If there is any overlap, replace the overlapping row with the original.\n if (hasOverlap) {\n const rowIndex = centeredRows.findIndex((items) => items.includes(intersectingRect));\n centeredRows.splice(rowIndex, 1, rows[rowIndex]);\n }\n }\n\n rects = rects.concat(finalRects);\n centeredRows.push(finalRects);\n });\n\n // Reduce array of arrays to a single array of points.\n // https://stackoverflow.com/a/10865042/373422\n // Then reset sort back to how the items were passed to this method.\n // Remove the wrapper object with index, map to a Point.\n return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread\n .sort((a, b) => (a.id - b.id))\n .map((itemRect) => new Point(itemRect.left, itemRect.top));\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import TinyEmitter from 'tiny-emitter';\nimport matches from 'matches-selector';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\n\nimport Point from './point';\nimport Rect from './rect';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport {\n getItemPosition,\n getColumnSpan,\n getAvailablePositions,\n getShortColumn,\n getCenteredPositions,\n} from './layout';\nimport arrayMax from './array-max';\nimport hyphenate from './hyphenate';\n\nfunction arrayUnique(x) {\n return Array.from(new Set(x));\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle extends TinyEmitter {\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n super();\n // eslint-disable-next-line prefer-object-spread\n this.options = Object.assign({}, Shuffle.options, options);\n\n // Allow misspelling of delimiter since that's how it used to be.\n // Remove in v6.\n if (this.options.delimeter) {\n this.options.delimiter = this.options.delimeter;\n }\n\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems(this.items);\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // If the page has not already emitted the `load` event, call layout on load.\n // This avoids layout issues caused by images and fonts loading after the\n // instance has been initialized.\n if (document.readyState !== 'complete') {\n const layout = this.layout.bind(this);\n window.addEventListener('load', function onLoad() {\n window.removeEventListener('load', onLoad);\n layout();\n });\n }\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this.setItemTransitions(this.items);\n this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle\n ? this.options.throttle(resizeFunction, this.options.throttleTime)\n : resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n }\n\n // Check for an element\n if (option && option.nodeType && option.nodeType === 1) {\n return option;\n }\n\n // Check for jQuery object\n if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string|string[]|function(Element):boolean} [category] Category to\n * filter by. If it's given, the last category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|string[]|function(Element):boolean} category Category or function to filter by.\n * @param {ShuffleItem[]} items A collection of items to filter.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|string[]|function():boolean} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n }\n\n // Check each element's data-groups attribute against the given category.\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimiter\n ? attr.split(this.options.delimiter)\n : JSON.parse(attr);\n\n function testCategory(category) {\n return keys.includes(category);\n }\n\n if (Array.isArray(category)) {\n if (this.options.filterMode === Shuffle.FilterMode.ANY) {\n return category.some(testCategory);\n }\n return category.every(testCategory);\n }\n\n return keys.includes(category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {ShuffleItem[]} items Set to initialize.\n * @private\n */\n _initItems(items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @param {ShuffleItem[]} items Set to dispose.\n * @private\n */\n _disposeItems(items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of a new Shuffle instance.\n * @param {ShuffleItem[]} items Shuffle items to set transitions on.\n * @protected\n */\n setItemTransitions(items) {\n const { speed, easing } = this.options;\n const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left'];\n\n // Allow users to transtion other properties if they exist in the `before`\n // css mapping of the shuffle item.\n const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map((k) => hyphenate(k));\n const properties = positionProps.concat(cssProps).join();\n\n items.forEach((item) => {\n item.element.style.transitionDuration = speed + 'ms';\n item.element.style.transitionTimingFunction = easing;\n item.element.style.transitionProperty = properties;\n });\n }\n\n _getItems() {\n return Array.from(this.element.children)\n .filter((el) => matches(el, this.options.itemSelector))\n .map((el) => new ShuffleItem(el));\n }\n\n /**\n * Combine the current items array with a new one and sort it by DOM order.\n * @param {ShuffleItem[]} items Items to track.\n * @return {ShuffleItem[]}\n */\n _mergeNewItems(items) {\n const children = Array.from(this.element.children);\n return sorter(this.items.concat(items), {\n by(element) {\n return children.indexOf(element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter((item) => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter((item) => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.options.sizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.options.sizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns)\n < this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns || 0), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * Emit an event from this instance.\n * @param {string} name Event name.\n * @param {Object} [data={}] Optional object data.\n */\n _dispatch(name, data = {}) {\n if (this.isDestroyed) {\n return;\n }\n\n data.shuffle = this;\n this.emit(name, data);\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {ShuffleItem[]} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n const itemPositions = this._getNextPositions(items);\n\n let count = 0;\n items.forEach((item, i) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = itemPositions[i];\n item.scale = ShuffleItem.Scale.VISIBLE;\n item.isHidden = false;\n\n // Clone the object so that the `before` object isn't modified when the\n // transition delay is added.\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Return an array of Point instances representing the future positions of\n * each item.\n * @param {ShuffleItem[]} items Array of sorted shuffle items.\n * @return {Point[]}\n * @private\n */\n _getNextPositions(items) {\n // If position data is going to be changed, add the item's size to the\n // transformer to allow for calculations.\n if (this.options.isCentered) {\n const itemsData = items.map((item, i) => {\n const itemSize = Shuffle.getSize(item.element, true);\n const point = this._getItemPosition(itemSize);\n return new Rect(point.x, point.y, itemSize.width, itemSize.height, i);\n });\n\n return this.getTransformedPositions(itemsData, this.containerWidth);\n }\n\n // If no transforms are going to happen, simply return an array of the\n // future points of each item.\n return items.map((item) => this._getItemPosition(Shuffle.getSize(item.element, true)));\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Mutate positions before they're applied.\n * @param {Rect[]} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Point[]}\n * @protected\n */\n getTransformedPositions(itemRects, containerWidth) {\n return getCenteredPositions(itemRects, containerWidth);\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {ShuffleItem[]} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.isHidden) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {ShuffleItem} item Item to get styles for. Should have updated\n * scale and point properties.\n * @param {Object} styleObject Extra styles that will be used in the transition.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @protected\n */\n getStylesForTransition(item, styleObject) {\n // Clone the object to avoid mutating the original.\n // eslint-disable-next-line prefer-object-spread\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x;\n const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y;\n styles.transform = `translate(${x}px, ${y}px) scale(${item.scale})`;\n } else {\n styles.left = item.point.x + 'px';\n styles.top = item.point.y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {function} itemCallback Callback for the item.\n * @param {function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(opts.styles);\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatch(Shuffle.EventType.LAYOUT);\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Object[]} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map((obj) => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Object[]} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map((obj) => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(obj.styles);\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|string[]|function(Element):boolean} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {SortOptions} [sortOptions] A sort object which can sort the visible set\n */\n filter(category, sortOptions) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortOptions);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {SortOptions} [sortOptions] The options object to pass to `sorter`.\n */\n sort(sortOptions = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n const items = sorter(this._getFilteredItems(), sortOptions);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = sortOptions;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated.\n */\n update(isOnlyLayout = false) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Element[]} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map((el) => new ShuffleItem(el));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Determine which items will go with the current filter.\n this._resetCols();\n\n const allItems = this._mergeNewItems(items);\n const sortedItems = sorter(allItems, this.lastSort);\n const allSortedItemsSet = this._filter(this.lastFilter, sortedItems);\n\n const isNewItem = (item) => items.includes(item);\n const applyHiddenState = (item) => {\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n };\n\n // Layout all items again so that new items get positions.\n // Synchonously apply positions.\n const itemPositions = this._getNextPositions(allSortedItemsSet.visible);\n allSortedItemsSet.visible.forEach((item, i) => {\n if (isNewItem(item)) {\n item.point = itemPositions[i];\n applyHiddenState(item);\n item.applyCss(this.getStylesForTransition(item, {}));\n }\n });\n\n allSortedItemsSet.hidden.forEach((item) => {\n if (isNewItem(item)) {\n applyHiddenState(item);\n }\n });\n\n // Cause layout so that the styles above are applied.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Add transition to each item.\n this.setItemTransitions(items);\n\n // Update the list of items.\n this.items = this._mergeNewItems(items);\n\n // Update layout/visibility of new and old items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout = true) {\n this.isEnabled = true;\n if (isUpdateLayout) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items.\n * @param {Element[]} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle instance.\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map((element) => this.getItemByElement(element))\n .filter((item) => !!item);\n\n const handleLayout = () => {\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter((item) => !oldItems.includes(item));\n this._updateItemCount();\n\n this.once(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or undefined if it's not found.\n */\n getItemByElement(element) {\n return this.items.find((item) => item.element === element);\n }\n\n /**\n * Dump the elements currently stored and reinitialize all child elements which\n * match the `itemSelector`.\n */\n resetItems() {\n // Remove refs to current items.\n this._disposeItems(this.items);\n this.isInitialized = false;\n\n // Find new items in the DOM.\n this.items = this._getItems();\n\n // Set initial styles on the new items.\n this._initItems(this.items);\n\n this.once(Shuffle.EventType.LAYOUT, () => {\n // Add transition to each item.\n this.setItemTransitions(this.items);\n this.isInitialized = true;\n });\n\n // Lay out all items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems(this.items);\n\n this.items.length = 0;\n this._transitions.length = 0;\n\n // Null DOM references\n this.options.sizer = null;\n this.element = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n this.isEnabled = false;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins=false] Whether to include margins.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins = false) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Element[]} elements DOM elements that won't be transitioned.\n * @param {function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const { style } = element;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause forced synchronous layout.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/** @enum {string} */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/** @enum {string} */\nShuffle.FilterMode = {\n ANY: 'any',\n ALL: 'all',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimiter\n // to ','.\n delimiter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 150,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With \"any\",\n // the element passes the test if any of its groups are in the array. With \"all\",\n // the element only passes if all groups are in the array.\n filterMode: Shuffle.FilterMode.ANY,\n\n // Attempt to center grid items in each row.\n isCentered: false,\n\n // Whether to round pixel values used in translate(x, y). This usually avoids\n // blurriness.\n roundTransforms: true,\n};\n\nShuffle.Point = Point;\nShuffle.Rect = Rect;\n\n// Expose for testing. Hack at your own risk.\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\nShuffle.__getCenteredPositions = getCenteredPositions;\n\nexport default Shuffle;\n","/**\n * Hyphenates a javascript style string to a css one. For example:\n * MozBoxSizing -> -moz-box-sizing.\n * @param {string} str The string to hyphenate.\n * @return {string} The hyphenated string.\n */\nexport default function hyphenate(str) {\n return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`);\n}\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","proto","Element","vendor","matches","matchesSelector","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","el","selector","nodeType","nodes","parentNode","querySelectorAll","func","wait","args","rtn","timeoutID","last","delta","Date","setTimeout","noop","getNumber","value","parseFloat","Point","x","y","a","b","Rect","w","h","id","left","top","width","height","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isVisible","isHidden","classList","remove","Classes","add","removeAttribute","setAttribute","addClasses","applyCss","Css","INITIAL","scale","Scale","point","classes","forEach","className","_this","_this2","obj","Object","keys","key","_this3","style","removeClasses","position","visibility","willChange","before","opacity","after","transitionDelay","document","body","documentElement","createElement","cssText","appendChild","window","getComputedStyle","removeChild","getNumberStyle","styles","testComputedSize","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","defaults","reverse","by","compare","randomize","sorter","arr","options","opts","assign","original","Array","from","revert","array","n","Math","floor","random","temp","sort","valA","valB","undefined","transitions","count","cancelTransitionEnd","removeEventListener","onTransitionEnd","evt","currentTarget","target","addEventListener","arrayMax","max","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","min","ceil","getAvailablePositions","positions","available","getShortColumn","buffer","minPosition","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","intersectingRect","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersects","rowIndex","findIndex","items","includes","splice","concat","map","arrayUnique","Set","Shuffle","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","_getElementOption","TypeError","_init","_getItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","jquery","overflow","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","show","hide","init","dispose","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","replace","str","m1","toLowerCase","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","itemSelector","indexOf","gutterSize","size","gutterWidth","gutter","_getGutterSize","_getColumnSize","calculatedColumns","columnThreshold","cols","colWidth","_getContainerSize","index","staggerAmount","staggerAmountMax","shuffle","itemPositions","_getNextPositions","equals","_this4","getStylesForTransition","_getStaggerAmount","isCentered","itemsData","itemSize","_this5","_getItemPosition","getTransformedPositions","gridSize","total","span","setY","shortColumnIndex","setHeight","getItemPosition","_getConcealedItems","_this6","update","styleObject","roundTransforms","transform","itemCallback","done","_this7","_whenTransitionDone","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","_dispatch","EventType","LAYOUT","fns","context","pending","finished","results","maybeDone","err","result","parallel","_this8","_getTransitionFunction","_movementFinished","objects","elements","_skipTransitions","sortOptions","_filter","_shrink","_updateItemCount","_resetCols","_layout","_processQueue","_setContainerSize","isOnlyLayout","newItems","sortedItems","_mergeNewItems","allSortedItemsSet","isNewItem","applyHiddenState","_this9","isUpdateLayout","oldItems","_this10","getItemByElement","_disposeItems","REMOVED","find","_this11","includeMargins","marginLeft","marginRight","marginTop","marginBottom","duration","delay","TinyEmitter","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"shuffle.min.js","sources":["../node_modules/tiny-emitter/index.js","../node_modules/matches-selector/index.js","../node_modules/throttleit/index.js","../node_modules/array-parallel/index.js","../src/get-number.js","../src/point.js","../src/rect.js","../src/classes.js","../src/shuffle-item.js","../src/computed-size.js","../src/get-number-style.js","../src/sorter.js","../src/on-transition-end.js","../src/array-max.js","../src/layout.js","../src/array-min.js","../src/shuffle.js","../src/hyphenate.js"],"sourcesContent":["function E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n","'use strict';\n\nvar proto = typeof Element !== 'undefined' ? Element.prototype : {};\nvar vendor = proto.matches\n || proto.matchesSelector\n || proto.webkitMatchesSelector\n || proto.mozMatchesSelector\n || proto.msMatchesSelector\n || proto.oMatchesSelector;\n\nmodule.exports = match;\n\n/**\n * Match `el` to `selector`.\n *\n * @param {Element} el\n * @param {String} selector\n * @return {Boolean}\n * @api public\n */\n\nfunction match(el, selector) {\n if (!el || el.nodeType !== 1) return false;\n if (vendor) return vendor.call(el, selector);\n var nodes = el.parentNode.querySelectorAll(selector);\n for (var i = 0; i < nodes.length; i++) {\n if (nodes[i] == el) return true;\n }\n return false;\n}\n","module.exports = throttle;\n\n/**\n * Returns a new function that, when invoked, invokes `func` at most once per `wait` milliseconds.\n *\n * @param {Function} func Function to wrap.\n * @param {Number} wait Number of milliseconds that must elapse between `func` invocations.\n * @return {Function} A new function that wraps the `func` function passed in.\n */\n\nfunction throttle (func, wait) {\n var ctx, args, rtn, timeoutID; // caching\n var last = 0;\n\n return function throttled () {\n ctx = this;\n args = arguments;\n var delta = new Date() - last;\n if (!timeoutID)\n if (delta >= wait) call();\n else timeoutID = setTimeout(call, wait - delta);\n return rtn;\n };\n\n function call () {\n timeoutID = 0;\n last = +new Date();\n rtn = func.apply(ctx, args);\n ctx = null;\n args = null;\n }\n}\n","module.exports = function parallel(fns, context, callback) {\n if (!callback) {\n if (typeof context === 'function') {\n callback = context\n context = null\n } else {\n callback = noop\n }\n }\n\n var pending = fns && fns.length\n if (!pending) return callback(null, []);\n\n var finished = false\n var results = new Array(pending)\n\n fns.forEach(context ? function (fn, i) {\n fn.call(context, maybeDone(i))\n } : function (fn, i) {\n fn(maybeDone(i))\n })\n\n function maybeDone(i) {\n return function (err, result) {\n if (finished) return;\n\n if (err) {\n callback(err, results)\n finished = true\n return\n }\n\n results[i] = result\n\n if (!--pending) callback(null, results);\n }\n }\n}\n\nfunction noop() {}\n","/**\n * Always returns a numeric value, given a value. Logic from jQuery's `isNumeric`.\n * @param {*} value Possibly numeric value.\n * @return {number} `value` or zero if `value` isn't numeric.\n */\nexport default function getNumber(value) {\n return parseFloat(value) || 0;\n}\n","import getNumber from './get-number';\n\nclass Point {\n /**\n * Represents a coordinate pair.\n * @param {number} [x=0] X.\n * @param {number} [y=0] Y.\n */\n constructor(x, y) {\n this.x = getNumber(x);\n this.y = getNumber(y);\n }\n\n /**\n * Whether two points are equal.\n * @param {Point} a Point A.\n * @param {Point} b Point B.\n * @return {boolean}\n */\n static equals(a, b) {\n return a.x === b.x && a.y === b.y;\n }\n}\n\nexport default Point;\n","export default class Rect {\n /**\n * Class for representing rectangular regions.\n * https://github.com/google/closure-library/blob/master/closure/goog/math/rect.js\n * @param {number} x Left.\n * @param {number} y Top.\n * @param {number} w Width.\n * @param {number} h Height.\n * @param {number} id Identifier\n * @constructor\n */\n constructor(x, y, w, h, id) {\n this.id = id;\n\n /** @type {number} */\n this.left = x;\n\n /** @type {number} */\n this.top = y;\n\n /** @type {number} */\n this.width = w;\n\n /** @type {number} */\n this.height = h;\n }\n\n /**\n * Returns whether two rectangles intersect.\n * @param {Rect} a A Rectangle.\n * @param {Rect} b A Rectangle.\n * @return {boolean} Whether a and b intersect.\n */\n static intersects(a, b) {\n return (\n a.left < b.left + b.width && b.left < a.left + a.width\n && a.top < b.top + b.height && b.top < a.top + a.height);\n }\n}\n","export default {\n BASE: 'shuffle',\n SHUFFLE_ITEM: 'shuffle-item',\n VISIBLE: 'shuffle-item--visible',\n HIDDEN: 'shuffle-item--hidden',\n};\n","import Point from './point';\nimport Classes from './classes';\n\nlet id = 0;\n\nclass ShuffleItem {\n constructor(element, isRTL) {\n id += 1;\n this.id = id;\n this.element = element;\n\n /**\n * Set correct direction of item\n */\n this.isRTL = isRTL;\n\n /**\n * Used to separate items for layout and shrink.\n */\n this.isVisible = true;\n\n /**\n * Used to determine if a transition will happen. By the time the _layout\n * and _shrink methods get the ShuffleItem instances, the `isVisible` value\n * has already been changed by the separation methods, so this property is\n * needed to know if the item was visible/hidden before the shrink/layout.\n */\n this.isHidden = false;\n }\n\n show() {\n this.isVisible = true;\n this.element.classList.remove(Classes.HIDDEN);\n this.element.classList.add(Classes.VISIBLE);\n this.element.removeAttribute('aria-hidden');\n }\n\n hide() {\n this.isVisible = false;\n this.element.classList.remove(Classes.VISIBLE);\n this.element.classList.add(Classes.HIDDEN);\n this.element.setAttribute('aria-hidden', true);\n }\n\n init() {\n this.addClasses([Classes.SHUFFLE_ITEM, Classes.VISIBLE]);\n this.applyCss(ShuffleItem.Css.INITIAL);\n this.applyCss(this.isRTL ? ShuffleItem.Css.DIRECTION.rtl : ShuffleItem.Css.DIRECTION.ltr);\n this.scale = ShuffleItem.Scale.VISIBLE;\n this.point = new Point();\n }\n\n addClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.add(className);\n });\n }\n\n removeClasses(classes) {\n classes.forEach((className) => {\n this.element.classList.remove(className);\n });\n }\n\n applyCss(obj) {\n Object.keys(obj).forEach((key) => {\n this.element.style[key] = obj[key];\n });\n }\n\n dispose() {\n this.removeClasses([\n Classes.HIDDEN,\n Classes.VISIBLE,\n Classes.SHUFFLE_ITEM,\n ]);\n\n this.element.removeAttribute('style');\n this.element = null;\n }\n}\n\nShuffleItem.Css = {\n INITIAL: {\n position: 'absolute',\n top: 0,\n visibility: 'visible',\n willChange: 'transform',\n },\n DIRECTION: {\n ltr: {\n left: 0,\n },\n rtl: {\n right: 0,\n },\n },\n VISIBLE: {\n before: {\n opacity: 1,\n visibility: 'visible',\n },\n after: {\n transitionDelay: '',\n },\n },\n HIDDEN: {\n before: {\n opacity: 0,\n },\n after: {\n visibility: 'hidden',\n transitionDelay: '',\n },\n },\n};\n\nShuffleItem.Scale = {\n VISIBLE: 1,\n HIDDEN: 0.001,\n};\n\nexport default ShuffleItem;\n","let value = null;\nexport default () => {\n if (value !== null) {\n return value;\n }\n\n const element = document.body || document.documentElement;\n const e = document.createElement('div');\n e.style.cssText = 'width:10px;padding:2px;box-sizing:border-box;';\n element.appendChild(e);\n\n value = window.getComputedStyle(e, null).width === '10px';\n\n element.removeChild(e);\n\n return value;\n};\n","import getNumber from './get-number';\nimport testComputedSize from './computed-size';\n\n/**\n * Retrieve the computed style for an element, parsed as a float.\n * @param {Element} element Element to get style for.\n * @param {string} style Style property.\n * @param {CSSStyleDeclaration} [styles] Optionally include clean styles to\n * use instead of asking for them again.\n * @return {number} The parsed computed value or zero if that fails because IE\n * will return 'auto' when the element doesn't have margins instead of\n * the computed style.\n */\nexport default function getNumberStyle(\n element, style,\n styles = window.getComputedStyle(element, null),\n) {\n let value = getNumber(styles[style]);\n\n // Support IE<=11 and W3C spec.\n if (!testComputedSize() && style === 'width') {\n value += getNumber(styles.paddingLeft)\n + getNumber(styles.paddingRight)\n + getNumber(styles.borderLeftWidth)\n + getNumber(styles.borderRightWidth);\n } else if (!testComputedSize() && style === 'height') {\n value += getNumber(styles.paddingTop)\n + getNumber(styles.paddingBottom)\n + getNumber(styles.borderTopWidth)\n + getNumber(styles.borderBottomWidth);\n }\n\n return value;\n}\n","/**\n * Fisher-Yates shuffle.\n * http://stackoverflow.com/a/962890/373422\n * https://bost.ocks.org/mike/shuffle/\n * @param {Array} array Array to shuffle.\n * @return {Array} Randomly sorted array.\n */\nfunction randomize(array) {\n let n = array.length;\n\n while (n) {\n n -= 1;\n const i = Math.floor(Math.random() * (n + 1));\n const temp = array[i];\n array[i] = array[n];\n array[n] = temp;\n }\n\n return array;\n}\n\nconst defaults = {\n // Use array.reverse() to reverse the results\n reverse: false,\n\n // Sorting function\n by: null,\n\n // Custom sort function\n compare: null,\n\n // If true, this will skip the sorting and return a randomized order in the array\n randomize: false,\n\n // Determines which property of each item in the array is passed to the\n // sorting method.\n key: 'element',\n};\n\n/**\n * You can return `undefined` from the `by` function to revert to DOM order.\n * @param {Array} arr Array to sort.\n * @param {SortOptions} options Sorting options.\n * @return {Array}\n */\nexport default function sorter(arr, options) {\n // eslint-disable-next-line prefer-object-spread\n const opts = Object.assign({}, defaults, options);\n const original = Array.from(arr);\n let revert = false;\n\n if (!arr.length) {\n return [];\n }\n\n if (opts.randomize) {\n return randomize(arr);\n }\n\n // Sort the elements by the opts.by function.\n // If we don't have opts.by, default to DOM order\n if (typeof opts.by === 'function') {\n arr.sort((a, b) => {\n // Exit early if we already know we want to revert\n if (revert) {\n return 0;\n }\n\n const valA = opts.by(a[opts.key]);\n const valB = opts.by(b[opts.key]);\n\n // If both values are undefined, use the DOM order\n if (valA === undefined && valB === undefined) {\n revert = true;\n return 0;\n }\n\n if (valA < valB || valA === 'sortFirst' || valB === 'sortLast') {\n return -1;\n }\n\n if (valA > valB || valA === 'sortLast' || valB === 'sortFirst') {\n return 1;\n }\n\n return 0;\n });\n } else if (typeof opts.compare === 'function') {\n arr.sort(opts.compare);\n }\n\n // Revert to the original array if necessary\n if (revert) {\n return original;\n }\n\n if (opts.reverse) {\n arr.reverse();\n }\n\n return arr;\n}\n","const transitions = {};\nconst eventName = 'transitionend';\nlet count = 0;\n\nfunction uniqueId() {\n count += 1;\n return eventName + count;\n}\n\nexport function cancelTransitionEnd(id) {\n if (transitions[id]) {\n transitions[id].element.removeEventListener(eventName, transitions[id].listener);\n transitions[id] = null;\n return true;\n }\n\n return false;\n}\n\nexport function onTransitionEnd(element, callback) {\n const id = uniqueId();\n const listener = (evt) => {\n if (evt.currentTarget === evt.target) {\n cancelTransitionEnd(id);\n callback(evt);\n }\n };\n\n element.addEventListener(eventName, listener);\n\n transitions[id] = { element, listener };\n\n return id;\n}\n","export default function arrayMax(array) {\n return Math.max.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import Point from './point';\nimport Rect from './rect';\nimport arrayMax from './array-max';\nimport arrayMin from './array-min';\n\n/**\n * Determine the number of columns an items spans.\n * @param {number} itemWidth Width of the item.\n * @param {number} columnWidth Width of the column (includes gutter).\n * @param {number} columns Total number of columns\n * @param {number} threshold A buffer value for the size of the column to fit.\n * @return {number}\n */\nexport function getColumnSpan(itemWidth, columnWidth, columns, threshold) {\n let columnSpan = itemWidth / columnWidth;\n\n // If the difference between the rounded column span number and the\n // calculated column span number is really small, round the number to\n // make it fit.\n if (Math.abs(Math.round(columnSpan) - columnSpan) < threshold) {\n // e.g. columnSpan = 4.0089945390298745\n columnSpan = Math.round(columnSpan);\n }\n\n // Ensure the column span is not more than the amount of columns in the whole layout.\n return Math.min(Math.ceil(columnSpan), columns);\n}\n\n/**\n * Retrieves the column set to use for placement.\n * @param {number} columnSpan The number of columns this current item spans.\n * @param {number} columns The total columns in the grid.\n * @return {Array.} An array of numbers represeting the column set.\n */\nexport function getAvailablePositions(positions, columnSpan, columns) {\n // The item spans only one column.\n if (columnSpan === 1) {\n return positions;\n }\n\n // The item spans more than one column, figure out how many different\n // places it could fit horizontally.\n // The group count is the number of places within the positions this block\n // could fit, ignoring the current positions of items.\n // Imagine a 2 column brick as the second item in a 4 column grid with\n // 10px height each. Find the places it would fit:\n // [20, 10, 10, 0]\n // | | |\n // * * *\n //\n // Then take the places which fit and get the bigger of the two:\n // max([20, 10]), max([10, 10]), max([10, 0]) = [20, 10, 10]\n //\n // Next, find the first smallest number (the short column).\n // [20, 10, 10]\n // |\n // *\n //\n // And that's where it should be placed!\n //\n // Another example where the second column's item extends past the first:\n // [10, 20, 10, 0] => [20, 20, 10] => 10\n const available = [];\n\n // For how many possible positions for this item there are.\n for (let i = 0; i <= columns - columnSpan; i++) {\n // Find the bigger value for each place it could fit.\n available.push(arrayMax(positions.slice(i, i + columnSpan)));\n }\n\n return available;\n}\n\n/**\n * Find index of short column, the first from the left where this item will go.\n *\n * @param {Array.} positions The array to search for the smallest number.\n * @param {number} buffer Optional buffer which is very useful when the height\n * is a percentage of the width.\n * @return {number} Index of the short column.\n */\nexport function getShortColumn(positions, buffer) {\n const minPosition = arrayMin(positions);\n for (let i = 0, len = positions.length; i < len; i++) {\n if (positions[i] >= minPosition - buffer && positions[i] <= minPosition + buffer) {\n return i;\n }\n }\n\n return 0;\n}\n\n/**\n * Determine the location of the next item, based on its size.\n * @param {Object} itemSize Object with width and height.\n * @param {Array.} positions Positions of the other current items.\n * @param {number} gridSize The column width or row height.\n * @param {number} total The total number of columns or rows.\n * @param {number} threshold Buffer value for the column to fit.\n * @param {number} buffer Vertical buffer for the height of items.\n * @return {Point}\n */\nexport function getItemPosition({\n itemSize, positions, gridSize, total, threshold, buffer,\n}) {\n const span = getColumnSpan(itemSize.width, gridSize, total, threshold);\n const setY = getAvailablePositions(positions, span, total);\n const shortColumnIndex = getShortColumn(setY, buffer);\n\n // Position the item\n const point = new Point(gridSize * shortColumnIndex, setY[shortColumnIndex]);\n\n // Update the columns array with the new values for each column.\n // e.g. before the update the columns could be [250, 0, 0, 0] for an item\n // which spans 2 columns. After it would be [250, itemHeight, itemHeight, 0].\n const setHeight = setY[shortColumnIndex] + itemSize.height;\n for (let i = 0; i < span; i++) {\n positions[shortColumnIndex + i] = setHeight;\n }\n\n return point;\n}\n\n/**\n * This method attempts to center items. This method could potentially be slow\n * with a large number of items because it must place items, then check every\n * previous item to ensure there is no overlap.\n * @param {Array.} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Array.}\n */\nexport function getCenteredPositions(itemRects, containerWidth) {\n const rowMap = {};\n\n // Populate rows by their offset because items could jump between rows like:\n // a c\n // bbb\n itemRects.forEach((itemRect) => {\n if (rowMap[itemRect.top]) {\n // Push the point to the last row array.\n rowMap[itemRect.top].push(itemRect);\n } else {\n // Start of a new row.\n rowMap[itemRect.top] = [itemRect];\n }\n });\n\n // For each row, find the end of the last item, then calculate\n // the remaining space by dividing it by 2. Then add that\n // offset to the x position of each point.\n let rects = [];\n const rows = [];\n const centeredRows = [];\n Object.keys(rowMap).forEach((key) => {\n const itemRects = rowMap[key];\n rows.push(itemRects);\n const lastItem = itemRects[itemRects.length - 1];\n const end = lastItem.left + lastItem.width;\n const offset = Math.round((containerWidth - end) / 2);\n\n let finalRects = itemRects;\n let canMove = false;\n if (offset > 0) {\n const newRects = [];\n canMove = itemRects.every((r) => {\n const newRect = new Rect(r.left + offset, r.top, r.width, r.height, r.id);\n\n // Check all current rects to make sure none overlap.\n const noOverlap = !rects.some((r) => Rect.intersects(newRect, r));\n\n newRects.push(newRect);\n return noOverlap;\n });\n\n // If none of the rectangles overlapped, the whole group can be centered.\n if (canMove) {\n finalRects = newRects;\n }\n }\n\n // If the items are not going to be offset, ensure that the original\n // placement for this row will not overlap previous rows (row-spanning\n // elements could be in the way).\n if (!canMove) {\n let intersectingRect;\n const hasOverlap = itemRects.some((itemRect) => rects.some((r) => {\n const intersects = Rect.intersects(itemRect, r);\n if (intersects) {\n intersectingRect = r;\n }\n return intersects;\n }));\n\n // If there is any overlap, replace the overlapping row with the original.\n if (hasOverlap) {\n const rowIndex = centeredRows.findIndex((items) => items.includes(intersectingRect));\n centeredRows.splice(rowIndex, 1, rows[rowIndex]);\n }\n }\n\n rects = rects.concat(finalRects);\n centeredRows.push(finalRects);\n });\n\n // Reduce array of arrays to a single array of points.\n // https://stackoverflow.com/a/10865042/373422\n // Then reset sort back to how the items were passed to this method.\n // Remove the wrapper object with index, map to a Point.\n return [].concat.apply([], centeredRows) // eslint-disable-line prefer-spread\n .sort((a, b) => (a.id - b.id))\n .map((itemRect) => new Point(itemRect.left, itemRect.top));\n}\n","export default function arrayMin(array) {\n return Math.min.apply(Math, array); // eslint-disable-line prefer-spread\n}\n","import TinyEmitter from 'tiny-emitter';\nimport matches from 'matches-selector';\nimport throttle from 'throttleit';\nimport parallel from 'array-parallel';\n\nimport Point from './point';\nimport Rect from './rect';\nimport ShuffleItem from './shuffle-item';\nimport Classes from './classes';\nimport getNumberStyle from './get-number-style';\nimport sorter from './sorter';\nimport { onTransitionEnd, cancelTransitionEnd } from './on-transition-end';\nimport {\n getItemPosition,\n getColumnSpan,\n getAvailablePositions,\n getShortColumn,\n getCenteredPositions,\n} from './layout';\nimport arrayMax from './array-max';\nimport hyphenate from './hyphenate';\n\nfunction arrayUnique(x) {\n return Array.from(new Set(x));\n}\n\n// Used for unique instance variables\nlet id = 0;\n\nclass Shuffle extends TinyEmitter {\n /**\n * Categorize, sort, and filter a responsive grid of items.\n *\n * @param {Element} element An element which is the parent container for the grid items.\n * @param {Object} [options=Shuffle.options] Options object.\n * @constructor\n */\n constructor(element, options = {}) {\n super();\n // eslint-disable-next-line prefer-object-spread\n this.options = Object.assign({}, Shuffle.options, options);\n\n // Allow misspelling of delimiter since that's how it used to be.\n // Remove in v6.\n if (this.options.delimeter) {\n this.options.delimiter = this.options.delimeter;\n }\n\n this.lastSort = {};\n this.group = Shuffle.ALL_ITEMS;\n this.lastFilter = Shuffle.ALL_ITEMS;\n this.isEnabled = true;\n this.isDestroyed = false;\n this.isInitialized = false;\n this._transitions = [];\n this.isTransitioning = false;\n this._queue = [];\n\n const el = this._getElementOption(element);\n\n if (!el) {\n throw new TypeError('Shuffle needs to be initialized with an element.');\n }\n\n this.element = el;\n this.id = 'shuffle_' + id;\n id += 1;\n\n this._init();\n this.isInitialized = true;\n }\n\n _init() {\n this.items = this._getItems();\n\n this.options.sizer = this._getElementOption(this.options.sizer);\n\n // Add class and invalidate styles\n this.element.classList.add(Shuffle.Classes.BASE);\n\n // Set initial css for each item\n this._initItems(this.items);\n\n // Bind resize events\n this._onResize = this._getResizeFunction();\n window.addEventListener('resize', this._onResize);\n\n // If the page has not already emitted the `load` event, call layout on load.\n // This avoids layout issues caused by images and fonts loading after the\n // instance has been initialized.\n if (document.readyState !== 'complete') {\n const layout = this.layout.bind(this);\n window.addEventListener('load', function onLoad() {\n window.removeEventListener('load', onLoad);\n layout();\n });\n }\n\n // Get container css all in one request. Causes reflow\n const containerCss = window.getComputedStyle(this.element, null);\n const containerWidth = Shuffle.getSize(this.element).width;\n\n // Add styles to the container if it doesn't have them.\n this._validateStyles(containerCss);\n\n // We already got the container's width above, no need to cause another\n // reflow getting it again... Calculate the number of columns there will be\n this._setColumns(containerWidth);\n\n // Kick off!\n this.filter(this.options.group, this.options.initialSort);\n\n // The shuffle items haven't had transitions set on them yet so the user\n // doesn't see the first layout. Set them now that the first layout is done.\n // First, however, a synchronous layout must be caused for the previous\n // styles to be applied without transitions.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n this.setItemTransitions(this.items);\n this.element.style.transition = `height ${this.options.speed}ms ${this.options.easing}`;\n }\n\n /**\n * Returns a throttled and proxied function for the resize handler.\n * @return {function}\n * @private\n */\n _getResizeFunction() {\n const resizeFunction = this._handleResize.bind(this);\n return this.options.throttle\n ? this.options.throttle(resizeFunction, this.options.throttleTime)\n : resizeFunction;\n }\n\n /**\n * Retrieve an element from an option.\n * @param {string|jQuery|Element} option The option to check.\n * @return {?Element} The plain element or null.\n * @private\n */\n _getElementOption(option) {\n // If column width is a string, treat is as a selector and search for the\n // sizer element within the outermost container\n if (typeof option === 'string') {\n return this.element.querySelector(option);\n }\n\n // Check for an element\n if (option && option.nodeType && option.nodeType === 1) {\n return option;\n }\n\n // Check for jQuery object\n if (option && option.jquery) {\n return option[0];\n }\n\n return null;\n }\n\n /**\n * Ensures the shuffle container has the css styles it needs applied to it.\n * @param {Object} styles Key value pairs for position and overflow.\n * @private\n */\n _validateStyles(styles) {\n // Position cannot be static.\n if (styles.position === 'static') {\n this.element.style.position = 'relative';\n }\n\n // Overflow has to be hidden.\n if (styles.overflow !== 'hidden') {\n this.element.style.overflow = 'hidden';\n }\n }\n\n /**\n * Filter the elements by a category.\n * @param {string|string[]|function(Element):boolean} [category] Category to\n * filter by. If it's given, the last category will be used to filter the items.\n * @param {Array} [collection] Optionally filter a collection. Defaults to\n * all the items.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _filter(category = this.lastFilter, collection = this.items) {\n const set = this._getFilteredSets(category, collection);\n\n // Individually add/remove hidden/visible classes\n this._toggleFilterClasses(set);\n\n // Save the last filter in case elements are appended.\n this.lastFilter = category;\n\n // This is saved mainly because providing a filter function (like searching)\n // will overwrite the `lastFilter` property every time its called.\n if (typeof category === 'string') {\n this.group = category;\n }\n\n return set;\n }\n\n /**\n * Returns an object containing the visible and hidden elements.\n * @param {string|string[]|function(Element):boolean} category Category or function to filter by.\n * @param {ShuffleItem[]} items A collection of items to filter.\n * @return {{visible: ShuffleItem[], hidden: ShuffleItem[]}}\n * @private\n */\n _getFilteredSets(category, items) {\n let visible = [];\n const hidden = [];\n\n // category === 'all', add visible class to everything\n if (category === Shuffle.ALL_ITEMS) {\n visible = items;\n\n // Loop through each item and use provided function to determine\n // whether to hide it or not.\n } else {\n items.forEach((item) => {\n if (this._doesPassFilter(category, item.element)) {\n visible.push(item);\n } else {\n hidden.push(item);\n }\n });\n }\n\n return {\n visible,\n hidden,\n };\n }\n\n /**\n * Test an item to see if it passes a category.\n * @param {string|string[]|function():boolean} category Category or function to filter by.\n * @param {Element} element An element to test.\n * @return {boolean} Whether it passes the category/filter.\n * @private\n */\n _doesPassFilter(category, element) {\n if (typeof category === 'function') {\n return category.call(element, element, this);\n }\n\n // Check each element's data-groups attribute against the given category.\n const attr = element.getAttribute('data-' + Shuffle.FILTER_ATTRIBUTE_KEY);\n const keys = this.options.delimiter\n ? attr.split(this.options.delimiter)\n : JSON.parse(attr);\n\n function testCategory(category) {\n return keys.includes(category);\n }\n\n if (Array.isArray(category)) {\n if (this.options.filterMode === Shuffle.FilterMode.ANY) {\n return category.some(testCategory);\n }\n return category.every(testCategory);\n }\n\n return keys.includes(category);\n }\n\n /**\n * Toggles the visible and hidden class names.\n * @param {{visible, hidden}} Object with visible and hidden arrays.\n * @private\n */\n _toggleFilterClasses({ visible, hidden }) {\n visible.forEach((item) => {\n item.show();\n });\n\n hidden.forEach((item) => {\n item.hide();\n });\n }\n\n /**\n * Set the initial css for each item\n * @param {ShuffleItem[]} items Set to initialize.\n * @private\n */\n _initItems(items) {\n items.forEach((item) => {\n item.init();\n });\n }\n\n /**\n * Remove element reference and styles.\n * @param {ShuffleItem[]} items Set to dispose.\n * @private\n */\n _disposeItems(items) {\n items.forEach((item) => {\n item.dispose();\n });\n }\n\n /**\n * Updates the visible item count.\n * @private\n */\n _updateItemCount() {\n this.visibleItems = this._getFilteredItems().length;\n }\n\n /**\n * Sets css transform transition on a group of elements. This is not executed\n * at the same time as `item.init` so that transitions don't occur upon\n * initialization of a new Shuffle instance.\n * @param {ShuffleItem[]} items Shuffle items to set transitions on.\n * @protected\n */\n setItemTransitions(items) {\n const { speed, easing } = this.options;\n const positionProps = this.options.useTransforms ? ['transform'] : ['top', 'left'];\n\n // Allow users to transtion other properties if they exist in the `before`\n // css mapping of the shuffle item.\n const cssProps = Object.keys(ShuffleItem.Css.HIDDEN.before).map((k) => hyphenate(k));\n const properties = positionProps.concat(cssProps).join();\n\n items.forEach((item) => {\n item.element.style.transitionDuration = speed + 'ms';\n item.element.style.transitionTimingFunction = easing;\n item.element.style.transitionProperty = properties;\n });\n }\n\n _getItems() {\n return Array.from(this.element.children)\n .filter((el) => matches(el, this.options.itemSelector))\n .map((el) => new ShuffleItem(el, this.options));\n }\n\n /**\n * Combine the current items array with a new one and sort it by DOM order.\n * @param {ShuffleItem[]} items Items to track.\n * @return {ShuffleItem[]}\n */\n _mergeNewItems(items) {\n const children = Array.from(this.element.children);\n return sorter(this.items.concat(items), {\n by(element) {\n return children.indexOf(element);\n },\n });\n }\n\n _getFilteredItems() {\n return this.items.filter((item) => item.isVisible);\n }\n\n _getConcealedItems() {\n return this.items.filter((item) => !item.isVisible);\n }\n\n /**\n * Returns the column size, based on column width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @param {number} gutterSize Size of the gutters.\n * @return {number}\n * @private\n */\n _getColumnSize(containerWidth, gutterSize) {\n let size;\n\n // If the columnWidth property is a function, then the grid is fluid\n if (typeof this.options.columnWidth === 'function') {\n size = this.options.columnWidth(containerWidth);\n\n // columnWidth option isn't a function, are they using a sizing element?\n } else if (this.options.sizer) {\n size = Shuffle.getSize(this.options.sizer).width;\n\n // if not, how about the explicitly set option?\n } else if (this.options.columnWidth) {\n size = this.options.columnWidth;\n\n // or use the size of the first item\n } else if (this.items.length > 0) {\n size = Shuffle.getSize(this.items[0].element, true).width;\n\n // if there's no items, use size of container\n } else {\n size = containerWidth;\n }\n\n // Don't let them set a column width of zero.\n if (size === 0) {\n size = containerWidth;\n }\n\n return size + gutterSize;\n }\n\n /**\n * Returns the gutter size, based on gutter width and sizer options.\n * @param {number} containerWidth Size of the parent container.\n * @return {number}\n * @private\n */\n _getGutterSize(containerWidth) {\n let size;\n if (typeof this.options.gutterWidth === 'function') {\n size = this.options.gutterWidth(containerWidth);\n } else if (this.options.sizer) {\n size = getNumberStyle(this.options.sizer, 'marginLeft');\n } else {\n size = this.options.gutterWidth;\n }\n\n return size;\n }\n\n /**\n * Calculate the number of columns to be used. Gets css if using sizer element.\n * @param {number} [containerWidth] Optionally specify a container width if\n * it's already available.\n */\n _setColumns(containerWidth = Shuffle.getSize(this.element).width) {\n const gutter = this._getGutterSize(containerWidth);\n const columnWidth = this._getColumnSize(containerWidth, gutter);\n let calculatedColumns = (containerWidth + gutter) / columnWidth;\n\n // Widths given from getStyles are not precise enough...\n if (Math.abs(Math.round(calculatedColumns) - calculatedColumns)\n < this.options.columnThreshold) {\n // e.g. calculatedColumns = 11.998876\n calculatedColumns = Math.round(calculatedColumns);\n }\n\n this.cols = Math.max(Math.floor(calculatedColumns || 0), 1);\n this.containerWidth = containerWidth;\n this.colWidth = columnWidth;\n }\n\n /**\n * Adjust the height of the grid\n */\n _setContainerSize() {\n this.element.style.height = this._getContainerSize() + 'px';\n }\n\n /**\n * Based on the column heights, it returns the biggest one.\n * @return {number}\n * @private\n */\n _getContainerSize() {\n return arrayMax(this.positions);\n }\n\n /**\n * Get the clamped stagger amount.\n * @param {number} index Index of the item to be staggered.\n * @return {number}\n */\n _getStaggerAmount(index) {\n return Math.min(index * this.options.staggerAmount, this.options.staggerAmountMax);\n }\n\n /**\n * Emit an event from this instance.\n * @param {string} name Event name.\n * @param {Object} [data={}] Optional object data.\n */\n _dispatch(name, data = {}) {\n if (this.isDestroyed) {\n return;\n }\n\n data.shuffle = this;\n this.emit(name, data);\n }\n\n /**\n * Zeros out the y columns array, which is used to determine item placement.\n * @private\n */\n _resetCols() {\n let i = this.cols;\n this.positions = [];\n while (i) {\n i -= 1;\n this.positions.push(0);\n }\n }\n\n /**\n * Loops through each item that should be shown and calculates the x, y position.\n * @param {ShuffleItem[]} items Array of items that will be shown/layed\n * out in order in their array.\n */\n _layout(items) {\n const itemPositions = this._getNextPositions(items);\n\n let count = 0;\n items.forEach((item, i) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.VISIBLE.after);\n }\n\n // If the item will not change its position, do not add it to the render\n // queue. Transitions don't fire when setting a property to the same value.\n if (Point.equals(item.point, itemPositions[i]) && !item.isHidden) {\n item.applyCss(ShuffleItem.Css.VISIBLE.before);\n callback();\n return;\n }\n\n item.point = itemPositions[i];\n item.scale = ShuffleItem.Scale.VISIBLE;\n item.isHidden = false;\n\n // Clone the object so that the `before` object isn't modified when the\n // transition delay is added.\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.VISIBLE.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Return an array of Point instances representing the future positions of\n * each item.\n * @param {ShuffleItem[]} items Array of sorted shuffle items.\n * @return {Point[]}\n * @private\n */\n _getNextPositions(items) {\n // If position data is going to be changed, add the item's size to the\n // transformer to allow for calculations.\n if (this.options.isCentered) {\n const itemsData = items.map((item, i) => {\n const itemSize = Shuffle.getSize(item.element, true);\n const point = this._getItemPosition(itemSize);\n return new Rect(point.x, point.y, itemSize.width, itemSize.height, i);\n });\n\n return this.getTransformedPositions(itemsData, this.containerWidth);\n }\n\n // If no transforms are going to happen, simply return an array of the\n // future points of each item.\n return items.map((item) => this._getItemPosition(Shuffle.getSize(item.element, true)));\n }\n\n /**\n * Determine the location of the next item, based on its size.\n * @param {{width: number, height: number}} itemSize Object with width and height.\n * @return {Point}\n * @private\n */\n _getItemPosition(itemSize) {\n return getItemPosition({\n itemSize,\n positions: this.positions,\n gridSize: this.colWidth,\n total: this.cols,\n threshold: this.options.columnThreshold,\n buffer: this.options.buffer,\n });\n }\n\n /**\n * Mutate positions before they're applied.\n * @param {Rect[]} itemRects Item data objects.\n * @param {number} containerWidth Width of the containing element.\n * @return {Point[]}\n * @protected\n */\n getTransformedPositions(itemRects, containerWidth) {\n return getCenteredPositions(itemRects, containerWidth);\n }\n\n /**\n * Hides the elements that don't match our filter.\n * @param {ShuffleItem[]} collection Collection to shrink.\n * @private\n */\n _shrink(collection = this._getConcealedItems()) {\n let count = 0;\n collection.forEach((item) => {\n function callback() {\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n }\n\n // Continuing would add a transitionend event listener to the element, but\n // that listener would not execute because the transform and opacity would\n // stay the same.\n // The callback is executed here because it is not guaranteed to be called\n // after the transitionend event because the transitionend could be\n // canceled if another animation starts.\n if (item.isHidden) {\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n callback();\n return;\n }\n\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n\n const styles = this.getStylesForTransition(item, ShuffleItem.Css.HIDDEN.before);\n styles.transitionDelay = this._getStaggerAmount(count) + 'ms';\n\n this._queue.push({\n item,\n styles,\n callback,\n });\n\n count += 1;\n });\n }\n\n /**\n * Resize handler.\n * @private\n */\n _handleResize() {\n // If shuffle is disabled, destroyed, don't do anything\n if (!this.isEnabled || this.isDestroyed) {\n return;\n }\n\n this.update();\n }\n\n /**\n * Returns styles which will be applied to the an item for a transition.\n * @param {ShuffleItem} item Item to get styles for. Should have updated\n * scale and point properties.\n * @param {Object} styleObject Extra styles that will be used in the transition.\n * @return {!Object} Transforms for transitions, left/top for animate.\n * @protected\n */\n getStylesForTransition(item, styleObject) {\n // Clone the object to avoid mutating the original.\n // eslint-disable-next-line prefer-object-spread\n const styles = Object.assign({}, styleObject);\n\n if (this.options.useTransforms) {\n const sign = this.options.isRTL ? '-' : '';\n const x = this.options.roundTransforms ? Math.round(item.point.x) : item.point.x;\n const y = this.options.roundTransforms ? Math.round(item.point.y) : item.point.y;\n styles.transform = `translate(${sign}${x}px, ${y}px) scale(${item.scale})`;\n } else {\n if (this.options.isRTL) {\n styles.right = item.point.x + 'px';\n } else {\n styles.left = item.point.x + 'px';\n }\n styles.top = item.point.y + 'px';\n }\n\n return styles;\n }\n\n /**\n * Listen for the transition end on an element and execute the itemCallback\n * when it finishes.\n * @param {Element} element Element to listen on.\n * @param {function} itemCallback Callback for the item.\n * @param {function} done Callback to notify `parallel` that this one is done.\n */\n _whenTransitionDone(element, itemCallback, done) {\n const id = onTransitionEnd(element, (evt) => {\n itemCallback();\n done(null, evt);\n });\n\n this._transitions.push(id);\n }\n\n /**\n * Return a function which will set CSS styles and call the `done` function\n * when (if) the transition finishes.\n * @param {Object} opts Transition object.\n * @return {function} A function to be called with a `done` function.\n */\n _getTransitionFunction(opts) {\n return (done) => {\n opts.item.applyCss(opts.styles);\n this._whenTransitionDone(opts.item.element, opts.callback, done);\n };\n }\n\n /**\n * Execute the styles gathered in the style queue. This applies styles to elements,\n * triggering transitions.\n * @private\n */\n _processQueue() {\n if (this.isTransitioning) {\n this._cancelMovement();\n }\n\n const hasSpeed = this.options.speed > 0;\n const hasQueue = this._queue.length > 0;\n\n if (hasQueue && hasSpeed && this.isInitialized) {\n this._startTransitions(this._queue);\n } else if (hasQueue) {\n this._styleImmediately(this._queue);\n this._dispatch(Shuffle.EventType.LAYOUT);\n\n // A call to layout happened, but none of the newly visible items will\n // change position or the transition duration is zero, which will not trigger\n // the transitionend event.\n } else {\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n // Remove everything in the style queue\n this._queue.length = 0;\n }\n\n /**\n * Wait for each transition to finish, the emit the layout event.\n * @param {Object[]} transitions Array of transition objects.\n */\n _startTransitions(transitions) {\n // Set flag that shuffle is currently in motion.\n this.isTransitioning = true;\n\n // Create an array of functions to be called.\n const callbacks = transitions.map((obj) => this._getTransitionFunction(obj));\n\n parallel(callbacks, this._movementFinished.bind(this));\n }\n\n _cancelMovement() {\n // Remove the transition end event for each listener.\n this._transitions.forEach(cancelTransitionEnd);\n\n // Reset the array.\n this._transitions.length = 0;\n\n // Show it's no longer active.\n this.isTransitioning = false;\n }\n\n /**\n * Apply styles without a transition.\n * @param {Object[]} objects Array of transition objects.\n * @private\n */\n _styleImmediately(objects) {\n if (objects.length) {\n const elements = objects.map((obj) => obj.item.element);\n\n Shuffle._skipTransitions(elements, () => {\n objects.forEach((obj) => {\n obj.item.applyCss(obj.styles);\n obj.callback();\n });\n });\n }\n }\n\n _movementFinished() {\n this._transitions.length = 0;\n this.isTransitioning = false;\n this._dispatch(Shuffle.EventType.LAYOUT);\n }\n\n /**\n * The magic. This is what makes the plugin 'shuffle'\n * @param {string|string[]|function(Element):boolean} [category] Category to filter by.\n * Can be a function, string, or array of strings.\n * @param {SortOptions} [sortOptions] A sort object which can sort the visible set\n */\n filter(category, sortOptions) {\n if (!this.isEnabled) {\n return;\n }\n\n if (!category || (category && category.length === 0)) {\n category = Shuffle.ALL_ITEMS; // eslint-disable-line no-param-reassign\n }\n\n this._filter(category);\n\n // Shrink each hidden item\n this._shrink();\n\n // How many visible elements?\n this._updateItemCount();\n\n // Update transforms on visible elements so they will animate to their new positions.\n this.sort(sortOptions);\n }\n\n /**\n * Gets the visible elements, sorts them, and passes them to layout.\n * @param {SortOptions} [sortOptions] The options object to pass to `sorter`.\n */\n sort(sortOptions = this.lastSort) {\n if (!this.isEnabled) {\n return;\n }\n\n this._resetCols();\n\n const items = sorter(this._getFilteredItems(), sortOptions);\n\n this._layout(items);\n\n // `_layout` always happens after `_shrink`, so it's safe to process the style\n // queue here with styles from the shrink method.\n this._processQueue();\n\n // Adjust the height of the container.\n this._setContainerSize();\n\n this.lastSort = sortOptions;\n }\n\n /**\n * Reposition everything.\n * @param {boolean} [isOnlyLayout=false] If true, column and gutter widths won't be recalculated.\n */\n update(isOnlyLayout = false) {\n if (this.isEnabled) {\n if (!isOnlyLayout) {\n // Get updated colCount\n this._setColumns();\n }\n\n // Layout items\n this.sort();\n }\n }\n\n /**\n * Use this instead of `update()` if you don't need the columns and gutters updated\n * Maybe an image inside `shuffle` loaded (and now has a height), which means calculations\n * could be off.\n */\n layout() {\n this.update(true);\n }\n\n /**\n * New items have been appended to shuffle. Mix them in with the current\n * filter or sort status.\n * @param {Element[]} newItems Collection of new items.\n */\n add(newItems) {\n const items = arrayUnique(newItems).map((el) => new ShuffleItem(el, this.options));\n\n // Add classes and set initial positions.\n this._initItems(items);\n\n // Determine which items will go with the current filter.\n this._resetCols();\n\n const allItems = this._mergeNewItems(items);\n const sortedItems = sorter(allItems, this.lastSort);\n const allSortedItemsSet = this._filter(this.lastFilter, sortedItems);\n\n const isNewItem = (item) => items.includes(item);\n const applyHiddenState = (item) => {\n item.scale = ShuffleItem.Scale.HIDDEN;\n item.isHidden = true;\n item.applyCss(ShuffleItem.Css.HIDDEN.before);\n item.applyCss(ShuffleItem.Css.HIDDEN.after);\n };\n\n // Layout all items again so that new items get positions.\n // Synchonously apply positions.\n const itemPositions = this._getNextPositions(allSortedItemsSet.visible);\n allSortedItemsSet.visible.forEach((item, i) => {\n if (isNewItem(item)) {\n item.point = itemPositions[i];\n applyHiddenState(item);\n item.applyCss(this.getStylesForTransition(item, {}));\n }\n });\n\n allSortedItemsSet.hidden.forEach((item) => {\n if (isNewItem(item)) {\n applyHiddenState(item);\n }\n });\n\n // Cause layout so that the styles above are applied.\n this.element.offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Add transition to each item.\n this.setItemTransitions(items);\n\n // Update the list of items.\n this.items = this._mergeNewItems(items);\n\n // Update layout/visibility of new and old items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Disables shuffle from updating dimensions and layout on resize\n */\n disable() {\n this.isEnabled = false;\n }\n\n /**\n * Enables shuffle again\n * @param {boolean} [isUpdateLayout=true] if undefined, shuffle will update columns and gutters\n */\n enable(isUpdateLayout = true) {\n this.isEnabled = true;\n if (isUpdateLayout) {\n this.update();\n }\n }\n\n /**\n * Remove 1 or more shuffle items.\n * @param {Element[]} elements An array containing one or more\n * elements in shuffle\n * @return {Shuffle} The shuffle instance.\n */\n remove(elements) {\n if (!elements.length) {\n return;\n }\n\n const collection = arrayUnique(elements);\n\n const oldItems = collection\n .map((element) => this.getItemByElement(element))\n .filter((item) => !!item);\n\n const handleLayout = () => {\n this._disposeItems(oldItems);\n\n // Remove the collection in the callback\n collection.forEach((element) => {\n element.parentNode.removeChild(element);\n });\n\n this._dispatch(Shuffle.EventType.REMOVED, { collection });\n };\n\n // Hide collection first.\n this._toggleFilterClasses({\n visible: [],\n hidden: oldItems,\n });\n\n this._shrink(oldItems);\n\n this.sort();\n\n // Update the list of items here because `remove` could be called again\n // with an item that is in the process of being removed.\n this.items = this.items.filter((item) => !oldItems.includes(item));\n this._updateItemCount();\n\n this.once(Shuffle.EventType.LAYOUT, handleLayout);\n }\n\n /**\n * Retrieve a shuffle item by its element.\n * @param {Element} element Element to look for.\n * @return {?ShuffleItem} A shuffle item or undefined if it's not found.\n */\n getItemByElement(element) {\n return this.items.find((item) => item.element === element);\n }\n\n /**\n * Dump the elements currently stored and reinitialize all child elements which\n * match the `itemSelector`.\n */\n resetItems() {\n // Remove refs to current items.\n this._disposeItems(this.items);\n this.isInitialized = false;\n\n // Find new items in the DOM.\n this.items = this._getItems();\n\n // Set initial styles on the new items.\n this._initItems(this.items);\n\n this.once(Shuffle.EventType.LAYOUT, () => {\n // Add transition to each item.\n this.setItemTransitions(this.items);\n this.isInitialized = true;\n });\n\n // Lay out all items.\n this.filter(this.lastFilter);\n }\n\n /**\n * Destroys shuffle, removes events, styles, and classes\n */\n destroy() {\n this._cancelMovement();\n window.removeEventListener('resize', this._onResize);\n\n // Reset container styles\n this.element.classList.remove('shuffle');\n this.element.removeAttribute('style');\n\n // Reset individual item styles\n this._disposeItems(this.items);\n\n this.items.length = 0;\n this._transitions.length = 0;\n\n // Null DOM references\n this.options.sizer = null;\n this.element = null;\n\n // Set a flag so if a debounced resize has been triggered,\n // it can first check if it is actually isDestroyed and not doing anything\n this.isDestroyed = true;\n this.isEnabled = false;\n }\n\n /**\n * Returns the outer width of an element, optionally including its margins.\n *\n * There are a few different methods for getting the width of an element, none of\n * which work perfectly for all Shuffle's use cases.\n *\n * 1. getBoundingClientRect() `left` and `right` properties.\n * - Accounts for transform scaled elements, making it useless for Shuffle\n * elements which have shrunk.\n * 2. The `offsetWidth` property.\n * - This value stays the same regardless of the elements transform property,\n * however, it does not return subpixel values.\n * 3. getComputedStyle()\n * - This works great Chrome, Firefox, Safari, but IE<=11 does not include\n * padding and border when box-sizing: border-box is set, requiring a feature\n * test and extra work to add the padding back for IE and other browsers which\n * follow the W3C spec here.\n *\n * @param {Element} element The element.\n * @param {boolean} [includeMargins=false] Whether to include margins.\n * @return {{width: number, height: number}} The width and height.\n */\n static getSize(element, includeMargins = false) {\n // Store the styles so that they can be used by others without asking for it again.\n const styles = window.getComputedStyle(element, null);\n let width = getNumberStyle(element, 'width', styles);\n let height = getNumberStyle(element, 'height', styles);\n\n if (includeMargins) {\n const marginLeft = getNumberStyle(element, 'marginLeft', styles);\n const marginRight = getNumberStyle(element, 'marginRight', styles);\n const marginTop = getNumberStyle(element, 'marginTop', styles);\n const marginBottom = getNumberStyle(element, 'marginBottom', styles);\n width += marginLeft + marginRight;\n height += marginTop + marginBottom;\n }\n\n return {\n width,\n height,\n };\n }\n\n /**\n * Change a property or execute a function which will not have a transition\n * @param {Element[]} elements DOM elements that won't be transitioned.\n * @param {function} callback A function which will be called while transition\n * is set to 0ms.\n * @private\n */\n static _skipTransitions(elements, callback) {\n const zero = '0ms';\n\n // Save current duration and delay.\n const data = elements.map((element) => {\n const { style } = element;\n const duration = style.transitionDuration;\n const delay = style.transitionDelay;\n\n // Set the duration to zero so it happens immediately\n style.transitionDuration = zero;\n style.transitionDelay = zero;\n\n return {\n duration,\n delay,\n };\n });\n\n callback();\n\n // Cause forced synchronous layout.\n elements[0].offsetWidth; // eslint-disable-line no-unused-expressions\n\n // Put the duration back\n elements.forEach((element, i) => {\n element.style.transitionDuration = data[i].duration;\n element.style.transitionDelay = data[i].delay;\n });\n }\n}\n\nShuffle.ShuffleItem = ShuffleItem;\n\nShuffle.ALL_ITEMS = 'all';\nShuffle.FILTER_ATTRIBUTE_KEY = 'groups';\n\n/** @enum {string} */\nShuffle.EventType = {\n LAYOUT: 'shuffle:layout',\n REMOVED: 'shuffle:removed',\n};\n\n/** @enum {string} */\nShuffle.Classes = Classes;\n\n/** @enum {string} */\nShuffle.FilterMode = {\n ANY: 'any',\n ALL: 'all',\n};\n\n// Overrideable options\nShuffle.options = {\n // Initial filter group.\n group: Shuffle.ALL_ITEMS,\n\n // Transition/animation speed (milliseconds).\n speed: 250,\n\n // CSS easing function to use.\n easing: 'cubic-bezier(0.4, 0.0, 0.2, 1)',\n\n // e.g. '.picture-item'.\n itemSelector: '*',\n\n // Element or selector string. Use an element to determine the size of columns\n // and gutters.\n sizer: null,\n\n // A static number or function that tells the plugin how wide the gutters\n // between columns are (in pixels).\n gutterWidth: 0,\n\n // A static number or function that returns a number which tells the plugin\n // how wide the columns are (in pixels).\n columnWidth: 0,\n\n // If your group is not json, and is comma delimeted, you could set delimiter\n // to ','.\n delimiter: null,\n\n // Useful for percentage based heights when they might not always be exactly\n // the same (in pixels).\n buffer: 0,\n\n // Reading the width of elements isn't precise enough and can cause columns to\n // jump between values.\n columnThreshold: 0.01,\n\n // Shuffle can be isInitialized with a sort object. It is the same object\n // given to the sort method.\n initialSort: null,\n\n // By default, shuffle will throttle resize events. This can be changed or\n // removed.\n throttle,\n\n // How often shuffle can be called on resize (in milliseconds).\n throttleTime: 300,\n\n // Transition delay offset for each item in milliseconds.\n staggerAmount: 15,\n\n // Maximum stagger delay in milliseconds.\n staggerAmountMax: 150,\n\n // Whether to use transforms or absolute positioning.\n useTransforms: true,\n\n // Affects using an array with filter. e.g. `filter(['one', 'two'])`. With \"any\",\n // the element passes the test if any of its groups are in the array. With \"all\",\n // the element only passes if all groups are in the array.\n filterMode: Shuffle.FilterMode.ANY,\n\n // Attempt to center grid items in each row.\n isCentered: false,\n\n // Attempt to align grid items to right.\n isRTL: false,\n\n // Whether to round pixel values used in translate(x, y). This usually avoids\n // blurriness.\n roundTransforms: true,\n};\n\nShuffle.Point = Point;\nShuffle.Rect = Rect;\n\n// Expose for testing. Hack at your own risk.\nShuffle.__sorter = sorter;\nShuffle.__getColumnSpan = getColumnSpan;\nShuffle.__getAvailablePositions = getAvailablePositions;\nShuffle.__getShortColumn = getShortColumn;\nShuffle.__getCenteredPositions = getCenteredPositions;\n\nexport default Shuffle;\n","/**\n * Hyphenates a javascript style string to a css one. For example:\n * MozBoxSizing -> -moz-box-sizing.\n * @param {string} str The string to hyphenate.\n * @return {string} The hyphenated string.\n */\nexport default function hyphenate(str) {\n return str.replace(/([A-Z])/g, (str, m1) => `-${m1.toLowerCase()}`);\n}\n"],"names":["E","prototype","on","name","callback","ctx","e","this","push","fn","once","self","listener","off","apply","arguments","_","emit","data","slice","call","evtArr","i","len","length","evts","liveEvents","proto","Element","vendor","matches","matchesSelector","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","el","selector","nodeType","nodes","parentNode","querySelectorAll","func","wait","args","rtn","timeoutID","last","delta","Date","setTimeout","noop","getNumber","value","parseFloat","Point","constructor","x","y","a","b","Rect","w","h","id","left","top","width","height","BASE","SHUFFLE_ITEM","VISIBLE","HIDDEN","ShuffleItem","element","isRTL","isVisible","isHidden","show","classList","remove","Classes","add","removeAttribute","hide","setAttribute","init","addClasses","applyCss","Css","INITIAL","DIRECTION","rtl","ltr","scale","Scale","point","classes","forEach","className","removeClasses","obj","Object","keys","key","style","dispose","position","visibility","willChange","right","before","opacity","after","transitionDelay","document","body","documentElement","createElement","cssText","appendChild","window","getComputedStyle","removeChild","getNumberStyle","styles","testComputedSize","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","defaults","reverse","by","compare","randomize","sorter","arr","options","opts","assign","original","Array","from","revert","array","n","Math","floor","random","temp","sort","valA","valB","undefined","transitions","eventName","count","cancelTransitionEnd","removeEventListener","onTransitionEnd","evt","currentTarget","target","addEventListener","arrayMax","max","getColumnSpan","itemWidth","columnWidth","columns","threshold","columnSpan","abs","round","min","ceil","getAvailablePositions","positions","available","getShortColumn","buffer","minPosition","getCenteredPositions","itemRects","containerWidth","rowMap","itemRect","rects","rows","centeredRows","lastItem","end","offset","finalRects","canMove","newRects","every","r","newRect","noOverlap","some","intersects","intersectingRect","rowIndex","findIndex","items","includes","splice","concat","map","arrayUnique","Set","Shuffle","TinyEmitter","delimeter","delimiter","lastSort","group","ALL_ITEMS","lastFilter","isEnabled","isDestroyed","isInitialized","_transitions","isTransitioning","_queue","_getElementOption","TypeError","_init","_getItems","sizer","_initItems","_onResize","_getResizeFunction","readyState","layout","bind","onLoad","containerCss","getSize","_validateStyles","_setColumns","filter","initialSort","offsetWidth","setItemTransitions","transition","speed","easing","resizeFunction","_handleResize","throttle","throttleTime","option","querySelector","jquery","overflow","_filter","category","collection","set","_getFilteredSets","_toggleFilterClasses","visible","hidden","item","_doesPassFilter","attr","getAttribute","FILTER_ATTRIBUTE_KEY","split","JSON","parse","testCategory","isArray","filterMode","FilterMode","ANY","_disposeItems","_updateItemCount","visibleItems","_getFilteredItems","positionProps","useTransforms","cssProps","k","replace","str","m1","toLowerCase","properties","join","transitionDuration","transitionTimingFunction","transitionProperty","children","itemSelector","_mergeNewItems","indexOf","_getConcealedItems","_getColumnSize","gutterSize","size","_getGutterSize","gutterWidth","gutter","calculatedColumns","columnThreshold","cols","colWidth","_setContainerSize","_getContainerSize","_getStaggerAmount","index","staggerAmount","staggerAmountMax","_dispatch","shuffle","_resetCols","_layout","itemPositions","_getNextPositions","equals","getStylesForTransition","isCentered","itemsData","itemSize","_getItemPosition","getTransformedPositions","gridSize","total","span","setY","shortColumnIndex","setHeight","getItemPosition","_shrink","update","styleObject","sign","roundTransforms","transform","_whenTransitionDone","itemCallback","done","_getTransitionFunction","_processQueue","_cancelMovement","hasSpeed","hasQueue","_startTransitions","_styleImmediately","EventType","LAYOUT","fns","context","pending","finished","results","maybeDone","err","result","parallel","_movementFinished","objects","elements","_skipTransitions","sortOptions","isOnlyLayout","newItems","sortedItems","allSortedItemsSet","isNewItem","applyHiddenState","disable","enable","isUpdateLayout","oldItems","getItemByElement","REMOVED","find","resetItems","destroy","includeMargins","duration","delay","ALL","__sorter","__getColumnSpan","__getAvailablePositions","__getShortColumn","__getCenteredPositions"],"mappings":"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"} \ No newline at end of file