PageSourceSearch

https://shopspicydan.com/cdn/shop/t/170/assets/build-a-drip.js?v=137620586018604072201788310659

js shopspicydan.com collected 2026-09-26 04:47:02 UTC 62,877 bytes, 2 lines download raw bytes

1const DEBUG_MODE=!0;function initBuildADrip(){console.log("Build-A-Drip configurator initializing...");function debounce(func,delay){let timeout;return()=>{clearTimeout(timeout),timeout=setTimeout(func,delay)}}window.addEventListener("load",setupAccordions),window.addEventListener("resize",debounce(setupAccordions,200));const container=document.getElementById("build-a-drip-model-viewer"),modelLoader=document.getElementById("model-loader");modelLoader&&(modelLoader.style.display="flex");class BuildADripConfigurator{constructor(){this.modelViewer=document.getElementById("build-a-drip-model-viewer"),this.priceElement=document.getElementById("build-a-drip-price"),this.priceElementMobile=document.getElementById("build-a-drip-price-mobile"),this.addToCartBtn=document.getElementById("add-to-cart"),this.mobileAddToCartBtn=document.querySelector(".mobile-add-to-cart"),this.shareBtn=document.getElementById("share-config"),this.shareBtnMobile=document.getElementById("share-config-mobile"),this.baseColorOptions=document.getElementById("base-color-options"),this.carabinerColorOptions=document.getElementById("carabiner-color-options"),this.charmOptions=document.getElementById("charm-options"),this.mobileOptionsWrapper=document.querySelector(".mobile-options-wrapper"),this.mobileSelectedOptionDetails=document.querySelector(".mobile-selected-option-details"),this.prevBtn=document.querySelector(".prev-btn"),this.nextBtn=document.querySelector(".next-btn"),this.currentStepElement=document.querySelector(".current-step"),this.basePrice=parseFloat(document.querySelector("#build-a-drip-base-price").dataset.price);const buildADripSection=document.getElementById("build-a-drip-container");this.showNoCarabiner=buildADripSection?.dataset.showNoCarabiner==="true",this.currentOptions={beads:null,carabiner:null,charm:null},this.productsData={beads:[],carabiner:[],charm:[]},this.baseType="beads",this.beadProducts=[],this.chainProducts=[],this.currentMobileStep=1,this.totalMobileSteps=4,this.modelLoaded=!1,this.necklaceCarabinerOverrides={sonny:"Carabiner - Gold",sir:"NECKLACE_BEAN001"},this.init()}
1async init(){console.log("BuildADripConfigurator initializing..."),await this.fetchBuildADripProducts(),this.parseUrlParams(),this.renderOptions(),this.setupEventListeners(),console.log("BuildADripConfigurator initialization complete")}async fetchBuildADripProducts(){try{const variantMetafieldsScript=document.getElementById("build-a-drip-variants");let variantMetafields={};if(variantMetafieldsScript)try{variantMetafields=JSON.parse(variantMetafieldsScript.textContent)}catch(e){console.error("Failed to parse variant metafields JSON:",e)}(await(await fetch("/collections/9f31b47a-dc2d-4c3e-b876-a3fc8e7e7e11/products.json")).json()).products.forEach(product=>{const productType=this.getProductType(product);productType&&product.variants.forEach(variant=>{const variantId=String(variant.id),meta=variantMetafields[variantId]||{};if(!(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1")&&(meta.hidden_on_new_site==!0||meta.hidden_on_new_site==="true"))return;const nodeId=meta.node_id||"",colorName=meta.color_name||variant.title,thumbImage=meta.image||(variant.featured_image?variant.featured_image.src:null),otherThumbImage=meta.other_thumb?`https:${meta.other_thumb}`:null,option={id:variant.id,productId:product.id,title:variant.title,colorName,nodeId:this.normalizeNodeId(nodeId),price:parseFloat(variant.price),image:thumbImage,otherThumbImage,available:variant.available,sku:variant.sku};this.productsData[productType].push(option)})}),this.productsData.charm.unshift({id:"no-charm",productId:null,title:"No Charm",colorName:"No Charm",nodeId:null,price:0,image:"https://cdn.shopify.com/s/files/1/0767/9272/5688/files/no-charm.png?v=1743305046",otherThumbImage:null,available:!0,sku:null}),this.showNoCarabiner&&this.productsData.carabiner.unshift({id:"no-carabiner",productId:null,title:"No Carabiner",colorName:"No Carabiner",nodeId:null,price:0,image:"https://cdn.shopify.com/s/files/1/0767/9272/5688/files/no-charm.png?v=1743305046",otherThumbImage:null,available:!0,sku:null})}catch(error){console.error("Error fetching Build-A-Drip products:",error)}}getProductType(product){if(product.tags&&product.tags.includes("beads"))return"beads";if(product.tags&&product.tags.includes("carabiner"))return"carabiner";if(product.tags&&product.tags.includes("charm"))return"charm";const title=product.title.toLowerCase();return title.includes("bead")?"beads":title.includes("carabiner")?"carabiner":title.includes("charm")?"charm":null}parseUrlParams(){const urlParams=new URLSearchParams(window.location.search),beadParam=urlParams.get("bead"),carabinerParam=urlParams.get("carabiner"),charmParam=urlParams.get("charm"),beadOption=beadParam?this.productsData.beads.find(opt=>opt.id.toString()===beadParam||opt.sku===beadParam):null;beadOption&&beadOption.nodeId&&beadOption.nodeId.startsWith("chain")&&(this.baseType="metal"),this.currentOptions.beads=beadOption||this.productsData.beads[0];const carabinerOption=carabinerParam?this.productsData.carabiner.find(opt=>opt.id.toString()===carabinerParam||opt.sku===carabinerParam):null;if(this.currentOptions.carabiner=carabinerOption||this.productsData.carabiner.find(opt=>opt.colorName==="Gold"&&opt.available)||this.productsData.carabiner.find(opt=>opt.id!=="no-carabiner"&&opt.available)||this.productsData.carabiner[0],charmParam){const charmOption=this.productsData.charm.find(opt=>opt.id.toString()===charmParam||opt.sku===charmParam);charmOption&&(this.currentOptions.charm=charmOption)}else this.currentOptions.charm=this.productsData.charm.find(opt=>opt.id==="no-charm")}renderOptions(){this.beadProducts=this.productsData.beads.filter(opt=>!opt.nodeId||!opt.nodeId.startsWith("chain")),this.chainProducts=this.productsData.beads.filter(opt=>opt.nodeId&&opt.nodeId.startsWith("chain")),this.renderProductOptions(this.baseColorOptions,this.beadProducts,"beads",!0);const baseChainOptions=document.getElementById("base-chain-options");baseChainOptions&&this.renderProductOptions(baseChainOptions,this.chainProducts,"beads",!0),this.renderProductOptions(this.carabinerColorOptions,this.productsData.carabiner,"carabiner",!0),this.renderProductOptions(this.charmOptions,this.productsData.charm,"charm",!1);const mobileBaseColorOptions=document.getElementById("base-color-options-mobile"),mobileBaseChainOptions=document.getElementById("base-chain-options-mobile"),mobileCarabinerColorOptions=document.getElementById("carabiner-color-options-mobile"),mobileCharmOptions=document.getElementById("charm-options-mobile");mobileBaseColorOptions&&this.renderProductOptions(mobileBaseColorOptions,this.beadProducts,"beads",!0),mobileBaseChainOptions&&this.renderProductOptions(mobileBaseChainOptions,this.chainProducts,"beads",!0),mobileCarabinerColorOptions&&this.renderProductOptions(mobileCarabinerColorOptions,this.productsData.carabiner,"carabiner",!0),mobileCharmOptions&&this.renderProductOptions(mobileCharmOptions,this.productsData.charm,"charm",!1),this.updateUISelections(),this.updateTotalPrice(),this.applyBaseTypeVisibility()}
1applyBaseTypeVisibility(){const isBeads=this.baseType==="beads";document.querySelectorAll(".base-type-toggle-btn").forEach(btn=>{btn.classList.toggle("active",btn.dataset.baseType===this.baseType)});const beadsGroup=document.querySelector('[data-option-group="beads"]'),chainGroup=document.querySelector('[data-option-group="chain"]');beadsGroup&&(beadsGroup.style.display=isBeads?"":"none"),chainGroup&&(chainGroup.style.display=isBeads?"none":"");const mobileBeadsGroup=document.querySelector('[data-mobile-option-group="beads"]'),mobileChainGroup=document.querySelector('[data-mobile-option-group="chain"]');mobileBeadsGroup&&(mobileBeadsGroup.style.display=isBeads?"":"none"),mobileChainGroup&&(mobileChainGroup.style.display=isBeads?"none":"")}setBaseType(type){this.baseType=type,this.applyBaseTypeVisibility();const pool=type==="beads"?this.beadProducts:this.chainProducts;if(pool.length>0){const firstAvailable=pool.find(opt=>opt.available)||pool[0];this.selectOption("beads",firstAvailable)}this.updateShareableUrl()}renderProductOptions(container2,options,optionType,isColorOption){container2.innerHTML="";const sortedOptions=[...options].sort((a,b)=>a.available&&!b.available?-1:!a.available&&b.available?1:0);console.log("Carabiner options:",sortedOptions),sortedOptions.forEach(option=>{const optionElement=document.createElement("div");if(optionElement.className=isColorOption?"option-item color-option":"option-item charm-option",optionElement.dataset.optionId=option.id,optionElement.dataset.optionType=optionType,optionElement.dataset.nodeId=option.nodeId,!option.available){optionElement.classList.add("option-unavailable");const soldOutLabel=document.createElement("div");soldOutLabel.className="sold-out-label",soldOutLabel.textContent="Sold Out",optionElement.appendChild(soldOutLabel)}if(isColorOption){const isHeartOption=option.colorName.toLowerCase().includes("heart");if(option.image){const imgElement=document.createElement("img");if(imgElement.src=option.otherThumbImage||option.image,imgElement.alt=option.colorName||option.title,imgElement.className="color-option-image",imgElement.loading="lazy",imgElement.decoding="async",isHeartOption)optionElement.appendChild(imgElement);else{const wrapperSize=container2.id&&container2.id.includes("-mobile")?"40px":"34px",imgWrapper=document.createElement("div");imgWrapper.style.width=wrapperSize,imgWrapper.style.height=wrapperSize,imgWrapper.style.overflow="hidden",imgWrapper.style.borderRadius="50%",imgWrapper.appendChild(imgElement),optionElement.appendChild(imgWrapper)}}isHeartOption&&optionElement.classList.add("heart-option"),optionElement.title=option.colorName||option.title}else if(option.id==="no-charm"){const imgElement=document.createElement("img");imgElement.src=option.image,imgElement.alt="no charm",imgElement.className="charm-image",imgElement.loading="lazy",imgElement.decoding="async",optionElement.prepend(imgElement)}else{const displayName=option.colorName||option.title;if(option.image){const imgElement=document.createElement("img");imgElement.src=option.image,imgElement.alt=displayName,imgElement.className="charm-image",imgElement.loading="lazy",imgElement.decoding="async",optionElement.prepend(imgElement)}}if(this.currentOptions[optionType]&&this.currentOptions[optionType].id===option.id&&optionElement.classList.add("selected"),window.innerWidth>=1025){const isChainContainer=container2.id&&container2.id.includes("chain"),hoverNameDisplayId=optionType==="beads"&&isChainContainer?"chain-selected-name":`${optionType}-selected-name`;optionElement.addEventListener("mouseenter",()=>{const nameDisplay=document.getElementById(hoverNameDisplayId);if(nameDisplay){nameDisplay.hasAttribute("data-original-text")||nameDisplay.setAttribute("data-original-text",nameDisplay.innerHTML);const displayName=option.colorName||option.title,displayPrice=this.getDisplayPrice(optionType,option.price),previewText=displayPrice>0?`${displayName} <span class="inline-price">+$${displayPrice.toFixed(2)}</span>`:displayName;nameDisplay.innerHTML=previewText}}),optionElement.addEventListener("mouseleave",()=>{const nameDisplay=document.getElementById(hoverNameDisplayId);if(nameDisplay){const original=nameDisplay.getAttribute("data-original-text");original&&(nameDisplay.innerHTML=original,nameDisplay.removeAttribute("data-original-text"))}})}optionElement.addEventListener("click",()=>{this.selectOption(optionType,option)}),container2.appendChild(optionElement)})}normalizeNodeId(nodeId){return String(nodeId).toLowerCase()}getEffectiveCarabinerNodeId(){if(!this.currentOptions.carabiner)return null;if(this.currentOptions.beads){const normalizedNecklaceName=(this.currentOptions.beads.colorName||this.currentOptions.beads.title).toLowerCase().trim(),normalizedCarabinerName=(this.currentOptions.carabiner.colorName||this.currentOptions.carabiner.title).toLowerCase().trim();if(this.necklaceCarabinerOverrides[normalizedNecklaceName]){const overrideValue=this.necklaceCarabinerOverrides[normalizedNecklaceName];if(normalizedCarabinerName.includes("gold"))return console.log("[getEffectiveCarabinerNodeId] Applying override for",normalizedNecklaceName),console.log("[getEffectiveCarabinerNodeId] Override value:",overrideValue),overrideValue}for(const[overrideKey,overrideValue]of Object.entries(this.necklaceCarabinerOverrides))if((normalizedNecklaceName.includes(overrideKey)||overrideKey.includes(normalizedNecklaceName))&&normalizedCarabinerName.includes("gold"))return overrideValue}const carabinerNodeId=this.currentOptions.carabiner.nodeId;return carabinerNodeId&&this.normalizeNodeId(carabinerNodeId)==="carabiner - gold"?(console.log("[getEffectiveCarabinerNodeId] Applying global gold override: Carabiner - Gold -> Carabiner - Gold001"),"Carabiner - Gold001"):this.currentOptions.carabiner.nodeId}selectOption(optionType,option){this.currentOptions[optionType]=option,document.querySelectorAll(`.option-item[data-option-type="${optionType}"]`).forEach(item=>{item.dataset.optionId===option.id.toString()?item.classList.add("selected"):item.classList.remove("selected")});const nameDisplayId=optionType==="beads"&&this.baseType==="metal"?"chain-selected-name":`${optionType}-selected-name`,nameDisplay=document.getElementById(nameDisplayId);if(nameDisplay){const displayName=option.colorName||option.title,displayPrice=this.getDisplayPrice(optionType,option.price),finalText=displayPrice>0?`${displayName} <span class="inline-price">+$${displayPrice.toFixed(2)}</span>`:displayName;nameDisplay.innerHTML=finalText,nameDisplay.setAttribute("data-original-text",finalText)}const mobileNameDisplayId=optionType==="beads"&&this.baseType==="metal"?"chain-selected-name-mobile":`${optionType}-selected-name-mobile`,mobileNameDisplay=document.getElementById(mobileNameDisplayId);if(mobileNameDisplay){const displayName=option.colorName||option.title,displayPrice=this.getDisplayPrice(optionType,option.price),finalText=displayPrice>0?`${displayName} <span class="inline-price">+$${displayPrice.toFixed(2)}</span>`:displayName;mobileNameDisplay.innerHTML=finalText}if(window.lastCameraPosition=window.isCameraAtFrontView(),this.updateModel(),this.updateTotalPrice(),this.updateShareableUrl(),this.currentMobileStep&&this.mobileSelectedOptionDetail
1s){const typeForStep={1:"beads",2:"carabiner",3:"charm"}[this.currentMobileStep];if(optionType===typeForStep){const nameSpan=this.mobileSelectedOptionDetails.querySelector(".mobile-selected-name");let displayText=option.colorName||option.title;const displayPrice=this.getDisplayPrice(optionType,option.price);if(displayPrice>0&&(displayText+=` +$${displayPrice.toFixed(2)}`),nameSpan)nameSpan.textContent=displayText;else{const newSpan=document.createElement("span");newSpan.className="mobile-selected-name",newSpan.textContent=displayText,this.mobileSelectedOptionDetails.appendChild(newSpan)}}}}updateModel(isInitialLoad){if(!window.dripModelViewer){window.addEventListener("model-loaded",()=>{this.updateModel()},{once:!0});return}if(!window.dripModelViewer.model)return;const isBeadsChanging=this.currentOptions.beads!==this.previousOptions?.beads,isCarabinerChanging=this.currentOptions.carabiner!==this.previousOptions?.carabiner,isCharmChanging=this.currentOptions.charm!==this.previousOptions?.charm,cameraHasMoved=!window.isCameraAtFrontView();if(this.previousOptions={...this.currentOptions},this.currentOptions.beads){const nodeId=this.currentOptions.beads.nodeId;isBeadsChanging?window.resetViewToFront(800,!cameraHasMoved,"necklace",!1,()=>{if(window.updateModelNode("necklace",nodeId),window.adjustCameraForNecklace(nodeId),this.currentOptions.carabiner){const carabinerNodeId=this.getEffectiveCarabinerNodeId();window.updateModelNode("carabiner",carabinerNodeId)}if(this.currentOptions.charm&&this.currentOptions.charm.id!=="no-charm"){const charmNodeId=this.currentOptions.charm.nodeId;window.updateModelNode("charm",charmNodeId)}}):(window.updateModelNode("necklace",nodeId),window.adjustCameraForNecklace(nodeId))}if(this.currentOptions.carabiner){const nodeId=this.getEffectiveCarabinerNodeId();if(this.currentOptions.carabiner.id==="no-carabiner")try{hideAllNodesOfComponentType("carabiner")}catch(error){console.error("[updateModel] Error hiding carabiner nodes:",error)}else isCarabinerChanging?(window.resetViewToFront(800,!cameraHasMoved,"necklace",!1),setTimeout(()=>{window.updateModelNode("carabiner",nodeId),this.currentOptions.beads&&window.adjustCameraForNecklace(this.currentOptions.beads.nodeId)},800)):window.updateModelNode("carabiner",nodeId)}if(this.currentOptions.charm){const nodeId=this.currentOptions.charm.nodeId;if(this.currentOptions.charm.id==="no-charm")try{hideAllNodesOfComponentType("charm")}catch(error){console.error("[updateModel] Error hiding charm nodes:",error)}else isCharmChanging?(window.resetViewToFront(800,!cameraHasMoved,"necklace",!1),setTimeout(()=>{window.updateModelNode("charm",nodeId),this.currentOptions.beads&&window.adjustCameraForNecklace(this.currentOptions.beads.nodeId)},1500),setTimeout(()=>{window.animateSwap&&window.animateSwap(nodeId)},900)):window.updateModelNode("charm",nodeId)}}formatPriceWithCurrency(price){if(typeof Shopify>"u"||!Shopify.currency||!Shopify.currency.active)return"$"+price.toFixed(2);const currencyCode=Shopify.currency.active,format={USD:{symbol:"$",position:"before"},CAD:{symbol:"$",position:"before",code:"CAD"},EUR:{symbol:"\u20AC",position:"before"},GBP:{symbol:"\xA3",position:"before"}}[currencyCode]||{symbol:"$",position:"before"},formattedNumber=currencyCode==="EUR"?price.toFixed(2).replace(".",","):price.toFixed(2);let formattedPrice="";return format.position==="before"?formattedPrice=format.symbol+formattedNumber:formattedPrice=formattedNumber+format.symbol,format.code&&(formattedPrice+=" "+format.code),formattedPrice}updateTotalPrice(){let totalPrice=this.basePrice;Object.keys(this.currentOptions).forEach(optionType=>{this.currentOptions[optionType]&&(totalPrice+=this.currentOptions[optionType].price||0)});const formattedPrice=this.formatPriceWithCurrency(totalPrice);this.priceElement.textContent=formattedPrice,this.priceElementMobile.textContent=formattedPrice}getDisplayPrice(optionType,price){return optionType==="beads"?price>130?price-130:0:optionType==="carabiner"?price>65?price-65:0:price>0?price:0}updateUISelections(){Object.keys(this.currentOptions).forEach(optionType=>{if(this.currentOptions[optionType]){const selectedOption=this.currentOptions[optionType];document.querySelectorAll(`.option-item[data-option-type="${optionType}"][data-option-id="${selectedOption.id}"]`).forEach(el=>el.classList.add("selected"));const nameDisplay=document.getElementById(`${optionType}-selected-name`);if(nameDisplay){const displayName=selectedOption.colorName||selectedOption.title,displayPrice=this.getDisplayPrice(optionType,selectedOption.price);displayPrice>0?nameDisplay.innerHTML=`${displayName} <span class="inline-price">+$${displayPrice.toFixed(2)}</span>`:nameDisplay.textContent=displayName}const mobileNameDisplay=document.getElementById(`${optionType}-selected-name-mobile`);if(mobileNameDisplay){const displayName=selectedOption.colorName||selectedOption.title,displayPrice=this.getDisplayPrice(optionType,selectedOption.price);displayPrice>0?mobileNameDisplay.innerHTML=`${displayName} <span class="inline-price">+$${displayPrice.toFixed(2)}</span>`:mobileNameDisplay.textContent=displayName}}})}updateShareableUrl(){const params=new URLSearchParams;this.currentOptions.beads&&params.set("bead",this.currentOptions.beads.id),this.currentOptions.carabiner&&params.set("carabiner",this.currentOptions.carabiner.id),this.currentOptions.charm&&params.set("charm",this.currentOptions.charm.id);const newUrl=`${window.location.pathname}?${params.toString()}`;window.history.replaceState({},"",newUrl)}setupMobileNavigation(){console.log("Setting up mobile navigation...");const prevBtn=document.getElementById("mobile-prev-option"),nextBtn=document.getElementById("mobile-next-option");
1if(console.log("Prev button:",prevBtn),console.log("Next button:",nextBtn),!prevBtn||!nextBtn){console.log("Mobile navigation buttons not found");return}let currentStep=0;const totalSteps=4,updateMobileStep=step=>{console.log("Updating mobile step to:",step);const allGroups=document.querySelectorAll(".mobile-option-group");console.log("Found option groups:",allGroups.length),allGroups.forEach(group=>{group.classList.remove("active")});const currentGroups=document.querySelectorAll(`.mobile-option-group[data-step="${step}"]`);if(console.log("Current groups for step",step,":",currentGroups.length),currentGroups.forEach(group=>{group.classList.add("active")}),document.querySelectorAll(".mobile-step-indicator").forEach(indicator=>{parseInt(indicator.dataset.step)===step?(indicator.classList.add("active"),indicator.style.opacity="1"):(indicator.classList.remove("active"),indicator.style.opacity="0.3")}),prevBtn.disabled=step===0,nextBtn.disabled=step===totalSteps-1,step===2&&this.currentOptions.carabiner&&this.currentOptions.carabiner.id==="no-carabiner"){const firstCarabiner=this.productsData.carabiner.find(opt=>opt.id!=="no-carabiner"&&opt.available);firstCarabiner&&this.selectOption("carabiner",firstCarabiner)}currentStep=step};prevBtn.addEventListener("click",e=>{console.log("Prev button clicked, current step:",currentStep),e.preventDefault(),currentStep>0&&updateMobileStep(currentStep-1)}),nextBtn.addEventListener("click",e=>{console.log("Next button clicked, current step:",currentStep),e.preventDefault(),currentStep<totalSteps-1&&updateMobileStep(currentStep+1)}),console.log("Initializing to step 0"),updateMobileStep(0)}showMobileStep(step){this.currentStepElement.textContent=step,this.currentMobileStep=step,this.mobileOptionsWrapper.innerHTML="",this.mobileSelectedOptionDetails.innerHTML="";let optionType,title,isColorOption;switch(step){case 1:optionType="beads",title="Base Color",isColorOption=!0;break;case 2:optionType="carabiner",title="Carabiner",isColorOption=!0;break;case 3:optionType="charm",title="Charm",isColorOption=!1;break}const titleElement=document.createElement("h3");titleElement.textContent=title,this.mobileSelectedOptionDetails.appendChild(titleElement);const selectedOption=this.currentOptions[optionType];if(selectedOption){const nameSpan=document.createElement("span");nameSpan.className="mobile-selected-name";let displayText=selectedOption.colorName||selectedOption.title;optionType==="charm"&&selectedOption.price>0&&(displayText+=` +$${selectedOption.price.toFixed(2)}`),nameSpan.textContent=displayText,this.mobileSelectedOptionDetails.appendChild(nameSpan)}const optionsContainer=document.createElement("div");optionsContainer.className="mobile-option-selections",this.renderProductOptions(optionsContainer,this.productsData[optionType],optionType,isColorOption),this.mobileOptionsWrapper.appendChild(optionsContainer),this.prevBtn.disabled=step===1,this.nextBtn.disabled=step===this.totalMobileSteps}addToCart(){console.log("addToCart function called"),console.log("Current options:",this.currentOptions);const missingOptions=[];if(this.currentOptions.beads||missingOptions.push("Base"),this.currentOptions.carabiner||missingOptions.push("Carabiner"),missingOptions.length>0){alert(`Please select the following options: ${missingOptions.join(", ")}`);return}const bundleId=`drip-${Date.now()}`,items=[],selectedOptions=["beads","carabiner","charm"];let beadsAdded=!1;if(selectedOptions.forEach(type=>{const option=this.currentOptions[type];if(!option||option.id==="no-charm"||option.id==="no-carabiner")return;const componentLabel=type==="beads"?this.baseType==="metal"?"Chain":"Beads":type.charAt(0).toUpperCase()+type.slice(1),properties={"Bundle Group":bundleId,Component:componentLabel,Color:option.colorName||option.title};items.push({id:option.id,properties}),type==="beads"&&(beadsAdded=!0)}),!beadsAdded){alert("Error: Beads failed to be added to the bundle. Please try again and contact us at [email protected]");return}fetch("/cart/add.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({items})}).then(response=>{if(!response.ok)throw new Error("Network response was not ok");return response.json()}).then(data=>{typeof window.updateCartUI=="function"&&window.updateCartUI(),this.showConfirmation()}).catch(error=>{console.error("Error adding items to cart:",error),alert("There was an error adding this bundle to your cart.")})}showConfirmation(){const isHomepage=window.location.pathname==="/"||window.location.pathname==="/pages/home",configurator=document.querySelector(".configurator"),confirmationContent=document.getElementById("build-a-drip-confirmation-content");
1if(isHomepage){console.log("On homepage: Skipping confirmation modal");return}if(configurator&&confirmationContent){console.log("Showing confirmation content"),configurator.classList.add("hidden"),confirmationContent.classList.remove("hidden"),confirmationContent.classList.add("flex");const finalSaleCheckbox=document.getElementById("final-sale-checkbox"),finalSaleCheckboxMobile=document.getElementById("final-sale-checkbox-mobile"),addToCartBtn=document.getElementById("add-to-cart"),addToCartBtnMobile=document.getElementById("add-to-cart-mobile"),section=document.getElementById("build-a-drip-section"),requireCheckbox=section&&section.dataset.requireFinalSaleCheckbox==="true";finalSaleCheckbox&&(finalSaleCheckbox.checked=!1),finalSaleCheckboxMobile&&(finalSaleCheckboxMobile.checked=!1),addToCartBtn&&(addToCartBtn.disabled=requireCheckbox,addToCartBtn.style.cursor=requireCheckbox?"not-allowed":"pointer"),addToCartBtnMobile&&(addToCartBtnMobile.disabled=requireCheckbox,addToCartBtnMobile.style.cursor=requireCheckbox?"not-allowed":"pointer")}else console.error("Could not find configurator or confirmation content"),console.log("configurator:",configurator),console.log("confirmationContent:",confirmationContent)}shareConfiguration(){const shareUrl=window.location.href;navigator.clipboard.writeText(shareUrl).then(()=>{alert("Configuration URL copied to clipboard!")}).catch(err=>{console.error("Could not copy URL: ",err),alert("The URL for this configuration is: "+shareUrl)})}setupEventListeners(){console.log("Setting up event listeners..."),console.log("Add to cart button:",this.addToCartBtn);const section=document.getElementById("build-a-drip-section"),requireCheckbox=section&&section.dataset.requireFinalSaleCheckbox==="true";this.addToCartBtn?(this.addToCartBtn.addEventListener("click",()=>{console.log("Add to cart button clicked!"),this.addToCart()}),this.addToCartBtn.setAttribute("data-listener-added","true"),requireCheckbox||(this.addToCartBtn.disabled=!1,this.addToCartBtn.style.cursor="pointer")):console.error("Add to cart button not found!"),this.mobileAddToCartBtn&&(requireCheckbox||(this.mobileAddToCartBtn.disabled=!1,this.mobileAddToCartBtn.style.cursor="pointer"));const finalSaleCheckbox=document.getElementById("final-sale-checkbox");finalSaleCheckbox&&this.addToCartBtn&&requireCheckbox&&finalSaleCheckbox.addEventListener("change",e=>{e.target.checked?(this.addToCartBtn.disabled=!1,this.addToCartBtn.style.cursor="pointer"):(this.addToCartBtn.disabled=!0,this.addToCartBtn.style.cursor="not-allowed")});const finalSaleCheckboxMobile=document.getElementById("final-sale-checkbox-mobile");finalSaleCheckboxMobile&&this.mobileAddToCartBtn&&requireCheckbox&&finalSaleCheckboxMobile.addEventListener("change",e=>{e.target.checked?(this.mobileAddToCartBtn.disabled=!1,this.mobileAddToCartBtn.style.cursor="pointer"):(this.mobileAddToCartBtn.disabled=!0,this.mobileAddToCartBtn.style.cursor="not-allowed")}),this.mobileAddToCartBtn&&window.innerWidth<768?(this.mobileAddToCartBtn.onclick=()=>this.addToCart(),this.mobileAddToCartBtn.setAttribute("data-listener-added","true")):this.mobileAddToCartBtn&&(this.mobileAddToCartBtn.onclick=null),this.shareBtn&&this.shareBtn.addEventListener("click",()=>this.shareConfiguration()),this.shareBtnMobile&&this.shareBtnMobile.addEventListener("click",()=>this.shareConfiguration()),document.querySelectorAll(".base-type-toggle-btn").forEach(btn=>{btn.addEventListener("click",()=>{this.setBaseType(btn.dataset.baseType)})}),console.log("About to call setupMobileNavigation..."),this.setupMobileNavigation(),console.log("setupMobileNavigation called"),this.modelViewer&&(this.modelViewer.addEventListener("mousedown",()=>{window.stopAutoRotate&&window.stopAutoRotate()}),this.modelViewer.addEventListener("touchstart",()=>{window.stopAutoRotate&&window.stopAutoRotate()}))}selectBySku(beadSku,carabinerSku,charmSku){if(console.log("selectBySku called with:",beadSku,carabinerSku,charmSku),beadSku){const beadOption=this.productsData.beads.find(opt=>opt.sku===beadSku);if(beadOption){const newBaseType=beadOption.nodeId&&beadOption.nodeId.startsWith("chain")?"metal":"beads";newBaseType!==this.baseType&&(this.baseType=newBaseType,this.applyBaseTypeVisibility()),this.currentOptions.beads=beadOption,this.selectOption("beads",beadOption),console.log("Selected bead:",beadOption)}}if(carabinerSku){const carabinerOption=this.productsData.carabiner.find(opt=>
1opt.sku===carabinerSku);carabinerOption&&(this.currentOptions.carabiner=carabinerOption,this.selectOption("carabiner",carabinerOption),console.log("Selected carabiner:",carabinerOption))}if(charmSku){const charmOption=this.productsData.charm.find(opt=>opt.sku===charmSku||opt.id===charmSku);charmOption&&(this.currentOptions.charm=charmOption,this.selectOption("charm",charmOption),console.log("Selected charm:",charmOption))}this.updatePrice(),this.renderOptions()}}window.normalizeNodeName=function(name){return name.replace(/\s+/g,"_-_-").replace(/[^a-zA-Z0-9_-]/g,"")};const necklaceCameraOverrides={};window.adjustCameraForNecklace=function(nodeId){if(!window.dripModelViewer||!window.dripModelViewer.camera||!window.initialCameraState)return;const necklaceName=(nodeId||"").replace(/^necklace\s*-?\s*/i,"").trim().toLowerCase(),override=necklaceCameraOverrides[necklaceName]||null,cam=window.dripModelViewer.camera,controls=window.dripModelViewer.controls,front=window.initialCameraState,targetZ=front.position.z*(override?override.zoomFactor:1),targetY=front.position.y+(override?override.yOffset:0),targetTY=front.target.y+(override?override.yOffset*.5:0),startZ=cam.position.z,startY=cam.position.y,startTY=controls.target.y,duration=600,startTime=performance.now();function animateCamera(now){const elapsed=now-startTime,t=Math.min(elapsed/duration,1),ease=t*(2-t);cam.position.z=startZ+(targetZ-startZ)*ease,cam.position.y=startY+(targetY-startY)*ease,controls.target.y=startTY+(targetTY-startTY)*ease,controls.update(),t<1&&requestAnimationFrame(animateCamera)}requestAnimationFrame(animateCamera)},window.saveCameraState=function(){window.dripModelViewer&&window.dripModelViewer.camera&&(window.initialCameraState={position:{x:window.dripModelViewer.camera.position.x,y:window.dripModelViewer.camera.position.y,z:window.dripModelViewer.camera.position.z},target:window.dripModelViewer.controls?{x:window.dripModelViewer.controls.target.x,y:window.dripModelViewer.controls.target.y,z:window.dripModelViewer.controls.target.z}:null})},window.resetViewToFront=function(duration=1e3,forceRotate=!1,componentType=null,forceAlways=!1,onComplete=null){if(!window.dripModelViewer||!window.dripModelViewer.controls||!window.initialCameraState)return;const frontView=window.initialCameraState,currentPosition={x:window.dripModelViewer.camera.position.x,y:window.dripModelViewer.camera.position.y,z:window.dripModelViewer.camera.position.z},currentTarget={x:window.dripModelViewer.controls.target.x,y:window.dripModelViewer.controls.target.y,z:window.dripModelViewer.controls.target.z},vectorX=currentPosition.x-currentTarget.x,vectorZ=currentPosition.z-currentTarget.z,currentRadius=Math.sqrt(vectorX*vectorX+vectorZ*vectorZ),currentAngle=Math.atan2(vectorX,vectorZ),targetVectorX=frontView.position.x-frontView.target.x,targetVectorZ=frontView.position.z-frontView.target.z,targetRadius=Math.sqrt(targetVectorX*targetVectorX+targetVectorZ*targetVectorZ),targetAngle=Math.atan2(targetVectorX,targetVectorZ),angleDifference=Math.abs(targetAngle-currentAngle)%(2*Math.PI),radiusDifference=Math.abs(targetRadius-currentRadius),positionYDifference=Math.abs(frontView.position.y-currentPosition.y),targetPointDifference=Math.abs(frontView.target.x-currentTarget.x)+Math.abs(frontView.target.y-currentTarget.y)+Math.abs(frontView.target.z-currentTarget.z),isAtFront=angleDifference<.1&&radiusDifference<.5&&positionYDifference<.5&&targetPointDifference<.5;if(!forceAlways&&isAtFront&&(forceRotate||componentType==="necklace")){typeof onComplete=="function"&&onComplete();return}let angleDistance=targetAngle-currentAngle;angleDistance>Math.PI&&(angleDistance-=2*Math.PI),angleDistance<-Math.PI&&(angleDistance+=2*Math.PI);const startTime=Date.now();function animate(){const elapsed=Date.now()-startTime,progress=Math.min(elapsed/duration,1),easeProgress=.5-.5*Math.cos(progress*Math.PI),newRadius=currentRadius+(targetRadius-currentRadius)*easeProgress,newAngle=currentAngle+angleDistance*easeProgress,newX=currentTarget.x+Math.sin(newAngle)*newRadius,newZ=currentTarget.z+Math.cos(newAngle)*newRadius,newY=currentPosition.y+(frontView.position.y-currentPosition.y)*easeProgress;window.dripModelViewer.camera.position.set(newX,newY,newZ),window.dripModelViewer.controls.target.x=currentTarget.x+(frontView.target.x-currentTarget.x)*easeProgress,window.dripModelViewer.controls.target.y=currentTarget.y+(frontView.target.y-currentTarget.y)*easeProgress,window.dripModelViewer.controls.target.z=currentTarget.z+(frontView.target.z-currentTarget.z)*easeProgress,window.dripModelViewer.controls.update(),progress<1?requestAnimationFrame(animate):typeof onComplete=="function"&&onComplete()}animate()},window.performRotationAnimation=function(duration=1500){if(!window.dripModelViewer||!window.dripModelViewer.controls||!window.initialCameraState)return;const currentPosition={x:window.dripModelViewer.camera.position.x,y:window.dripModelViewer.camera.position.y,z:window.dripModelViewer.camera.position.z},currentTarget={x:window.dripModelViewer.controls.target.x,y:window.dripModelViewer.controls.target.y,z:window.dripModelViewer.controls.target.z},vectorX=currentPosition.x-currentTarget.x,vectorZ=currentPosition.z-currentTarget.z,currentRadius=Math.sqrt(vectorX*vectorX+vectorZ*vectorZ),startAngle=Math.atan2(vectorX,vectorZ),startTime=Date.now();function rotateCamera(){const elapsed=Date.now()-startTime,progress=Math.min(elapsed/duration,1),easeProgress=progress<.5?4*progress*progress*progress:1-Math.pow(-2*progress+2,3)/2,newAngle=startAngle+2*Math.PI*easeProgress,newX=currentTarget.x+Math.sin(newAngle)*currentRadius,newZ=currentTarget.z+Math.cos(newAngle)*currentRadius;window.dripModelViewer.camera.position.set(newX,currentPosition.y,newZ),window.dripModelViewer.controls.update(),progress<1&&requestAnimationFrame(rotateCamera)}rotateCamera()},window.animateSwap=function(nodeId){if(!window.dripModelViewer||!nodeId)return;const formattedNodeId=formatNodeName(nodeId);let carabiner=null;window.dripModelViewer.model.getObjectByName&&(carabiner=window.dripModelViewer.model.getObjectByName(formattedNodeId));const originalScale={x:carabiner.scale.x,y:carabiner.scale.y,z:carabiner.scale.z},originalPosition={x:carabiner.position.x,y:carabiner.position.y,z:carabiner.position.z},duration=800,startTime=Date.now();function animate(){const elapsed=Date.now()-startTime,progress=Math.min(elapsed/duration,1);if(progress<=.5){const scaleProgress=1-progress*2;carabiner.scale.set(originalScale.x*scaleProgress,originalScale.y*scaleProgress,originalScale.z*scaleProgress)}else{const scaleProgress=(progress-.5)*2;carabiner.scale.set(originalScale.x*scaleProgress,originalScale.y*scaleProgress,originalScale.z*scaleProgress)}window.dripModelViewer.controls.update(),progress<1?requestAnimationFrame(animate):(carabiner.scale.set(originalScale.x,originalScale.y,originalScale.z),carabiner.position.set(originalPosition.x,originalPosition.y,originalPosition.z),window.dripModelViewer.controls.update())}animate()},window.isCameraAtFrontView=function(){if(!window.dripModelViewer||!window.dripModelViewer.controls||!window.initialCameraState)return!0;const currentPosition=window.dripModelViewer.camera.position,frontPosition=window.initialCameraState.position,currentTarget=window.dripModelViewer.controls.target,frontTarget=window.initialCameraState.target,positionDifference=Math.abs(frontPosition.x-currentPosition.x)+Math.abs(frontPosition.y-currentPosition.y)+Math.abs(frontPosition.z-currentPosition.z),targetDifference=Math.abs(frontTarget.x-currentTarget.x)+Math.abs(frontTarget.y-currentTarget.y)+Math.abs(frontTarget.z-currentTarget.z);return positionDifference<.5&&targetDifference<.5},window.updateModelNode=function(componentType,nodeId){if(!window.dripModelViewer)return;const formattedNodeId=formatNodeName(nodeId);console.log(`[updateModelNode] Looking for ${componentType} node: "${nodeId}" -> formatted: "${formattedNodeId}"`);let targetNode=null;if(nodeId.includes("_")&&!nodeId.includes(" ")&&(targetNode=window.dripModelViewer.model.getObjectByName(nodeId),console.log(`[updateModelNode] Direct underscore format "${nodeId}": ${targetNode?"FOUND":"not found"}`),targetNode)){hideAllNodesOfComponentType(componentType),setNodeAndChildrenVisibility(targetNode,!0),targetNode.material&&fixMaterialOpacity(targetNode.material,targetNode.name,targetNode),targetNode.traverse(child=>{child.material&&fixMaterialOpacity(child.material,child.name,child)});return}const spaceFormatNodeId=nodeId.split(" ").map((part,index)=>part==="-"?"-":index===0&&componentType==="necklace"?part.toUpperCase():part.charAt(0).toUpperCase()+part.slice(1)).join(" "),upperCaseFormatNodeId=nodeId.split(" ").map(part=>part==="-"?"-":part.toUpperCase()).join(" "),upperCaseUnderscoreNodeId=nodeId.split(" ").map(part=>part==="-"?"-":part.toUpperCase()).join("_");if(window.dripModelViewer.model.getObjectByName){if(targetNode=window.dripModelViewer.model.getObjectByName(spaceFormatNodeId),console.log(`[updateModelNode] Space format "${spaceFormatNodeId}": ${targetNode?"FOUND":"not found"}`),targetNode||(targetNode=window.dripModelViewer.model.getObjectByName(upperCaseFormatNodeId),console.log(`[updateModelNode] Uppercase format "${upperCaseFormatNodeId}": ${targetNode?"FOUND":"not found"}`)),targetNode||(targetNode=window.dripModelViewer.model.getObjectByName(upperCaseUnderscoreNodeId),console.log(`[updateModelNode] Uppercase underscore format "${upperCaseUnderscoreNodeId}": ${targetNode?"FOUND":"not found"}`)),targetNode||(targetNode=window.dripModelViewer.model.getObjectByName(formattedNodeId),console.log(`[updateModelNode] Underscore format "${formattedNodeId}": ${targetNode?"FOUND":"not found"}`)),!targetNode){const searchLower=spaceFormatNodeId.toLowerCase();window.dripModelViewer.model.traverse(node=>{node.name&&node.name.toLowerCase()===searchLower&&(targetNode=node,console.log(`[updateModelNode] Case-insensitive match found: "${node.name}"`))})}}else{const matchingNodes=[];findNodesByName(window.dripModelViewer.model,formattedNodeId,matchingNodes),matchingNodes.length>0&&(targetNode=matchingNodes[0])}const materialNodes=componentType==="necklace"||componentType==="beads"?findRelatedMaterialNodes(formattedNodeId,spaceFormatNodeId,upperCaseFormatNodeId,upperCaseUnderscoreNodeId):[];if(targetNode){if(hideAllNodesOfComponentType(componentType),setNodeAndChildrenVisibility(targetNode,!0),targetNode.material&&fixMaterialOpacity(targetNode.material,targetNode.name,targetNode),targetNode.traverse(child=>{child.material&&fixMaterialOpacity(child.material,child.name,child)}),console.log("[updateModelNode] targetNode.name:",targetNode.name),targetNode.name&&(targetNode.name==="BEADS_-_SIR"||targetNode.name==="BEADS - SIR")){console.log("[updateModelNode] Sir necklace detected, handling special case");const sirVariant=window.dripModelViewer.model.getObjectByName("BEADS_-_SIR001");if(sirVariant){console.log("[updateModelNode] Also showing BEADS_-_SIR001 for sir necklace"),console.log("[updateModelNode] BEADS_-_SIR parent:",targetNode.parent?.name),console.log("[updateModelNode] BEADS_-_SIR001 parent:",sirVariant.parent?.name),console.log("[updateModelNode] Are they siblings?",targetNode.parent===sirVariant.parent),setNodeAndChildrenVisibility(sirVariant,!0),sirVariant.material&&fixMaterialOpacity(sirVariant.material,sirVariant.name,sirVariant),sirVariant.traverse(child=>{child.material&&fixMaterialOpacity(child.material,child.name,child)});let currentNode=sirVariant.parent;for(;currentNode;)currentNode.visible=!0,currentNode=currentNode.parent;
1sirVariant.parent&&sirVariant.parent.children.forEach(sibling=>{sibling.name&&sibling.name.startsWith("BEADS_-_SIR001_")&&(setNodeAndChildrenVisibility(sibling,!0),sibling.material&&fixMaterialOpacity(sibling.material,sibling.name,sibling),sibling.traverse(child=>{child.material&&fixMaterialOpacity(child.material,child.name,child)}),console.log("[updateModelNode] Also showing variant:",sibling.name))}),sirVariant.children&&sirVariant.children.length>0&&sirVariant.children.forEach(child=>{child.name&&child.name.startsWith("BEADS_-_SIR001_")&&(setNodeAndChildrenVisibility(child,!0),child.material&&fixMaterialOpacity(child.material,child.name,child),child.traverse(grandchild=>{grandchild.material&&fixMaterialOpacity(grandchild.material,grandchild.name,grandchild)}),console.log("[updateModelNode] Also showing child variant:",child.name))})}else console.warn("[updateModelNode] BEADS_-_SIR001 node not found for sir necklace")}if(materialNodes.forEach(node=>{setNodeAndChildrenVisibility(node,!0),node.material&&fixMaterialOpacity(node.material,node.name,node),node.traverse(child=>{child.material&&fixMaterialOpacity(child.material,child.name,child)})}),targetNode.parent){const nodesToKeepVisible=new Set([targetNode,...materialNodes]);if(targetNode.name&&(targetNode.name==="BEADS_-_SIR"||targetNode.name==="BEADS - SIR")){const sirVariant=window.dripModelViewer.model.getObjectByName("BEADS_-_SIR001");sirVariant&&(nodesToKeepVisible.add(sirVariant),console.log("[updateModelNode] Added BEADS_-_SIR001 to nodesToKeepVisible"),sirVariant.parent&&sirVariant.parent.children.forEach(sibling=>{sibling.name&&sibling.name.startsWith("BEADS_-_SIR001_")&&(nodesToKeepVisible.add(sibling),console.log("[updateModelNode] Added variant to nodesToKeepVisible:",sibling.name))}),sirVariant.children&&sirVariant.children.length>0&&sirVariant.children.forEach(child=>{child.name&&child.name.startsWith("BEADS_-_SIR001_")&&(nodesToKeepVisible.add(child),console.log("[updateModelNode] Added child variant to nodesToKeepVisible:",child.name))}),console.log("[updateModelNode] nodesToKeepVisible now has size:",nodesToKeepVisible.size))}const targetBaseName=targetNode.name,numberPattern=new RegExp(`^${targetBaseName.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}_\\d+$`),threeDigitPattern=new RegExp(`^${targetBaseName.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\d{3}$`),dotNumberPattern=new RegExp(`^${targetBaseName.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\.\\d+$`);targetBaseName.includes("SAPPHIRE")&&(console.log("[updateModelNode] Sapphire base name:",targetBaseName),console.log("[updateModelNode] Looking for numbered variants with patterns:"),console.log("  - Underscore pattern:",numberPattern.source),console.log("  - Three digit pattern:",threeDigitPattern.source),console.log("  - Dot pattern:",dotNumberPattern.source),console.log("[updateModelNode] Siblings:",targetNode.parent?.children?.map(c=>c.name))),targetNode.parent.children.forEach(sibling=>{sibling.name&&(numberPattern.test(sibling.name)||threeDigitPattern.test(sibling.name)||dotNumberPattern.test(sibling.name))&&(nodesToKeepVisible.add(sibling),setNodeAndChildrenVisibility(sibling,!0),console.log("[updateModelNode] Found and showing numbered sibling:",sibling.name),console.log("[updateModelNode] Sibling has material?",sibling.material?"yes":"no"),sibling.material&&console.log("[updateModelNode] Material opacity:",sibling.material.opacity))}),targetNode.children&&targetNode.children.length>0&&targetNode.children.forEach(child=>{child.name&&(numberPattern.test(child.name)||threeDigitPattern.test(child.name)||dotNumberPattern.test(child.name))&&(nodesToKeepVisible.add(child),setNodeAndChildrenVisibility(child,!0))}),targetNode.parent.children.forEach(sibling=>{if(!nodesToKeepVisible.has(sibling)){if(sibling.name&&sibling.name.includes("COLLECTION"))return;const sibName=(sibling.name||"").toLowerCase(),ctLower=componentType.toLowerCase();(sibName.startsWith(ctLower+"_-_")||sibName.startsWith(ctLower+" - ")||sibName.startsWith(ctLower+".")||sibName===ctLower||ctLower==="necklace"&&(sibName.startsWith("beads_-_")||sibName.startsWith("beads - ")))&&(sibling.name==="BEADS_-_SIR001"&&(console.log("[updateModelNode] WARNING: About to hide BEADS_-_SIR001 (not in nodesToKeepVisible)"),console.log("[updateModelNode] nodesToKeepVisible size:",nodesToKeepVisible.size)),setNodeAndChildrenVisibility(sibling,!1))}});let currentNode=targetNode.parent;for(;currentNode;)currentNode.visible=!0,currentNode=currentNode.parent}handleInnerBeadsMaterial(componentType,nodeId)}else if(console.warn(`Node '${formattedNodeId}' not found in model`),console.warn("[BuildADrip] Node not found. Debugging:"),console.warn(`  Looking for: "${spaceFormatNodeId}" or "${formattedNodeId}"`),console.warn(`  Component: ${componentType}`),window.dripModelViewer&&window.dripModelViewer.model){const allNodes=[],relevantNodes=[];window.dripModelViewer.model.traverse(n=>{if(n.name){allNodes.push(n.name);const lower=n.name.toLowerCase();(lower.includes(componentType)||lower.includes("spacer")||lower.includes("carabiner")||lower.includes("charm"))&&relevantNodes.push(n.name)}}),console.warn(`[BuildADrip] ${relevantNodes.length} relevant nodes:`,relevantNodes.slice(0,20)),console.warn(`[BuildADrip] Total named nodes: ${allNodes.length}`);const searchLower=spaceFormatNodeId.toLowerCase(),similar=allNodes.filter(name=>name.toLowerCase().includes(searchLower.split(" ")[0])||name.toLowerCase()===searchLower);similar.length>0&&console.warn("[BuildADrip] Similar names:",similar)}};function setNodeAndChildrenVisibility(node,isVisible){node&&(node.visible=isVisible,isVisible&&node.material&&(fixMaterialOpacity(node.material,node.name,node),node.name&&node.name.includes("SAPPHIRE")&&(console.log("[setNodeAndChildrenVisibility] Setting visibility for sapphire node:",node.name),Array.isArray(node.material)?console.log("[setNodeAndChildrenVisibility] Multiple materials:",node.material.map(m=>m.name)):console.log("[setNodeAndChildrenVisibility] Material name:",node.material.name))),node.children&&node.traverse(child=>{child.visible=isVisible,isVisible&&child.material&&(fixMaterialOpacity(child.material,child.name,child),(node.name?.includes("SAPPHIRE")||child.name?.includes("SAPPHIRE"))&&(console.log("[setNodeAndChildrenVisibility] Child node:",child.name||"unnamed"),Array.isArray(child.material)?console.log("[setNodeAndChildrenVisibility] Child has multiple materials:",child.material.map(m=>m.name)):console.log("[setNodeAndChildrenVisibility] Child material name:",child.material.name)))}))}function fixMaterialOpacity(material,nodeName="",node=null){if(Array.isArray(material)){material.forEach(mat=>fixMaterialOpacity(mat,nodeName,node));return}const lowerName=nodeName.toLowerCase();if(lowerName.includes("carabiner")||lowerName.includes("charm")){material.needsUpdate=!0;return}if(lowerName.includes("spacer")){material.needsUpdate=!0;return}if(material.transmission&&material.transmission>0&&!lowerName.includes("sapphire")&&!lowerName.includes("apple")){if(node){const oldMat=material;let opaqueMap=null;if(oldMat.map&&oldMat.map.image)try{const img=oldMat.map.image,w=img.width||img.naturalWi
1dth,h=img.height||img.naturalHeight;if(w&&h){const canvas=document.createElement("canvas");canvas.width=w,canvas.height=h;const ctx=canvas.getContext("2d");ctx.drawImage(img,0,0,w,h);const imageData=ctx.getImageData(0,0,w,h),px=imageData.data;for(let i=3;i<px.length;i+=4)px[i]=255;ctx.putImageData(imageData,0,0),opaqueMap=new THREE.CanvasTexture(canvas),opaqueMap.encoding=oldMat.map.encoding,opaqueMap.wrapS=oldMat.map.wrapS,opaqueMap.wrapT=oldMat.map.wrapT,opaqueMap.flipY=oldMat.map.flipY,opaqueMap.needsUpdate=!0}}catch(e){console.warn("[fixMaterialOpacity] Could not strip texture alpha:",e),opaqueMap=oldMat.map}let matColor=oldMat.color?oldMat.color.clone():new THREE.Color(1,1,1);if(!oldMat.map&&oldMat.name&&!(oldMat.name||"").toLowerCase().includes("spacer")){const hexMatch=oldMat.name.match(/\b([0-9A-Fa-f]{6})\b/);hexMatch&&(matColor=new THREE.Color("#"+hexMatch[1]),console.log("[fixMaterialOpacity] Extracted color from material name:",oldMat.name,"\u2192 #"+hexMatch[1]))}const newMat=new THREE.MeshStandardMaterial({color:matColor,map:opaqueMap,metalness:oldMat.metalness??0,roughness:oldMat.roughness??.5,normalMap:oldMat.normalMap||null,aoMap:oldMat.aoMap||null,emissive:oldMat.emissive?oldMat.emissive.clone():new THREE.Color(0,0,0),emissiveMap:oldMat.emissiveMap||null,envMap:oldMat.envMap||null,envMapIntensity:oldMat.envMapIntensity??1,side:THREE.DoubleSide,depthWrite:!0,alphaTest:0,name:oldMat.name}),matNameLower=(oldMat.name||"").toLowerCase();if(matNameLower.includes("spacer"))newMat.color=new THREE.Color("#ff0015"),newMat.opacity=1,newMat.transparent=!1,newMat.depthWrite=!0,newMat.roughness=.05,newMat.metalness=0,newMat.envMapIntensity=0;else if(matNameLower.includes("clear quartz"))newMat.map=null,newMat.opacity=.4,newMat.transparent=!0,newMat.depthWrite=!1,newMat.roughness=0,newMat.metalness=.15,newMat.envMapIntensity=5,newMat.color=new THREE.Color(.97,.98,1),newMat.emissive=new THREE.Color(.15,.15,.18);else if(matNameLower.includes("candy")&&!matNameLower.includes("bead")){newMat.opacity=.65,newMat.transparent=!0,newMat.depthWrite=!1;const hsl={};newMat.color.getHSL(hsl),newMat.color.setHSL(hsl.h,Math.min(hsl.s*2,1),hsl.l*.85)}else(matNameLower.includes("scarlet")||matNameLower.includes("glass"))&&!matNameLower.includes("bead")?(newMat.opacity=.65,newMat.transparent=!0,newMat.depthWrite=!1):(newMat.opacity=1,newMat.transparent=!1);node.material=newMat,console.log("[fixMaterialOpacity] Replaced transmission material with MeshStandardMaterial:",nodeName,{materialName:oldMat.name,hadMap:!!oldMat.map,hadAlphaMap:!!oldMat.alphaMap,oldTransmission:oldMat.transmission,oldOpacity:oldMat.opacity})}return}if(nodeName.toLowerCase().includes("apple")&&material.name&&material.name.toLowerCase().includes("watermelon")&&(material.transparent=!0,material.opacity=.5,material.ior=.5,material.thickness=1,material.envMapIntensity=1.2),nodeName.toLowerCase().includes("sapphire")){const originalOpacity=material.opacity,originalTransparent=material.transparent;if(material.opacity<.3&&(material.opacity=1),material.opacity>=1&&(material.transparent=!1),material.name&&material.name.toLowerCase().includes("gem")&&(material.metalness=.849,material.roughness=.032,material.transparent=!0,material.opacity=.85,material.transmission=0,material.ior=.5,material.thickness=1,material.envMapIntensity=2,material.clearcoat=1,material.clearcoatRoughness=.05,material.depthWrite=!0),material.color){const brightness=(material.color.r+material.color.g+material.color.b)/3;console.log("[fixMaterialOpacity] Sapphire color brightness:",brightness,"RGB:",{r:material.color.r,g:material.color.g,b:material.color.b})}material.needsUpdate=!0,console.log("[fixMaterialOpacity] Sapphire material:",nodeName,{name:material.name,opacityBefore:originalOpacity,opacityAfter:material.opacity,transparentBefore:originalTransparent,transparentAfter:material.transparent,metalness:material.metalness,roughness:material.roughness,envMapIntensity:material.envMapIntensity,hasMap:!!material.map,hasColor:!!material.color});return}const matNameLowerForSage=(material.name||"").toLowerCase();if(!matNameLowerForSage.includes("spacer")&&(matNameLowerForSage.includes("sage stone")||lowerName.includes("sage")&&matNameLowerForSage.includes("sage"))){if(node&&material.map&&material.map.image)try{const img=material.map.image,w=img.width||img.naturalWi
1dth,h=img.height||img.naturalHeight;if(w&&h){const canvas=document.createElement("canvas");canvas.width=w,canvas.height=h;const ctx=canvas.getContext("2d");ctx.drawImage(img,0,0,w,h);const px=ctx.getImageData(0,0,w,h).data;let rSum=0,gSum=0,bSum=0,count=0;for(let i=0;i<px.length;i+=4)px[i+3]>128&&(rSum+=px[i],gSum+=px[i+1],bSum+=px[i+2],count++);const avgR=count?Math.round(rSum/count):180,avgG=count?Math.round(gSum/count):200,avgB=count?Math.round(bSum/count):180;ctx.clearRect(0,0,w,h),ctx.fillStyle=`rgb(${avgR},${avgG},${avgB})`,ctx.fillRect(0,0,w,h),ctx.drawImage(img,0,0,w,h);const finalData=ctx.getImageData(0,0,w,h),fp=finalData.data;for(let i=3;i<fp.length;i+=4)fp[i]=255;ctx.putImageData(finalData,0,0);const opaqueMap=new THREE.CanvasTexture(canvas);opaqueMap.encoding=material.map.encoding,opaqueMap.wrapS=material.map.wrapS,opaqueMap.wrapT=material.map.wrapT,opaqueMap.flipY=material.map.flipY,opaqueMap.needsUpdate=!0,material.map=opaqueMap,console.log("[fixMaterialOpacity] Sage texture fill color:",`rgb(${avgR},${avgG},${avgB})`,"from",count,"visible pixels")}}catch(e){console.warn("[fixMaterialOpacity] Could not process sage texture:",e)}material.transparent=!0,material.opacity=.6,material.side=THREE.DoubleSide,material.depthWrite=!1,material.roughness=0,material.metalness=0,material.envMapIntensity=3.5,material.color&&(material.emissive=material.color.clone().multiplyScalar(.3)),material.clearcoat!==void 0&&(material.clearcoat=1,material.clearcoatRoughness=0),material.needsUpdate=!0,console.log("[fixMaterialOpacity] Applied gem-like properties to sage stone:",nodeName,{materialName:material.name,opacity:material.opacity});return}material.opacity<.3?(material.opacity=1,material.transparent=!1,material.depthWrite=!0,material.alphaTest=0,material.needsUpdate=!0,console.log("[fixMaterialOpacity] Fixed invisible material (opacity was < 0.3):",nodeName,{materialName:material.name,hasMap:!!material.map,hasAlphaMap:!!material.alphaMap})):nodeName.toLowerCase().includes("pearl")&&(node&&node.material&&!node.material.userData.clonedForPearl&&(node.material=node.material.clone(),node.material.userData.clonedForPearl=!0,material=node.material),material.opacity=1,material.metalness=.3,material.roughness=.3,material.envMapIntensity=.2,material.needsUpdate=!0),material.needsUpdate=!0}function findRelatedMaterialNodes(formattedNodeId,spaceFormatNodeId,upperCaseFormatNodeId,upperCaseUnderscoreNodeId){const materialNodes=[];return[`${formattedNodeId}_SPACER`,`${formattedNodeId}_SPACERS`,`${formattedNodeId}_Spacer`,`${formattedNodeId}_Spacers`,`${formattedNodeId}_Material`,`${formattedNodeId}_Materials`,`${formattedNodeId}_Inner`,`${formattedNodeId}_Beads`,`${formattedNodeId}_Inner_Beads`,`${formattedNodeId} SPACER`,`${formattedNodeId} SPACERS`,`${formattedNodeId} Spacer`,`${formattedNodeId} Spacers`,`${formattedNodeId} Material`,`${formattedNodeId} Materials`,`${spaceFormatNodeId} SPACER`,`${spaceFormatNodeId} SPACERS`,`${spaceFormatNodeId} Spacer`,`${spaceFormatNodeId} Spacers`,`${spaceFormatNodeId} Material`,`${spaceFormatNodeId} Materials`,`${spaceFormatNodeId} Inner`,`${spaceFormatNodeId} Beads`,`${upperCaseFormatNodeId} SPACER`,`${upperCaseFormatNodeId} SPACERS`,`${upperCaseFormatNodeId} Material`,`${upperCaseFormatNodeId} Materials`,`${upperCaseFormatNodeId} Inner`,`${upperCaseFormatNodeId} Beads`,`${upperCaseUnderscoreNodeId}_SPACER`,`${upperCaseUnderscoreNodeId}_SPACERS`,`${upperCaseUnderscoreNodeId}_Material`,`${upperCaseUnderscoreNodeId}_Materials`,`${upperCaseUnderscoreNodeId}_Inner`,`${upperCaseUnderscoreNodeId}_Beads`].forEach(name=>{const node=window.dripModelViewer.model.getObjectByName(name);node&&(materialNodes.push(node),console.log("[findRelatedMaterialNodes] Found material node:",name))}),materialNodes.length===0&&console.warn("[findRelatedMaterialNodes] No material nodes found for:",formattedNodeId),materialNodes}function handleInnerBeadsMaterial(componentType,nodeId){if(componentType.toLowerCase()==="necklace"){const formattedNodeId=formatNodeName(nodeId),beadName=nodeId.replace(/^necklace\s*-?\s*/i,"").trim(),capitalizedBeadName=beadName.charAt(0).toUpperCase()+beadName.slice(1),specificSpacerNames=[`${formattedNodeId}_SPACER`,`${formattedNodeId}_SPACERS`,`NECKLACE_-_${beadName.toUpperCase()}_SPACER`,`NECKLACE_-_${beadName.toUpperCase()}_SPACERS`,`NECKLACE - ${capitalizedBeadName} SPACER`,`NECKLACE - ${capitalizedBeadName} SPACERS`,`NECKLACE - ${beadName.toUpperCase()} SPACER`,`NECKLACE - ${beadName.toUpperCase()} SPACERS`,`NECKLACE - ${beadName} SPACER`,`NECKLACE - ${beadName} SPACERS`];let spacerFound=!1;
1if(specificSpacerNames.forEach(spacerName=>{const spacerNode=window.dripModelViewer.model.getObjectByName(spacerName);spacerNode&&(spacerNode.visible=!0,spacerFound=!0,spacerNode.material&&fixMaterialOpacity(spacerNode.material,spacerNode.name,spacerNode),spacerNode.traverse(child=>{child.visible=!0,child.material&&fixMaterialOpacity(child.material,child.name,child)}))}),!spacerFound){const innerBeadsNode=window.dripModelViewer.model.getObjectByName("InnerBeads");innerBeadsNode&&(innerBeadsNode.visible=!0,innerBeadsNode.material&&fixMaterialOpacity(innerBeadsNode.material,innerBeadsNode.name,innerBeadsNode),innerBeadsNode.traverse(child=>{child.visible=!0,child.material&&fixMaterialOpacity(child.material,child.name,child)}))}getAllNodes(window.dripModelViewer.model).forEach(node=>{const nodeName=node.name?node.name.toLowerCase():"";(nodeName.includes("bead")||nodeName.includes("inner")||nodeName.includes("material")||nodeName.includes("spacer"))&&node.visible&&(node.material&&fixMaterialOpacity(node.material,node.name,node),node.traverse(child=>{child.material&&fixMaterialOpacity(child.material,child.name,child)}))})}}function formatNodeName(nodeName){const parts=nodeName.split(" "),componentType=parts[0].toLowerCase();return parts.map((part,index)=>part==="-"?"-":index===0&&componentType==="necklace"?part.toUpperCase():part.charAt(0).toUpperCase()+part.slice(1)).join("_")}function hideAllNodesOfComponentType(componentType){if(!window.dripModelViewer||!window.dripModelViewer.model){console.warn("[hideAllNodesOfComponentType] Model not ready, skipping");return}const allNodes=getAllNodes(window.dripModelViewer.model),formattedComponentType=componentType.charAt(0).toUpperCase()+componentType.slice(1),upperComponentType=componentType.toUpperCase();allNodes.forEach(node=>{if(node.name){const name=node.name;if(name==="NECKLACE_BEAN001"){const isSirSelected=(window.buildADripConfigurator?.currentOptions?.beads?.colorName?.toLowerCase()||"").includes("sir");if(componentType==="necklace"&&isSirSelected){console.log("[hideAllNodesOfComponentType] Skipping NECKLACE_BEAN001 (sir's carabiner) - necklace mode");return}if(componentType==="carabiner"){const isGoldCarabiner=(window.buildADripConfigurator?.currentOptions?.carabiner?.colorName?.toLowerCase()||"").includes("gold");if(isSirSelected&&isGoldCarabiner){console.log("[hideAllNodesOfComponentType] Skipping NECKLACE_BEAN001 (sir's carabiner) - carabiner mode");return}else{console.log("[hideAllNodesOfComponentType] Hiding NECKLACE_BEAN001 - not sir+gold"),node.visible=!1;return}}}let matches=name.startsWith(formattedComponentType+"_-_")||name.startsWith(formattedComponentType+" - ")||name.startsWith(upperComponentType+"_-_")||name.startsWith(upperComponentType+" - ");componentType==="necklace"&&(matches=matches||name.startsWith("BEADS_-_")||name.startsWith("BEADS - ")||name.startsWith("Beads_-_")||name.startsWith("Beads - ")||name.startsWith("Chain_-_")||name.startsWith("Chain - ")||name.startsWith("CHAIN_-_")||name.startsWith("CHAIN - ")),matches&&(node.visible=!1)}})}function getAllNodes(node){const nodes=[];function traverse(currentNode){nodes.push(currentNode),currentNode.children&&currentNode.children.forEach(child=>traverse(child))}return traverse(node),nodes}function findNodesByName(node,name,result){node.name===name&&result.push(node),node.children&&node.children.forEach(child=>{findNodesByName(child,name,result)})}function setupAccordions(){const groups=document.querySelectorAll(".option-group"),headers=document.querySelectorAll(".option-group-header");if(groups.length===0)return;if(window.innerHeight>=700){groups.forEach(group=>{group.classList.add("active");const icon=group.querySelector(".accordion-toggle .icon");icon&&(icon.textContent="\u2212")});return}groups.forEach((group,i)=>{if(i===0){group.classList.add("active");const icon=group.querySelector(".accordion-toggle .icon");icon&&(icon.textContent="\u2212")}else{group.classList.remove("active");const icon=group.querySelector(".accordion-toggle .icon");icon&&(icon.textContent="+")}}),headers.forEach(header=>{header.addEventListener("click",()=>{const currentGroup=header.closest(".option-group");groups.forEach(group=>
1{const icon=group.querySelector(".accordion-toggle .icon");if(group===currentGroup){const isActive=group.classList.contains("active");group.classList.toggle("active"),icon&&(icon.textContent=isActive?"+":"\u2212")}})})})}if(window.buildADripConfigurator||(window.buildADripConfigurator=new BuildADripConfigurator),setTimeout(()=>{const addToCartBtn=document.getElementById("add-to-cart");addToCartBtn&&!addToCartBtn.hasAttribute("data-listener-added")&&(console.log("Fallback: Adding event listener to add to cart button"),addToCartBtn.addEventListener("click",()=>{console.log("Fallback: Add to cart button clicked!"),window.buildADripConfigurator?window.buildADripConfigurator.addToCart():console.error("buildADripConfigurator not available")}),addToCartBtn.setAttribute("data-listener-added","true"))},1e3),container&&!window.dripModelViewer){const modelUrl="v12.glb";let modelLoadHandled=!1;window.addEventListener("model-loaded",()=>{if(!modelLoadHandled){modelLoadHandled=!0;try{window.buildADripConfigurator?.updateModel()}catch(error){console.error("[initBuildADrip] Error in updateModel (event):",error)}finally{modelLoader&&(modelLoader.style.display="none")}}},{once:!0}),window.dripModelViewer=new DripModelViewer("build-a-drip-model-viewer",modelUrl),setTimeout(()=>{if(window.dripModelViewer?.model&&!modelLoadHandled){modelLoadHandled=!0;try{window.buildADripConfigurator?.updateModel()}catch(error){console.error("[initBuildADrip] Error in updateModel (already loaded):",error)}finally{modelLoader&&(modelLoader.style.display="none")}}},100)}}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",initBuildADrip):initBuildADrip();
2//# sourceMappingURL=/cdn/shop/t/170/assets/build-a-drip.js.map?v=137620586018604072201788310659

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.