{"version":3,"file":"build.main-product.min.js","sources":["../src/js/entrypoints/main-product.js"],"sourcesContent":["import log from '~/lib/log';\nimport formatMoney from './format-money';\nimport { Splide } from '@splidejs/splide';\n\nfunction mainProduct(productData = {}) {\n  log.debug('mainProduct FUNCTION CALLED', productData);\n  return {\n    mediaCount: productData.mediaCount || 0,\n    variantId: productData.variantId || null,\n    addToCartText: productData.addToCartText || 'Add to cart',\n    soldOutText: productData.soldOutText || 'Sold out',\n    quantityValue: productData.quantityValue || 1,\n    selectedColor: productData.selectedColor || '',\n    selectedOtherOption: productData.selectedOtherOption || '',\n    selectedVariantTitle: productData.selectedVariantTitle || '',\n    selectedVariantAvailable: productData.selectedVariantAvailable || false,\n    variants: productData.variants || [],\n    colorOptionPosition: productData.colorOptionPosition || 0,\n    otherOptionPosition: productData.otherOptionPosition || 0,\n    selectedColorImage: productData.selectedColorImage || '',\n    selectedColorName: productData.selectedColorName || '',\n    selectedVariant: null,\n\n    init() {\n      log.debug('mainProduct INIT called');\n\n      // Check URL for variant parameter and set initial variant\n      const urlParams = new URLSearchParams(window.location.search);\n      const variantIdFromUrl = urlParams.get('variant');\n\n      if (variantIdFromUrl) {\n        // Find the variant from URL parameter\n        const variantFromUrl = this.variants.find((v) => v.id === parseInt(variantIdFromUrl, 10));\n\n        if (variantFromUrl) {\n          // Set the options based on the URL variant\n          if (this.colorOptionPosition > 0) {\n            this.selectedColor = variantFromUrl.options[this.colorOptionPosition - 1];\n            const colorValue = this.variants.find((v) => v.id === variantFromUrl.id);\n\n            if (colorValue) {\n              // You might need to get the color swatch info here if needed\n            }\n          }\n\n          if (this.otherOptionPosition > 0) {\n            this.selectedOtherOption = variantFromUrl.options[this.otherOptionPosition - 1];\n          }\n        }\n      }\n\n      // Initialize the selected variant on component mount\n      this.updateSelectedVariant();\n\n      // Watch for price changes\n      this.$watch('selectedVariant', (variant) => {\n        if (variant && variant.price) {\n          log.debug('$watch triggered - Variant price changed');\n          // Update URL with variant parameter\n          this.updateUrl();\n        }\n      });\n    },\n\n    updateUrl() {\n      if (this.variantId) {\n        const url = new URL(window.location.href);\n\n        url.searchParams.set('variant', this.variantId);\n        window.history.replaceState({}, '', url);\n      }\n    },\n\n    initSplide() {\n      // Use querySelector since x-ref is in a child snippet\n      // Add a small delay to ensure DOM is ready\n      this.$nextTick(() => {\n        // Try multiple times to find the element in case of slow rendering\n        const findElement = (attempts = 0) => {\n          const element = this.$el.querySelector('.splide');\n\n          if (!element) {\n            if (attempts < 5) {\n              // Retry after a short delay\n              setTimeout(() => findElement(attempts + 1), 100);\n              return;\n            }\n\n            log.warn('Splide element not found after multiple attempts');\n            return;\n          }\n\n          const slideCount = element.querySelectorAll('.splide__slide').length;\n\n          if (slideCount === 0) {\n            log.warn('No slides found in Splide container');\n            return;\n          }\n\n          log.debug(`Found ${slideCount} slides`);\n\n          // Disable slider features if only one slide\n          const isSingleSlide = slideCount === 1;\n\n          // Destroy existing instance if any\n          if (this.splide) {\n            this.splide.destroy();\n          }\n\n          this.splide = new Splide(element, {\n            type: isSingleSlide ? 'slide' : 'loop',\n            perPage: 1,\n            perMove: 1,\n            gap: '1rem',\n            pagination: false,\n            arrows: false,\n            drag: !isSingleSlide, // Disable drag/swipe for single slide\n            swipe: !isSingleSlide, // Disable swipe for single slide\n            wheel: false, // Disable mouse wheel navigation\n            cover: true, // Cover the entire slide area\n            updateOnMove: true, // Update on move for better rendering\n          });\n\n          // After mounting, ensure slides maintain aspect ratio and are visible\n          this.splide.on('mounted', () => {\n            // Make all Splide elements visible\n            const splideElements = element.querySelectorAll('.splide, .splide__track, .splide__list, .splide__slide');\n            splideElements.forEach((el) => {\n              el.style.visibility = 'visible';\n              // Remove any inline height styles that Splide might have added\n              if (el.classList.contains('splide__slide') && el.style.height) {\n                el.style.height = '';\n              }\n            });\n\n            // Ensure images are visible\n            const images = element.querySelectorAll('.splide__slide img');\n            images.forEach((img) => {\n              img.style.visibility = 'visible';\n              img.style.display = 'block';\n            });\n          });\n          this.splide.mount();\n          log.debug('Splide initialized successfully');\n        };\n\n        findElement();\n      });\n    },\n\n    get hasPrevious() {\n      return this.mediaCount > 1;\n    },\n    get hasNext() {\n      return this.mediaCount > 1;\n    },\n\n    goToPrevious() {\n      if (this.splide && this.hasPrevious) {\n        this.splide.go('<');\n      }\n    },\n\n    goToNext() {\n      if (this.splide && this.hasNext) {\n        this.splide.go('>');\n      }\n    },\n\n    selectColor(color = '', image = '', colorName = '') {\n      this.selectedColor = color;\n      this.selectedColorImage = image;\n      this.selectedColorName = colorName;\n\n      // Auto-select first available size/option for this color\n      if (this.otherOptionPosition > 0) {\n        // Find first available variant with this color\n        for (const variant of this.variants) {\n          const variantColor = variant.options[this.colorOptionPosition - 1];\n          if (variantColor === color && variant.available) {\n            // Select the size/option from this variant\n            this.selectedOtherOption = variant.options[this.otherOptionPosition - 1];\n            break;\n          }\n        }\n      }\n\n      // Reset quantity to 1 when variant changes\n      this.quantityValue = 1;\n\n      this.updateSelectedVariant();\n    },\n\n    selectOtherOption(option) {\n      this.selectedOtherOption = option;\n      log.debug('Variants', this.variants);\n      this.selectedUnavailableColor = this.variants.filter((variant) => {\n        const variantColor = variant.options[this.otherOptionPosition - 1];\n        return variantColor === this.selectedOtherOption && !variant.available;\n      });\n\n      // Reset quantity to 1 when variant changes\n      this.quantityValue = 1;\n\n      this.updateSelectedVariant();\n    },\n\n    isOptionAvailable(optionPosition, optionValue) {\n      // Check if this option value is available with the currently selected other options\n      for (const variant of this.variants) {\n        // Check if this variant has the option value we're looking for\n        if (variant.options[optionPosition] !== optionValue) {\n          continue;\n        }\n\n        // Check color option if it exists and is selected\n        if (this.colorOptionPosition > 0 && this.selectedColor) {\n          const colorMatches = variant.options[this.colorOptionPosition - 1] === this.selectedColor;\n          if (!colorMatches) {\n            continue;\n          }\n        }\n\n        // If we found a matching variant that's available, return true\n        if (variant.available) {\n          return true;\n        }\n      }\n\n      // No available variant found with this option value\n      return false;\n    },\n\n    updateSelectedVariant() {\n      // Find the variant that matches the selected options\n      for (const variant of this.variants) {\n        let colorMatches = true;\n        let otherOptionMatches = true;\n\n        // Check color option if it exists\n        if (this.colorOptionPosition > 0) {\n          colorMatches = variant.options[this.colorOptionPosition - 1] === this.selectedColor;\n        }\n\n        // Check other option if it exists\n        if (this.otherOptionPosition > 0) {\n          otherOptionMatches = variant.options[this.otherOptionPosition - 1] === this.selectedOtherOption;\n        }\n\n        // Only match if ALL applicable options match\n        if (colorMatches && otherOptionMatches) {\n          // Create a new object to ensure Alpine reactivity\n          this.selectedVariant = {\n            id: variant.id,\n            title: variant.title,\n            available: variant.available,\n            price: variant.price,\n            compare_at_price: variant.compare_at_price,\n            options: variant.options,\n          };\n          this.variantId = variant.id;\n          this.selectedVariantTitle = variant.title;\n          this.selectedVariantAvailable = variant.available;\n          log.debug('Selected variant:', this.selectedVariant);\n          return;\n        }\n      }\n\n      log.warn('No matching variant found for:', {\n        color: this.selectedColor,\n        otherOption: this.selectedOtherOption,\n      });\n    },\n\n    // Used when multiplying quantity against selected variant price\n    formatMoney(cents) {\n      // Format money using Shopify's money format\n      // Convert cents to dollars with 2 decimal places\n      const dollars = (cents / 100).toFixed(2);\n      // Replace {{amount}} or {{amount_with_comma_separator}} in the format string\n      return formatMoney(dollars) || '';\n    },\n\n  };\n}\n\nfunction imageZoom() {\n  return {\n    scale: 1,\n    panning: false,\n    pointX: 0,\n    pointY: 0,\n    startX: 0,\n    startY: 0,\n    openModal: false,\n\n    updateScale(value) {\n      this.scale = parseFloat(value);\n      if (this.scale <= 1) {\n        this.reset();\n      }\n    },\n\n    startDrag(e) {\n      if (this.scale <= 1) {\n        return;\n      }\n\n      this.panning = true;\n      this.startX = e.clientX || e.touches[0].clientX;\n      this.startY = e.clientY || e.touches[0].clientY;\n\n      // Stop bubbling so Splide doesn't swipe\n      e.stopPropagation();\n    },\n\n    onDrag(e) {\n      if (!this.panning) {\n        return;\n      }\n\n      e.preventDefault();\n      e.stopPropagation();\n\n      const clientX = e.clientX || (e.touches ? e.touches[0].clientX : 0);\n      const clientY = e.clientY || (e.touches ? e.touches[0].clientY : 0);\n\n      const dx = (clientX - this.startX) / this.scale;\n      const dy = (clientY - this.startY) / this.scale;\n\n      this.pointX += dx;\n      this.pointY += dy;\n\n      this.startX = clientX;\n      this.startY = clientY;\n    },\n\n    endDrag() {\n      this.panning = false;\n    },\n\n    reset() {\n      this.scale = 1;\n      this.pointX = 0;\n      this.pointY = 0;\n      this.panning = false;\n    },\n  };\n}\n\n// Make mainProduct and imageZoom available globally for Alpine.js\nwindow.mainProduct = mainProduct;\nwindow.imageZoom = imageZoom;\n\n"],"names":["window","mainProduct","productData","log","debug","prefix","mediaCount","variantId","addToCartText","soldOutText","quantityValue","selectedColor","selectedOtherOption","selectedVariantTitle","selectedVariantAvailable","variants","colorOptionPosition","otherOptionPosition","selectedColorImage","selectedColorName","selectedVariant","init","variantIdFromUrl","URLSearchParams","location","search","get","variantFromUrl","this","find","v","id","parseInt","options","updateSelectedVariant","$watch","variant","price","updateUrl","url","URL","href","searchParams","set","history","replaceState","initSplide","$nextTick","findElement","attempts","element","$el","querySelector","setTimeout","warn","slideCount","querySelectorAll","length","isSingleSlide","splide","destroy","Splide","type","perPage","perMove","gap","pagination","arrows","drag","swipe","wheel","cover","updateOnMove","on","forEach","el","style","visibility","classList","contains","height","img","display","mount","hasPrevious","hasNext","goToPrevious","go","goToNext","selectColor","color","image","colorName","available","selectOtherOption","option","selectedUnavailableColor","filter","isOptionAvailable","optionPosition","optionValue","colorMatches","otherOptionMatches","title","compare_at_price","otherOption","formatMoney","cents","dollars","toFixed","imageZoom","scale","panning","pointX","pointY","startX","startY","openModal","updateScale","value","parseFloat","reset","startDrag","e","clientX","touches","clientY","stopPropagation","onDrag","preventDefault","dx","dy","endDrag"],"mappings":"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"}