{
  "version": 3,
  "sources": ["/cdn/shop/t/68/assets/component-cart-items.js?cb=1791266025"],
  "sourcesContent": ["import { Component } from '@theme/component';\nimport {\n  fetchConfig,\n  debounce,\n  onAnimationEnd,\n  prefersReducedMotion,\n  resetShimmer,\n  startViewTransition,\n} from '@theme/utilities';\nimport { morphSection, sectionRenderer } from '@theme/section-renderer';\nimport { ThemeEvents, QuantitySelectorUpdateEvent, CartSectionRestoredEvent } from '@theme/events';\nimport { cartPerformance } from '@theme/performance';\nimport {\n  createViewEventElement,\n  CartErrorEvent,\n  CartDiscountUpdateEvent,\n  CartLinesUpdateEvent,\n  CartNoteUpdateEvent,\n  StandardEvents,\n} from '@shopify/events';\n\n/** @typedef {import('./utilities').TextComponent} TextComponent */\n\n/**\n * A custom element that displays a cart items component.\n *\n * @typedef {object} Refs\n * @property {HTMLElement[]} quantitySelectors - The quantity selector elements.\n * @property {HTMLTableRowElement[]} cartItemRows - The cart item rows.\n * @property {TextComponent} cartTotal - The cart total.\n *\n * @extends {Component<Refs>}\n */\nexport class CartItemsComponent extends createViewEventElement(Component) {\n  /** @type {Set<Promise<void>>} */\n  static #pendingQuantityUpdates = new Set();\n\n  /**\n   * Includes quantity mutations, their section renders, and control cleanup across all cart instances.\n   * @returns {ReadonlyArray<Promise<void>>} A snapshot that cannot modify the shared pending set.\n   */\n  static get pendingQuantityUpdates() {\n    return Array.from(CartItemsComponent.#pendingQuantityUpdates);\n  }\n\n  #debouncedOnChange = debounce(\n    /** @param {Event} event */\n    (event) => {\n      if (event instanceof QuantitySelectorUpdateEvent) this.#onQuantityChange(event);\n    },\n    300\n  );\n  /** @type {Promise<any> | null} */\n  #pendingCartFetch = null;\n\n  // AYUNEL OVERRIDE 2026-10-03, cart audit: an uncertain mutation must be checked before further line/checkout actions.\n  #cartNeedsConfirmation = false;\n  #cartErrorMessage = '';\n\n  updatedCallback() {\n    super.updatedCallback();\n    // Gift/points refreshes morph this subtree too: retain the failure notice and the offline lock.\n    if (this.#cartErrorMessage) this.#renderCartError();\n  }\n\n  /** @param {string} message */\n  async #recoverCartError(message) {\n    let restored = false;\n    try {\n      await this.#renderConfirmedCartSection();\n      restored = true;\n    } catch {\n      // Keep the last confirmed rows visible; never retry the mutation after a lost response.\n    }\n    this.#cartNeedsConfirmation = !restored;\n    this.#cartErrorMessage = message || '\u30AB\u30FC\u30C8\u306E\u66F4\u65B0\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30AB\u30FC\u30C8\u3067\u5185\u5BB9\u3092\u3054\u78BA\u8A8D\u304F\u3060\u3055\u3044\u3002';\n    this.#renderCartError();\n  }\n\n  /**\n   * Confirm that a fresh section was accepted and applied by the shared renderer.\n   * A cancelled render may return an empty string or unused HTML; neither confirms\n   * the row indices currently on screen. Validate before morphing error-page HTML.\n   * @param {{ injectStylesheet?: boolean }} [options]\n   */\n  async #renderConfirmedCartSection(options = {}) {\n    let accepted = false;\n    const sectionId = this.sectionId;\n    const html = await sectionRenderer.renderSection(sectionId, {\n      cache: false,\n      mode: this.isDrawer ? 'hydration' : 'full',\n      ...options,\n      shouldRender: (sectionHTML) => {\n        const sectionDocument = new DOMParser().parseFromString(sectionHTML, 'text/html');\n        if (!sectionDocument.getElementById(`shopify-section-${sectionId}`)) {\n          throw new Error('Cart section missing from recovery response');\n        }\n        accepted = true;\n        return true;\n      },\n    });\n    if (!html || !accepted) throw new Error('Cart recovery was cancelled before render');\n    this.#updateCartQuantitySelectorButtonStates();\n  }\n\n  #renderCartError() {\n    if (this.#cartNeedsConfirmation) {\n      for (const control of /** @type {NodeListOf<HTMLInputElement | HTMLButtonElement>} */ (this.querySelectorAll('button, input'))) {\n        control.disabled = true;\n      }\n    }\n    this.querySelector('[data-ayunel-cart-error]')?.remove();\n    const error = document.createElement('p');\n    error.dataset.ayunelCartError = '';\n    error.className = 'cart-item__error cart-primary-typography';\n    error.setAttribute('role', 'alert');\n    error.textContent = this.#cartErrorMessage;\n    const link = document.createElement('a');\n    link.href = Theme.routes.cart_url;\n    link.textContent = '\u30AB\u30FC\u30C8\u3092\u78BA\u8A8D\u3059\u308B';\n    link.className = 'button button-secondary';\n    error.appendChild(link);\n    this.prepend(error);\n  }\n\n  /**\n   * True when the event was dispatched from outside this cart-items-component (e.g.\n   * `Shopify.actions.updateCart(...)` from an external app, or the SFAPI default\n   * handler). Internal dispatchers (cart-discount-component, cart-note) live inside\n   * `this` and either morph the section themselves or don't need a refresh \u2014 running\n   * a fallback render in that case double-renders and can clobber form state.\n   * @param {Event} event\n   */\n  #isExternalCartUpdate(event) {\n    return !(event.target instanceof Node) || !this.contains(event.target);\n  }\n\n  /**\n   * Refreshes this section when a cart AJAX response cannot include rendered section HTML.\n   * @param {Object} [options] - Additional section morph options.\n   * @param {boolean} [options.injectStylesheet]\n   */\n  async #refreshCartSection(options = {}) {\n    try {\n      await this.#renderConfirmedCartSection(options);\n      return true;\n    } catch (error) {\n      // The mutation can already have succeeded. Its old line numbers are now\n      // unsafe even if this GET was aborted; do not unlock or replay the POST.\n      this.#cartNeedsConfirmation = true;\n      this.#cartErrorMessage = '\u30AB\u30FC\u30C8\u306E\u66F4\u65B0\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30AB\u30FC\u30C8\u3067\u5185\u5BB9\u3092\u3054\u78BA\u8A8D\u304F\u3060\u3055\u3044\u3002';\n      this.#renderCartError();\n      this.dispatchEvent(\n        new CartErrorEvent({\n          error: error?.message || 'Failed to refresh cart',\n          code: 'SERVICE_UNAVAILABLE',\n        })\n      );\n      return false;\n    }\n  }\n\n  /** @param {CartDiscountUpdateEvent} event */\n  #handleDiscountUpdate = (event) => {\n    const isExternalCartUpdate = this.#isExternalCartUpdate(event);\n\n    event.promise\n      ?.then(({ detail }) => {\n        if (!isExternalCartUpdate) return;\n\n        const sectionsHtml = detail?.sections?.[this.sectionId];\n        if (sectionsHtml) {\n          sectionRenderer.abortRender(this.sectionId);\n          morphSection(this.sectionId, sectionsHtml, { mode: this.isDrawer ? 'hydration' : 'full' });\n          this.#updateCartQuantitySelectorButtonStates();\n        } else {\n          // External caller (Shopify.actions.updateCart or SFAPI default handler) didn't\n          // attach sections; refetch so the discount UI reflects the post-mutation cart.\n          this.#refreshCartSection();\n        }\n      })\n      .catch((error) => {\n        if (error?.name !== 'AbortError') console.warn('[cart-items] Event promise rejected:', error);\n      });\n  };\n\n  /** @param {CartNoteUpdateEvent} event */\n  #handleNoteUpdate = (event) => {\n    // Internal cart-note dispatches don't need a section refresh \u2014 the user typed the\n    // value and the textarea retains it. Only external callers need the UI synced.\n    if (!this.#isExternalCartUpdate(event)) return;\n    event.promise\n      ?.then(({ detail }) => {\n        const sections = /** @type {Record<string, string> | undefined} */ (detail?.sections);\n        const sectionsHtml = sections?.[this.sectionId];\n        if (sectionsHtml) {\n          sectionRenderer.abortRender(this.sectionId);\n          morphSection(this.sectionId, sectionsHtml, { mode: this.isDrawer ? 'hydration' : 'full' });\n        } else {\n          this.#refreshCartSection();\n        }\n      })\n      .catch((error) => {\n        if (error?.name !== 'AbortError') console.warn('[cart-items] Event promise rejected:', error);\n      });\n  };\n\n  connectedCallback() {\n    super.connectedCallback();\n\n    document.addEventListener(StandardEvents.cartLinesUpdate, this.#handleCartUpdate);\n    document.addEventListener(ThemeEvents.quantitySelectorUpdate, this.#debouncedOnChange);\n    document.addEventListener(StandardEvents.cartDiscountUpdate, this.#handleDiscountUpdate);\n    document.addEventListener(StandardEvents.cartNoteUpdate, this.#handleNoteUpdate);\n    window.addEventListener('pageshow', this.#handlePageShow);\n  }\n\n  disconnectedCallback() {\n    super.disconnectedCallback();\n\n    document.removeEventListener(StandardEvents.cartLinesUpdate, this.#handleCartUpdate);\n    document.removeEventListener(ThemeEvents.quantitySelectorUpdate, this.#debouncedOnChange);\n    document.removeEventListener(StandardEvents.cartDiscountUpdate, this.#handleDiscountUpdate);\n    document.removeEventListener(StandardEvents.cartNoteUpdate, this.#handleNoteUpdate);\n    window.removeEventListener('pageshow', this.#handlePageShow);\n  }\n\n  /**\n   * Re-renders the cart section when the page is restored from the back/forward cache.\n   *\n   * A restored page replays a frozen DOM, so the line items still show whatever the cart\n   * held before the shopper navigated away. `cart-icon.js` self-corrects its count bubble\n   * on this same event, which is why the bubble and the cart body disagree until a reload.\n   *\n   * `persisted` alone does not cover Chrome. Chrome refuses the bfcache for any document holding\n   * the Sign in with Shop iframe, `/services/login_with_shop/authorize` inside the shadow root of\n   * `shopify-account > shop-login`, and every product page carries one. A shopper's Back there\n   * rebuilds the document from the HTTP disk cache instead: `persisted` is false and the frozen\n   * cart markup renders anyway. Only the navigation entry separates that from an ordinary page\n   * view, so it is the second channel. Safari and Firefox do restore the same page and arrive\n   * through `persisted`. Measured on os3 across all three browsers, 2026-09-03.\n   *\n   * Both channels are still needed. A restored document keeps its ORIGINAL navigation entry in\n   * Chrome and Safari, reporting `navigate`, so `back_forward` alone would miss every real\n   * restore. And `pageshow` fires after `load` on every ordinary navigation, so dropping both\n   * guards would put a section fetch on every page view.\n   *\n   * @param {PageTransitionEvent} event\n   */\n  #handlePageShow = (event) => {\n    const navigationEntry = globalThis.performance?.getEntriesByType?.('navigation')[0];\n    const navigationType = CartItemsComponent.#isNavigationTiming(navigationEntry) ? navigationEntry.type : undefined;\n    if (!event.persisted && navigationType !== 'back_forward') return;\n    // `section_id` is optional in `snippets/cart-items-component.liquid` and the `sectionId`\n    // getter throws without it. Every other caller reads it inside a promise chain that\n    // already has a catch; this one runs straight off a window listener, so it would escape.\n    if (!this.dataset.sectionId) return;\n\n    // `cache: false` on both paths. A bfcache restore never fires `load`, so the renderer's cache\n    // still holds the pre-navigation copy. A disk-cache Back does fire `load` and seeds the cache\n    // from the stale document it just rebuilt. Either way the cached copy is the same stale HTML\n    // the DOM already shows.\n    sectionRenderer\n      .renderSection(this.sectionId, {\n        cache: false,\n        mode: this.isDrawer ? 'hydration' : 'full',\n        // Empty \u2192 non-empty adds the cart summary markup, which carries its own stylesheet.\n        injectStylesheet: this.isDrawer && this.querySelector('[data-cart-drawer-empty]') !== null,\n      })\n      .then(() => {\n        // Morph swaps the quantity selectors in place, so they never reconnect and their\n        // min/max button states stay bound to the pre-restore quantities. A line restored to its\n        // minimum would otherwise keep minus enabled: a wrong affordance and a wasted cart mutation.\n        this.#updateCartQuantitySelectorButtonStates();\n        // No drawer-open event fires on a restore, so the sticky summary measurement has to\n        // be driven from here. `cart-drawer-component` listens for this.\n        this.dispatchEvent(new CartSectionRestoredEvent());\n      })\n      .catch((error) => {\n        if (error?.name !== 'AbortError') console.warn('[cart-items] bfcache restore render failed:', error);\n      });\n  };\n\n  /**\n   * Handles QuantitySelectorUpdateEvent change event.\n   * @param {QuantitySelectorUpdateEvent} event - The event.\n   */\n  #onQuantityChange(event) {\n    if (!(event.target instanceof Node) || !this.contains(event.target)) return;\n\n    const { quantity, cartLine: line } = event.detail;\n\n    // Cart items require a line number\n    if (!line) return;\n\n    if (quantity === 0) {\n      return this.onLineItemRemove(line);\n    }\n\n    this.updateQuantity({\n      line,\n      quantity,\n      action: 'change',\n    });\n    const lineItemRow = this.refs.cartItemRows[line - 1];\n\n    if (!lineItemRow) return;\n\n    const textComponent = /** @type {TextComponent | undefined} */ (lineItemRow.querySelector('text-component'));\n    textComponent?.shimmer();\n  }\n\n  /**\n   * Handles the line item removal.\n   * @param {number} line - The line item index.\n   */\n  onLineItemRemove(line) {\n    this.updateQuantity({\n      line,\n      quantity: 0,\n      action: 'clear',\n    });\n\n    // AYUNEL OVERRIDE 2026-10-03: keep confirmed rows while pending; successful server sections remove them.\n    // The native optimistic empty/remove paths erased rows even when the request failed (including the final item).\n  }\n\n  /**\n   * Updates the quantity.\n   * @param {Object} config - The config.\n   * @param {number} config.line - The line.\n   * @param {number} config.quantity - The quantity.\n   * @param {string} config.action - The action.\n   */\n  async updateQuantity(config) {\n    if (this.#cartNeedsConfirmation) return;\n    this.#cartErrorMessage = '';\n    this.querySelector('[data-ayunel-cart-error]')?.remove();\n    const cartPerformaceUpdateMarker = cartPerformance.createStartingMarker(`${config.action}:user-action`);\n    const deferredUpdatePromise = CartLinesUpdateEvent.createPromise();\n    let completeQuantityUpdate = () => {};\n    /** @type {Promise<void>} */\n    const quantityUpdate = new Promise((resolve) => {\n      completeQuantityUpdate = () => resolve();\n    });\n    CartItemsComponent.#pendingQuantityUpdates.add(quantityUpdate);\n\n    try {\n      this.#disableCartItems();\n\n      const { line, quantity } = config;\n      const { cartTotal } = this.refs;\n\n      const cartItemsComponents = document.querySelectorAll('cart-items-component');\n      const sectionsToUpdate = new Set([this.sectionId]);\n      for (const item of cartItemsComponents) {\n        if (item instanceof HTMLElement && item.dataset.sectionId) {\n          sectionsToUpdate.add(item.dataset.sectionId);\n        }\n      }\n\n      for (const sectionId of sectionsToUpdate) {\n        sectionRenderer.abortRender(sectionId);\n      }\n\n      const body = JSON.stringify({\n        line: line,\n        quantity: quantity,\n        sections: Array.from(sectionsToUpdate).join(','),\n        sections_url: window.location.pathname,\n      });\n\n      cartTotal?.shimmer();\n\n      const lineId = this.refs.cartItemRows[line - 1]?.dataset.key ?? '';\n      this.dispatchEvent(\n        new CartLinesUpdateEvent({\n          action: config.action === 'change' && quantity > 0 ? 'update' : 'remove',\n          context: 'cart',\n          lines: [{ id: lineId, quantity }],\n          promise: deferredUpdatePromise.promise,\n        })\n      );\n\n      const response = await fetch(`${Theme.routes.cart_change_url}`, fetchConfig('json', { body }));\n      const responseText = await response.text();\n      const parsedResponseText = JSON.parse(responseText);\n      if (!response.ok && !parsedResponseText.errors) throw new Error(`Cart update HTTP ${response.status}`);\n\n      resetShimmer(this);\n\n      if (parsedResponseText.errors) {\n        this.dispatchEvent(new CartErrorEvent({ error: parsedResponseText.errors, code: 'INVALID' }));\n        await this.#recoverCartError(parsedResponseText.errors);\n        deferredUpdatePromise.reject(new Error(parsedResponseText.errors));\n        return;\n      }\n\n      const sections = /** @type {Record<string, string> | null | undefined} */ (parsedResponseText.sections);\n      const sectionHTML = sections?.[this.sectionId];\n      const parsedItemCount = Number(parsedResponseText.item_count);\n      let newCartItemCount = Number.isFinite(parsedItemCount) ? parsedItemCount : 0;\n\n      // Update data-cart-quantity for all matching variants\n      this.#updateQuantitySelectors(parsedResponseText);\n\n      if (!sectionHTML) {\n        deferredUpdatePromise.resolve({\n          cart: CartLinesUpdateEvent.createCartFromAjaxResponse(parsedResponseText),\n          detail: {\n            sections: sections ?? undefined,\n            items: parsedResponseText.items,\n            itemCount: newCartItemCount,\n            source: 'cart-items-component',\n            didError: false,\n          },\n        });\n\n        await this.#refreshCartSection();\n        return;\n      }\n\n      const newSectionHTML = new DOMParser().parseFromString(sectionHTML, 'text/html');\n\n      // Grab the new cart item count from a hidden element\n      const newCartHiddenItemCount = newSectionHTML.querySelector('[ref=\"cartItemCount\"]')?.textContent;\n      newCartItemCount = newCartHiddenItemCount ? parseInt(newCartHiddenItemCount, 10) : newCartItemCount;\n\n      deferredUpdatePromise.resolve({\n        cart: CartLinesUpdateEvent.createCartFromAjaxResponse(parsedResponseText),\n        detail: {\n          sections: sections ?? undefined,\n          items: parsedResponseText.items,\n          itemCount: newCartItemCount,\n          source: 'cart-items-component',\n          didError: false,\n        },\n      });\n\n      sectionRenderer.abortRender(this.sectionId);\n      await morphSection(this.sectionId, sectionHTML, {\n        mode: this.isDrawer ? 'hydration' : 'full',\n      });\n\n      this.#updateCartQuantitySelectorButtonStates();\n    } catch (error) {\n      console.error(error);\n      resetShimmer(this);\n      await this.#recoverCartError('\u30AB\u30FC\u30C8\u306E\u66F4\u65B0\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30AB\u30FC\u30C8\u3067\u5185\u5BB9\u3092\u3054\u78BA\u8A8D\u304F\u3060\u3055\u3044\u3002');\n      deferredUpdatePromise.reject(error);\n\n      this.dispatchEvent(\n        new CartErrorEvent({\n          error: error?.message || 'Failed to update cart',\n          code: 'SERVICE_UNAVAILABLE',\n        })\n      );\n    } finally {\n      try {\n        this.#enableCartItems();\n        cartPerformance.measureFromMarker(cartPerformaceUpdateMarker);\n      } finally {\n        CartItemsComponent.#pendingQuantityUpdates.delete(quantityUpdate);\n        completeQuantityUpdate();\n      }\n    }\n  }\n\n  /**\n   * Handles the cart update.\n   *\n   * @param {CartLinesUpdateEvent} event\n   */\n  #handleCartUpdate = (event) => {\n    if (event.target === this) return;\n\n    event.promise\n      ?.then(async ({ detail }) => {\n        const sections = detail?.sections;\n        const cartItemsHtml = sections?.[this.sectionId];\n        // Animate empty \u2192 non-empty in the drawer (possible in squeeze mode\n        // where the page is interactive alongside the open drawer). This also\n        // needs the response stylesheet because it adds the cart summary markup.\n        const wasEmptyCartDrawer = this.isDrawer && this.querySelector('[data-cart-drawer-empty]') !== null;\n        /** @type {'hydration' | 'full'} */\n        const mode = this.isDrawer ? 'hydration' : 'full';\n        const morphOptions = {\n          mode,\n          injectStylesheet: wasEmptyCartDrawer,\n        };\n\n        if (cartItemsHtml) {\n          sectionRenderer.abortRender(this.sectionId);\n          const existingKeys = new Set(this.refs.cartItemRows?.map((row) => row.dataset.key) ?? []);\n\n          if (wasEmptyCartDrawer) {\n            startViewTransition(() => {\n              morphSection(this.sectionId, cartItemsHtml, morphOptions);\n            }, ['fill-cart-drawer']);\n          } else {\n            await morphSection(this.sectionId, cartItemsHtml, morphOptions);\n          }\n\n          // Animate newly added rows (reverse of the remove animation).\n          if (!wasEmptyCartDrawer && !prefersReducedMotion()) {\n            for (const row of this.refs.cartItemRows ?? []) {\n              if (!existingKeys.has(row.dataset.key)) {\n                row.classList.add('adding');\n                onAnimationEnd(row, () => row.classList.remove('adding'));\n              }\n            }\n          }\n\n          // Update button states for all cart quantity selectors after morph\n          this.#updateCartQuantitySelectorButtonStates();\n        } else {\n          this.#refreshCartSection(morphOptions);\n        }\n      })\n      .catch((error) => {\n        if (error?.name !== 'AbortError') console.warn('[cart-items] Event promise rejected:', error);\n      });\n  };\n\n  /**\n   * Disables the cart items.\n   */\n  #disableCartItems() {\n    this.classList.add('cart-items-disabled');\n  }\n\n  /**\n   * Enables the cart items.\n   */\n  #enableCartItems() {\n    this.classList.remove('cart-items-disabled');\n  }\n\n  /**\n   * Updates quantity selectors for all matching variants in the cart.\n   * @param {Object} updatedCart - The updated cart object.\n   * @param {Array<{variant_id: number, quantity: number}>} [updatedCart.items] - The cart items.\n   */\n  #updateQuantitySelectors(updatedCart) {\n    if (!updatedCart.items) return;\n\n    for (const item of updatedCart.items) {\n      const variantId = item.variant_id.toString();\n      const selectors = document.querySelectorAll(`quantity-selector-component[data-variant-id=\"${variantId}\"]`);\n\n      for (const selector of selectors) {\n        const input = selector.querySelector('input[data-cart-quantity]');\n        if (!input) continue;\n\n        input.setAttribute('data-cart-quantity', item.quantity.toString());\n\n        // Update the quantity selector's internal state\n        if ('updateCartQuantity' in selector && typeof selector.updateCartQuantity === 'function') {\n          selector.updateCartQuantity();\n        }\n      }\n    }\n  }\n\n  /**\n   * Updates button states for all cart quantity selector components.\n   */\n  #updateCartQuantitySelectorButtonStates() {\n    for (const selector of document.querySelectorAll('cart-quantity-selector-component')) {\n      /** @type {any} */ (selector).updateButtonStates?.();\n    }\n  }\n\n  async fetchCartData() {\n    if (this.#pendingCartFetch) return this.#pendingCartFetch;\n\n    this.#pendingCartFetch = (async () => {\n      const response = await fetch(`${Theme.routes.cart_url}.json`, {\n        headers: { Accept: 'application/json' },\n        credentials: 'same-origin',\n      });\n      if (!response.ok) throw new Error(`Failed to fetch cart: ${response.status} ${response.statusText}`);\n      const data = await response.json();\n      return data;\n    })().finally(() => {\n      this.#pendingCartFetch = null;\n    });\n\n    return this.#pendingCartFetch;\n  }\n\n  /**\n   * Gets the section id.\n   * @returns {string} The section id.\n   */\n  get sectionId() {\n    const { sectionId } = this.dataset;\n\n    if (!sectionId) throw new Error('Section id missing');\n\n    return sectionId;\n  }\n\n  /**\n   * @returns {boolean} Whether the component is a drawer.\n   */\n  get isDrawer() {\n    return this.dataset.drawer !== undefined;\n  }\n\n  /**\n   * `getEntriesByType` is typed as the `PerformanceEntry` base, which has no `type`, and the DOM\n   * lib has no per-string overload for `'navigation'`. `entryType` is the spec's discriminant and\n   * lives on the base, so this narrows at runtime instead of asserting the way a cast would.\n   *\n   * @param {PerformanceEntry | undefined} entry\n   * @returns {entry is PerformanceNavigationTiming}\n   */\n  static #isNavigationTiming(entry) {\n    return entry?.entryType === 'navigation';\n  }\n}\n\nif (!customElements.get('cart-items-component')) {\n  customElements.define('cart-items-component', CartItemsComponent);\n}\n"],
  "mappings": "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",
  "names": []
}
