1/*! device.js 0.1.61 */ 2(function () { 3 var a, b, c, d, e, f, g, h, i, j; 4 a = window.fbDeviceDetector, window.fbDeviceDetector = {}, c = window.document.documentElement, j = window.navigator.userAgent.toLowerCase(), fbDeviceDetector.ios = function () { 5 return fbDeviceDetector.iphone() || fbDeviceDetector.ipod() || fbDeviceDetector.ipad() 6 }, fbDeviceDetector.iphone = function () { 7 return d("iphone") 8 }, fbDeviceDetector.ipod = function () { 9 return d("ipod") 10 }, fbDeviceDetector.ipad = function () { 11 return d("ipad") 12 }, fbDeviceDetector.android = function () { 13 return d("android") 14 }, fbDeviceDetector.androidPhone = function () { 15 return fbDeviceDetector.android() && d("mobile") 16 }, fbDeviceDetector.androidTablet = function () { 17 return fbDeviceDetector.android() && !d("mobile") 18 }, fbDeviceDetector.blackberry = function () { 19 return d("blackberry") || d("bb10") || d("rim") 20 }, fbDeviceDetector.blackberryPhone = function () { 21 return fbDeviceDetector.blackberry() && !d("tablet") 22 }, fbDeviceDetector.blackberryTablet = function () { 23 return fbDeviceDetector.blackberry() && d("tablet") 24 }, fbDeviceDetector.windows = function () { 25 return d("windows") 26 }, fbDeviceDetector.windowsPhone = function () { 27 return fbDeviceDetector.windows() && d("phone") 28 }, fbDeviceDetector.windowsTablet = function () { 29 return fbDeviceDetector.windows() && d("touch") && !fbDeviceDetector.windowsPhone() 30 }, fbDeviceDetector.fxos = function () { 31 return (d("(mobile;") || d("(tablet;")) && d("; rv:") 32 }, fbDeviceDetector.fxosPhone = function () { 33 return fbDeviceDetector.fxos() && d("mobile") 34 }, fbDeviceDetector.fxosTablet = function () { 35 return fbDeviceDetector.fxos() && d("tablet") 36 }, fbDeviceDetector.meego = function () { 37 return d("meego") 38 }, fbDeviceDetector.cordova = function () { 39 return window.cordova && "file:" === location.protocol 40 }, fbDeviceDetector.nodeWebkit = function () { 41 return "object" == typeof window.process 42 }, fbDeviceDetector.mobile = function () { 43 return fbDeviceDetector.androidPhone() || fbDeviceDetector.iphone() || fbDeviceDetector.ipod() || fbDeviceDetector.windowsPhone() || fbDeviceDetector.blackberryPhone() || fbDeviceDetector.fxosPhone() || fbDeviceDetector.meego() 44 }, fbDeviceDetector.tablet = function () { 45 return fbDeviceDetector.ipad() || fbDeviceDetector.androidTablet() || fbDeviceDetector.blackberryTablet() || fbDeviceDetector.windowsTablet() || fbDeviceDetector.fxosTablet() 46 }, fbDeviceDetector.desktop = function () { 47 return !fbDeviceDetector.tablet() && !fbDeviceDetector.mobile() 48 }, fbDeviceDetector.portrait = function () { 49 return window.innerHeight / window.innerWidth > 1 50 }, fbDeviceDetector.landscape = function () { 51 return window.innerHeight / window.innerWidth < 1 52 }, fbDeviceDetector.noConflict = function () { 53 return window.fbDeviceDetector = a, this 54 }, d = function (a) { 55 return -1 !== j.indexOf(a) 56 }, f = function (a) { 57 var b; 58 return b = new RegExp(a, "i"), c.className.match(b) 59 }, b = function (a) { 60 return f(a) ? void 0 : c.className += " " + a 61 }, h = function (a) { 62 return f(a) ? c.className = c.className.replace(a, "") : void 0 63 }, fbDeviceDetector.ios() ? fbDeviceDetector.ipad() ? b("ios ipad tablet") : fbDeviceDetector.iphone() ? b("ios iphone mobile") : fbDeviceDetector.ipod() && b("ios ipod mobile") : b(fbDeviceDetector.android() ? fbDeviceDetector.androidTablet() ? "android tablet" : "android mobile" : fbDeviceDetector.blackberry() ? fbDeviceDetector.blackberryTablet() ? "blackberry tablet" : "blackberry mobile" : fbDeviceDetector.windows() ? fbDeviceDetector.windowsTablet() ? "windows tablet" : fbDeviceDetector.windowsPhone() ? "windows mobile" : "desktop" : fbDeviceDetector.fxos() ? fbDeviceDetector.fxosTablet() ? "fxos tablet" : "fxos mobile" : fbDeviceDetector.meego() ? "meego mobile" : fbDeviceDetector.nodeWebkit() ? "node-webkit" : "desktop"), fbDeviceDetector.cordova() && b("cordova"), e = function () { 64 return fbDeviceDetector.landscape() ? (h("portrait"), b("landscape")) : (h("landscape"), b("portrait")) 65 }, i = "onorientationchange" in window, g = i ? "orientationchange" : "resize", window.addEventListener ? window.addEventListener(g, e, !1) : window.attachEvent ? window.attachEvent(g, e) : window[g] = e, e() 66}).call(this); 67 68//Added 2022-09-26 mcanever - Load GA4 crossdomain decoration utility (async just to avoid blocking everything is Cloudfront is down) 69(function () { 70 if (typeof _GA4CrossDomain !== 'undefined') { 71 return; 72 } 73 var s = document.createElement('script'); 74 s.type = 'text/javascript'; 75 s.async = true; 76 s.src = 'https://staticaws.fbwebprogram.com/accor_tracking_decorator/ga4crossdomain.js'; 77 var x = document.getElementsByTagName('script')[0]; 78 x.parentNode.insertBefore(s, x); 79})(); 80//--- 81 82(function (w, global, cfg) { 83 var default_checkin = new Date(); 84 var default_checkout = new Date(default_checkin.getTime() + 86400000); 85 var log = function () { 86 if (w.console && console.log) { 87 console.log.apply(console, Array.prototype.slice.call(arguments)); 88 } 89 }; 90 var serialize = (function (slice) { 91 return function (form) { 92 if (form == null) return {}; 93 var ar = slice.call(form.elements) 94 .filter(function (element) { 95 return !element.disabled; 96 }) 97 .filter(function (element) { 98 return !/^input$/i.test(element.tagName) || !/^(?:checkbox|radio)$/i.test(element.type) || element.checked; 99 }) 100 .filter(function (element) { 101 return !/^select$/i.test(element.tagName) || (typeof (element.selectedOptions) === 'undefined' ? true : element.selectedOptions.length > 0); 102 }) 103 .map(function (element) { 104 switch (element.tagName.toLowerCase()) { 105 case 'checkbox': 106 case 'radio': 107 return {name: element.name, value: element.value === null ? 'on' : element.value}; 108 case 'select': 109 if (element.multiple) { 110 return { 111 name: element.name, 112 value: slice.call(element.selectedOptions).map(function (option) { 113 return option.value; 114 }) 115 }; 116 } 117 return { 118 name: element.name, 119 value: element.value 120 }; 121 default: 122 return { 123 name: element.name, 124 value: element.value || '' 125 }; 126 } 127 }); 128 var obj = {}; 129 if (ar.length > 0) { 130 for (var i = 0; i < ar.length; i++) { 131 var el = ar[i]; 132 if (el.name != '') { 133 obj[el.name] = el.value; 134 } 135 } 136 } 137 return obj;
138 } 139 }(Array.prototype.slice)); 140 var zPad = function (s) { 141 s = s + ''; 142 if (s.length == 1) { 143 s = '0' + s; 144 } 145 return s; 146 }; 147 var isValidObject = function (obj) { 148 return (obj !== null && obj.constructor.toString().indexOf("Array") === -1 && typeof obj === 'object'); 149 }; 150 var merge = function (defaults, obj) { 151 if (!isValidObject(obj) || !isValidObject(defaults)) return defaults; 152 var result = {}; 153 for (var i in defaults) { 154 if (defaults.hasOwnProperty(i)) result[i] = defaults[i]; 155 } 156 for (var i in obj) { 157 if (obj.hasOwnProperty(i)) result[i] = obj[i]; 158 } 159 return result; 160 }; 161 var parseFBdate = function (fbdate) { 162 if (typeof fbdate !== undefined && fbdate.length === 6) { 163 var year = parseInt(fbdate.substr(0, 2), 10) + 2000; 164 var month = parseInt(fbdate.substr(2, 2), 10) - 1; 165 var day = parseInt(fbdate.substr(4, 2), 10); 166 return new Date(year, month, day); 167 } 168 return new Date(); 169 }; 170 var parseQueryString = function (qs) { 171 var queryString = {}; 172 qs.replace( 173 new RegExp("([^?=&]+)(=([^&]*))?", "g"), 174 function ($0, $1, $2, $3) { 175 queryString[$1] = $3; 176 } 177 ); 178 return queryString; 179 }; 180 var parseFirstDate = function (firstdate) { 181 var result = {}; 182 if (typeof firstdate !== 'undefined') { 183 var parts = firstdate.match(/^(\d{6})?;(\d+)?;(\d+)?;([\d|]+)?(;([\d|]+)?)?(&.*)?$/); 184 if (parts) { 185 var arrival_date = false; 186 if (typeof parts[1] !== 'undefined') { 187 arrival_date = parseFBdate(parts[1]); 188 result.arrivalDate = formatDate(arrival_date); 189 } 190 if (typeof parts[2] !== 'undefined' && parts[2] != '') { 191 var nbnights = parseInt(parts[2], 10); 192 if (arrival_date) { 193 result.departureDate = formatDate(new Date(arrival_date.getTime() + nbnights * 86400000)); 194 } else { 195 result.arrivalDate = formatDate(new Date()); 196 result.departureDate = formatDate(new Date(new Date().getTime() + nbnights * 86400000)); 197 } 198 result.arrivalDate = formatDate(parseFBdate(parts[1])); 199 } 200 if (typeof parts[3] !== 'undefined' && parts[3] != '') { 201 result.selectedAdultCount = parts[3]; 202 } 203 if (typeof parts[4] !== 'undefined' && parts[4] != '') { 204 var chunks = parts[4].split('|'); 205 if (chunks.length === 1) { 206 result.selectedChildCount = parts[4]; 207 } else { 208 result.selectedChildCount = chunks[0]; 209 result.selectedInfantCount = chunks[1]; 210 } 211 } 212 // The chunk containing the query string can be either in the 6th, 7th or 8th slot, 213 // depending on the regExp matches 214 for (var idx = 5; idx < 8; idx++) { 215 if (typeof parts[idx] !== 'undefined' && parts[idx] != '') { 216 var qs = parseQueryString(parts[idx]); 217 if (typeof qs.CurrencyLabel !== 'undefined' && qs.CurrencyLabel != '') { 218 result.currency = qs.CurrencyLabel; 219 } 220 if (typeof qs.locale !== 'undefined' && qs.locale != '') { 221 result.language = qs.locale.substr(0, 2).toUpperCase(); 222 } 223 if (typeof qs.rate !== 'undefined' && qs.rate != '') { 224 if (!isNaN(parseInt(qs.rate, 10))) { 225 result.rateAction = 'Highlight'; 226 result.rateId = qs.rate; 227 } else { 228 result.rate = qs.rate; 229 } 230 } 231 } 232 } 233 } 234 } 235 return result; 236 }; 237 var getConfig = function () { 238 if (typeof w[cfg] !== 'undefined') { 239 return w[cfg]; 240 } else { 241 log('$AvailProConfig not found (yet?)'); 242 return {}; 243 } 244 }; 245 var openWindow = function (url) { 246 if (typeof (_gat) != "undefined") { 247 waction = _gat._getTrackerByName()._getLinkerUrl(url); 248 } 249 if (typeof (ga) != "undefined") { 250 ga(function (tracker) { 251 var linkerParam = tracker.get('linkerParam'); 252 url += '&' + linkerParam; 253 }); 254 } 255 //Added 2022-09-26 mcanever - Decorate for GA4 if decorator is available 256 if (typeof _GA4CrossDomain !== 'undefined' && typeof _GA4CrossDomain.decorateURL === 'function') { 257 try { 258 url = _GA4CrossDomain.decorateURL(url); 259 } catch (e) {
260 // Do nothing. Bloody ad blockers. 261 } 262 } 263 //--- 264 window.open(url, '_blank'); 265 }; 266 var clone = function (o) { 267 return JSON.parse(JSON.stringify(o)); 268 }; 269 var maybeDecorateParams = function (params) { 270 var decoratorsCount = 0; 271 //Added 2023-11-03 mcanever - Decorate for GA4 if decorator is available 272 if (typeof _GA4CrossDomain !== 'undefined' && typeof _GA4CrossDomain.decorateObject === 'function') { 273 try { 274 params = _GA4CrossDomain.decorateObject(params); 275 } catch (e) { 276 // Do nothing. Bloody ad blockers. 277 } 278 } 279 //--- 280 if (typeof window.DEdgeBookingFormDecorators !== 'undefined' 281 && typeof window.DEdgeBookingFormDecorators.length !== 'undefined' 282 && window.DEdgeBookingFormDecorators.length > 0 283 ) { 284 for (var i = 0; i < window.DEdgeBookingFormDecorators.length; i++) { 285 var singleDecorator = window.DEdgeBookingFormDecorators[i]; 286 if (typeof singleDecorator === 'function') { 287 params = singleDecorator(params); 288 decoratorsCount++; 289 } 290 } 291 } 292 if (decoratorsCount > 0) { 293 log('Availpro parameters after ' + decoratorsCount + ' decorators', params); 294 } 295 return params; 296 }; 297 var doSubmit = function (path, params, method, target) { 298 299 var isInsite = typeof $AvailProConfig.insite_be !== 'undefined' && $AvailProConfig.insite_be === '1'; 300 301 if (!isInsite) { 302 method = method || "post"; 303 target = target || "_self"; 304 params = params || {}; 305 params = maybeDecorateParams(params); 306 var form = document.createElement("form"); 307 form.setAttribute("method", method); 308 form.setAttribute("action", path); 309 form.setAttribute("target", target); 310 form.setAttribute("style", "display:none;"); 311 for (var key in params) { 312 if (params.hasOwnProperty(key) && params[key] !== false) { 313 var hiddenField = document.createElement("input"); 314 hiddenField.setAttribute("type", "hidden"); 315 hiddenField.setAttribute("name", key); 316 hiddenField.setAttribute("value", params[key]); 317 form.appendChild(hiddenField); 318 } 319 } 320 document.body.appendChild(form); 321 form.submit(); 322 } else { 323 let urlPieces = []; 324 urlPieces.arrival = typeof params.arrivalDate !== 'undefined' ? 'arrivalDate=' + params.arrivalDate : '', 325 urlPieces.departure = typeof params.departureDate !== 'undefined' ? 'departureDate=' + params.departureDate : '', 326 urlPieces.adults = typeof params.selectedAdultCount !== 'undefined' ? 'selectedAdultCount=' + params.selectedAdultCount : '', 327 urlPieces.children = typeof params.selectedChildCount !== 'undefined' ? 'selectedChildCount=' + params.selectedChildCount : '', 328 urlPieces.infants = typeof params.selectedChildCount !== 'undefined' ? 'selectedInfantCount=' + params.selectedInfantCount : '', 329 urlPieces.hotelId = typeof params.hotelId !== 'undefined' ? 'hotelId=' + params.hotelId : '', 330 urlPieces.rateAction = typeof params.rateAction !== 'undefined' ? 'rateAction=' + params.rateAction : '', 331 urlPieces.rateId = typeof params.rateId !== 'undefined' ? 'rateId=' + params.rateId : '', 332 urlPieces.roomAction = typeof params.roomAction !== 'undefined' ? 'roomAction=' + params.roomAction : '', 333 urlPieces.roomId = typeof params.roomId !== 'undefined' ? 'roomId=' + params.roomId : '', 334 urlPieces.rate = typeof params.rate !== 'undefined' ? 'promoCode=' + params.rate : '', 335 urlPieces.currency = typeof params.currency !== 'undefined' ? 'currency=' + params.currency : ''; 336 337 338 const baseUrl = $AvailProConfig.base_url;
339 let urlParams = ''; 340 Object.values(urlPieces).forEach(function (item, index) { 341 if (item !== '') { 342 urlParams += item + '&'; 343 } 344 }); 345 urlParams = urlParams.substring(0, urlParams.length - 1); //remove last & 346 const url = baseUrl + '?' + urlParams; 347 348 349 insiteBECallDialog(url); 350 351 } 352 }; 353 354 var insiteBECallDialog = function (url) { 355 //mambo jumbo to load the URL in the iframe inside the dialog. Because dialog.showModal() blocks the main thread and prevent loading the iframe properly 356 const dialog = document.querySelector('#dedgeInsiteDialog'); 357 const oldIframe = dialog.querySelector('iframe'); 358 const oldUrl = oldIframe ? oldIframe.src : ''; 359 360 const bodyOverflow = document.body.style.overflow; 361 const iframe = document.createElement('iframe'); 362 363 document.body.style.overflow = "hidden" 364 //check if the URL has changed compared to the existing iframe, otherwise just show the dialog 365 if (oldUrl !== url) { 366 iframe.src = url; 367 iframe.setAttribute('loading', 'eager'); 368 369 iframe.className = oldIframe.className; 370 371 oldIframe.remove(); 372 dialog.appendChild(iframe); 373 374 iframe.classList.add('loading_iframe'); 375 //rebind the click event to the new iframe close button 376 iframe.addEventListener('load', () => { 377 iframe.classList.remove('loading_iframe'); 378 const doc = iframe.contentDocument; 379 doc.addEventListener('click', (e) => { 380 const targetClass = e.target.className; 381 //needed because the gst-button--variation-close is too generic as class name and the button miss a specific class or id to target it directly 382 const parentClass = e.target.parentElement.className; 383 const granParentClass = e.target.parentElement.parentElement.className; 384 if ( 385 //depends on if the target is the button or an icon inside the button, duh! 386 (targetClass.includes('gst-button--variation-close') && parentClass.includes('cvg-header-insite')) || 387 (parentClass.includes('gst-button--variation-close') && granParentClass.includes('cvg-header-insite'))) { 388 dialog.close(); 389 //restore body overflow 390 document.body.style.overflow = bodyOverflow; 391 } 392 }); 393 //esc button added to iframe for accessibility 394 doc.addEventListener('keydown', (e) => { 395 console.log('keydown in iframe', e.key, e.keyCode, e.which); 396 //esc key 397 if (e.key === 'Escape' || e.keyCode === 27 || e.which === 27) { 398 dialog.close(); 399 //restore body overflow 400 document.body.style.overflow = bodyOverflow; 401 } 402 }) 403 }); 404 405 } else { 406 iframe.classList.remove('loading_iframe'); 407 } 408 409 dialog.showModal(); 410 } 411 var buildDate = function (year, month, day, fallback) { 412 //Build a date object from possibly dirty input... 413 if (typeof fallback === 'undefined') { 414 fallback = new Date(); 415 } 416 if (typeof year !== 'undefined') { 417 year = parseInt(year, 10); 418 if (!year || year < 2016) year = fallback.getFullYear(); 419 } else { 420 year = fallback.getFullYear() 421 } 422 if (typeof month !== 'undefined') { 423 month = parseInt(month, 10); 424 if (!month || month < 1 || month > 12) month = fallback.getMonth() + 1; 425 } else { 426 month = fallback.getMonth() + 1 427 } 428 if (typeof day !== 'undefined') { 429 day = parseInt(day, 10); 430 if (!day || day < 1 || day > 31) day = fallback.getDate(); 431 } else { 432 day = fallback.getDate() 433 } 434 return new Date(year, month - 1, day); 435 }; 436 var formatDate = function (dateObj) { 437 if (dateObj === 'undefined') { 438 dateObj = new Date(); 439 } 440 return dateObj.getFullYear() + '-' + zPad(dateObj.getMonth() + 1) + '-' + zPad(dateObj.getDate()); 441 }; 442 var cancelBooking = function (maybeHotelID, language) { 443 var config = getConfig(); 444 var params = clone(defaultParams); 445 if (typeof language !== 'undefined' && language != '') { 446 params.language = language.toUpperCase(); 447 } 448 var cancelUrl = config.base_url.replace('.com/', '.com/modification/'); 449 doSubmit(cancelUrl, params, 'GET', '_blank'); 450 }; 451 var defaultParams = { 452 arrivalDate: formatDate(default_checkin), 453 departureDate: formatDate(default_checkout), 454 selectedAdultCount: 1, 455 selectedChildCount: 0, 456 selectedInfantCount: 0 457 }; 458 var conf = getConfig(); 459 if (typeof conf.pass_language !== 'undefined' && conf.pass_language == '1') { 460 defaultParams.language = conf.language; 461 } 462 if (typeof conf.currency !== 'undefined' && conf.currency != '') { 463 defaultParams.currency = conf.currency; 464 } 465 log('default AVP Params', defaultParams); 466 var openBookingEngine = function (obj) { 467 var config = getConfig(); 468 var params = clone(defaultParams); 469 var baseURL = config.base_url; 470 var overridingBaseURL = false; 471 if ( 472 typeof obj !== 'undefined' 473 && typeof obj.maybeHotelID !== 'undefined' 474 && /^https:\/\//.test(obj.maybeHotelID) 475 ) { 476 overridingBaseURL = true; 477 baseURL = obj.maybeHotelID;
478 } 479 480 if (typeof obj !== 'undefined') { 481 if (typeof obj.firstDate !== 'undefined') { 482 var firstDateObj = parseFirstDate(obj.firstDate); 483 params = merge(params, firstDateObj); 484 } 485 if (typeof obj.language !== 'undefined' && obj.language.match(/^[A-Z]{2}$/)) { 486 params.language = obj.language; 487 } 488 if (typeof obj.roomId !== 'undefined') { 489 params.roomId = obj.roomId; 490 params.roomAction = 'Highlight'; 491 } 492 if (typeof obj.rate !== 'undefined') { 493 var cleanedRate = obj.rate.replace(/&rate=/i, '').replace(/&rate=/i, '').replace(/^rate=/i, '').replace(/\s+/, ''); 494 if (!isNaN(parseInt(cleanedRate, 10))) { 495 params.rateAction = 'Highlight'; 496 params.rateId = cleanedRate; 497 } else { 498 params.rate = cleanedRate; 499 } 500 } 501 if (typeof obj.nights !== 'undefined') { 502 params.arrivalDate = formatDate(new Date()); 503 params.departureDate = formatDate(new Date(new Date().getTime() + 86400000 * parseInt(obj.nights, 10))); 504 } 505 if (typeof (config.currency) !== 'undefined' && config.currency !== '' && config.currency !== null) { 506 params.currency = config.currency; 507 } 508 if (typeof (obj.currency) !== 'undefined' && obj.currency !== '' && obj.currency !== null) { 509 params.currency = obj.currency; 510 } 511 var avp_specific_parameters = ['arrivalDate', 'departureDate', 'selectedAdultCount', 'selectedChildCount', 512 'selectedInfantCount', 'header', 'footer', 'roomId', 'selectedRate', 'selectedRateId', 'city', 'country', 'promoCode']; 513 for (var i = 0; i < avp_specific_parameters.length; i++) { 514 var key = avp_specific_parameters[i]; 515 if (typeof obj[key] !== 'undefined' && obj[key] !== '') { 516 params[key] = obj[key]; 517 } 518 } 519 // if (params.roomId != '' && (typeof params.rate === 'undefined' || params.rate == '' )) { 520 // delete params.arrivalDate; 521 // delete params.departureDate; 522 // delete params.firstDate; 523 // } 524 525 var isGroupBE = typeof config.is_group_be !== 'undefined' && config.is_group_be; 526 var hasSpecificHotelID = typeof obj.maybeHotelID !== 'undefined' && obj.maybeHotelID !== ''; 527 var hasHotelIDFromConfig = typeof config.hid !== 'undefined' && config.hid !== ''; 528 if (!overridingBaseURL && isGroupBE && (hasSpecificHotelID || hasHotelIDFromConfig)) { 529 params.hotelId = hasSpecificHotelID ? obj.maybeHotelID : config.hid; 530 } 531 log(baseURL); 532 log(params); 533 doSubmit(baseURL, params, 'GET', '_blank'); 534 } else { 535 log("openBookingEngine called without params"); 536 doSubmit(baseURL, {}, 'GET', '_blank'); 537 } 538 }; 539 var handleFormSubmit = function (form) { 540 var config = getConfig(); 541 var params = clone(defaultParams); 542 var formData = serialize(form); 543 var formArrivalDate = false; 544 //Read check-in date 545 if (typeof formData.fromyear !== 'undefined' 546 && typeof formData.frommonth !== 'undefined' 547 && typeof formData.fromday !== 'undefined' 548 ) { 549 formArrivalDate = buildDate(formData.fromyear, formData.frommonth, formData.fromday, default_checkin); 550 params.arrivalDate = formatDate(formArrivalDate); 551 } 552 //If we have read correctly arrival, we can set departure to the day after as a fallback 553 var fallback_dep = formArrivalDate ? new Date(formArrivalDate.getTime() + 86400000) : new Date(default_checkout.getTime()); 554 params.departureDate = formatDate(fallback_dep); 555 //Read check-out date 556 var formDepartureDate = false; 557 if (typeof formData.toyear !== 'undefined' 558 && typeof formData.tomonth !== 'undefined' 559 && typeof formData.today !== 'undefined' 560 ) { 561 formDepartureDate = buildDate(formData.toyear, formData.tomonth, formData.today, fallback_dep); 562 params.departureDate = formatDate(formDepartureDate); 563 } 564 if (!formDepartureDate && typeof formData.nbdays !== 'undefined' && parseInt(formData.nbdays, 10) > 0) { 565 var current_checkin = formArrivalDate ? formArrivalDate : default_checkin; 566 formDepartureDate = new Date(current_checkin.getTime() + (parseInt(formData.nbdays, 10) * 86400000)); 567 params.departureDate = formatDate(formDepartureDate); 568 } 569 570 if (typeof formData.adulteresa !== 'undefined' && parseInt(formData.adulteresa, 10) > 0) { 571 params.selectedAdultCount = parseInt(formData.adulteresa, 10); 572 } 573 574 if (typeof formData.enfantresa !== 'undefined' && parseInt(formData.enfantresa, 10) > 0) { 575 params.selectedChildCount = parseInt(formData.enfantresa, 10); 576 params.selectedInfantCount = 0; 577 if (typeof formData.childrenAges1 !== 'undefined' && formData.childrenAges1 != '') { 578 var infants_maxage = 2; 579 var n_infants = 0; 580 var n_children = 0; 581 if (typeof config.infants_maxage !== 'undefined' && config.infants_maxage != '') { 582 infants_maxage = parseInt(config.infants_maxage, 10); 583 } 584 var ages = formData.childrenAges1.split(','); 585 if (ages.length == parseInt(formData.enfantresa, 10)) { 586 for (var i = 0; i < ages.length; i++) { 587 var age = parseInt(ages[i], 10); 588 // By default, if no age is specified by the user, the children will be treated as 589 // children and not infants 590 if (isNaN(age)) { 591 age = infants_maxage + 1; 592 } 593 if (age > infants_maxage) { 594 n_children++; 595 } else { 596 n_infants++; 597 } 598 } 599 params.selectedChildCount = n_children; 600 params.selectedInfantCount = n_infants; 601 } 602 } 603 } 604 if (typeof formData.AccessCode !== 'undefined' && formData.AccessCode !== '') { 605 params.promocode = formData.AccessCode; 606 } 607 608 var avp_specific_parameters = ['header', 'footer', 'roomId', 'rate', 'selectedRate', 'selectedRateId']; 609 for (var i = 0; i < avp_specific_parameters.length; i++) { 610 var key = avp_specific_parameters[i]; 611 if (typeof formData[key] !== 'undefined' && formData[key] !== '') { 612 params[key] = formData[key]; 613 } 614 } 615 if (typeof config.is_group_be !== 'undefined' && config.is_group_be 616 && typeof config.hid !== 'undefined' && config.hid !== '' 617 ) { 618 params.hotelId = typeof formData.maybeHotelID !== 'undefined' && formData.maybeHotelID !== '' ? formData.maybeHotelID : config.hid; 619 } 620 if (typeof (config.currency) !== 'undefined' && config.currency !== '' && config.currency !== null) { 621 params.currency = config.currency; 622 } 623 if (typeof (formData.currency) !== 'undefined' && formData.currency !== '' && formData.currency !== null) { 624 params.currency = formData.currency; 625 } 626 log(config.base_url, params); 627 log('Original Form Params', formData); 628 log('Final Params sent to AvailPro', params); 629 doSubmit(config.base_url, params, 'GET', '_blank'); 630 }; 631 632 /** 633 * Expose $AvailPro 634 */ 635 w[global] = {
636 openBookingEngine: openBookingEngine, 637 handleFormSubmit: handleFormSubmit, 638 openWindow: openWindow, 639 cancelBooking: cancelBooking, 640 insiteBECallDialog: insiteBECallDialog 641 }; 642})(window, '$AvailPro', '$AvailProConfig'); 643 644/** 645 * Cross-compatibility functions: FASTBOOKING Syntax --> AvailPro BE 646 */ 647 648function fbOpenWindow(cname, waction, title, width, height) { 649 $AvailPro.openWindow(waction); 650 transferGAdata(waction); 651} 652 653// Main direct reservation function 654function hhotelResaDirect(cname, lg, codeprice, firstroom, codetrack, firstdate) { 655 hhotelResa(cname, lg, codeprice, firstroom, firstdate, codetrack, "", "", "style=DIRECT"); 656} 657 658// standard search availabilities in a group 659function hhotelSearchGroup(cluster, lg, price, nights, title) { 660 hhotelSearch(cluster, lg, price, nights, title, "", ""); 661} 662 663// go to the cancel reservation page 664function hhotelcancel(cname, lg) { 665 $AvailPro.cancelBooking(cname, lg); 666} 667 668// Main standard reservation function 669function hhotelResa(cname, lg, codeprice, firstroom, firstdate, codetrack, cluster, theme, args) { 670 var options = {maybeHotelID: cname}; 671 if (lg != "") options.language = lg.toUpperCase(); 672 if (firstroom != "") options.roomId = firstroom; 673 if (firstdate != "") options.firstDate = firstdate; 674 if (codeprice != "") { 675 options.rate = codeprice; 676 options.selectedRate = codeprice.replace(/&rate=/i, '').replace(/&rate=/i, '').replace(/^rate=/i, ''); 677 } 678 $AvailPro.openBookingEngine(options); 679} 680 681function hhotelSearch(cluster, lg, price, nights, title, theme, args) { 682 var options = {}; 683 if (lg != "") options.language = lg.toUpperCase(); 684 if (firstroom != "") options.roomId = firstroom; 685 if (price != "") options.rate = price; 686 if (nights != "") options.nights = nights; 687 $AvailPro.openBookingEngine(options); 688} 689 690function convertToFirstDate(year, month, day, nights, adults, children) { 691 var zPad = function (s) { 692 s = s + ''; 693 if (s.length == 1) { 694 s = '0' + s; 695 } 696 return s; 697 }; 698 if (typeof nights === 'undefined') nights = ''; 699 if (typeof adults === 'undefined') adults = ''; 700 if (typeof children === 'undefined') children = ''; 701 return year.toString().substr(2) + zPad(month.toString()) + zPad(day) + ';' + nights + ';' + adults + ';' + children; 702} 703 704// MAIN AVAILABILITY CHECK 705function hhotelDispopriceFHP(cname, lg, year, month, day, nights, currency, adults, additionalParams) { 706 var options = {maybeHotelID: cname}; 707 if (lg != "") options.language = lg.toUpperCase(); 708 if (year != "" && month != "" && day != "") options.firstDate = convertToFirstDate(year, month, day, nights, adults); 709 if (currency != "") options.currency = currency; 710 // if additionalParams is passed, then copy the properties to options 711 if (typeof additionalParams === 'object' && additionalParams !== null) { 712 for (var key in additionalParams) { 713 if (additionalParams.hasOwnProperty(key)) { 714 options[key] = additionalParams[key]; 715 } 716 } 717 } 718 $AvailPro.openBookingEngine(options); 719} 720 721function hhotelDispoprice(myForm) { 722 hhotelFormValidation(myForm, 0); 723} 724 725function hhotelFormValidation(myForm, mandatoryCode) { 726 myForm.action = '#'; 727 $AvailPro.handleFormSubmit(myForm); 728 return false; 729} 730 731/** 732 * 733 * FB FUNCTIONS KEPT FOR BACK COMPATIBILITY 734 * 735 */ 736 737if (typeof (FB_useGoogleAnalytics) == "undefined") 738 var FB_useGoogleAnalytics = false; 739if (typeof (FB_useAsyncGoogleAnalytics) == "undefined") 740 var FB_useAsyncGoogleAnalytics = false; 741if (typeof (FB_GoogleAnalyticsTrackerName) == "undefined") 742 var FB_GoogleAnalyticsTrackerName = ""; 743 744function transferGAdata(url) { 745 if (FB_useAsyncGoogleAnalytics) { 746 if (typeof _gaq !== 'undefined') { 747 _gaq.push(function () { 748 var pageTracker = _gat._getTrackerByName(); 749 new Image().src = pageTracker._getLinkerUrl(url);
750 _gaq.push(['_trackPageview', '/FastBooking/ClicBook']); 751 }); 752 } 753 } else { 754 pageTracker._initData(); 755 new Image().src = pageTracker._getLinkerUrl(url); 756 pageTracker._trackPageview('/FastBooking/ClicBook'); 757 } 758} 759 760function start() { 761 var nbm = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; 762 var thisform = document.idForm; 763 if (typeof (thisform) == 'undefined') { 764 return; 765 } 766 build_year_select(thisform); 767 var MD = new Date(); 768 var nday = MD.getDate(); 769 var amois = MD.getMonth(); 770 var ayear = takeYear(MD); 771 var cur_year = ayear; 772 nday += FB_nb_day_delay; 773 if (nday > nbm[amois]) { 774 nday -= nbm[amois]; 775 amois++; 776 if (amois > 11) { 777 ayear++; 778 amois = 0; 779 } 780 } 781 var indexDay = nday - 1; 782 var indexMois = amois; 783 var indexYear = ayear - cur_year; 784 if (indexDay < 0 || indexDay > 30) 785 indexDay = 0; 786 if (indexMois < 0 || indexMois > 11) 787 indexMois = 0; 788 if (indexYear < 0 || indexYear > 1) 789 indexDay = 0; 790 thisform.fromday.selectedIndex = indexDay; 791 thisform.frommonth.selectedIndex = indexMois; 792 thisform.fromyear.selectedIndex = indexYear; 793 update_departure(); 794} 795 796function build_year_select(thisform) { 797 var cur_date = new Date(); 798 var cur_year = takeYear(cur_date); 799 thisform.fromyear.options[0] = new Option(cur_year, cur_year, true, true); 800 if (thisform.toyear != null) { 801 var cur_yb = new Option(cur_year, cur_year, true, true); 802 thisform.toyear.options[0] = cur_yb; 803 } 804 var next_y = new Option(cur_year + 1, cur_year + 1, false, false); 805 thisform.fromyear.options[1] = next_y; 806 var next_yb = new Option(cur_year + 1, cur_year + 1, false, false); 807 if (thisform.toyear != null) { 808 thisform.toyear.options[1] = next_yb; 809 } 810} 811 812function check_departure() { 813 var thisform = document.idForm; 814 if (thisform.today == null) 815 return; 816 var nbm = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; 817 var ar_day = parseInt(thisform.fromday.value) + 1; 818 var ar_month = parseInt(thisform.frommonth.value); 819 var ar_year = parseInt(thisform.fromyear.value); 820 if (ar_day > nbm[ar_month - 1]) { 821 ar_day = 1; 822 ar_month += 1; 823 if (ar_month > 12) { 824 ar_month = 1; 825 ar_year += 1; 826 } 827 } 828 var cur_date = new Date(); 829 var cur_year = takeYear(cur_date); 830 thisform.today.selectedIndex = ar_day - 1; 831 thisform.tomonth.selectedIndex = ar_month - 1; 832 thisform.toyear.selectedIndex = ar_year - cur_year; 833} 834 835// update departure : check 836function update_departure() { 837 var thisform = document.idForm; 838 if (thisform.today == null) 839 return; 840 var ar_day = parseInt(thisform.fromday.value) + 1; 841 var ar_month = parseInt(thisform.frommonth.value); 842 var ar_year = parseInt(thisform.fromyear.value); 843 var de_day = parseInt(thisform.today.value) + 1; 844 var de_month = parseInt(thisform.tomonth.value); 845 var de_year = parseInt(thisform.toyear.value); 846 if (de_year < ar_year) { 847 check_departure(); 848 } else { 849 if (de_year == ar_year) { 850 if (de_month < ar_month) { 851 check_departure(); 852 } else { 853 if (de_month == ar_month) { 854 if (de_day <= ar_day) { 855 check_departure(); 856 } 857 } 858 } 859 } 860 } 861} 862 863function takeYear(theDate) { 864 var x = theDate.getYear(); 865 var y = x % 100; 866 y += (y < 38) ? 2000 : 1900; 867 return y; 868} 869 870// ages chidren for quick form 871function ageschildren() { 872 var age = ''; 873 var obj1 = ''; 874 var n = document.idForm.enfantresa.options[document.idForm.enfantresa.selectedIndex].value; 875 for (var i = 1; i <= n; i++) { 876 if (i == 1) { 877 obj1 = document.getElementById("agechild" + i); 878 age += obj1.options[obj1.selectedIndex].value; 879 } else { 880 obj1 = document.getElementById("agechild" + i); 881 age += ';'; 882 age += obj1.options[obj1.selectedIndex].value; 883 } 884 } 885 document.idForm.agesval.value = age; 886}
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.