{"version":3,"file":"fjGallery.min.js","sources":["../src/utils/global.js","../node_modules/throttle-debounce/esm/index.js","../node_modules/raf-schd/dist/raf-schd.esm.js","../node_modules/better-justified-layout/dist/better-justified-layout.js","../src/utils/get-img-dimensions.js","../src/fjGallery.js","../src/utils/ready.js","../src/fjGallery.umd.js"],"sourcesContent":["/* eslint-disable import/no-mutable-exports */\n/* eslint-disable no-restricted-globals */\nlet win;\n\nif (typeof window !== 'undefined') {\n  win = window;\n} else if (typeof global !== 'undefined') {\n  win = global;\n} else if (typeof self !== 'undefined') {\n  win = self;\n} else {\n  win = {};\n}\n\nexport default win;\n","/* eslint-disable no-undefined,no-param-reassign,no-shadow */\n\n/**\n * Throttle execution of a function. Especially useful for rate limiting\n * execution of handlers on events like resize and scroll.\n *\n * @param {number} delay -                  A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher)\n *                                            are most useful.\n * @param {Function} callback -               A function to be executed after delay milliseconds. The `this` context and all arguments are passed through,\n *                                            as-is, to `callback` when the throttled-function is executed.\n * @param {object} [options] -              An object to configure options.\n * @param {boolean} [options.noTrailing] -   Optional, defaults to false. If noTrailing is true, callback will only execute every `delay` milliseconds\n *                                            while the throttled-function is being called. If noTrailing is false or unspecified, callback will be executed\n *                                            one final time after the last throttled-function call. (After the throttled-function has not been called for\n *                                            `delay` milliseconds, the internal counter is reset).\n * @param {boolean} [options.noLeading] -   Optional, defaults to false. If noLeading is false, the first throttled-function call will execute callback\n *                                            immediately. If noLeading is true, the first the callback execution will be skipped. It should be noted that\n *                                            callback will never executed if both noLeading = true and noTrailing = true.\n * @param {boolean} [options.debounceMode] - If `debounceMode` is true (at begin), schedule `clear` to execute after `delay` ms. If `debounceMode` is\n *                                            false (at end), schedule `callback` to execute after `delay` ms.\n *\n * @returns {Function} A new, throttled, function.\n */\nfunction throttle (delay, callback, options) {\n  var _ref = options || {},\n      _ref$noTrailing = _ref.noTrailing,\n      noTrailing = _ref$noTrailing === void 0 ? false : _ref$noTrailing,\n      _ref$noLeading = _ref.noLeading,\n      noLeading = _ref$noLeading === void 0 ? false : _ref$noLeading,\n      _ref$debounceMode = _ref.debounceMode,\n      debounceMode = _ref$debounceMode === void 0 ? undefined : _ref$debounceMode;\n  /*\n   * After wrapper has stopped being called, this timeout ensures that\n   * `callback` is executed at the proper times in `throttle` and `end`\n   * debounce modes.\n   */\n\n\n  var timeoutID;\n  var cancelled = false; // Keep track of the last time `callback` was executed.\n\n  var lastExec = 0; // Function to clear existing timeout\n\n  function clearExistingTimeout() {\n    if (timeoutID) {\n      clearTimeout(timeoutID);\n    }\n  } // Function to cancel next exec\n\n\n  function cancel(options) {\n    var _ref2 = options || {},\n        _ref2$upcomingOnly = _ref2.upcomingOnly,\n        upcomingOnly = _ref2$upcomingOnly === void 0 ? false : _ref2$upcomingOnly;\n\n    clearExistingTimeout();\n    cancelled = !upcomingOnly;\n  }\n  /*\n   * The `wrapper` function encapsulates all of the throttling / debouncing\n   * functionality and when executed will limit the rate at which `callback`\n   * is executed.\n   */\n\n\n  function wrapper() {\n    for (var _len = arguments.length, arguments_ = new Array(_len), _key = 0; _key < _len; _key++) {\n      arguments_[_key] = arguments[_key];\n    }\n\n    var self = this;\n    var elapsed = Date.now() - lastExec;\n\n    if (cancelled) {\n      return;\n    } // Execute `callback` and update the `lastExec` timestamp.\n\n\n    function exec() {\n      lastExec = Date.now();\n      callback.apply(self, arguments_);\n    }\n    /*\n     * If `debounceMode` is true (at begin) this is used to clear the flag\n     * to allow future `callback` executions.\n     */\n\n\n    function clear() {\n      timeoutID = undefined;\n    }\n\n    if (!noLeading && debounceMode && !timeoutID) {\n      /*\n       * Since `wrapper` is being called for the first time and\n       * `debounceMode` is true (at begin), execute `callback`\n       * and noLeading != true.\n       */\n      exec();\n    }\n\n    clearExistingTimeout();\n\n    if (debounceMode === undefined && elapsed > delay) {\n      if (noLeading) {\n        /*\n         * In throttle mode with noLeading, if `delay` time has\n         * been exceeded, update `lastExec` and schedule `callback`\n         * to execute after `delay` ms.\n         */\n        lastExec = Date.now();\n\n        if (!noTrailing) {\n          timeoutID = setTimeout(debounceMode ? clear : exec, delay);\n        }\n      } else {\n        /*\n         * In throttle mode without noLeading, if `delay` time has been exceeded, execute\n         * `callback`.\n         */\n        exec();\n      }\n    } else if (noTrailing !== true) {\n      /*\n       * In trailing throttle mode, since `delay` time has not been\n       * exceeded, schedule `callback` to execute `delay` ms after most\n       * recent execution.\n       *\n       * If `debounceMode` is true (at begin), schedule `clear` to execute\n       * after `delay` ms.\n       *\n       * If `debounceMode` is false (at end), schedule `callback` to\n       * execute after `delay` ms.\n       */\n      timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay);\n    }\n  }\n\n  wrapper.cancel = cancel; // Return the wrapper function.\n\n  return wrapper;\n}\n\n/* eslint-disable no-undefined */\n/**\n * Debounce execution of a function. Debouncing, unlike throttling,\n * guarantees that a function is only executed a single time, either at the\n * very beginning of a series of calls, or at the very end.\n *\n * @param {number} delay -               A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful.\n * @param {Function} callback -          A function to be executed after delay milliseconds. The `this` context and all arguments are passed through, as-is,\n *                                        to `callback` when the debounced-function is executed.\n * @param {object} [options] -           An object to configure options.\n * @param {boolean} [options.atBegin] -  Optional, defaults to false. If atBegin is false or unspecified, callback will only be executed `delay` milliseconds\n *                                        after the last debounced-function call. If atBegin is true, callback will be executed only at the first debounced-function call.\n *                                        (After the throttled-function has not been called for `delay` milliseconds, the internal counter is reset).\n *\n * @returns {Function} A new, debounced function.\n */\n\nfunction debounce (delay, callback, options) {\n  var _ref = options || {},\n      _ref$atBegin = _ref.atBegin,\n      atBegin = _ref$atBegin === void 0 ? false : _ref$atBegin;\n\n  return throttle(delay, callback, {\n    debounceMode: atBegin !== false\n  });\n}\n\nexport { debounce, throttle };\n//# sourceMappingURL=index.js.map\n","var rafSchd = function rafSchd(fn) {\n  var lastArgs = [];\n  var frameId = null;\n\n  var wrapperFn = function wrapperFn() {\n    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n      args[_key] = arguments[_key];\n    }\n\n    lastArgs = args;\n\n    if (frameId) {\n      return;\n    }\n\n    frameId = requestAnimationFrame(function () {\n      frameId = null;\n      fn.apply(void 0, lastArgs);\n    });\n  };\n\n  wrapperFn.cancel = function () {\n    if (!frameId) {\n      return;\n    }\n\n    cancelAnimationFrame(frameId);\n    frameId = null;\n  };\n\n  return wrapperFn;\n};\n\nexport default rafSchd;\n","'use strict';\n\n/**\n * Row\n * Wrapper for each row in a justified layout.\n * Stores relevant values and provides methods for calculating layout of individual rows.\n *\n * @param {Object} layoutConfig - The same as that passed\n * @param {Object} Initialization parameters. The following are all required:\n * @param params.index {Number} The index of this row\n * @param params.top {Number} Top of row, relative to container\n * @param params.left {Number} Left side of row relative to container (equal to container left padding)\n * @param params.width {Number} Width of row, not including container padding\n * @param params.spacing {Number} Horizontal spacing between items\n * @param params.targetRowHeight {Number} Layout algorithm will aim for this row height\n * @param params.targetRowHeightTolerance {Number} Row heights may vary +/- (`targetRowHeight` x `targetRowHeightTolerance`)\n * @param params.edgeCaseMinRowHeight {Number} Absolute minimum row height for edge cases that cannot be resolved within tolerance.\n * @param params.edgeCaseMaxRowHeight {Number} Absolute maximum row height for edge cases that cannot be resolved within tolerance.\n * @param params.isBreakoutRow {Boolean} Is this row in particular one of those breakout rows? Always false if it's not that kind of photo list\n * @param params.widowLayoutStyle {String} If widows are visible, how should they be laid out?\n * @constructor\n */\nconst Row = function (params) {\n  // The index of this row\n  this.index = params.index;\n\n  // Top of row, relative to container\n  this.top = params.top;\n\n  // Left side of row relative to container (equal to container left padding)\n  this.left = params.left;\n\n  // Width of row, not including container padding\n  this.width = params.width;\n\n  // Horizontal spacing between items\n  this.spacing = params.spacing;\n\n  // Row height calculation values\n  this.targetRowHeight = params.targetRowHeight;\n  this.targetRowHeightTolerance = params.targetRowHeightTolerance;\n  this.minAspectRatio = this.width / params.targetRowHeight * (1 - params.targetRowHeightTolerance);\n  this.maxAspectRatio = this.width / params.targetRowHeight * (1 + params.targetRowHeightTolerance);\n\n  // Edge case row height minimum/maximum\n  this.edgeCaseMinRowHeight = params.edgeCaseMinRowHeight;\n  this.edgeCaseMaxRowHeight = params.edgeCaseMaxRowHeight;\n\n  // Widow layout direction\n  this.widowLayoutStyle = params.widowLayoutStyle;\n\n  // Full width breakout rows\n  this.isBreakoutRow = params.isBreakoutRow;\n\n  // Store layout data for each item in row\n  this.items = [];\n\n  // Height remains at 0 until it's been calculated\n  this.height = 0;\n};\nRow.prototype = {\n  /**\n   * Attempt to add a single item to the row.\n   * This is the heart of the justified algorithm.\n   * This method is direction-agnostic; it deals only with sizes, not positions.\n   *\n   * If the item fits in the row, without pushing row height beyond min/max tolerance,\n   * the item is added and the method returns true.\n   *\n   * If the item leaves row height too high, there may be room to scale it down and add another item.\n   * In this case, the item is added and the method returns true, but the row is incomplete.\n   *\n   * If the item leaves row height too short, there are too many items to fit within tolerance.\n   * The method will either accept or reject the new item, favoring the resulting row height closest to within tolerance.\n   * If the item is rejected, left/right padding will be required to fit the row height within tolerance;\n   * if the item is accepted, top/bottom cropping will be required to fit the row height within tolerance.\n   *\n   * @method addItem\n   * @param itemData {Object} Item layout data, containing item aspect ratio.\n   * @return {Boolean} True if successfully added; false if rejected.\n   */\n  addItem: function (itemData) {\n    const newItems = this.items.concat(itemData);\n    // Calculate aspect ratios for items only; exclude spacing\n    const rowWidthWithoutSpacing = this.width - (newItems.length - 1) * this.spacing;\n    const newAspectRatio = newItems.reduce(function (sum, item) {\n      return sum + item.aspectRatio;\n    }, 0);\n    const targetAspectRatio = rowWidthWithoutSpacing / this.targetRowHeight;\n    let previousRowWidthWithoutSpacing;\n    let previousAspectRatio;\n    let previousTargetAspectRatio;\n\n    // Handle big full-width breakout photos if we're doing them\n    if (this.isBreakoutRow) {\n      // Only do it if there's no other items in this row\n      if (this.items.length === 0) {\n        // Only go full width if this photo is a square or landscape\n        if (itemData.aspectRatio >= 1) {\n          // Close out the row with a full width photo\n          this.items.push(itemData);\n          this.completeLayout(rowWidthWithoutSpacing / itemData.aspectRatio, \"justify\");\n          return true;\n        }\n      }\n    }\n    if (newAspectRatio < this.minAspectRatio) {\n      // New aspect ratio is too narrow / scaled row height is too tall.\n      // Accept this item and leave row open for more items.\n\n      this.items.push(Object.assign({}, itemData));\n      return true;\n    } else if (newAspectRatio > this.maxAspectRatio) {\n      // New aspect ratio is too wide / scaled row height will be too short.\n      // Accept item if the resulting aspect ratio is closer to target than it would be without the item.\n      // NOTE: Any row that falls into this block will require cropping/padding on individual items.\n\n      if (this.items.length === 0) {\n        // When there are no existing items, force acceptance of the new item and complete the layout.\n        // This is the pano special case.\n        this.items.push(Object.assign({}, itemData));\n        this.completeLayout(rowWidthWithoutSpacing / newAspectRatio, \"justify\");\n        return true;\n      }\n\n      // Calculate width/aspect ratio for row before adding new item\n      previousRowWidthWithoutSpacing = this.width - (this.items.length - 1) * this.spacing;\n      previousAspectRatio = this.items.reduce(function (sum, item) {\n        return sum + item.aspectRatio;\n      }, 0);\n      previousTargetAspectRatio = previousRowWidthWithoutSpacing / this.targetRowHeight;\n      if (Math.abs(newAspectRatio - targetAspectRatio) > Math.abs(previousAspectRatio - previousTargetAspectRatio)) {\n        // Row with new item is us farther away from target than row without; complete layout and reject item.\n        this.completeLayout(previousRowWidthWithoutSpacing / previousAspectRatio, \"justify\");\n        return false;\n      } else {\n        // Row with new item is us closer to target than row without;\n        // accept the new item and complete the row layout.\n        this.items.push(Object.assign({}, itemData));\n        this.completeLayout(rowWidthWithoutSpacing / newAspectRatio, \"justify\");\n        return true;\n      }\n    } else {\n      // New aspect ratio / scaled row height is within tolerance;\n      // accept the new item and complete the row layout.\n      this.items.push(Object.assign({}, itemData));\n      this.completeLayout(rowWidthWithoutSpacing / newAspectRatio, \"justify\");\n      return true;\n    }\n  },\n  /**\n   * Check if a row has completed its layout.\n   *\n   * @method isLayoutComplete\n   * @return {Boolean} True if complete; false if not.\n   */\n  isLayoutComplete: function () {\n    return this.height > 0;\n  },\n  /**\n   * Set row height and compute item geometry from that height.\n   * Will justify items within the row unless instructed not to.\n   *\n   * @method completeLayout\n   * @param newHeight {Number} Set row height to this value.\n   * @param widowLayoutStyle {String} How should widows display? Supported: left | justify | center\n   */\n  completeLayout: function (newHeight, widowLayoutStyle) {\n    let itemWidthSum = this.left;\n    const rowWidthWithoutSpacing = this.width - (this.items.length - 1) * this.spacing;\n    let clampedToNativeRatio;\n    let clampedHeight;\n    let errorWidthPerItem;\n    let roundedCumulativeErrors;\n    let singleItemGeometry;\n    let centerOffset;\n\n    // Justify unless explicitly specified otherwise.\n    if (typeof widowLayoutStyle === \"undefined\" || [\"justify\", \"center\", \"left\"].indexOf(widowLayoutStyle) < 0) {\n      widowLayoutStyle = \"left\";\n    }\n\n    // Clamp row height to edge case minimum/maximum.\n    clampedHeight = Math.max(this.edgeCaseMinRowHeight, Math.min(newHeight, this.edgeCaseMaxRowHeight));\n    if (newHeight !== clampedHeight) {\n      // If row height was clamped, the resulting row/item aspect ratio will be off,\n      // so force it to fit the width (recalculate aspectRatio to match clamped height).\n      // NOTE: this will result in cropping/padding commensurate to the amount of clamping.\n      this.height = clampedHeight;\n      clampedToNativeRatio = rowWidthWithoutSpacing / clampedHeight / (rowWidthWithoutSpacing / newHeight);\n    } else {\n      // If not clamped, leave ratio at 1.0.\n      this.height = newHeight;\n      clampedToNativeRatio = 1.0;\n    }\n\n    // Compute item geometry based on newHeight.\n    this.items.forEach(function (item) {\n      item.row = this.index;\n      item.top = this.top;\n      item.width = item.aspectRatio * this.height * clampedToNativeRatio;\n      item.height = this.height;\n\n      // Left-to-right.\n      // TODO right to left\n      // item.left = this.width - itemWidthSum - item.width;\n      item.left = itemWidthSum;\n\n      // Increment width.\n      itemWidthSum += item.width + this.spacing;\n    }, this);\n\n    // If specified, ensure items fill row and distribute error\n    // caused by rounding width and height across all items.\n    if (widowLayoutStyle === \"justify\") {\n      itemWidthSum -= this.spacing + this.left;\n      errorWidthPerItem = (itemWidthSum - this.width) / this.items.length;\n      roundedCumulativeErrors = this.items.map(function (item, i) {\n        return Math.round((i + 1) * errorWidthPerItem);\n      });\n      if (this.items.length === 1) {\n        // For rows with only one item, adjust item width to fill row.\n        singleItemGeometry = this.items[0];\n        singleItemGeometry.width -= Math.round(errorWidthPerItem);\n      } else {\n        // For rows with multiple items, adjust item width and shift items to fill the row,\n        // while maintaining equal spacing between items in the row.\n        this.items.forEach(function (item, i) {\n          if (i > 0) {\n            item.left -= roundedCumulativeErrors[i - 1];\n            item.width -= roundedCumulativeErrors[i] - roundedCumulativeErrors[i - 1];\n          } else {\n            item.width -= roundedCumulativeErrors[i];\n          }\n        });\n      }\n    } else if (widowLayoutStyle === \"center\") {\n      // Center widows\n      centerOffset = (this.width - itemWidthSum) / 2;\n      this.items.forEach(function (item) {\n        item.left += centerOffset + this.spacing;\n      }, this);\n    }\n  },\n  /**\n   * Force completion of row layout with current items.\n   *\n   * @method forceComplete\n   * @param fitToWidth {Boolean} Stretch current items to fill the row width.\n   *                             This will likely result in padding.\n   * @param fitToWidth {Number}\n   */\n  forceComplete: function (fitToWidth, rowHeight) {\n    // TODO Handle fitting to width\n    // var rowWidthWithoutSpacing = this.width - (this.items.length - 1) * this.spacing,\n    // \tcurrentAspectRatio = this.items.reduce(function (sum, item) {\n    // \t\treturn sum + item.aspectRatio;\n    // \t}, 0);\n\n    if (typeof rowHeight === \"number\") {\n      this.completeLayout(rowHeight, this.widowLayoutStyle);\n    } else {\n      // Complete using target row height.\n      this.completeLayout(this.targetRowHeight, this.widowLayoutStyle);\n    }\n  },\n  /**\n   * Return layout data for items within row.\n   * Note: returns actual list, not a copy.\n   *\n   * @method getItems\n   * @return Layout data for items within row.\n   */\n  getItems: function () {\n    return this.items;\n  }\n};\n\n/*!\n * Copyright 2019 SmugMug, Inc. | Copyright 2024 nK\n * Licensed under the terms of the MIT license. Please see LICENSE file in the project root for terms.\n * @license\n */\n\n/**\n * Create a new, empty row.\n *\n * @method createNewRow\n * @param layoutConfig {Object} The layout configuration\n * @param layoutData {Object} The current state of the layout\n * @return A new, empty row of the type specified by this layout.\n */\nfunction createNewRow(layoutConfig, layoutData) {\n  let isBreakoutRow;\n\n  // Work out if this is a full width breakout row\n  if (layoutConfig.fullWidthBreakoutRowCadence !== false) {\n    if ((layoutData._rows.length + 1) % layoutConfig.fullWidthBreakoutRowCadence === 0) {\n      isBreakoutRow = true;\n    }\n  }\n  return new Row({\n    index: layoutData._rows.length,\n    top: layoutData._containerHeight,\n    left: layoutConfig.containerPadding.left,\n    width: layoutConfig.containerWidth - layoutConfig.containerPadding.left - layoutConfig.containerPadding.right,\n    spacing: layoutConfig.boxSpacing.horizontal,\n    targetRowHeight: layoutConfig.targetRowHeight,\n    targetRowHeightTolerance: layoutConfig.targetRowHeightTolerance,\n    edgeCaseMinRowHeight: layoutConfig.edgeCaseMinRowHeight * layoutConfig.targetRowHeight,\n    edgeCaseMaxRowHeight: layoutConfig.edgeCaseMaxRowHeight * layoutConfig.targetRowHeight,\n    rightToLeft: false,\n    isBreakoutRow: isBreakoutRow,\n    widowLayoutStyle: layoutConfig.widowLayoutStyle\n  });\n}\n\n/**\n * Add a completed row to the layout.\n * Note: the row must have already been completed.\n *\n * @method addRow\n * @param layoutConfig {Object} The layout configuration\n * @param layoutData {Object} The current state of the layout\n * @param row {Row} The row to add.\n * @return {Array} Each item added to the row.\n */\nfunction addRow(layoutConfig, layoutData, row) {\n  layoutData._rows.push(row);\n  layoutData._layoutItems = layoutData._layoutItems.concat(row.getItems());\n\n  // Increment the container height\n  layoutData._containerHeight += row.height + layoutConfig.boxSpacing.vertical;\n  return row.items;\n}\n\n/**\n * Calculate the current layout for all items in the list that require layout.\n * \"Layout\" means geometry: position within container and size\n *\n * @method computeLayout\n * @param layoutConfig {Object} The layout configuration\n * @param layoutData {Object} The current state of the layout\n * @param itemLayoutData {Array} Array of items to lay out, with data required to lay out each item\n * @return {Object} The newly-calculated layout, containing the new container height, and lists of layout items\n */\nfunction computeLayout(layoutConfig, layoutData, itemLayoutData) {\n  let laidOutItems = [];\n  let itemAdded;\n  let currentRow;\n  let nextToLastRowHeight;\n\n  // Apply forced aspect ratio if specified, and set a flag.\n  if (layoutConfig.forceAspectRatio) {\n    itemLayoutData.forEach(function (itemData) {\n      itemData.forcedAspectRatio = true;\n      itemData.aspectRatio = layoutConfig.forceAspectRatio;\n    });\n  }\n\n  // Loop through the items\n  itemLayoutData.some(function (itemData, i) {\n    if (isNaN(itemData.aspectRatio)) {\n      throw new Error(\"Item \" + i + \" has an invalid aspect ratio\");\n    }\n\n    // If not currently building up a row, make a new one.\n    if (!currentRow) {\n      currentRow = createNewRow(layoutConfig, layoutData);\n    }\n\n    // Attempt to add item to the current row.\n    itemAdded = currentRow.addItem(itemData);\n    if (currentRow.isLayoutComplete()) {\n      // Row is filled; add it and start a new one\n      laidOutItems = laidOutItems.concat(addRow(layoutConfig, layoutData, currentRow));\n      if (layoutData._rows.length >= layoutConfig.maxNumRows) {\n        currentRow = null;\n        return true;\n      }\n      currentRow = createNewRow(layoutConfig, layoutData);\n\n      // Item was rejected; add it to its own row\n      if (!itemAdded) {\n        itemAdded = currentRow.addItem(itemData);\n        if (currentRow.isLayoutComplete()) {\n          // If the rejected item fills a row on its own, add the row and start another new one\n          laidOutItems = laidOutItems.concat(addRow(layoutConfig, layoutData, currentRow));\n          if (layoutData._rows.length >= layoutConfig.maxNumRows) {\n            currentRow = null;\n            return true;\n          }\n          currentRow = createNewRow(layoutConfig, layoutData);\n        }\n      }\n    }\n  });\n\n  // Handle any leftover content (orphans) depending on where they lie\n  // in this layout update, and in the total content set.\n  if (currentRow && currentRow.getItems().length && layoutConfig.showWidows) {\n    // Last page of all content or orphan suppression is suppressed; lay out orphans.\n    if (layoutData._rows.length) {\n      // Only Match previous row's height if it exists and it isn't a breakout row\n      if (layoutData._rows[layoutData._rows.length - 1].isBreakoutRow) {\n        nextToLastRowHeight = layoutData._rows[layoutData._rows.length - 1].targetRowHeight;\n      } else {\n        nextToLastRowHeight = layoutData._rows[layoutData._rows.length - 1].height;\n      }\n      currentRow.forceComplete(false, nextToLastRowHeight);\n    } else {\n      // ...else use target height if there is no other row height to reference.\n      currentRow.forceComplete(false);\n    }\n    laidOutItems = laidOutItems.concat(addRow(layoutConfig, layoutData, currentRow));\n    layoutConfig._widowCount = currentRow.getItems().length;\n  }\n\n  // We need to clean up the bottom container padding\n  // First remove the height added for box spacing\n  layoutData._containerHeight = layoutData._containerHeight - layoutConfig.boxSpacing.vertical;\n  // Then add our bottom container padding\n  layoutData._containerHeight = layoutData._containerHeight + layoutConfig.containerPadding.bottom;\n  return {\n    containerHeight: layoutData._containerHeight,\n    widowCount: layoutConfig._widowCount,\n    boxes: layoutData._layoutItems\n  };\n}\n\n/**\n * Takes in a bunch of box data and config. Returns\n * geometry to lay them out in a justified view.\n *\n * @method covertSizesToAspectRatios\n * @param sizes {Array} Array of objects with widths and heights\n * @return {Array} A list of aspect ratios\n */\nfunction index (input, config) {\n  let layoutConfig = {};\n  const layoutData = {};\n\n  // Defaults\n  const defaults = {\n    containerWidth: 1060,\n    containerPadding: 10,\n    boxSpacing: 10,\n    targetRowHeight: 320,\n    targetRowHeightTolerance: 0.25,\n    edgeCaseMinRowHeight: 0.5,\n    edgeCaseMaxRowHeight: 2.5,\n    maxNumRows: Number.POSITIVE_INFINITY,\n    forceAspectRatio: false,\n    showWidows: true,\n    fullWidthBreakoutRowCadence: false,\n    widowLayoutStyle: \"left\"\n  };\n  const containerPadding = {};\n  const boxSpacing = {};\n  config = config || {};\n\n  // Merge defaults and config passed in\n  layoutConfig = Object.assign(defaults, config);\n\n  // Sort out padding and spacing values\n  containerPadding.top = !isNaN(parseFloat(layoutConfig.containerPadding.top)) ? layoutConfig.containerPadding.top : layoutConfig.containerPadding;\n  containerPadding.right = !isNaN(parseFloat(layoutConfig.containerPadding.right)) ? layoutConfig.containerPadding.right : layoutConfig.containerPadding;\n  containerPadding.bottom = !isNaN(parseFloat(layoutConfig.containerPadding.bottom)) ? layoutConfig.containerPadding.bottom : layoutConfig.containerPadding;\n  containerPadding.left = !isNaN(parseFloat(layoutConfig.containerPadding.left)) ? layoutConfig.containerPadding.left : layoutConfig.containerPadding;\n  boxSpacing.horizontal = !isNaN(parseFloat(layoutConfig.boxSpacing.horizontal)) ? layoutConfig.boxSpacing.horizontal : layoutConfig.boxSpacing;\n  boxSpacing.vertical = !isNaN(parseFloat(layoutConfig.boxSpacing.vertical)) ? layoutConfig.boxSpacing.vertical : layoutConfig.boxSpacing;\n  layoutConfig.containerPadding = containerPadding;\n  layoutConfig.boxSpacing = boxSpacing;\n\n  // Local\n  layoutData._layoutItems = [];\n  layoutData._awakeItems = [];\n  layoutData._inViewportItems = [];\n  layoutData._leadingOrphans = [];\n  layoutData._trailingOrphans = [];\n  layoutData._containerHeight = layoutConfig.containerPadding.top;\n  layoutData._rows = [];\n  layoutData._orphans = [];\n  layoutConfig._widowCount = 0;\n\n  // Convert widths and heights to aspect ratios if we need to\n  return computeLayout(layoutConfig, layoutData, input.map(function (item) {\n    if (item.width && item.height) {\n      return {\n        aspectRatio: item.width / item.height\n      };\n    } else {\n      return {\n        aspectRatio: item\n      };\n    }\n  }));\n}\n\nmodule.exports = index;\n//# sourceMappingURL=better-justified-layout.js.map\n","// get image dimensions\n// thanks https://gist.github.com/dimsemenov/5382856\nfunction getImgDimensions(img, cb) {\n  let interval;\n  let hasSize = false;\n  let addedListeners = false;\n\n  const onHasSize = () => {\n    if (hasSize) {\n      cb(hasSize);\n      return;\n    }\n\n    // check for non-zero, non-undefined naturalWidth\n    if (!img.naturalWidth) {\n      return;\n    }\n\n    hasSize = {\n      width: img.naturalWidth,\n      height: img.naturalHeight,\n    };\n    cb(hasSize);\n\n    clearInterval(interval);\n    if (addedListeners) {\n      // eslint-disable-next-line no-use-before-define\n      removeListeners();\n    }\n  };\n  const onLoaded = () => {\n    onHasSize();\n  };\n  const onError = () => {\n    onHasSize();\n  };\n  const checkSize = () => {\n    if (img.naturalWidth > 0) {\n      onHasSize();\n    }\n  };\n  const addListeners = () => {\n    addedListeners = true;\n    img.addEventListener('load', onLoaded);\n    img.addEventListener('error', onError);\n  };\n  const removeListeners = () => {\n    addedListeners = false;\n    img.removeEventListener('load', onLoaded);\n    img.removeEventListener('error', onError);\n  };\n\n  checkSize();\n\n  if (!hasSize) {\n    addListeners();\n    interval = setInterval(checkSize, 100);\n  }\n}\n\nexport default getImgDimensions;\n","import { debounce } from 'throttle-debounce';\nimport rafSchd from 'raf-schd';\nimport justifiedLayout from 'better-justified-layout';\n\nimport domReady from './utils/ready';\nimport global from './utils/global';\nimport getImgDimensions from './utils/get-img-dimensions';\n\n// list with all fjGallery instances\n// need to render all in one scroll/resize event\nconst fjGalleryList = [];\n\nconst updateFjGallery = rafSchd(() => {\n  fjGalleryList.forEach((item) => {\n    item.resize();\n  });\n});\n\nglobal.addEventListener('resize', updateFjGallery);\nglobal.addEventListener('orientationchange', updateFjGallery);\nglobal.addEventListener('load', updateFjGallery);\ndomReady(() => {\n  updateFjGallery();\n});\n\nlet instanceID = 0;\n\n// fjGallery class\nclass FJGallery {\n  constructor(container, userOptions) {\n    const self = this;\n\n    self.instanceID = instanceID;\n    instanceID += 1;\n\n    self.$container = container;\n\n    self.images = [];\n\n    self.defaults = {\n      itemSelector: '.fj-gallery-item',\n      imageSelector: 'img',\n      gutter: 10, // supports object like `{ horizontal: 10, vertical: 10 }`.\n      rowHeight: 320,\n      rowHeightTolerance: 0.25, // [0, 1]\n      maxRowsCount: Number.POSITIVE_INFINITY,\n      edgeCaseMinRowHeight: 0.5,\n      edgeCaseMaxRowHeight: 2.5,\n      lastRow: 'left', // left, center, right, hide\n      transitionDuration: '0.3s',\n      calculateItemsHeight: false,\n      resizeDebounce: 100,\n      isRtl: self.css(self.$container, 'direction') === 'rtl',\n\n      // events\n      onInit: null, // function() {}\n      onDestroy: null, // function() {}\n      onAppendImages: null, // function() {}\n      onBeforeJustify: null, // function() {}\n      onJustify: null, // function() {}\n    };\n\n    // prepare data-options\n    const dataOptions = self.$container.dataset || {};\n    const pureDataOptions = {};\n    Object.keys(dataOptions).forEach((key) => {\n      const loweCaseOption = key.substr(0, 1).toLowerCase() + key.substr(1);\n      if (loweCaseOption && typeof self.defaults[loweCaseOption] !== 'undefined') {\n        pureDataOptions[loweCaseOption] = dataOptions[key];\n      }\n    });\n\n    self.options = {\n      ...self.defaults,\n      ...pureDataOptions,\n      ...userOptions,\n    };\n\n    self.pureOptions = {\n      ...self.options,\n    };\n\n    // debounce for resize\n    self.resize = debounce(self.options.resizeDebounce, self.resize);\n    self.justify = rafSchd(self.justify.bind(self));\n\n    self.init();\n  }\n\n  // add styles to element\n  // eslint-disable-next-line class-methods-use-this\n  css(el, styles) {\n    if (typeof styles === 'string') {\n      return global.getComputedStyle(el).getPropertyValue(styles);\n    }\n\n    Object.keys(styles).forEach((key) => {\n      el.style[key] = styles[key];\n    });\n    return el;\n  }\n\n  // set temporary transition with event listener\n  applyTransition($item, properties) {\n    const self = this;\n\n    // Remove previous event listener\n    self.onTransitionEnd($item)();\n\n    // Add transitions\n    self.css($item, {\n      'transition-property': properties.join(', '),\n      'transition-duration': self.options.transitionDuration,\n    });\n\n    // Add event listener\n    $item.addEventListener('transitionend', self.onTransitionEnd($item, properties), false);\n  }\n\n  onTransitionEnd($item) {\n    const self = this;\n\n    return () => {\n      self.css($item, {\n        'transition-property': '',\n        'transition-duration': '',\n      });\n\n      $item.removeEventListener('transitionend', self.onTransitionEnd($item));\n    };\n  }\n\n  // add to fjGallery instances list\n  addToFjGalleryList() {\n    fjGalleryList.push(this);\n    updateFjGallery();\n  }\n\n  // remove from fjGallery instances list\n  removeFromFjGalleryList() {\n    const self = this;\n\n    fjGalleryList.forEach((item, key) => {\n      if (item.instanceID === self.instanceID) {\n        fjGalleryList.splice(key, 1);\n      }\n    });\n  }\n\n  init() {\n    const self = this;\n\n    self.appendImages(self.$container.querySelectorAll(self.options.itemSelector));\n\n    self.addToFjGalleryList();\n\n    // call onInit event\n    if (self.options.onInit) {\n      self.options.onInit.call(self);\n    }\n  }\n\n  // append images\n  appendImages($images) {\n    const self = this;\n\n    // check if jQuery\n    if (global.jQuery && $images instanceof global.jQuery) {\n      $images = $images.get();\n    }\n\n    if (!$images || !$images.length) {\n      return;\n    }\n\n    $images.forEach(($item) => {\n      // if $images is jQuery, for some reason in this array there is undefined item, that not a DOM,\n      // so we need to check for $item.querySelector.\n      if ($item && !$item.fjGalleryImage && $item.querySelector) {\n        const $image = $item.querySelector(self.options.imageSelector);\n\n        if ($image) {\n          $item.fjGalleryImage = self;\n          const data = {\n            $item,\n            $image,\n            width: parseFloat($image.getAttribute('width')) || false,\n            height: parseFloat($image.getAttribute('height')) || false,\n            loadSizes() {\n              const itemData = this;\n              getImgDimensions($image, (dimensions) => {\n                if (itemData.width !== dimensions.width || itemData.height !== dimensions.height) {\n                  itemData.width = dimensions.width;\n                  itemData.height = dimensions.height;\n                  self.resize();\n                }\n              });\n            },\n          };\n          data.loadSizes();\n\n          self.images.push(data);\n        }\n      }\n    });\n\n    // call onAppendImages event\n    if (self.options.onAppendImages) {\n      self.options.onAppendImages.call(self, [$images]);\n    }\n\n    self.justify();\n  }\n\n  // justify images\n  justify() {\n    const self = this;\n    const justifyArray = [];\n\n    self.justifyCount = (self.justifyCount || 0) + 1;\n\n    // call onBeforeJustify event\n    if (self.options.onBeforeJustify) {\n      self.options.onBeforeJustify.call(self);\n    }\n\n    self.images.forEach((data) => {\n      if (data.width && data.height) {\n        justifyArray.push(data.width / data.height);\n      }\n    });\n\n    const justifiedOptions = {\n      containerWidth: self.$container.getBoundingClientRect().width,\n      containerPadding: {\n        top: parseFloat(self.css(self.$container, 'padding-top')) || 0,\n        right: parseFloat(self.css(self.$container, 'padding-right')) || 0,\n        bottom: parseFloat(self.css(self.$container, 'padding-bottom')) || 0,\n        left: parseFloat(self.css(self.$container, 'padding-left')) || 0,\n      },\n      boxSpacing: self.options.gutter,\n      targetRowHeight: self.options.rowHeight,\n      targetRowHeightTolerance: self.options.rowHeightTolerance,\n      maxNumRows: self.options.maxRowsCount,\n      edgeCaseMinRowHeight: self.options.edgeCaseMinRowHeight,\n      edgeCaseMaxRowHeight: self.options.edgeCaseMaxRowHeight,\n      showWidows: self.options.lastRow !== 'hide',\n    };\n    const justifiedData = justifiedLayout(justifyArray, justifiedOptions);\n\n    // Align last row\n    if (\n      justifiedData.widowCount &&\n      (self.options.lastRow === 'center' || self.options.lastRow === 'right')\n    ) {\n      const lastItemData = justifiedData.boxes[justifiedData.boxes.length - 1];\n      let gapSize = justifiedOptions.containerWidth - lastItemData.width - lastItemData.left;\n\n      if (self.options.lastRow === 'center') {\n        gapSize /= 2;\n      }\n      if (self.options.lastRow === 'right') {\n        gapSize -= justifiedOptions.containerPadding.right;\n      }\n\n      for (let i = 1; i <= justifiedData.widowCount; i += 1) {\n        justifiedData.boxes[justifiedData.boxes.length - i].left =\n          justifiedData.boxes[justifiedData.boxes.length - i].left + gapSize;\n      }\n    }\n\n    // RTL compatibility\n    if (self.options.isRtl) {\n      justifiedData.boxes.forEach((boxData, i) => {\n        justifiedData.boxes[i].left =\n          justifiedOptions.containerWidth -\n          justifiedData.boxes[i].left -\n          justifiedData.boxes[i].width -\n          justifiedOptions.containerPadding.right +\n          justifiedOptions.containerPadding.left;\n      });\n    }\n\n    let i = 0;\n    let additionalTopOffset = 0;\n    const rowsMaxHeight = {};\n\n    // Set image sizes.\n    self.images.forEach((data, imgI) => {\n      if (justifiedData.boxes[i] && data.width && data.height) {\n        // calculate additional offset based on actual items height.\n        if (\n          self.options.calculateItemsHeight &&\n          typeof rowsMaxHeight[justifiedData.boxes[i].row] === 'undefined' &&\n          Object.keys(rowsMaxHeight).length\n        ) {\n          additionalTopOffset +=\n            rowsMaxHeight[Object.keys(rowsMaxHeight).pop()] - justifiedData.boxes[imgI - 1].height;\n        }\n\n        if (self.options.transitionDuration && self.justifyCount > 1) {\n          self.applyTransition(data.$item, ['transform']);\n        }\n\n        self.css(data.$item, {\n          display: '',\n          position: 'absolute',\n          transform: `translateX(${justifiedData.boxes[i].left}px) translateY(${\n            justifiedData.boxes[i].top + additionalTopOffset\n          }px) translateZ(0)`,\n          width: `${justifiedData.boxes[i].width}px`,\n        });\n\n        // calculate actual items height.\n        if (self.options.calculateItemsHeight) {\n          const rect = data.$item.getBoundingClientRect();\n\n          if (\n            typeof rowsMaxHeight[justifiedData.boxes[i].row] === 'undefined' ||\n            rowsMaxHeight[justifiedData.boxes[i].row] < rect.height\n          ) {\n            rowsMaxHeight[justifiedData.boxes[i].row] = rect.height;\n          }\n        }\n\n        i += 1;\n      } else {\n        self.css(data.$item, {\n          display: 'none',\n        });\n      }\n    });\n\n    // increase additional offset based on the latest row items height.\n    if (self.options.calculateItemsHeight && Object.keys(rowsMaxHeight).length) {\n      additionalTopOffset +=\n        rowsMaxHeight[Object.keys(rowsMaxHeight).pop()] -\n        justifiedData.boxes[justifiedData.boxes.length - 1].height;\n    }\n\n    if (self.options.transitionDuration) {\n      self.applyTransition(self.$container, ['height']);\n    }\n\n    // Set container height.\n    self.css(self.$container, {\n      height: `${justifiedData.containerHeight + additionalTopOffset}px`,\n    });\n\n    // call onJustify event\n    if (self.options.onJustify) {\n      self.options.onJustify.call(self);\n    }\n  }\n\n  // update options and resize gallery items\n  updateOptions(options) {\n    const self = this;\n    self.options = {\n      ...self.options,\n      ...options,\n    };\n    self.justify();\n  }\n\n  destroy() {\n    const self = this;\n\n    self.removeFromFjGalleryList();\n\n    self.justifyCount = 0;\n\n    // call onDestroy event\n    if (self.options.onDestroy) {\n      self.options.onDestroy.call(self);\n    }\n\n    // remove styles.\n    self.css(self.$container, {\n      height: '',\n      transition: '',\n    });\n    self.images.forEach((data) => {\n      self.css(data.$item, {\n        position: '',\n        transform: '',\n        transition: '',\n        width: '',\n        height: '',\n      });\n    });\n\n    // delete fjGalleryImage instance from images\n    self.images.forEach((val) => {\n      delete val.$item.fjGalleryImage;\n    });\n\n    // delete fjGallery instance from container\n    delete self.$container.fjGallery;\n  }\n\n  resize() {\n    const self = this;\n\n    self.justify();\n  }\n}\n\n// global definition\nconst fjGallery = function (items, options, ...args) {\n  // check for dom element\n  // thanks: http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object\n  if (\n    typeof HTMLElement === 'object'\n      ? items instanceof HTMLElement\n      : items &&\n        typeof items === 'object' &&\n        items !== null &&\n        items.nodeType === 1 &&\n        typeof items.nodeName === 'string'\n  ) {\n    items = [items];\n  }\n\n  const len = items.length;\n  let k = 0;\n  let ret;\n\n  for (k; k < len; k += 1) {\n    if (typeof options === 'object' || typeof options === 'undefined') {\n      if (!items[k].fjGallery) {\n        // eslint-disable-next-line new-cap\n        items[k].fjGallery = new FJGallery(items[k], options);\n      }\n    } else if (items[k].fjGallery) {\n      // eslint-disable-next-line prefer-spread\n      ret = items[k].fjGallery[options].apply(items[k].fjGallery, args);\n    }\n    if (typeof ret !== 'undefined') {\n      return ret;\n    }\n  }\n\n  return items;\n};\nfjGallery.constructor = FJGallery;\n\nexport default fjGallery;\n","function ready(callback) {\n  if (document.readyState === 'complete' || document.readyState === 'interactive') {\n    // Already ready or interactive, execute callback\n    callback();\n  } else {\n    document.addEventListener('DOMContentLoaded', callback, {\n      capture: true,\n      once: true,\n      passive: true,\n    });\n  }\n}\n\nexport default ready;\n","import global from './utils/global';\nimport fjGallery from './fjGallery';\n\nconst $ = global.jQuery;\n\n// jQuery support\nif (typeof $ !== 'undefined') {\n  // add data to jQuery .data('fjGallery')\n  const oldInit = fjGallery.constructor.prototype.init;\n  fjGallery.constructor.prototype.init = function () {\n    $(this.$container).data('fjGallery', this);\n\n    if (oldInit) {\n      oldInit.call(this);\n    }\n  };\n\n  // remove data from jQuery .data('fjGallery')\n  const oldDestroy = fjGallery.constructor.prototype.destroy;\n  fjGallery.constructor.prototype.destroy = function () {\n    if (this.$container) {\n      $(this.$container).removeData('fjGallery');\n    }\n    if (oldDestroy) {\n      oldDestroy.call(this);\n    }\n  };\n\n  const $Plugin = function (...args) {\n    Array.prototype.unshift.call(args, this);\n    const res = fjGallery.apply(global, args);\n    return typeof res !== 'object' ? res : this;\n  };\n  $Plugin.constructor = fjGallery.constructor;\n\n  // no conflict\n  const old$Plugin = $.fn.fjGallery;\n  $.fn.fjGallery = $Plugin;\n  $.fn.fjGallery.noConflict = function () {\n    $.fn.fjGallery = old$Plugin;\n    return this;\n  };\n}\n\nexport default fjGallery;\n"],"names":["win","window","global","self","global$1","delay","callback","options","timeoutID","_ref","_ref$noTrailing","noTrailing","_ref$noLeading","noLeading","_ref$debounceMode","debounceMode","undefined","cancelled","lastExec","clearExistingTimeout","clearTimeout","wrapper","_len","arguments","length","arguments_","Array","_key","this","elapsed","Date","now","exec","apply","clear","setTimeout","cancel","_ref2$upcomingOnly","upcomingOnly","rafSchd","fn","lastArgs","frameId","wrapperFn","args","requestAnimationFrame","cancelAnimationFrame","Row","params","index","top","left","width","spacing","targetRowHeight","targetRowHeightTolerance","maxAspectRatio","edgeCaseMaxRowHeight","widowLayoutStyle","isBreakoutRow","items","height","prototype","addItem","itemData","newItems","concat","rowWidthWithoutSpacing","targetAspectRatio","previousRowWidthWithoutSpacing","previousTargetAspectRatio","aspectRatio","push","completeLayout","newAspectRatio","minAspectRatio","Object","assign","previousAspectRatio","reduce","sum","item","Math","abs","isLayoutComplete","newHeight","itemWidthSum","clampedToNativeRatio","clampedHeight","errorWidthPerItem","roundedCumulativeErrors","centerOffset","indexOf","max","edgeCaseMinRowHeight","min","forEach","row","map","i","round","singleItemGeometry","forceComplete","fitToWidth","rowHeight","getItems","getImgDimensions","img","cb","interval","hasSize","addedListeners","onHasSize","naturalWidth","naturalHeight","clearInterval","removeListeners","onLoaded","onError","checkSize","removeEventListener","addEventListener","setInterval","fjGalleryList","updateFjGallery","resize","document","readyState","capture","once","passive","instanceID","FJGallery","constructor","container","userOptions","$container","images","defaults","itemSelector","imageSelector","gutter","rowHeightTolerance","maxRowsCount","Number","POSITIVE_INFINITY","lastRow","transitionDuration","calculateItemsHeight","resizeDebounce","isRtl","css","onInit","onDestroy","onAppendImages","onBeforeJustify","onJustify","dataOptions","dataset","pureDataOptions","keys","key","loweCaseOption","substr","toLowerCase","pureOptions","debounce","justify","bind","init","el","styles","getComputedStyle","getPropertyValue","style","applyTransition","$item","properties","onTransitionEnd","join","addToFjGalleryList","removeFromFjGalleryList","splice","appendImages","querySelectorAll","call","$images","jQuery","get","fjGalleryImage","querySelector","$image","data","parseFloat","getAttribute","loadSizes","dimensions","justifyArray","justifyCount","justifiedOptions","containerWidth","getBoundingClientRect","containerPadding","right","bottom","boxSpacing","maxNumRows","showWidows","justifiedData","justifiedLayout","widowCount","lastItemData","boxes","gapSize","boxData","additionalTopOffset","rowsMaxHeight","imgI","pop","display","position","transform","rect","containerHeight","updateOptions","destroy","transition","val","fjGallery","HTMLElement","nodeType","nodeName","len","ret","k","$","oldInit","oldDestroy","removeData","$Plugin","unshift","res","old$Plugin","noConflict"],"mappings":"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","x_google_ignoreList":[1,2,3]}