1dayjs.extend(window.dayjs_plugin_isToday),dayjs.extend(window.dayjs_plugin_customParseFormat);let day_timeslot={},store={},global_delivery_method,datepicker,local_delivery_distance=0,local_delivery_shipping_method,is_delivery_cbd_sentosa=!1,is_delivery_tuas=!1,reset_cart=!1;function getRegionFromPostal(postalCode){const sector=parseInt(postalCode.substring(0,2),10);return sector>=75&§or<=80||sector>=53&§or<=57||sector===82?"North":sector>=41&§or<=52?"East":sector>=60&§or<=71?"West":sector===9?"South":sector>=1&§or<=39||[58,59,72,73].includes(sector)?"Central":"Unknown"}function checkDateAndTimeValidity(date,time,leadtime){if(!date||!time)return!1;let toCompare=date;if(time.indexOf("")==-1)toCompare+=` ${time}`;else{const[startTime,endTime]=time.split("-").map(s=>s.trim());toCompare+=` ${startTime}`}const toCompareDayjs=dayjs(toCompare,"DD MMM YY h:mma");let now=dayjs();return leadtime&&(now=dayjs().add(parseInt(leadtime),"m")),!now.isAfter(toCompareDayjs)}function validateSingaporePostalCode(input){if(!/^\d{6}$/.test(input))return!1;const prefix=parseInt(input.slice(0,2),10);return prefix>=1&&prefix<=82}function validateCbdOrSentosaPostCode(postal_code){if(!postal_code)return;if(validateSingaporePostalCode(postal_code)){const sector=parseInt(postal_code.substring(0,2),10),cbdSectors=[1,2,3,4,5,6,7,8],sentosaSectors=[9,10];return cbdSectors.includes(sector)?(console.log("This is in cbd area"),!0):sentosaSectors.includes(sector)?(console.log("This is in sentosa area"),!0):(console.log("not within cbd or sentosa"),!1)}}function validateTuasPostalCode(postal_code,address){if(!postal_code)return;if(validateSingaporePostalCode(postal_code)){const sector=parseInt(postal_code.substring(0,2),10);return!!(sector===62||(sector===63||sector===64)&&address&&["TUAS","JALAN AHMAD IBRAHIM"].includes(address))}}const testPostalCodeCbd=["018925","018956","018969","048618","059815","069119"],testPostalCodeSentosa=["098267","098268","098544","099048","099057","099598"],testNormalPostalCode=["640440","752101","370037","339263","367954"];function testValidateCbdOrSentosa(){testPostalCodeCbd.forEach(postal_code=>{console.log("test for cbd postal_code"),validateCbdOrSentosaPostCode(postal_code)}),testPostalCodeSentosa.forEach(postal_code=>{console.log("test for sentosa area"),validateCbdOrSentosaPostCode(postal_code)}),testNormalPostalCode.forEach(postal_code=>{console.log("test for non cbd/sentosa area"),validateCbdOrSentosaPostCode(postal_code)})}function buildTimeslot(date,leadtime,timeInput){if(!date||!leadtime||!timeInput)return;const day=dayjs(date).format("ddd")?.toLowerCase();if(day){const timeslot=day_timeslot[day],lead_time_pickup=parseInt(leadtime)||0;timeInput.innerHTML="<option value=''>Select time</option>";let timeslotTodayCount=0;if(timeslot)timeslot.forEach(val=>{let formattedTime,isRange,toCompareTime;if(val.indexOf("-")==-1)toCompareTime=dayjs(`${val}`,"HH:mm"),formattedTime=toCompareTime.format("h:mma"),isRange=!1;else{const[startTime,endTime]=val.split("-").map(s=>s.trim());toCompareTime=dayjs(startTime,"HH:mm");const formattedTimeStart=toCompareTime.format("h:mma"),formattedTimeEnd=dayjs(endTime,"HH:mm").format("h:mma");formattedTime=`${formattedTimeStart} - ${formattedTimeEnd}`}const option=document.createElement("option");if(option.value=formattedTime,option.innerHTML=formattedTime,dayjs(date).isToday()){const compareTime=dayjs().add(lead_time_pickup+10,"m");console.log("Leadtime: ",lead_time_pickup),console.log("time to compare: ",compareTime.format("HH:mm")),console.log("Timeslot: ",toCompareTime.format("HH:mm")),console.log("Is the current time now + leadtime + 10min before the timeslot?",compareTime.isBefore(toCompareTime)),compareTime.isBefore(toCompareTime)&&(timeInput.appendChild(option),timeslotTodayCount++)}else timeInput.appendChild(option)}),dayjs(date).isToday()&×lotTodayCount==0&&(timeInput.innerHTML="<option value=''>No more timeslot available</option>");else{const option=document.createElement("option");option.value="",option.innerHTML="No pickup available on this date/location",timeInput.appendChild(option)}}}class DatePicker extends HTMLElement{constructor(){super(),this.dates=[],this.method=void 0,this.pickupLocation=void 0,this.selectedDate=void 0,this.timingWindow=void 0,this.container=this,this.input=this.querySelector("input.select-date"),this.dateButtonContainer=this.querySelector(".order-date-button-wrapper"),this.dateButton=this.querySelectorAll("button.order-date-button"),this.loading=this.querySelector(".order-date-button-wrapper .loading__spinner"),this.cuttoffTime=this.querySelector('input[name="cutoff_time"]'),this.$timeInput=this.querySelector('select[name="delivery_time"]'),this.initDatePicker()}getCutOffTime(){let cuttoff=dayjs().hour(20).minute(0);if(this.cuttoffTime){const value=this.cuttoffTime.value,[hour,minute]=value.split(":");cuttoff=dayjs().hour(parseInt(hour)).minute(parseInt(minute))}return cuttoff}initDatesFromToday(){if(this.dates.length==0){this.showLoading();let first=dayjs(),cutoff=this.getCutOffTime();dayjs().isAfter(cutoff)&&(first=dayjs().add(1,"day")),this.dates=Array.from({length:4},(v,i)=>
1first.add(i,"day")),this.dates.forEach((date,index)=>{const button=document.createElement("button");button.classList.add("order-date-button"),button.setAttribute("data-value",dayjs(date).format("DD-MMM-YY"));const subtitle=document.createElement("div");subtitle.classList.add("order-date-isToday"),subtitle.innerHTML=dayjs(date).isToday()?"Today":dayjs(date).format("dddd"),button.appendChild(subtitle);const title=document.createElement("h3");title.classList.add("order-date-title"),title.innerHTML=` 2 <div>${dayjs(date).format("DD")}</div> 3 <div>${dayjs(date).format("MMM")}</div> 4 `,button.appendChild(title),button.addEventListener("click",evt=>{}),this.dateButtonContainer&&(this.dateButtonContainer.appendChild(button),this.dateButtonContainer.child)}),this.hideLoading()}}showLoading(){this.loading&&this.loading.classList.remove("hidden")}hideLoading(){this.loading&&this.loading.classList.add("hidden")}clearButtonActive(){this.dateButton.length&&this.dateButton.forEach(elem=>elem.removeAttribute("active"))}initDatePicker(){const today=dayjs(),endDate=today.add(1,"month");let minDate=today,cutoff=this.getCutOffTime();if(minDate.isAfter(cutoff)&&(minDate=today.add(1,"d")),localStorage.getItem("order_now_cart_attributes")){const DeliveryMethodWrapper=document.querySelector("delivery-method");this.input.addEventListener("click",()=>{DeliveryMethodWrapper.showDeliveryMethodChangeWarning(!0)})}datepicker=new AirDatepicker(this.input,{container:this.container,minDate,maxDate:endDate,dateFormat:"dd MMM yy",position:"top left",onSelect:({date,formattedDate,datepicker:datepicker2})=>{datepicker2.hide();let lead_time=global_delivery_method=="delivery"?delivery_timeslot_settings?.lead_time_delivery:store.leadtime_pickup;buildTimeslot(date,lead_time,this.$timeInput)}});let disabledDates=[];typeof blockout_dates<"u"&&blockout_dates.length&&(disabledDates=blockout_dates.map(date=>dayjs(date,"DD-MMM-YY").toDate()),datepicker&&datepicker.disableDate(disabledDates))}}customElements.define("date-picker",DatePicker);class DeliveryMethod extends HTMLElement{constructor(){super(),this.selection="",this.$input=this.querySelectorAll('#delivery-method-selection input[name="delivery_method"]'),this.$pickup=this.querySelectorAll('[data-method="pickup"] input[name="pickup_location"]'),this.datePickerContainer=document.querySelector("date-picker"),this.onChange(),this.onChangePickup(),this.$dateInput=document.querySelector('[name="delivery_date"]'),this.$timeInput=document.querySelector('[name="delivery_time"]'),this.$postalCode=this.querySelector('[name="delivery_postal_code"]'),this.$postalCodeMessage=this.querySelector('[data-message="delivery_postal_code"]'),this.$postalCode.addEventListener("change",this.onChangePostalCode.bind(this)),this.$deliveryWarning=document.querySelector("#change-delivery-warning-popup"),this.$deliveryWarningButtons=document.querySelectorAll("#change-delivery-warning-popup button"),this.handleDeliveryWarningButton(),this.$orderForm=document.querySelector("#order-now-dialog-form"),this.orderFormClass=document.querySelector("order-form")}async onChangePostalCode(e){this.clearErrorMessage();const value=e.target.value;if(value.length!==6)return;if(!validateSingaporePostalCode(value)){this.$postalCodeMessage.classList.remove("hidden"),this.$postalCodeMessage.classList.add("error"),this.$postalCodeMessage.textContent="Please enter a valid postal code.";return}is_delivery_cbd_sentosa=validateCbdOrSentosaPostCode(value);try{const res=await fetch(`https://www.onemap.gov.sg/api/common/elastic/search?searchVal=${value}&getAddrDetails=Y&returnGeom=N`,{method:"GET"}),result=await res.json();if(res.ok&&result.results?.length){const address=result.results[0],addressString=`${address?.BLK_NO} ${address?.ROAD_NAME}`;is_delivery_tuas=validateTuasPostalCode(value,address?.ROAD_NAME),this.$postalCodeMessage.classList.remove("hidden"),this.$postalCodeMessage.classList.add("success"),this.$postalCodeMessage.innerHTML=`Awesome! We can deliver to this location: <b>${addressString}</b>`,this.getDistanceMatrix(value)}else this.$postalCodeMessage.classList.remove("hidden"),this.$postalCodeMessage.classList.add("error"),this.$postalCodeMessage.textContent="Uh oh, we cannot delivery this location. This location cannot be found."}catch(error){console.log(error)}}async getDistanceMatrix(postal_code){if(!GOOGLE_CLOUD_KEY&&order_now_storelist.length)return;let storePostalCode;if(order_now_storelist.length){const store2=order_now_storelist.find(i=>i.delivery_fulfillment);store2.postal_code&&(storePostalCode=store2.store_postal_code);try{const url="https://routes.googleapis.com/directions/v2:computeRoutes",body={origin:{address:`${store2.store_postal_code}, Singapore`},destination:{address:`${postal_code}, Singapore`},routingPreference:"TRAFFIC_AWARE",travelMode:"DRIVE"},res=await fetch(url,{method:"POST",headers:{"Content-Type":"application/json","X-Goog-Api-Key":GOOGLE_CLOUD_KEY,"X-Goog-FieldMask":"routes.duration,routes.distanceMeters"},body:JSON.stringify(body)}),result=await res.json();if(res.ok&&result.routes?.length){const route=result.routes[0],distanceKm=Math.ceil(route.distanceMeters/1e3);local_delivery_distance=distanceKm,radius_distance&&Object.keys(radius_distance).length&&Object.keys(radius_distance).forEach(key=>{const[min,max]=radius_distance[key];distanceKm>=parseInt(min)&&distanceKm<parseInt(max)&&(local_delivery_shipping_method=key)})}}catch(error){console.log(error)}}}clearErrorMessage(){this.$postalCodeMessage.classList.add("hidden"),this.$postalCode.textContent=""}handleCheckSavedDeliverySettings(){const orderNowAttributes=localStorage.getItem("order_now_cart_attributes");if(!orderNowAttributes)return;const parseOrderNowAttributes=JSON.parse(orderNowAttributes)}onChange(){this.$input.length&&this.$input.forEach(elem=>{elem.addEventListener("change",e=>
4{if(localStorage.getItem("order_now_cart_attributes")){this.showDeliveryMethodChangeWarning(!0);return}const formWrapper=document.querySelectorAll("delivery-method div[data-method]");global_delivery_method=elem.value,elem.value=="delivery"&&this.updateTimeSlot(delivery_timeslot_settings.delivery_timeslot),this.$dateInput.value="",this.$timeInput.value="",this.$timeInput.innerHTML="<option value=''>Select date and location</option>",this.$pickup&&this.$pickup.forEach(dom=>dom.checked=!1),datepicker&&datepicker.clear(),this.datePickerContainer.classList.remove("hidden"),formWrapper.forEach(form=>{form.dataset.method==elem.value?form.classList.remove("hidden"):form.classList.add("hidden")})})})}showDeliveryMethodChangeWarning(flag){flag?(this.$deliveryWarning.removeAttribute("hidden"),this.$orderForm.setAttribute("hidden","")):(this.$deliveryWarning.setAttribute("hidden",""),this.$orderForm.removeAttribute("hidden"))}handleResetDeliveryMethod(){const button=document.querySelector('#change-delivery-warning-popup button[data-action="confirm"]'),urlParam=window.location.pathname;button.setAttribute("disabled",""),button.innerHTML="Loading..",this.orderFormClass.clearCart(`${urlParam}?reset_delivery_method=1`)}handleDeliveryWarningButton(){this.$deliveryWarningButtons.length&&this.$deliveryWarningButtons.forEach(button=>{button.addEventListener("click",e=>{const action=button.dataset.action;if(action=="cancel"){this.showDeliveryMethodChangeWarning(!1);const order_delivery_method=localStorage.getItem("order_delivery_method");this.$input&&this.$input.forEach(elem=>{elem.value==order_delivery_method&&(elem.checked=!0)})}action=="confirm"&&this.handleResetDeliveryMethod()})})}updateTimeSlot(timeslot){day_timeslot=timeslot}onChangePickup(){this.$pickup.length&&this.$pickup.forEach(elem=>{elem.addEventListener("change",e=>{const value=elem.value,store_information=order_now_storelist.find(i=>i.store_name==value);store_information.store_name&&(this.updateTimeSlot(store_information.pickup_slot),store=store_information,datepicker&&datepicker.clear(),this.$dateInput.value="",this.$timeInput.value="")})})}}customElements.define("delivery-method",DeliveryMethod);class OrderForm extends HTMLElement{constructor(){super(),this.$submit_button=this.querySelector('button[type="submit"]'),this.modal=document.querySelector("#PopupModal-orderNow"),this.form=this.querySelector("form#order-now-dialog-form"),this.location=null,this.delivery_date=null,this.watchInputChanges(),this.delivery_method=this.form.elements.delivery_method,this.pickup_location=this.form.elements.pickup_location,this.delivery_postal_code=this.form.elements.delivery_postal_code,this.delivery_time=this.form.elements.delivery_time,this.delivery_date=this.form.elements.delivery_date,this.$datePicker=this.querySelector("date-picker"),this.$pickupForm=this.querySelector('delivery-method [data-method="pickup"]'),this.$deliveryForm=this.querySelector('delivery-method [data-method="delivery"]'),this.$formMessage=this.querySelector(".form-message"),this.$navOrderNowBtn=document.querySelectorAll(".order-now-button"),this.$quickAddButtons=document.querySelector(".quick-add.no-js-hidden"),this.fetchCart()}watchInputChanges(){this.form&&(this.form.addEventListener("input",this.checkAllFields.bind(this)),this.form.addEventListener("change",this.checkAllFields.bind(this)),this.form.addEventListener("submit",this.submit.bind(this)))}checkAllFields(){if(this.$submit_button.setAttribute("disabled",""),!!this.delivery_method.value){if(this.delivery_method.value=="pickup"){if(!this.pickup_location.value)return}else if(!this.delivery_postal_code.value||!validateSingaporePostalCode(this.delivery_postal_code.value))return;this.delivery_time.value&&this.delivery_date.value&&this.$submit_button.removeAttribute("disabled")}}async fetchCart(){const localstorage_delivery_method=localStorage.getItem("order_delivery_method");localstorage_delivery_method&&(this.$navOrderNowBtn.forEach(elem=>elem.innerHTML=localstorage_delivery_method),global_delivery_method=localstorage_delivery_method);try{const res=await fetch("/cart.js"),result=await res.json();if(res.ok){const attributes=result.attributes;if(typeof attributes<"u"&&Object.keys(attributes).length){const{delivery_method,delivery_date,pickup_location,delivery_postal_code,delivery_shipping_method,delivery_distance,delivery_time,delivery_cbd_sentosa,delivery_tuas}=attributes;let leadtime;if(delivery_method=="delivery")leadtime=delivery_timeslot_settings.lead_time_delivery,local_delivery_shipping_method=delivery_shipping_method,local_delivery_distance=delivery_distance;else if(order_now_storelist&&pickup_location){const store2=order_now_storelist.find(i=>i.store_name==pickup_location);store2.store_name&&(leadtime=store2.leadtime_pickup)}console.log(leadtime);const checkOrderTimeAndDate=checkDateAndTimeValidity(delivery_date,delivery_time,leadtime);if(console.log(checkOrderTimeAndDate),!checkOrderTimeAndDate){this.modal.show(),this.clearCart(),this.$formMessage.classList.remove("hidden"),localStorage.removeItem("order_delivery_method"),this.$navOrderNowBtn.innerHTML="Order now",this.$formMessage.innerHTML="Uh oh! We're terribly sorry. The cutoff date and/or time selected has passed. Please re-select your preferred option. Product availabilities may have changed and may not be available in your cart.",datepicker&&datepicker.clear(),navOrderNowBtn&&navOrderNowBtn.forEac
4h(btn=>btn.innerHTML="Order now");return}datepicker&&datepicker.selectDate(dayjs(delivery_date,"DD MMM YY").toISOString()),delivery_cbd_sentosa&&(is_delivery_cbd_sentosa=delivery_cbd_sentosa),delivery_tuas&&(is_delivery_tuas=delivery_tuas),delivery_method&&(this.$datePicker.classList.remove("hidden"),this.delivery_method.forEach(radio=>{radio.checked=radio.value==delivery_method})),delivery_method=="pickup"?(this.$pickupForm.classList.remove("hidden"),store=order_now_storelist.find(i=>i.store_name==pickup_location),day_timeslot=store.pickup_slot,this.pickup_location.length?this.pickup_location.forEach(radio=>{radio.checked=radio.value===pickup_location}):this.pickup_location.value==pickup_location&&(this.pickup_location.checked=!0)):(this.delivery_postal_code.value=delivery_postal_code,this.$deliveryForm.classList.remove("hidden"),day_timeslot=delivery_timeslot_settings.delivery_timeslot),buildTimeslot(dayjs(delivery_date,"DD MMM YY"),leadtime,this.delivery_time),this.delivery_time.value=delivery_time}else{const pathname=window.location.pathname;new URLSearchParams(window.location.search).get("reset_delivery_method")&&this.modal.show(),this.$navOrderNowBtn.forEach(elem=>elem.innerHTML="Order Now"),this.quickAddButtons&&this.quickAddButtons.length&&this.quickAddButtons.forEach(elem=>{elem.setAttribute("hidden","")}),localStorage.removeItem("order_delivery_method"),localStorage.removeItem("order_now_cart_attributes"),(pathname.includes("/product")||pathname.includes("/cart"))&&this.modal.show()}}}catch(error){console.log(error)}}showLoading(){this.$submit_button.querySelector(".loading__spinner").classList.remove("hidden"),this.$submit_button.querySelector("span").classList.add("hidden")}hideLoading(){this.$submit_button.querySelector(".loading__spinner").classList.add("hidden"),this.$submit_button.querySelector("span").classList.remove("hidden")}async clearCart(url){this.showLoading();try{const res=await fetch("/cart/clear.js",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({sections:"cart-items"})}),result=await res.json();res.ok&&this.hideLoading()}catch{console.log("clear cart error")}let attributes={pickup_location:null,pickup_location_address:null,pickup_location_postal_code:null,delivery_postal_code:null,delivery_distance:null,delivery_shipping_method:null,delivery_date:null,delivery_time:null,delivery_method:null,delivery_cbd_sentosa:null,delivery_tuas:null,delivery_region:null};localStorage.removeItem("order_delivery_method"),localStorage.removeItem("order_now_cart_attributes");try{const res=await fetch("/cart/update.js",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({attributes})}),result=await res.json();if(!res.ok)return;url&&(window.location.href=url)}catch{}}clearAttributeType(attributes,type){type=="pickup"&&(attributes.pickup_location=null,attributes.pickup_location_address=null,attributes.pickup_location_postal_code=null),type=="delivery"&&(attributes.delivery_postal_code=null,attributes.delivery_distance=null,attributes.delivery_shipping_method=null)}async submit(e){e.preventDefault(),this.showLoading();let body={};const cartObjects=await(await fetch("/cart.js")).json();let lineItem;is_delivery_cbd_sentosa||is_delivery_tuas?(cartObjects&&(lineItem=cartObjects.items.find(item=>item.variant_id===45265591206076)),lineItem?body.updates={45265591206076:1}:await fetch("/cart/add.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:45265591206076,quantity:1})})):(body.updates={45265591206076:0},console.log(body));let attributes={delivery_method:this.delivery_method.value,delivery_date:this.delivery_date.value,delivery_time:this.delivery_time.value};this.delivery_method.value=="pickup"?(this.clearAttributeType(attributes,"delivery"),attributes.pickup_location=this.pickup_location.value,attributes.pickup_location_address=store.store_address,attributes.pickup_location_postal_code=store.store_postal_code):(this.clearAttributeType(attributes,"pickup"),attributes.delivery_postal_code=this.delivery_postal_code.value,attributes.delivery_region=getRegionFromPostal(this.delivery_postal_code.value),attributes.delivery_distance=local_delivery_distance,attributes.delivery_shipping_method=local_delivery_shipping_method??"short",is_delivery_cbd_sentosa&&(attributes.delivery_cbd_sentosa=is_delivery_cbd_sentosa),is_delivery_tuas&&(attributes.delivery_tuas=is_delivery_tuas)),body.attributes=attributes,typeof localStorage<"u"&&(localStorage.setItem("order_delivery_method",this.delivery_method.value),localStorage.setItem("order_now_cart_attributes",JSON.stringify(attributes)));try{const res=await fetch("/cart/update.js",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(body)}),result=await res.json();res.ok&&(this.hideLoading(),this.modal.hide(),window.location.pathname=="/"?window.location.replace("/collections/all"):window.location.reload())}catch{console.log("something happened")}}}customElements.define("order-form",OrderForm); 5//# sourceMappingURL=/cdn/shop/t/4/assets/order-now-dialog.js.map?v=68377716965101627431771884778
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.