const SELFBOOK_BASE_URL="https://sdk.selfbook.com",SELFBOOK_BASE_URL_V3="https://sdk-v3.selfbook.com",SELFBOOK_BASE_URL_LAYERS="%REACT_APP_SELFBOOK_BASE_URL_LAYERS%";let SELFBOOK_BACKEND_URL="https://api.selfbook.com/api/v2",SELFBOOK_BACKEND_URL_V3="https://api.selfbook.com/api/v3";const STATSIG_CLIENT_KEY="client-PV01TCjBc3a7zunh9brJUh2fIaLwbXaH7aQH2dFpSGW",STATSIG_EXPERIMENT="ddn",STATSIGN_SIGNAL_BOX_EXPERIMENT="ddn_signal_box";let SELFBOOK_APP_VERSION="v2",SELFBOOK_APP_BASE_URL=SELFBOOK_BASE_URL;const SELFBOOK_SCRIPT_ID="selfbook_jssdk",SELFBOOK_HOTEL_ID_PROP="hotelId",SELFBOOK_API_KEY_PROP="apiKey",SELFBOOK_WIDGET_ELEMENT_ID="selfbook_sdkwidget",SELFBOOK_WIDGET_WRAPPER_ELEMENT_ID="selfbook_sdkwidget_wrapper",SELFBOOK_WIDGET_LOADING_ELEMENT="selfbook-loading",IS_LANDING_PAGE_FLAG_ID="ddnLandingPage",BOOTSTRAP_ACTION="WIDGET/BOOTSTRAP",SELFBOOK_HOTEL_GROUP_INFO="selfbook_hotel_group_info",SELFBOOK_HOTEL_INFO="selfbook_hotel_info";window.selfbookStatsigClient=null;const BLACK_SQUARE_THEME_HOTELS=["6739"],THE_LINE_HOTELS=["68711","71661","2427"],COMPLETE_BOOKING_BTN_CLICK="Complete your reservation button click",ROUTE_PATHS={app:{confirmation:"/confirmation",wallet:"/wallet",account:"/account",settings:"/settings",reservations:"/reservations",reservationDetail:"/reservation-detail",editBooking:"/edit-booking",bookingConfirmed:"/booking-confirmed"}},INITIAL_PERSISTED_DATA={isExpired:!0,all:null,booking:null,core:null,router:null},GUEST_TYPE={ADULT:"adult",CHILD:"child",INFANT:"infants"};let initialV35AvailabilityStartEndDates={},initialCalendarResponse=null;function setOverflowHidden(e){const t=e?"hidden":"";document.body.style.overflow=t,document.documentElement.style.overflow=t}function getStatsigValue(e,t){if(window.selfbookStatsigClient){const n=window.selfbookStatsigClient.getExperiment(e);return n&&n.value&&n.value[t]}return null}const SUPPORTED_LOCALES=["en","fr","pt","da","de","de-DE","es-MX","it","ja","ko","nl","ro","ru","sq","sv","vi","zh","zh-CN","zh-TW","es"];function parseLocaleFromUrl(){try{const{pathname:e}=new URL(window.location.href),t=e.split("/").filter(Boolean),n=t[0]?.toLowerCase();if(!n)return null;if(!/^[a-z]{2}(-[a-z]{2})?$/i.test(n))return null;const o=n.replace(/^([a-z]{2})(-[a-z]{2})?$/i,(e,t,n)=>n?`${t.toLowerCase()}-${n.slice(1).toUpperCase()}`:t.toLowerCase());return SUPPORTED_LOCALES.includes(o)?o:"en"}catch{return null}}function appendWidgetScript({src:e,callback:t,type:n="text/javascript"}){const o=document.createElement("script");o.type=n,o.src=e,document.body.appendChild(o),t&&"function"==typeof t&&(o.onload=function(){t()})}function initFloatingSearchbar({apiKey:e,hotelId:t}={}){appendWidgetScript({src:`${SELFBOOK_BASE_URL_V3}/widgets/floating-search-bar.js`,type:"module",callback:function(){const n=SELFBOOK_BACKEND_URL.replace(/\/v[123]/,"");window.renderWidget(null,{backendURL:n,hotelId:t,apiKey:e})}})}function initDDNSignalBox({signalPartner:e,apiKey:t,hotelId:n}={}){e&&"none"!==e&&appendWidgetScript({src:`${SELFBOOK_BASE_URL_V3}/widgets/ddn-signal-box.js`,callback:function(){const o=SELFBOOK_BACKEND_URL.replace(/\/v[123]/,"");window.renderSBSignalBox({backendURL:o,hotelId:n,apiKey:t,ddn_signal_partner:e,experiment:"ddn_signal_box",locale:parseLocaleFromUrl()})}})}function initWidgets({apiKey:e,hotelId:t,hotelData:n}){if(n?.enable_direct_distribution_network&&(n?.enable_paypal_partner&&n?.enable_paypal||n?.enable_perplexity_partner)){initDDNSignalBox({signalPartner:getStatsigValue("ddn_signal_box","ddn_signal_partner"),apiKey:e,hotelId:t})}}function initSDKBus(){const e={},t={};window.sb_sdkBus={emit(n,o){t[n]||(t[n]=[]),t[n].push(o),e[n]?.length&&e[n].forEach(e=>e(o))},on(t,n){e[t]||(e[t]=[]),e[t].push(n)},off(t,n){e[t]&&(e[t]=e[t].filter(e=>e!==n))},pull(e){const n=t[e]||[];return t[e]=[],n}}}function checkStatus(e){if(e.status>=200&&e.status<300)return e;const t=new Error(e.statusText);throw t.response=e,t}async function parseJSON(e){try{const t=await e.text();if(!t)return;return JSON.parse(t)}catch(e){console.error("parseJSON: err: ",e)}}function intervalWrapper(e,t){const n=setInterval(e,t);return function(){clearInterval(n)}}function getHotelBasicData(e){try{const t=getFromSessionStorage(SELFBOOK_HOTEL_GROUP_INFO).hotels?.filter(t=>t.id==e),n=t?.[0]||{};return getIsEnableV35(n)&&(n.app_version="v3",n.enable_v3_new_ui_version=!0),n}catch(e){return console.error("getHotelBasicData: err: ",e),{}}}function getFromSessionStorage(e){try{return JSON.parse(sessionStorage.getItem(e))}catch(e){return console.error("getFromSessionStorage: err: ",{e:e}),{}}}function getPersistedData(e){try{const t=JSON.parse(e.getItem("persist:root"));if(!t)return INITIAL_PERSISTED_DATA;const n=JSON.parse(t.booking||"{}"),o=JSON.parse(t.core||"{}"),a=JSON.parse(t?.router||"{}"),{expireTime:r}=o,s=(Date.now()-new Date(o.interactionTime))/1e3;return{isExpired:s>r,all:t,booking:n,core:o,router:a}}catch(e){return console.error("getPersistedData: err: ",e),INITIAL_PERSISTED_DATA}}function fillGuestsFields(e=[],t){const n=t.default_adult_occupancy?t.default_adult_occupancy:2;return e?.map(e=>e.type===GUEST_TYPE.ADULT?{type:GUEST_TYPE.ADULT,count:parseInt(e.count)||n}:e.type===GUEST_TYPE.CHILD&&parseInt(e.count)>0?{type:GUEST_TYPE.CHILD,count:parseInt(e.count),age:parseInt(e.age)||1,special_request:e.special_request||""}:e.type===GUEST_TYPE.INFANT&&parseInt(e.count)>0?{type:GUEST_TYPE.INFANT,count:parseInt(e.count)||1,age:parseInt(e.age)||1,special_request:e.special_request||""}:void 0).filter(Boolean)}function buildRoomsGuests(e,t){const n=t.default_adult_occupancy?t.default_adult_occupancy:2,o=()=>Math.random().toString(36).slice(2),a=["adult","child","childAges","room2Adult","room3Adult","room4Adult"].some(t=>!!e[t]);if(e.guests?.length&&!a)return Array.from({length:4},(t,a)=>{const r=0===a?"guests":`guestsRoom${a+1}`;if(!e[r])return null;const s=e[r]?.map(e=>{const t=e?.type===GUEST_TYPE.ADULT?e?.count||n:e?.count,a=e?.type===GUEST_TYPE.CHILD&&"number"==typeof e?.age;return{type:e?.type,count:Number(t),guest_details:a?[{key:o(),age:Number(e?.age)}]:void 0}});return{key:0===a?"room1":o(),data:s}}).filter(Boolean);const r=t=>Number(e[t]||0),[s,i,l,c]=["roomCount","adult","child","infants"].map(r);if(s>1&&!r("room2Adult")){const e=i||n,t=Math.floor(e/s);let a=e%s;return Array.from({length:s},(e,n)=>{const r=a>=n+1?1:0;return{key:0===n?"room1":o(),data:[{type:GUEST_TYPE.ADULT,count:t+r}]}})}const d=[];return Array.from({length:4}).forEach((t,a)=>{const s=a+1,u=0===a?i||n:r(`room${s}Adult`);if(u){const t=[{type:GUEST_TYPE.ADULT,count:u}],n=0===a?l:r(`room${s}Child`),i=e[0===a?"childAges":`room${s}ChildAges`];i?i.split(",").forEach(e=>{t.push({type:GUEST_TYPE.CHILD,count:1,guest_details:[{key:o(),age:Number(e)}]})}):n&&t.push({type:GUEST_TYPE.CHILD,count:n}),0===a&&c>0&&t.push({type:GUEST_TYPE.INFANT,count:c}),d.push({key:0===a?"room1":o(),data:t})}}),d}function buildRedirectSynxisLink(e,t){let n=`https://be.synxis.com/?hotel=${t.id}&theme=${t.synxis_theme}&config=${t.synxis_config}`;try{if(e){const{startDate:t,endDate:o,promoCode:a,groupCode:r,guests:s,iataNumber:i,couponCode:l,destinationId:c,nights:d,rate:u,hotelId:p,roomCategory:_}=e;d&&(n+=`&nights=${d}`),t&&(n+=`&arrive=${t}`),o&&(n+=`&depart=${o}`),a&&(n+=`&promo=${a}`),r&&(n+=`&group=${r}`),i&&(n+=`&iataNumber=${i}`),l&&(n+=`&couponCode=${l}`),u&&(n+=`&rate=${u}`),c&&(n+=`&destinationId=${c}`),Array.isArray(_)?n+=`&roomCategory=${_.map(e=>e).join(",")}`:_&&(n+=`&roomCategory=${_}`),s&&s.length>0?("adult"===s[0].type&&(n+=`&adult=${s[0].count}`),s[1]&&"child"===s[1].type&&(n+=`&child=${s[1].count}`)):n+="&adult=1"}}catch(e){console.error("buildRedirectSynxisLink: err: ",e)}return n}function selectShowWidgetButtonCopies(e){return e.core.showWidgetButtonCopies||{}}function selectRoute(e){return e?.router?.location?e.router.location.pathname:ROUTE_PATHS.app.editBooking}function isObjectEqual(e,t){return JSON.stringify(e)===JSON.stringify(t)}function isTemplateDomainMatch(e,t){return e?.booking_template_domain&&t?.target?.href?.includes(e.booking_template_domain)}function getElementById(e){return document?.getElementById(e)}function getIsEnableV35(e){return!!SELFBOOK_APP_VERSION.match(/^v3/i)||(e?.enable_v3_new_ui_version||!1)}function getIsLayers(e){return"layers"===e?.app_version||!!SELFBOOK_APP_VERSION.match(/^layers/i)}function runDirectApplication(){console.info("(!) selfbook: widget initialization started");let e,t,n,o=!1,a=!1,r=!1,s=!1,i=!1,l=!1,c=!1;function d(){try{const e=document.createElement("script");if(e.innerHTML='\n !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","identify","reset","group","track","ready","alias","debug","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;ee.destination_id?.toLowerCase()===o.destinationId.toLowerCase());e&&(o.hotelId=e.id)}else o.hotelId=o?.hotelId||a?.id;if(a?.enable_direct_distribution_network&&"signalBox"!==o.userStartingPoint&&(a?.enable_paypal_partner&&a?.enable_paypal||a?.enable_perplexity_partner)){const e=getStatsigValue("ddn_signal_box","ddn_signal_partner");if("paypal"===e){const t=function(){const e=g();if(e)return"authenticated"===e?.state?.step&&!!e?.state?.identifier}();l=c?{}:{partner:e,signalBoxUserVerified:!!t,paypalData:t?y():null,shouldExecuteRegularFlow:(!t||!a?.is_default_date_logic_enabled||"single"!==i?.structure)&&s}}}}setOverflowHidden(!0),window.toggleShowSBSignalBox?.(!1);const u=getElementById("selfbook_sdkwidget"),p=getElementById("selfbook_sdkwidget_wrapper");window.selfbookWidgetStore||(p.appendChild(function(){const e=document.createElement("div");return e.id="selfbook-loading",e.style.color="white",e.style.marginRight="-50%",e.style.position="absolute",e.style.top="50%",e.style.left="50%",e.style.fontFamily="sans-serif",e.style.transform="translate(-50%, -50%)",e.innerHTML='',e}()),p.style.zIndex=1e11,p.style.height="100%",p.style.background="v2"===SELFBOOK_APP_VERSION?"rgba(0, 0, 0, .74)":"rgba(39, 39, 39, 0.74)",setOverflowHidden(!0)),function(e){if(!0===r)return;n&&n.length>0&&n.forEach(e=>{if(e.includes(".js")){const t=document.createElement("script");t.type="text/javascript",t.src=`${SELFBOOK_APP_BASE_URL}/${e}`,document.body.appendChild(t)}});e?.enable_direct_distribution_network||d();r=!0}(a);const _=setInterval(()=>{if(window.selfbookWidgetStore){const n=getIsLayers(a),r={hotelInfo:{...!n&&{hotelIdAsArg:!!o.hotelId},...n&&{hotelResponse:getFromSessionStorage(SELFBOOK_HOTEL_INFO)},apiKey:o.apiKey||t,hotelId:o.hotelId||e},bookingData:{...o,...l},...!n&&{hotelGroupInfo:getFromSessionStorage(SELFBOOK_HOTEL_GROUP_INFO)},roomsGuests:o.roomsGuests||void 0,shouldExecuteRegularFlow:!1===l?.shouldExecuteRegularFlow?l?.shouldExecuteRegularFlow:s,userIP:o.userIP?.country_code?o.userIP:void 0,version:o.version,isDdnLandingPageSource:c};!function(){const e=document.getElementById("selfbook-loading");e&&getElementById("selfbook_sdkwidget_wrapper").removeChild(e)}(),clearInterval(_),window.selfbookWidgetStore.dispatch({type:BOOTSTRAP_ACTION,payload:r}),"none"===u.style.display&&(p.style.zIndex=1e11,p.style.height="100%",p.style.background="v2"===SELFBOOK_APP_VERSION?"rgba(0, 0, 0, .74)":"rgba(39, 39, 39, 0.74)",setOverflowHidden(!0)),setTimeout(()=>{u.style.display="block",u.setAttribute("class","slide-in")},20),setTimeout(()=>{const e=p.querySelector('[aria-modal="true"]');e&&e.focus()},250)}},100)}function _(){try{const{isExpired:e,core:t,booking:n}=getPersistedData(localStorage);if(e||!t?.hotel?.data?.id)return void function(){try{localStorage.removeItem("persist:root")}catch(e){console.error("removePersistedData: err",e)}}();const o=t.bootstrapArgs;f({...o,startDate:n.bookingForm.start_date.slice(0,10),endDate:n.bookingForm.end_date?.slice(0,10)||null,guests:n.bookingForm.guests,propertyId:n.bookingForm.property_id,persistActive:!0,hotelId:t.hotel.data.id})}catch(e){console.error("openPersistWidget: err",e)}}const m=async()=>await fetch(`${SELFBOOK_APP_BASE_URL}/asset-manifest.json`,{headers:{"content-type":"application/json"}}).then(e=>e.json()).then(e=>function(e){n=e.entrypoints}(e));function g(){try{return JSON.parse(localStorage.getItem("selfbook_ddn-signal-box_auth"))}catch(e){console.error("Unable to extract Signal box from local storage.")}}function y(){const e=g();if(e)return e?.state?.user?.paypal_data}async function f(n={}){try{if(o)return;n.currencyCode&&(n.currency=n.currencyCode,delete n.currencyCode);let a=n.shouldExecuteRegularFlow||!1;n.apiKey&&await k(n.apiKey,n.hotelId);const r=getHotelBasicData(n.hotelId||e);getIsLayers(r)&&await async function(e,t){try{l=!0;const n=await u({url:`${SELFBOOK_BACKEND_URL_V3}/hotels/${e}`,headers:{"content-type":"application/json","API-Key":t}});sessionStorage.setItem(SELFBOOK_HOTEL_INFO,JSON.stringify(n)),l=!1}catch(e){console.log(e)}}(n.hotelId||e,n.apiKey||t),console.log("args",n);const s=getIsEnableV35(r),c=getFromSessionStorage(SELFBOOK_HOTEL_GROUP_INFO),d="group"===c?.structure,_="single"===c?.structure,m=function(e,t=[]){if(!e||"object"!=typeof e||Array.isArray(e))return!1;for(const n in e){if(t.includes(n))continue;const o=e[n];if(null!=o&&!("string"==typeof o&&""===o.trim()||Array.isArray(o)&&0===o.length||"object"==typeof o&&!Array.isArray(o)&&0===Object.keys(o).length))return!0}return!1}(n,["version","selfbook","hotelId","destinationId"]);if(s&&!1!==n.shouldExecuteRegularFlow&&((/*!initialAPIsCallsExecuted && */_&&m||d&&!i)&&(a=!0),r?.is_default_date_logic_enabled?n.startDate&&n.endDate&&(_||d&&n.hotelId)&&(a=!0):a=!0),n.guests?n.guests=fillGuestsFields(n.guests,r):n.guests=[{type:GUEST_TYPE.ADULT,count:r.default_adult_occupancy?r.default_adult_occupancy:2}],r.redirect_to_synxis){const e=buildRedirectSynxisLink(n,r);return void window.open(e,"_blank").focus()}getIsEnableV35(r)&&(n.roomsGuests=buildRoomsGuests(n,r)),p(n,r,a),document.getElementsByTagName("html")[0].setAttribute("translate","no")}catch(e){console.error("bookNow: err: ",e)}}function h(){const e="\n #selfbook_sdkwidget {\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0px;\n right: 0px;\n }\n\n .dismiss-btn-slide-in {\n -webkit-transition: 500ms;\n -moz-transition: 500ms;\n transition: 500ms;\n transform: translateX(0)!important\n }\n\n .dismiss-btn-slide-out {\n -webkit-transition: 500ms;\n -moz-transition: 500ms;\n transition: 500ms;\n transform: translateX(300px)!important\n }\n\n .dismiss-btn-slide-out span {\n display: none;\n }\n\n .payment-summary-wrapper {\n overflow: scroll!important;\n -ms-overflow-style: none!important;\n scrollbar-width: none!important;\n }\n .payment-summary-wrapper::-webkit-scrollbar {\n display: none!important;\n }\n\n .dismiss-btn-resize-in {\n width: 46px!important;\n height: 46px!important;\n transition: 500ms;\n right: 30px!important;\n }\n\n .dismiss-btn-resize-in span {\n display: none;\n }\n\n .dismiss-btn-resize-in:hover {\n width: 217px!important;\n height: 46px!important;\n transition: all 300ms linear;\n cursor: pointer;\n }\n\n .dismiss-btn-resize-in:hover span {\n display: inline;\n height: 20px!important;\n overflow: hidden;\n }\n\n .dismiss-btn-resize-out {\n width: 46px!important;\n height: 46px!important;\n transition: 500ms;\n right: -100px!important;\n }\n\n .slide-in {\n transform: translateX(100%);\n -webkit-transform: translateX(100%);\n animation: slide-in 0.8s forwards !important;\n -webkit-animation: slide-in 0.8s forwards !important;\n z-index: 1000000000000;\n }\n\n .slide-out {\n transform: translateX(100%);\n -webkit-transform: translateX(100%);\n animation: slide-out 1s forwards !important;\n -webkit-animation: slide-out 1s forwards !important;\n z-index: -1000000000000;\n }\n\n @media screen and (max-width:495px) {\n .slide-in {\n transform: translateY(100%);\n -webkit-transform: translateY(100%);\n animation: slide-up 0.8s forwards !important;\n -webkit-animation: slide-up 0.8s forwards !important;\n z-index: 1000000000000;\n }\n .slide-out {\n transform: translateY(100%);\n -webkit-transform: translateY(100%);\n animation: slide-down 0.5s forwards !important;\n -webkit-animation: slide-down 1s forwards !important;\n z-index: -1000000000000;\n }\n }\n\n @keyframes slide-in {\n 100% {\n transform: translateX(0%);\n }\n }\n\n @-webkit-keyframes slide-in {\n 100% {\n -webkit-transform: translateX(0%);\n }\n }\n\n @keyframes slide-up {\n 100% {\n transform: translateY(0%);\n }\n }\n\n @-webkit-keyframes slide-up {\n 100% {\n -webkit-transform: translateY(0%);\n }\n }\n\n @keyframes slide-out {\n 0% {\n transform: translateX(0%);\n }\n 100% {\n transform: translateX(100%);\n }\n }\n\n @-webkit-keyframes slide-out {\n 0% {\n -webkit-transform: translateX(0%);\n }\n 100% {\n -webkit-transform: translateX(100%);\n }\n }\n\n @keyframes slide-down {\n 0% {\n transform: translateY(0%);\n }\n 100% {\n transform: translateY(100%);\n }\n }\n\n @-webkit-keyframes slide-down {\n 0% {\n -webkit-transform: translateY(0%);\n }\n 100% {\n -webkit-transform: translateY(100%);\n }\n }\n ",t=document.createElement("style");t.textContent=e,document.head.append(t),function(e){const t=document.createElement("style");t.textContent=e,document.head.append(t)}(e)}function E(e){const t={startdate:"startDate",enddate:"endDate",rateplancode:"ratePlanCode",rate:"rate",roomid:"roomId",propertyid:"propertyId",destinationid:"destinationId",room:"room",room_count:"roomCount",adult:"adult",child:"child",child_ages:"childAges",infants:"infants",room2_adult:"room2Adult",room2_child:"room2Child",room2_child_ages:"room2ChildAges",room3_adult:"room3Adult",room3_child:"room3Child",room3_child_ages:"room3ChildAges",room4_adult:"room4Adult",room4_child:"room4Child",room4_child_ages:"room4ChildAges",currency:"currency",group:"group",locale:"locale",hotel:"hotel",promo:"promo",promocode:"promocode",selfbook:"selfbook",iatanumber:"iataNumber",couponcode:"couponCode",nights:"nights",reservationid:"reservationId",lastname:"lastName",search:"search",sbsearch:"sbsearch",threeDsContinueId:"three_ds_continue_id",status:"status",roomcategory:"roomCategory",properties:"properties",source:"source",include_inclusive_fees:"includeInclusiveFees",hotelid:"hotelId",version:"version",loyaltyuseremail:"loyaltyUserEmail",loyaltyeventname:"loyaltyEventname",loyaltysignupform:"loyaltySignupForm"};return Array.from(e.entries()).reduce((e,[n,o])=>({...e,[t[n.toLowerCase()]]:o}),{})}function S(){setTimeout(()=>{const t=setInterval(()=>{if(o||l)return;clearInterval(t);const n=E(new URLSearchParams(window.location.search));if("true"!==n.selfbook)return;const a=getHotelBasicData(n.hotel||n.hotelId||e),r=n.version?.toLowerCase?.();SELFBOOK_APP_VERSION=r||a?.app_version||"v2",w(n,a)},100)},500)}function w(e,t={}){const n=parseInt(t?.default_adult_occupancy)||2,o=[{type:"adult",count:e.adult||n},{type:"child",count:e.child||0},{type:"infants",count:e.infants||0}];f({...e,guests:o,groupCode:e.group,currency:e.currency||e.currencyCode,promoCode:e.promo||e.promocode,hotelId:e.hotel||e.hotelId||void 0,roomCategory:"string"==typeof e.roomCategory?e.roomCategory.split(",").map(e=>e.trim()):void 0})}async function b(){!function(){const e=document.createElement("div"),t=document.createElement("div");e.setAttribute("id","selfbook_sdkwidget"),e.style.display="none",t.setAttribute("id","selfbook_sdkwidget_wrapper"),t.style.background="rgba(0, 0, 0, 0)",t.style.position="fixed",t.style.top="0",t.style.right="0",t.style.width="100%",t.style.transition="background .5s ease-out",t.appendChild(e),document.body.appendChild(t)}(),await m(),function(){if(!0!==s){if(n&&n.length>0){const e=document.getElementsByTagName("head")[0];n.forEach(t=>{if(t.includes(".css")){const n=document.createElement("link");n.rel="stylesheet",n.type="text/css",n.media="all",n.href=`${SELFBOOK_APP_BASE_URL}/${t}`,e.appendChild(n)}})}s=!0}}(),_(),document?.querySelectorAll("a").forEach(t=>{t.addEventListener("click",t=>{try{"A"!==t.target.tagName&&"A"===t.target.parentNode?.tagName&&(t.target.href=t.target.parentNode.href);const n=t.target.href||"";if(-1===n.indexOf("?"))return;const o=E(new URLSearchParams(n.substring(n.indexOf("?")))),a=getHotelBasicData(o.hotelId||o.hotel||e);if(SELFBOOK_APP_VERSION=o.version?.toLowerCase?.()||a?.app_version||"v2",a?.mobile_display_only&&window.innerWidth>=768)return;(isTemplateDomainMatch(a,t)||"true"===o.selfbook)&&(t.preventDefault(),w(o,a))}catch(e){console.error("a-element: err: ",e)}})}),"complete"===document?.readyState?S():window?.addEventListener("load",S)}function O(e){return e.toISOString()}function I(){return new Promise(e=>{const t=document.createElement("script");t.src=`https://cdn.jsdelivr.net/npm/@statsig/js-client@3/build/statsig-js-client.min.js?apikey=${STATSIG_CLIENT_KEY}`,t.async=!0,t.onload=async()=>{await async function(){const e={userID:L()};let t=new window.Statsig.StatsigClient(STATSIG_CLIENT_KEY,e);await t.initializeAsync(),window.selfbookStatsigClient=t}(),e(t)},t.onerror=t=>{console.log("Failed to load Statsig script",t),e()},document.head.appendChild(t)})}function L(){const e="selfbook_statsig_anonymous_id";let t=localStorage.getItem(e);return t||(t=crypto.randomUUID?crypto.randomUUID():Math.random().toString(36).substring(2,15),localStorage.setItem(e,t)),t}async function k(n,r){try{o=!0;const s=r?`?id=${r}`:"",l=await u({url:`${SELFBOOK_BACKEND_URL}/hotels/info${s}`,headers:{"content-type":"application/json","API-Key":n}});sessionStorage.setItem(SELFBOOK_HOTEL_GROUP_INFO,JSON.stringify(l));const p={...l},_=getHotelBasicData(r);(function(e){const t=getFromSessionStorage(SELFBOOK_HOTEL_GROUP_INFO);return!("single"!==t?.structure||!e?.enable_direct_distribution_network&&!e?.enable_flex_cancellation)||!("group"!==t?.structure||!t?.hotels.some(e=>e.enable_direct_distribution_network||e.enable_flex_cancellation))||!("multiple_properties"!==t?.structure||!t?.hotels.some(e=>e.enable_direct_distribution_network||e.enable_flex_cancellation))})(_)&&await I(),d();const m=getIsLayers(_);!_?.enable_direct_distribution_network||m||c||initWidgets({apiKey:t,hotelId:e,hotelData:_}),m||initFloatingSearchbar({apiKey:t,hotelId:e});const g=E(new URLSearchParams(window.location.search));if(SELFBOOK_APP_VERSION=g.version?.toLowerCase?.()||_?.app_version||"v2",m?SELFBOOK_APP_BASE_URL=SELFBOOK_BASE_URL_LAYERS:SELFBOOK_APP_VERSION.match(/^v3/i)?(SELFBOOK_APP_BASE_URL=SELFBOOK_BASE_URL_V3,p.hotels=p?.hotels?.map(e=>({...e,enable_v3_new_ui_version:!0}))):SELFBOOK_APP_BASE_URL=SELFBOOK_BASE_URL,sessionStorage.setItem(SELFBOOK_HOTEL_GROUP_INFO,JSON.stringify(p)),!i&&getIsEnableV35(_)&&_?.is_default_date_logic_enabled&&"group"!==p?.structure)try{const t=await async function(t,n,o){try{const a=function(){const e=new Date,t=new Date(e.getFullYear(),e.getMonth(),1),n=new Date(e.getFullYear(),e.getMonth()+2,0);return{startDate:A(t),endDate:A(n)}}(),r={start_date:a.startDate,end_date:a.endDate,currency_code:o?.currency_code||"USD",guests:[{type:"adult",count:o?.default_adult_occupancy||2}]};window.sb_sdkBus.emit("sdk-calendar-status",{type:"loading",payload:r});const s=await u({url:`${"v2"===SELFBOOK_APP_VERSION?SELFBOOK_BACKEND_URL:SELFBOOK_BACKEND_URL.replace("v2","v3")}/hotels/${n||e}/calendar`,headers:{"content-type":"application/json","API-Key":t},data:JSON.stringify(r),method:"POST"});return initialCalendarResponse=s,window.sb_sdkBus.emit("sdk-calendar-status",{type:"success",payload:s}),s.data}catch(e){window.sb_sdkBus.emit("sdk-calendar-status",{type:"error",error:e.message}),console.log(e)}}(n,r,_),o=function(e){const t=new Date,n=t.getUTCFullYear(),o=t.getUTCMonth(),a=t.getUTCDate(),r=new Date(Date.UTC(n,o,a+14));let s=e.filter(e=>function(e){const[t,n,o]=e.split("-").map(Number);return new Date(Date.UTC(t,n-1,o))}(e.date)>r&&null!=e.price);0===s.length&&(s=e.filter(e=>null!=e.price));return 0===s.length?null:s.reduce((e,t)=>t.price`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`;const B=document?.getElementById("selfbook_jssdk");if(B){const n=new URL(B.getAttribute("src"));if(e=n.searchParams.get("hotelId"),t=n.searchParams.get("apiKey"),c="true"===n.searchParams.get("ddnLandingPage"),"?11howard"===window.location.search&&window.location.href.includes("staging")&&(e="66350",t="x9GTqyGB8Pboi5Tkk3fuQUrQ8qAecxzxNY0"),!t||!e)throw new Error("(!) selfbook: ApiKey and HotelId are required.");window.isSelfbookSDKActive=!0,initSDKBus(),k(t,e).then(e=>{getIsLayers(e)||h()})}window&&(window.sbApiLogger=function(n,o={},a){const r=`${"v2"===SELFBOOK_APP_VERSION?SELFBOOK_BACKEND_URL:SELFBOOK_BACKEND_URL.replace("v2","v3")}/hotels/${a||e}/events`;try{const e={generated_at:(new Date).toISOString(),event_source:"SDK",event_name:n,body:JSON.stringify(o)};fetch(r,{method:"POST",headers:{"Content-Type":"application/json","API-Key":t},body:JSON.stringify(e)})}catch(e){console.error("sbApiLogger error:",e)}},window.book=function(e,t,n,o,a,r,s,i,l,c,d="fr",u,p,_){f({startDate:e,endDate:t,guests:n,propertyId:o,currency:a,roomId:r,ratePlanCode:s,rate:i,promoCode:l,groupCode:c,locale:d,destinationId:p,hotelId:u,roomCategory:_})},window.bookNow=f,window.closeSelfbookWidget=function(){const e=getElementById("selfbook_sdkwidget"),t=getElementById("selfbook_sdkwidget_wrapper");setOverflowHidden(!1),e.setAttribute("class","slide-out"),t.style.background="rgba(0, 0, 0, 0)",window.selfbookWidgetStore.dispatch({type:"WIDGET/SELFBOOK_WIDGET_CLOSED"}),window.selfbookWidgetStore.dispatch({type:"ANALYTICS/TRACK_EVENT",payload:{eventType:"widget closed"}}),window.toggleShowSBSignalBox?.(!0),setTimeout(()=>{e.style.display="none",t.style.zIndex=-1e11},800)})}runDirectApplication(); /* Velas Resorts - iHotelier USD pricing hotels are part of separate SDK, under 99914 - Mar Del Cabo (107994) "mardelcabo" // www.mardelcabo.com/ - Casa Velas Boutique Hotel (14471) "hotelcasavelas" // www.hotelcasavelas.com/÷ - Velas Vallarta (14883) "velasvallarta" // www.velasvallarta.com/ - Grand Velas Boutique Hotel Los Cabos (115761) "loscabosboutique" // loscabosboutique.grandvelas.com/ - Grand Velas Riviera Nayarit (15042) "vallarta" // vallarta.grandvelas.com/ - Grand Velas Los Cabos (99914) "loscabos" // loscabos.grandvelas.com/ - Grand Velas Riviera Maya (15342) "rivieramaya" // rivieramaya.grandvelas.com/ - Group website: www.velasresorts.com - Group website: www.grandvelas.com MXN pricing hotels: - Grand Velas Los Cabos - 102826 - Grand Velas Riviera Maya - 73938 - Mar Del Cabo - 116298 - Grand Velas Riviera Nayarit - 73945 - Casa Velas Hotel Boutique - 73942 - Velas Vallarta - 73940 */ /* Hotel specific CTAs are redirected to external domain before reaching TC Portal. These links contain either "com/tracking/click", "com.mx/tracking/click" or "click-reservation-" When initial list of links is pulled, we then "map" known link for a hotel with that hotel's TC hotel code */ function getHotelId(link) { let hotelLinkContains = { /*USD pricing hotels:*/ /* Casa Velas Boutique Hotel */ "14471": 14471, "hotelcasavelas.com/tracking/click": 14471, /* Mar Del Cabo */ "107994": 107994, "mardelcabo.com/tracking/click": 107994, /* Velas Vallarta */ "14883": 14883, "velasvallarta.com/tracking/click": 14883, /* Grand Velas Riviera Maya */ "15342": 15342, "com/tracking/click-reservation-gvrm": 15342, "rivieramaya.grandvelas.com/tracking/click": 15342, /* Grand Velas Riviera Nayarit */ "15042": 15042, "com/tracking/click-reservation-gvrn": 15042, "vallarta.grandvelas.com/tracking/click": 15042, /* Grand Velas Boutique Los Cabos */ "115761": 115761, "com/tracking/click-reservation-gvblc": 115761, "loscabosboutique.grandvelas.com/tracking/click": 115761, /* Grand Velas Los Cabos */ "99914": 99914, "com/tracking/click-reservation-gvlc": 99914, "loscabos.grandvelas.com/tracking/click": 99914, /* MXN pricing hotels:*/ /* Grand Velas Los Cabos - 102826 */ "102826": 102826, "loscabos.grandvelas.com.mx/tracking/click": 102826, /* Grand Velas Riviera Maya - 73938 */ "73938": 73938, "rivieramaya.grandvelas.com.mx/tracking/click": 73938, /* Mar Del Cabo - 116298 */ "116298": 116298, "mardelcabo.com.mx/tracking/click": 116298, /* Grand Velas Riviera Nayarit - 73945 */ "73945": 73945, "vallarta.grandvelas.com.mx/tracking/click": 73945, /* Casa Velas Hotel Boutique - 73942 */ "73942": 73942, "hotelcasavelas.com.mx/tracking/click": 73942, "loscabosboutique.grandvelas.com.mx/tracking/click": 73942, /* Velas Vallarta - 73940 */ "73940": 73940, "velasvallarta.com.mx/tracking/click": 73940, }; for (const [key, id] of Object.entries(hotelLinkContains)) { if (link.includes(key)) { return id; // Return the corresponding hotel ID } } return null; // Return null if no match is found } function gvlcHotelIdByLang() { if (window.location.href.includes("www.velasresorts.com.mx")) { return "102826" } return "99914" } // hide property selector to prevent guests from selecting hotels that may not be live const hideHotelSelector = document.createElement('style'); hideHotelSelector.innerText = ` [data-testid="sb-property-select"], button[aria-label="Global Settings"]{ display: none !important; } #sb-top-wrapper { margin-top: 0px !important; } `; document.head.appendChild(hideHotelSelector); console.log( '%c Selfbook script loaded', 'background: #000; color: white;', ); function removeDueNowDueLaterSection() { if (document.querySelector('#selfbook_sdkwidget section div ul li')) { document.querySelectorAll('#selfbook_sdkwidget section div ul li').forEach(li => { // console.log(li.textContent.toLowerCase()) let elmText = li.textContent.toLowerCase(); if (elmText.includes("due now")) { li.remove(); } else if (elmText.includes("due later")) { li.remove(); } else if (elmText.includes("vence ahora")) { li.remove(); } else if (elmText.includes("vencimiento más tarde")) { li.remove(); } else if (elmText.includes("à payer maintenant")) { li.remove(); } else if (elmText.includes("à payer plus tard")) { li.remove(); } else if (elmText.includes("jetzt fällig")) { li.remove(); } else if (elmText.includes("später fällig")) { li.remove(); } }); } } let sbBookBtnOnPayment = document.createElement("style"); sbBookBtnOnPayment.innerHTML = ` #sb-pay > span, #sb-pay span:nth-child(2) { display: none !important; } #sb-pay { display: flex !important; align-items: center !important; justify-content: center !important; } `; document.head.appendChild(sbBookBtnOnPayment); setInterval(() => { removeDueNowDueLaterSection(); }, 1000); function modifyExistingSbLinks() { const links = document.querySelectorAll(`a[href*='selfbook=true']`); for (const link of links) { const href = link.getAttribute('href'); if (href) { const updatedHref = href.toString().toLowerCase(); const linkObj = hrefToObj(updatedHref); const finalParams = assignObjectVals(linkObj) link.setAttribute('href', window.location.href); link.addEventListener("click", (e) => { e.preventDefault(); bookNow(finalParams); console.log('modifyExistingSbLinks()', finalParams) }); } } } function setLocale(locale) { // Hotels support Spanish Spain const localeList = { "es-ES": "es", "es-es": "es", "es": "es", /* Spanish (Spain) */ "es-MX": "es", "es-mx": "es", /* Spanish (Mexico) */ } return localeList[locale] || localeList[document.documentElement.lang] || "en"; }; // Checks the format of the inputted date and puts it in the correct order format (YYYY-MM-DD) function convertDate(date) { try { const inputDate = new Date(date); const year = inputDate.getFullYear(); const month = (inputDate.getMonth() + 1).toString().padStart(2, '0'); const day = inputDate.getDate().toString().padStart(2, '0'); return [year, month, day].join('-'); } catch (error) { console.log(error, 'convertDate'); } }; // Validates date format is 'YYYY-MM-DD' function checkDateIsISOformat(inputString) { try { const regexPattern = /^\d{4}-\d{2}-\d{2}$/; return regexPattern.test(inputString); } catch (error) { console.log(error, 'checkDateIsISOformat'); } } /* Verifies these date formats: 'DD MONTH YYYY', 'YYYY-MM-DD', 'YYYY/MM/DD', 'MM/DD/YYYY' */ function verifyFutureDate(date) { try { if (date) { if (checkDateIsISOformat(date)) { const inputDate = new Date(date); const today = new Date(); today.setHours(0, 0, 0, 0); if (inputDate >= today) { const formattedDate = inputDate.toISOString().split('T')[0]; return formattedDate; } } else { const inputDate = new Date(date); const today = new Date(); today.setHours(0, 0, 0, 0); if (inputDate >= today) { return convertDate(inputDate); } } } return ''; } catch (error) { console.log(error, 'verifyFutureDate'); } } // arrival > departure, return new departure function compareDates(arrive, depart) { try { let arrivalDate = new Date(arrive); let departureDate = new Date(depart); arrivalDate.setHours(0, 0, 0, 0); departureDate.setHours(0, 0, 0, 0); if (arrivalDate > departureDate) { arrivalDate.setDate(arrivalDate.getDate() + 1); departureDate = arrivalDate; } return departureDate.toLocaleDateString('en-US', { year: 'numeric', month: '2-digit', day: '2-digit' }); } catch (error) { console.log(error, 'compareDates'); } } function reformatDate(date) { if (date) { let [month, day, year] = date.split("/"); return [year, month, day].join('-'); } return "" } /* This function flattens the array / object within guests */ function pruneGuests(object) { try { const pruneObject = object; if (pruneObject.guests && Array.isArray(pruneObject.guests)) { const guests = pruneObject.guests; for (const guest of guests) { if (guest.type === 'adult' && guest.count > 0) { pruneObject.adult = guest.count; } else if (guest.type === 'child' && guest.count > 0) { pruneObject.child = guest.count; } } delete pruneObject.guests; } // console.log('pruneObject', pruneObject); return pruneObject; } catch (error) { console.log(error, 'pruneGuests'); } } /* Fix for Currency Case Bug */ function upperCaseCurrency(currency) { try { if (!currency) { return null; } const currencyCode = currency.toUpperCase(); return currencyCode; } catch (error) { console.log(error, 'upperCaseCurrency'); } }; /* This function defines the bookNow() Object and assigns the values after running it through pruneObjectKeys(). */ function assignObjectVals(param) { try { const urlData = param; const arrive = urlData.datein || urlData.startdate; const depart = urlData.dateout || urlData.enddate; const updatedLocale = setLocale(urlData.locale); const updatedCurrency = upperCaseCurrency(urlData.currency); delete urlData.locale; delete urlData.currency; const bookNowParams = { startDate: verifyFutureDate(arrive), endDate: verifyFutureDate(depart), guests: [ { type: 'adult', count: (!urlData.adult ? null : parseInt(urlData.adult, 10)) }, { type: 'child', count: (!urlData.child ? null : parseInt(urlData.child, 10)) }, ], propertyId: urlData.propertyId, currency: updatedCurrency, roomId: urlData.roomtypeid || urlData.roomid, ratePlanCode: urlData.rate || urlData.rateplancode, promoCode: urlData.advertisementid || urlData.promocode, groupCode: urlData.group, locale: updatedLocale, hotel: urlData.hotel || urlData.hotelid, hotelId: urlData.hotel || urlData.hotelid, iataNumber: urlData.agencyid, ...urlData }; // Remove any properties with null or undefined values Object.keys(bookNowParams).forEach((key) => { if (bookNowParams[key] === null || bookNowParams[key] === undefined || bookNowParams[key] === "") { delete bookNowParams[key]; } }); return bookNowParams; } catch (error) { console.log(error, 'assignObjectVals'); } }; // Create a function that parses the URL and returns an object with the params function hrefToObj(url) { try { let href = url.replace(/%20/g, '') const params = (href.indexOf('?') == -1) ? {} : Object.fromEntries(new URLSearchParams( href.substring(href.indexOf('?')), )); return params; } catch (error) { console.log(error, 'hrefToObj'); } } // Create a direct link function objToSBlinks(params) { try { let siteUrl = `${window.location.pathname}?selfbook=true`; let sbObj = assignObjectVals(params); let prunedSBobj = pruneGuests(sbObj); let urlParams = decodeURIComponent( new URLSearchParams(prunedSBobj), ).toString(); return `${siteUrl}&${urlParams}`; } catch (error) { console.log(error, 'objToSBlinks'); } } function extractHotelID(url) { // Regular expression to match the numeric ID part of the URL const regex = /\/(\d+)/; // Execute the regular expression on the given URL const match = url.match(regex); // If there's a match, return the first capturing group (the numeric ID) // console.log('match is an array', match); return match ? match[1] : null; } // function returnProperMonthDate(date) { let months = { 'jan': '01', 'feb': '02', 'mar': '03', 'apr': '04', 'may': '05', 'jun': '06', 'jul': '07', 'aug': '08', 'sep': '09', 'oct': '10', 'nov': '11', 'dec': '12' } if (date.includes("/")) { return reformatDate(date); } let [paramMonth, paramDay] = date.toLowerCase().split(" "); let curMonth = new Date().getMonth(); let curYear = new Date().getFullYear(); let properMonth = months[paramMonth]; // console.log(properMonth, curYear); if (properMonth < curMonth) { // this means month for following year curYear += 1; } return [curYear, properMonth, paramDay].join("-"); } function returnISOdates(date) { if (date) { return new Date(date).toISOString().split("T")[0]; } return "" } /* Find booking links with specific keywords, then point them to Selfbook */ function linkReplacer(linkCollection, hId) { const allTCLinks = document.querySelectorAll(linkCollection); if (allTCLinks.length > 0) { for (let i = 0; i < allTCLinks.length; i++) { const link = allTCLinks[i].href.toString().toLowerCase(); let tempParams = {}; if (link.includes('?')) { const linkObj = hrefToObj(link); tempParams = assignObjectVals(linkObj); } let hotel_id = getHotelId(link); if (hotel_id === 102826 || hotel_id === 99914 || hotel_id === hId) { /* MXN pricing - Grand Velas Los Cabos - 102826 USD pricing - Grand Velas Los Cabos - 99914 */ const finalParams = { ...tempParams, hotelId: hotel_id }; allTCLinks[i].removeAttribute('target'); allTCLinks[i].href = "#"; allTCLinks[i].addEventListener('click', (e) => { e.preventDefault(); e.stopImmediatePropagation(); bookNow(finalParams); }); } } } }; function serializeBookingForm(form) { let formData = new FormData(form); let params = new URLSearchParams(); for (let [key, value] of formData.entries()) { params.append(key, value); } return params.toString(); } function queryStringToObj(queryString) { let params = new URLSearchParams(queryString); let result = {}; for (let [key, value] of params.entries()) { result[key] = value; } const tempGuests = []; // Add adults let adults = parseInt(result.adults || result.Adults) if (adults > 0) { tempGuests.push({ type: 'adult', count: adults }); } // Add each child as a separate guest with age for (let i = 1; i <= result.children; i++) { const ageKey = `child_age_${i}`; const ageVal = result[ageKey]; if (ageVal !== undefined && ageVal !== '') { tempGuests.push({ type: 'child', count: 1, age: parseInt(ageVal, 10) }); } } result.guests = tempGuests; return result; } function dateStringToISO(date) { if (!date) return null; // Check for MM/DD/YYYY format const mmddyyyy = /^(\d{2})\/(\d{2})\/(\d{4})$/; const mmmddyyyy = /^([A-Za-z]{3}) (\d{1,2}), (\d{4})$/; if (mmddyyyy.test(date)) { let [, month, day, year] = date.match(mmddyyyy); return `${year}-${month}-${day}`; } if (mmmddyyyy.test(date)) { let [, monthStr, day, year] = date.match(mmmddyyyy); const monthMap = { Jan: '01', Feb: '02', Mar: '03', Apr: '04', May: '05', Jun: '06', Jul: '07', Aug: '08', Sep: '09', Oct: '10', Nov: '11', Dec: '12' }; const month = monthMap[monthStr]; if (month) { let paddedDay = String(day).padStart(2, '0'); return `${year}-${month}-${paddedDay}`; } } // Fallback: return null if format doesn't match return null; } function mapFormObjToSB(obj, sbHotelId) { let bookingParms = { startDate: dateStringToISO(obj.checkindate), endDate: dateStringToISO(obj.checkoutdate), guests: obj.guests, hotelId: sbHotelId, } return bookingParms; } function returnHotelIdByName(name) { const hotelList = { "grand velas los cabos": 99914, "grand velas riviera maya": 15342, "grand velas riviera nayarit": 15042, "grand velas boutique los cabos": 115761, "casa velas": 14471, "casa velas boutique hotel": 14471, "velas vallarta": 14883, "mar del cabo": 107994, } return hotelList[name] || ""; }; function submitButtomCloner(submitButtom, callback) { if (submitButtom.getAttribute("type") !== null) { submitButtom.removeAttribute("type"); } if (submitButtom.getAttribute("onclick") !== null) { submitButtom.removeAttribute("onclick"); } const submitButtomClone = submitButtom.cloneNode(true); submitButtom.parentNode.replaceChild(submitButtomClone, submitButtom); submitButtomClone.addEventListener('click', (e) => { e.preventDefault(); e.stopImmediatePropagation(); // eslint-disable-next-line no-undef callback(); }); } // Clone a CTA function bookNowCloner(bookNowButton) { const bookNowButtonClone = bookNowButton.cloneNode(true); bookNowButton.parentNode.replaceChild(bookNowButtonClone, bookNowButton); bookNowButtonClone.addEventListener('click', (e) => { e.preventDefault(); e.stopImmediatePropagation(); // eslint-disable-next-line no-undef bookByUrl(); }); } function bookByUrl() { let hotel = ""; let site = window.location.host; if (site === "www.mardelcabo.com") { hotel = "107994" } else if (site === "www.mardelcabo.com.mx") { hotel = "116298" } else if (site === "www.hotelcasavelas.com") { hotel = "14471" } else if (site === "www.hotelcasavelas.com.mx") { hotel = "73942" } else if (site === "www.velasvallarta.com") { hotel = "14883" } else if (site === "www.velasvallarta.com.mx") { hotel = "73940" } else if (site === "rivieramaya.grandvelas.com") { hotel = "15342" } else if (site === "rivieramaya.grandvelas.com.mx") { hotel = "73938" } else if (site === "vallarta.grandvelas.com") { hotel = "15042" } else if (site === "vallarta.grandvelas.com.mx") { hotel = "73945" } else if (site === "loscabosboutique.grandvelas.com") { hotel = "115761" } else if (site === "loscabosboutique.grandvelas.com.mx") { hotel = "73942" } else if (site === "loscabos.grandvelas.com") { hotel = "99914" } else if (site === "loscabos.grandvelas.com.mx") { hotel = "102826" } bookNow({ hotelId: hotel }); } // function returnProperMonthDate(date) { let months = { 'jan': '01', 'feb': '02', 'mar': '03', 'apr': '04', 'may': '05', 'jun': '06', 'jul': '07', 'aug': '08', 'sep': '09', 'oct': '10', 'nov': '11', 'dec': '12' } if (date.includes("/")) { return reformatDate(date); } let [paramMonth, paramDay] = date.toLowerCase().split(" "); let curMonth = new Date().getMonth(); let curYear = new Date().getFullYear(); let properMonth = months[paramMonth]; // console.log(properMonth, curYear); if (properMonth < curMonth) { // this means month for following year curYear += 1; } return [curYear, properMonth, paramDay].join("-"); } function convertDateToISO(date) { if (date) { let [month, day, year] = date.split("/"); return [year, month, day].join('-'); } return ""; }; function returnISOdates(date) { if (date) { return new Date(date).toISOString().split("T")[0]; } return "" } function replaceDollarSignsOnPage() { try { // console.log('replaceDollarSignsOnPage') let currencyState = null; if (typeof selfbookWidgetStore !== 'undefined' && selfbookWidgetStore?.getState()?.core?.hotel?.data?.currency_code) { currencyState = selfbookWidgetStore?.getState().core?.currency?.currencyConversionCode; if (!currencyState) { currencyState = selfbookWidgetStore?.getState()?.core?.hotel?.data?.currency_code } } const viewCategory = document.querySelector('#selfbook_sdkwidget'); const modalContent = document.querySelector('#sb-modalcontent'); if (currencyState && currencyState === 'USD' && viewCategory !== null) { // console.log('currencyState = ', currencyState); let walker = document.createTreeWalker( viewCategory, NodeFilter.SHOW_TEXT, null, false ); let node; while ((node = walker.nextNode())) { // Skip nodes inside #sb-modalcontent // if (modalContent && modalContent.contains(node.parentNode)) { // continue; // } if (node.nodeValue.includes('$') && !node.nodeValue.includes('CA$') && !node.nodeValue.includes('A$') && !node.nodeValue.includes('R$') && !node.nodeValue.includes('CLP$') && !node.nodeValue.includes('COP$') && !node.nodeValue.includes('HK$') && !node.nodeValue.includes('MX$') && !node.nodeValue.includes('S$') ) { node.nodeValue = node.nodeValue.replace(/\$/g, 'USD'); } } } } catch (error) { console.log('replaceDollarSignsOnPage error:', error); } } const customStylesMobileFixes = document.createElement("style"); customStylesMobileFixes.innerText = ` /* conflict with positioning */ #selfbook-sdkwidget-resume { display: none !important; } @media (width <= 550px) { [data-testid="pricing"] div:nth-child(2) div span{ font-size: 15px !important; } [data-testid="pricing"] div:nth-child(2) div div { font-size: 13px !important; } } `; document.head.appendChild(customStylesMobileFixes); const linkCollection = `a[href*='reservations.travelclick.com'], a[href*='bookings.travelclick.com'], a[href*='reservations.grandvelas.com'], a[href*='reservations.velasresorts.com'], a[href*='ihotelier.com'], a[href*='com/tracking/click'], a[href*='com.mx/tracking/click'], a[href*='click-reservation']`; const customStyles = document.createElement("style"); customStyles.innerText = ` #selfbook-loading { max-width: 150px !important; } table[data-testid="sb-calendar-content"] button[data-testid*="sb-calendar-day-"] > div > div > span { flex-wrap: wrap !important; margin-top: -5px !important; } table[data-testid="sb-calendar-content"] button[data-testid*="sb-calendar-day-"] > div > div > span span:first-child { display: block !important; width: 100% !important; } `; document.head.appendChild(customStyles); // clone form CTA function formCtaCloner(ogCTA, funcName) { const formCTA = ogCTA.cloneNode(true); ogCTA.parentNode.replaceChild(formCTA, ogCTA); formCTA.setAttribute("data-sb-cta", "true"); formCTA.addEventListener("click", funcName); if (formCTA.hasAttribute("type")) { formCTA.removeAttribute("type"); } if (formCTA.hasAttribute("onclick")) { formCTA.removeAttribute("onclick"); } if (formCTA.hasAttribute("onkeypress")) { formCTA.removeAttribute("onkeypress"); } } // Create a custom CTA for the form, allowing for some hotels to use existing form CTA while other(s) use Selfbook // Form action is dynamic as each hotel has it's own URL function gvGradualTransitionFormCtaCloner(ogCTA, funcName, show) { // Clone CTA const formCTA = ogCTA.cloneNode(true); // Attach attributes to distinguish different CTAs ogCTA.parentNode.insertBefore(formCTA, ogCTA.nextSibling); ogCTA.setAttribute("data-og-cta", "true"); formCTA.setAttribute("data-sb-cta", "true"); formCTA.addEventListener("click", funcName); if (formCTA.hasAttribute("type")) { formCTA.removeAttribute("type"); } if (formCTA.hasAttribute("onclick")) { formCTA.removeAttribute("onclick"); } if (formCTA.hasAttribute("onkeypress")) { formCTA.removeAttribute("onkeypress"); } if (show) { formCTA.style = "display: none !important;"; } else { ogCTA.style = "display: none !important;"; } } (() => { // CSS Customization - hide the 'Due Now $' and replace with 'Book Now'? const customStyles = document.createElement("style"); customStyles.innerText = ` #sb-pay { align-items: center !important; justify-content: center !important; } #sb-pay > span { display: none !important; } #sb-pay div #sb-pay-text { visibility: hidden !important; } #selfbook_sdkwidget #sb-pay div #sb-pay-text:after { visibility: visible !important; display: flex !important; justify-content: center !important; align-items: center !important; padding-bottom: 20px !important; } #selfbook_sdkwidget [lang="en"] #sb-pay div #sb-pay-text:after { content: "BOOK NOW" !important; } #selfbook_sdkwidget [lang="es"] #sb-pay div #sb-pay-text:after { content: "RESERVAR AHORA" !important; } #selfbook-loading { max-width: 150px !important; } `; document.head.appendChild(customStyles); })(); setInterval(() => { if ( document.querySelector('#sb-modalcontent ul[data-testid="sb-dropdown-menu"] li div') && !document.querySelector('#sb-modalcontent ul[data-testid="sb-dropdown-menu"] li div[data-sb-updated]') ) { document.querySelector('#sb-modalcontent ul[data-testid="sb-dropdown-menu"] li div').setAttribute("data-sb-updated", "true"); document.querySelectorAll('#sb-modalcontent ul[data-testid="sb-dropdown-menu"] li div') .forEach(listItem => { let item = listItem.textContent.toLowerCase(); if (item.includes('spain')) { listItem.textContent = "SPANISH"; } }); } if (document.querySelector('#sb-modalcontent [data-testid="sb-floatable-container"] button span') && document.querySelector('#sb-modalcontent [data-testid="sb-floatable-container"] button span').textContent.toLowerCase().includes("spain") && !document.querySelector('#sb-modalcontent [data-testid="sb-floatable-container"] button span[data-sb-updated]')) { document.querySelector('#sb-modalcontent [data-testid="sb-floatable-container"] button span').setAttribute('data-sb-updated', 'true'); document.querySelector('#sb-modalcontent [data-testid="sb-floatable-container"] button span').textContent = "SPANISH"; } if (document.querySelector('#selfbook_sdkwidget [lang="es"] [data-testid="sb-edit-booking-guest-count"] div div div span') && !document.querySelector('#selfbook_sdkwidget [lang="es"] [data-testid="sb-edit-booking-guest-count"] div div div span[data-sb-updated]') ) { document.querySelector('#selfbook_sdkwidget [lang="es"] [data-testid="sb-edit-booking-guest-count"] div div div span').setAttribute("data-sb-updated", "true"); document.querySelectorAll('#selfbook_sdkwidget [lang="es"] [data-testid="sb-edit-booking-guest-count"] div div div span').forEach(listItem => { let item = listItem.textContent.toLowerCase(); if (item.includes("years old")) { console.log(listItem) listItem.textContent = "años de edad"; } }); } if (typeof selfbookWidgetStore !== 'undefined' && selfbookWidgetStore?.getState()?.core?.hotel?.data?.currency_code) { let currencyCode = selfbookWidgetStore?.getState()?.core?.hotel?.data?.currency_code; replaceDollarSignsOnPage(); } }, 500); if (window.location.hostname === "loscabos.grandvelas.com") { // if (window.location.hostname === "loscabos.grandvelas.com" || window.location.hostname === "loscabos.grandvelas.com.mx") { // Grand Velas Los Cabos (99914) console.log( '%c Grand Velas Los Cabos (99914) script initialized', 'background: #A4957D; color: white;', ); modifyExistingSbLinks(); linkReplacer(linkCollection, 99914); setInterval(() => { linkReplacer(linkCollection, 99914); if (typeof selfbookWidgetStore !== 'undefined' && selfbookWidgetStore?.getState()?.core?.hotel?.data?.enable_v3_new_ui_version && selfbookWidgetStore?.getState()?.core?.hotel?.data?.id === '99914') { if (document.querySelector('#sb-hotel-group')) { document.querySelector('#sb-hotel-group').setAttribute("style", "display: none !important;") } } }, 1000); if (document.querySelector(`a[data-uk-toggle="target: #modal-container"]`)) { document.querySelectorAll(`a[data-uk-toggle="target: #modal-container"]`).forEach(link => { bookNowCloner(link); }); } // Desktop form handler, for form fixed to footer, on loscabos.grandvelas.com (English) function loscabosDesktopForm() { let obj = {}; obj.hotelId = 99914; obj.startDate = returnISOdates(document.querySelector('#hotelresform input[name="checkindate"]').value); obj.endDate = returnISOdates(document.querySelector('#hotelresform input[name="checkoutdate"]').value); let adults = document.querySelector('#hotelresform #NumberOfAdults').value; let child = document.querySelector('#hotelresform #NumberOfChildrens').value; obj.guests = [ { type: 'adult', count: (!adults ? null : parseInt(adults, 10)) }, { type: 'child', count: (!child ? null : parseInt(child, 10)) }, ]; bookNow(obj); } // Desktop+Mobile form handler on www.grandvelas.com.mx, Spanish site function gvSpanishFormHandler(e) { let obj = {}; obj.hotel = 99914; obj.datein = document.querySelector("#reservationtable form input[name='checkindate']").value; obj.dateout = document.querySelector("#reservationtable form input[name='checkoutdate']").value; obj.adult = document.querySelector("#reservationtable form [name='Adults']").value; obj.child = document.querySelector("#reservationtable form [name='Children']").value; obj.locale = setLocale(); let finalParams = assignObjectVals(obj); bookNow(finalParams); } // slide-down form on desktop (English and Spanish sites) document.querySelector('#hotelresform li.last-child-btn') .addEventListener("click", (e) => { e.preventDefault(); e.stopImmediatePropagation(); pushToGtmRenderByDom($("#hotelresform")); /* Requested by Milestone */ let form = document.querySelector("#hotelresform"); let serializedData = serializeBookingForm(form); let result = queryStringToObj(serializedData); let finalParams = mapFormObjToSB(result, 99914); bookNow(finalParams) console.log("Custom click intercepted. Preventing form submission.", 'serializedData', serializedData, 'finalParams', finalParams); // Prevent reservation_validation1 from executing return false; }, true); // Use capture phase to intercept before inline handler } else if (window.location.hostname === "loscabos.grandvelas.com.mx") { // Grand Velas Los Cabos (102826) console.log( '%c Grand Velas Los Cabos (102826) script initialized', 'background: #A4957D; color: white;', ); const linkCollection = `a[href*='reservations.travelclick.com'], a[href*='bookings.travelclick.com'], a[href*='reservations.grandvelas.com'], a[href*='reservations.velasresorts.com'], a[href*='ihotelier.com'], a[href*='com/tracking/click'], a[href*='com.mx/tracking/click'], a[href*='click-reservation']`; modifyExistingSbLinks(); linkReplacer(linkCollection, 102826); setInterval(() => { linkReplacer(linkCollection, 102826); if (typeof selfbookWidgetStore !== 'undefined' && selfbookWidgetStore?.getState()?.core?.hotel?.data?.enable_v3_new_ui_version && selfbookWidgetStore?.getState()?.core?.hotel?.data?.id === '102826') { if (document.querySelector('#sb-hotel-group')) { document.querySelector('#sb-hotel-group').setAttribute("style", "display: none !important;") } } }, 1000); if (document.querySelector(`a[data-uk-toggle="target: #modal-container"]`)) { document.querySelectorAll(`a[data-uk-toggle="target: #modal-container"]`).forEach(link => { bookNowCloner(link); }); } // Desktop form handler, for form fixed to footer, on loscabos.grandvelas.com (English) function loscabosDesktopForm() { let obj = {}; obj.hotelId = 102826; obj.startDate = returnISOdates(document.querySelector('#hotelresform input[name="checkindate"]').value); obj.endDate = returnISOdates(document.querySelector('#hotelresform input[name="checkoutdate"]').value); let adults = document.querySelector('#hotelresform #NumberOfAdults').value; let child = document.querySelector('#hotelresform #NumberOfChildrens').value; obj.guests = [ { type: 'adult', count: (!adults ? null : parseInt(adults, 10)) }, { type: 'child', count: (!child ? null : parseInt(child, 10)) }, ]; bookNow(obj); } // Desktop+Mobile form handler on www.grandvelas.com.mx, Spanish site function gvSpanishFormHandler(e) { let obj = {}; obj.hotel = 102826; obj.datein = document.querySelector("#reservationtable form input[name='checkindate']").value; obj.dateout = document.querySelector("#reservationtable form input[name='checkoutdate']").value; obj.adult = document.querySelector("#reservationtable form [name='Adults']").value; obj.child = document.querySelector("#reservationtable form [name='Children']").value; obj.locale = setLocale(); let finalParams = assignObjectVals(obj); bookNow(finalParams); } // slide-down form on desktop (English and Spanish sites) document.querySelector('#hotelresform li.last-child-btn') .addEventListener("click", (e) => { e.preventDefault(); e.stopImmediatePropagation(); pushToGtmRenderByDom($("#hotelresform")); /* Requested by Milestone */ let form = document.querySelector("#hotelresform"); let serializedData = serializeBookingForm(form); let result = queryStringToObj(serializedData); let finalParams = mapFormObjToSB(result, 102826); bookNow(finalParams) console.log("Custom click intercepted. Preventing form submission.", 'serializedData', serializedData, 'finalParams', finalParams); // Prevent reservation_validation1 from executing return false; }, true); // Use capture phase to intercept before inline handler } else if (window.location.href.includes("selfbook-staging") && window.location.href.includes("www.velasresorts.com") || window.location.href.includes("www.velasresorts.com") && localStorage.getItem("selfbook-staging") === "true" ) { localStorage.setItem("selfbook-staging", "true"); // Grand Velas Resorts Group website console.log( '%c Grand Velas Resorts Group website script initialized', 'background: #A4957D; color: white;', ); function closeVelasResortsElm() { // close booking form on velasresorts.com // this is creating an 'overlay conflict' if (document.querySelector("#bookstay.uk-open") && document.querySelector("#main-mob-booking > div > div > div.web-header > div.web-only a")) { document.querySelector("#main-mob-booking > div > div > div.web-header > div.web-only a").click() } } // modifyExistingSbLinks(); linkReplacer(linkCollection); setInterval(() => { linkReplacer(linkCollection); }, 1000); // slide-down form on desktop (English and Spanish sites) document.querySelector('#desktopReservationForm1 .bookstay-form__submit-button') .addEventListener("click", (e) => { if (document.querySelector("#hotelselected1").value == "99914" && document.querySelector("#desktopReservationForm1 #resortselector1").value == 'Grand Velas Los Cabos') { e.preventDefault(); e.stopImmediatePropagation(); let form = document.querySelector("#desktopReservationForm1"); let serializedData = serializeBookingForm(form); let result = queryStringToObj(serializedData); let hotelId = gvlcHotelIdByLang(); let finalParams = mapFormObjToSB(result, hotelId); bookNow(finalParams) console.log("Custom click intercepted. Preventing form submission.", 'serializedData', serializedData, 'finalParams', finalParams); closeVelasResortsElm(); // Prevent reservation_validation1 from executing return false; } }, true); // Use capture phase to intercept before inline handler // desktop+footer form document.querySelector("#desktopReservationForm > div > div.hero-slideshow__form-actions.uk-width-auto.uk-text-center > button") .addEventListener("click", (e) => { if (document.querySelector("#hotelselected").value == "99914" && document.querySelector(".booking-sticky-sec form #resortselector").value == 'Grand Velas Los Cabos' ) { e.preventDefault(); e.stopImmediatePropagation(); let form = document.querySelector("#desktopReservationForm"); let serializedData = serializeBookingForm(form); let result = queryStringToObj(serializedData); let hotelId = gvlcHotelIdByLang(); let finalParams = mapFormObjToSB(result, hotelId); bookNow(finalParams) console.log("Custom click intercepted. Preventing form submission.", 'serializedData', serializedData, 'finalParams', finalParams); // Prevent reservation_validation1 from executing return false; } }, true); // Use capture phase to intercept before inline handler } else if ( window.location.href.includes("selfbook-staging") && window.location.hostname === 'rivieramaya.grandvelas.com.mx' || window.location.hostname === 'rivieramaya.grandvelas.com.mx' && localStorage.getItem("selfbook-staging") === "true" ) { // Grand Velas Riviera Maya (73938) console.log( '%c Grand Velas Riviera Maya (73938) script initialized', 'background: #A4957D; color: white;', ); (() => { const customStyles = document.createElement("style"); customStyles.innerText = ` #selfbook_sdkwidget button, #selfbook_sdkwidget .button { font-weight: unset !important; } `; document.head.appendChild(customStyles); })(); const linkCollection = `a[href*='reservations.travelclick.com'], a[href*='bookings.travelclick.com'], a[href*='reservations.grandvelas.com'], a[href*='reservations.velasresorts.com'], a[href*='ihotelier.com'], a[href*='com/tracking/click'], a[href*='com.mx/tracking/click'], a[href*='click-reservation']`; modifyExistingSbLinks(); linkReplacer(linkCollection, 73938); setInterval(() => { linkReplacer(linkCollection, 73938); }, 1000); if (document.querySelector(`a[data-uk-toggle]`)) { document.querySelectorAll(`a[data-uk-toggle]`).forEach(link => { bookNowCloner(link); }); } // Desktop form handler, for form fixed to footer, on loscabos.grandvelas.com (English) function loscabosDesktopForm() { let obj = {}; obj.hotelId = 73938; obj.startDate = returnISOdates(document.querySelector('#hotelresform input[name="checkindate"]').value); obj.endDate = returnISOdates(document.querySelector('#hotelresform input[name="checkoutdate"]').value); let adults = document.querySelector('#hotelresform #NumberOfAdults').value; let child = document.querySelector('#hotelresform #NumberOfChildrens').value; obj.guests = [ { type: 'adult', count: (!adults ? null : parseInt(adults, 10)) }, { type: 'child', count: (!child ? null : parseInt(child, 10)) }, ]; bookNow(obj); } // Desktop+Mobile form handler on www.grandvelas.com.mx, Spanish site function gvSpanishFormHandler(e) { let obj = {}; obj.hotel = 73938; obj.datein = document.querySelector("#reservationtable form input[name='checkindate']").value; obj.dateout = document.querySelector("#reservationtable form input[name='checkoutdate']").value; obj.adult = document.querySelector("#reservationtable form [name='Adults']").value; obj.child = document.querySelector("#reservationtable form [name='Children']").value; obj.locale = setLocale(); let finalParams = assignObjectVals(obj); bookNow(finalParams); } // slide-down form on desktop (English and Spanish sites) document.querySelector('#hotelresform li.last-child-btn') .addEventListener("click", (e) => { e.preventDefault(); e.stopImmediatePropagation(); pushToGtmRenderByDom($("#hotelresform")); /* Requested by Milestone */ let form = document.querySelector("#hotelresform"); let serializedData = serializeBookingForm(form); let result = queryStringToObj(serializedData); let finalParams = mapFormObjToSB(result, 73938); bookNow(finalParams) console.log("Custom click intercepted. Preventing form submission.", 'serializedData', serializedData, 'finalParams', finalParams); // Prevent reservation_validation1 from executing return false; }, true); // Use capture phase to intercept before inline handler } else if ( window.location.href.includes("selfbook-staging") && window.location.hostname === 'rivieramaya.grandvelas.com' || window.location.hostname === 'rivieramaya.grandvelas.com' && localStorage.getItem("selfbook-staging") === "true" ) { // Grand Velas Riviera Maya (15342) console.log( '%c Grand Velas Riviera Maya (15342) script initialized', 'background: #A4957D; color: white;', ); (() => { const customStyles = document.createElement("style"); customStyles.innerText = ` #selfbook_sdkwidget button, #selfbook_sdkwidget .button { font-weight: unset !important; } `; document.head.appendChild(customStyles); })(); const linkCollection = `a[href*='reservations.travelclick.com'], a[href*='bookings.travelclick.com'], a[href*='reservations.grandvelas.com'], a[href*='reservations.velasresorts.com'], a[href*='ihotelier.com'], a[href*='com/tracking/click'], a[href*='com.mx/tracking/click'], a[href*='click-reservation']`; modifyExistingSbLinks(); linkReplacer(linkCollection, 15342); setInterval(() => { linkReplacer(linkCollection, 15342); }, 1000); if (document.querySelector(`a[data-uk-toggle="target: #modal-container"]`)) { document.querySelectorAll(`a[data-uk-toggle="target: #modal-container"]`).forEach(link => { bookNowCloner(link); }); } // Desktop form handler, for form fixed to footer, on loscabos.grandvelas.com (English) function loscabosDesktopForm() { let obj = {}; obj.hotelId = 15342; obj.startDate = returnISOdates(document.querySelector('#hotelresform input[name="checkindate"]').value); obj.endDate = returnISOdates(document.querySelector('#hotelresform input[name="checkoutdate"]').value); let adults = document.querySelector('#hotelresform #NumberOfAdults').value; let child = document.querySelector('#hotelresform #NumberOfChildrens').value; obj.guests = [ { type: 'adult', count: (!adults ? null : parseInt(adults, 10)) }, { type: 'child', count: (!child ? null : parseInt(child, 10)) }, ]; bookNow(obj); } // Desktop+Mobile form handler on www.grandvelas.com.mx, Spanish site function gvSpanishFormHandler(e) { let obj = {}; obj.hotel = 15342; obj.datein = document.querySelector("#reservationtable form input[name='checkindate']").value; obj.dateout = document.querySelector("#reservationtable form input[name='checkoutdate']").value; obj.adult = document.querySelector("#reservationtable form [name='Adults']").value; obj.child = document.querySelector("#reservationtable form [name='Children']").value; obj.locale = setLocale(); let finalParams = assignObjectVals(obj); bookNow(finalParams); } // slide-down form on desktop (English and Spanish sites) document.querySelector('#hotelresform li.last-child-btn') .addEventListener("click", (e) => { e.preventDefault(); e.stopImmediatePropagation(); pushToGtmRenderByDom($("#hotelresform")); /* Requested by Milestone */ let form = document.querySelector("#hotelresform"); let serializedData = serializeBookingForm(form); let result = queryStringToObj(serializedData); let finalParams = mapFormObjToSB(result, 15342); bookNow(finalParams) console.log("Custom click intercepted. Preventing form submission.", 'serializedData', serializedData, 'finalParams', finalParams); // Prevent reservation_validation1 from executing return false; }, true); // Use capture phase to intercept before inline handler } // else if (window.location.href.includes("www.grandvelas.com")) { // // Grand Velas Resorts Group website // console.log( // '%c Grand Velas Resorts Group website script initialized', // 'background: #A4957D; color: white;', // ); // // hide property selector to prevent guests from selecting hotels that may not be live // const customStyles = document.createElement('style'); // customStyles.innerText = ` // #sb-top-wrapper > div:first-child { // display: none !important; // } // #sb-top-wrapper { // margin-top: 0px !important; // } // `; // document.head.appendChild(customStyles); // modifyExistingSbLinks(); // linkReplacer(linkCollection); // setInterval(() => { // linkReplacer(linkCollection); // }, 1000); // if (document.querySelector(`a[data-uk-toggle="target: #modal-container"]`)) { // document.querySelectorAll(`a[data-uk-toggle="target: #modal-container"]`).forEach(link => { // bookNowCloner(link); // }); // } // // Desktop form handler, for form fixed to footer, on grandvelas.com (English+Spanish) // function desktopFormGrandVelas(e) { // e.preventDefault(); // e.stopImmediatePropagation(); // let obj = {}; // obj.hotelId = document.querySelector('form#affixedReservationForm.affixed-booking__form.js-booking-form select[name="hotelid"]').value; // obj.startDate = convertDateToISO(document.querySelector('form#affixedReservationForm.affixed-booking__form.js-booking-form input[name="checkindate"]').value); // obj.endDate = convertDateToISO(document.querySelector('form#affixedReservationForm.affixed-booking__form.js-booking-form input[name="checkoutdate"]').value); // let adults = document.querySelector('form#affixedReservationForm.affixed-booking__form.js-booking-form input[name="adults"]').value; // let child = document.querySelector('form#affixedReservationForm.affixed-booking__form.js-booking-form input[name="children"]').value; // obj.guests = [ // { type: 'adult', count: (!adults ? null : parseInt(adults, 10)) }, // { type: 'child', count: (!child ? null : parseInt(child, 10)) }, // ]; // bookNow(obj); // } // /* // Gradual roll-out of some hotels within Grand Velas // */ // // toggle between CTA for Desktop form, fixed to footer, on grandvelas.com (English) // function footerFormChangeEvent(e) { // // when hotel is changed from hotel list, hide/show a specific CTA // document.querySelector('#affixedReservationForm #affixed-rooms').addEventListener('change', () => { // if (document.querySelector('#affixedReservationForm #affixed-rooms').value === '99914') { // document.querySelector('#affixedReservationForm [data-sb-cta]').style = "display: block !important;"; // document.querySelector('form#affixedReservationForm button[type="submit"]').style = "display: none !important;"; // } // else { // document.querySelector('#affixedReservationForm [data-sb-cta]').style = "display: none !important;"; // document.querySelector('form#affixedReservationForm button[data-og-cta]').style = "display: block !important;"; // } // }); // } // // Desktop form, fixed to footer, on grandvelas.com (English) // if (document.querySelector('form#affixedReservationForm.affixed-booking__form.js-booking-form')) { // // if form exists, set a variable to determine which CTA to display // let setFormCTA = true; // if (document.querySelector('#affixedReservationForm #affixed-rooms').value == "99914") { // setFormCTA = false; // } // // Clone form CTA, attach form function and set it to display or not // gvGradualTransitionFormCtaCloner( // document.querySelector('form#affixedReservationForm.affixed-booking__form.js-booking-form button[type="submit"]'), // desktopFormGrandVelas, // setFormCTA // ); // // Add an event to track input change // footerFormChangeEvent(); // } // function desktopSideFormGV(e) { // e.preventDefault(); // e.stopImmediatePropagation(); // let obj = {}; // obj.startDate = convertDateToISO(document.querySelector("#bookstay-widget-arrival").value); // obj.endDate = convertDateToISO(document.querySelector("#bookstay-widget-departure").value); // obj.hotelId = document.querySelector("#bookstay form #bookstay-select-resort").value; // let adults = document.querySelector('#bookstay form input[name="adults"]').value; // let child = document.querySelector('#bookstay form input[name="children"]').value; // obj.guests = [ // { type: 'adult', count: (!adults ? null : parseInt(adults, 10)) }, // { type: 'child', count: (!child ? null : parseInt(child, 10)) }, // ]; // bookNow(obj); // if (document.querySelector("#bookstay > div > button > span.template-icon.template-icon-Menu-Close")) { // // close the slide-in form // document.querySelector("#bookstay > div > button > span.template-icon.template-icon-Menu-Close").click(); // } // } // function asideFormChangeEvent(e) { // // when hotel is changed from hotel list, hide/show a specific CTA // document.querySelector("#bookstay form #bookstay-select-resort").addEventListener('change', () => { // if (document.querySelector("#bookstay form #bookstay-select-resort").value === '99914') { // document.querySelector('#bookstay form button[data-sb-cta]').style = "display: block !important;"; // document.querySelector('#bookstay form button[data-og-cta]').style = "display: none !important;"; // } // else { // document.querySelector('#bookstay form button[data-sb-cta]').style = "display: none !important;"; // document.querySelector('#bookstay form button[data-og-cta]').style = "display: block !important;"; // } // }); // } // // Desktop side nav on grandvelas.com (English and Spanish) // if (document.querySelector('#bookstay form')) { // // if form exists, set a variable to determine which CTA to display // let setFormCTA = true; // if (document.querySelector("#bookstay form #bookstay-select-resort").value == "99914") { // setFormCTA = false; // console.log('new CTA should show'); // } // gvGradualTransitionFormCtaCloner( // document.querySelector("#bookstay form button[type='submit']"), // desktopSideFormGV, // setFormCTA // ); // asideFormChangeEvent(); // } // } // Mar Del Cabo (107994) "mardelcabo" // www.mardelcabo.com/ // Casa Velas Boutique Hotel (14471) "hotelcasavelas" // www.hotelcasavelas.com/ // Velas Vallarta (14883) "velasvallarta" // www.velasvallarta.com/ // Grand Velas Boutique Hotel Los Cabos (115761) "loscabosboutique" // loscabosboutique.grandvelas.com/ // Grand Velas Riviera Nayarit (15042) "vallarta" // vallarta.grandvelas.com/ // Grand Velas Los Cabos (99914) "loscabos" // loscabos.grandvelas.com/ // Grand Velas Riviera Maya (15342) "rivieramaya" // rivieramaya.grandvelas.com/ // Group website: www.velasresorts.com // Group website: www.grandvelas.com // else if (window.location.href.includes("www.mardelcabo.com")) { // // Mar Del Cabo (107994) // console.log( // '%c Mar Del Cabo (107994) script initialized', // 'background: #A4957D; color: white;', // ); // // Start of hotel specific script // // hide property selector to prevent guests from selecting hotels that may not be live // const customStyles = document.createElement('style'); // customStyles.innerText = ` // #sb-top-wrapper > div:first-child { // display: none !important; // } // #sb-top-wrapper { // margin-top: 0px !important; // } // `; // document.head.appendChild(customStyles); // modifyExistingSbLinks(); // linkReplacer(linkCollection); // setInterval(() => { // linkReplacer(linkCollection); // // CTAs on https://www.mardelcabo.com/ // if (document.querySelector('[data-uk-toggle="target: #book_now"]') // && !document.querySelector('[data-uk-toggle="target: #book_now"][data-sb-updated]')) { // document.querySelector('[data-uk-toggle="target: #book_now"]').setAttribute('data-sb-updated', 'true'); // document.querySelectorAll('[data-uk-toggle="target: #book_now"]').forEach(button => { // bookNowCloner( // button // ); // }); // } // }, 1000); // } // else if (window.location.href.includes("hotelcasavelas.com")) { // // Casa Velas Boutique Hotel (14471) // console.log( // '%c Casa Velas Boutique Hotel (14471) script initialized', // 'background: #A4957D; color: white;', // ); // // Start of hotel specific script // // hide property selector to prevent guests from selecting hotels that may not be live // const customStyles = document.createElement('style'); // customStyles.innerText = ` // #sb-top-wrapper > div:first-child { // display: none !important; // } // #sb-top-wrapper { // margin-top: 0px !important; // } // `; // document.head.appendChild(customStyles); // modifyExistingSbLinks(); // linkReplacer(linkCollection); // setInterval(() => { // linkReplacer(linkCollection); // }, 1000); // // Deskop CTA // if (document.querySelector('.header-bottom-wrap .reserve-btn')) { // bookNowCloner( // document.querySelector('.header-bottom-wrap .reserve-btn') // ) // } // // Mobile CTA // if (document.querySelector('.mobile-footer-sticky-link-wrap div.reserve-btn')) { // bookNowCloner( // document.querySelector('.mobile-footer-sticky-link-wrap div.reserve-btn') // ) // } // } // else if (window.location.href.includes("velasvallarta.com")) { // // Velas Vallarta (14883) // console.log( // '%c Velas Vallarta (14883) script initialized', // 'background: #A4957D; color: white;', // ); // // Start of hotel specific script // // hide property selector to prevent guests from selecting hotels that may not be live // const customStyles = document.createElement('style'); // customStyles.innerText = ` // #sb-top-wrapper > div:first-child { // display: none !important; // } // #sb-top-wrapper { // margin-top: 0px !important; // } // `; // document.head.appendChild(customStyles); // modifyExistingSbLinks(); // linkReplacer(linkCollection) // setInterval(() => { // linkReplacer(linkCollection) // }, 1000); // // CTAs on Desktop (English) // if (document.querySelector('[data-uk-toggle="target: #bookstay"]')) { // document.querySelectorAll('[data-uk-toggle="target: #bookstay"]').forEach(button => { // bookNowCloner( // button // ); // }); // } // function velasVallartaDesktopForm(e) { // e.preventDefault(); // e.stopImmediatePropagation(); // let obj = {}; // obj.datein = document.querySelector("#affixed-dates-arrival").value; // obj.dateout = document.querySelector("#affixed-dates-departure").value; // obj.adult = document.querySelector("#affixedReservationForm .room-guests__col.room-guests__col--input [name='adults']").value; // obj.child = document.querySelector('#affixedReservationForm .room-guests__item.room-guests__item--children [name="children"]').value // let finalParams = assignObjectVals(obj); // bookNow(finalParams); // } // // Desktop form (English) // if (document.querySelector("#affixedReservationForm")) { // formCtaCloner(document.querySelector("#affixedReservationForm button[type='submit']"), velasVallartaDesktopForm) // } // // CTAs on Desktop (Spanish) // if (document.querySelector('div.reserve-btn')) { // bookNowCloner( // document.querySelector('div.reserve-btn') // ); // } // } // else if (window.location.href.includes("loscabosboutique.grandvelas.com")) { // // Grand Velas Boutique Hotel Los Cabos (115761) // console.log( // '%c Grand Velas Boutique Hotel Los Cabos (115761) script initialized', // 'background: #A4957D; color: white;', // ); // // Start of hotel specific script // // hide property selector to prevent guests from selecting hotels that may not be live // const customStyles = document.createElement('style'); // customStyles.innerText = ` // #sb-top-wrapper > div:first-child { // display: none !important; // } // #sb-top-wrapper { // margin-top: 0px !important; // } // `; // document.head.appendChild(customStyles); // } // else if (window.location.href.includes("vallarta.grandvelas.com")) { // // Grand Velas Riviera Nayarit (15042) // console.log( // '%c Grand Velas Riviera Nayarit (15042) script initialized', // 'background: #A4957D; color: white;', // ); // // Start of hotel specific script // // hide property selector to prevent guests from selecting hotels that may not be live // const customStyles = document.createElement('style'); // customStyles.innerText = ` // #sb-top-wrapper > div:first-child { // display: none !important; // } // #sb-top-wrapper { // margin-top: 0px !important; // } // `; // document.head.appendChild(customStyles); else { console.log("SB not loaded"); }