window.checkoutOptionsData = {"url":"https:\/\/enhanced-checkout-options.com\/checkout\/1ih2d8","enabled":true,"message":"Subscription is not active.","places":[{"id":"cart","name":"Cart","page":"cart","selectors":[{"selector":".cart-totals","position":"inside","tag":"table","class":"cart-section"}],"enabled":true,"groups":[{"name":"Fully Insure Order for $3.99","description":"Full coverage for loss and damage on your package","type":"checkbox","is_mandatory":false,"id":125,"specific_countries":[],"options":[{"name":"Fully Insure Order Against Loss and Damage","is_default":1,"price":"3.99","checked":false,"sku":"order-insurance","show_price":true,"item_id":null,"has_note":false,"note":""}]}]}],"allEnabledOptionSkus":[{"sku":"order-insurance","name":"Fully Insure Order Against Loss and Damage"},{"sku":"free-return","name":"Free returns & exchanges for $3.99 (US Customers)"}],"redirectAfterOptionSelect":false,"script":"https:\/\/enhanced-checkout-options.com\/js\/cart.js","currency":{"code":"USD","format":"${{PRICE}}"}}; // Guard against this script running more than once on the same page (e.g. a // duplicate script-tag registration, or a stale entry left over from a // reinstall). Without this, a second execution's top-level `let`/`const` // declarations collide with the first's in the shared global scope and throw // "Identifier '...' has already been declared" - a SyntaxError that aborts // the *entire* second script before it runs a single statement. Wrapping the // rest in a block also makes these declarations block-scoped, so even an // unguarded second load can no longer redeclare them. if (!window.__ecoCartBootLoaded) { window.__ecoCartBootLoaded = true; let places = window.checkoutOptionsData.places; window.checkoutApplicationBaseApiUrl = window.checkoutOptionsData.url; window.checkoutOptionsPlaces = window.checkoutOptionsData.places; window.reloadData = false; const addScript = async src => new Promise((resolve, reject) => { const el = document.createElement('script'); el.src = src; el.addEventListener('load', resolve); el.addEventListener('error', reject); document.body.append(el); }); const hideTotalsFromCart = () => { const namesToHide = []; if (window.checkoutOptionsData && window.checkoutOptionsData.allEnabledOptionSkus) { window.checkoutOptionsData.allEnabledOptionSkus.forEach(option => { namesToHide.push(option.name); }); } if (namesToHide.length === 0) { return; } // This runs on every insertPlaceHolders() poll (every 100ms). Only touch the DOM // when something actually changed - unconditionally removing and recreating the // .cart-total--custom
  • every tick made it impossible to interact with (e.g. // inspect) and constantly churned the cart totals list for no reason. const cartTotalsList = document.querySelector('ul.cart-totals'); const matchedNames = new Set(); const items = document.querySelectorAll('tr.cart-item'); items.forEach(item => { const nameElement = item.querySelector('.cart-item-name__label, .cart-item-name a, .cart-item-name'); if (!nameElement) return; const name = nameElement.textContent.trim().replace(/\s+/g, ' '); const shouldHide = namesToHide.includes(name); if (shouldHide) { matchedNames.add(name); if (item.style.display !== 'none') { item.style.display = 'none'; } if (cartTotalsList) { const priceElement = item.querySelector('.cart-item-value'); const price = priceElement ? priceElement.textContent.trim() : ''; const existing = cartTotalsList.querySelector( `.cart-total--custom[data-option-name="${CSS.escape(name)}"]` ); if (existing) { const valueEl = existing.querySelector('.cart-total-value span'); if (valueEl && valueEl.textContent.trim() !== price) { valueEl.textContent = price; } } else { const customTotal = document.createElement('li'); customTotal.className = 'cart-total cart-total--custom'; customTotal.dataset.optionName = name; customTotal.innerHTML = `
    ${name}:
    ${price}
    `; cartTotalsList.prepend(customTotal); } } } else if (item.style.display !== '') { item.style.display = ''; } }); // Drop custom totals for items that are no longer in the cart / no longer matched. if (cartTotalsList) { cartTotalsList.querySelectorAll('.cart-total--custom').forEach(el => { if (!matchedNames.has(el.dataset.optionName)) { el.remove(); } }); } const miniCartItems = document.querySelectorAll('.previewCartItem'); miniCartItems.forEach(item => { const nameElement = item.querySelector('.previewCartItem-name a'); if (nameElement) { const name = nameElement.textContent.trim(); const shouldHide = namesToHide.includes(name); if (shouldHide) { if (item.style.display !== 'none') item.style.display = 'none'; } else { if (item.style.display !== '') item.style.display = ''; } } }); } const insertPlaceHolders = () => { hideTotalsFromCart(); window.checkoutOptionsPlaces.map((place, index) => { if (!place.enabled) return false; place.selectors.map((sel, index) => { let element = document.querySelector(sel.selector); let id = `cart-options-placeholder-${index}`; if (element && !document.getElementById(id)) { let placeHolder = document.createElement(sel.tag ?? 'div'); placeHolder.className = sel.class; placeHolder.id = id; placeHolder.dataset.checkoutOption = place.id; placeHolder.innerHTML = ["
  • " , "Loading..." , "
  • "].join(''); if (sel.position === 'before') { element.parentNode.insertBefore(placeHolder, element) } else if (sel.position === 'inside') { element.append(placeHolder); } else { element.parentNode.insertBefore(placeHolder, element.nextSibling); } } }); }); setTimeout(insertPlaceHolders, 100); } insertPlaceHolders(); setTimeout(() => { fetch('/api/storefront/carts', { method: "GET", credentials: "same-origin" }) .then(response => response.json()) .then(result => { addScript((document.location.href.indexOf("debug") > 0 ? "http://localhost/js/cart.js" : window.checkoutOptionsData.script) + "?v=5&id=" + result[0].id).then(); window.bigcommerceCartId = result[0].id; }) .catch(error => console.error(error)); }, 300) document.addEventListener('DOMContentLoaded', function () { const cartContent = document.querySelector('[data-cart-content]'); if (!cartContent) return; let removeTimeout = null; const observer = new MutationObserver(function () { clearTimeout(removeTimeout); removeTimeout = setTimeout(function () { window.reloadData = true; const section = document.querySelector('.cart-section'); if (section) { section.remove(); } }, 1); }); observer.observe(cartContent, { childList: true, subtree: true }); }); }