{
  "version": 3,
  "sources": ["/cdn/shop/t/5/assets/cart-discount.js?fresh=1779779648853865000"],
  "sourcesContent": ["import { Component } from '@theme/component';\nimport { morphSection } from '@theme/section-renderer';\nimport { DiscountUpdateEvent } from '@theme/events';\nimport { fetchConfig } from '@theme/utilities';\nimport { cartPerformance } from '@theme/performance';\n\n/**\n * A custom element that applies a discount to the cart.\n *\n * @typedef {Object} CartDiscountComponentRefs\n * @property {HTMLElement} cartDiscountError - The error element.\n * @property {HTMLElement} cartDiscountErrorDiscountCode - The discount code error element.\n * @property {HTMLElement} cartDiscountErrorShipping - The shipping error element.\n */\n\n/**\n * @extends {Component<CartDiscountComponentRefs>}\n */\nclass CartDiscount extends Component {\n  requiredRefs = ['cartDiscountError', 'cartDiscountErrorDiscountCode', 'cartDiscountErrorShipping'];\n\n  /** @type {AbortController | null} */\n  #activeFetch = null;\n\n  #createAbortController() {\n    if (this.#activeFetch) {\n      this.#activeFetch.abort();\n    }\n\n    const abortController = new AbortController();\n    this.#activeFetch = abortController;\n    return abortController;\n  }\n\n  /**\n   * Handles updates to the cart note.\n   * @param {SubmitEvent} event - The submit event on our form.\n   */\n  applyDiscount = async (event) => {\n    const { cartDiscountError, cartDiscountErrorDiscountCode, cartDiscountErrorShipping } = this.refs;\n\n    event.preventDefault();\n    event.stopPropagation();\n\n    const form = event.target;\n    if (!(form instanceof HTMLFormElement)) return;\n\n    const discountCode = form.querySelector('input[name=\"discount\"]');\n    if (!(discountCode instanceof HTMLInputElement) || typeof this.dataset.sectionId !== 'string') return;\n\n    const discountCodeValue = discountCode.value;\n\n    const abortController = this.#createAbortController();\n\n    try {\n      const existingDiscounts = this.#existingDiscounts();\n      if (existingDiscounts.includes(discountCodeValue)) return;\n\n      cartDiscountError.classList.add('hidden');\n      cartDiscountErrorDiscountCode.classList.add('hidden');\n      cartDiscountErrorShipping.classList.add('hidden');\n\n      const config = fetchConfig('json', {\n        body: JSON.stringify({\n          discount: [...existingDiscounts, discountCodeValue].join(','),\n          sections: [this.dataset.sectionId],\n        }),\n      });\n\n      const response = await fetch(Theme.routes.cart_update_url, {\n        ...config,\n        signal: abortController.signal,\n      });\n\n      const data = await response.json();\n\n      if (\n        data.discount_codes.find((/** @type {{ code: string; applicable: boolean; }} */ discount) => {\n          return discount.code === discountCodeValue && discount.applicable === false;\n        })\n      ) {\n        discountCode.value = '';\n        this.#handleDiscountError('discount_code');\n        return;\n      }\n\n      const newHtml = data.sections[this.dataset.sectionId];\n      const parsedHtml = new DOMParser().parseFromString(newHtml, 'text/html');\n      const section = parsedHtml.getElementById(`shopify-section-${this.dataset.sectionId}`);\n      const discountCodes = section?.querySelectorAll('.cart-discount__pill') || [];\n      if (section) {\n        const codes = Array.from(discountCodes)\n          .map((element) => (element instanceof HTMLLIElement ? element.dataset.discountCode : null))\n          .filter(Boolean);\n        // Before morphing, we need to check if the shipping discount is applicable in the UI\n        // we check the liquid logic compared to the cart payload to assess whether we leveraged\n        // a valid shipping discount code.\n        if (\n          codes.length === existingDiscounts.length &&\n          codes.every((/** @type {string} */ code) => existingDiscounts.includes(code)) &&\n          data.discount_codes.find((/** @type {{ code: string; applicable: boolean; }} */ discount) => {\n            return discount.code === discountCodeValue && discount.applicable === true;\n          })\n        ) {\n          this.#handleDiscountError('shipping');\n          discountCode.value = '';\n          return;\n        }\n      }\n\n      document.dispatchEvent(new DiscountUpdateEvent(data, this.id));\n      morphSection(this.dataset.sectionId, newHtml);\n    } catch (error) {\n    } finally {\n      this.#activeFetch = null;\n      cartPerformance.measureFromEvent('discount-update:user-action', event);\n    }\n  };\n\n  /**\n   * Handles removing a discount from the cart.\n   * @param {MouseEvent | KeyboardEvent} event - The mouse or keyboard event in our pill.\n   */\n  removeDiscount = async (event) => {\n    event.preventDefault();\n    event.stopPropagation();\n\n    if (\n      (event instanceof KeyboardEvent && event.key !== 'Enter') ||\n      !(event instanceof MouseEvent) ||\n      !(event.target instanceof HTMLElement) ||\n      typeof this.dataset.sectionId !== 'string'\n    ) {\n      return;\n    }\n\n    const pill = event.target.closest('.cart-discount__pill');\n    if (!(pill instanceof HTMLLIElement)) return;\n\n    const discountCode = pill.dataset.discountCode;\n    if (!discountCode) return;\n\n    const existingDiscounts = this.#existingDiscounts();\n    const index = existingDiscounts.indexOf(discountCode);\n    if (index === -1) return;\n\n    existingDiscounts.splice(index, 1);\n\n    const abortController = this.#createAbortController();\n\n    try {\n      const config = fetchConfig('json', {\n        body: JSON.stringify({ discount: existingDiscounts.join(','), sections: [this.dataset.sectionId] }),\n      });\n\n      const response = await fetch(Theme.routes.cart_update_url, {\n        ...config,\n        signal: abortController.signal,\n      });\n\n      const data = await response.json();\n\n      document.dispatchEvent(new DiscountUpdateEvent(data, this.id));\n      morphSection(this.dataset.sectionId, data.sections[this.dataset.sectionId]);\n    } catch (error) {\n    } finally {\n      this.#activeFetch = null;\n    }\n  };\n\n  /**\n   * Handles the discount error.\n   *\n   * @param {'discount_code' | 'shipping'} type - The type of discount error.\n   */\n  #handleDiscountError(type) {\n    const { cartDiscountError, cartDiscountErrorDiscountCode, cartDiscountErrorShipping } = this.refs;\n    const target = type === 'discount_code' ? cartDiscountErrorDiscountCode : cartDiscountErrorShipping;\n    cartDiscountError.classList.remove('hidden');\n    target.classList.remove('hidden');\n  }\n\n  /**\n   * Returns an array of existing discount codes.\n   * @returns {string[]}\n   */\n  #existingDiscounts() {\n    /** @type {string[]} */\n    const discountCodes = [];\n    const discountPills = this.querySelectorAll('.cart-discount__pill');\n    for (const pill of discountPills) {\n      if (pill instanceof HTMLLIElement && typeof pill.dataset.discountCode === 'string') {\n        discountCodes.push(pill.dataset.discountCode);\n      }\n    }\n\n    return discountCodes;\n  }\n}\n\nif (!customElements.get('cart-discount-component')) {\n  customElements.define('cart-discount-component', CartDiscount);\n}\n"],
  "mappings": "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",
  "names": []
}
