1if(!customElements.get("cart-discount-code")){class CartDiscountCode extends HTMLElement{connectedCallback(){this.dataset.initialized!=="true"&&(this.dataset.initialized="true",this.appliedCodes=[],this.panel=this.querySelector(".cart-sidebar-discount__panel"),this.triggerButton=this.querySelector(".cart-sidebar-discount__trigger"),this.codesList=this.querySelector(".cart-sidebar-discount__codes-list"),this.input=this.querySelector(".cart-sidebar-discount__input"),this.applyButton=this.querySelector(".cart-sidebar-discount__apply"),this.errorElement=this.querySelector(".cart-sidebar-discount__error"),this.onTriggerClick=()=>{this.setPanelOpen(!this.classList.contains("is-open"))},this.onApplyClick=event=>{event.preventDefault(),event.stopPropagation(),this.onApply()},this.onCodesListClick=event=>{const removeButton=event.target.closest("[data-remove-index]");removeButton&&(event.preventDefault(),event.stopPropagation(),this.onRemoveCode(Number(removeButton.dataset.removeIndex)))},this.onInputKeydown=event=>{event.key==="Enter"&&(event.preventDefault(),this.onApply())},this.onInputInput=()=>{this.toggleApplyState()},this.triggerButton?.addEventListener("click",this.onTriggerClick),this.applyButton?.addEventListener("click",this.onApplyClick),this.codesList?.addEventListener("click",this.onCodesListClick),this.input?.addEventListener("keydown",this.onInputKeydown),this.input?.addEventListener("input",this.onInputInput),this.toggleApplyState(),this.scheduleSyncFromCart(),typeof subscribe=="function"&&typeof PUB_SUB_EVENTS<"u"&&(this.cartUpdateUnsubscriber=subscribe(PUB_SUB_EVENTS.cartUpdate,event=>{event.source!=="cart-discount-code"&&this.syncFromCart()})))}disconnectedCallback(){this.triggerButton?.removeEventListener("click",this.onTriggerClick),this.applyButton?.removeEventListener("click",this.onApplyClick),this.codesList?.removeEventListener("click",this.onCodesListClick),this.input?.removeEventListener("keydown",this.onInputKeydown),this.input?.removeEventListener("input",this.onInputInput),this.cartUpdateUnsubscriber&&(this.cartUpdateUnsubscriber(),this.cartUpdateUnsubscriber=void 0)}getCartUrl(){return(window.routes?.cart_url||"/cart").replace(/\/$/,"")}getCartUpdateUrl(){return window.routes?.cart_update_url||"/cart/update.js"}scheduleSyncFromCart(){const runSync=()=>{this.syncFromCart()};if(window.routes?.cart_url){runSync();return}if(document.readyState==="loading"){document.addEventListener("DOMContentLoaded",runSync,{once:!0});return}window.requestAnimationFrame(runSync)}setPanelOpen(isOpen){this.classList.toggle("is-open",isOpen),this.triggerButton?.setAttribute("aria-expanded",isOpen?"true":"false"),isOpen&&window.requestAnimationFrame(()=>this.input?.focus())}toggleApplyState(){!this.applyButton||!this.input||(this.applyButton.disabled=this.input.value.trim().length===0)}setLoading(isLoading){this.applyButton&&(isLoading?(this.applyButton.disabled=!0,this.applyButton.classList.add("is-loading"),this.applyButton.innerHTML=`<span class="visually-hidden">${this.getLabel("applyingLabel")}</span><span class="cart-sidebar-discount__loader" aria-hidden="true"></span>`):(this.applyButton.classList.remove("is-loading"),this.applyButton.textContent=this.getLabel("applyLabel"),this.toggleApplyState()))}setError(message){this.errorElement&&(this.errorElement.textContent=message?this.decodeHtmlEntities(message):""),message&&this.setPanelOpen(!0)}decodeHtmlEntities(value){if(!value)return value;const element=document.createElement("textarea");return element.innerHTML=value,element.value}getLabel(name,fallback=""){return this.decodeHtmlEntities(this.dataset[name]||fallback)}normalizeCode(code){return code.trim().toLowerCase()}looksLikeDiscountCode(value){const trimmed=String(value||"").trim();return trimmed?!(trimmed.includes(" ")&&trimmed.length>20):!1}getAppliedCodesFromCart(cart){const codes=[],seen=new Set,addCode=code=>{const trimmedCode=String(code||"").trim(),normalizedCode=this.normalizeCode(trimmedCode);!trimmedCode||!this.looksLikeDiscountCode(trimmedCode)||seen.has(normalizedCode)||(seen.add(normalizedCode),codes.push(trimmedCode))};return Array.isArray(cart.discount_codes)&&cart.discount_codes.forEac
1h(entry=>{if(!(!entry?.code||entry.applicable===!1)){if(entry.applicable===!0){addCode(entry.code);return}addCode(entry.code)}}),!codes.length&&Array.isArray(cart.cart_level_discount_applications)&&cart.cart_level_discount_applications.forEach(application=>{application?.type==="discount_code"&&application.title&&addCode(application.title)}),codes}formatInvalidForCartMessage(code){return this.getLabel("invalidForCartLabel","{{ code }} isn't valid for this cart.").replace(/\{\{\s*code\s*\}\}/gi,code)}looksLikeApiErrorMessage(entryCode,attemptedCode){const message=entryCode.trim();return message?this.normalizeCode(message)!==this.normalizeCode(attemptedCode)&&(message.includes(" ")||message.length>40):!1}getDiscountErrorMessage(cart,attemptedCode,previousCodes,fallback){if(!Array.isArray(cart.discount_codes)||!attemptedCode)return fallback;const normalizedAttempt=this.normalizeCode(attemptedCode),previousNormalized=new Set((previousCodes||[]).map(entry=>this.normalizeCode(entry))),rejected=cart.discount_codes.filter(entry=>entry.applicable===!1&&entry.code);if(!rejected.length)return fallback;if(rejected.find(entry=>this.normalizeCode(entry.code)===normalizedAttempt))return this.formatInvalidForCartMessage(attemptedCode);const newRejections=rejected.filter(entry=>!previousNormalized.has(this.normalizeCode(entry.code)));if(newRejections.length){const apiErrorEntry=newRejections.find(entry=>this.looksLikeApiErrorMessage(entry.code,attemptedCode));return apiErrorEntry?apiErrorEntry.code.trim():this.formatInvalidForCartMessage(attemptedCode)}const firstRejected=rejected[0];return this.looksLikeApiErrorMessage(firstRejected.code,attemptedCode)?firstRejected.code.trim():this.formatInvalidForCartMessage(firstRejected.code)}isCodeValidOnCart(cart,code){if(!Array.isArray(cart.discount_codes))return!1;const normalizedCode=this.normalizeCode(code);return cart.discount_codes.some(entry=>entry.applicable===!0&&entry.code&&this.normalizeCode(entry.code)===normalizedCode)}setAppliedCodes(codes){const uniqueCodes=[],seen=new Set;codes.forEach(code=>{const trimmedCode=code.trim(),normalizedCode=this.normalizeCode(trimmedCode);!trimmedCode||seen.has(normalizedCode)||(seen.add(normalizedCode),uniqueCodes.push(trimmedCode))}),this.appliedCodes=uniqueCodes,this.classList.toggle("has-codes",uniqueCodes.length>0),this.renderAppliedCodes()}escapeHtml(value){return String(value).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}renderAppliedCodes(){if(!this.codesList)return;const removeLabelTemplate=this.getLabel("removeCodeLabel","Remove {{ code }}");this.codesList.innerHTML=this.appliedCodes.map((code,index)=>{const safeCode=this.escapeHtml(code),removeLabel=this.escapeHtml(removeLabelTemplate.replace("{{ code }}",code));return` 2 <li class="cart-sidebar-discount__code-chip"> 3 <span class="cart-sidebar-discount__code-value">${safeCode}</span> 4 <button 5 type="button" 6 class="cart-sidebar-discount__code-remove" 7 data-remove-index="${index}" 8 aria-label="${removeLabel}" 9 >×</button> 10 </li> 11 `}).join("")}async fetchCart(){const response=await fetch(`${this.getCartUrl()}.js`);if(!response.ok)throw new Error("Cart fetch failed");return response.json()}async updateCartSections(){if(this.dataset.context!=="drawer")return;const response=await fetch(`${this.getCartUrl()}?section_id=cart-drawer`);if(!response.ok)return;const responseText=await response.text(),html=new DOMParser().parseFromString(responseText,"text/html");["cart-drawer-items",".cart-drawer__footer"].forEach(selector=>{const targetElement=document.querySelector(selector),sourceElement=html.querySelector(selector);targetElement&&sourceElement&&targetElement.replaceWith(sourceElement)}),typeof publish=="function"&&typeof PUB_SUB_EVENTS<"u"&&publish(PUB_SUB_EVENTS.cartUpdate,{source:"cart-discount-code"})}async applyDiscountCodes(codes){const payload={discount:codes.length?codes.join(","):""},response=await fetch(this.getCartUpdateUrl(),{...fetchConfig(),body:JSON.stringify(payload)});if(!response.ok)throw new Error("Discount update failed");return response.json()}async onApply(){const code=this.input?.value.trim();if(!code){this.setError(this.getLabel("invalidLabel"));return}if(this.appliedCodes.some(appliedCode=>this.normalizeCode(appliedCode)===this.normalizeCode(code))){this.setError(this.getLabel("alreadyAppliedLabel"));return}this.setError(""),this.setLoading(!0);const previousCodes=[...this.appliedCodes],nextCodes=[...this.appliedCodes,code];try{const cart=await this.applyDiscountCodes(nextCodes);if(this.isCodeValidOnCart(cart,code))this.setAppliedCodes(this.getAppliedCodesFromCart(cart)),this.input&&(this.input.value=""),this.setPanelOpen(!1),await this.updateCartSections();else{await this.applyDiscountCodes(previousCodes);const revertedCart=await this.fetchCart();this.setAppliedCodes(this.getAppliedCodesFromCart(revertedCart)),this.setError(this.getDiscountErrorMessage(cart,code,previousCodes,this.getLabel("invalidLabel")))}}catch(error){console.error(error);try{await this.applyDiscountCodes(previousCodes);const revertedCart=await this.fetchCart();this.setAppliedCodes(this.getAppliedCodesFromCart(revertedCart))}catch(revertError){console.error(revertError)}this.setError(this.getLabel("errorLabel"))}finally{this.setLoading(!1)}}
11async onRemoveCode(codeIndex){if(!this.appliedCodes[codeIndex])return;this.setError("");const nextCodes=this.appliedCodes.filter((_,index)=>index!==codeIndex);try{await this.applyDiscountCodes(nextCodes);const cart=await this.fetchCart();this.setAppliedCodes(this.getAppliedCodesFromCart(cart)),this.input&&(this.input.value=""),this.toggleApplyState(),nextCodes.length===0?this.setPanelOpen(!0):this.setPanelOpen(!1),await this.updateCartSections()}catch(error){console.error(error),this.setError(this.getLabel("errorLabel"))}}async syncFromCart(){try{const cart=await this.fetchCart();this.setAppliedCodes(this.getAppliedCodesFromCart(cart))}catch(error){console.error(error)}}}customElements.define("cart-discount-code",CartDiscountCode)} 12//# sourceMappingURL=/cdn/shop/t/200/assets/cart-discount-code.js.map?v=117812665682183072861790001946
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.