{"version":3,"file":"builder-prints-4f7d915d.js","sources":["../../../client/src/javascripts/customer_pages/_prints-builder/common/add-photos-device.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/prop-types.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/panda-view-simple-previews/panda-view-simple-preview.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/photo-quality/dpi-classification.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/photo-quality/dpi-notice.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/photo-quality/photo-dpi-notice.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/panda-view-simple-previews.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/desktop/photos-list/list-view-item-preview-and-controls.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/list-quantity-field-handlers.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/number-input-field/button.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/number-input-field/index.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/photo-quality/recommended-print-size-badge.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/desktop/photos-list/item-size.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/photo-modifications.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/reset-photo-edits.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/photo-filename.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/photo-quality/recommended-print-size.js","../../../client/src/javascripts/customer_pages/_prints-builder/desktop/photos-list/item.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/size-helpers.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/collect-by-root-image.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/photo-root-ids.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/quantity-helpers.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/totalizing-mixin.js","../../../client/src/javascripts/customer_pages/_prints-builder/desktop/photos-list.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/summary-table.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/totalizer.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/events/fire-tracking-event.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/add-to-cart-controls.jsx","../../../client/src/javascripts/customer_pages/_utils/shallow-comparator-mixin.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/upload-progress-bar.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/desktop/radio-button-group.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/finish-and-delivery-options.js","../../../client/src/javascripts/customer_pages/_prints-builder/desktop/options.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/invalid-sizes-modal.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/invalid-delivery-option-modal.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/photo-remove-confirmation-modal.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/photo-remove-confirmation.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/json-data-url.js","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/viewing-size-key.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/prints-builder-mixin.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/upload-photo-mixin/from-album-to-prints-loader.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/upload-photos-mixin.js","../../../client/src/javascripts/customer_pages/_prints-builder/desktop/_pricing-chart-popup.js","../../../client/src/javascripts/customer_pages/_prints-builder/desktop/pricing-chart-popup.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/bulk-quantity-change/size.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/bulk-quantity-change/index.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/desktop/summary-chart.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/desktop/loading-photo-placeholders.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/raw-image-cache.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/advanced-editor/cropper-convert.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/advanced-editor/snap-crop-to-bounds.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/advanced-editor/constants.js","../../../client/src/javascripts/customer_pages/_prints-builder/common/advanced-editor/controller.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/advanced-editor/image-cropper.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/advanced-editor/slider-scale.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/advanced-editor/slider-control.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/advanced-editor/filter-buttons.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/advanced-editor/navigation.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/desktop/advanced-editor/slider-controls-panel.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/advanced-editor/filters.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/advanced-editor/edit-buttons.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/advanced-editor/display-edit-value.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/advanced-editor/slider-control.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/advanced-editor/slider-and-buttons-panel.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/advanced-editor/header.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/advanced-editor/image-edit-preview.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/advanced-editor/index.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/print_finish_tabs.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/desktop/prints-builder.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/finish-selector.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/delivery-selector.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/photos-filter.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/photos-grid/photo/pending-photo.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/photos-grid/photo/editable-photo-buttons.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/photos-grid/photo/editable-photo.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/photos-grid/photo.jsx","../../../client/src/javascripts/customer_pages/_utils/paginator/use-pagination.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/print-count-display.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/glass/quantity-input.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/photos-grid/side-menu.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/render-size-button.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/resize-options-modal.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/footer.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/photos-grid/index.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/images-helper.js","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/prints-builder.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/glass/print-size-filter.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/photos-grid/photo/simple-thumbnail.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/multi-select/multi-select-modal.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/multi-select/use-multi-select.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/glass/preview-badges.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/glass/photo-list-view.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/summary-dropdown/options-wrapper.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/summary-dropdown/button-options.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/summary-dropdown/dropdown-options.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/summary-dropdown/index.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/glass/photo-selection-view.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/photos-grid/scroll-to-top-btn.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/with-gesture-actions.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/mobile/index.jsx","../../../client/src/javascripts/customer_pages/_prints-builder/common/debounced-scroll-handler.js","../../../client/src/javascripts/entry_points/builder-prints.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\n\nconst AddPhotosDevice = ({ onClick, buttonClassName }) => {\n  return (\n    <div className=\"add-photos-device d-flex flex-column align-items-center justify-content-center\">\n      <div className=\"add-photos-device__icon\" />\n      <p>No photos have been added</p>\n      <button\n        className={`btn add-photos ${buttonClassName}`}\n        onClick={onClick}>\n        Add Photos\n      </button>\n    </div>\n  );\n};\n\nAddPhotosDevice.propTypes = {\n  onClick: PropTypes.func.isRequired,\n  buttonClassName: PropTypes.string,\n}\n\nAddPhotosDevice.defaultProps = {\n  buttonClassName: 'btn-outline-secondary'\n}\n\nexport default AddPhotosDevice;\n","import PropTypes from 'prop-types';\n\nconst isObject = obj => {\n  return Object.prototype.toString.call(obj) == '[object Object]';\n};\n\nconst priceMap = (props, propName, componentName) => {\n  const error = new Error(\n    `Invalid prop values \\`${propName}\\` supplied to` +\n      ` \\`${componentName}\\`. Validation failed.`\n  );\n\n  const priceMap = props[propName] || {};\n\n  const allValid = (list, validator) => {\n    for (const item of list) {\n      const componentName = validator.toString(),\n        propName = '_',\n        props = { [propName]: item },\n        isInvalid = validator(props, propName, componentName);\n\n      if (typeof isInvalid !== 'undefined') {\n        return false;\n      }\n    }\n\n    return true;\n  };\n\n  if (!isObject(priceMap) || !allValid(Object.values(priceMap), priceList)) {\n    return error;\n  }\n};\n\nconst priceList = (props, propName, componentName) => {\n  const error = new Error(\n    `Invalid prop values \\`${propName}\\` supplied to` +\n      ` \\`${componentName}\\`. Validation failed.`\n  );\n\n  const priceList = props[propName] || {};\n\n  const allOfType = (list, expectedType) => {\n    for (const item of list) {\n      if (typeof item !== expectedType) {\n        return false;\n      }\n    }\n\n    return true;\n  };\n\n  if (!isObject(priceList) || !allOfType(Object.values(priceList), 'number')) {\n    return error;\n  }\n};\n\nconst CoercedSelectValue = PropTypes.oneOfType([\n  PropTypes.number, // from a serialiser\n  PropTypes.string, // from the `value` of a <Select>\n]);\n\nconst productOption = PropTypes.shape({\n  key: PropTypes.string,\n  finish: PropTypes.shape({\n    name: PropTypes.string,\n    title: PropTypes.string,\n  }),\n  border: PropTypes.bool,\n  standard_product_code: PropTypes.string,\n  delivery_options: PropTypes.arrayOf(PropTypes.number),\n});\n\nconst PhotoDimensions = PropTypes.shape({\n  w: PropTypes.number,\n  h: PropTypes.number,\n});\n\nconst UploadedPhoto = PropTypes.shape({\n  id: PropTypes.number,\n  image_id: PropTypes.number,\n  root_image_id: PropTypes.number,\n  uploaded: PropTypes.bool,\n  source: PropTypes.string,\n  filesize: PropTypes.oneOfType([PropTypes.number]),\n  filename: PropTypes.string,\n  quantity: PropTypes.number,\n  crop: PropTypes.arrayOf(PropTypes.number),\n  fx: PropTypes.string,\n  gamma: PropTypes.number,\n  colour_fx: PropTypes.string,\n  angle: PropTypes.number,\n  straighten: PropTypes.number,\n  raw_dimensions: PhotoDimensions,\n  large_dimensions: PhotoDimensions,\n  thumb_dimensions: PhotoDimensions,\n  raw_url: PropTypes.string,\n  large_url: PropTypes.string,\n  thumb_url: PropTypes.string,\n});\n\nconst DeliveryOption = PropTypes.shape({\n  analytics_id: PropTypes.string,\n  code: PropTypes.string,\n  key: CoercedSelectValue,\n  time_hours: CoercedSelectValue,\n  timescale: PropTypes.string,\n  title: PropTypes.string,\n  mobile_title: PropTypes.string,\n  type: PropTypes.string,\n});\n\nconst PrintFinish = PropTypes.shape({\n  key: CoercedSelectValue,\n  name: PropTypes.string,\n  title: PropTypes.string,\n});\n\nconst PrintSize = PropTypes.shape({\n  key: PropTypes.string,\n  size_id: PropTypes.string,\n  title: PropTypes.string,\n  default: PropTypes.bool,\n  area: PropTypes.arrayOf(PropTypes.number),\n  options: productOption,\n  prices: priceMap,\n  photos: PropTypes.arrayOf(UploadedPhoto),\n});\n\nconst PrintsBuilderUrlsShape = PropTypes.shape({\n  data: PropTypes.string.isRequired, // json data of available prints config\n  add_to_cart: PropTypes.string.isRequired, // update current order with print details\n  basket: PropTypes.string.isRequired, // json data of whats in the basket\n  upload: PropTypes.string.isRequired, // file upload\n  upload_from_album: PropTypes.string.isRequired, // album upload\n  cart_page: PropTypes.string.isRequired, // url of page to nav to from prints builder\n});\n\nexport {\n  DeliveryOption,\n  PrintFinish,\n  PrintSize,\n  PhotoDimensions,\n  CoercedSelectValue,\n  UploadedPhoto,\n  PrintsBuilderUrlsShape,\n  // exported for testing\n  priceMap as _priceMap,\n  priceList as _priceList,\n};\n","'use strict';\n\n// Import JS Modules\nimport React from 'react';\nimport { PandaView } from '../../../_utils/image-editor';\n\n// -----------------------------------------------------------\n//  PandaViewSimplePreview\n// -----------------------------------------------------------\nconst PandaViewSimplePreview = (props) => {\n  return (\n    <PandaView { ...props }\n               mode=\"preview\"\n               cropEdges />\n  );\n}\n\nexport default PandaViewSimplePreview;\n","const DPILevels = {\n  Minimum: 100,\n  Recommended: 200\n};\n\nfunction parseDpi(photoDpi) {\n  return Math.round(parseFloat(photoDpi));\n}\n\nfunction aboveRecommendedDpi(photoDpi) {\n  const dpi = parseDpi(photoDpi);\n\n  if (Number.isNaN(dpi)) {\n    return undefined;\n  }\n\n  return dpi >= DPILevels.Recommended;\n}\n\nfunction aboveMinimumDpi(photoDpi) {\n  const dpi = parseDpi(photoDpi);\n\n  if (Number.isNaN(dpi)) {\n    return undefined;\n  }\n\n  return dpi >= DPILevels.Minimum;\n}\n\nexport {\n  aboveRecommendedDpi,\n  aboveMinimumDpi\n}\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\n\nimport NoticeTooltipOnHover from '../../../_utils/notice-tooltip';\nimport { aboveMinimumDpi } from './dpi-classification';\nimport { PrintSize } from '../../prop-types';\n\nconst DpiNotices = {\n  BelowMinimum: 'Poor Resolution',\n};\n\nconst DpiNoticeTooltips = {\n  BelowMinimum:\n    'Poor Resolution: Image may print blurry or pixelated, we suggest a smaller sized print',\n};\n\nconst DpiNotice = ({\n  dpi,\n  noText,\n  tooltipPosition,\n  tooltipCSSClasses,\n  recommendedPrintSize,\n  hideTooltip,\n}) => {\n  const isAboveMinimum = aboveMinimumDpi(dpi);\n\n  if (isAboveMinimum === undefined || isAboveMinimum) {\n    return null;\n  }\n\n  const dpiNotice = 'BelowMinimum';\n  const dpiCssClass = 'minimum';\n  const noticeContent = (\n    <div\n      className={classNames(\n        `dpi-notice text-center dpi-notice-below-${dpiCssClass}`,\n        { 'd-flex align-items-center justify-content-center': !noText }\n      )}\n      aria-label={`${DpiNotices[dpiNotice]} warning`}\n      role=\"tooltip\"\n      tabIndex=\"0\">\n      <span className=\"dpi-notice__icon\" aria-hidden=\"true\">\n        <span>!</span>\n      </span>\n      <span\n        className={classNames({ 'd-none': noText })}\n        aria-hidden={noText ? 'true' : 'false'}>\n        {DpiNotices[dpiNotice]}\n      </span>\n    </div>\n  );\n\n  return hideTooltip ? (\n    noticeContent\n  ) : (\n    <NoticeTooltipOnHover\n      tooltipCSSClasses={classNames(\n        'dpi-tooltip',\n        `dpi-tooltip-below-${dpiCssClass}`,\n        tooltipCSSClasses\n      )}\n      tooltipPosition={tooltipPosition}\n      content={`${DpiNoticeTooltips[dpiNotice]}${\n        recommendedPrintSize\n          ? ` - recommended: ${recommendedPrintSize.title}`\n          : ''\n      }`}\n      show={false}>\n      {noticeContent}\n    </NoticeTooltipOnHover>\n  );\n};\n\nDpiNotice.propTypes = {\n  dpi: PropTypes.number.isRequired,\n  noText: PropTypes.bool,\n  tooltipPosition: PropTypes.string,\n  tooltipCSSClasses: PropTypes.string,\n  hideTooltip: PropTypes.bool,\n  recommendedPrintSize: PrintSize,\n};\n\nDpiNotice.defaultProps = {\n  noText: false,\n  tooltipPosition: undefined,\n  tooltipCSSClasses: undefined,\n  recommendedPrintSize: null,\n  hideTooltip: false,\n};\n\nexport default DpiNotice;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport IU from '../../../_utils/img/img-utils';\nimport DpiNotice from './dpi-notice';\nimport { PrintSize, PhotoDimensions } from '../../prop-types';\n\n// eslint-disable-next-line camelcase\nconst PhotoDpiNotice = ({ noText, tooltipPosition, tooltipCSSClasses, hideTooltip, recommendedPrintSize, size_area, raw_dimensions }) => (\n  <DpiNotice\n    dpi={IU.imgHelpers.getPhotoDPI({ size_area, raw_dimensions })}\n    noText={!!noText}\n    tooltipPosition={tooltipPosition}\n    tooltipCSSClasses={tooltipCSSClasses}\n    recommendedPrintSize={recommendedPrintSize}\n    hideTooltip={hideTooltip}\n  />\n);\n\nPhotoDpiNotice.propTypes = {\n  size_area: PropTypes.arrayOf(PropTypes.number).isRequired,\n  raw_dimensions: PhotoDimensions.isRequired,\n  noText: PropTypes.bool,\n  tooltipPosition: PropTypes.string,\n  tooltipCSSClasses: PropTypes.string,\n  recommendedPrintSize: PrintSize,\n  hideTooltip: PropTypes.bool,\n}\n\nPhotoDpiNotice.defaultProps = {\n  noText: false,\n  tooltipPosition: undefined,\n  tooltipCSSClasses: undefined,\n  hideTooltip: false,\n  recommendedPrintSize: null,\n}\n\nexport default PhotoDpiNotice;\n","import React from 'react';\r\nimport PropTypes from 'prop-types';\r\nimport classNames from 'classnames';\r\n\r\nimport { PrintSize } from '../prop-types';\r\nimport PandaViewSimplePreview from './panda-view-simple-previews/panda-view-simple-preview';\r\nimport Spinner from '../../_utils/spinner';\r\nimport PhotoDpiNotice from './photo-quality/photo-dpi-notice';\r\n\r\nconst PandaViewSimplePreviews = props => {\r\n  const {\r\n    thumb_url: thumbUrl,\r\n    raw_dimensions: rawDimensions,\r\n    isWallet,\r\n    showSize,\r\n    size,\r\n    quantity,\r\n    showQuantity,\r\n    showLowQualityWarning,\r\n    crop,\r\n    lowQualityInformationPosition,\r\n    lowQualityInformationCSSClasses,\r\n    recommendedPrintSize,\r\n    hideLowQualityInformationTooltip,\r\n  } = props;\r\n\r\n  if (!thumbUrl) return <Spinner />;\r\n\r\n  const orientation = () => {\r\n    if (rawDimensions.h <= rawDimensions.w) return 'landscape';\r\n    if (rawDimensions.h > rawDimensions.w) return 'portrait';\r\n  };\r\n\r\n  return (\r\n    <div\r\n      className={classNames(\r\n        'preview d-flex justify-content-center align-items-center m-auto',\r\n        orientation(),\r\n        { wallet: isWallet }\r\n      )}>\r\n      <div className=\"panda-preview d-flex\">\r\n        {(isWallet ? ['left', 'right'] : ['single']).map(preview => (\r\n          <PandaViewSimplePreview key={preview} {...props} />\r\n        ))}\r\n        {showSize && (\r\n          <div\r\n            className={classNames('size-value', {\r\n              'd-none': quantity === 0,\r\n            })}>\r\n            {size.title + (size.options.border === true ? \" Bordered\": \"\")}\r\n          </div>\r\n        )}\r\n        {showQuantity && <div className=\"quantity-value\">{quantity}</div>}\r\n        {showLowQualityWarning && (\r\n          <PhotoDpiNotice\r\n            size_area={size.area}\r\n            raw_dimensions={rawDimensions}\r\n            recommendedPrintSize={recommendedPrintSize}\r\n            crop={crop}\r\n            iconOnly={false}\r\n            tooltipPosition={lowQualityInformationPosition}\r\n            tooltipCSSClasses={lowQualityInformationCSSClasses}\r\n            hideTooltip={hideLowQualityInformationTooltip}\r\n          />\r\n        )}\r\n      </div>\r\n    </div>\r\n  );\r\n};\r\n\r\nPandaViewSimplePreviews.propTypes = {\r\n  thumb_url: PropTypes.string,\r\n  raw_dimensions: PropTypes.objectOf(PropTypes.number),\r\n  isWallet: PropTypes.bool.isRequired,\r\n  showSize: PropTypes.bool,\r\n  size: PrintSize.isRequired,\r\n  showQuantity: PropTypes.bool.isRequired,\r\n  quantity: PropTypes.number.isRequired,\r\n  showLowQualityWarning: PropTypes.bool,\r\n  crop: PropTypes.arrayOf(PropTypes.number),\r\n  lowQualityInformationPosition: PropTypes.string,\r\n  lowQualityInformationCSSClasses: PropTypes.string,\r\n  recommendedPrintSize: PrintSize,\r\n  hideLowQualityInformationTooltip: PropTypes.bool,\r\n};\r\n\r\nPandaViewSimplePreviews.defaultProps = {\r\n  showSize: false,\r\n  thumb_url: null,\r\n  raw_dimensions: null,\r\n  crop: null,\r\n  showLowQualityWarning: false,\r\n  lowQualityInformationPosition: undefined,\r\n  lowQualityInformationCSSClasses: undefined,\r\n  recommendedPrintSize: null,\r\n  hideLowQualityInformationTooltip: false,\r\n};\r\n\r\nexport default PandaViewSimplePreviews;\r\n","// Import Libraries\nimport React, { Component } from 'react';\n// Import JS Modules\nimport { builderDispatch } from '../../../_utils/ui';\nimport { UpdatePhotoEvents } from '../../common/events/event-declarations';\n// Import JSX Modules\nimport PandaViewSimplePreviews from '../../common/panda-view-simple-previews';\n\nclass ListViewItemPreviewAndControls extends Component {\n  static isEditEnabled(photo) {\n    const { quantity, uploaded, fromBasket } = photo;\n\n    return !!quantity && (!!fromBasket || !!uploaded);\n  }\n\n  constructor(props) {\n    super(props);\n    this.handleEdit = this.handleEdit.bind(this);\n    this.handleRemove = this.handleRemove.bind(this);\n    this.handleRemoveByRootId = this.handleRemoveByRootId.bind(this);\n  }\n\n  handleEdit() {\n    const {\n      photo: {\n        root_image_id: rootImageId,\n        size: { key },\n      },\n      isLastPhoto,\n    } = this.props;\n\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.ADVANCED_EDIT,\n      imageId: rootImageId,\n      sizeKey: key,\n      isLastPhoto,\n    });\n  }\n\n  handleRemove() {\n    const {\n      photo: {\n        image_id: imageId,\n        size: { key },\n      },\n    } = this.props;\n\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.REMOVE,\n      sizeKey: key,\n      imageId,\n    });\n  }\n\n  handleRemoveByRootId() {\n    const {\n      photo: { root_image_id: rootImageId },\n    } = this.props;\n\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.SHOW_REMOVE_CONFIRMATION,\n      imageId: rootImageId,\n      useRoot: true,\n    });\n  }\n\n  render() {\n    const {\n      photo,\n      displayRootImageOnly,\n      isLastPhoto,\n      showSize,\n      showQuantity,\n      showLowQualityWarning,\n      recommendedPrintSize,\n    } = this.props;\n\n    const {\n      size: { title: size, area },\n      filename,\n    } = photo;\n\n    const handleEdit = displayRootImageOnly ? undefined : this.handleEdit;\n    const handleRemove =\n      displayRootImageOnly || isLastPhoto\n        ? this.handleRemoveByRootId\n        : this.handleRemove;\n\n    return (\n      <div className=\"d-inline-block list-item__preview\">\n        <PandaViewSimplePreviews\n          {...photo}\n          isWallet={size === 'Wallet'}\n          size_area={area}\n          recommendedPrintSize={recommendedPrintSize}\n          showSize={showSize}\n          showQuantity={showQuantity}\n          showLowQualityWarning={showLowQualityWarning}\n          lowQualityInformationPosition={showLowQualityWarning && 'right'}\n          lowQualityInformationCSSClasses={showLowQualityWarning && 'desktop'}\n          onClick={handleEdit}\n        />\n\n        <div\n          role=\"toolbar\"\n          className=\"list-item__controls d-flex justify-content-between align-items-center\">\n          <button\n            type=\"button\"\n            className=\"btn btn-link btn-underline edit-photo\"\n            disabled={!this.constructor.isEditEnabled(photo)}\n            aria-label={`Edit ${filename} ${size}`}\n            title={`Edit ${filename} ${size}`}\n            role=\"link\"\n            onClick={handleEdit}>\n            Edit\n          </button>\n          <button\n            type=\"button\"\n            className=\"btn btn-link remove-photo\"\n            aria-label={`Delete ${filename} ${size}`}\n            title={`Delete ${filename} ${size}`}\n            onClick={handleRemove}>\n            <i className=\"far fa-trash-alt\" />\n          </button>\n        </div>\n      </div>\n    );\n  }\n}\n\nexport default ListViewItemPreviewAndControls;\n","import React from 'react';\nimport { UpdatePhotoEvents } from './events/event-declarations';\nimport { builderDispatch } from '../../_utils/ui';\n\nconst ListQuantityFieldHandlers = WrappedComponent => props => {\n  const MAX_QUANTITY = 999;\n\n  const add = quantity => {\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.ADD_TO_SIZE,\n      root_image_id: props.rootIds || props.rootId,\n      targetSizeKey: props.sizeKey,\n      quantity,\n    });\n  };\n\n  const update = quantity => {\n    if (props.onChange) {\n      add(quantity);\n      return props.onChange(quantity, props.sizeKey);\n    }\n\n    return builderDispatch.dispatch({\n      type: UpdatePhotoEvents.UPDATE,\n      photo: props.photos.map(photo => ({\n        ...photo,\n        quantity,\n      })),\n      hard: true,\n    });\n  };\n\n  const remove = () => {\n    const photoIds = props.photos.map(photo => photo.image_id);\n\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.REMOVE,\n      sizeKey: props.sizeKey,\n      imageId: photoIds,\n    });\n  };\n\n  const quantity = () => {\n    if (props.photo && props.photo.quantity) {\n      return props.photo.quantity;\n    }\n\n    const sizeQuantity = props.quantity;\n\n    function reducePhotoQuantity(memo, photo) {\n      return memo + (photo.quantity || sizeQuantity || 0);\n    }\n\n    return (props.photos || []).reduce(reducePhotoQuantity, 0);\n  };\n\n  const handleQuantityChange = e => {\n    const value = parseInt(e.target.value || 0, 10);\n\n    if (Number.isNaN(value)) return;\n\n    if (value < 0) {\n      e.target.value = 0;\n      return;\n    }\n\n    if (value > MAX_QUANTITY) {\n      e.target.value = MAX_QUANTITY;\n      return;\n    }\n\n    if (value && quantity() === 0) {\n      add(value);\n      return;\n    }\n\n    if (value) {\n      update(value, 'quantity');\n      return;\n    }\n\n    remove();\n  };\n\n  const handleFormSubmit = e => {\n    e.preventDefault();\n  };\n\n  const newProps = {\n    ...props,\n    handleFormSubmit,\n    handleQuantityChange,\n    quantity,\n  };\n\n  return <WrappedComponent {...newProps} />;\n};\n\nexport default ListQuantityFieldHandlers;\n","import React from 'react';\nimport classNames from 'classnames';\nimport PropTypes from 'prop-types';\n\nconst LONG_TOUCH_INTERVAL = 300;\nlet intervalID;\n\nconst handleTouchStart = (e, onClick) => {\n  $(e.target).one('click mousedown', event => {\n    event.preventDefault();\n    event.stopPropagation();\n  });\n\n  if (intervalID) {\n    window.clearTimeout(intervalID);\n  }\n\n  onClick();\n\n  intervalID = window.setTimeout(onClick, LONG_TOUCH_INTERVAL);\n};\n\nconst handleTouchEnd = () => {\n  window.clearTimeout(intervalID);\n  intervalID = null;\n};\n\nconst Button = props => {\n  const {\n    inputID,\n    ariaLabel,\n    className,\n    disabled,\n    max,\n    min,\n    value,\n    onClick,\n    children,\n  } = props;\n\n  return (\n    <button\n      aria-controls={inputID}\n      aria-disabled={disabled}\n      aria-label={ariaLabel}\n      className={classNames('btn', 'btn-info', className)}\n      disabled={disabled}\n      type=\"button\"\n      aria-valuemax={max}\n      aria-valuemin={min}\n      aria-valuenow={value}\n      onKeyPress={onClick}\n      onMouseDown={onClick}\n      onTouchStart={e => handleTouchStart(e, onClick)}\n      onTouchEnd={() => handleTouchEnd()}>\n      {children}\n    </button>\n  );\n};\n\nButton.propTypes = {\n  inputID: PropTypes.string,\n  ariaLabel: PropTypes.string,\n  className: PropTypes.string,\n  disabled: PropTypes.bool,\n  max: PropTypes.string,\n  min: PropTypes.string,\n  value: PropTypes.number,\n  onClick: PropTypes.func,\n  children: PropTypes.element,\n}.isRequired;\n\nexport default Button;\n","import React, { useState, useEffect, useCallback } from 'react';\nimport classNames from 'classnames';\nimport PropTypes from 'prop-types';\nimport { CoercedSelectValue } from '../../prop-types';\nimport QuantityButton from './button';\n\nconst handleInputSelect = (e) => {\n  e.preventDefault();\n};\n\nconst handleInputFocus = (e, value) => {\n  if (value === 0) {\n    e.target.select();\n  }\n};\n\nconst handleDecrementClick = (onChange, currentValue) => {\n  onChange({\n    target: {\n      value: (parseInt(currentValue, 10) || 0) - 1,\n    },\n  });\n};\n\nconst handleIncrementClick = (onChange, currentValue) => {\n  onChange({\n    target: {\n      value: (parseInt(currentValue, 10) || 0) + 1,\n    },\n  });\n};\n\nconst isValidNumber = (val) => {\n  const number = Number(val);\n  return Number.isInteger(number);\n};\n\nconst NumberInputField = (props) => {\n  const {\n    noButtons,\n    label,\n    disabled,\n    value: propValue,\n    id,\n    min,\n    max,\n    onChange,\n    inputClassName,\n  } = props;\n  const [inputValue, setInputValue] = useState(propValue);\n\n  // only update immediately if the value is a valid, positive number\n  const handleChange = useCallback(\n    (e) => {\n      const {\n        target: { value },\n      } = e;\n\n      setInputValue(value);\n      if (isValidNumber(value) && Number(value) > 0) {\n        onChange(e);\n      }\n    },\n    [onChange],\n  );\n\n  // update the value if the input is blurred only if it's a valid number, zero or above\n  // otherwise reset the input to the prop value\n  // ie only a zero will actually remove the photo size\n  const handleBlur = useCallback(\n    (e) => {\n      const {\n        target: { value },\n      } = e;\n      const inputValueNotBlank = String(value).trim().length > 0;\n\n      if (isValidNumber(value) && Number(value) >= 0 && inputValueNotBlank) {\n        onChange(e);\n      } else {\n        setInputValue(propValue);\n      }\n    },\n    [onChange, propValue],\n  );\n\n  // ui is rendered with blank values then gets updated, and size quantity can be updated\n  // from other controls\n  useEffect(() => {\n    setInputValue(propValue);\n  }, [propValue]);\n\n  return (\n    <div\n      className={classNames('input-group number-field flex-nowrap', {\n        'no-buttons': noButtons,\n      })}>\n      <span className=\"input-group-prepend\">\n        <QuantityButton\n          ariaLabel={`${label} print, ${inputValue}, decrease quantity`}\n          className=\"less\"\n          disabled={disabled || inputValue <= min}\n          inputID={id}\n          max={max}\n          min={min}\n          value={inputValue}\n          onClick={() => handleDecrementClick(onChange, inputValue)}>\n          <i className=\"fa fa-minus\" />\n        </QuantityButton>\n      </span>\n      <input\n        id={id}\n        aria-atomic=\"false\"\n        aria-label={`${label}, quantity ${inputValue}`}\n        aria-live=\"assertive\"\n        aria-valuemax={max}\n        aria-valuemin={min}\n        aria-valuenow={inputValue}\n        className={inputClassName}\n        type=\"number\"\n        value={inputValue}\n        onChange={handleChange}\n        onBlur={handleBlur}\n        onFocus={(e) => handleInputFocus(e, inputValue)}\n        onSelect={(e) => handleInputSelect(e)}\n        disabled={disabled}\n      />\n      <span className=\"input-group-append\">\n        <QuantityButton\n          ariaLabel={`${label} print, ${inputValue}, increase quantity`}\n          className=\"more\"\n          disabled={disabled || inputValue >= max}\n          inputID={id}\n          max={max}\n          min={min}\n          value={inputValue}\n          onClick={() => handleIncrementClick(onChange, inputValue)}>\n          <i className=\"fa fa-plus\" />\n        </QuantityButton>\n      </span>\n    </div>\n  );\n};\n\nNumberInputField.propTypes = {\n  noButtons: PropTypes.bool,\n  label: PropTypes.string,\n  disabled: PropTypes.bool.isRequired,\n  value: CoercedSelectValue.isRequired,\n  id: PropTypes.string.isRequired,\n  min: PropTypes.number.isRequired,\n  max: PropTypes.number.isRequired,\n  onChange: PropTypes.func.isRequired,\n  inputClassName: PropTypes.string,\n};\n\nNumberInputField.defaultProps = {\n  noButtons: false,\n  label: undefined,\n};\n\nexport default NumberInputField;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\n\nexport default function RecommendedPrintSizeBadge({ className }) {\n  return (<span className={classNames('badge badge-pill badge-primary recommended-print-size-badge', className)}>Recommended</span>);\n}\n\nRecommendedPrintSizeBadge.propTypes = {\n  className: PropTypes.string,\n}\n\nRecommendedPrintSizeBadge.defaultProps = {\n  className: null,\n}\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Currency from '../../../_utils/tools/currency';\nimport { PhotoDimensions, PrintSize } from '../../prop-types';\nimport ListQuantityFieldHandlers from '../../common/list-quantity-field-handlers';\nimport PhotoDpiNotice from '../../common/photo-quality/photo-dpi-notice';\nimport NumberInputField from '../../common/number-input-field';\nimport RecommendedPrintSizeBadge from '../../common/photo-quality/recommended-print-size-badge';\n\nconst ItemSize = ({\n  rootId,\n  sizeKey,\n  title,\n  options,\n  area,\n  rawDimensions,\n  showLowQualityWarning,\n  price,\n  disabled,\n  handleFormSubmit,\n  handleQuantityChange,\n  quantity,\n  recommendedPrintSize,\n}) => {\n  const inputId = `size-quantity-change-${rootId}-${sizeKey}`;\n  const isRecommended =\n    recommendedPrintSize && recommendedPrintSize.key === sizeKey;\n\n  return (\n    <li>\n      <form className=\"form-inline mb-2\" onSubmit={handleFormSubmit}>\n        <div className=\"list-item__size form-group flex-nowrap justify-content-end w-100\">\n          {isRecommended && <RecommendedPrintSizeBadge className=\"mr-2\" />}\n          {showLowQualityWarning && (\n            <PhotoDpiNotice\n              size_area={area}\n              raw_dimensions={rawDimensions}\n              noText\n              tooltipPosition=\"left\"\n              tooltipCSSClasses=\"desktop\"\n              recommendedPrintSize={recommendedPrintSize}\n            />\n          )}\n          {/* eslint-disable-next-line jsx-a11y/label-has-for */}\n          <label aria-hidden=\"true\" htmlFor={inputId}>\n            {title}\n          </label>\n          {options[\"border\"] &&\n          <span className=\"list-item__size-border form-group flex-nowrap justify-content-end mr-2\">Bordered</span>\n          }\n          <NumberInputField\n            id={inputId}\n            min={0}\n            max={999}\n            value={quantity()}\n            label={sizeKey}\n            disabled={disabled}\n            onChange={handleQuantityChange}\n          />\n          <span className=\"price-each text-muted\">\n            {Currency.format(price)}&nbsp;ea\n          </span>\n        </div>\n      </form>\n    </li>\n  );\n};\n\nItemSize.propTypes = {\n  sizeKey: PropTypes.string.isRequired,\n  title: PropTypes.string.isRequired,\n  options: PropTypes.object.isRequired,\n  rootId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,\n  area: PropTypes.arrayOf(PropTypes.number).isRequired,\n  price: PropTypes.number.isRequired,\n  rawDimensions: PhotoDimensions,\n  showLowQualityWarning: PropTypes.bool,\n  disabled: PropTypes.bool,\n  handleFormSubmit: PropTypes.func.isRequired,\n  handleQuantityChange: PropTypes.func.isRequired,\n  quantity: PropTypes.func.isRequired,\n  recommendedPrintSize: PrintSize,\n};\n\nItemSize.defaultProps = {\n  showLowQualityWarning: false,\n  disabled: false,\n  recommendedPrintSize: null,\n  rawDimensions: null,\n};\n\nexport default ListQuantityFieldHandlers(ItemSize);\n","class PhotoModifications {\n  constructor(photos) {\n    this.photos = [].concat(photos);\n  }\n\n  set(key, value) {\n    this.photos.forEach((photo) => {\n      photo.modified || (photo.modified = photo[key] != value);\n\n      photo[key] = value;\n    });\n  }\n\n  setFrom(source, ...keys) {\n    keys.length || (keys = Object.keys(source)); // if there's no specific keys supplied just copy the source object lock stock\n\n    keys.forEach((key) => this.set(key, source[key]));\n  }\n\n  addTo(key, increaseBy) {\n    this.photos.forEach((photo) => {\n      const value = photo[key] + increaseBy;\n      photo.modified || (photo.modified = photo[key] != value);\n\n      photo[key] = value;\n    });\n  }\n\n  reset(...keys) {\n    keys.forEach((key) => this.set(key, null));\n  }\n\n  touch() {\n    return this.photos.map((photo) => {\n      photo.modified = true;\n\n      return photo;\n    });\n  }\n\n  clear() {\n    this.photos.forEach((photo) => {\n      delete photo.modified;\n      delete photo.make_new_copy;\n    });\n  }\n}\n\nexport default PhotoModifications;\n","// Resets Photo Edits\n\nimport PhotoModifications from '../common/photo-modifications';\n\nexport default function resetPhotoEdits(photo) {\n  new PhotoModifications(photo).reset('gamma', 'straighten', 'angle', 'colour_fx', 'fx', 'crop');\n\n  return photo;\n}\n","import React from 'react';\nimport { UploadedPhoto } from '../prop-types';\n\nconst urlRegexp = new RegExp(/[^/]+?(?=\\?)|[^/]+$/, 'g');\n\nexport default function PhotoFilename({ photo: { filename } }) {\n  if (!filename) return null;\n\n  const [output] = filename.match(urlRegexp);\n\n  return <p className=\"list-item__photos-filename text-truncate\">{output}</p>;\n}\n\nPhotoFilename.propTypes = {\n  photo: UploadedPhoto.isRequired,\n};\n","/* eslint-disable no-unused-expressions */\n/* eslint-disable no-console */\nimport IU from '../../../_utils/img/img-utils';\nimport { aboveRecommendedDpi } from './dpi-classification';\n\nconst PORTRAIT = 0;\nconst LANDSCAPE = 1;\nconst EXCLUDED_PRINT_SIZE_TITLES = ['Wallet'];\n\nconst aspectRatio = ({ x, y }) => {\n  const ratio = x / y;\n  const orientation = x < y ? PORTRAIT : LANDSCAPE;\n  if (orientation === PORTRAIT) {\n    return 1 / ratio;\n  }\n\n  return ratio;\n};\n\nconst aspectRatioDelta = (a, b) =>\n  Math.abs(Math.round(a * 100) - Math.round(b * 100)); // Round to the nearest integer to avoid float comparisons\n\n/**\n * Find the print size that best matches the photo aspect ratio and results in DPI at or above recommended level\n * When multiple print sizes match criteria, the largest is selected\n * Returns undefined if there are no suitable matches, or if the feature is disabled\n */\nfunction findRecommendedPrintSize(sizes, photo) {\n  if (!photo || !photo.raw_dimensions) {\n    return undefined;\n  }\n\n  const photoAspectRatio = aspectRatio({\n    x: photo.raw_dimensions.w,\n    y: photo.raw_dimensions.h\n  });\n  if (Number.isNaN(photoAspectRatio)) {\n    return undefined;\n  }\n\n  // Exclude any print sizes not recommendable - This title check is done elsewhere in the app :/\n  const availableSizes = sizes.filter(\n    size => !EXCLUDED_PRINT_SIZE_TITLES.includes(size.title)\n  );\n\n  // Find the closest rounded aspect ratio to photo\n  const closestAspectRatioDelta = Math.min(\n    ...availableSizes.map(size => {\n      const [x, y] = size.area;\n      const sizeAspectRatio = aspectRatio({ x, y });\n      return aspectRatioDelta(photoAspectRatio, sizeAspectRatio);\n    })\n  );\n\n  // Find all the print sizes that match criteria having the closest aspect ratio and DPI above recommended level\n  const bestFitSizes = availableSizes.filter(size => {\n    const [x, y] = size.area;\n    const sizeAspectRatio = aspectRatio({ x, y });\n    const dpi = IU.imgHelpers.getPhotoDPI({\n      size_area: size.area,\n      raw_dimensions: photo.raw_dimensions\n    });\n    const sizeAspectRatioDelta = aspectRatioDelta(\n      photoAspectRatio,\n      sizeAspectRatio\n    );\n\n    return (\n      sizeAspectRatioDelta === closestAspectRatioDelta && aboveRecommendedDpi(dpi)\n    ); // DPI is rounded as a <0.5 difference is indistinguishable so prefer to be positively biased\n  });\n\n  if (!bestFitSizes.length) {\n    return undefined;\n  }\n\n  // Sort by print size and return the largest\n  return bestFitSizes.sort((a, b) => {\n    return b.area.reduce((x, y) => x * y) - a.area.reduce((x, y) => x * y);\n  })[0];\n}\n\nexport default findRecommendedPrintSize;\n","import React, { Component } from 'react';\nimport classNames from 'classnames';\n\nimport ListViewItemPreviewAndControls from './list-view-item-preview-and-controls';\nimport ItemSize from './item-size';\nimport resetPhotoEdits from '../../common/reset-photo-edits';\nimport PhotoFilename from '../../common/photo-filename';\nimport findRecommendedPrintSize from '../../common/photo-quality/recommended-print-size';\n\nconst baseNumberOfSizesToShow = 4;\nconst secondNumberOfSizesToShow = 10;\nconst subsequentPagesOfSizesToShow = 5;\nconst DEFAULT_DIMENSIONS = {\n  w: 1000,\n  h: 1000,\n};\n\nconst printSizeListEqual = (listA, listB) =>\n  listA.length === listB.length &&\n  listA.every(\n    (o, i) =>\n      Object.keys(o).length === Object.keys(listB[i]).length &&\n      o.key === listB[i].key\n  );\n\nclass PhotosListItem extends Component {\n  constructor(props) {\n    super(props);\n\n    this.state = {\n      numberOfSizesToShow: baseNumberOfSizesToShow,\n      recommendedPrintSize: findRecommendedPrintSize(\n        props.sizes,\n        this.rootPhoto\n      ),\n    };\n  }\n\n  componentDidUpdate(prevProps) {\n    const { sizes: previousSizes } = prevProps;\n    const { sizes } = this.props;\n\n    // If print sizes have changed then update recommendedPrintSize so that an invalid print size is not recommended or selectable\n    if (!printSizeListEqual(previousSizes, sizes)) {\n      const recommendedPrintSize = findRecommendedPrintSize(\n        sizes,\n        this.rootPhoto\n      );\n      this.setState({\n        // eslint-disable-line react/no-did-update-set-state\n        recommendedPrintSize,\n      });\n    }\n  }\n\n  get rootPhoto() {\n    const { photos = {} } = this.props;\n    const firstSizeKey = Object.keys(photos)[0];\n    return firstSizeKey ? photos[firstSizeKey][0] : null;\n  }\n\n  handleShowMoreSizesClick = () => {\n    this.setState(({ numberOfSizesToShow: prevNumberOfSizesToShow }) => {\n      const numberOfSizesToShow = (({ sizes }) => {\n        if (prevNumberOfSizesToShow >= sizes.length) {\n          return baseNumberOfSizesToShow;\n        }\n\n        if (prevNumberOfSizesToShow < secondNumberOfSizesToShow) {\n          return secondNumberOfSizesToShow;\n        }\n\n        return prevNumberOfSizesToShow + subsequentPagesOfSizesToShow;\n      })(this.props);\n\n      return {\n        numberOfSizesToShow,\n      };\n    });\n  };\n\n  rawDimensions() {\n    const { photos } = this.props;\n\n    const sizeWithRawDimensions = Object.keys(photos).find(sizeKey => {\n      const size = photos[sizeKey];\n      return size && size[0] && size[0].raw_dimensions;\n    });\n\n    if (sizeWithRawDimensions) {\n      return photos[sizeWithRawDimensions][0].raw_dimensions;\n    }\n\n    return null;\n  }\n\n  previews() {\n    const { photos } = this.props;\n\n    return Object.entries(photos)\n      .reduce((list, [, sizePhotos]) => {\n        const photo = sizePhotos[0];\n        if (photo && photo.quantity) {\n          list.push(photo);\n        }\n\n        return list;\n      }, [])\n      .sort((a, b) => {\n        // Return a sorted array by the id's of photo sizes so that newly added sizes\n        // top the viewed collection\n        // First two if (s) account for newly added images where id is null\n        if (a.id === null) return -1;\n        if (b.id === null) return 1;\n        return a.id - b.id;\n      });\n  }\n\n  render() {\n    const { sizes, photos, rootId, disabled } = this.props;\n    const { numberOfSizesToShow, recommendedPrintSize } = this.state;\n\n    const previews = this.previews();\n    const moreFewerButtonToggleLabel = `${\n      numberOfSizesToShow >= sizes.length ? 'Fewer' : 'More'\n    } sizes`;\n    const rawDimensions = this.rawDimensions();\n    const printSizeList = [\n      recommendedPrintSize,\n      ...sizes.filter(\n        size => !recommendedPrintSize || size.key !== recommendedPrintSize.key\n      ),\n    ].filter(Boolean);\n\n    let $previews = previews.map((photo, key, array) => {\n      return (\n        <ListViewItemPreviewAndControls\n          // eslint-disable-next-line react/no-array-index-key\n          key={key}\n          photo={photo}\n          isLastPhoto={array.length === 1}\n          recommendedPrintSize={recommendedPrintSize}\n          showSize\n          showQuantity\n          showLowQualityWarning\n        />\n      );\n    });\n\n    if (previews.length === 0) {\n      resetPhotoEdits(this.rootPhoto);\n\n      $previews = (\n        <ListViewItemPreviewAndControls\n          photo={this.rootPhoto}\n          displayRootImageOnly\n          showQuantity\n        />\n      );\n    }\n\n    return (\n      <section className=\"list-item\">\n        <PhotoFilename photo={this.rootPhoto} />\n        <div className=\"d-flex\">\n          <div className=\"flex-grow-1\">{$previews}</div>\n          <div\n            className={classNames('list-item__sizes flex-shrink-0', {\n              'list-item__sizes-expanded':\n                numberOfSizesToShow > baseNumberOfSizesToShow,\n            })}>\n            <ul className=\"list-unstyled\">\n              {printSizeList.slice(0, numberOfSizesToShow).map(size => (\n                <ItemSize\n                  rootId={rootId}\n                  {...size}\n                  sizeKey={size.key}\n                  photos={photos[size.key] || []}\n                  showLowQualityWarning={!!rawDimensions}\n                  rawDimensions={rawDimensions || DEFAULT_DIMENSIONS}\n                  disabled={disabled}\n                  recommendedPrintSize={recommendedPrintSize}\n                />\n              ))}\n            </ul>\n            {sizes.length > baseNumberOfSizesToShow && (\n              <button\n                type=\"button\"\n                className=\"btn btn-link btn-underline list-item__sizes-toggle\"\n                aria-label={`View ${moreFewerButtonToggleLabel}`}\n                onClick={this.handleShowMoreSizesClick}>\n                {moreFewerButtonToggleLabel}\n              </button>\n            )}\n          </div>\n        </div>\n      </section>\n    );\n  }\n}\n\nexport default PhotosListItem;\n","const ALL_PHOTOS_KEY = undefined;\n\n// a print is a photo with quantity\nfunction sizeHasPrints(size) {\n  size || (size = {});\n\n  return (size.photos || []).some(photo => photo.quantity);\n}\n\nfunction sizeHasRootImage(size, imageID) {\n  size || (size = {});\n  imageID = parseInt(imageID, 10);\n\n  return (size.photos || []).some(\n    photo => photo.quantity && photo.root_image_id === imageID\n  );\n}\n\n// a photo is just a photo regardless of quantity\nfunction sizeHasPhotos(size) {\n  size || (size = {});\n\n  return (size.photos || []).length > 0;\n}\n\nfunction stripZeroQuantityPhotosFromSize(size) {\n  if (!size) return;\n\n  size = { ...size };\n  size.photos = size.photos.filter(photo => photo.quantity);\n\n  return size;\n}\n\nfunction defaultSize(sizes) {\n  return sizes.find(size => size.default);\n}\n\nfunction individual(photo, size) {\n  return { ...photo, size };\n}\n\nfunction collection(photos, size) {\n  return photos.map(photo => individual(photo, size));\n}\n\nfunction fromCollection(sizes) {\n  return sizes.reduce(\n    (memo, size) => memo.concat(collection(size.photos, size)),\n    []\n  );\n}\n\nexport default {\n  ALL_PHOTOS_KEY,\n  sizeHasPrints,\n  sizeHasPhotos,\n  stripZeroQuantityPhotosFromSize,\n  sizeHasRootImage,\n  defaultSize,\n  augment: {\n    individual,\n    collection,\n    fromCollection,\n  },\n};\n","import SizeHelpers from './size-helpers';\n\nconst allPhotos = sizes => {\n  return SizeHelpers.augment.fromCollection(sizes);\n};\n\nconst allPhotosCollectedByRootImage = sizes => {\n  // we want a hash of all the photos by their root image_file and which contain an array of the related photos\n  return allPhotos(sizes).reduce((acc, photo) => {\n    if (photo.image_id) {\n      const rootId = photo.root_image_id;\n      const sizeId = photo.size.key;\n\n      if (!acc[rootId]) {\n        acc[rootId] = {};\n      }\n\n      if (!acc[rootId][sizeId]) {\n        acc[rootId][sizeId] = [];\n      }\n\n      acc[rootId][sizeId].push(photo);\n    }\n\n    return acc;\n  }, {});\n};\n\nexport { allPhotosCollectedByRootImage };\n","import SizeHelpers from '../common/size-helpers';\n\nconst allPhotos = sizes => {\n  return SizeHelpers.augment.fromCollection(sizes);\n};\n\nconst photoRootIds = (sizes, fromPhotoCollecton = false) => {\n  const photos = fromPhotoCollecton ? sizes : allPhotos(sizes);\n\n  return photos.reduce((acc, photo) => {\n    if (photo.image_id && acc.indexOf(photo.root_image_id) === -1) {\n      acc.push(photo.root_image_id);\n    }\n\n    return acc;\n  }, []);\n};\n\nexport default photoRootIds;\n","export class QuantityHelpers {\n  /**\n   * Get the price for a photo at a given quantity\n   * and size\n   * @param {Object} size The size object from the state\n   * @param {Object} deliveryOption The delivery object from the state\n   * @param {Boolean} fallback Whether or not to fallback to a quantity of one if a size is missing\n   * @returns {Number} The non-decimal price\n   */\n  static priceAtQuantityForSize(size, deliveryOption, fallback) {\n    const quantityForSize = QuantityHelpers.quantityForSize(size) || (fallback ? 1 : 0);\n    const priceBreaks = [];\n    const prices = size.prices[deliveryOption.key];\n\n    // Get price breaks points into an array\n    for (const key in prices) {\n      if (prices.hasOwnProperty(key)) {\n        priceBreaks.push(parseInt(key, 10));\n      }\n    }\n\n    // Sort priceBreaks low to high and find value at next lowest price break\n    return priceBreaks\n      .sort((a, b) => a - b)\n      .reduce((acc, priceBreak) => {\n        return quantityForSize >= priceBreak\n          ? prices[priceBreak]\n          : acc;\n      }, 0);\n  }\n\n  /**\n   * Get the quantity of all the photos for a given size\n   * @param {Object} size The size object from the state\n   * @returns {Number} The quantity at a size\n   */\n  static quantityForSize(size) {\n    return (size.photos || []).reduce((acc, photo) => acc + (parseInt(photo.quantity, 10) || 0), 0);\n  }\n}\n","import SizeHelpers from './size-helpers';\nimport { QuantityHelpers } from './quantity-helpers';\n\nconst sizesWithPrints = sizes => {\n  return sizes.filter(SizeHelpers.sizeHasPrints);\n};\n\nconst sizesWithRootImage = (sizes, imageID) => {\n  return sizes.filter(size => SizeHelpers.sizeHasRootImage(size, imageID));\n};\n\nconst quantityForSize = size => {\n  return QuantityHelpers.quantityForSize(size);\n};\n\nconst priceAtQuantityForSize = (\n  size,\n  deliveryOption,\n  fallbackToQuantityOfOne\n) => {\n  return QuantityHelpers.priceAtQuantityForSize(\n    size,\n    deliveryOption,\n    fallbackToQuantityOfOne\n  );\n};\n\nconst totalPrice = (sizes, deliveryOption) => {\n  return sizesWithPrints(sizes).reduce(\n    (memo, size) =>\n      memo +\n      priceAtQuantityForSize(size, deliveryOption) * quantityForSize(size),\n    0\n  );\n};\n\nconst totalQuantity = sizes => {\n  return sizesWithPrints(sizes).reduce(\n    (memo, size) => memo + quantityForSize(size),\n    0\n  );\n};\n\nconst sizesWithPrice = (availableSizes, sizes, deliveryOption) => {\n  return availableSizes.map(availableSize => {\n    const size = sizes.reduce((acc, currentSize) => {\n      return currentSize.key === availableSize.key ? currentSize : acc;\n    }, availableSize);\n\n    return {\n      ...availableSize,\n      price: priceAtQuantityForSize(size, deliveryOption, true),\n    };\n  });\n};\n\nexport {\n  sizesWithRootImage,\n  sizesWithPrice,\n  totalQuantity,\n  totalPrice,\n  sizesWithPrints,\n  quantityForSize,\n  priceAtQuantityForSize,\n};\n","import React, { Component } from 'react';\nimport classNames from 'classnames';\nimport PropTypes from 'prop-types';\nimport { DeliveryOption, PrintSize } from '../prop-types';\nimport Paginator from '../../_utils/paginator';\nimport screenAndStyle from '../../_utils/screen-and-style';\nimport PhotosListItem from './photos-list/item';\nimport { allPhotosCollectedByRootImage } from '../common/collect-by-root-image';\nimport photoRootIds from '../common/photo-root-ids';\nimport { sizesWithPrice } from '../common/totalizing-mixin';\n\nclass PhotosList extends Component {\n  constructor(props) {\n    super(props);\n\n    this.state = {\n      page: 1,\n    };\n\n    this.handlePagePrevious = this.handlePagePrevious.bind(this);\n    this.handlePageNext = this.handlePageNext.bind(this);\n    this.handleGoToPage = this.handleGoToPage.bind(this);\n  }\n\n  UNSAFE_componentWillMount() {\n    this.pageSize = 70;\n    if (screenAndStyle.isMobileBrowser()) {\n      this.pageSize = 15;\n    }\n    if (screenAndStyle.assumePhoneOrSmallScreen()) {\n      this.pageSize = 10;\n    }\n  }\n\n  paginate(items) {\n    const { page } = this.state;\n    return items.slice((page - 1) * this.pageSize, page * this.pageSize);\n  }\n\n  handleGoToPage(page) {\n    this.setState({\n      page,\n    });\n  }\n\n  handlePageNext() {\n    this.setState(previousState => ({\n      page: previousState.page + 1,\n    }));\n  }\n\n  handlePagePrevious() {\n    const { page } = this.state;\n    if (page > 1) {\n      this.setState(previousState => ({\n        page: previousState.page - 1,\n      }));\n    }\n  }\n\n  render() {\n    const { availableSizes, sizes, deliveryOption, disabled } = this.props;\n    const { page } = this.state;\n    const sizesAndPrice = sizesWithPrice(availableSizes, sizes, deliveryOption);\n    const rootIds = photoRootIds(sizes);\n    const paginatedRootIds = this.paginate(rootIds);\n    const totalPageCount = Math.ceil(rootIds.length / this.pageSize);\n    const allPhotosByRootImage = allPhotosCollectedByRootImage(sizes);\n\n    return (\n      <div\n        className={classNames('list-view-desktop', {\n          touch: screenAndStyle.isTouch(),\n        })}>\n        <Paginator\n          title=\"Uploaded photos pages\"\n          page={page}\n          totalPageCount={totalPageCount}\n          scrollTarget={-200}\n          onPageNext={this.handlePageNext}\n          onPagePrevious={this.handlePagePrevious}\n          onGoToPage={this.handleGoToPage}>\n          {paginatedRootIds.map(rootId => {\n            return (\n              <PhotosListItem\n                rootId={parseInt(rootId, 10) || rootId}\n                photos={allPhotosByRootImage[rootId] || {}}\n                sizes={sizesAndPrice}\n                key={`${rootId}`}\n                disabled={disabled}\n              />\n            );\n          })}\n        </Paginator>\n      </div>\n    );\n  }\n}\n\nPhotosList.propTypes = {\n  availableSizes: PropTypes.arrayOf(PrintSize),\n  sizes: PropTypes.arrayOf(PrintSize),\n  deliveryOption: DeliveryOption,\n  disabled: PropTypes.bool,\n}.isRequired;\n\nexport default PhotosList;\n","import createReactClass from 'create-react-class';\nimport genericHelpers from '../../_utils/generic-helpers';\nimport PropTypes from 'prop-types';\nimport { PrintSize, DeliveryOption } from '../prop-types';\n\n('use strict');\n\n// Import Libraries\nimport React from 'react';\n// Import JS Modules\nimport Currency from '../../_utils/tools/currency';\nimport {\n  sizesWithPrints,\n  quantityForSize,\n  priceAtQuantityForSize,\n  totalPrice,\n} from './totalizing-mixin';\n\nvar SummaryTable = createReactClass({\n  render() {\n    const sizes = sizesWithPrints(this.props.sizes);\n\n    if (!sizes.length) {\n      return (\n        <div className=\"summary\" data-test-id=\"summary-table\">\n          <table className=\"table table-sm table-hover m-0\">\n            <tbody>\n              <tr>\n                <td>No Prints</td>\n                <td></td>\n                <td className=\"summary-price\">{Currency.format(0)} ea</td>\n                <td className=\"text-right\">{Currency.format(0)}</td>\n              </tr>\n            </tbody>\n            <tfoot>\n              <tr>\n                <td colSpan=\"4\" className=\"text-right total-price\">\n                  {Currency.format(0)}\n                </td>\n              </tr>\n            </tfoot>\n          </table>\n        </div>\n      );\n    }\n\n    return (\n      <div className=\"summary\">\n        <table className=\"table table-sm m-0\" data-test-id=\"summary-table\">\n          <thead>\n            <tr>\n              <th className=\"summary-size\">Size</th>\n              <th className=\"summary-quantity\">Qty</th>\n              <th className=\"summary-finish d-none\">Finish</th>\n              <th className=\"summary-price\">Price</th>\n              <th className=\"text-right\">Total</th>\n            </tr>\n          </thead>\n          <tbody>\n            {sizes.map(size => {\n              const quantity = size.quantity || quantityForSize(size);\n              const price =\n                size.price ||\n                priceAtQuantityForSize(\n                  size,\n                  this.props.deliveryOption,\n                  size.price\n                );\n\n              return (\n                <tr key={size.key} data-test-id=\"print-size-table-row\">\n                  <td className=\"summary-size\">{ size.options.border ? size.title + \" B\" : size.title}</td>\n                  <td className=\"summary-quantity\">{quantity}</td>\n                  <td className=\"summary-finish d-none\">\n                    {genericHelpers.capitalizeString(size.options.finish.title)}\n                  </td>\n                  <td className=\"summary-price\">{Currency.format(price)} ea</td>\n                  <td className=\"text-right\">\n                    {Currency.format(price * quantity)}\n                  </td>\n                </tr>\n              );\n            })}\n          </tbody>\n          <tfoot>\n            <tr>\n              <td colSpan=\"5\" className=\"text-right total-price\">\n                {Currency.format(totalPrice(sizes, this.props.deliveryOption))}\n              </td>\n            </tr>\n          </tfoot>\n        </table>\n      </div>\n    );\n  },\n});\n\nSummaryTable.propTypes = {\n  sizes: PropTypes.arrayOf(PrintSize).isRequired,\n  deliveryOption: DeliveryOption.isRequired,\n};\n\nexport default SummaryTable;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport Currency from '../../_utils/tools/currency';\nimport { totalQuantity, totalPrice } from './totalizing-mixin';\nimport Table from './summary-table';\nimport DropDown from '../../_common/dropdown';\nimport { DeliveryOption, PrintSize } from '../prop-types';\n\nexport default function Totaliser({ showQuantity, sizes, deliveryOption }) {\n  const buttonText = (\n    <React.Fragment>\n      <span>Total: </span>\n      {Currency.format(totalPrice(sizes, deliveryOption))}\n    </React.Fragment>\n  );\n\n  return (\n    <div className=\"total-price\">\n      {showQuantity && (\n        <div className=\"total-price__quantity\">Qty: {totalQuantity(sizes)}</div>\n      )}\n      <DropDown\n        id=\"total-price\"\n        buttonId=\"total-price-trigger\"\n        buttonText={buttonText}>\n        <Table deliveryOption={deliveryOption} sizes={sizes} />\n      </DropDown>\n    </div>\n  );\n}\n\nTotaliser.propTypes = {\n  showQuantity: PropTypes.bool,\n  sizes: PropTypes.arrayOf(PrintSize),\n  deliveryOption: DeliveryOption,\n};\n\nTotaliser.defaultProps = {\n  showQuantity: false,\n  sizes: [],\n  deliveryOption: {},\n};\n","\n// Import JS Modules\nimport { builderDispatch } from '../../../_utils/ui';\n\n// -----------------------------------------------------------\n//  fireTrackingEvent\n// -----------------------------------------------------------\nconst fireTrackingEvent = function fireTrackingEvent(type) {\n  builderDispatch.dispatch({ type });\n};\n\nexport default fireTrackingEvent;\n","import React, { useCallback } from 'react';\n\nimport { WebUI } from '../../_utils/ui';\nimport translate from '../../_utils/tools/translate';\n\nimport fireTrackingEvent from './events/fire-tracking-event';\nimport ProgressButton from '../../_utils/progress-button';\nimport sendToGoogleAnalytics from '../../_prism-builder/desktop/slot-tools/send-to-google-analytics';\n\nconst buttonText = `Add to ${translate('Cart')}`;\n\nconst AddToCartControls = ({ basketUrl, enabled, onAddToCart }) => {\n  const handleAddToCart = useCallback(\n    e => {\n      e.preventDefault();\n\n      if (enabled) {\n        onAddToCart(() => {\n          sendToGoogleAnalytics('Add-to-cart', 'checkout');\n          fireTrackingEvent(WebUI.PHOTO_EVENT_ADD_TO_CART);\n          location.href = basketUrl;\n        });\n      }\n    },\n    [enabled, onAddToCart, basketUrl]\n  );\n\n  return (\n    <ProgressButton\n      aria-label={buttonText}\n      className=\"btn btn-primary btn-add-to-cart\"\n      data-test=\"add-to-cart\"\n      disabled={!enabled}\n      href={basketUrl}\n      onClick={handleAddToCart}>\n      {buttonText}\n    </ProgressButton>\n  );\n};\n\nexport default AddToCartControls;\n","\n// Import JS Modules\nimport genericHelpers from './generic-helpers';\n\n// -----------------------------------------------------------\n//  ShallowComparatorMixin\n// -----------------------------------------------------------\nconst ShallowComparatorMixin = {\n  shouldComponentUpdate(nextProps, nextState) {\n    return !genericHelpers.shallowObjectEquals(this.props, nextProps)\n            || !genericHelpers.shallowObjectEquals(this.state, nextState);\n  },\n};\n\nexport default ShallowComparatorMixin;\n","import createReactClass from 'create-react-class';\n'use strict';\n\n// Import Libraries\nimport React from 'react';\nimport classNames from 'classnames';\n// Import JS Modules\nimport ShallowComparatorMixin from '../../_utils/shallow-comparator-mixin';\n\n// -----------------------------------------------------------\n//  PrintsBuilderApp.UploadProgressBar\n// -----------------------------------------------------------\nvar UploadProgressBar = createReactClass({\n  mixins: [ShallowComparatorMixin],\n  render() {\n    if (!this.props.total) {\n      return null;\n    }\n\n    const index = Math.min(this.props.index + 1, this.props.total),\n          percent = Math.min(Math.round((index / this.props.total) * 100), 100);\n\n    const $body = (() => {\n      if (this.props.paused) {\n        return <span>Paused</span>;\n      }\n\n      return <span>Uploading {index} of {this.props.total}</span>;\n    })();\n\n    return (\n      <div className=\"progress-bar__container\" data-test=\"upload-progress\">\n        <div className=\"progress\">\n          <div role=\"progressbar\"\n            className={classNames('progress-bar text-left', { 'bg-success ': !this.props.paused, 'bg-warning': this.props.paused })}\n            aria-valuenow={percent}\n            aria-valuemin=\"0\"\n            aria-valuemax=\"100\"\n            style={{ width: percent + '%' }}>\n            {$body}\n          </div>\n        </div>\n      </div>\n    );\n  }\n});\n\nexport default UploadProgressBar;\n","'use strict';\n\n// Import Libraries\nimport React from 'react';\nimport classNames from 'classnames';\n\n// -----------------------------------------------------------\n//  Radio Buttons\n// -----------------------------------------------------------\nconst RadioButtonGroup = ({ title, options, value, onChange }) => {\n  const radioButtonsTitle = title || 'radio-button';\n\n  return (\n    <div aria-label={radioButtonsTitle} className=\"input__radio-button-group\" role=\"radiogroup\">\n      { title && <h6 className=\"input__radio-buttons-title\">{title}</h6> }\n      {options.map(option => {\n        const id = `${radioButtonsTitle}-${option.label}`.replace(/\\s/g, '-').toLowerCase();\n\n        let attrDisabled = {};\n        if(option.disabled) {\n          attrDisabled = { disabled: \"disabled\" }\n        }\n\n        return (\n          <div key={`option_${option.value}`} className=\"input__radio-button\" >\n            <label\n              className={classNames({\n                checked: option.value == value,\n                option_disabled: option.disabled,\n              })}\n              htmlFor={id}>\n              <input\n                aria-checked={option.value == value}\n                checked={option.value == value}\n                id={id}\n                name={`option-group__${radioButtonsTitle}`.replace(/\\s/g, '-').toLowerCase()}\n                type=\"radio\"\n                value={option.value}\n                {...attrDisabled}\n                onChange={({ target }) => onChange(target.value)}\n              />\n              {option.label}\n            </label>\n          </div>\n        );\n      })}\n    </div>\n  );\n};\n\nexport default RadioButtonGroup;\n","import genericHelpers from 'Utils/generic-helpers';\n\nconst finishValue = (finish, finishKeys) => {\n  const finishKey = finish.key;\n  return finishKeys.indexOf(finishKey) === -1\n    ? `${finishKeys[0]}`\n    : `${finishKey}`;\n};\n\nconst availableFinishOptions = (finishes, finishKeys) => {\n  return (finishes || []).map(finish => ({\n    value: `${finish.key}`,\n    label: genericHelpers.capitalizeString(finish.title),\n    disabled: finishKeys.indexOf(finish.key) === -1,\n  }));\n};\n\nconst calculateSelectedFinish = (\n  deliveryOptionKey,\n  value,\n  finishesByDeliveryOption\n) =>\n  (finishesByDeliveryOption[deliveryOptionKey] || []).reduce((memo, finish) =>\n    value === finish.key.toString() ? finish : memo\n  );\n\nconst availableFinishKeys = (finishesByDeliveryOption, deliveryOption) =>\n  (finishesByDeliveryOption[deliveryOption.key] || []).map(\n    delivery => delivery.key\n  );\n\nconst availableDeliveryOptions = (deliveryOptions, finishesByDeliveryOption, useMobileTitle = false) =>\n  deliveryOptions.map(deliveryOption => ({\n    value: `${deliveryOption.key}`,\n    label: genericHelpers.capitalizeString(\n      useMobileTitle ? deliveryOption.mobile_title : deliveryOption.title\n    ),\n    disabled: !finishesByDeliveryOption[deliveryOption.key],\n  }));\n\nconst availableDeliveryOptionsForFinish = (\n  deliveryOptions,\n  finishesByDeliveryOption,\n  selectedFinish,\n  useMobileTitle\n) =>\n  deliveryOptions.map(deliveryOption => ({\n    value: `${deliveryOption.key}`,\n    label: useMobileTitle ? deliveryOption.mobile_title : deliveryOption.title,\n    code: deliveryOption.code,\n    disabled: !(finishesByDeliveryOption[deliveryOption.key] || []).find(\n      f => f.key === selectedFinish.key\n    ),\n  }));\n\nconst selectedDeliveryOption = (deliveryOptions, value) =>\n  deliveryOptions.reduce((memo, deliveryOption) =>\n    value === deliveryOption.key.toString() ? deliveryOption : memo\n  );\n\nconst addSelectedAttributeToOptions = (options, selectedValue) =>\n  options.map(option => ({\n    ...option,\n    selected: `${option?.value || option?.key}` === `${selectedValue}`,\n  }));\n\nexport {\n  availableFinishKeys,\n  finishValue,\n  availableFinishOptions,\n  calculateSelectedFinish,\n  availableDeliveryOptions,\n  availableDeliveryOptionsForFinish,\n  selectedDeliveryOption,\n  addSelectedAttributeToOptions,\n};\n","import React from 'react';\nimport classNames from 'classnames';\nimport PropTypes from 'prop-types';\nimport RadioButtons from './radio-button-group';\nimport { builderDispatch, WebUI } from '../../_utils/ui';\nimport { DeliveryOption, PrintFinish } from '../prop-types';\nimport {\n  availableFinishKeys,\n  finishValue,\n  availableFinishOptions,\n  availableDeliveryOptionsForFinish,\n  calculateSelectedFinish,\n  selectedDeliveryOption,\n} from '../common/finish-and-delivery-options';\n\nconst handleDeliveryChange = (deliveryOptions, value, onChange) => {\n  onChange({\n    delivery_option: selectedDeliveryOption(deliveryOptions, value),\n  });\n};\n\nconst handleFinishChange = (\n  deliveryOption,\n  value,\n  finishesByDeliveryOption,\n  onChange\n) => {\n  onChange({\n    finish: calculateSelectedFinish(\n      deliveryOption.key,\n      value,\n      finishesByDeliveryOption\n    ),\n  });\n};\n\nconst handleShowAllPrices = () => {\n  builderDispatch.dispatch({\n    type: WebUI.SHOW_PRINTS_PRICES,\n  });\n};\n\nconst Options = props => {\n  const {\n    finishes,\n    finish,\n    finishesByDeliveryOption,\n    deliveryOption,\n    deliveryOptions,\n    onChange,\n    showAllPricesLink,\n    hidePrintFinishes,\n  } = props;\n\n  return (\n    <div className=\"options\">\n      <div\n        className={classNames('form-group finish', {\n          'd-none': hidePrintFinishes,\n        })}>\n        <RadioButtons\n          id=\"option-finish\"\n          options={availableFinishOptions(\n            finishes,\n            availableFinishKeys(finishesByDeliveryOption, deliveryOption)\n          )}\n          title=\"Print Finish\"\n          value={finishValue(\n            finish,\n            availableFinishKeys(finishesByDeliveryOption, deliveryOption)\n          )}\n          onChange={value =>\n            handleFinishChange(\n              deliveryOption,\n              value,\n              finishesByDeliveryOption,\n              onChange\n            )\n          }\n        />\n        <hr />\n      </div>\n      <div className=\"form-group delivery\">\n        {/* eslint-disable-next-line jsx-a11y/label-has-associated-control,jsx-a11y/label-has-for */}\n        <label htmlFor=\"option-delivery\" className=\"mb-1\">\n          Delivery Method*\n        </label>\n        <button\n          aria-label=\"See Prices\"\n          className={classNames('btn btn-link btn-underline px-1', {\n            'd-none': !showAllPricesLink,\n          })}\n          role=\"link\"\n          type=\"button\"\n          onClick={handleShowAllPrices}>\n          See Prices\n        </button>\n        <small className=\"d-block mb-2\">*Prices for each item will vary</small>\n        <RadioButtons\n          id=\"option-delivery\"\n          options={availableDeliveryOptionsForFinish(\n            deliveryOptions,\n            finishesByDeliveryOption,\n            finish\n          )}\n          value={deliveryOption.key}\n          onChange={value =>\n            handleDeliveryChange(deliveryOptions, value, onChange)\n          }\n        />\n      </div>\n      <hr />\n    </div>\n  );\n};\n\nOptions.propTypes = {\n  finishes: PropTypes.arrayOf(PrintFinish),\n  finish: PrintFinish.isRequired,\n  finishesByDeliveryOption: PropTypes.objectOf(PropTypes.arrayOf(PrintFinish))\n    .isRequired,\n  deliveryOption: DeliveryOption.isRequired,\n  deliveryOptions: PropTypes.arrayOf(DeliveryOption).isRequired,\n  showAllPricesLink: PropTypes.bool,\n  hidePrintFinishes: PropTypes.bool,\n  onChange: PropTypes.func.isRequired,\n};\n\nOptions.defaultProps = {\n  finishes: [],\n  showAllPricesLink: false,\n  hidePrintFinishes: false,\n};\n\nexport default Options;\n","import React, { useEffect, useState } from 'react';\nimport screenAndStyle from '../../_utils/screen-and-style.js';\nimport { UpdatePhotoEvents } from '../common/events/event-declarations';\nimport { builderDispatch } from '../../_utils/ui';\nimport Modal from '../../_utils/modal';\n\nconst DESKTOP_CONTINUE_MSG =\n  'Continuing will remove the unavailable sizes from your order.';\nconst MOBILE_CONTINUE_MSG =\n  'Continuing will remove the unavailable sizes and photos from your order.';\n\nexport default function InvalidSizesModal() {\n  const [invalidSizes, setInvalidSizes] = useState([]);\n  const [isOpen, handleIsOpen] = useState(false);\n  const [onContinue, setOnContinueCallback] = useState(null);\n\n  useEffect(() => {\n    const builderDispatchToken = builderDispatch.register(payload => {\n      switch (payload.type) {\n        case UpdatePhotoEvents.SHOW_INVALID_SIZES_MODAL:\n          setInvalidSizes(payload.invalidSizes);\n          openModal();\n          setOnContinueCallback(() => payload.onContinue);\n          break;\n      }\n    });\n\n    return () => {\n      builderDispatch.unregister(builderDispatchToken);\n    };\n  }, []);\n\n  useEffect(() => {\n    if (!isOpen) {\n      return;\n    }\n    openModal();\n\n    return () => {\n      closeModal();\n    };\n  }, [isOpen]);\n\n  function handleOnContinue() {\n    onContinue && onContinue();\n    closeModal();\n  }\n\n  function openModal() {\n    handleIsOpen(true);\n  }\n\n  function closeModal() {\n    handleIsOpen(false);\n  }\n\n  const invalidOptions = invalidSizes.map(size =>\n    [size.title, size.options?.finish?.title].filter(Boolean).join(' ')\n  );\n\n  return (\n    <Modal\n      close\n      className=\"prints-builder__invalid-sizes-modal\"\n      open={isOpen}\n      onOpen={openModal}\n      onClose={closeModal}\n      title={'Are you sure?'}\n      maxWidth={486}>\n      <>\n        <p>\n          Some print sizes are not available with these print options (\n          {invalidOptions.join(', ')}).\n        </p>\n        <p>\n          {(screenAndStyle.isBootstrapXS() && MOBILE_CONTINUE_MSG) ||\n            DESKTOP_CONTINUE_MSG}\n        </p>\n        <div className=\"modal-footer\">\n          <button\n            aria-label=\"close modal\"\n            className=\"btn btn-link btn-underline\"\n            type=\"button\"\n            onClick={closeModal}\n            data-dismiss=\"modal\">\n            Cancel\n          </button>\n          <button\n            aria-label=\"continue\"\n            className=\"btn btn-primary\"\n            type=\"button\"\n            data-dismiss=\"modal\"\n            onClick={handleOnContinue}>\n            Continue\n          </button>\n        </div>\n      </>\n    </Modal>\n  );\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\n\nimport { UpdatePhotoEvents } from '../common/events/event-declarations';\nimport { builderDispatch } from '../../_utils/ui';\n\nexport default class InvalidDeliveryOptionModal extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      nextDeliveryOption: null,\n      printFinish: null,\n    };\n  }\n\n  UNSAFE_componentWillMount() {\n    this.builderDispatchToken = builderDispatch.register((payload) => {\n      switch (payload.type) {\n        case UpdatePhotoEvents.SHOW_INVALID_DELIVERY_OPTION_MODAL:\n          const { nextDeliveryOption, printFinish, onContinue } = payload;\n\n          this.setState(\n            {\n              nextDeliveryOption,\n              printFinish,\n            },\n            () => {\n              this.onContinue = onContinue;\n              this.open();\n            },\n          );\n          break;\n      }\n    });\n  }\n\n  componentDidMount() {\n    $(ReactDOM.findDOMNode(this)).modal({\n      show: false,\n    });\n  }\n\n  componentWillUnmount() {\n    builderDispatch.unregister(this.builderDispatchToken);\n  }\n\n  open() {\n    $(ReactDOM.findDOMNode(this)).modal('show');\n  }\n\n  handleContinue = () => {\n    if (this.onContinue) {\n      this.onContinue();\n    }\n  };\n\n  render() {\n    const { printFinish, nextDeliveryOption } = this.state;\n\n    return (\n      <div className=\"modal fade\">\n        <div className=\"modal-dialog\">\n          <div className=\"modal-content\">\n            <div className=\"modal-heading\">\n              <h4 className=\"modal-title\">\n                Currently selected delivery method is not available\n              </h4>\n              <button\n                type=\"button\"\n                className=\"close\"\n                data-dismiss=\"modal\"\n                aria-label=\"Close\"\n              />\n            </div>\n            <div className=\"modal-body\">\n              <p>\n                {printFinish?.title || 'The current finish'} prints are not\n                available for this delivery method.\n              </p>\n              <p>\n                Click{' '}\n                {nextDeliveryOption &&\n                  'Accept to switch to an available delivery method, or '}\n                Cancel to stay with this finish type.\n              </p>\n            </div>\n            <div className=\"modal-footer\">\n              <button\n                className=\"btn btn-link btn-underline\"\n                type=\"button\"\n                data-dismiss=\"modal\">\n                Cancel\n              </button>\n              {nextDeliveryOption && (\n                <button\n                  className=\"btn btn-primary\"\n                  type=\"button\"\n                  data-dismiss=\"modal\"\n                  onClick={this.handleContinue}>\n                  Accept\n                </button>\n              )}\n            </div>\n          </div>\n        </div>\n      </div>\n    );\n  }\n}\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Modal from '../../_utils/modal';\nimport Button from '../../_common/button';\n\nexport default function PhotoRemoveConfirmationModal({\n  className,\n  title,\n  isOpen,\n  onRemove,\n  onClose,\n}) {\n  return (\n    <>\n      <Modal\n        className={`mx-2 ${className}`}\n        maxWidth={500}\n        open={isOpen}\n        onClose={onClose}\n        title={title}\n        actions={\n          <>\n            <Button\n              text=\"Cancel\"\n              className=\"btn btn-link\"\n              data-dismiss=\"modal\"\n              type=\"button\"\n              aria-label=\"Cancel without removing this photo\"\n              onClick={onClose}\n            />\n            <Button\n              text=\"Remove\"\n              className=\"btn btn-primary btn-remove\"\n              data-dismiss=\"modal\"\n              type=\"button\"\n              aria-label=\"Remove this photo\"\n              onClick={onRemove}\n            />\n          </>\n        }\n      />\n    </>\n  );\n}\n\nPhotoRemoveConfirmationModal.propTypes = {\n  className: PropTypes.string,\n  title: PropTypes.string.isRequired,\n  isOpen: PropTypes.bool.isRequired,\n  onRemove: PropTypes.func.isRequired,\n  onClose: PropTypes.func.isRequired,\n};\n\nPhotoRemoveConfirmationModal.defaultProps = {\n  className: '',\n};\n","import createReactClass from 'create-react-class';\n\n('use strict');\n\n// Import Libraries\nimport React from 'react';\n// Import JS Modules\nimport { UpdatePhotoEvents } from './events/event-declarations';\nimport { builderDispatch } from '../../_utils/ui';\nimport PhotoRemoveConfirmationModal from './photo-remove-confirmation-modal';\n\n// -----------------------------------------------------------\n//  PhotoRemoveConfirmation\n// -----------------------------------------------------------\nconst PhotoRemoveConfirmation = createReactClass({\n  getInitialState() {\n    return {\n      isOpen: false,\n    };\n  },\n  componentDidMount() {\n    this.builderDispatchToken = builderDispatch.register(payload => {\n      switch (payload.type) {\n        case UpdatePhotoEvents.SHOW_REMOVE_CONFIRMATION:\n          this.sizeKey = payload.sizeKey;\n          this.imageId = payload.imageId;\n          this.useRoot = payload.useRoot;\n          this.onCancel = payload.onCancel;\n          this.open();\n          break;\n      }\n    });\n  },\n  componentWillUnmount() {\n    builderDispatch.unregister(this.builderDispatchToken);\n  },\n  render() {\n    return (\n      <PhotoRemoveConfirmationModal\n        className=\"photo-remove-confirmation\"\n        title=\"Are you sure you want to remove this photo?\"\n        isOpen={this.state.isOpen}\n        onRemove={this.handleRemove}\n        onClose={this.handleCancel}\n      />\n    );\n  },\n  open() {\n    this.setState({ isOpen: true });\n  },\n  handleCancel() {\n    if (typeof this.onCancel === 'function') {\n      this.onCancel();\n    }\n\n    this.setState({ isOpen: false });\n  },\n  handleRemove() {\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.REMOVE,\n      sizeKey: this.sizeKey,\n      imageId: this.imageId,\n      useRoot: this.useRoot,\n    });\n\n    this.setState({ isOpen: false });\n  },\n});\n\nexport default PhotoRemoveConfirmation;\n","import parseQueryString from '../../_utils/parse-query-string';\nimport Store from '../../_utils/tools/store';\n\nexport default function jsonDataURL(baseURL) {\n  if(Store.isWalmart()) {\n    return jsonDataURLWalmart(baseURL);\n  }\n\n  return jsonDataURLGeneric(baseURL);\n}\n\nfunction jsonDataURLGeneric(baseURL) {\n  const finishParam = (parseQueryString()['finish-include'] || '').toLowerCase();\n\n  if (finishParam != \"\") {\n    return `${baseURL}?finish-include=${finishParam}`;\n  }\n\n  return baseURL;\n};\n\nfunction jsonDataURLWalmart(baseURL) {\n  const finishParam = (parseQueryString().finish || '').toLowerCase();\n  const excludedFinishes = ['metallic', 'stressed'];\n\n  return excludedFinishes.indexOf(finishParam) === -1\n    // by default, exclude these finishes...\n    ? `${baseURL}?finish-exclude=${excludedFinishes.join(',')}`\n    // but, include them if they are explicitly asked for (for some reason)\n    : `${baseURL}?finish-include=${finishParam}`;\n};","const ITEM_TYPE_PRINT = `print`;\nconst PREFIX = {\n  type: 'item_type',\n  size: 'print_size',\n  finish: 'print_finish',\n  border: 'print_border',\n};\n\nexport default class ViewingSizeKey {\n  static validForSizesWithPrints(sizes, viewingSizeKey) {\n    return sizes.some(size => size.key === viewingSizeKey);\n  }\n\n  constructor(viewingSizeKey) {\n    this.viewingSizeKey = viewingSizeKey;\n  }\n\n  create({ size, finish, border }) {\n    if (!size || !finish) {\n      return undefined;\n    }\n\n    const typeKey = `${PREFIX.type}--${ITEM_TYPE_PRINT}`;\n    const finishKey = `${PREFIX.finish}--${finish}`;\n    const sizeKey = `${PREFIX.size}--${size}`;\n    const borderKey = `${PREFIX.border}--${border ? border : \"no\"}`;\n\n    return this.join([typeKey, sizeKey, finishKey, borderKey]);\n  }\n\n  update(key, value) {\n    if (!this.viewingSizeKey) {\n      return undefined;\n    }\n\n    const keysArr = Object.entries(this.properties()).reduce(\n      (arr, [currentKey, currentValue]) => {\n        if (currentKey === key) {\n          arr.push(`${PREFIX[key]}--${value}`);\n        } else {\n          arr.push(currentValue);\n        }\n        return arr;\n      },\n      []\n    );\n\n    return this.join(keysArr);\n  }\n\n  properties() {\n    const [type, size, finish] = this.viewingSizeKey.split(';');\n\n    return { type, size, finish };\n  }\n\n  join(properties) {\n    return properties.filter(Boolean).join(';');\n  }\n}\n","// Import JS Modules\nimport flatMap from 'lodash/flatMap';\nimport cloneDeep from 'lodash.clonedeep';\nimport jsonDataURL from './json-data-url';\nimport parseQueryString from '../../_utils/parse-query-string';\nimport { builderDispatch, WebUI } from '../../_utils/ui';\nimport {\n  UpdatePhotoEvents,\n  RemoveSizeEvents,\n  DefaultsEvents,\n} from './events/event-declarations';\nimport genericHelpers from '../../_utils/generic-helpers';\nimport resetPhotoEdits from './reset-photo-edits';\nimport SizeHelpers from './size-helpers';\nimport PhotoModifications from './photo-modifications';\nimport ViewingSizeKey from '../mobile/viewing-size-key';\n\n// This file contains functions that are common to the prints builder and the mobile prints builder.\n// Any change made to these functions have to be tested in the mobile component.\n\nconst PHOTO_ATTRIBUTES = [\n  'angle',\n  'crop',\n  'fx',\n  'saturation',\n  'colour_fx',\n  'straighten',\n  'gamma',\n  'quantity',\n];\n\nconst PrintsBuilderMixin = {\n  data: {\n    finishes: [],\n    delivery_options: [],\n  },\n  loadCallbacks() {\n    this.builderDispatchToken = builderDispatch.register(payload => {\n      switch (payload.type) {\n        case WebUI.UPLOAD_BEGUN:\n          this.handleUploadBegun(payload.number_of_files);\n          break;\n        case WebUI.UPLOAD_PROGRESS:\n          this.handleUploadProgress(\n            payload.data,\n            payload.source,\n            payload.number_of_files\n          );\n          break;\n        case WebUI.UPLOAD_PAUSED:\n          this.handleUploadPaused();\n          break;\n        case WebUI.UPLOAD_RESUMED:\n          this.handleUploadResumed();\n          break;\n        case WebUI.UPLOAD_DONE:\n          this.handleUploadDone(\n            payload.number_of_files,\n            payload.number_of_errors,\n            payload.message\n          );\n          break;\n        case WebUI.UPLOAD_ABORTED:\n          this.handleAbortedUpload();\n          break;\n        case WebUI.UPLOAD_CLOSED:\n          this.handleUploadClosed();\n          break;\n        case UpdatePhotoEvents.UPDATE:\n          this.handleApplyEditPhoto(payload.photo, payload.hard);\n          break;\n        case UpdatePhotoEvents.REMOVE:\n          if (payload.useRoot) this.handleRemovePhotoByRoot(payload.imageId);\n          else {\n            this.handleRemovePhoto(\n              payload.sizeKey,\n              payload.imageId,\n              payload.selectedPhotoId\n            );\n          }\n          break;\n        case UpdatePhotoEvents.ADD_TO_SIZE:\n          this.handleAddPhotoToSize(\n            payload.size_key,\n            payload.root_image_id,\n            payload.targetSizeKey,\n            payload.quantity\n          );\n          break;\n        case UpdatePhotoEvents.RESIZE:\n          this.handleResizePhoto(\n            payload.size_key,\n            payload.image_id,\n            payload.targetSizeKey\n          );\n          break;\n        case UpdatePhotoEvents.RESIZE_MULTI_SELECT:\n          this.resizeMultiSelectPhotos(\n            payload.targetSizeKey,\n            payload.selectPhotoImageIds\n          );\n          break;\n        case RemoveSizeEvents.REMOVE:\n          this.handleRemoveSize(payload.size_key);\n          break;\n        case UpdatePhotoEvents.ADVANCED_EDIT:\n          this.handleAdvancedEdit(\n            payload.imageId,\n            payload.sizeKey,\n            payload.isLastPhoto\n          );\n          break;\n        case UpdatePhotoEvents.ADVANCED_EDIT_CLOSE:\n          this.handleAdvancedEditClose();\n          break;\n        case WebUI.CART_MERGED:\n          this.loadBasketContents(payload.basketPath);\n          break;\n        case DefaultsEvents.CHANGE_SIZE:\n          this.handleDefaultSizeChanged(payload.sizeKey);\n          break;\n      }\n    });\n  },\n  unloadCallbacks() {\n    builderDispatch.unregister(this.builderDispatchToken);\n  },\n  loadData() {\n    const that = this;\n    const xhr = new XMLHttpRequest();\n\n    xhr.onreadystatechange = function() {\n      if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {\n        const data = JSON.parse(this.responseText);\n\n        if (!data.sizes.length || !data.finishes.length) {\n          return that.showEmptyBuilder(data);\n        }\n\n        // set some defaults\n        // either from the JSON\n        // or querystring\n\n        const {\n          size: defaultSizeParam,\n          finish: defaultFinishParam,\n          delivery: defaultDeliveryOption,\n        } = parseQueryString();\n        const availableFinishesByDeliveryOption = generateAvailableFinishesByDeliveryOption(\n          data\n        );\n\n        let initialFinish;\n        let initialDeliveryOption;\n        let defaultSize;\n        let param;\n\n        // find default finish according to querystring\n        if (defaultFinishParam) {\n          initialFinish = data.finishes.find(\n            finish =>\n              finish.title.toLowerCase() === defaultFinishParam.toLowerCase()\n          );\n        }\n\n        // find default size and finish according to querystring\n        if (defaultSizeParam) {\n          if (initialFinish) {\n            defaultSize = data.sizes.find(\n              size =>\n                size.size_id.toLowerCase() === defaultSizeParam.toLowerCase() &&\n                size.options.finish.name === initialFinish.name\n            );\n          } else {\n            defaultSize = data.sizes.find(\n              size =>\n                size.size_id.toLowerCase() === defaultSizeParam.toLowerCase()\n            );\n          }\n        }\n\n        if (initialFinish?.name && !defaultSize) {\n          const initialFinishName = initialFinish.name.toLowerCase();\n          defaultSize = data.sizes.find(({ options }) =>\n            initialFinishName.includes(options.finish.name)\n          );\n        }\n\n        if (!defaultSize) {\n          defaultSize = SizeHelpers.defaultSize(data.sizes) || data.sizes[0];\n        }\n\n        // find default delivery according to querystring\n        param = (defaultDeliveryOption || '').toLowerCase();\n        // default to first time if not already set\n        if (!param) {\n          param = data.delivery_options[0].key;\n        }\n\n        // now then, the default delivery option should be subordinate to the size and finish chosen\n        // make sure the delivery option key is within the size's options\n        // if it isn't, in that case default to the first delivery option of the size\n        param = parseInt(param, 10);\n        if (\n          initialFinish &&\n          defaultSize.options.finish.name === initialFinish.name &&\n          defaultSize.options.delivery_options &&\n          defaultSize.options.delivery_options.indexOf(param) === -1\n        ) {\n          param = defaultSize.options.delivery_options[0];\n        }\n\n        initialDeliveryOption = data.delivery_options.find(\n          delivery_option => delivery_option.key == param\n        );\n\n        // or fall back to the first available\n        initialDeliveryOption ||\n          ([initialDeliveryOption] = data.delivery_options);\n\n        // or fall back to the first available finish with delivery options\n        let loopCounter = 1;\n        while (!initialFinish) {\n          const availableFinishes =\n            availableFinishesByDeliveryOption[initialDeliveryOption.key];\n          if (availableFinishes) {\n            [initialFinish] = availableFinishes;\n          } else {\n            // there were no availableFinishes for the selected delivery option\n            // roll on to the next delivery option and try again.\n            const deliveryOptionIndex = data.delivery_options.indexOf(\n              initialDeliveryOption\n            );\n            initialDeliveryOption =\n              data.delivery_options[\n                (deliveryOptionIndex + 1) % data.delivery_options.length\n              ];\n            if (loopCounter > data.delivery_options.length) {\n              return that.showEmptyBuilder(data);\n            }\n            ++loopCounter;\n            // in theory this could result in a infinite loop\n            // but config would have to be pretty screwed up for that to happen.\n            // but during tests everything is possible! My computer has self-restarted because of this ;(\n            // so I added this 'loopCounter' stuff to avoid infinite loop. (MK)\n          }\n        }\n\n        that.data = data;\n        that.selectedSizeKey = defaultSize.key;\n        that.initialSizeKey = defaultSize.key; // We may need to reset to this later\n        that.availableFinishesByDeliveryOption = availableFinishesByDeliveryOption;\n        that.setState(\n          {\n            finish: initialFinish,\n            delivery_option: initialDeliveryOption,\n            viewingSizeKey:\n              (defaultSizeParam && defaultSize.key) ||\n              SizeHelpers.ALL_PHOTOS_KEY,\n            sizes: data.sizes.map(size => ({ ...size, photos: [] })),\n          },\n          () => {\n            delete that.data.sizes;\n            that.loadBasketContents();\n          }\n        );\n      }\n    };\n    xhr.open('GET', jsonDataURL(this.props.urls.data));\n    xhr.send();\n\n    function generateAvailableFinishesByDeliveryOption(data) {\n      const finishes = {};\n      data.finishes.forEach(finish => {\n        data.sizes.forEach(size => {\n          size.options.delivery_options.forEach(delivery_option_id => {\n            if (finish.name === size.options.finish.name) {\n              finishes[delivery_option_id] ||\n                (finishes[delivery_option_id] = []);\n              if (finishes[delivery_option_id].indexOf(finish) === -1) {\n                finishes[delivery_option_id].push(finish);\n              }\n            }\n          });\n        });\n      });\n      return finishes;\n    }\n  },\n\n  loadBasketContents(basketUrl) {\n    const that = this;\n    const xhr = new XMLHttpRequest();\n\n    xhr.onreadystatechange = function() {\n      if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {\n        const { prints = [] } = JSON.parse(this.responseText);\n        const validFinishNames = that.data.finishes.map(finish => finish.name);\n\n        // add photos to correct size\n        prints.forEach(function(print) {\n          print.fromBasket = true;\n\n          // eject if this print isn't of a valid finish\n          if (validFinishNames.indexOf(print.finish) === -1) {\n            return;\n          }\n\n          const sizeHash = {};\n          let size = sizeHash[print.size];\n\n          // hopefully the size is already present in the lookup hash\n          if (!size) {\n            // it wasn't, but it might be in the existing sizes\n            size = this.state.sizes.reduce((memo, size) => {\n              const regex = new RegExp(`${print.size}.+${print.finish}.+${print.border}$`);\n              return size.key.match(regex) ? size : memo;\n            }, null);\n          }\n\n          if (size.photos.every(p => p.image_id !== print.image_id)) {\n            size.photos.push(print);\n\n            sizeHash[print.size] = size;\n            delete print.size; // was needed for reconciling, don't need it anymore\n          }\n        }, that);\n\n        let initialDeliveryOption;\n        let initialFinish;\n        let invalidDeliveryOptionSelected = false;\n\n        if (prints[0]) {\n          const { delivery, finish: printFinish } = prints[0];\n          initialFinish = window.features.allowMultiplePrintFinishesPerOrder\n            ? that.state.finish\n            : that.data.finishes.find(finish => finish.name === printFinish);\n          initialDeliveryOption = that.data.delivery_options.find(\n            delivery_option =>\n              that.availableFinishesByDeliveryOption[delivery_option.key] &&\n              delivery_option.key == delivery\n          );\n\n          invalidDeliveryOptionSelected = that.availableFinishesByDeliveryOption[\n            initialDeliveryOption.key\n          ]?.every(f => f.key !== initialFinish.key);\n        }\n\n        const initialSize =\n          !that.desktop && that.determineInitialSize(that.state.viewingSizeKey);\n\n        that.setState(\n          {\n            finish: initialFinish || that.state.finish,\n            delivery_option:\n              initialDeliveryOption || that.state.delivery_option,\n            viewingSizeKey: initialSize && initialSize.key,\n            ready: true,\n            invalidDeliveryOptionSelected,\n          },\n          function() {\n            if (basketUrl) {\n              return;\n            }\n\n            // if builder has no prints then fire loader\n            if (this.props.uploadFromGalleryListenerUrl) {\n              this.handleAddPhotosFromGallery();\n              return;\n            }\n\n            if (!prints.length) {\n              this.handleAddPhotos();\n            }\n\n            if (invalidDeliveryOptionSelected) {\n              const nextAvailableDeliveryOption = this.data.delivery_options.find(\n                deliveryOption =>\n                  that.availableFinishesByDeliveryOption[deliveryOption.key]\n              );\n              const { finish } = this.state;\n\n              builderDispatch.dispatch({\n                type: UpdatePhotoEvents.SHOW_INVALID_DELIVERY_OPTION_MODAL,\n                nextDeliveryOption: nextAvailableDeliveryOption,\n                printFinish: finish,\n                onContinue: () =>\n                  this.setDeliveryAndFinish(\n                    nextAvailableDeliveryOption,\n                    finish\n                  ),\n              });\n            }\n          }\n        );\n      }\n    };\n    xhr.open(\n      'GET',\n      `${basketUrl || this.props.urls.basket}.json` + `?_=${Date.now()}`\n    );\n    xhr.send();\n  },\n\n  allPhotos() {\n    return this.state.sizes.reduce(\n      (memo, size) => memo.concat(size.photos),\n      []\n    );\n  },\n  hasPrints() {\n    return this.state.sizes.some(SizeHelpers.sizeHasPrints);\n  },\n  hasPhotos() {\n    return this.state.sizes.some(SizeHelpers.sizeHasPhotos);\n  },\n  hasPhotosForSelectedFinish() {\n    return this.getSizesByFinish().some(SizeHelpers.sizeHasPhotos);\n  },\n  totalQuantity() {\n    return this.allPhotos().reduce((total, photo) => total + photo.quantity, 0);\n  },\n  getSizeFromKey(sizeKey) {\n    return this.state.sizes.find(size => size.key == sizeKey);\n  },\n  getPhoto(size, imageId, fallbackToRootImageIdOrOriginalImageId = false) {\n    const photos = size && size.photos ? size.photos : this.allPhotos();\n    // Return the photo for which one of its image id(s) matches the supplied imageId\n    // There should only be one match; hence the use of Array.prototype.find()\n    return photos.find(\n      photo =>\n        photo.image_id == imageId ||\n        (fallbackToRootImageIdOrOriginalImageId &&\n          (photo.root_image_id == imageId ||\n            photo.original_image_id == imageId))\n    );\n  },\n  getPhotosBySize(size) {\n    return this.state.sizes.find(s => s.key === size).photos;\n  },\n  getSizesByFinish() {\n    const { sizes, finish } = this.state;\n\n    return sizes.filter(size => {\n      const regex = new RegExp(`${finish.name}`);\n\n      return size.key.match(regex);\n    });\n  },\n  getPhotosWithTheSameRootId(rootImageId) {\n    return this.allPhotos().filter(photo => photo.root_image_id == rootImageId);\n  },\n  availableSizesForSelectedDeliveryAndFinish() {\n    const { finish, delivery_option } = this.state;\n    return this.availableSizesForDeliveryAndFinish(delivery_option, finish);\n  },\n  availableSizesForDeliveryAndFinish(delivery = {}, finish = {}) {\n    return this.state.sizes.filter(\n      size =>\n        size.options.finish.name == finish.name &&\n        (size.options.delivery_options || []).includes(delivery.key)\n    );\n  },\n  handleViewingSizeChanged(sizeKey) {\n    this.setState({\n      viewingSizeKey: sizeKey,\n    });\n  },\n  handleResize(targetSizeKey) {\n    const { viewingSizeKey } = this.state;\n    const resizeAll = viewingSizeKey === SizeHelpers.ALL_PHOTOS_KEY;\n\n    const sizes = resizeAll\n      ? this._resizeAll(targetSizeKey)\n      : this._resizeByKey(targetSizeKey, viewingSizeKey);\n\n    this.setState({ sizes }, function() {\n      this.handleViewingSizeChanged(targetSizeKey);\n      this.save();\n    });\n  },\n  resizeMultiSelectPhotos(targetSizeKey, selectPhotoImageIds) {\n    const photoSizes = [...this.state.sizes];\n\n    // Make a copy of all the selected photos\n    const selectedPhotosToMove = photoSizes.flatMap(({ photos }) =>\n      photos.filter(photo => selectPhotoImageIds.includes(photo.image_id))\n    );\n\n    const sizes = photoSizes.map(size => {\n      // Remove selected images from old size\n      size.photos = size.photos.filter(\n        photo => !selectPhotoImageIds.includes(photo.image_id)\n      );\n\n      // Add selected photo to new size\n      if (size.key === targetSizeKey) {\n        size.photos = new PhotoModifications(\n          this._mergePhotosAndUpdateQuantity([\n            ...size.photos,\n            ...selectedPhotosToMove,\n          ])\n        ).touch();\n      }\n\n      return size;\n    });\n\n    this.setState({ sizes }, () => {\n      this.handleViewingSizeChanged(SizeHelpers.ALL_PHOTOS_KEY);\n      this.save();\n    });\n  },\n  _resizeByKey(targetSizeKey, viewingSizeKey) {\n    // Merge the photos from the current viewing size\n    // with those from the target size\n    const photos = this._mergePhotosAndUpdateQuantity([\n      ...this.getPhotosBySize(viewingSizeKey),\n      ...this.getPhotosBySize(targetSizeKey),\n    ]);\n\n    return this.state.sizes.map(size => {\n      // Remove all the source photos\n      if (size.key === viewingSizeKey) {\n        size.photos = [];\n      }\n      // Merge the source and destination photos\n      if (size.key === targetSizeKey) {\n        size.photos = new PhotoModifications(photos).touch();\n      }\n\n      return size;\n    });\n  },\n  _resizeAll(targetSizeKey) {\n    const sizePhotos = this._mergePhotosAndUpdateQuantity(\n      flatMap(this.getSizesByFinish(), size => size.photos)\n    );\n\n    return this.state.sizes.map(size => {\n      // If the key matches the target and finish type then assign all the\n      // photos to it, otherwise make the array empty. This\n      // will move every single photo from every single size to\n      // a single size\n\n      const targetFinish = targetSizeKey.split(';').pop();\n      let photos;\n\n      if (size.key === targetSizeKey) {\n        photos = new PhotoModifications(sizePhotos).touch();\n      } else if (size.key.includes(targetFinish)) {\n        photos = [];\n      } else {\n        photos = size.photos;\n      }\n\n      return {\n        ...size,\n        photos,\n      };\n    });\n  },\n  _mergePhotosAndUpdateQuantity(photos) {\n    // Take a flattened list of photos and combine those\n    // with the same root id. Duplicate photos will have\n    // their quantities increased\n    return photos.reduce((acc, photo) => {\n      const dupeIndex = acc.findIndex(\n        s => s.root_image_id === photo.root_image_id\n      );\n      // This photo is safe to add\n      if (dupeIndex === -1) return [...acc, photo];\n      // Update the quantity if it's a dupe, and mark the\n      // now unused image for deletion\n      new PhotoModifications(acc[dupeIndex]).addTo('quantity', photo.quantity);\n      this._markForDeletion(photo.id);\n\n      return acc;\n    }, []);\n  },\n  _markForDeletion(id) {\n    const deleted = this.toBeDeleted || [];\n    this.toBeDeleted = [...deleted, id];\n  },\n  handleQuantityChanged(quantity, sizeKey) {\n    quantity = parseInt(quantity) || 1;\n    sizeKey = sizeKey || this.state.viewingSizeKey;\n\n    const sizes = [...this.state.sizes];\n\n    sizes\n      .filter(size => size.key == sizeKey)\n      .forEach(size =>\n        new PhotoModifications(size.photos).set('quantity', quantity)\n      );\n\n    this.setState(\n      {\n        sizes,\n      },\n      () => {\n        this.save();\n      }\n    );\n  },\n  handleOptionsChanged({\n    finish = this.state.finish,\n    delivery_option = this.state.delivery_option,\n  } = {}) {\n    const sizesWithPrints = this.state.sizes.filter(SizeHelpers.sizeHasPrints);\n    const availableSizes = this.availableSizesForDeliveryAndFinish(\n      delivery_option,\n      finish\n    ).map(size => size.key);\n\n    const invalidSizes = sizesWithPrints.filter(size => {\n      const keyWithoutFinish = size.key.split(';', 2).join(';');\n      return !availableSizes.some(\n        availableSize =>\n          availableSize.match(keyWithoutFinish) &&\n          size.options.delivery_options.includes(delivery_option.key)\n      );\n    });\n\n    if (invalidSizes.length) {\n      const invalidKeySizes = invalidSizes.map(size => size.key);\n\n      builderDispatch.dispatch({\n        type: UpdatePhotoEvents.SHOW_INVALID_SIZES_MODAL,\n        invalidSizes,\n        onContinue: () => {\n          const validSizesWithPrints = sizesWithPrints.filter(\n            ({ key }) => !invalidKeySizes.includes(key)\n          );\n\n          this.setDeliveryAndFinishAndRemoveInvalidSizes(\n            delivery_option,\n            finish,\n            invalidKeySizes\n          );\n          this._applyFinishToSizesPrints(validSizesWithPrints, finish);\n\n          if (\n            !ViewingSizeKey.validForSizesWithPrints(\n              validSizesWithPrints,\n              this.state.viewingSizeKey\n            )\n          ) {\n            this.handleViewingSizeChanged(SizeHelpers.ALL_PHOTOS_KEY);\n          }\n        },\n      });\n    } else {\n      this._applyFinishToSizesPrints(sizesWithPrints, finish);\n      this.setDeliveryAndFinish(delivery_option, finish);\n    }\n  },\n  setDeliveryAndFinishAndRemoveInvalidSizes(\n    delivery_option,\n    finish,\n    invalidSizeKeys = []\n  ) {\n    invalidSizeKeys.forEach(invalidSizeKey => {\n      const size = this.getSizeFromKey(invalidSizeKey);\n      new PhotoModifications(size.photos).set('quantity', 0);\n    });\n\n    this.setState(\n      {\n        sizes: [...this.state.sizes],\n        finish,\n        delivery_option,\n      },\n      function() {\n        this.ignoreModified = true;\n        this.save();\n      }\n    );\n  },\n  setDeliveryAndFinish(delivery_option, finish) {\n    this.setState(\n      {\n        finish,\n        delivery_option,\n        invalidDeliveryOptionSelected: false,\n      },\n      function() {\n        this.ignoreModified = true;\n        this.save();\n      }\n    );\n  },\n  handleAdvancedPhotoQuantityChanged(value) {\n    value = Math.max(value, 1);\n\n    const sizes = [...this.state.sizes];\n\n    sizes\n      .filter(size => size.key == this.advanced_edit.size.key)\n      .forEach(size => {\n        const photos = size.photos.filter(\n          photo => photo.id == this.advanced_edit.photo.id\n        );\n        new PhotoModifications(photos).set('quantity', value);\n      });\n\n    this.setState(\n      {\n        sizes,\n      },\n      function() {\n        this.save();\n      }\n    );\n  },\n  handleAdvancedEditSelectPhoto(photo) {\n    if (!this.advanced_edit) return;\n\n    this.advanced_edit.size = photo.size;\n    this.advanced_edit.photo = photo;\n  },\n  handleApplyEditPhoto(updatedPhotos, save) {\n    updatedPhotos = [].concat(updatedPhotos);\n\n    let { viewingSizeKey } = this.state;\n\n    updatedPhotos.forEach(updatedPhoto => {\n      const size = this.getSizeFromKey(updatedPhoto.size.key);\n      const photo =\n        this.getPhoto(size, updatedPhoto.image_id) ||\n        this.getPhoto(size, updatedPhoto.root_image_id, true);\n\n      if (photo) {\n        new PhotoModifications(photo).setFrom(\n          updatedPhoto,\n          ...PHOTO_ATTRIBUTES\n        );\n      }\n\n      viewingSizeKey =\n        viewingSizeKey != size.key || SizeHelpers.sizeHasPrints(size)\n          ? viewingSizeKey\n          : undefined;\n    });\n\n    this.setState(\n      ({ sizes }) => {\n        return {\n          sizes: [...sizes],\n          viewingSizeKey,\n        };\n      },\n      () => {\n        if (save) {\n          this.save();\n        }\n      }\n    );\n  },\n  _applyFinishToSizesPrints(sizesWithPrints = [], finish = {}) {\n    if (window.features.allowMultiplePrintFinishesPerOrder) {\n      return;\n    }\n\n    const { name } = finish;\n\n    if (!name || !sizesWithPrints.length) {\n      return;\n    }\n\n    const { sizes, viewingSizeKey } = this.state;\n    const allSizes = cloneDeep(sizes);\n\n    // Same method as handleResizePhoto()\n    // however making a copy of state to target photos.\n\n    sizesWithPrints.forEach(({ size_id, photos, key }) => {\n      photos.forEach(({ image_id }) => {\n        const sourceSize = allSizes.find(size => size.key === key);\n        const photo = this.getPhoto(sourceSize, image_id, true);\n\n        const targetSizeKey = new ViewingSizeKey(viewingSizeKey).create({\n          size: size_id,\n          finish: name,\n\t\t  border: photo.border\n        });\n\n        const targetSize = allSizes.find(size => size.key === targetSizeKey);\n        const photoModifications = new PhotoModifications(photo);\n\n        if (sourceSize.key === targetSize.key) {\n          // Will only match when the delivery option is going to change\n          // So no need to move photos\n          return;\n        }\n\n        // if there's a version of this photo lying in the target size then remove it\n        let index = targetSize.photos.reduce(\n          (memo, targetPhoto, i) =>\n            targetPhoto.root_image_id == photo.root_image_id ? i : memo,\n          -1\n        );\n\n        if (index > -1) {\n          const toBeDeleted = targetSize.photos.splice(index, 1);\n          this.toBeDeleted = (this.toBeDeleted || []).concat(\n            toBeDeleted.map(photo => photo.id)\n          );\n        }\n\n        // remove this photo from the source size\n        index = sourceSize.photos.indexOf(photo);\n        if (index > -1) {\n          photoModifications.touch();\n          sourceSize.photos.splice(index, 1);\n        }\n\n        // // add it to the target size\n        targetSize.photos.push(photo);\n      });\n    });\n\n    if (viewingSizeKey) {\n      const newTargetSizeKey = new ViewingSizeKey(viewingSizeKey).update(\n        'finish',\n        name\n      );\n      this.handleViewingSizeChanged(newTargetSizeKey);\n    }\n\n    this.setState({\n      sizes: [...allSizes],\n    });\n  },\n  handleResizePhoto(sourceSizeKey, imageId, targetSizeKey) {\n    const sourceSize = this.getSizeFromKey(sourceSizeKey);\n    const photo = this.getPhoto(sourceSize, imageId, true);\n    const targetSize = this.getSizeFromKey(targetSizeKey);\n    const photoModifications = new PhotoModifications(photo);\n\n    photoModifications.reset('crop');\n\n    // if there's a version of this photo lying in the target size then remove it\n    let index = targetSize.photos.reduce(\n      (memo, targetPhoto, i) =>\n        targetPhoto.root_image_id == photo.root_image_id ? i : memo,\n      -1\n    );\n\n    if (index > -1) {\n      const toBeDeleted = targetSize.photos.splice(index, 1);\n      this.toBeDeleted = (this.toBeDeleted || []).concat(\n        toBeDeleted.map(photo => photo.id)\n      );\n    }\n\n    // remove this photo from the source size\n    index = sourceSize.photos.indexOf(photo);\n    if (index > -1) {\n      photoModifications.touch();\n      sourceSize.photos.splice(index, 1);\n    }\n\n    // add it to the target size\n    targetSize.photos.unshift(photo);\n\n    this.setState(\n      {\n        sizes: [...this.state.sizes],\n        viewingSizeKey: this.state.viewingSizeKey && targetSizeKey,\n      },\n      function() {\n        this.refreshEL2(targetSizeKey, photo.image_id);\n        this.save();\n      }\n    );\n  },\n  handleAddPhotoToSize(\n    sourceSizeKey,\n    rootImageIdOrIds,\n    targetSizeKey,\n    quantity\n  ) {\n    rootImageIdOrIds = [].concat(rootImageIdOrIds);\n\n    const targetSize = this.getSizeFromKey(targetSizeKey);\n    const sourcePhotos = [];\n\n    rootImageIdOrIds.forEach(rootImageId => {\n      let newPhoto;\n\n      // Pick first (or any of the returned images as we'll have to reset edits anyway)\n      const [sourcePhoto] = this.getPhotosWithTheSameRootId(rootImageId);\n\n      if (sourcePhoto) {\n        // 'new photo' may already be in the size but with quantity zero\n        newPhoto = targetSize.photos.find(\n          photo => photo.root_image_id == rootImageId\n        );\n\n        // photo might already in the size array, perhaps with quantity zero\n        if (!newPhoto) {\n          newPhoto = {};\n\n          // set the newPhoto's Item id to null\n          // to dissociate it with the old Item\n          new PhotoModifications(newPhoto).setFrom({\n            ...sourcePhoto,\n            id: null,\n            original_image_id: sourcePhoto.image_id,\n            make_new_copy: true,\n          });\n\n          resetPhotoEdits(newPhoto);\n\n          targetSize.photos.push(newPhoto);\n        }\n\n        // Reset Edits only if quantity is 0. This avoids bulk resetting.\n        if (newPhoto.quantity === 0) {\n          resetPhotoEdits(newPhoto);\n        }\n        new PhotoModifications(newPhoto).set('quantity', quantity || 1);\n        sourcePhotos.push(sourcePhoto);\n      }\n    });\n\n    this.setState(\n      ({ sizes, viewingSizeKey }) => {\n        return {\n          sizes: [...sizes],\n          viewingSizeKey: this.advanced_edit ? targetSizeKey : viewingSizeKey,\n        };\n      },\n      () => {\n        this.saveHard(() => {\n          const sourcePhoto = sourcePhotos[0];\n          const newPhotoImageId =\n            sourcePhoto &&\n            targetSize.photos.reduce(\n              (memo, photo) =>\n                sourcePhoto.root_image_id == photo.root_image_id\n                  ? photo.image_id\n                  : memo,\n              null\n            );\n\n          if (this.advanced_edit && newPhotoImageId) {\n            this.refreshEL2(targetSizeKey, newPhotoImageId);\n          }\n\n          this.setState({ selectedPhotoId: newPhotoImageId });\n        });\n      }\n    );\n  },\n  handleRemovePhoto(sizeKey, imageIdOrIds, selectedPhotoId) {\n    imageIdOrIds = [].concat(imageIdOrIds);\n\n    const size = this.getSizeFromKey(sizeKey);\n\n    if (this.allowZeroQuantity()) {\n      imageIdOrIds.forEach(imageId => {\n        const photo = this.getPhoto(size, imageId, true);\n        if (!photo) {\n          return;\n        }\n\n        new PhotoModifications(photo).set('quantity', 0);\n      });\n    } else {\n      this.deletePhotos(sizeKey, imageIdOrIds);\n    }\n\n    this.setState(\n      ({ sizes, viewingSizeKey }) => {\n        return {\n          sizes: [...sizes],\n          selectedPhotoId,\n          viewingSizeKey:\n            viewingSizeKey !== size.key || SizeHelpers.sizeHasPrints(size)\n              ? viewingSizeKey\n              : undefined,\n        };\n      },\n      () => {\n        this.advancedEditor().close(true);\n        this.save();\n      }\n    );\n  },\n  handleRemovePhotoByRoot(rootImageId) {\n    let removed = [];\n\n    this.state.sizes.forEach(size => {\n      const photo = this.getPhoto(size, rootImageId, true);\n\n      if (photo) {\n        const { photos } = size;\n        const index = photos.indexOf(photo);\n\n        if (index > -1) removed = removed.concat(photos.splice(index, 1));\n      }\n    });\n\n    this.setState(\n      ({ sizes }) => {\n        return {\n          sizes: [...sizes],\n          selectedPhotoId: undefined,\n        };\n      },\n      () => {\n        const toBeDeleted = removed\n          .filter(photo => !!photo.id)\n          .map(photo => photo.id);\n\n        this.toBeDeleted = (this.toBeDeleted || []).concat(toBeDeleted);\n        this.save();\n      }\n    );\n  },\n  handleRemoveSize(sizeKey) {\n    const size = this.getSizeFromKey(sizeKey);\n\n    // Set photo quantity to handle 0 quantity\n    new PhotoModifications(size.photos).set('quantity', 0);\n\n    this.setState(\n      {\n        sizes: [...this.state.sizes],\n        viewingSizeKey: undefined,\n      },\n      function() {\n        this.save();\n      }\n    );\n  },\n  handleDefaultSizeChanged(sizeKey) {\n    this.selectedSizeKey = sizeKey;\n\n    this.setState({\n      viewingSizeKey: sizeKey,\n    });\n  },\n  handleAdvancedEditClose() {\n    delete this.advanced_edit;\n  },\n  deletePhotos(sizeKey, imageIdOrIds) {\n    imageIdOrIds = [].concat(imageIdOrIds);\n\n    const size = this.getSizeFromKey(sizeKey);\n    if (!size) return;\n\n    const { photos } = size;\n    const removed = [];\n\n    imageIdOrIds.forEach(imageId => {\n      const photo = this.getPhoto(size, imageId, true);\n      const index = photos.indexOf(photo);\n\n      if (index > -1) {\n        removed.push(...photos.splice(index, 1));\n      }\n    });\n\n    this.toBeDeleted = (this.toBeDeleted || []).concat(removed.map(p => p.id));\n    this.save();\n  },\n  save() {\n    this.debouncedSave ||\n      (this.debouncedSave = genericHelpers.debounce(() => {\n        this.saveHard(() => {\n          this.clearWarningBeforeNavigatingAwayPendingSave();\n        });\n      }, 2000));\n\n    this.setWarningBeforeNavigatingAwayPendingSave();\n    this.debouncedSave();\n  },\n  saveHard(onComplete) {\n    if (this.saving && !onComplete) {\n      return;\n    }\n    const allPhotos = this.allPhotos();\n    const data = {\n      sizes: this.state.sizes\n        .filter(SizeHelpers.sizeHasPrints)\n        .map(buildSizeData, this)\n        .filter(size => size.photos.length),\n      to_be_deleted: []\n        .concat(this.toBeDeleted, photosWithNoQuantity())\n        .filter(Boolean),\n    };\n\n    ['sizes', 'to_be_deleted'].forEach(key => {\n      if (data[key].length === 0) {\n        delete data[key];\n      }\n    });\n\n    const xhr = new XMLHttpRequest();\n    xhr.open('POST', this.props.urls.add_to_cart);\n    xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');\n    xhr.onreadystatechange = () => {\n      if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {\n        // we've been returned the item ids\n        // of the new files which we will need to use when deleting them\n        const newItems = JSON.parse(xhr.responseText);\n        newItems.forEach(setIdsOfNewItem, this);\n        this.saving = false;\n        onComplete && onComplete();\n      }\n\n      function setIdsOfNewItem(newItem) {\n        const size = this.getSizeFromKey(newItem.size);\n        const photo = this.getPhoto(size, newItem.original_image_id);\n\n        if (photo) {\n          photo.id = newItem.id;\n          photo.image_id = newItem.image_id;\n        }\n      }\n    };\n\n    if (Object.keys(data).length) {\n      xhr.send(JSON.stringify(data));\n    } else {\n      onComplete && onComplete();\n    }\n\n    this.ignoreModified = false;\n    this.toBeDeleted = [];\n    new PhotoModifications(allPhotos).clear();\n    this.saving = true;\n\n    function photosWithNoQuantity() {\n      return allPhotos\n        .filter(photo => photo.quantity < 1)\n        .map(photo => photo.id);\n    }\n\n    function buildSizeData(size) {\n      const {\n        delivery_option: { key: deliveryOption },\n      } = this.state;\n\n      const photos = size.photos.filter(printFilter, this).map(buildPhotoData);\n      const what = size.options.key;\n\n      return {\n        photos,\n        what,\n      };\n\n      function printFilter({ id, image_id: imageId, quantity, modified }) {\n        return (\n          !id ||\n          (typeof imageId === 'number' &&\n            quantity &&\n            (this.ignoreModified || modified))\n        );\n      }\n\n      function buildPhotoData(photo) {\n        return {\n          id: photo.id,\n          image_id: photo.image_id,\n          make_new_copy: !!photo.make_new_copy,\n          quantity: photo.quantity,\n          filename: photo.filename,\n          filesize: photo.filesize,\n          angle: photo.angle,\n          crop: photo.crop,\n          fx: photo.fx,\n          size_key: size.key,\n          saturation: photo.saturation,\n          colour_fx: photo.colour_fx,\n          straighten: photo.straighten,\n          gamma: photo.gamma,\n          delivery_option: deliveryOption,\n        };\n      }\n    }\n  },\n  showEmptyBuilder(data) {\n    this.data = data;\n    this.setState(\n      {\n        finish: {},\n        delivery_option: data.delivery_options[0] || {},\n        viewingSizeKey: SizeHelpers.ALL_PHOTOS_KEY,\n        sizes: [],\n      },\n      () => {\n        alert(\n          'No available finishes or sizes for the given product. Please report this problem.'\n        );\n      }\n    );\n  },\n  determineInitialSize(key) {\n    if (!key) {\n      return { key: SizeHelpers.ALL_PHOTOS_KEY };\n    }\n\n    const defaultSize = this.getSizeFromKey(key);\n    // If there are photos for the default size\n    // then show them, otherwise show everything\n    return defaultSize.photos.length > 0\n      ? defaultSize\n      : { key: SizeHelpers.ALL_PHOTOS_KEY };\n  },\n  advancedEditor() {\n    return this.advancedEditorRef\n      ? this.advancedEditorRef.component\n      : {\n          setData() {},\n          close() {},\n        };\n  },\n  handleUploadClosed() {\n    if (this.addPhotosButtonRef) {\n      this.addPhotosButtonRef.focus();\n    }\n  },\n  handleAddToCart(callback) {\n    this.saveHard(() => {\n      this.clearWarningBeforeNavigatingAwayPendingSave();\n\n      if (typeof callback === 'function') callback();\n    });\n  },\n  setWarningBeforeNavigatingAwayPendingSave() {\n    this.setBeforeUnload('Changes that you made may not be saved.');\n  },\n  clearWarningBeforeNavigatingAwayPendingSave() {\n    this.setBeforeUnload();\n  },\n};\n\nexport default PrintsBuilderMixin;\n","import React from 'react';\nimport BSOverlay from '../../../_utils/bs-overlay';\nimport Failures from '../../../_photo-loader/failures';\nimport { builderDispatch, WebUI } from '../../../_utils/ui';\n\nclass PrintsBuilderPhotoAlbumDirectLoader {\n  constructor(uploadUrl, onBegunUploading, onUploaded, onDone) {\n    this._uploadUrl = uploadUrl;\n    this._onBegunUploading = onBegunUploading;\n    this._onUploaded = onUploaded;\n    this._onDone = onDone;\n\n    this._pollInterval = 5000;\n    this._doneHash = {};\n\n    builderDispatch.register((payload) => {\n      switch (payload.type) {\n        case WebUI.UPLOAD_ABORTED:\n        case WebUI.PHOTO_EVENT_REMOVE_PRINTS_CONFIRM:\n          this._clearInterval();\n          break;\n      }\n    });\n  }\n\n  slingshot(userPhotosIds) {\n    const formData = new FormData();\n    userPhotosIds.forEach((id) => formData.append('upload_from_gallery_photo_ids[]', id));\n    formData.append('source', 'albums');\n\n    fetch(this._uploadUrl, {\n      method: 'POST',\n      body: formData,\n      credentials: 'same-origin',\n      headers: {\n        'X-Requested-With': 'XMLHttpRequest', // in order for request.xhr? to be true\n      },\n    })\n      .then((response) => response.json())\n      .then((data) => {\n        if (window.history) {\n          window.history.replaceState({}, '', data.urls.prints_builder);\n        }\n\n        this.listen(data.urls.listener);\n      });\n  }\n\n  listen(url) {\n    perform.call(this, true);\n\n    this._pollingIntervalID = setInterval(perform.bind(this), this._pollInterval);\n\n    function perform(firstRun) {\n      fetch(url, {\n        credentials: 'same-origin',\n      })\n        .then((response) => response.json())\n        .then((data) => this._processPollResponse(data, firstRun))\n        .catch(() => { this._clearInterval() });\n    }\n  }\n\n  _processPollResponse(response, firstRun = false) {\n    if (firstRun) {\n      this._onBegunUploading(response.total);\n    }\n\n    (response.images || []).forEach((image) => {\n      if (this._doneHash.hasOwnProperty(image.image_id)) {\n        return;\n      }\n\n      this._onUploaded(image, 'albums');\n      this._doneHash[image.image_id] = image.image_id;\n    });\n\n    if (response.complete) {\n      this._clearInterval();\n\n      if (response.failures) {\n        this._showErrorModal(response);\n      } else {\n        this._onDone(response.images.length, 0);\n      }\n    }\n  }\n\n  _clearInterval() {\n    clearInterval(this._pollingIntervalID);\n    this._pollingIntervalID = null;\n  }\n\n  _showErrorModal({ failures }) {\n    const $modal = (\n      <BSOverlay\n        show\n        onHide={handleIgnore}\n      >\n        <Failures\n          numberOfFailures={failures.length}\n          shouldRetry\n          onIgnore={handleIgnore.bind(this)}\n          onRetry={handleRetry.bind(this)}\n        />\n      </BSOverlay>\n    );\n\n    $('body').append('<div id=\"direct-album-loader-error\" />');\n\n    ReactDOM.render($modal, document.getElementById('direct-album-loader-error'));\n\n    function handleIgnore() {\n      builderDispatch.dispatch({\n        type: WebUI.UPLOAD_ABORTED,\n      });\n\n      remove();\n    }\n\n    function handleRetry() {\n      this.slingshot(failures.map((failure) => failure.id));\n\n      remove();\n    }\n\n    function remove() {\n      $('#direct-album-loader-error, .modal-backdrop').remove();\n    }\n  }\n}\n\nexport default PrintsBuilderPhotoAlbumDirectLoader;\n","// Import JS Modules\nimport { builderDispatch, WebUI, PrismUI } from '../../_utils/ui';\nimport fetchImage from '../../_utils/fetch-image';\nimport PrintsBuilderPhotoAlbumDirectLoader from './upload-photo-mixin/from-album-to-prints-loader';\nimport LoaderAdditionalOptions from '../../_photo-loader/additional-options';\nimport SizeHelpers from '../common/size-helpers';\n// This file contains functions that are common to the prints builder and the mobile prints builder.\n// Any change made to those function have to be tested in the mobile component.\n\nconst UploadPhotosMixin = {\n  handleAddPhotos() {\n    const { currentlyLoading } = this.state;\n\n    if (currentlyLoading) {\n      return;\n    }\n\n    const additionalOptions = {\n      [LoaderAdditionalOptions.EXTRA_FILE_TYPES]: ['webp'],\n      [LoaderAdditionalOptions.PRINT_SIZES]: this.availableSizesForSelectedDeliveryAndFinish().map(\n        size => ({\n          key: size.key,\n          title: size.title,\n          selected: size.key === this.getPrintSizeKeyForNewUpload(),\n          default: size.default,\n        })\n      ),\n    };\n\n    builderDispatch.dispatch({\n      type: PrismUI.ADD_PHOTOS,\n      upload_url: this.props.urls.upload,\n      callToActionButtonText: 'Add to prints',\n      callToActionButtonEvent: 'event_add_to_prints',\n      add_title_text: 'photos will be added to your prints order',\n      additionalOptions,\n    });\n  },\n  handleAddPhotosFromGallery() {\n    const loader = new PrintsBuilderPhotoAlbumDirectLoader(\n      this.props.urls.upload_from_album,\n      this.handleUploadBegun,\n      this.handleUploadProgress,\n      this.handleUploadDone\n    );\n\n    loader.listen(this.props.uploadFromGalleryListenerUrl);\n  },\n  handleUploadBegun(total) {\n    this.setState({\n      currentlyLoading: {\n        index: 0,\n        total,\n        isComplete() {\n          return this.index === this.total;\n        },\n      },\n    });\n\n    this.setWarningBeforeNavigatingAwayDuringUpload();\n  },\n  handleUploadProgress(photo, source, total) {\n    // Important - the `photo` object is later added to the print size array but this reference is\n    // maintained and the object mutated later, `setState` is called with other keys but this triggers\n    // re-render with the `photo` object at that point\n    photo.source = source;\n    photo.uploaded = true;\n\n    const { currentlyLoading } = this.state;\n    const sizeKey = this.getPrintSizeKeyForNewUpload();\n\n    // Important - state is not updated through `setState` for some reason - instead we have\n    // to use `getSizeFromKey` which returns reference to obj which is then mutated\n    const size = this.getSizeFromKey(sizeKey);\n    size.photos = [].concat(photo, size.photos);\n\n    if (!currentlyLoading) {\n      return;\n    }\n\n    // delay adding the photo to the sizes photo array\n    // until the thumbnail has been pulled to the browser\n\n    preloadImage.call(this, 0, onPreloadSuccess, onPreloadFail);\n\n    // periodic save of order\n    if ((currentlyLoading.index + 1) % 10 === 0) {\n      this.save();\n    }\n\n    function preloadImage(attemptIndex, successCallback, failureCallback) {\n      const that = this;\n      const urls = ['thumb_url', 'large_url', 'raw_url'];\n      const url = urls[attemptIndex];\n\n      if (!photo[url]) {\n        failureCallback.call(that, attemptIndex);\n        return;\n      }\n\n      fetchImage(\n        photo[url],\n        '',\n        function() {\n          if (this.width > 600 || this.height > 600) {\n            resizeCorpulentImage(this, url => {\n              successCallback.call(that, url);\n            });\n          } else {\n            successCallback.call(that, this.src);\n          }\n        },\n        () => {\n          failureCallback.call(that, attemptIndex);\n        }\n      );\n    }\n\n    function resizeCorpulentImage(image, callback) {\n      let w;\n      let h;\n      if (image.width > image.height) {\n        w = 600;\n        h = (600 * image.height) / image.width;\n      } else {\n        h = 600;\n        w = (600 * image.width) / image.height;\n      }\n\n      const canvas = document.createElement('canvas');\n      let ctx;\n      canvas.width = w;\n      canvas.height = h;\n      ctx = canvas.getContext('2d');\n      ctx.scale(w / image.width, w / image.width);\n      ctx.drawImage(image, 0, 0);\n      if (typeof canvas.toBlob === 'function') {\n        canvas.toBlob(blob => {\n          const url = (window.URL || window.webkitURL).createObjectURL(blob);\n          callback(url);\n        }, 'image/jpeg');\n      } else {\n        callback(canvas.toDataURL('image/jpeg'));\n      }\n    }\n\n    function onPreloadSuccess(src) {\n      photo.thumb_url = src;\n      pushIntoFirstAvailablePhotoPlaceHolder.call(this, 'raw_url', photo);\n\n      incrementCurrentlyLoadingIndex.call(this);\n    }\n\n    function onPreloadFail(attemptIndex) {\n      if (attemptIndex < 3) {\n        preloadImage.call(\n          this,\n          attemptIndex + 1,\n          onPreloadSuccess,\n          onPreloadFail\n        );\n      } else {\n        incrementCurrentlyLoadingIndex.call(this);\n      }\n    }\n\n    function incrementCurrentlyLoadingIndex() {\n      const { currentlyLoading } = this.state;\n      if (!currentlyLoading) {\n        return;\n      }\n\n      ++currentlyLoading.index;\n      this.setState(\n        {\n          currentlyLoading,\n        },\n        function() {\n          if (currentlyLoading.isComplete()) {\n            this.setState({\n              currentlyLoading: undefined,\n            });\n\n            this.uploadCompleted();\n          }\n        }\n      );\n    }\n\n    function pushIntoFirstAvailablePhotoPlaceHolder(indicativeKey, newValue) {\n      this.state.sizes.forEach(size => {\n        for (let i = 0; i < size.photos.length; i++) {\n          if (!(indicativeKey in size.photos[i])) {\n            if (size.photos[i].quantity) {\n              newValue.quantity = size.photos[i].quantity;\n            }\n\n            Object.assign(size.photos[i], newValue);\n            break;\n          }\n        }\n      });\n    }\n\n    function uploadCompletedIfFinished() {\n      const { currentlyLoading } = this.state;\n      if (!currentlyLoading) return;\n\n      if (currentlyLoading.isComplete()) {\n        this.setState({\n          currentlyLoading: undefined,\n        });\n\n        this.uploadCompleted();\n      }\n    }\n  },\n  handleUploadDone(number_of_files, number_of_errors, message) {\n    if (number_of_errors) {\n      this.save();\n\n      // conventional upload\n      builderDispatch.delayedDispatch({\n        type: WebUI.UPLOAD_SHOW_FAILURES,\n        message,\n      });\n    }\n  },\n  handleUploadPaused() {\n    const { currentlyLoading } = this.state;\n    if (!currentlyLoading) return;\n\n    this.setState({\n      currentlyLoading: { ...currentlyLoading, paused: true },\n    });\n  },\n  handleUploadResumed() {\n    const { currentlyLoading } = this.state;\n    if (!currentlyLoading) return;\n\n    this.setState({\n      currentlyLoading: { ...currentlyLoading, paused: false },\n    });\n  },\n  handleAbortedUpload() {\n    this.setState(\n      {\n        currentlyLoading: undefined,\n      },\n      function() {\n        this.uploadCompleted();\n      }\n    );\n  },\n  removeIncompleteUploads() {\n    const sizes = $.extend([], this.state.sizes);\n\n    sizes.forEach(size => {\n      let i = size.photos.length - 1;\n      let photo;\n\n      while (i >= 0) {\n        photo = size.photos[i];\n\n        if (!('raw_url' in photo) && !('uploaded' in photo)) {\n          size.photos.splice(i, 1);\n        }\n        i--;\n      }\n    });\n\n    this.setState({\n      sizes,\n    });\n  },\n  uploadCompleted(callback) {\n    // you may depart\n    this.removeIncompleteUploads();\n\n    builderDispatch.delayedDispatch({\n      type: PrismUI.IMAGES_UPDATED,\n    });\n\n    const finaliseIntervalID = setInterval(() => {\n      if (!this.saving) {\n        this.saveHard(() => {\n          this.clearWarningBeforeNavigatingAwayDuringUpload();\n          clearInterval(finaliseIntervalID);\n\n          if (typeof callback === 'function') callback();\n        });\n      }\n    }, 100);\n  },\n\n  setWarningBeforeNavigatingAwayDuringUpload() {\n    this.setBeforeUnload(\n      'Photo uploading in progress. If you leave this page now your upload will be incomplete.'\n    );\n  },\n  clearWarningBeforeNavigatingAwayDuringUpload() {\n    this.setBeforeUnload();\n  },\n  setBeforeUnload(message) {\n    if ('onbeforeunload' in window) {\n      if (message) {\n        window.onbeforeunload = function() {\n          return message;\n        };\n      } else {\n        window.onbeforeunload = undefined;\n      }\n    } else if (message) {\n      $(document).on('click', 'a:not([href^=\"#\"])', showWarningMessage);\n    } else {\n      $(document).off('click', 'a:not([href^=\"#\"])', showWarningMessage);\n    }\n\n    function showWarningMessage(e) {\n      if (\n        !confirm(\n          'Photo uploading in progress. If you leave this page now your upload will be incomplete.'\n        )\n      ) {\n        e.preventDefault();\n      }\n    }\n  },\n  getPrintSizeKeyForNewUpload() {\n    const { viewingSizeKey, finish } = this.state;\n\n    // Try uploading via the mobile filtered size\n    if (viewingSizeKey && viewingSizeKey.includes(finish.name)) {\n      return viewingSizeKey;\n    }\n\n    // Try uploading via the selected uploader size\n    if (this.selectedSizeKey?.includes(finish.name)) {\n      return this.selectedSizeKey;\n    }\n\n    const availableSizes = this.availableSizesForSelectedDeliveryAndFinish();\n\n    // Try uploading via the default size otherwise first available size\n    return (\n      SizeHelpers.defaultSize(availableSizes)?.key || availableSizes[0].key\n    );\n  },\n};\n\nexport default UploadPhotosMixin;\n","/*\n  Helper function for looping through an object's properties.\n*/\nconst objEach = (obj, callback) => {\n  if (!obj) return;\n\n  Object.keys(obj).forEach(key => {\n    callback(key, obj[key]);\n  });\n};\n\n/*\n  Returns a cell in the table:\n    {\n      break: 1,\n      price: 12\n    }\n*/\nconst _pricingTablePriceBreak = (priceBreak, price) => {\n  return {\n    break: parseInt(priceBreak, 10),\n    price: price,\n  };\n}\n\n/*\n  Returns a product row in the table:\n    {\n      title: '4x6 (Glossy)',\n      delivery_prices: {\n        del_opt_1: [\n          { break: 1, price: 12 },\n          { break: 51, price: 42 },\n          { break: 101, price: 32 },\n        ],\n        ...\n      },\n      ...\n    }\n*/\nconst _pricingTableRow = (productsOfSize, productsPricesOfSize) => {\n  return {\n    title: productsOfSize[0].title,\n    delivery_prices: _productPricesToPricingTablePrices(productsPricesOfSize)\n  }\n};\n\n/*\n  Transforms the product's prices data structure:\n    {\n      del_opt_1: {\n        1: 12,\n        51: 42,\n        101: 32\n      },\n      del_opt_2: {\n        1: 22,\n        21: 19,\n        31: 14,\n        101: 11\n      }\n    }\n  into the PricingTable data structure:\n    {\n      del_opt_1: [\n        { break: 1, price: 12 },\n        { break: 51, price: 42 },\n        { break: 101, price: 32 }\n      ],\n      del_opt_2: [\n        { break: 1, price: 22 },\n        { break: 21, price: 19 },\n        { break: 31, price: 14 },\n        { break: 101, price: 11 }\n      ]\n    }\n*/\nconst _productPricesToPricingTablePrices = (productPrices) => {\n  const list = {};\n\n  objEach(productPrices, (deliveryOption, prices) => {\n    list[deliveryOption] || (list[deliveryOption] = []);\n\n    objEach(prices, (priceBreak, price) => {\n      list[deliveryOption].push(_pricingTablePriceBreak(priceBreak, price));\n    });\n  });\n\n  return list;\n}\n\n/*\n  Merge together the prices from a list of products.\n  The \"winner\" is the highest price of a break for the delivery option.\n  The result will have all delivery options and all that DO's price breaks.\n*/\nconst _bestPricesOfProducts = (products) => {\n  const bestPrices = {};\n\n  products.map(product => {\n    product.options.delivery_options.forEach(deliveryOption => {\n      bestPrices[deliveryOption] || (bestPrices[deliveryOption] = {});\n\n      objEach(product.prices[deliveryOption], (priceBreak, price) => {\n        if (!bestPrices[deliveryOption][priceBreak] ||\n          bestPrices[deliveryOption][priceBreak] < price) {\n          bestPrices[deliveryOption][priceBreak] = price;\n        }\n      });\n    });\n  });\n\n  return bestPrices;\n};\n\n/*\n  Returns the PricingTable data structure for a list of Print products.\n  Each row is a product, each column is a delivery option, each cell a price break.\n*/\nconst pricingTableData = (allProducts) => {\n  const allProductsBySize = allProducts.reduce((list, product) => {\n    const id = product.size_id;\n\n    list[id] || (list[id] = []);\n    list[id].push(product);\n\n    return list;\n  }, {});\n\n  return Object.values(allProductsBySize).map(productsOfSize => {\n    const productsPricesOfSize = _bestPricesOfProducts(productsOfSize);\n\n    return _pricingTableRow(productsOfSize, productsPricesOfSize);\n  });\n};\n\nexport {\n  pricingTableData,\n\n  _bestPricesOfProducts,\n  _productPricesToPricingTablePrices\n};\n","// Import Libraries\nimport React, { Component } from 'react';\nimport FocusTrap from 'focus-trap-react';\nimport PropTypes from 'prop-types';\nimport translate from '../../_utils/tools/translate';\nimport { builderDispatch, WebUI } from '../../_utils/ui';\nimport { DeliveryOption, PrintFinish, PrintSize } from '../prop-types';\nimport PricesTable from '../../_grouped-category/prices-table';\nimport { pricingTableData } from './_pricing-chart-popup';\n\nclass PricingChartPopup extends Component {\n  static isSquare(product) {\n    const matches = product.title.match(/[\\d.]+/g) || [];\n    if (matches.length !== 2) {\n      return false;\n    }\n\n    const [x, y] = matches;\n    return x === y;\n  }\n\n  constructor(props) {\n    super(props);\n\n    this.state = {\n      isOpen: false,\n    };\n\n    this.pricingChartModal = null;\n  }\n\n  UNSAFE_componentWillMount() {\n    this.builderDispatchToken = builderDispatch.register(payload => {\n      if (payload.type === WebUI.SHOW_PRINTS_PRICES) {\n        this.open();\n      }\n    });\n  }\n\n  componentDidMount() {\n    $(this.pricingChartModal)\n      .modal({ show: false })\n      .on('hide.bs.modal', () => {\n        this.setState({ isOpen: false });\n      })\n      .on('shown.bs.modal', () => {\n        this.setState({ isOpen: true });\n      });\n  }\n\n  componentWillUnmount() {\n    builderDispatch.unregister(this.builderDispatchToken);\n  }\n\n  open() {\n    $(this.pricingChartModal).modal('show');\n  }\n\n  close() {\n    $(this.pricingChartModal).modal('hide');\n  }\n\n  generateFinishesForDeliveryOptions() {\n    const { products, deliveryOptions } = this.props;\n\n    const finishesForDeliveryOptions = {};\n\n    products.forEach(product => {\n      const option = product.options;\n      option.delivery_options.forEach(deliveryOption => {\n        const availableDeliveryOption = deliveryOptions.find(\n          delOpt => delOpt.key === deliveryOption\n        );\n        if (!availableDeliveryOption) return;\n\n        const { code } = availableDeliveryOption;\n\n        if (!finishesForDeliveryOptions[code]) {\n          finishesForDeliveryOptions[code] = [];\n        }\n\n        if (\n          finishesForDeliveryOptions[code].indexOf(option.finish.name) === -1\n        ) {\n          finishesForDeliveryOptions[code].push(option.finish.name);\n        }\n      });\n    });\n\n    return finishesForDeliveryOptions;\n  }\n\n  printFinishDescription(finishesForDeliveryOption) {\n    const { finishes } = this.props;\n\n    const finishTitles = (finishesForDeliveryOption || []).map(\n      value => finishes.find(finish => finish.name === value).title\n    );\n\n    return finishTitles.length === 1\n      ? `${finishTitles[0]} Only`\n      : finishTitles.join(' or ');\n  }\n\n  deliveryDescriptionForCode(code, finishesForDeliveryOption) {\n    const { deliveryOptions } = this.props;\n    const deliveryOption = deliveryOptions.find(o => o.code === code);\n\n    return (\n      (deliveryOption && deliveryOption.help_text) ||\n      this.printFinishDescription(finishesForDeliveryOption[code])\n    );\n  }\n\n  render() {\n    const products = pricingTableData(this.props.products);\n    const oblongPrints = products.filter(\n      product => !PricingChartPopup.isSquare(product)\n    );\n    const squarePrints = products.filter(PricingChartPopup.isSquare);\n    const finishesForDeliveryOptions = this.generateFinishesForDeliveryOptions();\n    const { isOpen } = this.state;\n    const { deliveryOptions } = this.props;\n\n    return (\n      <FocusTrap active={isOpen}>\n        <div\n          ref={el => {\n            this.pricingChartModal = el;\n          }}\n          className=\"modal pricing-chart-popup\">\n          <div className=\"modal-dialog modal-lg\">\n            <div className=\"modal-content\">\n              <div className=\"modal-heading\">\n                <h4 className=\"modal-title\">Pricing Chart</h4>\n                <button\n                  aria-label=\"Close\"\n                  className=\"close\"\n                  data-dismiss=\"modal\"\n                  type=\"button\"\n                />\n              </div>\n              <div className=\"modal-body p-0\">\n                <PricesTable\n                  products={[...oblongPrints, ...squarePrints]}\n                  delivery_options={deliveryOptions}\n                  deliveryTitleRA={`${translate('Pickup')} in 1-Hour`}\n                  deliveryDescriptionRA={this.deliveryDescriptionForCode(\n                    'RA',\n                    finishesForDeliveryOptions\n                  )}\n                  deliveryDescriptionUFC={this.deliveryDescriptionForCode(\n                    'UFC',\n                    finishesForDeliveryOptions\n                  )}\n                  showBorders\n                />\n              </div>\n            </div>\n          </div>\n        </div>\n      </FocusTrap>\n    );\n  }\n}\n\nPricingChartPopup.propTypes = {\n  deliveryOptions: DeliveryOption,\n  finishes: PropTypes.arrayOf(PrintFinish),\n  products: PropTypes.arrayOf(PrintSize),\n}.isRequired;\n\nexport default PricingChartPopup;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport ListQuantityFieldHandlers from '../../common/list-quantity-field-handlers';\nimport NumberInputField from '../number-input-field';\n\n// Bulk Quantity Change Inputs are used to change the quantity of each size, if\n// each photo has the same quantity for that size. If the quantities are different\n// then the input is blank.\nconst uniformQuantityForPhotosOrBlank = (rootIds, photos = []) => {\n  const initialValue = photos[0] && photos[0].quantity;\n\n  if (!photos.length) return 0;\n\n  // if there are fewer photos for this size than\n  // there are altogether then there's not going to\n  // be a match\n  // deliberately undefined so number field is blank\n  if (photos.length < rootIds.length) return '';\n\n  for (let i = 0; i < photos.length; i += 1) {\n    // deliberately undefined so number field is blank\n    if (photos[i].quantity !== initialValue) return '';\n  }\n\n  return initialValue;\n};\n\nconst BulkQuantityChangeSize = ({\n  size_id: sizeId,\n  handleFormSubmit,\n  handleQuantityChange,\n  disabled,\n  title,\n  rootIds,\n  photos,\n}) => {\n  const inputID = `bulk-quantity-change-${sizeId}`;\n  const labelID = `${inputID}Label`;\n  const inputValue = uniformQuantityForPhotosOrBlank(rootIds, photos);\n\n  return (\n    <form\n      className=\"bulk-quantity-change__size form-inline\"\n      onSubmit={handleFormSubmit}>\n      <div className=\"form-group flex-nowrap\">\n        <NumberInputField\n          id={inputID}\n          min={0}\n          max={999}\n          disabled={disabled}\n          label={title}\n          value={inputValue}\n          noButtons\n          onChange={handleQuantityChange}\n          inputClassName=\"form-control-sm\"\n        />\n        {/* eslint-disable-next-line jsx-a11y/label-has-for */}\n        <label htmlFor={inputID} aria-labelledby={labelID}>\n          {title}\n        </label>\n      </div>\n    </form>\n  );\n};\n\nBulkQuantityChangeSize.propTypes = {\n  size_id: PropTypes.string,\n  title: PropTypes.string,\n  photos: PropTypes.string,\n  rootIds: PropTypes.arrayOf(PropTypes.number),\n  disabled: PropTypes.bool,\n  handleQuantityChange: PropTypes.func,\n  handleFormSubmit: PropTypes.func,\n}.isRequired;\n\nexport default ListQuantityFieldHandlers(BulkQuantityChangeSize);\n","import React, { useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { PrintSize, DeliveryOption } from '../../prop-types';\nimport BulkQuantityChangeSize from './size';\nimport photoRootIds from '../photo-root-ids';\nimport screenAndStyle from '../../../_utils/screen-and-style';\n\nexport default function BulkQuantityChange({\n  availableSizes,\n  photos,\n  disabled,\n  onChange,\n}) {\n  const [showAllSizes, setShowAllSizes] = useState(false);\n  const isMobile = screenAndStyle.assumePhoneOrSmallScreen();\n\n  function numberOfSizesToShow() {\n    if (isMobile) {\n      return 4;\n    }\n    if (screenAndStyle.isBootstrapLG()) {\n      return 6;\n    }\n\n    return 8;\n  }\n\n  function handleShowMoreSizesClick() {\n    setShowAllSizes(!showAllSizes);\n  }\n\n  const moreFewerButtonToggleLabel = `${showAllSizes ? 'Fewer' : 'More'} sizes`;\n  const sizes = showAllSizes\n    ? availableSizes\n    : availableSizes.slice(0, numberOfSizesToShow());\n  const rootIds = photoRootIds(photos, true);\n  const moreButton = (availableSizes.length > sizes.length || showAllSizes) && (\n    <div className=\"bulk-quantity-change__sizes-toggle d-flex align-items-end justify-content-end\">\n      <button\n        type=\"button\"\n        className=\"btn btn-link btn-underline px-0 py-1\"\n        aria-label={`View ${moreFewerButtonToggleLabel}`}\n        onClick={handleShowMoreSizesClick}>\n        {moreFewerButtonToggleLabel}\n      </button>\n    </div>\n  );\n\n  return (\n    <div className=\"bulk-quantity-change\">\n      <h6>Quick Order:</h6>\n      <p>Select and apply options to all photos.</p>\n      <div className=\"w-100 d-flex\">\n        <div className=\"bulk-quantity-change__sizes flex-grow-1\">\n          {sizes.map((size) => (\n            <BulkQuantityChangeSize\n              {...size}\n              title={\n                size.title + (size.options?.border === true ? ' Border' : '')\n              }\n              key={size.key}\n              sizeKey={size.key}\n              rootIds={rootIds}\n              disabled={disabled}\n              onChange={onChange}\n            />\n          ))}\n        </div>\n        {!isMobile && moreButton}\n      </div>\n      {isMobile && moreButton}\n    </div>\n  );\n}\n\nBulkQuantityChange.propTypes = {\n  availableSizes: PropTypes.arrayOf(PrintSize).isRequired,\n  photos: PropTypes.arrayOf(PrintSize),\n  onChange: PropTypes.func.isRequired,\n  disabled: PropTypes.bool.isRequired,\n  deliveryOption: DeliveryOption.isRequired,\n};\n\nBulkQuantityChange.defaultProps = {\n  photos: [],\n};\n","// Import Libraries\nimport React from 'react';\nimport classNames from 'classnames';\n// Import JS Modules\nimport SummaryTable from '../common/summary-table';\n\nconst SummaryChart = ({ className, ...props }) => (\n  <div className={classNames('summary-chart', className)}>\n    <h6>Your Print Order</h6>\n    <SummaryTable {...props} />\n  </div>\n);\n\nexport default SummaryChart;\n","/* eslint-disable react/no-array-index-key */\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nimport Spinner from '../../_utils/spinner';\nimport Button from '../../_common/button';\n\nexport default function LoadingPhotoPlaceholders({ index, total }) {\n  const remainingUploads = Number(total) - Number(index);\n\n  if (Number.isNaN(remainingUploads) || remainingUploads < 1) {\n    return null;\n  }\n\n  return (\n    <div className=\"list-view-desktop\">\n      {Array.from(Array(remainingUploads)).map((_, i) => {\n        return (\n          <section key={i} className=\"list-item\">\n            <div className=\"d-flex\">\n              <div className=\"flex-grow-1\">\n                <div className=\"d-inline-block list-item__preview\">\n                  <Spinner />\n                  <div\n                    role=\"toolbar\"\n                    className=\"list-item__controls d-flex justify-content-between align-items-center\">\n                    <Button\n                      disabled\n                      className=\"btn-link btn-underline edit-photo\"\n                      text=\"Edit\"\n                    />\n                    <Button\n                      disabled\n                      hideLabel\n                      className=\"btn-link remove-photo\"\n                      text=\"Delete\"\n                      icon=\"fa-trash-alt\"\n                    />\n                  </div>\n                </div>\n              </div>\n            </div>\n          </section>\n        );\n      })}\n    </div>\n  );\n}\n\nLoadingPhotoPlaceholders.propTypes = {\n  index: PropTypes.number,\n  total: PropTypes.number,\n};\n\nLoadingPhotoPlaceholders.defaultProps = {\n  index: 0,\n  total: 0,\n};\n","// Import JS Modules\nimport fetchImage from '../../_utils/fetch-image';\n\n// -----------------------------------------------------------\n// RawImageCache\n// -----------------------------------------------------------\nconst RawImageCache = (function () {\n  let list = [];\n  let generation = 0;\n\n  return {\n    cache(url) {\n      if (!url) return;\n\n      let item = find(url);\n      if (!item) {\n        item = {\n          url,\n          image: fetch(url),\n        };\n        list.push(item);\n      }\n      item.generation = generation;\n      return item;\n    },\n    get(url, callback) {\n      if (!url) return;\n\n      const { image } = this.cache(url);\n      if (image.complete && typeof image.naturalWidth !== 'undefined' && image.naturalWidth != 0) {\n        // image is loaded\n        callback(image);\n        return;\n      }\n\n      // image isn't loaded - yet\n      image.onload = function () {\n        callback(this);\n      };\n    },\n    newGen() {\n      generation++;\n    },\n    gc() {\n      const newList = [];\n      for (let i = 0; i < list.length; i++) {\n        if (list[i].generation == generation) {\n          newList.push(list[i]);\n        }\n      }\n      list = newList;\n    },\n  };\n\n  function find(url) {\n    for (let i = 0; i < list.length; i++) {\n      if (list[i].url === url) return list[i];\n    }\n  }\n\n  function fetch(url) {\n    return fetchImage(url.replace(/^https?:/, ''), '');\n  }\n})();\n\nexport default RawImageCache;\n","class CropperConvert {\n  constructor(scale) {\n    this.scale = scale;\n  }\n\n  get crop() {\n    return new CropperConvert.Crop(this.scale);\n  }\n\n  static Crop = class extends CropperConvert {\n    to(crop) {\n      // from Livelink to Cropper\n      const [x, y, width, height] = (crop || []).map(v => v / this.scale);\n\n      return { x, y, width, height };\n    }\n\n    from(data) {\n      // from Cropper to Livelink\n      const { x, y, width, height } = data;\n\n      return [x, y, width, height].map(v => v * this.scale);\n    }\n  };\n};\n\nexport default CropperConvert;\n","const MARGIN_LOW = -10;\nconst ZERO = 0;\n\nfunction snapCropToBounds({ x, y, width, height }) {\n  [x, y, width, height] = [x, y, width, height].map((v) => (MARGIN_LOW < v && v < ZERO ? ZERO : v)); // if any negative values are greater than -10 then snap them to zero\n\n  return { x, y, width, height };\n}\n\nexport default snapCropToBounds;\n","const MAXIMAL_ZOOM = 3;\nconst MODES = {\n  EDIT: 'drag',\n  BRIGHTNESS: 'brightness',\n  STRAIGHTEN: 'straighten',\n  CROP: 'crop-zoom',\n  ROTATE: 'rotate',\n  FILTERS: 'filters',\n};\n\nconst DEFAULT_MODE = MODES.CROP;\n\nconst EDIT_HEADER_TITLES = {\n  rotate: 'Rotate',\n  brightness: 'Brightness',\n  straighten: 'Tilt',\n  'crop-zoom': 'Crop & Zoom',\n  filters: 'Filters',\n};\n\nconst INITIAL_MIN_ZOOM = 1;\n\nexport {\n  MODES,\n  MAXIMAL_ZOOM,\n  EDIT_HEADER_TITLES,\n  DEFAULT_MODE,\n  INITIAL_MIN_ZOOM,\n};\n","import React from 'react';\nimport genericHelpers from '../../../_utils/generic-helpers';\nimport { builderDispatch } from '../../../_utils/ui';\nimport { UpdatePhotoEvents } from '../events/event-declarations';\n\nimport MobileFullScreen from '../../../_utils/mobile-full-screen';\nimport RawImageCache from '../raw-image-cache';\nimport CropperConvert from './cropper-convert';\nimport sendToGoogleAnalytics from '../../../_prism-builder/desktop/slot-tools/send-to-google-analytics';\nimport { FILTER_EFFECTS_OPTIONS } from '../../../_utils/advanced_editor/filter-effects-options';\nimport snapCropToBounds from './snap-crop-to-bounds';\nimport IU from '../../../_utils/img/img-utils';\nimport {\n  MAXIMAL_ZOOM,\n  MODES,\n  DEFAULT_MODE,\n  INITIAL_MIN_ZOOM,\n} from './constants';\n\nconst { imgHelpers, zoomHelpers } = IU;\n\nconst AdvancedEditorController = WrappedComponent => {\n  function extractPhotoData(source) {\n    return Object.keys(source).reduce((photoData, key) => {\n      if (typeof source[key] === 'function') {\n        return photoData;\n      }\n\n      return { ...photoData, [key]: source[key] };\n    }, {});\n  }\n\n  return class extends React.Component {\n    constructor(props) {\n      super(props);\n\n      this.state = {\n        imageSrc: null,\n        editMode: DEFAULT_MODE,\n      };\n      this.data = {};\n      this.initialZoom = INITIAL_MIN_ZOOM;\n\n      this.cropperRef = null;\n      this.setCropperRef = element => {\n        this.cropperRef = element;\n      };\n      this.setZoomSliderRef = element => {\n        this.zoomSliderRef = element;\n      };\n      this.setTiltSliderRef = element => {\n        this.tiltSliderRef = element;\n      };\n      this.setBrightnessSliderRef = element => {\n        this.brightnessSliderRef = element;\n      };\n      this.setDisplayEditValueRef = element => {\n        this.displayEditValueRef = element;\n      };\n\n      this.debouncedOnResize = genericHelpers.debounce(this.regenerateCropper);\n      this.debouncedRotate = genericHelpers.debounce(this.handleRotate);\n    }\n\n    componentDidMount() {\n      $(window).on('resize orientationchange', this.debouncedOnResize);\n    }\n\n    componentWillUnmount() {\n      $(window).off('resize orientationchange', this.debouncedOnResize);\n    }\n\n    getImageId = () => {\n      const { photo } = this.data;\n\n      return (photo || {}).image_id;\n    };\n\n    getDPI() {\n      const values = this.values();\n      values.raw_dimensions = {\n        w: values.crop[IU.WIDTH],\n        h: values.crop[IU.HEIGHT],\n      };\n\n      return parseInt(imgHelpers.getPhotoDPI(values), 10);\n    }\n\n    scale = () => {\n      const { photo } = this.data;\n      const { photo_image: image } = this.state;\n\n      return photo.raw_dimensions.w / image.naturalWidth;\n    };\n\n    updatePhotoEdits = () => {\n      const { photo } = this.data;\n      const values = this.values();\n\n      ['angle', 'crop', 'fx', 'gamma', 'straighten'].forEach(key => {\n        photo[key] = values[key] || null;\n      });\n\n      return photo;\n    };\n\n    apply = save => {\n      const photo = this.updatePhotoEdits();\n\n      builderDispatch.dispatch({\n        type: UpdatePhotoEvents.UPDATE,\n        photo,\n        hard: !!save,\n      });\n    };\n\n    setData = async (data, callback) => {\n      this.curCrop = undefined;\n\n      await this.clearDidChange();\n      await this.open();\n\n      this.data = this.data || {};\n      data.photo && (this.data.photo = extractPhotoData(data.photo));\n      data.availableSizes && (this.data.availableSizes = data.availableSizes);\n      data.sizes && (this.data.sizes = data.sizes);\n      await this.loadImage();\n\n      if (typeof this.getEffectUrls === 'function') {\n        this.getEffectUrls();\n      }\n\n      if (typeof callback === 'function') {\n        callback.call(this);\n      }\n    };\n\n    loadImage = () => {\n      return new Promise(resolve => {\n        const urlProp = 'large_url';\n        const photoUrl = this.data.photo[urlProp];\n\n        RawImageCache.newGen();\n        RawImageCache.cache(photoUrl);\n\n        this.setState(\n          {\n            photo_image: null,\n          },\n\n          () => {\n            RawImageCache.get(photoUrl, image => {\n              const { photo } = this.data;\n              const { image_id: imageId } = photo;\n              const scale = photo.raw_dimensions.w / image.naturalWidth;\n\n              this.curCrop = new CropperConvert(scale).crop.to(\n                zoomHelpers.getCrop(photo) || zoomHelpers.defaultCrop(photo)\n              );\n              this.curAngle = photo.angle || 0;\n              this.curEffect = photo.fx || IU.DEF_FX;\n\n              const gamma = photo.gamma || 1;\n\n              zoomHelpers.setBrightness(imageId, gamma * 10);\n              zoomHelpers.setStraighten(imageId, photo.straighten);\n\n              this.resetSliderValues();\n\n              this.setState(\n                {\n                  photo_image: image,\n                  editMode: DEFAULT_MODE,\n                  imageSrc: this.generateProcessedPhotoImageSrc(image),\n                },\n\n                () => {\n                  this.justLoaded = true;\n\n                  RawImageCache.gc();\n\n                  resolve();\n                }\n              );\n            });\n          }\n        );\n      });\n    };\n\n    generateProcessedPhotoImageSrc = (image, effect = this.curEffect) => {\n      const {\n        photo: { image_id: imageId },\n      } = this.data;\n      const props = {\n        angle: this.curAngle,\n        fx: effect,\n        gamma: zoomHelpers.getBrightness(imageId) / 10,\n        straighten: zoomHelpers.getStraighten(imageId),\n      };\n\n      return IU.imgHelpers.doProcessPhoto(image, props).toDataURL();\n    };\n\n    values = () => {\n      const { photo } = this.data;\n      const { image_id: imageId } = photo;\n      const scale = this.scale();\n\n      return {\n        angle: this.curAngle,\n        crop: new CropperConvert(scale).crop.from(\n          this.curCrop || zoomHelpers.defaultCrop(photo)\n        ),\n        fx: this.curEffect,\n        gamma: zoomHelpers.getBrightness(imageId) / 10,\n        size_area: photo.size.area,\n        straighten: zoomHelpers.getStraighten(imageId),\n      };\n    };\n\n    resetSliderValues = imageId => {\n      const id = imageId || this.getImageId();\n\n      [\n        {\n          ref: 'zoomSliderRef',\n          value: zoomHelpers.getZoom(id),\n        },\n        {\n          ref: 'tiltSliderRef',\n          value: zoomHelpers.getStraighten(id),\n        },\n        {\n          ref: 'brightnessSliderRef',\n          value: zoomHelpers.getBrightness(id),\n        },\n      ].forEach(sliderData => {\n        if (this[sliderData.ref]) {\n          this[sliderData.ref].set(sliderData.value);\n        }\n      });\n    };\n\n    getEffectUrls = async () => {\n      const { photo_image: image } = this.state;\n\n      if (!image) {\n        return;\n      }\n\n      const promises = FILTER_EFFECTS_OPTIONS.map(({ value: effect }) => {\n        return new Promise(resolve => {\n          window.setTimeout(() => {\n            resolve({\n              effect,\n              url: this.generateProcessedPhotoImageSrc(image, effect),\n            });\n          });\n        });\n      });\n\n      const effectUrls = (await Promise.all(promises)).reduce(\n        (urls, { effect, url }) => {\n          urls[effect] = url;\n          return urls;\n        },\n        {}\n      );\n\n      this.setState({\n        effectUrls,\n      });\n    };\n\n    open = () => {\n      this.should_apply_changes = true;\n\n      return new Promise(resolve => {\n        this.setState(\n          {\n            open: true,\n            effectUrls: undefined,\n          },\n          () => {\n            resolve();\n          }\n        );\n      });\n    };\n\n    close = cancelDidChange => {\n      if (cancelDidChange) {\n        this.did_change = false;\n      }\n\n      this.setState(\n        {\n          open: false,\n        },\n        () => {\n          builderDispatch.delayedDispatch({\n            type: UpdatePhotoEvents.ADVANCED_EDIT_CLOSE,\n          });\n        }\n      );\n    };\n\n    setInitialZoom = () => {\n      if (!this.cropperRef) {\n        return;\n      }\n\n      // trigger a zoom event with dummy data to set the zoom slider's intial value\n      const canvasData = this.cropperRef.getCanvasData();\n      this.initialZoom = canvasData.width / canvasData.naturalWidth;\n\n      // set the zoom slider's `min`\n      this.forceUpdate(() => this.cropperRef.zoomTo(this.initialZoom));\n    };\n\n    clearDidChange = () => {\n      return new Promise(resolve => {\n        this.did_change = false;\n\n        this.setState(\n          {\n            editMode: DEFAULT_MODE,\n            imageSrc: undefined,\n          },\n          () => {\n            resolve();\n          }\n        );\n      });\n    };\n\n    regenerateCropper = () => {\n      const { open } = this.state;\n\n      if (!open) {\n        return;\n      }\n\n      if (this.cropperRef) {\n        this.cropperRef.cropper.destroy();\n      }\n\n      const previousDidChange = this.did_change;\n\n      this.setData(\n        {\n          photo: {\n            ...this.data.photo,\n            ...this.values(),\n          },\n        },\n\n        () => {\n          this.did_change = previousDidChange;\n        }\n      );\n    };\n\n    handleTweakerDidChange = (\n      updateProcessedPhotoImageSrc = false,\n      onlyColorChanged = true\n    ) => {\n      this.did_change = true;\n\n      if (!updateProcessedPhotoImageSrc) {\n        return;\n      }\n\n      const { photo_image: image } = this.state;\n      const { viewport } = this.props;\n      const imageSrc = this.generateProcessedPhotoImageSrc(image);\n\n      this.updatePhotoEdits();\n\n      this.cropperRef && this.cropperRef.replace(imageSrc, onlyColorChanged);\n\n      viewport.isMobile &&\n        this.setState({\n          imageSrc: imageSrc,\n        });\n    };\n\n    handleEffect = value => {\n      this.curEffect = value;\n      this.handleTweakerDidChange(true);\n    };\n\n    handleZoom = value => {\n      this.zoomSliderTriggered = true;\n      this.displayEditValueRef && this.displayEditValueRef.set(value);\n\n      if (this.cropperRef) {\n        this.cropperRef.zoomTo(value);\n      }\n    };\n\n    handleStraighten = value => {\n      let newStraightenValue = parseFloat(value);\n\n      if (Number.isNaN(newStraightenValue)) {\n        newStraightenValue = IU.DEF_STRAIGHTEN;\n      }\n\n      zoomHelpers.setStraighten(this.getImageId(), newStraightenValue); // For Slider setting later\n\n      this.handleTweakerDidChange(true);\n    };\n\n    handleApply = () => {\n      if (this.did_change) {\n        this.apply(true);\n      }\n\n      this.close();\n    };\n\n    handleCrop = e => {\n      if (this.justLoaded) {\n        // this will set the zoom slider to the initial value in the cropper\n        // and set the slider's minmum value to it if required\n        // so that there isn't a coarse jump when first sliding.\n        // doing it here because the cropper has just initialized\n        this.setInitialZoom();\n        delete this.justLoaded;\n      }\n\n      this.curCrop = snapCropToBounds(e.detail);\n\n      this.handleTweakerDidChange();\n    };\n\n    handleCropperZoom = e => {\n      const value = e.detail.ratio;\n\n      if (value >= MAXIMAL_ZOOM) {\n        e.preventDefault();\n        return false;\n      }\n\n      const { image_id: imageId } = this.data.photo;\n      zoomHelpers.setZoom(imageId, value); // For Slider setting later\n\n      if (!this.zoomSliderTriggered && this.zoomSliderRef) {\n        this.displayEditValueRef && this.displayEditValueRef.set(value);\n        this.zoomSliderRef.set(value);\n      }\n\n      delete this.zoomSliderTriggered;\n    };\n\n    handleRotate = ({ angle = IU.RIGHT_ANGLE }) => {\n      const { photo } = this.data;\n\n      this.curAngle = this.curAngle || 0;\n      this.curAngle = (this.curAngle - angle) % 360;\n\n      while (this.curAngle < 0) {\n        this.curAngle += 360;\n      }\n\n      sendToGoogleAnalytics('el2', 'rotate');\n\n      // reset the crop. Saves a lot of fuss\n      this.curCrop = new CropperConvert(this.scale()).crop.to(\n        zoomHelpers.defaultCrop(photo)\n      );\n\n      this.handleTweakerDidChange(true, false);\n    };\n\n    handleBrightness = value => {\n      let newBrightnessValue = Number(value);\n      if (Number.isNaN(newBrightnessValue)) {\n        newBrightnessValue = IU.DEF_BRIGHT;\n      }\n      const {\n        photo: { image_id: imageId },\n      } = this.data;\n      zoomHelpers.setBrightness(imageId, newBrightnessValue); // For Slider setting later\n\n      this.handleTweakerDidChange(true);\n    };\n\n    handleReset = async () => {\n      const { photo } = this.data;\n\n      // strip most changes, but \"undo\" any saved straighten and brightness values\n      ['angle', 'crop', 'saturation'].forEach(key => {\n        photo[key] = null;\n      });\n      photo.straighten = IU.DEF_STRAIGHTEN; // Default Value\n      photo.gamma = IU.DEF_GAMMA; // Reset to default\n      photo.fx = IU.DEF_FX; // Default Value\n\n      this.curCrop = null;\n      this.curAngle = null;\n      this.curEffect = photo.fx;\n\n      zoomHelpers.setZoom(photo.image_id, null);\n      zoomHelpers.setBrightness(photo.image_id, photo.gamma * 10);\n      zoomHelpers.setStraighten(photo.image_id, photo.straighten);\n      await this.getEffectUrls();\n      await this.loadImage();\n    };\n\n    handleEditMode = editMode => {\n      const selectedMode = Object.values(MODES).includes(editMode);\n\n      if (!selectedMode) {\n        return;\n      }\n\n      this.setState(\n        {\n          editMode,\n        },\n        () => {\n          this.resetSliderValues();\n        }\n      );\n\n      if (editMode === MODES.ROTATE) {\n        this.debouncedRotate({ angle: IU.RIGHT_ANGLE });\n      } else {\n        this.updatePhotoEdits();\n      }\n    };\n\n    render() {\n      const { open, imageSrc, editMode, effectUrls } = this.state;\n      const handlers = {\n        handleRotate: this.debouncedRotate,\n        handleApply: this.handleApply,\n        handleCrop: this.handleCrop,\n        handleCropperZoom: this.handleCropperZoom,\n        handleBrightness: this.handleBrightness,\n        handleReset: this.handleReset,\n        handleEffect: this.handleEffect,\n        handleZoom: this.handleZoom,\n        handleStraighten: this.handleStraighten,\n        close: this.close,\n        handleEditMode: this.handleEditMode,\n      };\n\n      const refs = {\n        cropperRef: this.setCropperRef,\n        zoomSliderRef: this.setZoomSliderRef,\n        tiltSliderRef: this.setTiltSliderRef,\n        brightnessSliderRef: this.setBrightnessSliderRef,\n        displayEditValueRef: this.setDisplayEditValueRef,\n      };\n\n      const editorProps = {\n        ...this.data,\n        curCrop: this.curCrop,\n        imageSrc,\n        editMode,\n        effectUrls,\n        initialZoom: this.initialZoom,\n        open,\n      };\n\n      return (\n        <MobileFullScreen\n          className=\"image-slot-editor advanced-editor\"\n          open={!!open}\n          onBack={this.close}\n          noHeader\n          fullWidth>\n          <WrappedComponent refs={refs} handlers={handlers} {...editorProps} />\n        </MobileFullScreen>\n      );\n    }\n  };\n};\n\nexport default AdvancedEditorController;\n","import React from 'react';\nimport Cropper from 'react-cropper';\nimport PropTypes from 'prop-types';\nimport { UploadedPhoto } from '../../prop-types';\n\nimport 'cropperjs/dist/cropper.css';\nimport '../../../../../stylesheets/common/cropper-custom.css';\n\nimport IU from '../../../_utils/img/img-utils';\nimport Spinner from '../../../_utils/spinner';\n\nconst { imgHelpers } = IU;\n\nexport default function ImageCropper({\n  style,\n  imageSrc,\n  photo,\n  curCrop,\n  handleCropperZoom,\n  handleCrop,\n  cropperRef,\n}) {\n  if (!photo) {\n    return null;\n  }\n\n  if (!curCrop) {\n    return <Spinner style={style} />;\n  }\n\n  // The cropper\n  return (\n    <CropperWrapper>\n      <Cropper\n        key={`tweaker${photo.imageId}`}\n        id={`tweaker${photo.imageId}`}\n        ref={cropperRef}\n        style={style}\n        src={imageSrc}\n        alt=\"editor\"\n        data={curCrop}\n        aspectRatio={imgHelpers.getPhotoAspectRatio(photo)}\n        viewMode={2} // the crop box should be within the canvas\n        dragMode=\"move\"\n        toggleDragModeOnDblclick={false}\n        background={false}\n        autoCropArea={1}\n        minCropBoxWidth={1}\n        minCropBoxHeight={1}\n        crop={handleCrop}\n        zoom={handleCropperZoom}\n      />\n    </CropperWrapper>\n  );\n}\n\nexport const CropperWrapper = ({ children }) => {\n  return (\n    <div className=\"image_cropper__photo h-100\" aria-label=\"Resize Image\">\n      {children}\n    </div>\n  );\n};\n\nImageCropper.propTypes = {\n  style: PropTypes.shape({\n    width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n    height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n  }).isRequired,\n  imageSrc: PropTypes.string,\n  photo: UploadedPhoto,\n  curCrop: PropTypes.shape({\n    width: PropTypes.oneOfType([PropTypes.number]),\n    height: PropTypes.oneOfType([PropTypes.number]),\n  }),\n  handleCropperZoom: PropTypes.func.isRequired,\n  handleCrop: PropTypes.func.isRequired,\n  cropperRef: PropTypes.func.isRequired,\n};\n\nImageCropper.defaultProps = {\n  imageSrc: null,\n  photo: null,\n  curCrop: null,\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nexport const NUMBER_OF_TICKS = 40;\nexport const TICK_INCREMENT_PC = 100 / NUMBER_OF_TICKS;\n\nexport default function SliderScale({ className, setRef }) {\n  const TICK_SEQUENCE = Array.from(\n    { length: NUMBER_OF_TICKS + 1 },\n    (_, i) => Math.round(i * TICK_INCREMENT_PC * 10) / 10\n  );\n\n  return (\n    <svg\n      ref={setRef}\n      className={className}\n      role=\"presentation\"\n      width=\"100%\"\n      height=\"33\"\n      xmlns=\"http://www.w3.org/2000/svg\"\n      overflow=\"visible\">\n      <g transform=\"translate(0,14)\">\n        {TICK_SEQUENCE.map(inc => {\n          const majorIncrement = inc % 25 === 0;\n\n          return (\n            <rect\n              key={inc}\n              className={`tick tick__${majorIncrement ? 'major' : 'minor'}`}\n              x={`${inc}%`}\n              y={majorIncrement ? '-1' : '1'}\n              width={majorIncrement ? '2' : '1'}\n              height={majorIncrement ? '12' : '8'}\n            />\n          );\n        })}\n      </g>\n    </svg>\n  );\n}\n\nSliderScale.propTypes = {\n  className: PropTypes.string,\n};\n\nSliderScale.defaultProps = {\n  className: '',\n};\n","/* eslint-disable jsx-a11y/label-has-for */\n\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport MananaSlider from '../../../_utils/manana-slider';\nimport SliderScale, { NUMBER_OF_TICKS } from './slider-scale';\n\nconst SliderControl = props => {\n  const {\n    id,\n    label,\n    disabled,\n    onChange,\n    value,\n    threshold,\n    min,\n    max,\n    className,\n    sliderRef,\n    hideLabel,\n  } = props;\n  const step = (max - min) / (NUMBER_OF_TICKS * 4); // Ensure input steps are smaller than the markers for smoother movement\n\n  return (\n    <div className={classNames('slider-control', className)}>\n      <label className={classNames({ 'sr-only': hideLabel })} htmlFor={id}>\n        {label}\n      </label>\n      <div\n        className={classNames('slider-control__wrapper', {\n          disabled: disabled,\n        })}>\n        <MananaSlider\n          ref={sliderRef}\n          id={id}\n          classNames\n          disabled={disabled}\n          label={label}\n          min={min}\n          max={max}\n          step={step}\n          value={value}\n          handleChange={onChange}\n          threshold={threshold}\n        />\n\n        <SliderScale />\n      </div>\n    </div>\n  );\n};\n\nSliderControl.propTypes = {\n  id: PropTypes.string.isRequired,\n  label: PropTypes.string.isRequired,\n  className: PropTypes.string,\n  disabled: PropTypes.bool,\n  onChange: PropTypes.func,\n  value: PropTypes.number.isRequired,\n  threshold: PropTypes.number,\n  min: PropTypes.number,\n  max: PropTypes.number,\n  sliderRef: PropTypes.func,\n  hideLabel: PropTypes.bool,\n};\n\nSliderControl.defaultProps = {\n  disabled: false,\n  hideLabel: false,\n  threshold: undefined,\n  min: 0,\n  max: 100,\n  onChange: () => {},\n  className: null,\n  sliderRef: () => {},\n  label: '',\n};\n\nexport default SliderControl;\n","// Import Libraries\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport sendToGoogleAnalytics from '../../../_prism-builder/desktop/slot-tools/send-to-google-analytics';\nimport { FILTER_EFFECTS_OPTIONS } from '../../../_utils/advanced_editor/filter-effects-options';\n\nclass FilterButtons extends React.Component {\n  constructor(props) {\n    super(props);\n\n    this.state = {\n      effect: props.defaultValue,\n    };\n  }\n\n  render() {\n    const {\n      label: selectedLabel,\n      value: selectedValue,\n    } = FILTER_EFFECTS_OPTIONS.reduce((selected, option) =>\n      option.value == this.state.effect ? option : selected\n    );\n\n    return (\n      <div className=\"filters\">\n        <label tabIndex=\"0\">\n          Filters\n          <span className=\"d-none d-lg-inline text-capitalize\">\n            : {selectedLabel}\n          </span>\n        </label>\n        <div className=\"d-flex\">\n          {FILTER_EFFECTS_OPTIONS.filter(\n            ({ value }) => (this.props.urls || {})[value]\n          ).map(({ label, value }) => {\n            return (\n              <button\n                aria-label={label}\n                aria-pressed={selectedValue == value}\n                className={classNames('btn btn-link p-0', {\n                  selected: selectedValue == value,\n                })}\n                key={value}\n                title={label}\n                onClick={this.handleClick.bind(this, value)}>\n                <img\n                  alt={`${label} filter`}\n                  className=\"h-100 w-100\"\n                  role=\"presentation\"\n                  src={this.props.urls[value]}\n                />\n              </button>\n            );\n          })}\n        </div>\n      </div>\n    );\n  }\n\n  handleClick(value) {\n    this.setState(\n      {\n        effect: value,\n      },\n      function() {\n        this.props.onChange(value);\n      }\n    );\n\n    sendToGoogleAnalytics('el2', `filter-${value}`);\n  }\n}\n\nFilterButtons.propTypes = {\n  defaultValue: PropTypes.string,\n  onChange: PropTypes.func.isRequired,\n  urls: PropTypes.shape({ [PropTypes.string]: PropTypes.string }),\n};\n\nFilterButtons.defaultOptions = {\n  urls: {},\n  defaultValue: null,\n};\n\nexport default FilterButtons;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '../../../_common/button';\n\nexport default function Navigation({ handleApply, close, handleReset }) {\n  return (\n    <div\n      className={\n        'advanced-editor__navigation w-100 mt-auto mx-auto d-flex align-items-center justify-content-between'\n      }>\n      <Button\n        type=\"button\"\n        className=\"btn btn-link reset\"\n        aria-label=\"Reset changes\"\n        onClick={handleReset}>\n        Reset\n      </Button>\n      <Button\n        type=\"button\"\n        className=\"btn btn-link cancel\"\n        aria-label=\"Cancel changes and close edit window\"\n        onClick={close}>\n        Cancel\n      </Button>\n      <Button\n        type=\"button\"\n        className=\"btn btn-primary apply\"\n        aria-label=\"Apply changes and close edit window\"\n        onClick={handleApply}>\n        Apply\n      </Button>\n    </div>\n  );\n}\n\nNavigation.propTypes = {\n  handleApply: PropTypes.func.isRequired,\n  close: PropTypes.func.isRequired,\n  handleReset: PropTypes.func.isRequired,\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { UploadedPhoto } from '../../prop-types';\nimport SliderControl from '../../common/advanced-editor/slider-control';\nimport IU from '../../../_utils/img/img-utils';\nimport Button from '../../../_common/button';\nimport FilterButtons from '../../common/advanced-editor/filter-buttons';\nimport Navigation from '../../common/advanced-editor/navigation';\n\nconst { zoomHelpers } = IU;\n\nexport function SliderControlsPanel({\n  photo,\n  zoomSliderRef,\n  tiltSliderRef,\n  brightnessSliderRef,\n  initialZoom,\n  handleZoom,\n  handleStraighten,\n  handleBrightness,\n  handleRotate,\n  handleEffect,\n  effectUrls,\n  close,\n  handleReset,\n  handleApply,\n}) {\n  const imageId = (photo || {}).image_id;\n\n  return (\n    <div className=\"advanced-editor__slider-controls-panel h-100 d-flex flex-column\">\n      <h3 className=\"text-center mt-3\">Edit Photo</h3>\n      <div className=\"d-flex flex-column mt-3\">\n        <fieldset className=\"form-group\">\n          <legend className=\"h5 font-weight-bold\">Rotate</legend>\n          <div className=\"btn-toolbar mt-2\">\n            <Button\n              type=\"button\"\n              className=\"edit-btn rotate-acw\"\n              onClick={() => handleRotate({ angle: -IU.RIGHT_ANGLE })}\n              hideLabel>\n              Rotate 90 degrees anticlockwise\n            </Button>\n            <Button\n              type=\"button\"\n              className=\"edit-btn rotate-cw ml-3\"\n              onClick={() => handleRotate({ angle: IU.RIGHT_ANGLE })}\n              hideLabel>\n              Rotate 90 degrees clockwise\n            </Button>\n          </div>\n        </fieldset>\n        <SliderControl\n          sliderRef={zoomSliderRef}\n          label=\"Zoom\"\n          id=\"zoom-slider\"\n          className=\"form-group w-100 mt-1\"\n          onChange={handleZoom}\n          value={\n            zoomHelpers.getZoom(imageId) ||\n            zoomHelpers.getZoomFromPhotoData(photo) ||\n            initialZoom\n          }\n          min={initialZoom}\n          max={2.5}\n        />\n        <SliderControl\n          sliderRef={tiltSliderRef}\n          label=\"Tilt\"\n          id=\"tilt-slider\"\n          className=\"form-group w-100 mt-1\"\n          min={-20}\n          max={20}\n          threshold={100}\n          value={zoomHelpers.getStraighten(imageId)}\n          onChange={handleStraighten}\n        />\n        <SliderControl\n          sliderRef={brightnessSliderRef}\n          label=\"Brightness\"\n          id=\"brightness-slider\"\n          className=\"form-group w-100 mt-1\"\n          min={5}\n          max={15}\n          threshold={100}\n          value={zoomHelpers.getBrightness(imageId)}\n          onChange={handleBrightness}\n        />\n      </div>\n      <fieldset className=\"form-group mt-1 advanced-editor__filters\">\n        {photo && (\n          <FilterButtons\n            key={photo.fx}\n            defaultValue={photo.fx}\n            urls={effectUrls}\n            onChange={handleEffect}\n          />\n        )}\n      </fieldset>\n      <Navigation\n        handleReset={handleReset}\n        handleApply={handleApply}\n        close={close}\n      />\n    </div>\n  );\n}\n\nSliderControlsPanel.propTypes = {\n  photo: UploadedPhoto,\n  initialZoom: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),\n  effectUrls: PropTypes.shape({\n    [PropTypes.string]: PropTypes.string,\n  }),\n  zoomSliderRef: PropTypes.func.isRequired,\n  tiltSliderRef: PropTypes.func.isRequired,\n  brightnessSliderRef: PropTypes.func.isRequired,\n  handleZoom: PropTypes.func.isRequired,\n  handleStraighten: PropTypes.func.isRequired,\n  handleBrightness: PropTypes.func.isRequired,\n  handleRotate: PropTypes.func.isRequired,\n  handleEffect: PropTypes.func.isRequired,\n  close: PropTypes.func.isRequired,\n  handleReset: PropTypes.func.isRequired,\n  handleApply: PropTypes.func.isRequired,\n};\n\nSliderControlsPanel.defaultProps = {\n  photo: null,\n  effectUrls: {},\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport { UploadedPhoto } from '../../prop-types';\nimport { DEFAULT_MODE } from '../../common/advanced-editor/constants';\n\nimport FilterButtons from '../../common/advanced-editor/filter-buttons';\nimport Button from '../../../_common/button';\n\nexport default function Filters({\n  photo,\n  effectUrls,\n  handleEffect,\n  handleEditMode,\n  className,\n}) {\n  return (\n    <div className={classNames('advanced-editor__filters mx-auto', className)}>\n      <Button\n        type=\"button\"\n        className=\"edit-btn back-button\"\n        aria-label=\"Back to edit buttons\"\n        hideLabel\n        onClick={() => handleEditMode(DEFAULT_MODE)}\n      />\n      <FilterButtons\n        key={photo.fx}\n        defaultValue={photo.fx}\n        urls={effectUrls}\n        onChange={handleEffect}\n      />\n    </div>\n  );\n}\n\nFilters.propTypes = {\n  effectUrls: PropTypes.shape({\n    [PropTypes.string]: PropTypes.string,\n  }),\n  photo: UploadedPhoto.isRequired,\n  handleEffect: PropTypes.func.isRequired,\n  handleEditMode: PropTypes.func.isRequired,\n  className: PropTypes.string,\n};\n\nFilters.defaultProps = {\n  className: '',\n  effectUrls: {},\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport {\n  MODES,\n  EDIT_HEADER_TITLES,\n} from '../../common/advanced-editor/constants';\nimport Button from '../../../_common/button';\n\nconst ACTIVE_BTN_POSITION = 1;\n\nclass EditButtons extends React.PureComponent {\n  static orderEditButtons(orderableButtons, editMode) {\n    const orderableEditButtons = Object.assign([], orderableButtons);\n    const activeEditBtn = orderableEditButtons.findIndex(({ props }) =>\n      props.className.includes(editMode)\n    );\n\n    if (activeEditBtn !== -1) {\n      [\n        orderableEditButtons[ACTIVE_BTN_POSITION],\n        orderableEditButtons[activeEditBtn],\n      ] = [\n        orderableEditButtons[activeEditBtn],\n        orderableEditButtons[ACTIVE_BTN_POSITION],\n      ];\n    }\n\n    return orderableEditButtons;\n  }\n\n  constructor(props) {\n    super(props);\n  }\n\n  buttonClassNames = MODE => {\n    const { editMode } = this.props;\n\n    return classNames(`edit-btn ${MODE} text-nowrap`, {\n      active: MODE === editMode,\n    });\n  };\n\n  render() {\n    const {\n      handleEditMode,\n      className,\n      editMode,\n      photoEditsCurrentValues,\n      children,\n    } = this.props;\n    const { ROTATE, CROP, BRIGHTNESS, STRAIGHTEN, FILTERS } = MODES;\n\n    const orderableButtons = [BRIGHTNESS, CROP, STRAIGHTEN].map(mode => {\n      return (\n        <Button\n          key={mode}\n          type=\"button\"\n          className={this.buttonClassNames(mode)}\n          aria-label={`${EDIT_HEADER_TITLES[mode]} value is ${photoEditsCurrentValues[mode]}`}\n          onClick={() => handleEditMode(mode)}>\n          {EDIT_HEADER_TITLES[mode]}\n        </Button>\n      );\n    });\n\n    return (\n      <div\n        className={classNames(\n          'advanced-editor__edit-buttons align-items-center justify-content-around mx-auto',\n          className\n        )}>\n        <Button\n          type=\"button\"\n          className={`edit-btn ${FILTERS}`}\n          aria-label=\"Filters Edit\"\n          onClick={() => handleEditMode(FILTERS)}>\n          Filters\n        </Button>\n        {EditButtons.orderEditButtons(orderableButtons, editMode)}\n        <Button\n          type=\"button\"\n          className={`edit-btn ${ROTATE}`}\n          aria-label={`Rotate 90 degrees clockwise, current rotation is ${photoEditsCurrentValues[ROTATE]} degrees`}\n          onClick={() => handleEditMode(ROTATE)}>\n          Rotate\n        </Button>\n        {children}\n      </div>\n    );\n  }\n}\n\nexport default EditButtons;\n\nEditButtons.propTypes = {\n  handleEditMode: PropTypes.func.isRequired,\n  className: PropTypes.string,\n};\n\nEditButtons.defaultProps = {\n  className: '',\n};\n","import React from 'react';\n\nclass DisplayEditValue extends React.PureComponent {\n  static toFixedString(value) {\n    return Number(value)\n      .toFixed(1)\n      .toString();\n  }\n\n  constructor(props) {\n    super(props);\n\n    this.state = {\n      value: DisplayEditValue.toFixedString(this.props.value),\n    };\n  }\n\n  UNSAFE_componentWillReceiveProps(nextProps) {\n    const { value } = this.state;\n\n    if (nextProps.value !== value) {\n      this.set(nextProps.value);\n    }\n  }\n\n  set(value) {\n    const newValue = DisplayEditValue.toFixedString(value);\n    this.setState({ value: newValue });\n  }\n\n  render() {\n    const { hideValue } = this.props;\n    const { value } = this.state;\n\n    if (hideValue) {\n      return null;\n    }\n\n    return (\n      <div\n        key={value}\n        className=\"advanced-editor__display-edit-value position-absolute\">\n        {value}\n      </div>\n    );\n  }\n}\n\nexport default DisplayEditValue;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport genericHelpers from '../../../_utils/generic-helpers';\nimport SliderScale, {\n  TICK_INCREMENT_PC,\n} from '../../common/advanced-editor/slider-scale';\nimport {\n  percentageAsValue,\n  valueAsPercentage,\n} from '../../../_utils/tools/slider-control-conversions';\nimport DisplayEditValue from './display-edit-value';\nimport { EDIT_HEADER_TITLES } from '../../common/advanced-editor/constants';\n\nclass SliderControl extends React.PureComponent {\n  constructor(props) {\n    super(props);\n\n    this.startPos = null;\n    this.previousPos = null;\n\n    this.state = {\n      sliderActive: false,\n      sliderValue: this.props.value,\n    };\n\n    this.setScaleWrapper = element => {\n      this.scaleWrapper = element;\n    };\n    this.setSliderControlContainer = element => {\n      this.sliderControl = element;\n    };\n    this.setSliderFocusPoint = element => {\n      this.sliderFocusPoint = element;\n    };\n  }\n\n  componentDidMount() {\n    document.addEventListener('keydown', this.handleKeyPress);\n  }\n\n  componentWillUnmount() {\n    document.removeEventListener('keydown', this.handleKeyPress);\n  }\n\n  getSliderStartPos = () => {\n    const { left: sliderOffset } = this.sliderControl.getBoundingClientRect();\n    const { right, width } = this.scaleWrapper.getBoundingClientRect();\n    const startOffset = right - sliderOffset;\n\n    return Math.abs(startOffset - width * 1.5);\n  };\n\n  getSliderPercentage = () => {\n    const { width } = this.scaleWrapper.getBoundingClientRect();\n    return (this.getSliderStartPos() / width) * 100;\n  };\n\n  handleKeyPress = e => {\n    if (![37, 39].includes(e.keyCode)) {\n      return e;\n    }\n\n    const startPos = this.getSliderStartPos();\n\n    if (e.keyCode === 37) {\n      // Arrow Left\n      this.sliderControl.scrollLeft = startPos - TICK_INCREMENT_PC;\n    }\n\n    if (e.keyCode === 39) {\n      // Arrow Right\n      this.sliderControl.scrollLeft = startPos + TICK_INCREMENT_PC;\n    }\n\n    this.handleChange();\n  };\n\n  handleScroll = e => {\n    e.preventDefault();\n    const { offsetLeft } = this.sliderControl;\n    const mouseMovement = e.pageX - offsetLeft;\n    const distance = mouseMovement - this.startPos;\n    this.sliderControl.scrollLeft = this.previousPos - distance;\n  };\n\n  handleChange = () => {\n    const { onChange, threshold, min, max, disabled } = this.props;\n\n    if (disabled) {\n      return;\n    }\n\n    const percentage = this.getSliderPercentage();\n    const value = percentageAsValue({ percentage, min, max });\n\n    genericHelpers.debounce(onChange(value), threshold);\n    this.setState({ sliderValue: value });\n  };\n\n  handleMouseDown = e => {\n    const { offsetLeft, scrollLeft } = this.sliderControl;\n    this.setState({ sliderActive: true });\n    this.startPos = e.pageX - offsetLeft;\n    this.previousPos = scrollLeft;\n  };\n\n  handleLeave = () => {\n    this.setState({ sliderActive: false });\n  };\n\n  handleMouseMove = e => {\n    const { disabled } = this.props;\n    const { sliderActive } = this.state;\n\n    if (!sliderActive || disabled) {\n      return;\n    }\n\n    this.handleScroll(e);\n    this.handleChange();\n  };\n\n  set = value => {\n    const { min, max } = this.props;\n    const { width } = this.sliderControl.getBoundingClientRect();\n    const percentage = valueAsPercentage({ value, min, max });\n\n    this.sliderControl.scrollLeft = (width / 100) * percentage;\n    this.setState({ sliderValue: value });\n\n    // Set timeout for Mobile device focus\n    setTimeout(() => {\n      this.sliderFocusPoint.focus();\n    }, 1);\n  };\n\n  render() {\n    const { onChange, min, max, editMode } = this.props;\n\n    if (!onChange) {\n      return null;\n    }\n\n    const { sliderValue } = this.state;\n    const sliderDisplayValue = DisplayEditValue.toFixedString(sliderValue);\n\n    return (\n      <div className=\"slider-control__wrapper\">\n        <span className=\"slider-control__line badge badge-pill badge-primary\"></span>\n        <div\n          className=\"slider-control position-relative\"\n          ref={this.setSliderControlContainer}\n          tabIndex=\"0\">\n          <div\n            ref={this.setSliderFocusPoint}\n            role=\"slider\"\n            tabIndex=\"0\"\n            className=\"slider-control__scale-wrapper\"\n            aria-valuetext={`Current value for ${EDIT_HEADER_TITLES[editMode]} is ${sliderDisplayValue}`}\n            aria-valuemin={min}\n            aria-valuemax={max}\n            aria-valuenow={Number(sliderDisplayValue)}\n            aria-label=\"Swipe left or right with two fingers to adjust\"\n            onMouseDown={this.handleMouseDown}\n            onMouseMove={this.handleMouseMove}\n            onMouseUp={this.handleLeave}\n            onMouseLeave={this.handleLeave}\n            onTouchMove={this.handleChange}>\n            <SliderScale\n              setRef={this.setScaleWrapper}\n              className=\"slider-control__scale\"\n            />\n          </div>\n        </div>\n      </div>\n    );\n  }\n}\n\nexport default SliderControl;\n\nSliderControl.propTypes = {\n  min: PropTypes.number,\n  max: PropTypes.number,\n  threshold: PropTypes.number,\n  onChange: PropTypes.func,\n};\n\nSliderControl.defaultProps = {\n  min: 0,\n  max: 0,\n  threshold: 0,\n  onChange: null,\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { UploadedPhoto } from '../../prop-types';\nimport Filters from '../../mobile/advanced-editor/filters';\nimport EditButtons from './edit-buttons';\nimport DisplayEditValue from './display-edit-value';\nimport SliderControl from '../../mobile/advanced-editor/slider-control';\nimport Navigation from '../../common/advanced-editor/navigation';\nimport { MODES } from '../../common/advanced-editor/constants';\nimport IU from '../../../_utils/img/img-utils';\n\nconst { zoomHelpers } = IU;\n\nexport function SliderAndButtonsPanel({\n  close,\n  editMode,\n  photo,\n  effectUrls,\n  initialZoom,\n  handleApply,\n  handleReset,\n  handleEditMode,\n  handleZoom,\n  handleStraighten,\n  handleBrightness,\n  handleEffect,\n  ...refs\n}) {\n  const { CROP, ROTATE, STRAIGHTEN, BRIGHTNESS } = MODES;\n  const imageId = (photo || {}).image_id;\n\n  const filtersEnabled = editMode === MODES.FILTERS;\n  const filtersCss = filtersEnabled ? 'd-flex' : 'd-none';\n  const controlsCss = filtersEnabled ? 'd-none' : 'd-flex';\n\n  const sliderAttributes = {\n    [CROP]: {\n      ref: refs.zoomSliderRef,\n      onChange: handleZoom,\n      value:\n        zoomHelpers.getZoom(imageId) ||\n        zoomHelpers.getZoomFromPhotoData(photo) ||\n        initialZoom,\n      min: initialZoom,\n      max: 2.5,\n      threshold: 100,\n    },\n    [BRIGHTNESS]: {\n      ref: refs.brightnessSliderRef,\n      onChange: handleBrightness,\n      value: zoomHelpers.getBrightness(imageId),\n      min: 5,\n      max: 15,\n      threshold: 200,\n    },\n    [STRAIGHTEN]: {\n      ref: refs.tiltSliderRef,\n      onChange: handleStraighten,\n      value: zoomHelpers.getStraighten(imageId),\n      min: -20,\n      max: 20,\n      threshold: 200,\n    },\n    [ROTATE]: {\n      value: photo?.angle || 0,\n      onChange: () => {}, // Keep slider displayed for placement purposes\n    },\n  };\n\n  const currentSlider = Object.assign({ editMode }, sliderAttributes[editMode]);\n  const photoEditsCurrentValues = Object.entries(sliderAttributes).reduce(\n    (values, [key, { value }]) => {\n      return { ...values, ...{ [key]: DisplayEditValue.toFixedString(value) } };\n    },\n    {}\n  );\n\n  return (\n    <div className=\"advanced-editor__slider-and-buttons-panel w-100\">\n      {photo && (\n        <Filters\n          className={filtersCss}\n          handleEditMode={handleEditMode}\n          photo={photo}\n          effectUrls={effectUrls}\n          handleEffect={handleEffect}\n        />\n      )}\n      <EditButtons\n        className={`${controlsCss} w-50`}\n        editMode={editMode}\n        handleEditMode={handleEditMode}\n        photoEditsCurrentValues={photoEditsCurrentValues}>\n        <DisplayEditValue\n          ref={refs.displayEditValueRef}\n          hideValue={editMode === ROTATE}\n          value={currentSlider.value}\n        />\n      </EditButtons>\n      <SliderControl\n        ref={currentSlider.ref}\n        disabled={editMode === ROTATE}\n        {...currentSlider}\n      />\n      <Navigation\n        handleApply={handleApply}\n        close={close}\n        handleReset={handleReset}\n      />\n    </div>\n  );\n}\n\nSliderAndButtonsPanel.propTypes = {\n  photo: UploadedPhoto,\n  editMode: PropTypes.string.isRequired,\n  initialZoom: PropTypes.oneOfType([PropTypes.number, PropTypes.string])\n    .isRequired,\n  effectUrls: PropTypes.shape({\n    [PropTypes.string]: PropTypes.string,\n  }),\n  refs: PropTypes.shape({\n    [PropTypes.string]: PropTypes.func,\n  }),\n  handleZoom: PropTypes.func.isRequired,\n  handleStraighten: PropTypes.func.isRequired,\n  handleBrightness: PropTypes.func.isRequired,\n  handleRotate: PropTypes.func.isRequired,\n  handleEffect: PropTypes.func.isRequired,\n  close: PropTypes.func.isRequired,\n  handleReset: PropTypes.func.isRequired,\n  handleApply: PropTypes.func.isRequired,\n};\n\nSliderAndButtonsPanel.defaultProps = {\n  photo: null,\n  refs: {},\n  effectUrls: {},\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\n\nimport { EDIT_HEADER_TITLES } from './constants';\n\nexport default function Header({ title, className, id }) {\n  return (\n    <div id={id} className={className}>{EDIT_HEADER_TITLES[title] || 'Edit Photo'}</div>\n  );\n}\n\nHeader.propTypes = {\n  title: PropTypes.string,\n  className: PropTypes.string,\n  id: PropTypes.string.isRequired,\n};\n\nHeader.defaultProps = {\n  title: null,\n  className: '',\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { UploadedPhoto } from '../../prop-types';\nimport { PandaView } from '../../../_utils/image-editor';\nimport Spinner from '../../../_utils/spinner';\n\nexport default function ImageEditPreview({\n  style,\n  photo\n}) {\n  if (!photo) {\n    return <Spinner style={style} />;\n  }\n\n  return (\n    <PandaView\n      {...photo}\n      resolution=\"full-edit-preview\"\n      style={{ ...style, objectFit: 'contain' }}\n      cropEdges\n    />\n  );\n}\n\nImageEditPreview.propTypes = {\n  style: PropTypes.shape({\n    width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n    height: PropTypes.oneOfType([PropTypes.string, PropTypes.number])\n  }).isRequired,\n  photo: UploadedPhoto\n};\n\nImageEditPreview.defaultProps = {\n  photo: null\n};\n\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\n\nimport { UploadedPhoto } from '../../prop-types';\nimport AdvancedEditorController from '../../common/advanced-editor/controller';\nimport {\n  getViewport,\n  WithViewportSize,\n} from '../../../_utils/hoc/with-viewport-size';\nimport ImageCropper from '../../common/advanced-editor/image-cropper';\nimport { SliderControlsPanel } from '../../desktop/advanced-editor/slider-controls-panel';\nimport { SliderAndButtonsPanel } from '../../mobile/advanced-editor/slider-and-buttons-panel';\nimport { MODES } from './constants';\nimport Header from './header';\nimport ImageEditPreview from '../../mobile/advanced-editor/image-edit-preview';\nimport OrientationMessage from '../../../_utils/orientation-message';\nimport screenAndStyle from '../../../_utils/screen-and-style';\n\nconst AdvancedEditor = ({\n  imageSrc,\n  curCrop,\n  photo,\n  editMode,\n  effectUrls,\n  initialZoom,\n  refs,\n  handlers,\n  open,\n}) => {\n  const { CROP, ROTATE } = MODES;\n  const showCropper = [CROP, ROTATE].includes(editMode);\n  const orientationMessage =\n    'Please rotate your device to continue editing your print.';\n\n  const { height } = getViewport();\n  const isMobile = screenAndStyle.isBootstrapLGDown();\n\n  const cropperDimensions = {\n    height: isMobile ? height - 285 : '100%',\n    width: '100%',\n  };\n\n  return (\n    <div className=\"advanced-editor__wrapper d-flex flex-column\" role=\"dialog\" aria-label=\"Edit photo\" aria-describedby=\"advanced-editor-header\">\n      <Header\n        id={'advanced-editor-header'}\n        className=\"advanced-editor__header d-flex d-lg-none justify-content-center align-items-center grey-zone \"\n        title={editMode}\n      />\n      <div\n        className={classNames('advanced-editor__body row', {\n          preview: !showCropper,\n        })}>\n        <div\n          style={{\n            maxHeight: cropperDimensions.height,\n            minHeight: cropperDimensions.height,\n          }}\n          className=\"advanced-editor__photo col-xl-9 col-lg-8 col-sm-12 p-0\">\n          {showCropper ? (\n            <ImageCropper\n              cropperRef={refs.cropperRef}\n              style={cropperDimensions}\n              imageSrc={imageSrc}\n              curCrop={curCrop}\n              photo={photo}\n              {...handlers}\n            />\n          ) : (\n            <ImageEditPreview photo={photo} style={cropperDimensions} />\n          )}\n        </div>\n        {!isMobile && (\n          <div className=\"col-xl-3 col-lg-4 grey-zone\">\n            <SliderControlsPanel\n              photo={photo}\n              initialZoom={initialZoom}\n              effectUrls={effectUrls}\n              {...refs}\n              {...handlers}\n            />\n          </div>\n        )}\n      </div>\n      {isMobile && open && (\n        <SliderAndButtonsPanel\n          editMode={editMode}\n          imageSrc={imageSrc}\n          curCrop={curCrop}\n          photo={photo}\n          initialZoom={initialZoom}\n          effectUrls={effectUrls}\n          {...refs}\n          {...handlers}\n        />\n      )}\n      <OrientationMessage message={orientationMessage} />\n    </div>\n  );\n};\n\nAdvancedEditor.propTypes = {\n  imageSrc: PropTypes.string,\n  photo: UploadedPhoto,\n  curCrop: PropTypes.shape({\n    width: PropTypes.oneOfType([PropTypes.number]),\n    height: PropTypes.oneOfType([PropTypes.number]),\n  }),\n  initialZoom: PropTypes.number.isRequired,\n  refs: PropTypes.shape({\n    [PropTypes.string]: PropTypes.func,\n  }),\n  handlers: PropTypes.shape({\n    [PropTypes.string]: PropTypes.func,\n  }),\n  effectUrls: PropTypes.shape({\n    [PropTypes.string]: PropTypes.string,\n  }),\n};\n\nAdvancedEditor.defaultProps = {\n  imageSrc: null,\n  photo: null,\n  curCrop: null,\n  effectUrls: null,\n  refs: null,\n  handlers: null,\n  open: false,\n};\n\nexport default WithViewportSize(AdvancedEditorController(AdvancedEditor));\n","import React from 'react';\nimport classNames from 'classnames';\nimport PropTypes from 'prop-types';\nimport { PrintFinish } from '../prop-types';\nimport ButtonRibbon from '../../_utils/button-ribbon';\n\nexport default function PrintFinishTabs({ finishes, selectedFinish }) {\n  if (!finishes.length) {\n    return null;\n  }\n\n  return (\n    <ButtonRibbon\n      className=\"prints_builder-finish-tabs\"\n      role=\"tablist\"\n      gradient>\n      <ul className=\"nav nav-tabs w-100 d-flex flex-nowrap mt-2 px-lg-3 px-sm-1\">\n        {finishes.map(({ title, name }) => {\n          const active = name === selectedFinish.name;\n          const href = `${window.location.pathname}?finish=${title}`;\n\n          return (\n            <li\n              className={classNames(\n                'nav-item d-flex justify-content-center align-items-center text-nowrap mx-1',\n                {\n                  active: active,\n                  'grey-zone': active,\n                }\n              )}\n              onClick={() => (window.location.href = href)}\n              key={name}>\n              {title}\n            </li>\n          );\n        })}\n      </ul>\n    </ButtonRibbon>\n  );\n}\n\nPrintFinishTabs.propTypes = {\n  finishes: PropTypes.arrayOf(PrintFinish).isRequired,\n  selectedFinish: PrintFinish.isRequired,\n};\n","import createReactClass from 'create-react-class';\n// Import Libraries\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\n// Import JS Modules\nimport genericHelpers from '../../_utils/generic-helpers';\nimport screenAndStyle from '../../_utils/screen-and-style';\n// Import JSX Modules\nimport FullScreenSpinner from '../../_prism-builder/desktop/notices/full-screen-spinner';\nimport SiteLogo from '../../_application/site-logo';\nimport Login from '../../_application/login';\nimport AddPhotosDevice from '../common/add-photos-device';\nimport PhotosList from './photos-list';\nimport Totaliser from '../common/totalizer';\nimport AddToCartControls from '../common/add-to-cart-controls';\nimport UploadProgressBar from '../common/upload-progress-bar';\nimport Options from './options';\nimport InvalidSizesModal from '../common/invalid-sizes-modal';\nimport InvalidDeliveryOptionModal from '../common/invalid-delivery-option-modal';\nimport PhotoRemoveConfirmation from '../common/photo-remove-confirmation';\nimport SizeHelpers from '../common/size-helpers';\nimport PrintsBuilderMixin from '../common/prints-builder-mixin';\nimport UploadPhotosMixin from '../common/upload-photos-mixin';\nimport PricingChartPopup from './pricing-chart-popup';\nimport BulkQuantityChange from '../common/bulk-quantity-change';\nimport SummaryChart from './summary-chart';\nimport LoadingPhotoPlaceholders from './loading-photo-placeholders';\nimport AdvancedEditor from '../common/advanced-editor';\nimport PrintFinishTabs from '../common/print_finish_tabs';\nimport { PrintsBuilderUrlsShape } from '../prop-types';\n\n// -----------------------------------------------------------\n//  Controller\n// -----------------------------------------------------------\nconst PrintsBuilder = createReactClass({\n  mixins: [PrintsBuilderMixin, UploadPhotosMixin],\n  displayName: 'PrintsBuilder',\n  desktop: true,\n  getInitialState() {\n    return {\n      finish: {},\n      delivery_option: {},\n      sizes: [],\n      currentlyLoading: undefined,\n      invalidDeliveryOptionSelected: false,\n    };\n  },\n\n  UNSAFE_componentWillMount() {\n    this.loadData();\n    this.loadCallbacks();\n\n    this._forceUpdate = genericHelpers.debounce(() => this.forceUpdate());\n\n    $(window).on('resize orientationchange', this._forceUpdate);\n  },\n\n  componentDidMount() {\n    document.body.classList.add('disable-focus-styles');\n    window.addEventListener('keydown', this.handleKeyPress);\n  },\n\n  componentWillUnmount() {\n    this.unloadCallbacks();\n\n    $(window).off('resize orientationchange', this._forceUpdate);\n    window.removeEventListener('keydown', this.handleKeyPress, false);\n  },\n\n  render() {\n    const availableSizes = this.availableSizesForSelectedDeliveryAndFinish();\n    const { sizes, invalidDeliveryOptionSelected } = this.state;\n\n    const $pricingChartPopup = (({ pricesPopup }, { ready, sizes }) => {\n      if (pricesPopup && ready) {\n        return (\n          <PricingChartPopup\n            products={sizes}\n            finishes={this.data.finishes}\n            deliveryOptions={this.data.delivery_options}\n          />\n        );\n      }\n    })(window.features, this.state);\n\n    const hasPhotos = this.hasPhotos();\n    const sizesByFinish = this.getSizesByFinish();\n    const { currentlyLoading } = this.state;\n    const {\n      features: { pricesPopup, allowMultiplePrintFinishesPerOrder },\n    } = window;\n\n    return (\n      <div\n        className={classNames('prints-builder__grid desktop', {\n          'is-touch': screenAndStyle.isTouch(),\n        })}>\n        <header className=\"prints-builder__header d-flex align-items-center\">\n          <div className=\"flex-grow-1\">\n            <SiteLogo />\n          </div>\n          <div className=\"flex-shrink-0 d-flex align-items-center justify-content-end h-100\">\n            <Login />\n            <Totaliser\n              sizes={sizes}\n              deliveryOption={this.state.delivery_option}\n            />\n            <AddToCartControls\n              enabled={this.hasPrints() && !currentlyLoading}\n              basketUrl={this.props.urls.cart_page}\n              onAddToCart={this.handleAddToCart}\n            />\n          </div>\n        </header>\n        <main className=\"prints-builder__list d-flex flex-column position-relative\">\n          {allowMultiplePrintFinishesPerOrder && (\n            <PrintFinishTabs\n              finishes={[...this.data.finishes]}\n              selectedFinish={this.state.finish}\n            />\n          )}\n          <div className=\"grey-zone flex-shrink-0\">\n            <BulkQuantityChange\n              availableSizes={availableSizes}\n              sizes={sizes}\n              photos={this.allPhotos()}\n              deliveryOption={this.state.delivery_option}\n              disabled={!hasPhotos || !!currentlyLoading}\n              onChange={this.handleQuantityChanged}\n            />\n          </div>\n          <UploadProgressBar {...currentlyLoading} />\n          <div className=\"list-view\">\n            {!!currentlyLoading && (\n              <LoadingPhotoPlaceholders {...currentlyLoading} />\n            )}\n            {hasPhotos && (\n              <PhotosList\n                availableSizes={availableSizes}\n                sizes={sizesByFinish}\n                finish={this.state.finish}\n                deliveryOption={this.state.delivery_option}\n                showPricesPopup={pricesPopup}\n                disabled={!!currentlyLoading}\n                onQuantityChanged={this.handleQuantityChanged}\n              />\n            )}\n            {!this.hasPhotosForSelectedFinish() && !currentlyLoading && (\n              <AddPhotosDevice onClick={this.handleAddPhotos} />\n            )}\n          </div>\n        </main>\n        <aside className=\"prints-builder__side-bar d-flex flex-column grey-zone\">\n          <Options\n            availableSizes={availableSizes}\n            deliveryOptions={[...this.data.delivery_options]}\n            deliveryOption={this.state.delivery_option}\n            finishesByDeliveryOption={Object.assign(\n              {},\n              this.availableFinishesByDeliveryOption\n            )}\n            finishes={[...this.data.finishes]}\n            finish={this.state.finish}\n            showAllPricesLink={!!pricesPopup}\n            hidePrintFinishes={!!allowMultiplePrintFinishesPerOrder}\n            onChange={this.handleOptionsChanged}\n            onQuantityChanged={this.handleQuantityChanged}\n          />\n          <SummaryChart\n            className=\"flex-grow-1\"\n            sizes={sizes}\n            deliveryOption={this.state.delivery_option}\n          />\n          <button\n            ref={ref => (this.addPhotosButtonRef = ref)}\n            className=\"btn btn-outline-secondary add-photos\"\n            role=\"button\"\n            onClick={this.handleAddPhotos}\n            disabled={!!currentlyLoading || invalidDeliveryOptionSelected}>\n            Add {hasPhotos ? 'More' : ''} Photos\n          </button>\n        </aside>\n        <AdvancedEditor\n          ref={ref => (this.advancedEditorRef = ref)}\n          availableSizes={availableSizes}\n          onQuantityChanged={this.handleAdvancedPhotoQuantityChanged}\n        />\n        <PhotoRemoveConfirmation />\n        {$pricingChartPopup}\n        <InvalidSizesModal />\n        <InvalidDeliveryOptionModal />\n        <FullScreenSpinner show={!this.state.ready} />\n      </div>\n    );\n  },\n  handleAdvancedEdit(rootImageId, selectedSizeKey, isLastPhoto) {\n    // Retrieve the photo with the selectedSizeKey\n    const photo = this.state.sizes\n      .filter(size => size.photos.length)\n      .reduce((photo, size) => {\n        const relevantPhoto = this.getPhoto(size, rootImageId, true);\n        if (relevantPhoto && relevantPhoto.quantity) {\n          const tmpPhoto = SizeHelpers.augment.individual(relevantPhoto, size);\n          if (tmpPhoto.size.key == selectedSizeKey) {\n            photo = tmpPhoto;\n          }\n        }\n        if (photo) photo.isLastPhoto = isLastPhoto;\n        return photo;\n      }, undefined);\n\n    this.advanced_edit = {\n      size: photo.size,\n      photo: photo,\n    };\n\n    this.advancedEditor().setData({\n      photo: photo,\n      availableSizes: this.availableSizesForSelectedDeliveryAndFinish(),\n      sizes: [...this.state.sizes],\n    });\n  },\n  refreshEL2(sizeKey, imageId) {\n    if (this.advanced_edit) {\n      const size = this.getSizeFromKey(sizeKey),\n        photo = this.getPhoto(size, imageId);\n\n      this.handleAdvancedEdit(photo.root_image_id, sizeKey);\n    }\n  },\n  allowZeroQuantity() {\n    return true;\n  },\n\n  handleKeyPress(event) {\n    if (event.keyCode === 9) {\n      document.body.classList.remove('disable-focus-styles');\n    }\n  },\n});\n\nPrintsBuilder.propTypes = {\n  urls: PrintsBuilderUrlsShape.isRequired,\n  features: PropTypes.object,\n  uploadFromGalleryListenerUrl: PropTypes.string,\n};\n\nexport default PrintsBuilder;\n","// Import Libraries\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport Select from '../../_utils/select-wrapper';\nimport { DeliveryOption, PrintFinish } from '../prop-types';\nimport {\n  calculateSelectedFinish,\n  availableFinishKeys,\n  availableFinishOptions,\n  finishValue,\n} from '../common/finish-and-delivery-options';\n\nconst handleFinishChange = (\n  deliveryOption,\n  value,\n  finishesByDeliveryOption,\n  onChange\n) => {\n  onChange({\n    finish: calculateSelectedFinish(\n      deliveryOption.key,\n      value,\n      finishesByDeliveryOption\n    ),\n  });\n};\n\nconst FinishSelector = ({\n  deliveryOption,\n  finishesByDeliveryOption,\n  finishes,\n  finish,\n  onChange,\n}) => {\n  const finishKeys = availableFinishKeys(\n    finishesByDeliveryOption,\n    deliveryOption\n  );\n\n  return (\n    <Select\n      label=\"Paper Quality\"\n      aria-label=\"Select Finish\"\n      value={finishValue(finish, finishKeys)}\n      options={availableFinishOptions(finishes, finishKeys)}\n      inputStyleLink\n      withCaret\n      onChange={value =>\n        handleFinishChange(\n          deliveryOption,\n          value,\n          finishesByDeliveryOption,\n          onChange\n        )\n      }\n    />\n  );\n};\n\nFinishSelector.propTypes = {\n  deliveryOption: DeliveryOption,\n  finishesByDeliveryOption: PropTypes.objectOf(PropTypes.arrayOf(PrintFinish)),\n  finishes: PropTypes.arrayOf(PrintFinish),\n  finish: PrintFinish,\n  onChange: PropTypes.func,\n}.isRequired;\n\nexport default FinishSelector;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Select from '../../_utils/select-wrapper';\nimport { DeliveryOption, PrintFinish } from '../prop-types';\nimport {\n  selectedDeliveryOption,\n  availableDeliveryOptionsForFinish,\n} from '../common/finish-and-delivery-options';\n\nconst handleDeliveryChange = (\n  value,\n  deliveryOptions,\n  onChange\n) => {\n  onChange({\n    delivery_option: selectedDeliveryOption(deliveryOptions, value)\n  });\n};\n\nconst DeliverySelector = ({\n  deliveryOptions,\n  deliveryOption,\n  finishesByDeliveryOption,\n  finish,\n  onChange,\n}) => (\n  <Select\n    label=\"Delivery Method\"\n    aria-label=\"Select Delivery\"\n    value={deliveryOption.key}\n    options={availableDeliveryOptionsForFinish(\n      deliveryOptions,\n      finishesByDeliveryOption,\n      finish,\n      true\n    )}\n    inputStyleLink\n    withCaret\n    onChange={value =>\n      handleDeliveryChange(\n        value,\n        deliveryOptions,\n        onChange\n      )\n    }\n  />\n);\n\nDeliverySelector.propTypes = {\n  deliveryOptions: PropTypes.arrayOf(DeliveryOption),\n  deliveryOption: DeliveryOption,\n  finishesByDeliveryOption: PropTypes.arrayOf(PrintFinish),\n  finish: PrintFinish,\n  onChange: PropTypes.func,\n}.isRequired;\n\nexport default DeliverySelector;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Currency from '../../_utils/tools/currency';\nimport Select from '../../_utils/select-wrapper';\nimport { PrintSize, DeliveryOption } from '../prop-types';\nimport Utils from '../common/size-helpers';\nimport { QuantityHelpers } from '../common/quantity-helpers';\n\nclass PhotosFilter extends React.Component {\n  get sizes() {\n    const { sizes } = this.props;\n    return [\n      {\n        label: 'All sizes',\n        value: Utils.ALL_PHOTOS_KEY,\n        disabled: false,\n      },\n      ...sizes.map(size => ({\n        label: this.generateSizeLabel(size),\n        value: size.key,\n        disabled: false,\n      })),\n    ];\n  }\n\n  get resizes() {\n    const { viewingSizeKey, availableSizes } = this.props;\n    return [\n      {\n        label: 'Resize by filtered',\n        value: Utils.ALL_PHOTOS_KEY,\n        disabled: false,\n      },\n      ...availableSizes\n        .filter(({ key }) => key !== viewingSizeKey)\n        .map(size => ({\n          label: this.generateSizeLabel(size),\n          value: size.key,\n          disabled: false,\n        })),\n    ];\n  }\n\n  handleChange = (value, func) => {\n    let selectedValue = value;\n\n    if (selectedValue === 'undefined') {\n      selectedValue = undefined;\n    }\n    func(selectedValue);\n  };\n\n  generateSizeLabel(size) {\n    const { deliveryOption } = this.props;\n    const price = QuantityHelpers.priceAtQuantityForSize(\n      size,\n      deliveryOption,\n      true\n    );\n    return `${size.title} (${Currency.format(price)} ea)`;\n  }\n\n  render() {\n    const { viewingSizeKey, onChange, onResize } = this.props;\n    return (\n      <div className=\"d-flex justify-content-between h-100\">\n        <div className=\"filter-option filter\">\n          <Select\n            label=\"Filter\"\n            options={this.sizes}\n            value={viewingSizeKey || Utils.ALL_PHOTOS_KEY}\n            inputStyleLink\n            withCaret\n            onChange={value => this.handleChange(value, onChange)}\n          />\n        </div>\n\n        <div className=\"filter-option resize\">\n          <Select\n            label=\"Resize\"\n            options={this.resizes}\n            value=\"\"\n            inputStyleLink\n            onChange={value => this.handleChange(value, onResize)}\n          />\n        </div>\n      </div>\n    );\n  }\n}\n\nPhotosFilter.propTypes = {\n  sizes: PropTypes.arrayOf(PrintSize).isRequired,\n  availableSizes: PropTypes.arrayOf(PrintSize).isRequired,\n  deliveryOption: DeliveryOption.isRequired,\n  viewingSizeKey: PropTypes.string,\n  onChange: PropTypes.func.isRequired,\n  onResize: PropTypes.func.isRequired,\n};\n\nPhotosFilter.defaultProps = {\n  viewingSizeKey: undefined,\n};\n\nexport default PhotosFilter;\n","// Import Libraries\nimport React from 'react';\n// Import JS Modules\nimport Spinner from '../../../../_utils/spinner';\n\nconst PendingPhoto = () => (\n  <div className=\"photo pending\">\n    <Spinner />\n  </div>\n);\n\nexport default PendingPhoto;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { PrintSize } from '../../../prop-types';\nimport { WebUI, builderDispatch } from '../../../../_utils/ui';\nimport fireTrackingEvent from '../../../common/events/fire-tracking-event';\nimport { UpdatePhotoEvents } from '../../../common/events/event-declarations';\n\nconst handleEdit = (photo, onAdvancedEdit) => {\n  const {\n    size: { key },\n    image_id: imageId,\n  } = photo;\n  fireTrackingEvent(WebUI.PHOTO_EVENT_ADVANCED_EDIT);\n  onAdvancedEdit(key, imageId);\n};\n\nconst handleRemove = photo => {\n  const {\n    size: { key },\n    image_id: imageId,\n  } = photo;\n\n  builderDispatch.dispatch({\n    type: UpdatePhotoEvents.REMOVE,\n    sizeKey: key,\n    imageId,\n  });\n};\n\nconst handleRemoveByRootId = rootImageId => {\n  builderDispatch.dispatch({\n    type: UpdatePhotoEvents.SHOW_REMOVE_CONFIRMATION,\n    imageId: rootImageId,\n    useRoot: true,\n  });\n};\n\nexport default function EditablePhotoButtons({\n  photo,\n  isLastPhoto,\n  onAdvancedEdit,\n}) {\n  return (\n    <div className=\"photo-editable__buttons d-flex justify-content-between\">\n      <button\n        aria-label={`Edit ${photo.filename} ${photo.size.title}`}\n        className=\"btn btn-link btn-underline pl-0\"\n        title={`Edit ${photo.filename} ${photo.size.title}`}\n        role=\"link\"\n        type=\"button\"\n        onClick={() => handleEdit(photo, onAdvancedEdit)}>\n        Edit\n      </button>\n      <button\n        aria-label={`Remove ${photo.filename} ${photo.size.title}`}\n        className=\"btn btn-link btn-underline pr-0\"\n        title={`Remove ${photo.filename} ${photo.size.title}`}\n        role=\"link\"\n        type=\"button\"\n        onClick={() =>\n          isLastPhoto\n            ? handleRemoveByRootId(photo.root_image_id)\n            : handleRemove(photo)\n        }>\n        Remove\n      </button>\n    </div>\n  );\n}\n\nEditablePhotoButtons.propTypes = {\n  photo: PrintSize,\n  isLastPhoto: PropTypes.bool,\n  onAdvancedEdit: PropTypes.func,\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { PrintSize } from '../../../prop-types';\nimport PandaViewSimplePreviews from '../../../common/panda-view-simple-previews';\nimport EditablePhotoButtons from './editable-photo-buttons';\n\nconst EditablePhoto = props => {\n  const { photo, isLastPhoto, onAdvancedEdit, recommendedPrintSize } = props;\n\n  return (\n    <div className=\"d-flex\">\n      <div className=\"editable-photo-wrapper flex-shrink-0\">\n        <PandaViewSimplePreviews\n          {...photo}\n          isWallet={photo.size.title === 'Wallet'}\n          size_area={photo.size.area}\n          recommendedPrintSize={recommendedPrintSize}\n          showSize={false}\n          showQuantity={false}\n          showLowQualityWarning\n          lowQualityInformationPosition=\"bottom\"\n          lowQualityInformationCSSClasses=\"mobile\"\n        />\n        <EditablePhotoButtons\n          photo={photo}\n          isLastPhoto={isLastPhoto}\n          onAdvancedEdit={onAdvancedEdit}\n        />\n      </div>\n    </div>\n  );\n};\n\nEditablePhoto.propTypes = {\n  photo: PrintSize,\n  isLastPhoto: PropTypes.bool,\n  availableSizes: PropTypes.arrayOf(PrintSize),\n  sizesWithRootImage: PropTypes.arrayOf(PrintSize),\n  onAdvancedEdit: PropTypes.func,\n}.isRequired;\n\nexport default EditablePhoto;\n","// Import JS Libraries\nimport React from 'react';\n// Import JS Modules\nimport PendingPhoto from './photo/pending-photo';\nimport EditablePhoto from './photo/editable-photo';\n\nconst Photo = (\n  photo,\n  isLastPhoto,\n  sizesWithRootImage,\n  availableSizes,\n  onAdvancedEditPhoto,\n  recommendedPrintSize,\n  photoComponent = EditablePhoto,\n  isSelected,\n  layoutProps = {}\n) => {\n  const photoIsEditable = 'raw_url' in photo;\n\n  if (!photoIsEditable) {\n    return <PendingPhoto />;\n  }\n\n  return React.createElement(photoComponent, {\n    photo,\n    isLastPhoto,\n    sizesWithRootImage,\n    availableSizes,\n    onAdvancedEdit: onAdvancedEditPhoto,\n    recommendedPrintSize: recommendedPrintSize,\n    isSelected,\n    layoutProps,\n  });\n};\n\nexport default Photo;\n","import { useState } from 'react';\n\nconst DEFAULT_PAGE_SIZE = 10;\n\nexport function usePagination({ items, itemsPerPage = DEFAULT_PAGE_SIZE }) {\n  const [page, setPage] = useState(1);\n  const paginate = (items) => {\n    return items.slice((page - 1) * itemsPerPage, page * itemsPerPage);\n  }\n\n  const handleGoToPage = (page) => {\n    setPage(page);\n  }\n\n  const handlePageNext = () => {\n    setPage(prevPage => prevPage + 1);\n  }\n\n  const handlePagePrevious = () => {\n    setPage(prevPage => prevPage > 1 ? prevPage - 1 : prevPage);\n  }\n\n  const totalPageCount = Math.ceil(items.length / itemsPerPage);\n\n  return {\n    page,\n    handleGoToPage,\n    handlePageNext,\n    handlePagePrevious,\n    totalPageCount,\n    paginatedItems: paginate(items)\n  };\n}\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nexport default function PrintCountDisplay({\n  selectedCount,\n  totalCount,\n  text,\n  classNames,\n  hideTotal,\n}) {\n  return (\n    <span data-test-id=\"print-count-display\" className={classNames}>\n      {selectedCount}\n      <span className={(hideTotal && 'd-none') || ''}>{`/${totalCount}`}</span>\n      {text && ` ${text}`}\n    </span>\n  );\n}\n\nPrintCountDisplay.propTypes = {\n  selectedCount: PropTypes.number.isRequired,\n  totalCount: PropTypes.number.isRequired,\n  text: PropTypes.string,\n  hideTotal: PropTypes.bool,\n  classNames: PropTypes.string,\n};\n\nPrintCountDisplay.defaultProps = {\n  text: '',\n  classNames: '',\n  hideTotal: false,\n};\n","import React, { useState, useCallback } from 'react';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport Button from '../../../_common/button';\n\nexport function QuantityInput({\n  className,\n  value,\n  onQuantityChange,\n  min,\n  max,\n  id,\n  hideLabel,\n}) {\n  const inputId = `${id}-input`;\n  const [internalValue, setInternalValue] = useState(value);\n  const handleInputChange = e => {\n    setInternalValue(\n      Number.isNaN(e.target.valueAsNumber) ? '' : e.target.valueAsNumber\n    );\n  };\n  const handleQuantityUpdate = useCallback(\n    quantityValue => {\n      const quantityNumber = Number(quantityValue);\n      const numberValid =\n        !Number.isNaN(quantityNumber) &&\n        quantityNumber >= min &&\n        quantityNumber <= max;\n\n      if (numberValid) {\n        setInternalValue(quantityNumber);\n        onQuantityChange(quantityNumber);\n      } else {\n        setInternalValue(value); // reset when not valid\n      }\n    },\n    [onQuantityChange, min, max, value]\n  );\n  const handleKeyDown = event => {\n    if (event.keyCode === 27) {\n      // reset on Escape key, unfocus rather than blur() so we dont trigger onBlur\n      document.body.focus();\n      setInternalValue(value);\n    } else if (event.key === 'Enter') {\n      event.target.blur(); // accept the current value on Enter key\n    }\n  };\n\n  return (\n    <div\n      id={id}\n      className={classNames('input-group quantity-input-group', className)}>\n      <div className=\"input-group-prepend\">\n        <Button\n          className=\"btn-secondary btn-minus\"\n          aria-label=\"Decrease quantity of prints by 1\"\n          disabled={value - 1 < min}\n          onClick={() => handleQuantityUpdate(value - 1)}\n          text=\"Less\"\n          icon=\"fa-minus fa-fw\"\n          hideLabel\n        />\n      </div>\n      <input\n        type=\"number\"\n        className=\"form-control\"\n        id={inputId}\n        min={min}\n        max={max}\n        step=\"1\"\n        value={internalValue}\n        onChange={handleInputChange}\n        onBlur={() => handleQuantityUpdate(internalValue)}\n        onKeyDown={handleKeyDown}\n      />\n      <div className=\"input-group-append\">\n        <Button\n          className=\"btn-secondary btn-plus\"\n          aria-label=\"Increase quantity of prints by 1\"\n          disabled={value + 1 > max}\n          onClick={() => handleQuantityUpdate(value + 1)}\n          text=\"More\"\n          icon=\"fa-plus fa-fw\"\n          hideLabel\n        />\n      </div>\n      <label\n        htmlFor={inputId}\n        className={classNames('w-100 text-center mb-0', {\n          'sr-only': hideLabel,\n        })}>\n        Quantity\n      </label>\n    </div>\n  );\n}\n\nQuantityInput.propTypes = {\n  className: PropTypes.string,\n  value: PropTypes.number.isRequired,\n  onQuantityChange: PropTypes.func.isRequired,\n  min: PropTypes.number,\n  max: PropTypes.number,\n  id: PropTypes.string,\n};\n\nQuantityInput.defaultProps = {\n  min: 1,\n  max: 999,\n  id: 'prints-builder-photo-quantity',\n  hideLabel: false,\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { UploadedPhoto } from '../../prop-types';\nimport { QuantityInput } from '../glass/quantity-input';\nimport Button from '../../../_common/button';\nimport { builderDispatch } from '../../../_utils/ui';\nimport { UpdatePhotoEvents } from '../../common/events/event-declarations';\n\nexport default function SideMenu({ photo, handleResizeOptionsModal }) {\n  const update = (value, photo, key) => {\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.UPDATE,\n      photo: {\n        ...photo,\n        [key]: value,\n      },\n      hard: true,\n    });\n  };\n\n  const handleQuantityChange = (e, photo) => {\n    const value = parseInt(e.target.value, 10);\n    return update(value, photo, 'quantity');\n  };\n\n  const { quantity, image_id: imageId, size } = photo;\n\n  return (\n    <>\n      <QuantityInput\n        key={`${imageId}-${quantity}`}\n        value={quantity}\n        onQuantityChange={value =>\n          handleQuantityChange({ target: { value } }, photo)\n        }\n        hideLabel\n      />\n      <Button\n        className=\"list-view-mobile__resize-btn\"\n        onClick={handleResizeOptionsModal}>\n        Change Size\n        <p className=\"list-view-mobile__change-size-text\">{size.title}</p>\n      </Button>\n    </>\n  );\n}\n\nSideMenu.propTypes = {\n  photo: UploadedPhoto.isRequired,\n  handleResizeOptionsModal: PropTypes.func.isRequired,\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { PrintSize } from '../prop-types';\nimport PhotoDpiNotice from '../common/photo-quality/photo-dpi-notice';\nimport Currency from '../../_utils/tools/currency';\nimport RecommendedPrintSizeBadge from '../common/photo-quality/recommended-print-size-badge';\n\nexport function renderSizeButton({\n  title,\n  price,\n  area,\n  key,\n  sizesWithPrints,\n  photoDimensions,\n  showLowQualityWarning,\n  hideTooltip,\n  crop,\n  onClick,\n  recommendedPrintSize,\n}) {\n  const isDisabled = !!(sizesWithPrints || []).find(size => size.key === key);\n  const isRecommended =\n    recommendedPrintSize && recommendedPrintSize.key === key;\n\n  return (\n    <button\n      type=\"button\"\n      key={key}\n      className=\"btn btn-link btn-block size-options__size\"\n      disabled={isDisabled}\n      onClick={() => onClick(key)}>\n      {showLowQualityWarning && (\n        <PhotoDpiNotice\n          size_area={area}\n          raw_dimensions={photoDimensions}\n          crop={crop}\n          noText\n          hideTooltip={hideTooltip}\n        />\n      )}\n      <strong>{title}</strong> ({Currency.format(price)})\n      {isDisabled && ' - Already added'}\n      {isRecommended && <RecommendedPrintSizeBadge className=\"ml-2\" />}\n    </button>\n  );\n}\n\nrenderSizeButton.propTypes = {\n  availableSizes: PropTypes.arrayOf(PrintSize),\n  showLowQualityWarning: PropTypes.bool,\n  onAddSize: PropTypes.func,\n}.isRequired;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { PrintSize } from '../prop-types';\nimport { renderSizeButton } from './render-size-button';\n\nexport default function ResizeOptionsModal({\n  viewingSizeKey,\n  availableSizes,\n  showResizeOptionsModal,\n  handleResizeOptionsModal,\n  onClick,\n  title,\n  recommendedPrintSize,\n  showLowQualityWarning,\n  hideTooltip,\n  photoDimensions,\n  sizesWithPrints,\n}) {\n  const printSizeList = [...availableSizes]\n    .filter(({ key }) => key !== viewingSizeKey)\n    .sort(\n      (a, b) =>\n        (recommendedPrintSize && b.key === recommendedPrintSize.key) -\n        (recommendedPrintSize && a.key === recommendedPrintSize.key)\n    );\n\n  return (\n    <div\n      role=\"dialog\"\n      className={`modal ${showResizeOptionsModal ? 'd-block show' : 'd-none'}`}>\n      <div className=\"modal-dialog modal-sm size-options__modal\">\n        <div className=\"modal-content\">\n          <div className=\"modal-heading text-center\">\n            <h4 className=\"modal-title mb-3\">{title}</h4>\n            <button\n              type=\"button\"\n              className=\"close\"\n              data-dismiss=\"modal\"\n              aria-label=\"Close\"\n              onClick={handleResizeOptionsModal}\n            />\n          </div>\n          <div className=\"modal-body\">\n            {printSizeList.map(size =>\n              renderSizeButton({\n                ...size,\n                onClick,\n                recommendedPrintSize,\n                showLowQualityWarning,\n                hideTooltip,\n                photoDimensions,\n                sizesWithPrints,\n              })\n            )}\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n\nResizeOptionsModal.propTypes = {\n  availableSizes: PropTypes.arrayOf(PrintSize).isRequired,\n  viewingSizeKey: PropTypes.string,\n  showResizeOptionsModal: PropTypes.bool.isRequired,\n  handleResizeOptionsModal: PropTypes.func.isRequired,\n  onClick: PropTypes.func.isRequired,\n  title: PropTypes.string.isRequired,\n};\n\nResizeOptionsModal.defaultProps = {\n  viewingSizeKey: undefined,\n};\n","import React from 'react';\n\nexport default function Footer({ children }) {\n  return (\n    <footer className=\"prints-builder__footer d-flex align-items-center flex-column\">\n      {children}\n    </footer>\n  );\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { DeliveryOption, PrintSize } from '../../prop-types';\nimport PropTypes from 'prop-types';\nimport classNames from 'classnames';\nimport { allPhotosCollectedByRootImage } from '../../common/collect-by-root-image';\nimport {\n  sizesWithPrice,\n  sizesWithRootImage,\n  totalQuantity,\n} from '../../common/totalizing-mixin';\nimport Photo from '../photos-grid/photo';\nimport PhotoFilename from '../../common/photo-filename';\nimport findRecommendedPrintSize from '../../common/photo-quality/recommended-print-size';\nimport Paginator from '../../../_utils/paginator';\nimport { usePagination } from '../../../_utils/paginator/use-pagination';\nimport pluralize from '../../../_utils/tools/pluralize';\nimport PrintCountDisplay from '../print-count-display';\nimport Button from '../../../_common/button';\nimport SideMenu from './side-menu';\nimport ResizeOptionsModal from '../resize-options-modal';\nimport Footer from '../footer';\nimport { builderDispatch } from '../../../_utils/ui';\nimport { UpdatePhotoEvents } from '../../common/events/event-declarations';\n\nconst modalType = {\n  NONE: undefined,\n  CHANGE_SIZE: 'change_size',\n  ADD_SIZE: 'add_size',\n};\n\nexport default function PhotosGrid({\n  sizes,\n  availableSizes,\n  viewingSizeKey,\n  onAdvancedEditPhoto,\n  deliveryOption,\n  orderedPhotos,\n  invalidDeliveryOptionSelected,\n  handleAddPhotos,\n}) {\n  const PHOTOS_PER_PAGE = 25;\n  const recommendedPrintSizes = findAllRecommendedPrintSizes();\n  const totalPhotosLength = totalQuantity(orderedPhotos);\n  const {\n    page,\n    paginatedItems,\n    totalPageCount,\n    handlePageNext,\n    handlePagePrevious,\n    handleGoToPage,\n  } = usePagination({\n    items: orderedPhotos,\n    itemsPerPage: PHOTOS_PER_PAGE,\n  });\n  const defaultSelectedPhoto = {\n    raw_dimensions: { w: 1000, h: 1000 },\n    root_image_id: undefined,\n  };\n  const selectedPhotoRef = useRef(defaultSelectedPhoto);\n  const [selectedModal, setSelectedModal] = useState(modalType.NONE);\n  const selectedPhoto = selectedPhotoRef.current;\n\n  useEffect(() => {\n    handleGoToPage(1);\n  }, [viewingSizeKey]); // reset page if size filter changes\n\n  function findAllRecommendedPrintSizes() {\n    const photosCollection = allPhotosCollectedByRootImage(sizes);\n\n    return Object.entries(photosCollection).reduce(\n      (acc, [id, photoSizes = {}]) => {\n        const photo = (Object.values(photoSizes)[0] || [])[0];\n        acc[id] = findRecommendedPrintSize(availableSizes, photo);\n        return acc;\n      },\n      {}\n    );\n  }\n\n  function addSize(targetSizeKey) {\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.ADD_TO_SIZE,\n      root_image_id: selectedPhoto.root_image_id,\n      targetSizeKey,\n      quantity: 1,\n    });\n  }\n\n  function handleCloseModal() {\n    selectedPhotoRef.current = defaultSelectedPhoto;\n    setSelectedModal(modalType.NONE);\n  }\n\n  const handleSizeChange = targetSizeKey => {\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.RESIZE,\n      image_id: selectedPhoto.image_id,\n      size_key: selectedPhoto.size.key,\n      targetSizeKey,\n    });\n  };\n\n  const modalOptions = {\n    [modalType.CHANGE_SIZE]: {\n      title: 'Change Size',\n      onClick: targetSizeKey => handleSizeChange(targetSizeKey),\n    },\n    [modalType.ADD_SIZE]: {\n      title: 'Add Size',\n      onClick: targetSizeKey => addSize(targetSizeKey),\n    },\n  };\n\n  return (\n    <>\n      <div className=\"list-view list-view-mobile\">\n        {paginatedItems.map(({ id, photos = [], isLastPhoto }) => (\n          <section\n            key={`photo_${id}`}\n            className={classNames('d-flex flex-column list-item', {\n              last: isLastPhoto,\n            })}>\n            <PhotoFilename photo={photos[0]} />\n            <Button\n              className=\"btn btn-sm btn-link list-view-mobile__add-size add-size\"\n              type=\"button\"\n              text=\"Add Size\"\n              onClick={() => {\n                selectedPhotoRef.current = photos[0];\n                setSelectedModal(modalType.ADD_SIZE);\n              }}\n            />\n            {photos.map((photo, index) => (\n              <div\n                key={`${id}_${photo.size.size_id}`}\n                className=\"list-item__size row\">\n                <div className=\"col-6 list-item__size__photo\">\n                  {Photo(\n                    photo,\n                    isLastPhoto,\n                    sizesWithRootImage(sizes, id),\n                    availableSizes,\n                    onAdvancedEditPhoto,\n                    recommendedPrintSizes[id]\n                  )}\n                </div>\n                <div className=\"col-6 list-item__size__side-menu\">\n                  <SideMenu\n                    photo={photo}\n                    handleResizeOptionsModal={() => {\n                      selectedPhotoRef.current = photo;\n                      setSelectedModal(modalType.CHANGE_SIZE);\n                    }}\n                  />\n                </div>\n              </div>\n            ))}\n          </section>\n        ))}\n        {selectedModal && (\n          <ResizeOptionsModal\n            title={modalOptions[selectedModal].title}\n            availableSizes={sizesWithPrice(\n              availableSizes,\n              sizes,\n              deliveryOption\n            )}\n            sizesWithPrints={sizesWithRootImage(\n              sizes,\n              selectedPhoto.root_image_id\n            )}\n            onClick={targetSizeKey => {\n              modalOptions[selectedModal].onClick(targetSizeKey);\n              handleCloseModal();\n            }}\n            showResizeOptionsModal={!!selectedModal}\n            deliveryOption={deliveryOption}\n            handleResizeOptionsModal={handleCloseModal}\n            photoDimensions={selectedPhoto.raw_dimensions}\n            recommendedPrintSize={\n              recommendedPrintSizes[selectedPhoto.root_image_id]\n            }\n            showLowQualityWarning\n            hideTooltip\n          />\n        )}\n        <Footer>\n          <Paginator\n            title=\"Uploaded photos pages\"\n            page={page}\n            totalPageCount={totalPageCount}\n            scrollTarget={-200}\n            onPageNext={handlePageNext}\n            onPagePrevious={handlePagePrevious}\n            onGoToPage={handleGoToPage}\n          />\n          <div className=\"w-100 d-flex align-items-center justify-content-between\">\n            <PrintCountDisplay\n              hideTotal\n              selectedCount={totalPhotosLength}\n              totalCount={totalPhotosLength}\n              text={pluralize('photo', totalPhotosLength)}\n            />\n            <Button\n              className=\"btn btn-link btn-underline\"\n              onClick={handleAddPhotos}\n              disabled={invalidDeliveryOptionSelected}>\n              + Add more photos\n            </Button>\n          </div>\n        </Footer>\n      </div>\n    </>\n  );\n}\n\nPhotosGrid.propTypes = {\n  deliveryOption: DeliveryOption,\n  availableSizes: PropTypes.arrayOf(PrintSize),\n  sizes: PropTypes.arrayOf(PrintSize),\n}.isRequired;\n","import { allPhotosCollectedByRootImage } from './collect-by-root-image';\nimport SizeHelpers from './size-helpers';\n\nfunction photosById({ photoIds, sizes, id }) {\n  if (Object.keys(photoIds).length) {\n    return photoIds[id];\n  }\n  const photos = allPhotosCollectedByRootImage(sizes);\n\n  Object.entries(photos).forEach(([id, size]) => {\n    photoIds[id] = Object.entries(size).map(([, [photo]]) => photo.id);\n  });\n\n  return photoIds[id];\n}\n\nfunction getSizesByFinish({ sizes, finish }) {\n  return sizes.filter(size => {\n    return size.key.includes(finish.name) ? [size.key] : [];\n  });\n}\n\nfunction sortedAndFilteredImages({ viewingSizeKey, sizes, finish, photoIds }) {\n  const photosCollection = allPhotosCollectedByRootImage(\n    getSizesByFinish({ sizes, finish })\n      .filter(SizeHelpers.sizeHasPrints)\n      .map(SizeHelpers.stripZeroQuantityPhotosFromSize)\n  );\n\n  return Object.entries(photosCollection)\n    .map(([id, photoSizes = {}]) => {\n      let photos = Object.entries(photoSizes).map(\n        ([, [photoArray]]) => photoArray\n      );\n      const isLastPhoto = photos.length === 1;\n\n      function filterBySize(photo) {\n        return photo.size.key === viewingSizeKey;\n      }\n\n      if (viewingSizeKey) {\n        photos = photos.filter(filterBySize);\n      }\n\n      photos = photos.sort((a, b) => {\n        const idArray = photosById({ photoIds, sizes, id }) || [];\n\n        const aIndex = idArray.indexOf(a.id);\n        if (aIndex < 0) {\n          return 1;\n        }\n\n        const bIndex = idArray.indexOf(b.id);\n        if (bIndex < 0) {\n          return -1;\n        }\n\n        // Sort in order of ID Array\n        return aIndex < bIndex ? -1 : 1;\n      });\n\n      return {\n        id,\n        photos,\n        isLastPhoto,\n      };\n    })\n    .filter(({ photos }) => photos.length);\n}\n\nexport { sortedAndFilteredImages };\n","import createReactClass from 'create-react-class';\n// Import Libraries\nimport React from 'react';\nimport PropTypes from 'prop-types';\n// Import JS Modules\nimport AddPhotosDevice from '../common/add-photos-device';\nimport genericHelpers from '../../_utils/generic-helpers';\nimport startSessionTimeout from '../../_utils/tools/session-timeout';\nimport FinishSelector from './finish-selector';\nimport DeliverySelector from './delivery-selector';\nimport PhotosFilter from './photos-filter';\nimport PhotosGrid from './photos-grid';\nimport PhotoRemoveConfirmation from '../common/photo-remove-confirmation';\nimport PrintsBuilderMixin from '../common/prints-builder-mixin';\nimport SiteLogo from '../../_application/site-logo';\nimport SizeHelpers from '../common/size-helpers';\nimport Totaliser from '../common/totalizer';\nimport AddToCartControls from '../common/add-to-cart-controls';\nimport InvalidSizesModal from '../common/invalid-sizes-modal';\nimport InvalidDeliveryOptionModal from '../common/invalid-delivery-option-modal';\nimport UploadPhotosMixin from '../common/upload-photos-mixin';\nimport UploadProgressBar from '../common/upload-progress-bar';\nimport FullScreenSpinner from '../../_prism-builder/desktop/notices/full-screen-spinner';\nimport AdvancedEditor from '../common/advanced-editor';\nimport PrintFinishTabs from '../common/print_finish_tabs';\nimport { PrintsBuilderUrlsShape } from '../prop-types';\nimport { sortedAndFilteredImages } from '../common/images-helper';\nimport Button from '../../_common/button';\nimport { totalQuantity } from '../common/totalizing-mixin';\nimport Footer from './footer';\nimport { allPhotosCollectedByRootImage } from '../common/collect-by-root-image';\nimport BulkQuantityChange from '../common/bulk-quantity-change';\n\n// -----------------------------------------------------------\n//  Controller\n// -----------------------------------------------------------\nconst MobilePrintsBuilder = createReactClass({\n  mixins: [PrintsBuilderMixin, UploadPhotosMixin],\n  displayName: 'Mobile prints builder',\n  _photoIDs: {},\n  getInitialState() {\n    return {\n      finish: {},\n      delivery_option: {},\n      sizes: [],\n    };\n  },\n  UNSAFE_componentWillMount() {\n    this.loadData();\n\n    // loader callbacks\n    this.loadCallbacks();\n\n    this._forceUpdate = genericHelpers.debounce(() => this.forceUpdate());\n  },\n  componentDidMount() {\n    this.handleViewportResize();\n    window.addEventListener('resize', this.handleViewportResize);\n    this.handleSessionTimeout();\n  },\n  componentWillUnmount() {\n    window.removeEventListener('resize', this.handleViewportResize);\n    this.unloadCallbacks();\n  },\n  render() {\n    const {\n      delivery_option: deliveryOption,\n      viewingSizeKey,\n      currentlyLoading,\n      finish,\n      ready,\n      invalidDeliveryOptionSelected,\n    } = this.state;\n    const {\n      features: { allowMultiplePrintFinishesPerOrder },\n      urls,\n    } = this.props;\n    const availableSizes = this.availableSizesForSelectedDeliveryAndFinish();\n    const sizes = this.state.sizes\n      .filter(SizeHelpers.sizeHasPrints)\n      .map(SizeHelpers.stripZeroQuantityPhotosFromSize);\n    const sizesByFinish = this.getSizesByFinish().filter(\n      SizeHelpers.sizeHasPrints\n    );\n\n    // Keeps a record of the original order of prints\n    const photos = allPhotosCollectedByRootImage(sizes);\n    Object.entries(photos).forEach(([id, size]) => {\n      this._photoIDs[id] = Object.entries(size).map(([, [photo]]) => photo.id);\n    });\n\n    const orderedPhotos = sortedAndFilteredImages({\n      sizes,\n      photoIds: this._photoIDs,\n      viewingSizeKey,\n      finish,\n    });\n    const orderedPhotosLength = totalQuantity(orderedPhotos);\n    const deliveryOptions = [...this.data.delivery_options];\n    const finishes = [...this.data.finishes];\n    const finishesByDeliveryOption = Object.assign(\n      {},\n      this.availableFinishesByDeliveryOption\n    );\n\n    return (\n      <div className=\"prints-builder__grid m-web\">\n        <header className=\"prints-builder__header d-flex align-items-center\">\n          <div className=\"flex-grow-1\">\n            <SiteLogo />\n          </div>\n          <Totaliser sizes={sizes} deliveryOption={deliveryOption} />\n        </header>\n        <aside className=\"print-order__summary-and-filter\">\n          {allowMultiplePrintFinishesPerOrder && (\n            <PrintFinishTabs finishes={finishes} selectedFinish={finish} />\n          )}\n          <div className=\"grey-zone print-order__summary-container\">\n            <div className=\"d-flex align-items-center\">\n              <div className=\"flex-grow-1\">\n                <button\n                  className=\"btn btn-link p-0 border-0 collapsed print-order__title\"\n                  type=\"button\"\n                  data-toggle=\"collapse\"\n                  data-target=\"#summary-chart\"\n                  aria-expanded=\"true\"\n                  aria-controls=\"summary-chart\"\n                  aria-label=\"Your Print Order\">\n                  <span>Print order</span>\n                </button>\n              </div>\n              <div>\n                <AddToCartControls\n                  enabled={this.hasPrints() && !currentlyLoading}\n                  basketUrl={urls.cart_page}\n                  onAddToCart={this.handleAddToCart}\n                />\n              </div>\n            </div>\n\n            <div id=\"summary-chart\" className=\"collapse show\">\n              <hr />\n              <div className=\"print-order__summary\">\n                {!allowMultiplePrintFinishesPerOrder && (\n                  <FinishSelector\n                    deliveryOption={deliveryOption}\n                    finishesByDeliveryOption={finishesByDeliveryOption}\n                    finishes={finishes}\n                    finish={finish}\n                    onChange={this.handleOptionsChanged}\n                  />\n                )}\n                <DeliverySelector\n                  deliveryOptions={deliveryOptions}\n                  deliveryOption={deliveryOption}\n                  finishesByDeliveryOption={finishesByDeliveryOption}\n                  finish={finish}\n                  onChange={this.handleOptionsChanged}\n                />\n                <BulkQuantityChange\n                  sizes={sizes}\n                  photos={this.allPhotos()}\n                  onChange={this.handleQuantityChanged}\n                  disabled={!this.hasPrints() || !!this.state.currentlyLoading}\n                  availableSizes={availableSizes}\n                  deliveryOption={deliveryOption}\n                />\n              </div>\n            </div>\n          </div>\n          <UploadProgressBar {...currentlyLoading} />\n          <InvalidSizesModal />\n          <InvalidDeliveryOptionModal />\n          {this.hasPrints() && (\n            <div className=\"print-order__filter\">\n              <PhotosFilter\n                sizes={sizesByFinish}\n                availableSizes={availableSizes}\n                deliveryOption={deliveryOption}\n                viewingSizeKey={viewingSizeKey}\n                onChange={this.handleViewingSizeChanged}\n                onResize={this.handleResize}\n              />\n            </div>\n          )}\n        </aside>\n        <main className=\"prints-builder__list\" onScroll={this.handleScroll}>\n          {(!orderedPhotosLength && (\n            <AddPhotosDevice onClick={this.handleAddPhotos} />\n          )) || (\n            <PhotosGrid\n              availableSizes={availableSizes}\n              deliveryOption={deliveryOption}\n              onAdvancedEditPhoto={this.handleAdvancedEdit}\n              sizes={sizesByFinish}\n              viewingSizeKey={viewingSizeKey}\n              orderedPhotos={orderedPhotos}\n              invalidDeliveryOptionSelected={invalidDeliveryOptionSelected}\n              handleAddPhotos={this.handleAddPhotos}\n            />\n          )}\n        </main>\n        {!orderedPhotosLength && (\n          <Footer>\n            <Button\n              className=\"btn btn-link btn-underline\"\n              onClick={this.handleAddPhotos}\n              disabled={invalidDeliveryOptionSelected}>\n              + Add more photos\n            </Button>\n          </Footer>\n        )}\n        <AdvancedEditor\n          ref={ref => (this.advancedEditorRef = ref)}\n          availableSizes={availableSizes}\n        />\n        <PhotoRemoveConfirmation />\n        <FullScreenSpinner show={!ready} />\n      </div>\n    );\n  },\n  addToCartEnabled() {\n    return this.hasPrints() && !this.state.currentlyLoading;\n  },\n\n  handleViewportResize() {\n    const vh = window.innerHeight * 0.01;\n    genericHelpers.debounce(\n      document.documentElement.style.setProperty('--vh', `${vh}px`)\n    );\n  },\n\n  handleAdvancedEdit(sizeKey, imageId) {\n    const size = this.getSizeFromKey(sizeKey);\n    const photo = SizeHelpers.augment.individual(\n      this.getPhoto(size, imageId, true),\n      size\n    );\n\n    this.advanced_edit = {\n      size,\n      photo,\n    };\n\n    this.advancedEditor().setData({\n      photo,\n      availableSizes: this.availableSizesForSelectedDeliveryAndFinish(),\n      sizes: [...this.state.sizes],\n    });\n  },\n\n  refreshEL2(sizeKey, imageId) {\n    if (this.advanced_edit) {\n      this.handleAdvancedEdit(sizeKey, imageId);\n    }\n  },\n\n  handleSessionTimeout() {\n    const { initSessionTimeout } = this.props;\n\n    if (initSessionTimeout) {\n      startSessionTimeout();\n    }\n  },\n\n  handleScroll() {\n    $('#summary-chart').collapse('hide');\n  },\n\n  allowZeroQuantity: () => false,\n});\n\nMobilePrintsBuilder.propTypes = {\n  urls: PrintsBuilderUrlsShape.isRequired,\n  features: PropTypes.object,\n  uploadFromGalleryListenerUrl: PropTypes.string,\n};\n\nexport default MobilePrintsBuilder;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Currency from '../../../_utils/tools/currency';\nimport Select from '../../../_utils/select-wrapper';\nimport { PrintSize, DeliveryOption } from '../../prop-types';\nimport Utils from '../../common/size-helpers';\nimport { QuantityHelpers } from '../../common/quantity-helpers';\n\nclass PrintSizeFilter extends React.Component {\n  get sizes() {\n    const { sizes, generateSizeOptionLabel } = this.props;\n    return [\n      {\n        label: 'All sizes',\n        value: Utils.ALL_PHOTOS_KEY,\n        disabled: false,\n      },\n      ...sizes.map(size => ({\n        label: generateSizeOptionLabel(size, this.props),\n        value: size.key,\n        disabled: false,\n      })),\n    ];\n  }\n\n  get resizes() {\n    const {\n      viewingSizeKey,\n      availableSizes,\n      generateSizeOptionLabel,\n    } = this.props;\n    return [\n      {\n        label: 'Resize by filtered',\n        value: Utils.ALL_PHOTOS_KEY,\n        disabled: false,\n      },\n      ...availableSizes\n        .filter(({ key }) => key !== viewingSizeKey)\n        .map(size => ({\n          label: generateSizeOptionLabel(size, this.props),\n          value: size.key,\n          disabled: false,\n        })),\n    ];\n  }\n\n  handleChange = (value, func) => {\n    let selectedValue = value;\n\n    if (selectedValue === 'undefined') {\n      selectedValue = undefined;\n    }\n    func(selectedValue);\n  };\n\n  render() {\n    const { viewingSizeKey, onChange } = this.props;\n\n    return (\n      <div className=\"d-flex justify-content-between h-100\">\n        <div className=\"filter-option filter mx-auto\">\n          <Select\n            label=\"Filter\"\n            options={this.sizes}\n            value={viewingSizeKey || Utils.ALL_PHOTOS_KEY}\n            inputStyleLink\n            withCaret\n            onChange={value => this.handleChange(value, onChange)}\n          />\n        </div>\n      </div>\n    );\n  }\n}\n\nconst generateSizeOptionLabel = (size, props) => {\n  const { deliveryOption } = props;\n  const price = QuantityHelpers.priceAtQuantityForSize(\n    size,\n    deliveryOption,\n    true\n  );\n  return `${size.title} (${Currency.format(price)} ea)`;\n};\n\nPrintSizeFilter.propTypes = {\n  sizes: PropTypes.arrayOf(PrintSize).isRequired,\n  availableSizes: PropTypes.arrayOf(PrintSize).isRequired,\n  deliveryOption: DeliveryOption.isRequired,\n  viewingSizeKey: PropTypes.string,\n  onChange: PropTypes.func.isRequired,\n  generateSizeOptionLabel: PropTypes.func,\n  hideLabelForAllSizes: PropTypes.bool,\n};\n\nPrintSizeFilter.defaultProps = {\n  viewingSizeKey: undefined,\n  hideLabelForAllSizes: false,\n  generateSizeOptionLabel,\n};\n\nexport default PrintSizeFilter;\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { PrintSize } from '../../../prop-types';\nimport PandaViewSimplePreviews from '../../../common/panda-view-simple-previews';\n\nconst SimpleThumbnail = props => {\n  const { photo, recommendedPrintSize, layoutProps } = props;\n\n  return (\n    <PandaViewSimplePreviews\n      {...photo}\n      isWallet={photo.size.title === 'Wallet'}\n      size_area={photo.size.area}\n      showSize={false}\n      showQuantity={false}\n      recommendedPrintSize={recommendedPrintSize}\n      {...layoutProps}\n    />\n  );\n};\n\nSimpleThumbnail.propTypes = {\n  photo: PrintSize,\n  isLastPhoto: PropTypes.bool,\n  availableSizes: PropTypes.arrayOf(PrintSize),\n  sizesWithRootImage: PropTypes.arrayOf(PrintSize),\n  onAdvancedEdit: PropTypes.func,\n  layoutProps: PropTypes.object,\n  isSelected: PropTypes.bool,\n};\n\nSimpleThumbnail.defaultProps = {\n  layoutProps: {},\n  isSelected: false,\n};\n\nexport default SimpleThumbnail;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '../../../_common/button';\nimport pluralize from '../../../_utils/tools/pluralize';\n\nexport default function MultiSelectModal({\n  handleShowMultiSelectModal,\n  multiSelectItemsCount,\n  maximumSelected,\n  showMultiSelectModal,\n  handleMultiSelectAll,\n  handleMultiUnSelectAll,\n  handleMultiDelete,\n  handleMultiResize,\n}) {\n  const bulkSelectText = (maximumSelected && 'Unselect All') || 'Select All';\n\n  function handleBulkSelect() {\n    if (maximumSelected) {\n      handleMultiUnSelectAll();\n    } else {\n      handleMultiSelectAll();\n    }\n  }\n\n  return (\n    <div\n      role=\"dialog\"\n      className={`multi-select-modal w-100 ${\n        showMultiSelectModal ? 'd-block' : 'd-none'\n      }`}>\n      <div className=\"multi-select-modal__button-wrapper row\">\n        <div className=\"col-12 mb-2 text-center position-relative\">\n          <p\n            aria-label={`${multiSelectItemsCount} ${pluralize(\n              'photo',\n              multiSelectItemsCount\n            )} selected`}\n            className=\"multi-select-modal__selected-text m-0\">\n            {multiSelectItemsCount}{' '}\n            <small className=\"muted\">\n              {pluralize('photo', multiSelectItemsCount)} selected\n            </small>\n          </p>\n          <Button\n            onClick={handleShowMultiSelectModal}\n            type=\"button\"\n            className=\"multi-select-modal__close-btn position-absolute\"\n            aria-label=\"Close Multi Select\"\n          />\n        </div>\n        <div role=\"toolbar\" className=\"col-12 d-flex justify-content-between\">\n          <Button\n            type=\"button\"\n            disabled={multiSelectItemsCount === 0}\n            onClick={handleMultiDelete}\n            className=\"w-100 multi-select-modal__remove\"\n            aria-label=\"Remove Selected\">\n            <span className=\"multi-select-modal__remove-icon\"></span>\n            <span>Remove</span>\n          </Button>\n          <Button\n            text={bulkSelectText}\n            type=\"button\"\n            className=\"w-100 multi-select-modal__bulk-select border border-dark\"\n            aria-label={bulkSelectText}\n            onClick={handleBulkSelect}\n          />\n          <Button\n            type=\"button\"\n            disabled={multiSelectItemsCount === 0}\n            onClick={handleMultiResize}\n            className=\"w-100 multi-select-modal__resize\"\n            aria-label=\"Resize Selected\">\n            <span className=\"multi-select-modal__resize-icon\"></span>\n            <span>Resize</span>\n          </Button>\n        </div>\n      </div>\n    </div>\n  );\n}\n\nMultiSelectModal.propTypes = {\n  showMultiSelectModal: PropTypes.bool.isRequired,\n  maximumSelected: PropTypes.bool.isRequired,\n  multiSelectItemsCount: PropTypes.number.isRequired,\n  handleShowMultiSelectModal: PropTypes.func.isRequired,\n  handleMultiSelectAll: PropTypes.func.isRequired,\n  handleMultiUnSelectAll: PropTypes.func.isRequired,\n  handleMultiDelete: PropTypes.func.isRequired,\n  handleMultiResize: PropTypes.func.isRequired,\n};\n","import { useState } from 'react';\nimport { builderDispatch } from '../../../_utils/ui';\nimport { UpdatePhotoEvents } from '../../common/events/event-declarations';\n\nexport function useMultiSelect({ photos, isActive }) {\n  const [multiSelectPhotos, setMultiSelectPhotos] = useState({});\n\n  function emptySelectedItems() {\n    setMultiSelectPhotos({});\n  }\n\n  function handleMultiSelectAll() {\n    setMultiSelectPhotos(\n      photos.reduce((memo, photo) => {\n        return {\n          ...{\n            [uniqueKey(photo)]: [photo.image_id],\n            ...memo,\n          },\n        };\n      }, {})\n    );\n  }\n\n  function handleMultiUnSelectAll() {\n    emptySelectedItems();\n  }\n\n  const handleMultiResize = targetSizeKey => {\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.RESIZE_MULTI_SELECT,\n      selectPhotoImageIds,\n      targetSizeKey,\n    });\n\n    emptySelectedItems();\n  };\n\n  function handleMultiDelete() {\n    const photosToDelete = photos.filter(\n      photo => multiSelectPhotos[uniqueKey(photo)]?.length\n    );\n\n    photosToDelete.forEach(photo => {\n      const {\n        size: { key },\n        image_id: imageId,\n      } = photo;\n\n      builderDispatch.dispatch({\n        type: UpdatePhotoEvents.REMOVE,\n        sizeKey: key,\n        imageId,\n      });\n    });\n\n    emptySelectedItems();\n  }\n\n  function handleMultiSelectItem(photo) {\n    const photoKey = uniqueKey(photo);\n\n    if (isMultiSelected(photo)) {\n      const photos = multiSelectPhotos[photoKey].filter(\n        imageId => photo.image_id !== imageId\n      );\n      return setMultiSelectPhotos({\n        ...multiSelectPhotos,\n        ...{ [photoKey]: photos },\n      });\n    }\n\n    setMultiSelectPhotos({\n      ...multiSelectPhotos,\n      ...{ [photoKey]: [photo.image_id] },\n    });\n  }\n\n  function isMultiSelected(photo) {\n    return (multiSelectPhotos[uniqueKey(photo)] || []).some(\n      imageId => imageId === photo?.image_id\n    );\n  }\n\n  function uniqueKey(photo) {\n    return `${photo.image_id}_${photo.size.size_id}`;\n  }\n\n  const selectPhotoImageIds = Object.values(multiSelectPhotos).flatMap(\n    photoImageId => photoImageId\n  );\n  const multiSelectItemsCount = selectPhotoImageIds.length;\n  const maximumSelected = multiSelectItemsCount === photos.length;\n\n  return {\n    maximumSelected,\n    isMultiSelected,\n    handleMultiSelectItem,\n    handleMultiSelectAll,\n    handleMultiUnSelectAll,\n    handleMultiResize,\n    handleMultiDelete,\n    multiSelectItemsCount,\n  };\n}\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport ClassNames from 'classnames';\n\nexport default function PreviewBadges({\n  photo,\n  handleOnClick,\n  viewingSizeSelected,\n  isSelected,\n  children,\n}) {\n  const {\n    quantity,\n    size: { title },\n  } = photo;\n\n  return (\n    <div className=\"preview-badges-wrapper position-relative\">\n      {quantity > 1 && (\n        <span\n          role=\"button\"\n          className=\"preview-badge preview-badge__quantity left\">\n          {quantity}\n        </span>\n      )}\n      <span\n        role=\"button\"\n        className=\"preview-badge preview-badge__right\"\n        onClick={handleOnClick}>\n        <span\n          className={ClassNames('preview-badge__tick', {\n            'p-0': viewingSizeSelected,\n            selected: isSelected,\n          })}></span>\n        {!viewingSizeSelected && (\n          <span className=\"preview-badge__title pl-0\">{title}</span>\n        )}\n      </span>\n      {children}\n    </div>\n  );\n}\n\nPreviewBadges.propTypes = {\n  isSelected: PropTypes.bool,\n};\n\nPreviewBadges.defaultProps = {\n  isSelected: false,\n};\n","import React, { useEffect, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { DeliveryOption, PrintSize } from '../../prop-types';\nimport classNames from 'classnames';\nimport {\n  sizesWithPrice,\n  sizesWithRootImage,\n} from '../../common/totalizing-mixin';\nimport Photo from '../photos-grid/photo';\nimport SimpleThumbnail from '../photos-grid/photo/simple-thumbnail';\nimport MultiSelectModal from '../multi-select/multi-select-modal';\nimport { useMultiSelect } from '../multi-select/use-multi-select';\nimport ResizeOptionsModal from '../resize-options-modal';\nimport PreviewBadges from './preview-badges';\nimport PhotoRemoveConfirmationModal from '../../common/photo-remove-confirmation-modal';\nimport Paginator from '../../../_utils/paginator';\nimport { usePagination } from '../../../_utils/paginator/use-pagination';\nimport Button from '../../../_common/button';\nimport Footer from '../footer';\n\nconst PHOTOS_PER_PAGE = 25;\n\nexport default function PhotoListView({\n  handleSinglePhotoSelection,\n  orderedPhotos,\n  recommendedPrintSizes,\n  sizes,\n  availableSizes,\n  onAdvancedEditPhoto,\n  deliveryOption,\n  showMultiSelectModal,\n  handleShowMultiSelectModal,\n  viewingSizeKey,\n  invalidDeliveryOptionSelected,\n  handleAddPhotos,\n  hideSummaryDropdown,\n}) {\n  const [showResizeOptionsModal, setShowResizeModal] = useState(false);\n  const [\n    showPhotoRemoveConfirmation,\n    setShowPhotoRemoveConfirmation,\n  ] = useState(false);\n  const multiselectPhotos = orderedPhotos.reduce(\n    (memo, size) => memo.concat([...size.photos]),\n    []\n  );\n  const {\n    isMultiSelected,\n    handleMultiSelectItem,\n    handleMultiSelectAll,\n    handleMultiUnSelectAll,\n    handleMultiDelete,\n    handleMultiResize,\n    multiSelectItemsCount,\n    maximumSelected,\n  } = useMultiSelect({\n    photos: multiselectPhotos,\n    isActive: showMultiSelectModal,\n  });\n\n  const displayedPhotos = orderedPhotos.flatMap(\n    ({ id, photos = [], isLastPhoto }) =>\n      photos.map(p => ({ id, photo: p, isLastPhoto }))\n  );\n  const {\n    page,\n    paginatedItems,\n    totalPageCount,\n    handlePageNext,\n    handlePagePrevious,\n    handleGoToPage,\n  } = usePagination({ items: displayedPhotos, itemsPerPage: PHOTOS_PER_PAGE });\n\n  useEffect(() => {\n    handleGoToPage(1);\n  }, [viewingSizeKey]); // reset page if size filter changes\n\n  const photoRemoveConfirmationText =\n    (multiSelectItemsCount > 1 &&\n      'Are you sure you want to remove these photos?') ||\n    'Are you sure you want to remove this photo?';\n\n  useEffect(() => {\n    if (showMultiSelectModal && multiSelectItemsCount < 1) {\n      handleShowMultiSelectModal();\n    }\n  }, [multiSelectItemsCount]);\n\n  function handleResizeOptionsModal() {\n    setShowResizeModal(prevResizeOptionsModal => !prevResizeOptionsModal);\n  }\n\n  function handlePhotoRemoveModal() {\n    setShowPhotoRemoveConfirmation(\n      prevShowPhotoRemoveConfirmation => !prevShowPhotoRemoveConfirmation\n    );\n  }\n\n  function handlePhotoRemoval() {\n    setShowPhotoRemoveConfirmation(true);\n  }\n\n  return (\n    <>\n      <div role=\"tree\" className=\"prints-builder__photo_grid\">\n        {paginatedItems.map(({ id, photo, isLastPhoto }) => {\n          const key = `${id}_${photo.size.size_id}`;\n          const isSelected = isMultiSelected(photo);\n\n          return (\n            <div\n              role=\"treeitem\"\n              key={key}\n              className=\"photo_grid__item grid-item\">\n              <div\n                className={classNames('photo_grid__container', {\n                  selected: isSelected,\n                })}\n                onClick={() => {\n                  showMultiSelectModal && handleMultiSelectItem(photo);\n                }}>\n                <PreviewBadges\n                  photo={photo}\n                  handleOnClick={() => {\n                    if (!showMultiSelectModal) {\n                      handleShowMultiSelectModal();\n                      handleMultiSelectItem(photo);\n                    }\n                  }}\n                  isMultiSelectActive={showMultiSelectModal}\n                  viewingSizeSelected={!!viewingSizeKey}\n                  isSelected={isSelected}>\n                  {Photo(\n                    {\n                      ...photo,\n                      onClick: () => {\n                        !showMultiSelectModal &&\n                          handleSinglePhotoSelection(photo.image_id);\n                      },\n                    },\n                    isLastPhoto,\n                    sizesWithRootImage(sizes, id),\n                    availableSizes,\n                    onAdvancedEditPhoto,\n                    recommendedPrintSizes[id],\n                    SimpleThumbnail,\n                    isSelected,\n                    {\n                      showLowQualityWarning: true,\n                      hideLowQualityInformationTooltip: true,\n                    }\n                  )}\n                </PreviewBadges>\n              </div>\n            </div>\n          );\n        })}\n        <Footer>\n          <Paginator\n            title=\"Uploaded photos pages\"\n            page={page}\n            totalPageCount={totalPageCount}\n            scrollTarget={-200}\n            onPageNext={handlePageNext}\n            onPagePrevious={handlePagePrevious}\n            onGoToPage={handleGoToPage}\n          />\n          <MultiSelectModal\n            maximumSelected={maximumSelected}\n            multiSelectItemsCount={multiSelectItemsCount}\n            handleMultiUnSelectAll={() => {\n              handleMultiUnSelectAll();\n              handleShowMultiSelectModal();\n            }}\n            handleMultiSelectAll={handleMultiSelectAll}\n            handleShowMultiSelectModal={() => {\n              handleMultiUnSelectAll();\n              handleShowMultiSelectModal();\n            }}\n            showMultiSelectModal={\n              !showResizeOptionsModal && showMultiSelectModal\n            }\n            handleMultiDelete={handlePhotoRemoval}\n            handleMultiResize={handleResizeOptionsModal}\n          />\n          <Button\n            type=\"button\"\n            className=\"btn btn-outline-secondary mx-auto mt-2\"\n            onClick={() => {\n              hideSummaryDropdown();\n              handleAddPhotos();\n            }}\n            disabled={invalidDeliveryOptionSelected}\n            text=\"Add More Photos\"\n          />\n        </Footer>\n      </div>\n      <ResizeOptionsModal\n        title={'Resize Selected Photos'}\n        availableSizes={sizesWithPrice(availableSizes, sizes, deliveryOption)}\n        onClick={targetSizeKey => {\n          handleMultiResize(targetSizeKey);\n          handleResizeOptionsModal();\n        }}\n        showSizeOptionsModal={showResizeOptionsModal}\n        deliveryOption={deliveryOption}\n        handleResizeOptionsModal={handleResizeOptionsModal}\n        showResizeOptionsModal={showResizeOptionsModal}\n      />\n      <PhotoRemoveConfirmationModal\n        title={photoRemoveConfirmationText}\n        className=\"photo-list-view__photo_removal_confirmation\"\n        onRemove={() => {\n          handleMultiDelete();\n          handlePhotoRemoveModal();\n        }}\n        onClose={handlePhotoRemoveModal}\n        isOpen={showPhotoRemoveConfirmation}\n      />\n    </>\n  );\n}\n\nPhotoListView.propTypes = {\n  deliveryOption: DeliveryOption.isRequired,\n  availableSizes: PropTypes.arrayOf(PrintSize).isRequired,\n  sizes: PropTypes.arrayOf(PrintSize).isRequired,\n  orderedPhotos: PropTypes.array.isRequired,\n  handleSinglePhotoSelection: PropTypes.func.isRequired,\n  onAdvancedEditPhoto: PropTypes.func.isRequired,\n  handleShowMultiSelectModal: PropTypes.func.isRequired,\n  showMultiSelectModal: PropTypes.bool.isRequired,\n};\n","import React from 'react';\nimport translate from '../../../_utils/tools/translate';\nimport Store from '../../../_utils/tools/store';\n\nexport default function OptionsWrapper({\n  finishWrapper,\n  children,\n  className,\n  disabledOptions,\n  blockingOption,\n}) {\n  const title =\n    (finishWrapper && 'Paper Finish') || `${translate('Shipping')} Method`;\n  const disabledOptionLabels = disabledOptions\n    .map(o => o.label)\n    .filter(Boolean);\n  const disabledOptionMessage =\n    disabledOptionLabels.length > 0 && blockingOption\n      ? `${disabledOptionLabels.join(', ')} not available for ${\n          blockingOption.title\n        }`\n      : null;\n  const displayDisabledOption = Store.isWalmart() && disabledOptionMessage;\n  const titleOption = (finishWrapper && 'finish') || 'delivery';\n\n  return (\n    <>\n      <div className={`clearfix my-1 options-wrapper__${titleOption}-title`}>\n        <h6 className=\"float-left mb-0 ml-1\">{title}</h6>\n        {displayDisabledOption && (\n          <span className=\"small float-right\">{disabledOptionMessage}</span>\n        )}\n      </div>\n      <div className={className}>{children}</div>\n    </>\n  );\n}\n\nOptionsWrapper.defaultProps = {\n  disabledOptions: [],\n};\n","import React, { useContext } from 'react';\nimport classNames from 'classnames';\nimport { SummaryDropdownContext } from './index';\nimport Button from '../../../_common/button';\nimport OptionsWrapper from './options-wrapper';\n\nexport default function ButtonOptions({\n  handleFinishChange,\n  handleDeliveryChange,\n}) {\n  const {\n    finishSelectorOptions,\n    deliverySelectorOptions,\n    selectedFinishOption,\n    selectedDeliveryOption,\n  } = useContext(\n    SummaryDropdownContext\n  );\n\n  function joinOptionLabel(label) {\n    return label.replace(/\\s/, '_').toLowerCase();\n  }\n\n  return (\n    <div className='print-order__order-buttons'>\n      <OptionsWrapper className='print-finish-selector d-flex'\n        disabledOptions={finishSelectorOptions.filter((o) => o.disabled)}\n        blockingOption={selectedDeliveryOption}\n        finishWrapper\n      >\n        {finishSelectorOptions.map(finish => (\n          <ButtonOption\n            disabled={finish.disabled}\n            key={finish.label}\n            isSelected={finish.selected}\n            text={finish.label}\n            thumbnailClass={joinOptionLabel(finish.label)}\n            handleChange={handleFinishChange}\n            value={finish.value}\n            ariaLabel={`Select ${finish.label} Finish`}\n          />\n        ))}\n      </OptionsWrapper>\n      <OptionsWrapper\n        className='delivery-method-selector d-flex'\n        disabledOptions={deliverySelectorOptions.filter((o) => o.disabled)}\n        blockingOption={selectedFinishOption}\n      >\n        {deliverySelectorOptions.map(deliveryOption => (\n          <ButtonOption\n            disabled={deliveryOption.disabled}\n            key={deliveryOption.label}\n            isSelected={deliveryOption.selected}\n            text={deliveryOption.label}\n            thumbnailClass={joinOptionLabel(deliveryOption.code)}\n            handleChange={handleDeliveryChange}\n            value={deliveryOption.value}\n            ariaLabel={`${deliveryOption.value} Delivery Option`}\n          />\n        ))}\n      </OptionsWrapper>\n    </div>\n  );\n}\n\nfunction ButtonOption({\n  disabled,\n  text,\n  value,\n  isSelected,\n  handleChange,\n  thumbnailClass,\n  ariaLabel,\n}) {\n  return (\n    <div className='col-6 px-1'>\n      <Button\n        className={classNames('w-100 h-100 btn-sm btn-outline-info', {\n          selected: isSelected,\n        })}\n        disabled={disabled}\n        type='button'\n        onClick={() => handleChange(value)}\n        aria-label={ariaLabel}>\n        <span\n          className={`summary-dropdown__option_thumbnail rounded-circle ${thumbnailClass}`}></span>\n        <span className='summary-dropdown__option_title'>{text}</span>\n      </Button>\n    </div>\n  );\n}\n","import React, { useContext } from 'react';\nimport OptionsWrapper from './options-wrapper';\nimport CustomUniversalSelect from '../../../_utils/custom-universal-select';\nimport { SummaryDropdownContext } from './index';\n\nexport default function DropdownOptions({\n  handleFinishChange,\n  handleDeliveryChange,\n}) {\n  const {\n    finishSelectorOptions,\n    selectedFinishOption,\n    selectedDeliveryOption,\n    deliverySelectorOptions,\n  } = useContext(SummaryDropdownContext);\n\n  return (\n    <div className=\"print-order__dropdown\">\n      <OptionsWrapper className=\"print-finish-selector\" finishWrapper>\n        <CustomUniversalSelect\n          hideCheckBox\n          solidArrowIcon\n          id=\"print-finish-selector\"\n          value={selectedFinishOption.key || ''}\n          options={finishSelectorOptions}\n          ariaLabel=\"Select Finish\"\n          onChange={value => handleFinishChange(value)}\n        />\n      </OptionsWrapper>\n      <OptionsWrapper className=\"delivery-selector\">\n        <CustomUniversalSelect\n          hideCheckBox\n          solidArrowIcon\n          id=\"delivery-selector\"\n          value={selectedDeliveryOption.key || ''}\n          options={deliverySelectorOptions}\n          ariaLabel=\"Select Delivery Option\"\n          onChange={value => handleDeliveryChange(value)}\n        />\n      </OptionsWrapper>\n    </div>\n  );\n}\n","import React, { createContext } from 'react';\nimport PropTypes from 'prop-types';\nimport { DeliveryOption, PrintFinish } from '../../prop-types';\nimport AddToCartControls from '../../common/add-to-cart-controls';\nimport {\n  availableDeliveryOptionsForFinish,\n  availableFinishKeys,\n  availableFinishOptions,\n  calculateSelectedFinish,\n  selectedDeliveryOption,\n  addSelectedAttributeToOptions,\n} from '../../common/finish-and-delivery-options';\nimport ButtonOptions from './button-options';\nimport DropdownOptions from './dropdown-options';\nimport Button from '../../../_common/button';\n\nexport const SummaryDropdownContext = createContext({\n  finishSelectorOptions: [],\n  deliverySelectorOptions: [],\n  selectedFinishOption: null,\n  selectedDeliveryOption: null,\n});\n\nconst OPTIONS_LIMIT = 2;\n\nexport default function SummaryDropdown({\n  deliveryOption,\n  deliveryOptions,\n  finishesByDeliveryOption,\n  finishes,\n  finish,\n  basketUrl,\n  allowMultiplePrintFinishesPerOrder,\n  addToCartEnabled,\n  handleOptionsChanged,\n  handleAddToCart,\n}) {\n  const displayOptionsAsDropdowns =\n    deliveryOptions.length > OPTIONS_LIMIT || finishes.length > OPTIONS_LIMIT;\n\n  const finishKeys = availableFinishKeys(\n    finishesByDeliveryOption,\n    deliveryOption\n  );\n\n  const handleFinishChange = value => {\n    const selectedFinish = calculateSelectedFinish(\n      deliveryOption.key,\n      value,\n      finishesByDeliveryOption\n    );\n\n    if (selectedFinish.key == finish.key) {\n      return;\n    }\n\n    if (allowMultiplePrintFinishesPerOrder) {\n      window.location = `${window.location.pathname}?finish=${selectedFinish.title}`;\n    } else {\n      handleOptionsChanged({ finish: selectedFinish });\n    }\n  };\n\n  const handleDeliveryChange = value => {\n    handleOptionsChanged({\n      delivery_option: selectedDeliveryOption(deliveryOptions, value),\n    });\n  };\n\n  return (\n    <SummaryDropdownContext.Provider\n      value={{\n        allowMultiplePrintFinishesPerOrder,\n        finishSelectorOptions: addSelectedAttributeToOptions(\n          availableFinishOptions(finishes, finishKeys),\n          finish.key\n        ),\n        selectedFinishOption: finish,\n        selectedDeliveryOption: deliveryOption,\n        deliverySelectorOptions: addSelectedAttributeToOptions(\n          availableDeliveryOptionsForFinish(\n            deliveryOptions,\n            finishesByDeliveryOption,\n            finish,\n            true\n          ),\n          deliveryOption.key\n        ),\n      }}>\n      <div className=\"grey-zone print-order__summary-dropdown\">\n        <div className=\"d-flex align-items-center\">\n          <div className=\"flex-grow-1\">\n            <Button\n              className=\"btn-link p-0 border-0 collapsed print-order__title\"\n              type=\"button\"\n              data-toggle=\"collapse\"\n              data-target=\"#summary-chart\"\n              aria-expanded=\"true\"\n              aria-controls=\"summary-chart\"\n              aria-label=\"Order Options\"\n              text=\"Order Options\"\n            />\n          </div>\n          <div>\n            <AddToCartControls\n              enabled={addToCartEnabled}\n              basketUrl={basketUrl}\n              onAddToCart={handleAddToCart}\n            />\n          </div>\n        </div>\n\n        <div id=\"summary-chart\" className=\"collapse show\">\n          <div className=\"print-order__summary\">\n            {(displayOptionsAsDropdowns && (\n              <DropdownOptions\n                handleFinishChange={handleFinishChange}\n                handleDeliveryChange={handleDeliveryChange}\n              />\n            )) || (\n              <ButtonOptions\n                handleFinishChange={handleFinishChange}\n                handleDeliveryChange={handleDeliveryChange}\n              />\n            )}\n          </div>\n        </div>\n      </div>\n    </SummaryDropdownContext.Provider>\n  );\n}\n\nSummaryDropdown.propTypes = {\n  deliveryOption: DeliveryOption.isRequired,\n  deliveryOptions: PropTypes.arrayOf(DeliveryOption).isRequired,\n  finishesByDeliveryOption: PropTypes.objectOf(PropTypes.arrayOf(PrintFinish))\n    .isRequired,\n  finishes: PropTypes.arrayOf(PrintFinish).isRequired,\n  finish: PrintFinish.isRequired,\n  basketUrl: PropTypes.string.isRequired,\n  allowMultiplePrintFinishesPerOrder: PropTypes.bool,\n  addToCartEnabled: PropTypes.bool.isRequired,\n  handleOptionsChanged: PropTypes.func.isRequired,\n  handleAddToCart: PropTypes.func.isRequired,\n};\n\nSummaryDropdown.defaultProps = {\n  allowMultiplePrintFinishesPerOrder: false,\n};\n","import React from 'react';\nimport PropTypes from 'prop-types';\n\nimport { UploadedPhoto, PrintSize, DeliveryOption } from '../../prop-types';\nimport Photo from '../photos-grid/photo';\nimport Utils from '../../common/size-helpers';\nimport PhotoFilename from '../../common/photo-filename';\nimport SimpleThumbnail from '../photos-grid/photo/simple-thumbnail';\nimport fireTrackingEvent from '../../common/events/fire-tracking-event';\nimport { WebUI, builderDispatch } from '../../../_utils/ui';\nimport { UpdatePhotoEvents } from '../../common/events/event-declarations';\nimport { QuantityInput } from './quantity-input';\nimport {\n  sizesWithRootImage,\n  sizesWithPrice,\n} from '../../common/totalizing-mixin';\nimport ResizeOptionsModal from '../resize-options-modal';\nimport Button from '../../../_common/button';\n\nconst SizeOptionsMode = {\n  NONE: undefined,\n  RESIZE: 'resize',\n  ADDSIZE: 'add_size',\n};\n\nclass PhotoSelectionView extends React.Component {\n  constructor(props) {\n    super(props);\n\n    this.state = {\n      sizeOptionsMode: SizeOptionsMode.NONE,\n    };\n  }\n\n  showResizeOptionsModal = () => {\n    this.setState({ sizeOptionsMode: SizeOptionsMode.RESIZE });\n  };\n\n  showAddSizeOptionsModal = () => {\n    this.setState({ sizeOptionsMode: SizeOptionsMode.ADDSIZE });\n  };\n\n  handleCloseSizeOptionsModal = () => {\n    this.setState({ sizeOptionsMode: SizeOptionsMode.NONE });\n  };\n\n  update = (value, key = 'quantity') => {\n    const { selectedPhoto } = this.props;\n\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.UPDATE,\n      photo: {\n        ...selectedPhoto,\n        [key]: value,\n      },\n      hard: true,\n    });\n  };\n\n  handleEdit = (photo, onAdvancedEdit) => {\n    const {\n      size: { key },\n      image_id: imageId,\n    } = photo;\n    fireTrackingEvent(WebUI.PHOTO_EVENT_ADVANCED_EDIT);\n    onAdvancedEdit(key, imageId);\n  };\n\n  handleQuantityUpdate = value => this.update(value, 'quantity');\n\n  handleRemove = (photo, nextPhoto) => {\n    const {\n      size: { key },\n      image_id: imageId,\n    } = photo;\n\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.REMOVE,\n      sizeKey: key,\n      imageId,\n      selectedPhotoId: nextPhoto?.image_id,\n    });\n  };\n\n  handleRemoveByRootId = rootImageId => {\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.SHOW_REMOVE_CONFIRMATION,\n      imageId: rootImageId,\n      useRoot: true,\n    });\n  };\n\n  handleSizeChange = (targetSizeKey, photo) => {\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.RESIZE,\n      image_id: photo.image_id,\n      size_key: photo.size.key,\n      targetSizeKey,\n    });\n  };\n\n  addSize(targetSizeKey, photo) {\n    builderDispatch.dispatch({\n      type: UpdatePhotoEvents.ADD_TO_SIZE,\n      root_image_id: photo.root_image_id,\n      targetSizeKey,\n      quantity: 1,\n    });\n  }\n\n  render() {\n    const {\n      selectedPhoto,\n      setSelectedPhotoId,\n      availableSizes,\n      sizes,\n      onAdvancedEditPhoto,\n      orderedPhotos,\n      recommendedPrintSizes,\n      selectedPhotoAssociatedPhotos,\n      deliveryOption,\n    } = this.props;\n    const { sizeOptionsMode } = this.state;\n\n    const currentPhotoIndex = orderedPhotos.findIndex(photo =>\n      photo.photos.map(p => p.image_id).includes(selectedPhoto.image_id)\n    );\n    const prevPhoto = orderedPhotos[currentPhotoIndex - 1];\n    const nextPhoto = orderedPhotos[currentPhotoIndex + 1];\n    const currentSizeIndex = selectedPhotoAssociatedPhotos.findIndex(\n      p => p.image_id === selectedPhoto.image_id\n    );\n    const prevSizePhoto = selectedPhotoAssociatedPhotos[currentSizeIndex - 1];\n    const nextSizePhoto = selectedPhotoAssociatedPhotos[currentSizeIndex + 1];\n    const isLastPhoto = selectedPhotoAssociatedPhotos.length <= 1;\n    const recommendedPrintSize = recommendedPrintSizes[selectedPhoto.image_id];\n\n    return (\n      <div className=\"prints-builder__photo-view d-flex flex-column\">\n        <div className=\"prints-builder__photo-view-header d-flex justify-content-between\">\n          <button\n            className=\"btn btn-link btn-underline ml-2\"\n            onClick={() => setSelectedPhotoId(Utils.ALL_PHOTOS_KEY)}\n            aria-label=\"Go back to the gallery of photos in your order\">\n            <i className=\"fas fa-chevron-left mr-1\" />\n            Back\n          </button>\n\n          <QuantityInput\n            key={`${selectedPhoto.image_id}-${selectedPhoto.quantity}`}\n            className=\"mt-3 mr-2\"\n            value={selectedPhoto.quantity}\n            onQuantityChange={this.handleQuantityUpdate}\n          />\n        </div>\n\n        <div className=\"prints-builder__photo-view__photo flex-fill\">\n          <div className=\"flex-grow-1\">\n            <div className=\"d-flex justify-content-center py-2\">\n              <Button\n                className=\"btn-lg\"\n                icon=\"fa-chevron-down ml-2\"\n                aria-label=\"Select another print size for your photo\"\n                text={`Size: ${selectedPhoto.size.title}`}\n                onClick={this.showResizeOptionsModal}\n              />\n            </div>\n\n            <div className=\"ml-4 mb-2\">\n              <PhotoFilename photo={selectedPhoto} />\n            </div>\n\n            {Photo(\n              { ...selectedPhoto, key: `${selectedPhoto.image_id}` },\n              false,\n              sizesWithRootImage(sizes, selectedPhoto.image_id),\n              availableSizes,\n              onAdvancedEditPhoto,\n              recommendedPrintSize,\n              SimpleThumbnail,\n              false,\n              {\n                showLowQualityWarning: true,\n                lowQualityInformationPosition: 'bottom',\n                lowQualityInformationCSSClasses: 'mobile',\n                isWallet: false,\n              }\n            )}\n\n            <div className=\"d-flex justify-content-between mt-2 px-4\">\n              <button\n                className=\"btn btn-link btn-underline\"\n                aria-label={`Remove ${selectedPhoto.filename} ${selectedPhoto.size.title}`}\n                onClick={() =>\n                  isLastPhoto\n                    ? this.handleRemoveByRootId(selectedPhoto.root_image_id)\n                    : this.handleRemove(\n                        selectedPhoto,\n                        prevSizePhoto || nextSizePhoto\n                      )\n                }>\n                <i className=\"fa fa-trash mr-2\" />\n                Remove\n              </button>\n\n              <button\n                className=\"btn btn-link btn-underline\"\n                aria-label={`Edit ${selectedPhoto.filename} ${selectedPhoto.size.title}`}\n                onClick={() =>\n                  this.handleEdit(selectedPhoto, onAdvancedEditPhoto)\n                }>\n                <i className=\"fa fa-pencil-alt mr-2\" />\n                Edit\n              </button>\n            </div>\n          </div>\n        </div>\n\n        <div className=\"row d-flex mt-auto mb-2 px-3\">\n          <div className=\"col p-0 text-center\">\n            {prevSizePhoto && (\n              <>\n                <span className=\"w-100 text-center\">Prev Size</span>\n                <button\n                  className=\"btn btn-pill\"\n                  onClick={() => setSelectedPhotoId(prevSizePhoto.image_id)}\n                  aria-label=\"Display the previous size of this photo\">\n                  <i className=\"fas fa-chevron-up mr-2\" />\n                  {prevSizePhoto.size.title}\n                </button>\n              </>\n            )}\n          </div>\n\n          <div className=\"col p-0 text-center\">\n            <Button\n              className=\"btn-pill add-size-btn\"\n              aria-label=\"Add a copy of this photo in a different size\"\n              text=\"Add Size\"\n              onClick={this.showAddSizeOptionsModal}\n            />\n          </div>\n\n          <div className=\"col p-0 text-center\">\n            {nextSizePhoto && (\n              <>\n                <span className=\"w-100 text-center\">Next Size</span>\n                <button\n                  className=\"btn btn-pill\"\n                  onClick={() => setSelectedPhotoId(nextSizePhoto.image_id)}\n                  aria-label=\"Display the next size of this photo\">\n                  <i className=\"fas fa-chevron-down mr-2\" />\n                  {nextSizePhoto.size.title}\n                </button>\n              </>\n            )}\n          </div>\n        </div>\n\n        <footer className=\"prints-builder__footer prints-builder__photo-view-footer\">\n          <div className=\"prints-builder__footer-border d-flex justify-content-between align-items-center\">\n            {prevPhoto && (\n              <button\n                className=\"btn btn-pill mr-auto\"\n                onClick={() => setSelectedPhotoId(prevPhoto.photos[0].image_id)}\n                aria-label=\"Display the previous photo in your order\">\n                <i className=\"fas fa-chevron-left mr-2\" />\n                Prev photo\n              </button>\n            )}\n\n            {nextPhoto && (\n              <button\n                className=\"btn btn-pill ml-auto\"\n                onClick={() => setSelectedPhotoId(nextPhoto.photos[0].image_id)}\n                aria-label=\"Display the next photo in your order\">\n                Next photo\n                <i className=\"fas fa-chevron-right ml-2\" />\n              </button>\n            )}\n          </div>\n        </footer>\n        <ResizeOptionsModal\n          title={'Resize'}\n          availableSizes={sizesWithPrice(availableSizes, sizes, deliveryOption)}\n          sizesWithPrints={sizesWithRootImage(\n            sizes,\n            selectedPhoto.root_image_id\n          )}\n          onClick={targetSizeKey => {\n            this.handleSizeChange(targetSizeKey, selectedPhoto);\n            this.handleCloseSizeOptionsModal();\n          }}\n          showResizeOptionsModal={sizeOptionsMode === SizeOptionsMode.RESIZE}\n          deliveryOption={deliveryOption}\n          handleResizeOptionsModal={this.handleCloseSizeOptionsModal}\n          recommendedPrintSize={recommendedPrintSize}\n          photoDimensions={selectedPhoto.raw_dimensions}\n          showLowQualityWarning\n          hideTooltip\n        />\n        <ResizeOptionsModal\n          title={'Add Size'}\n          availableSizes={sizesWithPrice(availableSizes, sizes, deliveryOption)}\n          sizesWithPrints={sizesWithRootImage(\n            sizes,\n            selectedPhoto.root_image_id\n          )}\n          onClick={targetSizeKey => {\n            this.addSize(targetSizeKey, selectedPhoto);\n            this.handleCloseSizeOptionsModal();\n          }}\n          showResizeOptionsModal={sizeOptionsMode === SizeOptionsMode.ADDSIZE}\n          deliveryOption={deliveryOption}\n          handleResizeOptionsModal={this.handleCloseSizeOptionsModal}\n          recommendedPrintSize={recommendedPrintSize}\n          photoDimensions={selectedPhoto.raw_dimensions}\n          showLowQualityWarning\n          hideTooltip\n        />\n      </div>\n    );\n  }\n}\n\nPhotoSelectionView.propTypes = {\n  setSelectedPhotoId: PropTypes.func.isRequired,\n  selectedPhoto: UploadedPhoto.isRequired,\n  orderedPhotos: PropTypes.arrayOf(PropTypes.object).isRequired,\n  selectedPhotoAssociatedPhotos: PropTypes.arrayOf(UploadedPhoto).isRequired,\n  recommendedPrintSizes: PropTypes.objectOf(PrintSize),\n  sizes: PropTypes.arrayOf(PrintSize),\n  availableSizes: PropTypes.arrayOf(PrintSize),\n  deliveryOption: DeliveryOption.isRequired,\n  onAdvancedEditPhoto: PropTypes.func.isRequired,\n};\n\nexport default PhotoSelectionView;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '../../../_common/button';\n\nexport default function ScrollToTopBtn({ onClick, showBtn }) {\n  const btnClass = `btn btn-outline-secondary scroll-to-top-btn ${\n    showBtn ? '' : 'd-none'\n  }`;\n\n  return (\n    <Button type=\"button\" className={btnClass} onClick={onClick}>\n      <span className=\"scroll-to-top-btn__icon\"></span>\n      <span className=\"scroll-to-top-btn__text\">Return To Top</span>\n    </Button>\n  );\n}\n\nScrollToTopBtn.propTypes = {\n  onClick: PropTypes.func.isRequired,\n  showBtn: PropTypes.bool.isRequired,\n};\n","import React, { useEffect, useRef } from 'react';\nimport { builderDispatch, WebUI } from '../../_utils/ui';\nimport { UpdatePhotoEvents } from '../common/events/event-declarations';\nimport screenAndStyle from '../../_utils/screen-and-style';\n\n// Disable back button for chrome\n// https://support.google.com/chrome/thread/8721521/disable-back-button-on-browser?hl=en\n\nif (!screenAndStyle.isSafari()) {\n  window.history.pushState(null, null, location.href);\n  window.history.back();\n  window.history.forward();\n  window.window.onpopstate = function() {\n    history.forward();\n  };\n}\n\nexport default function WithGestureActions({ backGesture, children }) {\n  const defaultBackBtnActionDisabled = useRef(false);\n  const disableGestureActions = useRef(false);\n  const backGestureTriggerDistance = 100;\n  let start;\n  let end;\n\n  useEffect(() => {\n    const builderDispatchToken = builderDispatch.register(payload => {\n      switch (payload.type) {\n        // Mobile editor has sliders so gesture could be called by mistake\n        case UpdatePhotoEvents.ADVANCED_EDIT_CLOSE:\n          disableGestureActions.current = false;\n          break;\n        case WebUI.PHOTO_EVENT_ADVANCED_EDIT:\n          disableGestureActions.current = true;\n          break;\n      }\n    });\n\n    return () => {\n      builderDispatch.unregister(builderDispatchToken);\n    };\n  }, []);\n\n  useEffect(() => {\n    defaultBackBtnActionDisabled.current = true;\n\n    return () => {\n      defaultBackBtnActionDisabled.current = false;\n    };\n  }, []);\n\n  useEffect(() => {\n    if (screenAndStyle.isSafari()) {\n      history.pushState(null, null, location.href);\n      window.addEventListener('popstate', function() {\n        history.pushState(null, null, location.href);\n      });\n    }\n\n    window.addEventListener('touchstart', handleTouchStart);\n    window.addEventListener('touchend', handleTouchEnd);\n    window.addEventListener('mousedown', handleMouseDown);\n    window.addEventListener('mouseup', handleMouseUp);\n    window.addEventListener('popstate', handleBackButtonPress);\n\n    return () => {\n      window.removeEventListener('touchstart', handleTouchStart);\n      window.removeEventListener('touchend', handleTouchEnd);\n      window.removeEventListener('mousedown', handleMouseDown);\n      window.removeEventListener('mouseup', handleMouseUp);\n      window.removeEventListener('popstate', handleBackButtonPress);\n    };\n  }, []);\n\n  function backGestureTriggered() {\n    return Number(end) - Number(start) >= backGestureTriggerDistance;\n  }\n\n  function handleBackGesture() {\n    if (backGestureTriggered() && !disableGestureActions.current) {\n      backGesture && backGesture();\n    }\n  }\n\n  function handleBackButtonPress(e) {\n    e.preventDefault();\n\n    if (\n      defaultBackBtnActionDisabled.current &&\n      !disableGestureActions.current\n    ) {\n      backGesture && backGesture();\n    }\n  }\n\n  function handleMouseUp(e) {\n    end = e.clientX;\n\n    handleBackGesture();\n  }\n\n  function handleMouseDown(e) {\n    start = e.clientX;\n    end = 0;\n  }\n\n  function handleTouchStart(e) {\n    start = e.targetTouches[0]?.clientX;\n    end = 0;\n  }\n\n  function handleTouchEnd(e) {\n    end = e.changedTouches[0]?.clientX;\n\n    handleBackGesture();\n  }\n\n  return children;\n}\n","import createReactClass from 'create-react-class';\nimport React from 'react';\nimport PropTypes from 'prop-types';\nimport { PrintsBuilderUrlsShape } from '../prop-types';\nimport AddPhotosDevice from '../common/add-photos-device';\nimport genericHelpers from '../../_utils/generic-helpers';\nimport startSessionTimeout from '../../_utils/tools/session-timeout';\nimport PrintSizeFilter from './glass/print-size-filter';\nimport PhotoListView from './glass/photo-list-view';\nimport PhotoRemoveConfirmation from '../common/photo-remove-confirmation';\nimport PrintsBuilderMixin from '../common/prints-builder-mixin';\nimport SiteLogo from '../../_application/site-logo';\nimport SizeHelpers from '../common/size-helpers';\nimport Totaliser from '../common/totalizer';\nimport InvalidSizesModal from '../common/invalid-sizes-modal';\nimport InvalidDeliveryOptionModal from '../common/invalid-delivery-option-modal';\nimport UploadPhotosMixin from '../common/upload-photos-mixin';\nimport UploadProgressBar from '../common/upload-progress-bar';\nimport FullScreenSpinner from '../../_prism-builder/desktop/notices/full-screen-spinner';\nimport AdvancedEditor from '../common/advanced-editor';\nimport SummaryDropdown from './summary-dropdown';\nimport PhotoSelectionView from './glass/photo-selection-view';\nimport { allPhotosCollectedByRootImage } from '../common/collect-by-root-image';\nimport findRecommendedPrintSize from '../common/photo-quality/recommended-print-size';\nimport ScrollToTopBtn from './photos-grid/scroll-to-top-btn';\nimport PrintCountDisplay from './print-count-display';\nimport pluralize from '../../_utils/tools/pluralize';\nimport WithGestureActions from './with-gesture-actions';\nimport { sortedAndFilteredImages } from '../common/images-helper';\nimport { totalQuantity } from '../common/totalizing-mixin';\nimport Button from '../../_common/button';\nimport Footer from './footer';\n\nconst NewMobilePrintsBuilder = createReactClass({\n  mixins: [PrintsBuilderMixin, UploadPhotosMixin],\n\n  displayName: 'Mobile prints builder',\n\n  getInitialState() {\n    return {\n      finish: {},\n      delivery_option: {},\n      sizes: [],\n      showMultiSelectModal: false,\n      selectedPhotoId: undefined,\n      showScrollToTopBtn: false,\n    };\n  },\n\n  _photoIDs: {},\n  listWrapperRef: undefined,\n\n  UNSAFE_componentWillMount() {\n    this.loadData();\n\n    // loader callbacks\n    this.loadCallbacks();\n\n    this._forceUpdate = genericHelpers.debounce(() => this.forceUpdate());\n  },\n\n  componentDidMount() {\n    window.addEventListener('resize', this.handleViewportResize);\n    window.addEventListener('orientationchange', this._forceUpdate);\n\n    this.handleViewportResize();\n    this.handleSessionTimeout();\n  },\n\n  componentWillUnmount() {\n    window.removeEventListener('resize', this.handleViewportResize);\n    window.removeEventListener('orientationchange', this._forceUpdate);\n\n    this.unloadCallbacks();\n  },\n\n  findAllRecommendedPrintSizes(availableSizes) {\n    const { sizes } = this.state;\n    const photosCollection = allPhotosCollectedByRootImage(sizes);\n\n    return Object.entries(photosCollection).reduce(\n      (acc, [id, photoSizes = {}]) => {\n        const photo = (Object.values(photoSizes)[0] || [])[0];\n        acc[id] = findRecommendedPrintSize(availableSizes, photo);\n        return acc;\n      },\n      {}\n    );\n  },\n\n  render() {\n    const {\n      delivery_option: deliveryOption,\n      viewingSizeKey,\n      currentlyLoading,\n      finish,\n      ready,\n      invalidDeliveryOptionSelected,\n      showMultiSelectModal,\n      selectedPhotoId,\n      showScrollToTopBtn,\n    } = this.state;\n    const {\n      features: { allowMultiplePrintFinishesPerOrder },\n      urls,\n    } = this.props;\n\n    // Keeps a record of the original order of prints\n    Object.entries(allPhotosCollectedByRootImage(this.state.sizes)).forEach(\n      ([id, size]) => {\n        this._photoIDs[id] = Object.entries(size).map(\n          ([, [photo]]) => photo.id\n        );\n      }\n    );\n\n    const availableSizes = this.availableSizesForSelectedDeliveryAndFinish();\n    const sizes = this.state.sizes\n      .filter(SizeHelpers.sizeHasPrints)\n      .map(SizeHelpers.stripZeroQuantityPhotosFromSize);\n\n    const sizesByFinish = this.getSizesByFinish().filter(\n      SizeHelpers.sizeHasPrints\n    );\n\n    const hasPrints = this.hasPrints();\n    const deliveryOptions = [...this.data.delivery_options];\n    const finishes = [...this.data.finishes];\n    const finishesByDeliveryOption = Object.assign(\n      {},\n      this.availableFinishesByDeliveryOption\n    );\n    const showGalleryView = hasPrints && !selectedPhotoId;\n    const orderedPhotos = sortedAndFilteredImages({\n      sizes,\n      photoIds: this._photoIDs,\n      viewingSizeKey,\n      finish,\n    });\n    const recommendedPrintSizes = this.findAllRecommendedPrintSizes(\n      availableSizes\n    );\n    const photos = SizeHelpers.augment.fromCollection(sizes);\n    const selectedPhoto = selectedPhotoId\n      ? photos.find(p => p.image_id === selectedPhotoId)\n      : null;\n    const selectedPhotoAssociatedPhotos = selectedPhoto\n      ? photos.filter(p => p.root_image_id === selectedPhoto.root_image_id)\n      : [];\n    const photosLength = photos.length;\n    const orderedPhotosLength = totalQuantity(orderedPhotos);\n    const hasSelectedPhotoId = selectedPhotoId !== undefined;\n    const displayAddPhotos = !currentlyLoading && orderedPhotosLength < 1;\n\n    return (\n      <div className=\"prints-builder__grid m-web mobile-builder__glass\">\n        <header className=\"prints-builder__header d-flex align-items-center\">\n          <div className=\"flex-grow-1\">\n            <SiteLogo />\n          </div>\n          <Totaliser sizes={sizes} deliveryOption={deliveryOption} />\n        </header>\n        <aside className=\"print-order__summary-and-filter\">\n          <SummaryDropdown\n            allowMultiplePrintFinishesPerOrder={\n              allowMultiplePrintFinishesPerOrder\n            }\n            basketUrl={urls.cart_page}\n            addToCartEnabled={hasPrints && !currentlyLoading}\n            handleAddToCart={this.handleAddToCart}\n            deliveryOption={deliveryOption}\n            deliveryOptions={deliveryOptions}\n            finishesByDeliveryOption={finishesByDeliveryOption}\n            finishes={finishes}\n            finish={finish}\n            handleOptionsChanged={this.handleOptionsChanged}\n          />\n          <UploadProgressBar {...currentlyLoading} />\n          <InvalidSizesModal />\n          <InvalidDeliveryOptionModal />\n          {showGalleryView && (\n            <div className=\"print-order__filter print-order__filter-border text-center\">\n              <PrintSizeFilter\n                sizes={sizesByFinish}\n                availableSizes={availableSizes}\n                deliveryOption={deliveryOption}\n                viewingSizeKey={viewingSizeKey}\n                onChange={this.handleViewingSizeChanged}\n                onResize={this.handleResize}\n                generateSizeOptionLabel={size => size.title}\n                hideLabelForAllSizes\n              />\n              {!!orderedPhotosLength && !hasSelectedPhotoId && (\n                <PrintCountDisplay\n                  classNames=\"prints-builder__m-web-print-count-display text-center\"\n                  selectedCount={\n                    viewingSizeKey || allowMultiplePrintFinishesPerOrder\n                      ? orderedPhotosLength\n                      : photosLength\n                  }\n                  totalCount={photosLength}\n                  text={pluralize('Print', photosLength)}\n                  hideTotal={photosLength === 1}\n                />\n              )}\n            </div>\n          )}\n        </aside>\n        <main\n          ref={ref => (this.listWrapperRef = ref)}\n          className=\"prints-builder__list position-relative\"\n          onScroll={this.handleScroll}>\n          <ScrollToTopBtn\n            onClick={this.handleScrollToTop}\n            showBtn={showScrollToTopBtn}\n          />\n          {!!orderedPhotosLength && hasSelectedPhotoId && (\n            <WithGestureActions backGesture={this.setSelectedPhotoId}>\n              <PhotoSelectionView\n                selectedPhoto={selectedPhoto}\n                selectedPhotoAssociatedPhotos={selectedPhotoAssociatedPhotos}\n                setSelectedPhotoId={this.setSelectedPhotoId}\n                availableSizes={availableSizes}\n                deliveryOption={deliveryOption}\n                onAdvancedEditPhoto={this.handleAdvancedEdit}\n                sizes={sizesByFinish}\n                viewingSizeKey={viewingSizeKey}\n                orderedPhotos={orderedPhotos}\n                recommendedPrintSizes={recommendedPrintSizes}\n              />\n            </WithGestureActions>\n          )}\n          {!!orderedPhotosLength && !hasSelectedPhotoId && (\n            <PhotoListView\n              availableSizes={availableSizes}\n              deliveryOption={deliveryOption}\n              onAdvancedEditPhoto={this.handleAdvancedEdit}\n              sizes={sizesByFinish}\n              orderedPhotos={orderedPhotos}\n              viewingSizeKey={viewingSizeKey}\n              handleSinglePhotoSelection={this.setSelectedPhotoId}\n              recommendedPrintSizes={recommendedPrintSizes}\n              showMultiSelectModal={showMultiSelectModal}\n              handleShowMultiSelectModal={this.handleShowMultiSelectModal}\n              invalidDeliveryOptionSelected={invalidDeliveryOptionSelected}\n              hideSummaryDropdown={this.hideSummaryDropdown}\n              handleAddPhotos={this.handleAddPhotos}\n            />\n          )}\n          {displayAddPhotos && (\n            <AddPhotosDevice\n              onClick={this.handleAddPhotos}\n              buttonClassName=\"btn-primary\"\n            />\n          )}\n        </main>\n        {!hasPrints && (\n          <Footer>\n            <Button\n              type=\"button\"\n              className=\"btn btn-outline-secondary mx-auto mt-2\"\n              onClick={this.handleAddPhotos}\n              disabled={invalidDeliveryOptionSelected}\n              text=\"Add More Photos\"\n            />\n          </Footer>\n        )}\n        <AdvancedEditor\n          ref={ref => (this.advancedEditorRef = ref)}\n          availableSizes={availableSizes}\n        />\n        <PhotoRemoveConfirmation />\n        <FullScreenSpinner show={!ready} />\n      </div>\n    );\n  },\n\n  addToCartEnabled() {\n    return this.hasPrints() && !this.state.currentlyLoading;\n  },\n\n  handleShowMultiSelectModal() {\n    this.hideSummaryDropdown();\n    this.setState(prevState => ({\n      showMultiSelectModal: !prevState.showMultiSelectModal,\n    }));\n  },\n\n  handleViewportResize() {\n    const vh = window.innerHeight * 0.01;\n    genericHelpers.debounce(\n      document.documentElement.style.setProperty('--vh', `${vh}px`)\n    );\n  },\n\n  handleAdvancedEdit(sizeKey, imageId) {\n    const size = this.getSizeFromKey(sizeKey);\n    const photo = SizeHelpers.augment.individual(\n      this.getPhoto(size, imageId, true),\n      size\n    );\n\n    this.advanced_edit = {\n      size,\n      photo,\n    };\n\n    this.advancedEditor().setData({\n      photo,\n      availableSizes: this.availableSizesForSelectedDeliveryAndFinish(),\n      sizes: [...this.state.sizes],\n    });\n  },\n\n  refreshEL2(sizeKey, imageId) {\n    if (this.advanced_edit) {\n      this.handleAdvancedEdit(sizeKey, imageId);\n    }\n  },\n\n  handleSessionTimeout() {\n    const { initSessionTimeout } = this.props;\n\n    if (initSessionTimeout) {\n      startSessionTimeout();\n    }\n  },\n\n  handleScroll() {\n    const { showScrollToTopBtn, selectedPhotoId } = this.state;\n    const scrollOffsetHeight = 50;\n    const scrollTop = this.listWrapperRef.scrollTop;\n\n    if (selectedPhotoId) {\n      this.setState({ showScrollToTopBtn: false });\n      return;\n    }\n\n    if (scrollTop > scrollOffsetHeight && !showScrollToTopBtn) {\n      this.hideSummaryDropdown();\n      this.setState({ showScrollToTopBtn: true });\n    }\n\n    if (scrollTop < scrollOffsetHeight && showScrollToTopBtn) {\n      this.setState({ showScrollToTopBtn: false });\n    }\n  },\n\n  handleScrollToTop() {\n    this.listWrapperRef.scrollTop = 0;\n    this.setState({ showScrollToTopBtn: false });\n  },\n\n  allowZeroQuantity: () => false,\n\n  setSelectedPhotoId(photoId) {\n    this.hideSummaryDropdown();\n    this.setState({ selectedPhotoId: photoId });\n  },\n\n  hideSummaryDropdown() {\n    $('#summary-chart').collapse('hide');\n  },\n});\n\nNewMobilePrintsBuilder.propTypes = {\n  urls: PrintsBuilderUrlsShape.isRequired,\n  features: PropTypes.objectOf(\n    PropTypes.oneOfType([PropTypes.string, PropTypes.bool])\n  ),\n  initSessionTimeout: PropTypes.bool,\n  uploadFromGalleryListenerUrl: PropTypes.string,\n};\n\nNewMobilePrintsBuilder.defaultProps = {\n  features: {},\n  initSessionTimeout: false,\n  uploadFromGalleryListenerUrl: '',\n};\n\nexport default NewMobilePrintsBuilder;\n","import genericHelpers from '../../_utils/generic-helpers';\n\n$(window).on('scroll', genericHelpers.debounce(() => {\n  if ($(document).scrollTop()) {\n    $('html').addClass('scrolled');\n  } else {\n    $('html').removeClass('scrolled');\n  }\n}, 100));\n","// Import Libraries\nimport React from 'react';\nimport ReactDOM from 'react-dom';\n// Import JS files\nimport PrintsBuilder from '../customer_pages/_prints-builder/desktop/prints-builder';\nimport MobilePrintsBuilder from '../customer_pages/_prints-builder/mobile/prints-builder';\nimport NewMobilePrintsBuilder from '../customer_pages/_prints-builder/mobile';\nimport App from '../customer_pages/_application/basket-contents-app';\nimport 'Utils/login-launcher';\nimport '../customer_pages/_prints-builder/common/debounced-scroll-handler';\nimport '../customer_pages/_application/iframe-login';\nimport '../customer_pages/_application/menu-analytics';\n\n// Define App: moved from slim file\nwindow.App = App;\n\n// N.B This implementation is moved from show.html.slim file\nif (bootstrapSize.isBootstrapXS() || bootstrapSize.isBootstrapSM()) {\n  // Render Mobile Prints Builder Page\n\n  if (\n    window.features?.testNewMobilePrintsBuilder || (\n      window.features?.displayNewMobilePrintsBuilder &&\n        window.splitAbTests?.mobile_prints_builder ===\n          'display_new_mobile_prints_builder'\n        )\n  ) {\n    ReactDOM.render(\n      <NewMobilePrintsBuilder\n        urls={window.urls}\n        features={window.features}\n        initSessionTimeout={window.initSessionTimeout}\n        uploadFromGalleryListenerUrl={window.uploadFromGalleryListenerUrl}\n      />,\n      document.getElementById('content')\n    );\n  } else {\n    ReactDOM.render(\n      <MobilePrintsBuilder\n        urls={window.urls}\n        features={window.features}\n        initSessionTimeout={window.initSessionTimeout}\n        uploadFromGalleryListenerUrl={window.uploadFromGalleryListenerUrl}\n      />,\n      document.getElementById('content')\n    );\n  }\n} else {\n  // Render Default Prints Builder Page\n  ReactDOM.render(\n    <PrintsBuilder\n      urls={window.urls}\n      features={window.features}\n      uploadFromGalleryListenerUrl={window.uploadFromGalleryListenerUrl}\n    />,\n    document.getElementById('content')\n  );\n}\n"],"names":["AddPhotosDevice","onClick","buttonClassName","React","PropTypes","isObject","obj","priceMap","props","propName","componentName","error","allValid","list","validator","item","priceList","allOfType","expectedType","CoercedSelectValue","productOption","PhotoDimensions","UploadedPhoto","DeliveryOption","PrintFinish","PrintSize","PrintsBuilderUrlsShape","PandaViewSimplePreview","PandaView","DPILevels","parseDpi","photoDpi","aboveRecommendedDpi","dpi","aboveMinimumDpi","DpiNotices","DpiNoticeTooltips","DpiNotice","noText","tooltipPosition","tooltipCSSClasses","recommendedPrintSize","hideTooltip","isAboveMinimum","dpiNotice","dpiCssClass","noticeContent","classNames","NoticeTooltipOnHover","PhotoDpiNotice","size_area","raw_dimensions","IU","PandaViewSimplePreviews","thumbUrl","rawDimensions","isWallet","showSize","size","quantity","showQuantity","showLowQualityWarning","crop","lowQualityInformationPosition","lowQualityInformationCSSClasses","hideLowQualityInformationTooltip","Spinner","orientation","preview","ListViewItemPreviewAndControls","Component","photo","uploaded","fromBasket","rootImageId","key","isLastPhoto","builderDispatch","UpdatePhotoEvents","imageId","displayRootImageOnly","area","filename","handleEdit","handleRemove","ListQuantityFieldHandlers","add","update","remove","photoIds","sizeQuantity","reducePhotoQuantity","memo","newProps","e","value","WrappedComponent","LONG_TOUCH_INTERVAL","intervalID","handleTouchStart","event","handleTouchEnd","Button","inputID","ariaLabel","className","disabled","max","min","children","handleInputSelect","handleInputFocus","handleDecrementClick","onChange","currentValue","handleIncrementClick","isValidNumber","val","number","NumberInputField","noButtons","label","propValue","id","inputClassName","inputValue","setInputValue","useState","handleChange","useCallback","handleBlur","inputValueNotBlank","useEffect","QuantityButton","RecommendedPrintSizeBadge","ItemSize","rootId","sizeKey","title","options","price","handleFormSubmit","handleQuantityChange","inputId","isRecommended","Currency","ItemSize$1","PhotoModifications","photos","source","keys","increaseBy","resetPhotoEdits","urlRegexp","PhotoFilename","output","PORTRAIT","LANDSCAPE","EXCLUDED_PRINT_SIZE_TITLES","aspectRatio","x","y","ratio","aspectRatioDelta","a","b","findRecommendedPrintSize","sizes","photoAspectRatio","availableSizes","closestAspectRatioDelta","sizeAspectRatio","bestFitSizes","baseNumberOfSizesToShow","secondNumberOfSizesToShow","subsequentPagesOfSizesToShow","DEFAULT_DIMENSIONS","printSizeListEqual","listA","listB","o","i","PhotosListItem","__publicField","prevNumberOfSizesToShow","prevProps","previousSizes","firstSizeKey","sizeWithRawDimensions","sizePhotos","numberOfSizesToShow","previews","moreFewerButtonToggleLabel","printSizeList","$previews","array","ALL_PHOTOS_KEY","sizeHasPrints","sizeHasRootImage","imageID","sizeHasPhotos","stripZeroQuantityPhotosFromSize","defaultSize","individual","collection","fromCollection","SizeHelpers","allPhotos","allPhotosCollectedByRootImage","acc","sizeId","photoRootIds","fromPhotoCollecton","QuantityHelpers","deliveryOption","fallback","quantityForSize","priceBreaks","prices","priceBreak","sizesWithPrints","sizesWithRootImage","priceAtQuantityForSize","fallbackToQuantityOfOne","totalPrice","totalQuantity","sizesWithPrice","availableSize","currentSize","PhotosList","screenAndStyle","items","page","previousState","sizesAndPrice","rootIds","paginatedRootIds","totalPageCount","allPhotosByRootImage","Paginator","SummaryTable","createReactClass","genericHelpers","Totaliser","buttonText","DropDown","Table","fireTrackingEvent","type","translate","AddToCartControls","basketUrl","enabled","onAddToCart","handleAddToCart","sendToGoogleAnalytics","WebUI","ProgressButton","ShallowComparatorMixin","nextProps","nextState","UploadProgressBar","index","percent","$body","RadioButtonGroup","radioButtonsTitle","option","attrDisabled","target","finishValue","finish","finishKeys","finishKey","availableFinishOptions","finishes","calculateSelectedFinish","deliveryOptionKey","finishesByDeliveryOption","availableFinishKeys","delivery","availableDeliveryOptionsForFinish","deliveryOptions","selectedFinish","useMobileTitle","f","selectedDeliveryOption","addSelectedAttributeToOptions","selectedValue","handleDeliveryChange","handleFinishChange","handleShowAllPrices","Options","showAllPricesLink","hidePrintFinishes","RadioButtons","DESKTOP_CONTINUE_MSG","MOBILE_CONTINUE_MSG","InvalidSizesModal","invalidSizes","setInvalidSizes","isOpen","handleIsOpen","onContinue","setOnContinueCallback","builderDispatchToken","payload","openModal","closeModal","handleOnContinue","invalidOptions","_b","_a","Modal","InvalidDeliveryOptionModal","nextDeliveryOption","printFinish","ReactDOM","PhotoRemoveConfirmationModal","onRemove","onClose","PhotoRemoveConfirmation","jsonDataURL","baseURL","Store","jsonDataURLWalmart","jsonDataURLGeneric","finishParam","parseQueryString","excludedFinishes","ITEM_TYPE_PRINT","PREFIX","ViewingSizeKey","viewingSizeKey","border","typeKey","borderKey","keysArr","arr","currentKey","properties","PHOTO_ATTRIBUTES","PrintsBuilderMixin","RemoveSizeEvents","DefaultsEvents","that","xhr","data","defaultSizeParam","defaultFinishParam","defaultDeliveryOption","availableFinishesByDeliveryOption","generateAvailableFinishesByDeliveryOption","initialFinish","initialDeliveryOption","param","initialFinishName","delivery_option","loopCounter","availableFinishes","deliveryOptionIndex","delivery_option_id","prints","validFinishNames","print","sizeHash","regex","p","invalidDeliveryOptionSelected","initialSize","nextAvailableDeliveryOption","total","fallbackToRootImageIdOrOriginalImageId","s","targetSizeKey","selectPhotoImageIds","photoSizes","selectedPhotosToMove","flatMap","targetFinish","dupeIndex","deleted","keyWithoutFinish","invalidKeySizes","validSizesWithPrints","invalidSizeKeys","invalidSizeKey","updatedPhotos","save","updatedPhoto","name","allSizes","cloneDeep","size_id","image_id","sourceSize","targetSize","photoModifications","targetPhoto","toBeDeleted","newTargetSizeKey","sourceSizeKey","rootImageIdOrIds","sourcePhotos","newPhoto","sourcePhoto","newPhotoImageId","imageIdOrIds","selectedPhotoId","removed","onComplete","buildSizeData","photosWithNoQuantity","setIdsOfNewItem","newItem","printFilter","buildPhotoData","what","modified","callback","PrintsBuilderPhotoAlbumDirectLoader","uploadUrl","onBegunUploading","onUploaded","onDone","userPhotosIds","formData","response","url","perform","firstRun","image","failures","$modal","BSOverlay","handleIgnore","Failures","handleRetry","failure","UploadPhotosMixin","currentlyLoading","additionalOptions","LoaderAdditionalOptions","PrismUI","preloadImage","onPreloadSuccess","onPreloadFail","attemptIndex","successCallback","failureCallback","fetchImage","resizeCorpulentImage","w","h","canvas","ctx","blob","src","pushIntoFirstAvailablePhotoPlaceHolder","incrementCurrentlyLoadingIndex","indicativeKey","newValue","number_of_files","number_of_errors","message","finaliseIntervalID","showWarningMessage","objEach","_pricingTablePriceBreak","_pricingTableRow","productsOfSize","productsPricesOfSize","_productPricesToPricingTablePrices","productPrices","_bestPricesOfProducts","products","bestPrices","product","pricingTableData","allProducts","allProductsBySize","PricingChartPopup","matches","finishesForDeliveryOptions","availableDeliveryOption","delOpt","code","finishesForDeliveryOption","finishTitles","oblongPrints","squarePrints","FocusTrap","el","PricesTable","uniformQuantityForPhotosOrBlank","initialValue","BulkQuantityChangeSize","labelID","BulkQuantityChangeSize$1","BulkQuantityChange","showAllSizes","setShowAllSizes","isMobile","handleShowMoreSizesClick","moreButton","SummaryChart","LoadingPhotoPlaceholders","remainingUploads","_","RawImageCache","generation","find","fetch","newList","_CropperConvert","scale","width","height","v","CropperConvert","MARGIN_LOW","ZERO","snapCropToBounds","MAXIMAL_ZOOM","MODES","DEFAULT_MODE","EDIT_HEADER_TITLES","INITIAL_MIN_ZOOM","imgHelpers","zoomHelpers","AdvancedEditorController","extractPhotoData","photoData","values","resolve","urlProp","photoUrl","gamma","effect","sliderData","promises","FILTER_EFFECTS_OPTIONS","effectUrls","urls","cancelDidChange","canvasData","open","previousDidChange","updateProcessedPhotoImageSrc","onlyColorChanged","viewport","imageSrc","newStraightenValue","angle","newBrightnessValue","editMode","element","handlers","refs","editorProps","MobileFullScreen","ImageCropper","style","curCrop","handleCropperZoom","handleCrop","cropperRef","CropperWrapper","Cropper","NUMBER_OF_TICKS","TICK_INCREMENT_PC","SliderScale","setRef","TICK_SEQUENCE","inc","majorIncrement","SliderControl","threshold","sliderRef","hideLabel","step","MananaSlider","FilterButtons","selectedLabel","selected","Navigation","handleApply","close","handleReset","SliderControlsPanel","zoomSliderRef","tiltSliderRef","brightnessSliderRef","initialZoom","handleZoom","handleStraighten","handleBrightness","handleRotate","handleEffect","Filters","handleEditMode","ACTIVE_BTN_POSITION","EditButtons","MODE","orderableButtons","orderableEditButtons","activeEditBtn","photoEditsCurrentValues","ROTATE","CROP","BRIGHTNESS","STRAIGHTEN","FILTERS","mode","DisplayEditValue","hideValue","sliderOffset","right","startOffset","startPos","offsetLeft","distance","percentage","percentageAsValue","scrollLeft","sliderActive","valueAsPercentage","sliderValue","sliderDisplayValue","SliderAndButtonsPanel","filtersEnabled","filtersCss","controlsCss","sliderAttributes","currentSlider","Header","ImageEditPreview","AdvancedEditor","showCropper","orientationMessage","getViewport","cropperDimensions","OrientationMessage","AdvancedEditor$1","WithViewportSize","PrintFinishTabs","ButtonRibbon","active","href","PrintsBuilder","$pricingChartPopup","pricesPopup","ready","hasPhotos","sizesByFinish","allowMultiplePrintFinishesPerOrder","SiteLogo","Login","ref","FullScreenSpinner","selectedSizeKey","relevantPhoto","tmpPhoto","FinishSelector","Select","DeliverySelector","PhotosFilter","func","Utils","onResize","PendingPhoto","onAdvancedEdit","handleRemoveByRootId","EditablePhotoButtons","EditablePhoto","Photo","onAdvancedEditPhoto","photoComponent","isSelected","layoutProps","DEFAULT_PAGE_SIZE","usePagination","itemsPerPage","setPage","paginate","handleGoToPage","handlePageNext","prevPage","handlePagePrevious","PrintCountDisplay","selectedCount","totalCount","text","hideTotal","QuantityInput","onQuantityChange","internalValue","setInternalValue","handleInputChange","handleQuantityUpdate","quantityValue","quantityNumber","handleKeyDown","SideMenu","handleResizeOptionsModal","renderSizeButton","photoDimensions","isDisabled","ResizeOptionsModal","showResizeOptionsModal","Footer","modalType","PhotosGrid","orderedPhotos","handleAddPhotos","recommendedPrintSizes","findAllRecommendedPrintSizes","totalPhotosLength","paginatedItems","defaultSelectedPhoto","selectedPhotoRef","useRef","selectedModal","setSelectedModal","selectedPhoto","photosCollection","addSize","handleCloseModal","handleSizeChange","modalOptions","pluralize","photosById","getSizesByFinish","sortedAndFilteredImages","photoArray","filterBySize","idArray","aIndex","bIndex","MobilePrintsBuilder","orderedPhotosLength","vh","initSessionTimeout","startSessionTimeout","PrintSizeFilter","generateSizeOptionLabel","SimpleThumbnail","MultiSelectModal","handleShowMultiSelectModal","multiSelectItemsCount","maximumSelected","showMultiSelectModal","handleMultiSelectAll","handleMultiUnSelectAll","handleMultiDelete","handleMultiResize","bulkSelectText","handleBulkSelect","useMultiSelect","isActive","multiSelectPhotos","setMultiSelectPhotos","emptySelectedItems","uniqueKey","handleMultiSelectItem","photoKey","isMultiSelected","photoImageId","PreviewBadges","handleOnClick","viewingSizeSelected","ClassNames","PHOTOS_PER_PAGE","PhotoListView","handleSinglePhotoSelection","hideSummaryDropdown","setShowResizeModal","showPhotoRemoveConfirmation","setShowPhotoRemoveConfirmation","multiselectPhotos","displayedPhotos","photoRemoveConfirmationText","prevResizeOptionsModal","handlePhotoRemoveModal","prevShowPhotoRemoveConfirmation","handlePhotoRemoval","OptionsWrapper","finishWrapper","disabledOptions","blockingOption","disabledOptionLabels","disabledOptionMessage","displayDisabledOption","titleOption","ButtonOptions","finishSelectorOptions","deliverySelectorOptions","selectedFinishOption","useContext","SummaryDropdownContext","joinOptionLabel","ButtonOption","thumbnailClass","DropdownOptions","CustomUniversalSelect","createContext","OPTIONS_LIMIT","SummaryDropdown","addToCartEnabled","handleOptionsChanged","displayOptionsAsDropdowns","SizeOptionsMode","PhotoSelectionView","nextPhoto","setSelectedPhotoId","selectedPhotoAssociatedPhotos","sizeOptionsMode","currentPhotoIndex","prevPhoto","currentSizeIndex","prevSizePhoto","nextSizePhoto","ScrollToTopBtn","showBtn","btnClass","WithGestureActions","backGesture","defaultBackBtnActionDisabled","disableGestureActions","backGestureTriggerDistance","start","end","handleMouseDown","handleMouseUp","handleBackButtonPress","backGestureTriggered","handleBackGesture","NewMobilePrintsBuilder","showScrollToTopBtn","hasPrints","showGalleryView","photosLength","hasSelectedPhotoId","displayAddPhotos","prevState","scrollOffsetHeight","scrollTop","photoId","App","_c"],"mappings":"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"}