1import{QuantitySelectorComponent}from"@theme/component-quantity-selector";const DATA_ELEMENT_ID="order-unit-limit-data",SECTION_ID="order-unit-limit",REBUY_FLYOUT=".rebuy-cart__flyout",REBUY_ITEM_REMOVE=".rebuy-cart__flyout-item-remove",REBUY_ITEM_QUANTITY=".rebuy-cart__flyout-item-quantity",NOTICE_CLASS="bl101-unit-limit-notice",NOTICE_LINK_CLASS="bl101-unit-limit-notice__link",BLOCKED_CLASS="bl101-unit-limit-blocked",OWNED_ATTRIBUTE="data-bl101-unit-limit-disabled",REBUY_CHECKOUT_CONTAINER='[data-target="checkout-buttons-container"]',REBUY_CHECKOUT_SELECTOR=`${REBUY_CHECKOUT_CONTAINER} button`,REBUY_ROOTS=`${REBUY_FLYOUT}, ${REBUY_CHECKOUT_CONTAINER}`,REBUY_CHECKOUT_AREA='[data-rebuy-component="checkout-area"]',EXCEEDED_CLASS="bl101-unit-limit-exceeded",REBUY_REFRESH_EVENTS=["rebuy:cart.change","rebuy:smartcart.ready","rebuy:smartcart.show","rebuy:smartcart.line-item-increase","rebuy:smartcart.line-item-decrease","rebuy:smartcart.line-item-removed","rebuy.add","rebuy.change"],THEME_REFRESH_EVENT="cart:update",state={units:0,cap:1/0,remaining:1/0,over:!1},debug={source:"init",lastError:null,events:[],observerRoot:null,mutationsIgnored:0},lastRead={cap:null,units:null};export function getOrderUnitLimitState(){return{...state}}export function clampToOrderUnitLimit(selector,base){if(!Number.isFinite(state.remaining))return base;const{min,cartQuantity}=selector.getCurrentValues(),isCartLine=!!selector.refs.quantityInput?.dataset.cartLine,allowance=Math.max(isCartLine?cartQuantity+state.remaining:state.remaining,min);return base===null?allowance:Math.min(base,allowance)}function readState(source){lastRead.cap=source.cap,lastRead.units=source.units;const cap=Number(source.cap);if(!Number.isFinite(cap)||cap<=0)return!1;state.cap=cap;const units=Number(source.units);return!Number.isFinite(units)||units<0?"cap":(state.units=units,state.remaining=Math.max(cap-units,0),state.over=units>cap,"full")}function readFromCartAttrs(){const host=document.querySelector("[data-unit-limit-cap]");return host instanceof HTMLElement?readState({cap:host.dataset.unitLimitCap,units:host.dataset.unitLimitUnits}):!1}function readFromJsonBlob(){const blob=document.getElementById(DATA_ELEMENT_ID);if(!blob?.textContent)return!1;try{return readState(JSON.parse(blob.textContent))}catch{return!1}}async function readFromCartSection(){if(await readAttrsFrom(`${Theme.routes.cart_url}?sections=${SECTION_ID}`,SECTION_ID)){debug.source="section";return}if(await readAttrsFrom(Theme.routes.cart_url)){debug.source="cart-page",console.warn("[unit-limit] section fetch returned nothing; fell back to fetching /cart. Check that sections/order-unit-limit.liquid is registered in templates/cart.json.");return}debug.source="none",console.warn("[unit-limit] could not read cart state; storefront limit UI is inactive.")}async function readAttrsFrom(url,sectionKey){try{const response=await fetch(url,{headers:{Accept:sectionKey?"application/json":"text/html"}});if(!response.ok)return debug.lastError=`${url} -> HTTP ${response.status}`,!1;let html;if(sectionKey){const sections=await response.json();if(html=sections[sectionKey],typeof html!="string")return debug.lastError=`${url} -> no "${sectionKey}" key (got: ${Object.keys(sections).join(", ")||"nothing"})`,!1}else html=await response.text();const host=new DOMParser().parseFromString(html,"text/html").querySelector("[data-unit-limit-cap]");return host instanceof HTMLElement?readState({cap:host.dataset.unitLimitCap,units:host.dataset.unitLimitUnits})==="full":(debug.lastError=`${url} -> no [data-unit-limit-cap] in response`,!1)}catch(error){return debug.lastError=`${url} -> ${error instanceof Error?error.message:String(error)}`,!1}}function updateQuantitySelectors(){for(const selector of document.querySelectorAll("quantity-selector-component, cart-quantity-selector-component"))"updateButtonStates"in selector&&typeof selector.updateButtonStates=="function"&&selector.updateButtonStates()}function unitLimitMessage(){return(Theme.translations?.cart_unit_limit_error||"Orders are limited to %{cap} items. You have %{units} \u2014 please remove %{excess} to check out.").replaceAll("%{cap}",String(state.cap)).replaceAll("%{units}",String(state.units)).replaceAll("%{excess}",String(Math.max(state.units-state.cap,0)))}
1function renderNoticeContent(notice){notice.textContent="",notice.append(`${unitLimitMessage()} `);const email=Theme.translations?.support_email,supportTemplate=Theme.translations?.cart_unit_limit_support;if(!email||!supportTemplate)return;const[before,after=""]=supportTemplate.split("%{email}"),link=document.createElement("a");link.className=NOTICE_LINK_CLASS,link.href=`mailto:${email}`,link.textContent=email,notice.append(before,link,after)}function updateRebuyFlyout(){const container=document.querySelector(REBUY_CHECKOUT_CONTAINER),flyout=document.querySelector(REBUY_FLYOUT);if(container instanceof HTMLElement)for(const control of container.querySelectorAll("button"))state.over?(control.setAttribute(OWNED_ATTRIBUTE,"true"),control.setAttribute("aria-disabled","true"),control.classList.add(BLOCKED_CLASS),control.disabled=!0):control.hasAttribute(OWNED_ATTRIBUTE)&&(control.removeAttribute(OWNED_ATTRIBUTE),control.removeAttribute("aria-disabled"),control.classList.remove(BLOCKED_CLASS),control.disabled=!1);if(document.querySelectorAll(`.${NOTICE_CLASS}`).forEach(node=>node.remove()),!state.over)return;const anchor=container??document.querySelector(REBUY_CHECKOUT_AREA),host=anchor?.parentElement??flyout;if(!(host instanceof HTMLElement)){debug.lastError="over limit, but no checkout container, checkout area or Rebuy flyout is in the DOM";return}const notice=document.createElement("div");notice.className=NOTICE_CLASS,notice.setAttribute("role","alert"),renderNoticeContent(notice),anchor?anchor.before(notice):host.append(notice)}function guardRebuyCheckoutClick(event){if(!state.over)return;const target=event.target;target instanceof Element&&target.closest(REBUY_CHECKOUT_CONTAINER)&&(event.preventDefault(),event.stopPropagation(),updateRebuyFlyout())}function guardRebuyCheckoutSubmit(event){if(!state.over)return;const form=event.target;!(form instanceof HTMLFormElement)||!(form.closest(REBUY_CHECKOUT_CONTAINER)??(event.submitter instanceof Element?event.submitter.closest(REBUY_CHECKOUT_CONTAINER):null))||(event.preventDefault(),event.stopPropagation(),updateRebuyFlyout())}function apply(){document.documentElement.classList.toggle(EXCEEDED_CLASS,state.over),updateQuantitySelectors(),updateRebuyFlyout()}let refreshHandle=0;function refresh(event){event?.type&&(debug.events=[...debug.events.slice(-49),event.type]);const bypassAttrs=!!event?.type?.startsWith("rebuy");clearTimeout(refreshHandle),refreshHandle=setTimeout(async()=>{(bypassAttrs||readFromCartAttrs()!=="full")&&await readFromCartSection(),apply()},bypassAttrs?200:50)}let cartObserver=null,bootstrapObserver=null,observedRoot=null,lastSignature="";function readLineQuantity(cell){const input=cell.querySelector("input");return input instanceof HTMLInputElement?input.value.trim():(cell.textContent??"").replace(/\s+/g,"")}function lineItemSignature(){const flyout=document.querySelector(REBUY_FLYOUT);if(!flyout)return"";const quantities=[...flyout.querySelectorAll(REBUY_ITEM_QUANTITY)].map(readLineQuantity);return`${flyout.querySelectorAll(REBUY_ITEM_REMOVE).length}:${quantities.join("|")}`}function handleCartMutations(mutations){let touchedCart=!1,controlsAppeared=!1;for(const mutation of mutations){const touched=[...mutation.addedNodes,...mutation.removedNodes],ours=touched.every(node=>node instanceof Element&&node.classList.contains(NOTICE_CLASS));touched.length&&ours||(touched.some(node=>node instanceof Element&&(node.matches?.(REBUY_ROOTS)||node.querySelector?.(REBUY_CHECKOUT_CONTAINER)))&&(controlsAppeared=!0),mutation.target.closest?.(REBUY_ROOTS)&&(touchedCart=!0))}if(touchedCart){const signature=lineItemSignature();if(signature!==lastSignature){lastSignature=signature,refresh(new Event("rebuy:observed"));return}}controlsAppeared?apply():debug.mutationsIgnored+=1}function observeRebuyCart(){const flyout=document.querySelector(REBUY_FLYOUT);if(!flyout)return!1;const parent=flyout.parentElement,root=parent&&parent!==document.body?parent:flyout;return cartObserver&&observedRoot===root&&root.isConnected||(cartObserver?.disconnect(),cartObserver=new MutationObserver(handleCartMutations),cartObserver.observe(root,{childList:!0,subtree:!0}),observedRoot=root,debug.observerRoot=root===flyout?REBUY_FLYOUT:`${root.tagName.toLowerCase()}${root.id?`#${root.id}`:""} > ${REBUY_FLYOUT}`,lastSignature=lineItemSignature(),bootstrapObserver?.disconnect(),bootstrapObserver=null),!0}function retryAttachAfterClick(){if(cartObserver){document.removeEventListener("click",retryAttachAfterClick);return}requestAnimationFrame(()=>observeRebuyCart())}function watchForRebuyCart(){cartObserver||bootstrapObserver||(bootstrapObserver=new MutationObserver(()=>observeRebuyCart()),bootstrapObserver.observe(document.body,{childList:!0}),document.addEventListener("click",retryAttachAfterClick))}function handleRebuyEvent(event){observeRebuyCart(),refresh(event)}
1function init(){const baseGetEffectiveMax=QuantitySelectorComponent.prototype.getEffectiveMax;QuantitySelectorComponent.prototype.getEffectiveMax=function(){return clampToOrderUnitLimit(this,baseGetEffectiveMax.call(this))},readFromCartAttrs()!=="full"&&readFromJsonBlob(),document.addEventListener(THEME_REFRESH_EVENT,refresh);for(const eventName of REBUY_REFRESH_EVENTS)document.addEventListener(eventName,handleRebuyEvent);document.addEventListener("click",guardRebuyCheckoutClick,!0),document.addEventListener("submit",guardRebuyCheckoutSubmit,!0),observeRebuyCart()||watchForRebuyCart(),Object.assign(window,{BL101UnitLimit:{state:getOrderUnitLimitState,report:()=>({...getOrderUnitLimitState(),source:debug.source,lastError:debug.lastError,rawFromLiquid:{...lastRead},rebuyEventsSeen:[...new Set(debug.events)],observerRoot:debug.observerRoot,lineItemSignature:lineItemSignature(),mutationsIgnored:debug.mutationsIgnored,flyoutFound:!!document.querySelector(REBUY_FLYOUT),htmlClassApplied:document.documentElement.classList.contains(EXCEEDED_CLASS),checkoutAreaFound:!!document.querySelector(REBUY_CHECKOUT_AREA),checkoutContainerFound:!!document.querySelector(REBUY_CHECKOUT_CONTAINER),checkoutButtonsFound:document.querySelectorAll(REBUY_CHECKOUT_SELECTOR).length,checkoutButtonsDisabled:[...document.querySelectorAll(REBUY_CHECKOUT_SELECTOR)].filter(button=>button.disabled).length,cartAttrsOnPage:!!document.querySelector("[data-unit-limit-cap]"),jsonBlobOnPage:!!document.getElementById(DATA_ELEMENT_ID)}),refresh:()=>refresh(new Event("rebuy:manual"))}}),apply()}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",init,{once:!0}):init(); 2//# sourceMappingURL=/cdn/shop/t/206/assets/order-unit-limit.js.map?v=139600679574080980641787314550
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.