1// checking to see if the receipt page or cross origin 2var isReceipt = window.location.href.includes('receipt'); 3var hasLoggedBundleInteract = 0; 4 5console.log({ setCookie }); 6 7var hasShownPreCheckoutOffer = false; 8 9var isCrossOrigin = 10 !window.location.href.includes('store') && 11 !window.location.href.includes('holiday_2021') && 12 !(typeof actLikeStore == 'undefined'); 13var askForPhone = true; 14// var phoneNumber = getCookie('phone_number'); 15 16function findExistingScriptTag(url) { 17 var resolvedUrl = ''; 18 19 try { 20 resolvedUrl = new URL(url, window.location.href).href; 21 } catch (scriptUrlError) { 22 resolvedUrl = ''; 23 } 24 25 return Array.from(document.querySelectorAll('script[src]')).find(function ( 26 scriptTag 27 ) { 28 var rawSrc = scriptTag.getAttribute('src') || ''; 29 var scriptSrc = scriptTag.src || rawSrc; 30 31 return ( 32 rawSrc === url || 33 scriptSrc === url || 34 (!!resolvedUrl && (rawSrc === resolvedUrl || scriptSrc === resolvedUrl)) || 35 scriptSrc.indexOf(url) !== -1 36 ); 37 }); 38} 39 40function loadScriptOnce(url, readyCheck, promiseKey) { 41 if (typeof readyCheck == 'function' && readyCheck()) { 42 return Promise.resolve(); 43 } 44 45 if (window[promiseKey]) { 46 return window[promiseKey]; 47 } 48 49 window[promiseKey] = new Promise(function (resolve, reject) { 50 var hasSettled = false; 51 var waitAttempts = 0; 52 var maxWaitAttempts = 120; 53 var scriptTag = null; 54 55 function finish(error) { 56 if (hasSettled) { 57 return; 58 } 59 60 hasSettled = true; 61 62 if (error) { 63 if (scriptTag && scriptTag.parentNode) { 64 scriptTag.parentNode.removeChild(scriptTag); 65 } 66 window[promiseKey] = null; 67 reject(error); 68 return; 69 } 70 71 resolve(); 72 } 73 74 function waitForReady() { 75 if (typeof readyCheck != 'function' || readyCheck()) { 76 finish(); 77 return; 78 } 79 80 waitAttempts++; 81 if (waitAttempts >= maxWaitAttempts) { 82 finish(new Error('Timed out waiting for script: ' + url)); 83 return; 84 } 85 86 window.setTimeout(waitForReady, 50); 87 } 88 89 function listenForScriptError() { 90 if (!scriptTag) { 91 return; 92 } 93 94 scriptTag.addEventListener( 95 'error', 96 function () { 97 finish(new Error('Failed to load script: ' + url)); 98 }, 99 { once: true } 100 ); 101 } 102 103 scriptTag = findExistingScriptTag(url); 104 if (scriptTag) { 105 listenForScriptError(); 106 waitForReady(); 107 return; 108 } 109 110 loadScript(url, function () { 111 waitForReady(); 112 }); 113 scriptTag = findExistingScriptTag(url); 114 listenForScriptError(); 115 }); 116 117 return window[promiseKey]; 118} 119 120function clearSchTicketOverhaulModalSessionState(cartItem) { 121 if (!cartItem || typeof cartItem != 'object') { 122 return cartItem; 123 } 124 125 delete cartItem.schTicketOverhaulModalSessionId; 126 return cartItem; 127} 128 129function loadStripeJsOnce() { 130 if (window.__storeStripeStaticLoadFailed === true) { 131 var failedStripeScript = findExistingScriptTag('https://js.stripe.com/v3/'); 132 if (failedStripeScript && failedStripeScript.parentNode) { 133 failedStripeScript.parentNode.removeChild(failedStripeScript); 134 } 135 window.__storeStripeScriptPromise = null; 136 window.__storeStripeStaticLoadFailed = false; 137 } 138 139 return loadScriptOnce( 140 'https://js.stripe.com/v3/', 141 function () { 142 return typeof Stripe != 'undefined'; 143 }, 144 '__storeStripeScriptPromise' 145 ); 146} 147 148function loadQuickPayScriptOnce() { 149 if ( 150 window.__quickPayScriptInitialized === true && 151 window.__quickPayStripeSetupReady !== true && 152 typeof Stripe != 'undefined' 153 ) { 154 var failedQuickPayScript = findExistingScriptTag( 155 window.STORE_QUICK_PAY_SCRIPT_URL || 156 '/assets/js/store/source/quickPay.js' 157 ); 158 if (failedQuickPayScript && failedQuickPayScript.parentNode) { 159 failedQuickPayScript.parentNode.removeChild(failedQuickPayScript); 160 } 161 window.__storeQuickPayScriptPromise = null; 162 window.__quickPayScriptInitialized = false; 163 } 164 165 return loadScriptOnce( 166 window.STORE_QUICK_PAY_SCRIPT_URL || 167 '/assets/js/store/source/quickPay.js', 168 function () { 169 return ( 170 window.__quickPayScriptInitialized === true && 171 window.__quickPayStripeSetupReady === true &&
172 typeof updateQuickPay == 'function' 173 ); 174 }, 175 '__storeQuickPayScriptPromise' 176 ); 177} 178 179function storeCartValueHasItems(cartValue) { 180 var parsedCart = cartValue; 181 182 if (typeof parsedCart == 'string') { 183 try { 184 parsedCart = JSON.parse(parsedCart); 185 } catch (cartParseError) { 186 try { 187 parsedCart = JSON.parse(decodeURIComponent(parsedCart)); 188 } catch (encodedCartParseError) { 189 return false; 190 } 191 } 192 } 193 194 return !!( 195 parsedCart && 196 typeof parsedCart == 'object' && 197 Array.isArray(parsedCart.items) && 198 parsedCart.items.length > 0 199 ); 200} 201 202function ensurePaymentSdksForPopulatedCart(cartValue, reason) { 203 if (!storeCartValueHasItems(cartValue)) { 204 return Promise.resolve(); 205 } 206 207 if ( 208 window.SCH_PAYMENT_SDK_INTENT_ENABLED || 209 window.PAYMENT_SDK_RETRY_ON_INTENT_ENABLED 210 ) { 211 return warmSchPaymentSdk(reason || 'cart-has-items'); 212 } 213 214 return loadStripeAndQuickPay(); 215} 216 217window.storeCartValueHasItems = storeCartValueHasItems; 218window.ensurePaymentSdksForPopulatedCart = ensurePaymentSdksForPopulatedCart; 219 220function warmSchPaymentSdk(reason) { 221 if ( 222 !window.SCH_PAYMENT_SDK_INTENT_ENABLED && 223 !window.PAYMENT_SDK_RETRY_ON_INTENT_ENABLED 224 ) { 225 return loadStripeAndQuickPay(); 226 } 227 228 if (!window.__schPaymentSdkIntent) { 229 window.__schPaymentSdkIntent = { 230 started: false, 231 ready: false, 232 reason: '', 233 }; 234 } 235 236 var intentState = window.__schPaymentSdkIntent; 237 if (intentState.started) { 238 return window.__schPaymentSdkPromise || Promise.resolve(); 239 } 240 241 intentState.started = true; 242 intentState.reason = reason || 'purchase-intent'; 243 244 window.__schPaymentSdkPromise = loadStripeAndQuickPay().then(function () { 245 intentState.ready = 246 typeof Stripe != 'undefined' && 247 window.__quickPayScriptInitialized === true && 248 window.__quickPayStripeSetupReady === true && 249 typeof updateQuickPay == 'function'; 250 251 if (!intentState.ready) { 252 intentState.started = false; 253 window.__schPaymentSdkPromise = null; 254 } 255 }); 256 257 return window.__schPaymentSdkPromise; 258} 259 260function initializeSchPaymentSdkIntent() { 261 if ( 262 !window.SCH_PAYMENT_SDK_INTENT_ENABLED && 263 !window.PAYMENT_SDK_RETRY_ON_INTENT_ENABLED 264 ) { 265 return; 266 } 267 268 var ticketSection = document.querySelector('#ticketsSection'); 269 var ticketIntentSelector = [ 270 '#ticketsSection', 271 '.navigateToBundle', 272 '[href*="ticketsSection"]', 273 '[onclick*="ticketsSection"]', 274 '[onclick*="navigateToBundle"]', 275 '[onclick*="schDesktopTicketCard2026HandleCta"]', 276 ].join(','); 277 var ticketSectionObserver = null; 278 function cleanupIntentListeners() { 279 document.removeEventListener('pointerover', handleTicketIntent, true); 280 document.removeEventListener('pointerdown', handleTicketIntent, true); 281 document.removeEventListener('focusin', handleTicketIntent, true); 282 document.removeEventListener('touchstart', handleTicketIntent, true); 283 if (ticketSectionObserver) { 284 ticketSectionObserver.disconnect(); 285 } 286 } 287 288 function startPaymentSdk(reason) { 289 warmSchPaymentSdk(reason).then(function () { 290 if (window.__schPaymentSdkIntent.ready) { 291 cleanupIntentListeners(); 292 } 293 }); 294 } 295 296 function handleTicketIntent(event) { 297 var target = event.target; 298 if ( 299 target && 300 typeof target.closest == 'function' && 301 target.closest(ticketIntentSelector) 302 ) { 303 startPaymentSdk(event.type); 304 } 305 } 306 307 document.addEventListener('pointerover', handleTicketIntent, { 308 capture: true, 309 passive: true, 310 }); 311 document.addEventListener('pointerdown', handleTicketIntent, { 312 capture: true, 313 passive: true, 314 }); 315 document.addEventListener('focusin', handleTicketIntent, true); 316 document.addEventListener('touchstart', handleTicketIntent, { 317 capture: true, 318 passive: true, 319 }); 320 if (ticketSection && typeof IntersectionObserver != 'undefined') { 321 ticketSectionObserver = new IntersectionObserver( 322 function (entries) { 323 if (entries.some(function (entry) { 324 return entry.isIntersecting; 325 })) { 326 startPaymentSdk('ticket-section-nearby'); 327 } 328 }, 329 { 330 rootMargin: '100px 0px', 331 } 332 ); 333 ticketSectionObserver.observe(ticketSection); 334 } 335 336 if ( 337 typeof cart != 'undefined' && 338 Array.isArray(cart.items) && 339 cart.items.length > 0 340 ) { 341 startPaymentSdk('existing-cart'); 342 } 343} 344 345function clearCart() { 346 deleteCookie('cart'); 347 deleteCookie('sch_cart'); 348 cart = { 349 currency: cy, 350 cy: cy, 351 items: [], 352 total: 0, 353 editIndex: null, 354 hasSubscription: 0, 355 hasTrial: 0, 356 hasIndividualTickets: 0, 357 hasAnnualPass: 0, 358 annualPassCount: 0, 359 singleUseCount: 0, 360 itemCount: 0, 361 }; 362} 363 364if (window.location.href.includes('clear_cart')) { 365 clearCart(); 366} 367 368//setting the default value for the current items in the page 369// if not already set on page 370if (typeof current_product == 'undefined') { 371 current_product = { 372 bundleId: 1, 373 productId: 1, 374 roleId: 1, 375 quantity: 4, 376 addons: {}, 377 }; 378} 379 380// creating function to update current product without memory leak 381function updateCurrentProduct(diff = {}) { 382 trace(); 383 var old_product = Object.assign({}, current_product); 384 current_product = Object.assign(current_product, diff); 385 console.log( 386 'updating current product', 387 { old_product }, 388 { diff }, 389 { current_product } 390 ); 391} 392 393// creating function to update current addon without memory leak 394function changeCurrentProductAddon(addonId, add = true) { 395 trace(); 396 var old_product = Object.assign({}, current_product); 397 current_product = Object.assign({}, current_product); 398 if (add) { 399 current_product.addons[addonId] = true; 400 } else { 401 delete current_product.addons[addonId]; 402 } 403 console.log( 404 'updating current addons', 405 { old_product }, 406 { addonId, add }, 407 { current_product } 408 ); 409 410 BundleModalRender(); 411} 412 413// creating function to update current addon without memory leak 414function setCurrentProductAddonState(addonId, state) { 415 trace(); 416 var old_product = Object.assign({}, current_product); 417 current_product = Object.assign({}, current_product); 418 if (!current_product.addons[addonId]) { 419 current_product.addons[addonId] = true; 420 } else { 421 delete current_product.addons[addonId]; 422 } 423 console.log( 424 'updating current addons', 425 { old_product }, 426 { addonId }, 427 { current_product } 428 ); 429 430 BundleModalRender(); 431} 432 433// creating function to update current addon without memory leak 434function toggleCurrentProductAddon(addonId) { 435 trace(); 436 var addon = allAddons[addonId] || {}; 437 console.log('new addon', { addon }); 438 var old_product = Object.assign({}, current_product); 439 current_product = Object.assign({}, current_product); 440 var alreadySelected = current_product.addons[addonId]; 441 if (addon.only_one_addon_allowed * 1) { 442 console.log('only one addone allowed!'); 443 current_product.addons = {}; 444 } 445 if (!alreadySelected) { 446 current_product.addons[addonId] = true; 447 } else { 448 delete current_product.addons[addonId]; 449 } 450 console.log( 451 'updating current addons', 452 { old_product }, 453 { addonId }, 454 { current_product } 455 ); 456 457 BundleModalRender(); 458} 459 460function toggleAddToCart(bundleId, add) { 461 console.log('toggleAddToCart', { bundleId }); 462 if (add) { 463 // Add item to cart 464 var bundle = getBundleInfo(bundleId); 465 const productInfo = getProductInfo(bundle.initial_product_id); 466 467 const product = { 468 bundleId: parseInt(bundle.id), 469 productId: parseInt(bundle.initial_product_id), 470 roleId: parseInt(bundle.initial_rid), 471 quantity: 1, 472 addons: bundle.initial_addons ? JSON.parse(bundle.initial_addons) : {}, 473 location: bundle.location || null, 474 locationType: bundle.locationType || null, 475 isInlineBundle: bundle.isInlineBundle || false, 476 planId: productInfo.plan_id || null, 477 v: '3.0.0', 478 }; 479 480 addToCart(false, product); 481 } else { 482 // Remove item from cart 483 const index = cart.items.findIndex((item) => item.bundleId == bundleId); 484 if (index > -1) { 485 cart.items.splice(index, 1); 486 console.log(`Removed item with bundleId ${bundleId} from cart.`); 487 } else { 488 console.log(`Item with bundleId ${bundleId} not found in cart.`); 489 } 490 } 491 492 BundleModalRender(); 493} 494 495function syncMembershipCheckboxes(checkbox) { 496 const checkboxes = document.querySelectorAll('.store-membership-checkbox');
497 checkboxes.forEach(function (cb) { 498 cb.checked = checkbox.checked; 499 }); 500} 501 502function toggleMembership(bundleId) { 503 var bundle = getBundleInfo(bundleId); 504 const bundleProductInfo = getProductInfo(bundle.initial_product_id); 505 const planIdElement = document.getElementById('plan_id'); 506 const processingFeeElement = document.querySelector('.processingFee'); 507 508 if (planIdElement) { 509 if (bundleProductInfo && bundleProductInfo.plan_id) { 510 planIdElement.value = bundleProductInfo.plan_id; 511 } else { 512 planIdElement.value = null; 513 } 514 } 515 516 // if chose membership over tickets, set fee to 0 517 if (WEBSITE_DOMAIN == 'sch' && processingFeeElement) { 518 // membership 519 if (bundle.id == 211) { 520 processingFeeElement.dataset.value = 0; 521 // tickets 522 } else if (bundle.id == 218) { 523 const feeString = processingFeeElement.innerText; 524 const formattedFee = parseFloat(feeString.replace('$', '')); 525 processingFeeElement.dataset.value = formattedFee; 526 } 527 } 528 529 // if it's tickets lets grab the inital quantity the customer selected 530 let toggleProductQuantity = 531 bundle.id == 218 532 ? (getCookie('initial_product_quantity') ?? bundle.initial_quantity) 533 : bundle.initial_quantity; 534 535 const productInfo = getProductInfo(bundle.initial_product_id, { suppressMissingLog: true }) || {}; 536 537 current_product = { 538 bundleId: parseInt(bundle.id), 539 productId: parseInt(bundle.initial_product_id), 540 roleId: parseInt(bundle.initial_rid), 541 quantity: toggleProductQuantity, 542 addons: bundle.initial_addons ? JSON.parse(bundle.initial_addons) : {}, 543 location: bundle.location || null, 544 locationType: bundle.locationType || null, 545 isInlineBundle: bundle.isInlineBundle || false, 546 planId: productInfo.plan_id || null, 547 v: '3.0.0', 548 }; 549 550 addToCart(true); 551} 552 553// creating function to update current addon without memory leak 554function toggleCurrentProductRoleUpgrade(roleId) { 555 trace(); 556 var old_product = Object.assign({}, current_product); 557 current_product = Object.assign({}, current_product); 558 if (current_product.roleId != roleId) { 559 current_product.roleId = roleId; 560 } else { 561 current_product.roleId = 1; 562 } 563 console.log( 564 'updating current addons', 565 { old_product }, 566 { roleId }, 567 { current_product } 568 ); 569 570 BundleModalRender(); 571} 572 573// First type of bundle navigation 574// From a With a matching slug 575// This function is generated from the php bridge 576var slug_bundle = getBundleFromSlug(); 577 578// onclick for the bundles 579document.querySelectorAll('.navigateToBundle').forEach(function (item) { 580 item.onclick = function (e) { 581 e.preventDefault(); 582 var bundleId = item.dataset.id; 583 var bundle = getBundleInfo(bundleId); 584 navigateToBundle(bundle); 585 }; 586}); 587 588//displaying the bundle page 589function navigateToBundle( 590 bundle, 591 editItem, 592 upgradeSale, 593 straigtToCheckout = false, 594 quantityOverride = 0, 595 skipBundleModal = false, 596 isOneClickCheckout = false 597) { 598 trace(); 599 600 if ( 601 window.SCH_PAYMENT_SDK_INTENT_ENABLED || 602 window.PAYMENT_SDK_RETRY_ON_INTENT_ENABLED 603 ) { 604 warmSchPaymentSdk('navigate-to-bundle'); 605 } else { 606 loadStripeAndQuickPay(); 607 } 608 609 console.log('navigateToBundle', { 610 bundle, 611 editItem, 612 upgradeSale, 613 straigtToCheckout, 614 }); 615 616 if ( 617 typeof fb_track_safe !== 'undefined' && 618 !window.location.href.includes('receipt') && 619 !document.querySelector('#isInlineBundle') 620 ) { 621 // tracking page view 622 fb_track_safe('track', 'BundleView'); 623 } 624 console.log('navigateToBundle', { bundle }); 625 626 if (quantityOverride) { 627 bundle.initial_quantity = quantityOverride; 628 } 629 630 if ( 631 bundle && 632 bundle.force_open_lead_form && 633 typeof openGenericCreateLeadModal == 'function' 634 ) { 635 return openGenericCreateLeadModal(bundle.force_open_lead_form); 636 } 637 638 const productInfo = getProductInfo(bundle.initial_product_id, { suppressMissingLog: true }) || {}; 639 640 if (editItem) { 641 var newEditItem = Object.assign({}, editItem); 642 643 clearSchTicketOverhaulModalSessionState(newEditItem); 644 newEditItem['isInlineBundle'] = false; 645 newEditItem['showBundle'] = true; 646 updateCurrentProduct(newEditItem); 647 cart.showCart = false;
648 // AB Test: Use modern cart view if redesign test is active 649 if (getCookie('AB_LR_SCH_FULL_STORE_REDESIGN') === '1') { 650 CartViewRender(); // Modern version from CartViewModern.js 651 } else { 652 CartViewRender(); // Original version from CartView.js 653 } 654 } else { 655 current_product = { 656 bundleId: parseInt(bundle.id), 657 productId: parseInt(bundle.initial_product_id), 658 roleId: parseInt(bundle.initial_rid), 659 quantity: bundle.initial_quantity, 660 adultQuantity: bundle.initial_quantity, 661 childQuantity: 0, 662 addons: bundle.initial_addons ? JSON.parse(bundle.initial_addons) : {}, 663 location: bundle.location || null, 664 locationType: bundle.locationType || null, 665 isInlineBundle: bundle.isInlineBundle || false, 666 planId: productInfo.plan_id || null, 667 v: '3.0.0', 668 }; 669 } 670 // tracking bundle page view 671 // only if not on receipt 672 if ( 673 typeof fb_track_safe != 'undefined' && 674 !window.location.href.includes('receipt') 675 ) { 676 fb_track_safe('track', 'CustomizeProduct'); 677 } 678 679 current_product.showBundle = true; 680 current_product.upgradeSale = upgradeSale; 681 682 // FIX: For duplicate upgrades (Bundle & Save), quantity should be 1 (voucher count) 683 // not the player count (e.g., 6). The player count is stored in originalPlayerCount. 684 if ( 685 upgradeSale && 686 upgradeSale.upgrade_type === 'b2c_web_sale_duplicate_upgrade' 687 ) { 688 current_product.quantity = 1; 689 current_product.adultQuantity = 1; 690 } 691 692 if (skipBundleModal) { 693 if (isOneClickCheckout) { 694 addToCart(false, current_product, true, true); 695 } else { 696 addToCart(false); 697 } 698 } else { 699 if (!straigtToCheckout) { 700 if (WEBSITE_DOMAIN == 'letsroam' && !editItem) { 701 if ( 702 current_product.bundleId === 142 || 703 current_product.bundleId === 143 704 ) { 705 addToCart(false); 706 } else { 707 BundleModalRender(); 708 if (!window.location.href.includes('receipt')) { 709 gtag_and_microsoft_uet('event', 'view_item', { 710 currency: cy?.toUpperCase(), 711 value: 0, 712 items: [{ item_id: `${bundle.id}` }], 713 }); 714 } 715 } 716 } else { 717 BundleModalRender(); 718 if (!window.location.href.includes('receipt')) { 719 gtag_and_microsoft_uet('event', 'view_item', { 720 currency: cy?.toUpperCase(), 721 value: 0, 722 items: [{ item_id: `${bundle.id}` }], 723 }); 724 } 725 } 726 } else { 727 addToCart(true); 728 } 729 } 730} 731 732function shouldMergeCartRowsForVariantCart() { 733 if (typeof WEBSITE_DOMAIN == 'undefined') { 734 return false; 735 } 736 737 if (getCookie('AB_LR_SCH_FULL_STORE_REDESIGN') === '1') { 738 return true; 739 } 740 741 if (WEBSITE_DOMAIN == 'sch') { 742 if (typeof window.matchMedia == 'function') { 743 return window.matchMedia('(max-width: 700px)').matches; 744 } 745 746 return window.innerWidth <= 700; 747 } 748 749 return false; 750} 751 752function stableCartValue(value) { 753 if (Array.isArray(value)) { 754 return value.map(stableCartValue); 755 } 756 757 if (value && typeof value == 'object') { 758 return Object.keys(value).sort().reduce(function (stableValue, key) { 759 stableValue[key] = stableCartValue(value[key]); 760 return stableValue; 761 }, {}); 762 } 763 764 return value === undefined ? null : value; 765} 766 767function getCartValueSignature(value) { 768 if (typeof value == 'string') { 769 try { 770 value = JSON.parse(value); 771 } catch (cartValueSignatureError) { 772 return value; 773 } 774 } 775 776 return JSON.stringify(stableCartValue(value)); 777} 778 779function getVariantCartItemMergeKey(cartItem) { 780 return [ 781 cartItem.bundleId || 1, 782 cartItem.productId || 1, 783 cartItem.roleId || 1, 784 cartItem.locationType || '', 785 cartItem.location || '', 786 cartItem.planId || '', 787 cartItem.bundle_price_override || '', 788 cartItem.product_price_override || '', 789 cartItem.forcePrice || '', 790 cartItem.season_pass_length_override || '', 791 cartItem.season_pass_players_override || '', 792 getCartValueSignature(cartItem.addons || {}), 793 ].join('|'); 794} 795 796function getCartNumber(value, fallback) { 797 var numberValue = Number(value); 798 799 return Number.isFinite(numberValue) ? numberValue : fallback; 800} 801 802function canMergeCartItemQuantityForPricing(cartItem) { 803 var bundle = getBundleInfo(cartItem.bundleId || 1) || {}; 804 var product = getProductInfo(cartItem.productId || 1, { suppressMissingLog: true }) || {}; 805 806 if (cartItem.applyVolumeDiscount) { 807 return true; 808 } 809 810 if (cartItem.forcePrice) { 811 return false;
812 } 813 814 if ( 815 product.subscription_length || 816 bundle.bundle_price_id || 817 bundle.bundle_price_override || 818 bundle.bundle_price 819 ) { 820 return false; 821 } 822 823 return true; 824} 825 826function isIndividualTicketCartItem(cartItem) { 827 var bundle = getBundleInfo(cartItem.bundleId || 1) || {}; 828 var product = getProductInfo(cartItem.productId || 1, { suppressMissingLog: true }) || {}; 829 var productUnit = String(product.unit || '').toLowerCase(); 830 var productSku = String(product.sku || '').toUpperCase(); 831 832 return ( 833 !Number(bundle.season_pass_tickets || 0) && 834 !cartItem.planId && 835 !product.plan_id && 836 !product.subscription_length && 837 !(product.physical_product && product.physical_product != '0') && 838 ( 839 productUnit === 'ticket' || 840 productUnit === 'tickets' || 841 productSku === 'SCH001' || 842 productSku === 'SCHIC-SINGLE' 843 ) 844 ); 845} 846 847function addCartItemForVariantCart(newCartItem) { 848 clearSchTicketOverhaulModalSessionState(newCartItem); 849 850 if ( 851 !shouldMergeCartRowsForVariantCart() || 852 !canMergeCartItemQuantityForPricing(newCartItem) 853 ) { 854 return false; 855 } 856 857 var newCartItemKey = getVariantCartItemMergeKey(newCartItem); 858 var existingCartItem = (cart.items || []).find(function (cartItem) { 859 return getVariantCartItemMergeKey(cartItem) == newCartItemKey; 860 }); 861 862 if (!existingCartItem) { 863 cart.items.push(newCartItem); 864 return true; 865 } 866 867 var addedQuantity = Math.max(1, Number(newCartItem.quantity || 1)); 868 var existingQuantity = Math.max(1, Number(existingCartItem.quantity || 1)); 869 var nextQuantity = existingQuantity + addedQuantity; 870 var existingChildQuantity = Math.max(0, getCartNumber(existingCartItem.childQuantity, 0)); 871 var addedChildQuantity = Math.max(0, getCartNumber(newCartItem.childQuantity, 0)); 872 var existingAdultQuantity = Math.max( 873 0, 874 getCartNumber(existingCartItem.adultQuantity, existingQuantity - existingChildQuantity) 875 ); 876 var addedAdultQuantity = Math.max( 877 0, 878 getCartNumber(newCartItem.adultQuantity, addedQuantity - addedChildQuantity) 879 ); 880 881 existingCartItem.quantity = nextQuantity; 882 existingCartItem.adultQuantity = existingAdultQuantity + addedAdultQuantity; 883 existingCartItem.childQuantity = existingChildQuantity + addedChildQuantity; 884 existingCartItem.specialDiscount = 0; 885 existingCartItem.specialDiscountText = 0; 886 existingCartItem.total = 0; 887 existingCartItem.regularTotal = 0; 888 existingCartItem.fullTotal = 0; 889 890 return true; 891} 892 893function getCartAddonsObject(addons) { 894 if (!addons) { 895 return {}; 896 } 897 898 if (typeof addons == 'string') { 899 try { 900 return JSON.parse(addons); 901 } catch (addonParseError) { 902 return {}; 903 } 904 } 905 906 return Object.assign({}, addons); 907} 908 909function getSeasonPassCartItemTraits(cartItem) { 910 var bundle = getBundleInfo(cartItem.bundleId || 1) || {}; 911 912 return [ 913 cartItem.productId || bundle.initial_product_id || 1, 914 cartItem.roleId || bundle.initial_rid || 1, 915 cartItem.locationType || bundle.locationType || '', 916 cartItem.location || bundle.location || '', 917 cartItem.season_pass_length_override || bundle.season_pass_length || '', 918 cartItem.season_pass_players_override || bundle.season_pass_tickets || '', 919 ].join('|'); 920} 921 922function cloneAdditionalCartItemFromSourceProduct(product) { 923 var additionalCartItem = Object.assign({}, product); 924 925 clearSchTicketOverhaulModalSessionState(additionalCartItem); 926 additionalCartItem.quantity = 1; 927 additionalCartItem.adultQuantity = 1; 928 additionalCartItem.childQuantity = 0; 929 additionalCartItem.addons = {}; 930 additionalCartItem.specialDiscount = 0; 931 additionalCartItem.specialDiscountText = 0; 932 additionalCartItem.total = 0; 933 additionalCartItem.regularTotal = 0; 934 additionalCartItem.fullTotal = 0; 935 936 return additionalCartItem; 937} 938 939function findExistingCartItemBySeasonPassTraits(seasonPassTraits) { 940 if (!cart || !Array.isArray(cart.items)) { 941 return null; 942 } 943 944 return cart.items.find(function (cartItem) { 945 var bundle = getBundleInfo(cartItem.bundleId || 1) || {}; 946 947 return ( 948 bundle.season_pass_tickets && 949 getSeasonPassCartItemTraits(cartItem) == seasonPassTraits 950 ); 951 }) || null; 952} 953 954function buildCartItemFromBundleId(bundleId) { 955 var bundle = getBundleInfo(bundleId) || {}; 956 var productInfo = getProductInfo(bundle.initial_product_id, { suppressMissingLog: true }) || {}; 957 var quantity = Number(bundle.initial_quantity || 1) || 1; 958 959 return { 960 bundleId: Number(bundleId), 961 productId: Number(bundle.initial_product_id), 962 roleId: Number(bundle.initial_rid), 963 quantity: quantity, 964 adultQuantity: quantity, 965 childQuantity: 0, 966 addons: getCartAddonsObject(bundle.initial_addons), 967 location: bundle.location || null, 968 locationType: bundle.locationType || null, 969 isInlineBundle: bundle.isInlineBundle || false, 970 planId: productInfo.plan_id || null, 971 v: '3.0.0', 972 }; 973} 974 975function findPreferredVariantSeasonPassCartItemByTraits(seasonPassTraits) { 976 if ( 977 typeof shouldMergeCartRowsForVariantCart != 'function' || 978 !shouldMergeCartRowsForVariantCart() || 979 typeof document == 'undefined' 980 ) { 981 return null; 982 } 983 984 var newTicketFlowCards = document.querySelectorAll('.sch-new-ticket-card[data-bundle-id]'); 985 for (var cardIndex = 0; cardIndex < newTicketFlowCards.length; cardIndex++) { 986 var bundleId = Number(newTicketFlowCards[cardIndex].dataset.bundleId || 0); 987 if (!bundleId) { 988 continue; 989 } 990 991 var bundle = getBundleInfo(bundleId) || {}; 992 if (!bundle.season_pass_tickets) { 993 continue; 994 } 995 996 var preferredCartItem = buildCartItemFromBundleId(bundleId); 997 if (getSeasonPassCartItemTraits(preferredCartItem) == seasonPassTraits) { 998 return preferredCartItem; 999 } 1000 } 1001 1002 return null; 1003} 1004 1005function normalizeVariantSeasonPassCartItem(cartItem) { 1006 if ( 1007 typeof shouldMergeCartRowsForVariantCart != 'function' || 1008 !shouldMergeCartRowsForVariantCart() || 1009 !cartItem 1010 ) { 1011 return false;
1012 } 1013 1014 var bundle = getBundleInfo(cartItem.bundleId || 1) || {}; 1015 if (!bundle.season_pass_tickets) { 1016 return false; 1017 } 1018 1019 var preferredCartItem = findPreferredVariantSeasonPassCartItemByTraits( 1020 getSeasonPassCartItemTraits(cartItem) 1021 ); 1022 if (!preferredCartItem || Number(preferredCartItem.bundleId || 0) == Number(cartItem.bundleId || 0)) { 1023 return false; 1024 } 1025 if ( 1026 getCartValueSignature(cartItem.addons || {}) != 1027 getCartValueSignature(preferredCartItem.addons || {}) 1028 ) { 1029 return false; 1030 } 1031 1032 cartItem.bundleId = preferredCartItem.bundleId; 1033 cartItem.productId = preferredCartItem.productId; 1034 cartItem.roleId = preferredCartItem.roleId; 1035 cartItem.location = preferredCartItem.location; 1036 cartItem.locationType = preferredCartItem.locationType; 1037 cartItem.isInlineBundle = preferredCartItem.isInlineBundle; 1038 cartItem.planId = preferredCartItem.planId; 1039 cartItem.addons = Object.assign({}, preferredCartItem.addons || {}); 1040 delete cartItem.bundle_price_override; 1041 delete cartItem.season_pass_length_override; 1042 delete cartItem.season_pass_players_override; 1043 delete cartItem.skipVolumeDiscount; 1044 delete cartItem.fromTieredPricing; 1045 delete cartItem.applyVolumeDiscount; 1046 cartItem.specialDiscount = 0; 1047 cartItem.specialDiscountText = 0; 1048 cartItem.total = 0; 1049 cartItem.regularTotal = 0; 1050 cartItem.fullTotal = 0; 1051 1052 return true; 1053} 1054 1055function normalizeVariantSeasonPassCartItems() { 1056 if (!cart || !Array.isArray(cart.items)) { 1057 return false; 1058 } 1059 1060 return cart.items.reduce(function (didNormalize, cartItem) { 1061 return normalizeVariantSeasonPassCartItem(cartItem) || didNormalize; 1062 }, false); 1063} 1064 1065function buildCartItemFromAdditionalBundleAddon(addonId, sourceProduct) { 1066 var addon = getAddonInfo(addonId) || {}; 1067 1068 if (!addon.additional_bundle) { 1069 return null; 1070 } 1071 1072 var additionalBundleCartItem = buildCartItemFromBundleId(addon.additional_bundle); 1073 var additionalBundleTraits = getSeasonPassCartItemTraits(additionalBundleCartItem); 1074 1075 if ( 1076 sourceProduct && 1077 additionalBundleTraits == getSeasonPassCartItemTraits(sourceProduct) 1078 ) { 1079 return cloneAdditionalCartItemFromSourceProduct(sourceProduct); 1080 } 1081 1082 var preferredVariantCartItem = findPreferredVariantSeasonPassCartItemByTraits(additionalBundleTraits); 1083 if (preferredVariantCartItem) { 1084 return preferredVariantCartItem; 1085 } 1086 1087 var existingMatchingCartItem = findExistingCartItemBySeasonPassTraits( 1088 additionalBundleTraits 1089 ); 1090 if (existingMatchingCartItem) { 1091 return cloneAdditionalCartItemFromSourceProduct(existingMatchingCartItem); 1092 } 1093 1094 return additionalBundleCartItem; 1095} 1096 1097function extractAdditionalBundleAddonCartItemsForVariantCart(product) { 1098 if (!shouldMergeCartRowsForVariantCart() || !product.addons) { 1099 return []; 1100 } 1101 1102 product.addons = getCartAddonsObject(product.addons); 1103 1104 return Object.keys(product.addons).reduce(function (additionalCartItems, addonId) { 1105 var additionalCartItem = buildCartItemFromAdditionalBundleAddon(addonId, product); 1106 1107 if (additionalCartItem) { 1108 delete product.addons[addonId]; 1109 additionalCartItems.push(additionalCartItem); 1110 } 1111 1112 return additionalCartItems; 1113 }, []); 1114} 1115 1116function addToCart( 1117 straightToCheckout = false, 1118 product = current_product, 1119 skipShowCart = false, 1120 skipCartViewRender = false 1121) { 1122 fb_track_safe('track', 'AddToCart', { content_id: 'store' }); 1123 1124 hiddenDebug('atc1'); 1125 1126 const bundleId = product.bundleIdOverride || product.bundleId; 1127 1128 // if hunt tickets set the initial quantity as a cookie so we can toggle back to it 1129 if (bundleId == 218) { 1130 setCookie('initial_product_quantity', product.quantity); 1131 } 1132 1133 // https://developers.google.com/analytics/devguides/collection/ga4/reference/events?client_type=gtag#add_to_cart 1134 1135 trace(); 1136 console.log('adding item to cart', { product }); 1137 1138 if (product.bundleIdOverride) { 1139 const overide = getBundleInfo(product.bundleIdOverride); 1140 const overrideProductInfo = getProductInfo(overide.initial_product_id, { suppressMissingLog: true }) || {}; 1141 product.bundleId = product.bundleIdOverride; 1142 product.productId = overide.initial_product_id; 1143 product.roleId = parseInt(overide.initial_rid); 1144 product.quantity = overide.initial_quantity; 1145 product.adultQuantity = overide.initial_quantity; 1146 product.childQuantity = 0; 1147 product.addons = overide.initial_addons ? JSON.parse(overide.initial_addons) : {}; 1148 product.location = overide.location || null; 1149 product.locationType = overide.locationType || null; 1150 product.isInlineBundle = overide.isInlineBundle || false; 1151 product.planId = overrideProductInfo.plan_id || null; 1152 } 1153 1154 // checking if cart has a subscription in it 1155 const cartAlreadyHasSubscription = cart.items.some((item) => !!item.planId); 1156 1157 // clearing cart if other things in there 1158 const productInfo = getProductInfo(product.productId); 1159 const bundleInfo = getBundleInfo(bundleId); 1160 1161 console.log({ cartAlreadyHasSubscription, productInfo }); 1162 1163 if (productInfo.plan_id || cartAlreadyHasSubscription) { 1164 cart.items = []; 1165 } 1166 1167 hiddenDebug('atc2'); 1168 1169 // editing and returning if the edit index was set, aka editing 1170 if (cart.editIndex === 0 || cart.editIndex) { 1171 var newCartItem = Object.assign({}, product); 1172 1173 clearSchTicketOverhaulModalSessionState(newCartItem); 1174 cart.items[cart.editIndex] = newCartItem; 1175 cart.editIndex = null; 1176 } else { 1177 var additionalBundleCartItems = extractAdditionalBundleAddonCartItemsForVariantCart(product); 1178 if ( 1179 bundleInfo.season_pass_tickets && 1180 WEBSITE_DOMAIN == 'letsroam' && 1181 !shouldMergeCartRowsForVariantCart() 1182 ) { 1183 for (let i = 0; i < product.quantity; i++) { 1184 if (i > 0) { 1185 product.addons = {}; 1186 } 1187 var newCartItem = Object.assign({}, product); 1188 clearSchTicketOverhaulModalSessionState(newCartItem); 1189 cart.items.push(newCartItem); 1190 } 1191 } else { 1192 var newCartItem = Object.assign({}, product); 1193 clearSchTicketOverhaulModalSessionState(newCartItem); 1194 // Each completed ticket selection is a distinct bundle the customer can 1195 // edit, copy, or remove independently. Variant grouping remains limited 1196 // to additional bundle add-ons created below. 1197 if (isIndividualTicketCartItem(newCartItem)) { 1198 cart.items.push(newCartItem); 1199 }
1199 else if (!addCartItemForVariantCart(newCartItem)) { 1200 cart.items.push(newCartItem); 1201 } 1202 } 1203 1204 additionalBundleCartItems.forEach(function (additionalBundleCartItem) { 1205 clearSchTicketOverhaulModalSessionState(additionalBundleCartItem); 1206 if (!addCartItemForVariantCart(additionalBundleCartItem)) { 1207 cart.items.push(additionalBundleCartItem); 1208 } 1209 }); 1210 } 1211 1212 if (!product.isInlineBundle) { 1213 product.showBundle = false; 1214 } else { 1215 navigateToBundle(Object.assign({}, initialBundle)); 1216 } 1217 1218 if (!skipShowCart) { 1219 cart.showCart = true; 1220 } 1221 1222 // adding useful cart stats 1223 updateCartStats(); 1224 1225 cart.total = priceCart('discounted'); 1226 cart.regularTotal = priceCart('regular'); 1227 cart.fullTotal = priceCart('full'); 1228 cart.realDiscount = realDiscount; 1229 1230 gtag_and_microsoft_uet('event', 'add_to_cart', { 1231 currency: cy?.toUpperCase(), 1232 value: cart.total, 1233 items: [{ item_id: `${bundleId}` }], 1234 }); 1235 1236 setCookie('sch_cart', cart); 1237 setCookie('cart', cart); 1238 1239 // rerendering bundle modal pop up 1240 // to hide it 1241 BundleModalRender(); 1242 1243 hiddenDebug('atc3'); 1244 1245 const isSubscription = !!productInfo.plan_id; 1246 1247 if (straightToCheckout || isSubscription) { 1248 goToCheckout(); 1249 } else if (window.embeddedCheckoutModalCartEditorActive) { 1250 renderEmbeddedCheckoutModalCartEditor(); 1251 } else if (!skipCartViewRender) { 1252 // AB Test: Use modern cart view if redesign test is active 1253 if (getCookie('AB_LR_SCH_FULL_STORE_REDESIGN') === '1') { 1254 CartViewRender(); // Modern version from CartViewModern.js 1255 } else { 1256 CartViewRender(); // Original version from CartView.js 1257 } 1258 } 1259} 1260 1261function showCheckout() { 1262 if (typeof CheckoutCartRender != 'undefined') { 1263 CheckoutCartRender(); 1264 } else { 1265 loadScript('assets/js/store/source/CheckoutCart.js', function () { 1266 CheckoutCartRender(); 1267 }); 1268 } 1269 1270 // submit order button 1271 var btnCompleteOrderCheckout = document.querySelector( 1272 '#btnCompleteOrderCheckout' 1273 ); 1274 btnCompleteOrderCheckout.addEventListener('click', function () { 1275 btnCompleteOrderCheckout.onclick = handleSubmitPress; 1276 }); 1277} 1278 1279function isEmbeddedCheckoutModalEnabled() { 1280 if ( 1281 typeof WEBSITE_DOMAIN == 'undefined' || 1282 !['sch', 'letsroam'].includes(WEBSITE_DOMAIN) 1283 ) { 1284 return false; 1285 } 1286 1287 if (typeof abVersionEquals == 'function') { 1288 return abVersionEquals('SCH_LR_CHECKOUT_POPUP', 1); 1289 } 1290 1291 return false; 1292} 1293 1294function getCheckoutCtaText() { 1295 if ( 1296 getCookie('AB_RECEIPT_PAGE_REDESIGN') == '1' && 1297 window.location.href.includes('receipt') 1298 ) { 1299 return 'Purchase'; 1300 } 1301 1302 if ( 1303 typeof window.checkoutCtaTextOverride == 'string' && 1304 window.checkoutCtaTextOverride.trim() 1305 ) { 1306 return window.checkoutCtaTextOverride.trim(); 1307 } 1308 1309 return isEmbeddedCheckoutModalEnabled() ? 'Checkout' : 'Proceed To Checkout'; 1310} 1311 1312function buildCheckoutUrl(options = {}) { 1313 var { 1314 embeddedCartModal = false, 1315 includeCartInQuery = true, 1316 cacheKey = '', 1317 } = options; 1318 1319 var baseURL = '/store/checkout/'; 1320 var pageCookieLanguage = 1321 typeof pageLanguage != 'undefined' ? pageLanguage : getCookie('language'); 1322 1323 if (pageCookieLanguage && pageCookieLanguage != 'en') { 1324 baseURL = `/${pageCookieLanguage}${baseURL}`; 1325 } 1326 1327 var passthroughQueryParts = getCheckoutContextQueryParts(); 1328 var queryParts = [ 1329 'source=' + encodeURIComponent(window.location.pathname), 1330 ]; 1331 1332 queryParts = queryParts.concat(passthroughQueryParts); 1333 1334 if (embeddedCartModal) { 1335 queryParts.push('embedded_cart_modal=1'); 1336 queryParts.push('embedded_cart_modal_shell=1'); 1337 if (cacheKey) { 1338 queryParts.push('embedded_cart_cache_key=' + encodeURIComponent(cacheKey)); 1339 } 1340 } 1341 1342 if (includeCartInQuery) { 1343 queryParts.push('sch_cart=' + encodeURIComponent(JSON.stringify(cart))); 1344 } 1345 1346 return baseURL + '?' + queryParts.join('&'); 1347} 1348 1349function buildEmbeddedCheckoutSessionUrl(cacheKey = '') { 1350 var baseURL = '/store/checkout/'; 1351 var pageCookieLanguage = 1352 typeof pageLanguage != 'undefined' ? pageLanguage : getCookie('language'); 1353 1354 if (pageCookieLanguage && pageCookieLanguage != 'en') { 1355 baseURL = `/${pageCookieLanguage}${baseURL}
1355`; 1356 } 1357 1358 var passthroughQueryParts = getCheckoutContextQueryParts(); 1359 var queryParts = [ 1360 'source=' + encodeURIComponent(window.location.pathname), 1361 'embedded_checkout_session=1', 1362 'sch_cart=' + encodeURIComponent(JSON.stringify(cart)), 1363 ]; 1364 1365 queryParts = queryParts.concat(passthroughQueryParts); 1366 1367 if (cacheKey) { 1368 queryParts.push( 1369 'embedded_checkout_cache_key=' + encodeURIComponent(cacheKey) 1370 ); 1371 } 1372 1373 return baseURL + '?' + queryParts.join('&'); 1374} 1375 1376function getCheckoutContextQueryParts() { 1377 var queryParts = []; 1378 var existingKeys = {}; 1379 var queryParams = new URLSearchParams(window.location.search || ''); 1380 1381 queryParams.forEach(function (value, key) { 1382 if ( 1383 key.startsWith('AB_') || 1384 key == 'autoTest' || 1385 key == 'test' || 1386 key == 'is_bot' || 1387 key == 'testing_website_domain' || 1388 key == 'testing_domain' || 1389 key == 'website_domain' || 1390 key == 'WEBSITE_DOMAIN' || 1391 key == 'show_b2c_exit_feedback_on_checkout' 1392 ) { 1393 if (existingKeys[key]) { 1394 return; 1395 } 1396 1397 existingKeys[key] = true; 1398 queryParts.push( 1399 encodeURIComponent(key) + '=' + encodeURIComponent(value) 1400 ); 1401 } 1402 }); 1403 1404 return queryParts; 1405} 1406 1407function getEmbeddedCheckoutModalContainer() { 1408 var modalContainer = document.querySelector('#embeddedCheckoutModalContainer'); 1409 1410 if (!modalContainer) { 1411 modalContainer = document.createElement('div'); 1412 modalContainer.id = 'embeddedCheckoutModalContainer'; 1413 document.body.appendChild(modalContainer); 1414 } 1415 1416 return modalContainer; 1417} 1418 1419function getEmbeddedCheckoutModalCartCacheKey() { 1420 var pageCookieLanguage = 1421 typeof pageLanguage != 'undefined' ? pageLanguage : getCookie('language'); 1422 var checkoutRealDiscount = 1423 typeof realDiscount != 'undefined' 1424 ? Number(realDiscount) || 0 1425 : Number(cart.realDiscount) || 0; 1426 1427 return JSON.stringify({ 1428 currency: typeof cy != 'undefined' ? cy : '', 1429 language: pageCookieLanguage || '', 1430 source: window.location.pathname, 1431 realDiscount: checkoutRealDiscount, 1432 discountCode: getCookie('sch_discount') || '', 1433 items: (cart.items || []).map(function (cartItem) { 1434 return { 1435 bundleId: cartItem.bundleId || '', 1436 productId: cartItem.productId || '', 1437 quantity: cartItem.quantity || 0, 1438 planId: cartItem.planId || '', 1439 addons: cartItem.addons || {}, 1440 specialDiscount: cartItem.specialDiscount || '', 1441 }; 1442 }), 1443 }); 1444} 1445 1446function hasEmbeddedCheckoutCartItems() { 1447 return ( 1448 cart && 1449 Array.isArray(cart.items) && 1450 cart.items.length > 0 1451 ); 1452} 1453 1454function warmEmbeddedCheckoutModalStripeRuntime() { 1455 if (!isEmbeddedCheckoutModalEnabled() || !hasEmbeddedCheckoutCartItems()) { 1456 return; 1457 } 1458 1459 getEmbeddedCheckoutModalStripeInstance().catch(function (error) { 1460 console.log('unable to warm embedded checkout stripe runtime', { error }); 1461 }); 1462} 1463 1464function primeEmbeddedCheckoutModalSession() { 1465 if (!isEmbeddedCheckoutModalEnabled() || !hasEmbeddedCheckoutCartItems()) { 1466 return; 1467 } 1468 1469 warmEmbeddedCheckoutModalStripeRuntime(); 1470 fetchEmbeddedCheckoutModalClientSecret( 1471 getEmbeddedCheckoutModalCartCacheKey() 1472 ).catch(function (error) { 1473 console.log('unable to prime embedded checkout session', { error }); 1474 }); 1475} 1476 1477function getEmbeddedCheckoutTriggerElement(target) { 1478 if (!target || typeof target.closest != 'function') { 1479 return null; 1480 } 1481 1482 return target.closest('.goToCheckout, #btnCompleteOrderCheckout'); 1483} 1484 1485function bindEmbeddedCheckoutModalWarmup() { 1486 if (window.embeddedCheckoutModalWarmupBound) { 1487 return; 1488 } 1489 1490 window.embeddedCheckoutModalWarmupBound = true; 1491 1492 document.addEventListener( 1493 'pointerenter', 1494 function (event) { 1495 if (!getEmbeddedCheckoutTriggerElement(event.target)) { 1496 return; 1497 } 1498 1499 warmEmbeddedCheckoutModalStripeRuntime(); 1500 }, 1501 true 1502 ); 1503 1504 document.addEventListener( 1505 'pointerdown', 1506 function (event) { 1507 if (!getEmbeddedCheckoutTriggerElement(event.target)) { 1508 return; 1509 } 1510 1511 primeEmbeddedCheckoutModalSession(); 1512 }, 1513 true 1514 ); 1515} 1516 1517function shouldPreloadEmbeddedCheckoutModal() { 1518 return ( 1519 isEmbeddedCheckoutModalEnabled() && 1520 hasEmbeddedCheckoutCartItems() 1521 ); 1522} 1523 1524function updateEmbeddedCheckoutModalIntro() { 1525 var intro = document.querySelector('#embeddedCheckoutModalIntro'); 1526 1527 if (!intro) { 1528 return; 1529 } 1530 1531 intro.outerHTML = getEmbeddedCheckoutIntroHtml(); 1532} 1533 1534function getEmbeddedCheckoutModalElements() { 1535 return { 1536 overlay: document.querySelector('#embeddedCheckoutModalOverlay'), 1537 dialog: document.querySelector('#embeddedCheckoutModalDialog'), 1538 intro: document.querySelector('#embeddedCheckoutModalIntro'), 1539 closeButton: document.querySelector('#embeddedCheckoutModalClose'), 1540 exitPrompt: document.querySelector('#embeddedCheckoutModalExitPrompt'), 1541 exitPromptStayButton: document.querySelector( 1542 '#embeddedCheckoutModalExitPromptStay' 1543 ), 1544 exitPromptLeaveButton: document.querySelector( 1545 '#embeddedCheckoutModalExitPromptLeave' 1546 ), 1547 loadingState: document.querySelector('#embeddedCheckoutModalLoading'), 1548 loadingLabel: document.querySelector('#embeddedCheckoutModalLoadingLabel'), 1549 iframeShell: document.querySelector('#embeddedCheckoutModalIframeShell'), 1550 cartEditorShell: document.querySelector('#embeddedCheckoutModalCartEditor'), 1551 cartEditorContent: document.querySelector( 1552 '#embeddedCheckoutModalCartEditorContent' 1553 ), 1554 checkoutMount: document.querySelector('#embeddedCheckoutModalCheckoutMount'), 1555 }; 1556} 1557 1558function setEmbeddedCheckoutExitPromptVisible(isVisible) { 1559 var elements = getEmbeddedCheckoutModalElements(); 1560 1561 if (!elements.exitPrompt) { 1562 return; 1563 } 1564 1565 elements.exitPrompt.style.display = isVisible ? 'flex' : 'none'; 1566 elements.exitPrompt.setAttribute('aria-hidden', isVisible ? 'false' : 'true'); 1567 1568 if (window.innerWidth <= 700) { 1569 if (elements.overlay) { 1570 elements.overlay.style.setProperty( 1571 'overflow', 1572 isVisible ? 'hidden' : 'hidden', 1573 'important' 1574 ); 1575 elements.overlay.style.setProperty( 1576 'touch-action', 1577 isVisible ? 'none' : 'auto', 1578 'important' 1579 ); 1580 } 1581 1582 if (elements.dialog) { 1583 elements.dialog.style.setProperty( 1584 'overflow-y', 1585 isVisible ? 'hidden' : 'auto', 1586 'important' 1587 ); 1588 elements.dialog.style.setProperty( 1589 'touch-action', 1590 isVisible ? 'none' : 'pan-y', 1591 'important' 1592 ); 1593 } 1594 } 1595} 1596 1597function setEmbeddedCheckoutModalClosable(isClosable) { 1598 var elements = getEmbeddedCheckoutModalElements(); 1599 1600 window.embeddedCheckoutModalClosable = isClosable; 1601 1602 if (!elements.closeButton) { 1603 return; 1604 } 1605 1606 elements.closeButton.style.opacity = isClosable ? '1' : '0.45'; 1607 elements.closeButton.style.cursor = isClosable ? 'pointer' : 'default'; 1608} 1609 1610function showEmbeddedCheckoutModalOverlay() { 1611 var elements = getEmbeddedCheckoutModalElements(); 1612 1613 if (!elements.overlay) { 1614 return; 1615 } 1616 1617 elements.overlay.style.display = 'flex'; 1618 elements.overlay.setAttribute('aria-hidden', 'false'); 1619 setEmbeddedCheckoutModalClosable(true); 1620 document.body.style.overflow = 'hidden'; 1621 1622 if (window.innerWidth <= 700) { 1623 elements.overlay.scrollTop = 0; 1624 if (elements.dialog) { 1625 elements.dialog.scrollTop = 0; 1626 } 1627 1628 window.embeddedCheckoutModalScrollTop = 1629 window.pageYOffset || 1630 document.documentElement.scrollTop || 1631 document.body.scrollTop || 1632 0; 1633 document.body.style.position = 'fixed'; 1634 document.body.style.top = `-${window.embeddedCheckoutModalScrollTop}px`; 1635 document.body.style.left = '0'; 1636 document.body.style.right = '0'; 1637 document.body.style.width = '100%'; 1638 } 1639} 1640 1641function hideEmbeddedCheckoutModalOverlay() { 1642 var elements = getEmbeddedCheckoutModalElements(); 1643 1644 if (!elements.overlay) { 1645 return; 1646 } 1647 1648 elements.overlay.style.display = 'none'; 1649 elements.overlay.setAttribute('aria-hidden', 'true'); 1650 document.body.style.overflow = ''; 1651 1652 if (window.innerWidth <= 700) { 1653 var scrollTop = window.embeddedCheckoutModalScrollTop || 0; 1654 document.body.style.position = ''; 1655 document.body.style.top = ''; 1656 document.body.style.left = ''; 1657 document.body.style.right = ''; 1658 document.body.style.width = ''; 1659 window.scrollTo(0, scrollTop); 1660 window.embeddedCheckoutModalScrollTop = 0; 1661 } 1662} 1663 1664function closeEmbeddedCheckoutModal() { 1665 window.embeddedCheckoutModalCartEditorActive = false;
1666 setEmbeddedCheckoutExitPromptVisible(false); 1667 hideEmbeddedCheckoutModalOverlay(); 1668 1669 if ( 1670 typeof window.showSupportChatWidget === 'function' && 1671 !cart.showCart && 1672 (!cart.items || cart.items.length === 0 || window.innerWidth > 768) 1673 ) { 1674 window.showSupportChatWidget(); 1675 } 1676} 1677 1678function openCartFromEmbeddedCheckoutModal() { 1679 closeEmbeddedCheckoutModal(); 1680 cart.showCart = true; 1681 1682 if (typeof CartViewRender == 'function') { 1683 CartViewRender(); 1684 return; 1685 } 1686 1687 if (typeof showCartClick == 'function') { 1688 showCartClick({ 1689 preventDefault: function () {}, 1690 }); 1691 } 1692} 1693 1694function getEmbeddedCheckoutModalAvailableHeight() { 1695 var modalPadding = window.innerWidth <= 700 ? 12 : 24; 1696 1697 if (window.innerWidth <= 700) { 1698 return Math.max(420, window.innerHeight - modalPadding); 1699 } 1700 1701 return Math.max(560, window.innerHeight - modalPadding); 1702} 1703 1704function getEmbeddedCheckoutModalInitialHeight() { 1705 if (window.innerWidth > 700) { 1706 return 1000; 1707 } 1708 1709 return getEmbeddedCheckoutModalAvailableHeight(); 1710} 1711 1712function getEmbeddedCheckoutModalMinimumWidth() { 1713 if (window.innerWidth > 700) { 1714 return Math.min(1050, getEmbeddedCheckoutModalInitialWidth()); 1715 } 1716 1717 return window.innerWidth - 24; 1718} 1719 1720function getEmbeddedCheckoutModalInitialWidth() { 1721 if (window.innerWidth > 700) { 1722 return Math.min(window.innerWidth - 48, 1180); 1723 } 1724 1725 return window.innerWidth - 24; 1726} 1727 1728function getEmbeddedCheckoutModalLockIconSvg() { 1729 return ` 1730 <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#1D3A45" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="flex: 0 0 auto;"> 1731 <rect x="3" y="11" width="18" height="10" rx="2"></rect> 1732 <path d="M7 11V7a5 5 0 0 1 10 0v4"></path> 1733 </svg> 1734 `; 1735} 1736 1737function getEmbeddedCheckoutModalCloseIconSvg() { 1738 return ` 1739 <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#1D3A45" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: block;"> 1740 <path d="M18 6 6 18"></path> 1741 <path d="m6 6 12 12"></path> 1742 </svg> 1743 `; 1744} 1745 1746function getEmbeddedCheckoutModalCartIconSvg() { 1747 return ` 1748 <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#1D3A45" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: block; flex: 0 0 auto;"> 1749 <circle cx="8" cy="21" r="1"></circle> 1750 <circle cx="19" cy="21" r="1"></circle> 1751 <path d="M2.05 2.05h2l2.66 12.39a2 2 0 0 0 2 1.56h9.72a2 2 0 0 0 2-1.64L23 6H6"></path> 1752 </svg> 1753 `; 1754} 1755 1756function getEmbeddedCheckoutModalLoaderIconSvg() { 1757 return ` 1758 <svg class="embeddedCheckoutModalLoaderIcon" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: block; flex: 0 0 auto;"> 1759 <path d="M21 12a9 9 0 1 1-6.219-8.56"></path> 1760 </svg> 1761 `; 1762} 1763 1764function getSchCheckoutAnswersBreakdownItems() { 1765 function getPlayerCoverageText(ticketCount) { 1766 if (ticketCount === 1) { 1767 return 'Covers one player.'; 1768 } 1769 1770 return `Covers up to ${ticketCount} players.`; 1771 } 1772 1773 if ( 1774 WEBSITE_DOMAIN !== 'sch' || 1775 !abVersionEquals('SCH_CHECKOUT_ANSWERS_V2', 1) || 1776 cart.hasSubscription || 1777 cart.hasTrial || 1778 !Array.isArray(cart.items) 1779 ) { 1780 return []; 1781 } 1782 1783 return cart.items.reduce(function (items, cartItem) { 1784 var bundle = getBundleInfo(cartItem.bundleId || 1) || {}; 1785 var product = getProductInfo(cartItem.productId || 1) || {}; 1786 var hasFixedBundlePrice = 1787 bundle.bundle_price_id || bundle.bundle_price_override; 1788 var isAnnualPassItem = !!bundle.season_pass_tickets; 1789 var isTicketVariantItem = 1790 !product.subscription_length && 1791 !product.physical_product && 1792 !isAnnualPassItem; 1793 1794 if (isTicketVariantItem) { 1795 var ticketCount = hasFixedBundlePrice 1796 ? parseInt(bundle.initial_quantity, 10) || 0 1797 : parseInt(cartItem.quantity, 10) || 0; 1798 1799 if (ticketCount > 0) { 1800 items.push({ 1801 title: 1802 ticketCount === 1 1803 ? '1 Scavenger Hunt Ticket' 1804 : `${ticketCount} Scavenger Hunt Tickets`, 1805 descriptionHtml: 1806 `Works for one scavenger hunt experience in <b>any</b> of our 3000+ locations. ${getPlayerCoverageText(ticketCount)}`, 1807 }); 1808 } 1809 } else if (isAnnualPassItem) { 1810 var seasonPassTickets = parseInt(bundle.season_pass_tickets, 10) || 0; 1811 1812 if (cartItem.addons) {
1813 Object.keys(cartItem.addons).forEach(function (addonId) { 1814 var addon = getAddonInfo(addonId); 1815 if (addon && addon.additional_tickets) { 1816 seasonPassTickets += parseInt(addon.additional_tickets, 10) || 0; 1817 } 1818 }); 1819 } 1820 1821 if (seasonPassTickets > 0) { 1822 var passLength = 1823 parseInt( 1824 cartItem.season_pass_length_override || bundle.season_pass_length, 1825 10 1826 ) || 12; 1827 var passTitle = 1828 cartItem.locationType === 'state' && cartItem.location 1829 ? String(bundle.title || '').replace('Single State', cartItem.location) 1830 : bundle.title || 1831 (passLength === 12 1832 ? 'Scavenger Hunt Annual Pass' 1833 : `${passLength}-Month Explorer Pass`); 1834 var passDuration = passLength === 12 ? '1 year' : `${passLength} months`; 1835 var passPlayerLabel = seasonPassTickets === 1 ? 'Player' : 'Players'; 1836 1837 items.push({ 1838 title: passTitle, 1839 descriptionHtml: `Works for unlimited scavenger hunt experiences in <b>any</b> of our 3000+ locations for ${passDuration} after redemption. Up to ${seasonPassTickets} ${passPlayerLabel}.`, 1840 }); 1841 } 1842 } 1843 1844 return items; 1845 }, []); 1846} 1847 1848function getSchCheckoutAnswersIntroHtml() { 1849 return ''; 1850} 1851 1852function getEmbeddedCheckoutIntroDescription() { 1853 if (cart.hasTrial) { 1854 return `Unlimited scavenger hunts for up to 6 players. <b>FREE ${cart.trialPeriodDays}-day trial</b>, then billed monthly. Cancel anytime.`; 1855 } 1856 1857 if (cart.hasSubscription) { 1858 return 'Unlimited scavenger hunts for up to 6 players. Billed monthly. Cancel anytime.'; 1859 } 1860 1861 var schCheckoutAnswersIntroHtml = getSchCheckoutAnswersIntroHtml(); 1862 1863 if (schCheckoutAnswersIntroHtml) { 1864 return schCheckoutAnswersIntroHtml; 1865 } 1866 1867 var introParts = []; 1868 1869 if (cart.hasIndividualTickets) { 1870 introParts.push( 1871 'Scavenger Hunt Tickets are valid for use on any <i>one</i> scavenger hunt, and must be used within 2 years of purchase.' 1872 ); 1873 } 1874 1875 if (cart.hasAnnualPass) { 1876 introParts.push( 1877 'Scavenger Hunt Annual Passes are valid for 1 year after being redeemed, and can be used on unlimited hunts in our 3000+ cities.' 1878 ); 1879 } 1880 1881 return introParts.join(' '); 1882} 1883 1884function getEmbeddedCheckoutIntroHtml() { 1885 var discountText = 1886 typeof discountDescription != 'undefined' && discountDescription 1887 ? discountDescription 1888 : 'Up to 55% off all tickets and passes'; 1889 var introDescription = getEmbeddedCheckoutIntroDescription(); 1890 var showSchCheckoutAnswersBreakdown = 1891 getSchCheckoutAnswersBreakdownItems().length > 0; 1892 1893 return ` 1894 <div id="embeddedCheckoutModalIntro" style="width: 100%; margin: 0; padding: 28px 76px 0 20px; box-sizing: border-box;"> 1895 <div id="embeddedCheckoutModalIntroTop" style="display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;"> 1896 <div id="embeddedCheckoutModalTitleGroup" style="display: flex; align-items: center; gap: 12px; min-width: 0;"> 1897 ${getEmbeddedCheckoutModalLockIconSvg()} 1898 <h1 id="embeddedCheckoutModalTitle" style="margin: 0; font-family: 'Plus Jakarta Sans', sans-serif; font-size: 24px; font-weight: 800; line-height: 1.1;">Secure Checkout</h1> 1899 </div> 1900 </div> 1901 <div class="h-margin__b--0 h-margin-m__b--10" style="margin-top: 12px; margin-bottom: 0;"> 1902 ${introDescription} 1903 </div> 1904 ${ 1905 showSchCheckoutAnswersBreakdown 1906 ? '' 1907 : `<p class="h-margin__v--5" style="margin: 8px 0 0; font-family: 'Plus Jakarta Sans', sans-serif; font-size: 17px; line-height: 1.35;"><span style="font-weight: 800;">Discount Already Applied:</span> <span style="font-weight: 800;">${discountText}</span></p>` 1908 } 1909 <p class="h-margin__v--5" style="margin: 10px 0 0; font-family: 'Plus Jakarta Sans', sans-serif; font-size: 17px; line-height: 1.35;"><span style="font-weight: 800;">Enter your contact details.</span> If this is a gift, you'll add the gift recipient's info later</p> 1910 </div> 1911 `; 1912} 1913 1914function getEmbeddedCheckoutModalLoadingLabelHtml(labelText = 'Loading Secure Checkout') { 1915 return `${getEmbeddedCheckoutModalLoaderIconSvg()}<span>${labelText}</span>`;
1916} 1917 1918function setEmbeddedCheckoutModalLoadingLabelText(labelText) { 1919 var loadingLabel = document.querySelector('#embeddedCheckoutModalLoadingLabel'); 1920 1921 if (!loadingLabel) { 1922 return; 1923 } 1924 1925 loadingLabel.innerHTML = getEmbeddedCheckoutModalLoadingLabelHtml(labelText); 1926} 1927 1928function setEmbeddedCheckoutModalViewMode(mode) { 1929 var elements = getEmbeddedCheckoutModalElements(); 1930 1931 if (!elements.iframeShell || !elements.cartEditorShell) { 1932 return; 1933 } 1934 1935 var isCartEditorMode = mode === 'cart-editor'; 1936 1937 elements.iframeShell.style.display = isCartEditorMode ? 'none' : 'block'; 1938 elements.cartEditorShell.style.display = isCartEditorMode ? 'block' : 'none'; 1939} 1940 1941function syncEmbeddedCheckoutModalCartState() { 1942 if (cart.items) { 1943 handleVolumeDiscountsAndShipping(); 1944 } 1945 1946 cart.total = priceCart('discounted'); 1947 cart.regularTotal = priceCart('regular'); 1948 cart.fullTotal = priceCart('full'); 1949 cart.realDiscount = realDiscount; 1950 1951 updateCartStats(); 1952 1953 setCookie('sch_cart', cart); 1954 setCookie('cart', cart); 1955} 1956 1957function getEmbeddedCheckoutModalCartActionText(actionText, fallback) { 1958 if (typeof translateText == 'function') { 1959 return translateText(actionText, commonTranslationDictionary); 1960 } 1961 1962 return fallback; 1963} 1964 1965function duplicateEmbeddedCheckoutModalCartItem(position) { 1966 if ( 1967 confirm( 1968 getEmbeddedCheckoutModalCartActionText( 1969 'Are you sure you want to duplicate this item?', 1970 'Are you sure you want to duplicate this item?' 1971 ) 1972 ) !== true 1973 ) { 1974 return; 1975 } 1976 1977 var newItem = Object.assign({}, cart.items[position]); 1978 clearSchTicketOverhaulModalSessionState(newItem); 1979 cart.items.push(newItem); 1980 syncEmbeddedCheckoutModalCartState(); 1981 1982 if (typeof window.updateCards === 'function') { 1983 window.updateCards(); 1984 } 1985 1986 renderEmbeddedCheckoutModalCartEditor(); 1987} 1988 1989function removeEmbeddedCheckoutModalCartItem(position, itemToRemove) { 1990 if ( 1991 confirm( 1992 getEmbeddedCheckoutModalCartActionText( 1993 'Are you sure you want to remove this item from your cart?', 1994 'Are you sure you want to remove this item from your cart?' 1995 ) 1996 ) !== true 1997 ) { 1998 return; 1999 } 2000 2001 fb_track_safe('track', 'CartItemRemove'); 2002 2003 gtag_and_microsoft_uet('event', 'remove_from_cart', { 2004 currency: cy?.toUpperCase() || 'USD', 2005 value: Number(itemToRemove.total), 2006 items: [{ item_id: `${itemToRemove.bundleId}` }], 2007 }); 2008 2009 cart.items.splice(position, 1); 2010 syncEmbeddedCheckoutModalCartState(); 2011 2012 if (typeof window.updateCards === 'function') { 2013 window.updateCards(); 2014 } 2015 2016 renderEmbeddedCheckoutModalCartEditor(); 2017} 2018 2019function createEmbeddedCheckoutModalCartEditorItem(cartItem, index) { 2020 if (typeof CartItem == 'function') { 2021 var cartItemView = CartItem(cartItem, index); 2022 2023 if (cartItemView.querySelector('.edit-item')) { 2024 cartItemView.querySelector('.edit-item').onclick = function (e) { 2025 fb_track_safe('track', 'CartItemEdit'); 2026 cart.editIndex = index; 2027 navigateToBundle(getBundleInfo(cartItem.bundleId || 1) || {}, cartItem); 2028 }; 2029 } 2030 2031 if (cartItemView.querySelector('.copy-item')) { 2032 cartItemView.querySelector('.copy-item').onclick = function (e) { 2033 e.preventDefault(); 2034 duplicateEmbeddedCheckoutModalCartItem(index); 2035 }; 2036 } 2037 2038 if (cartItemView.querySelector('.delete-item')) { 2039 cartItemView.querySelector('.delete-item').onclick = function (e) { 2040 e.preventDefault(); 2041 removeEmbeddedCheckoutModalCartItem(index, cartItem); 2042 }; 2043 } 2044 2045 return cartItemView; 2046 } 2047 2048 return renderHTML(` 2049 <div style="border: 1px solid rgba(29, 58, 69, 0.1); border-radius: 16px; padding: 16px; margin-bottom: 12px;"> 2050 <div style="font-weight: 700; color: #1D3A45;">${(getBundleInfo(cartItem.bundleId || 1) || {}).title || 'Cart Item'}</div> 2051 <div style="margin-top: 6px; color: rgba(29, 58, 69, 0.78);">${formatPrice(cartItem.total || 0, cy)}</div> 2052 </div> 2053 `); 2054} 2055 2056function renderEmbeddedCheckoutModalCartEditor() { 2057 var elements = getEmbeddedCheckoutModalElements(); 2058 2059 if (!elements.cartEditorContent) { 2060 return; 2061 } 2062 2063 window.embeddedCheckoutModalCartEditorActive = true; 2064 setEmbeddedCheckoutExitPromptVisible(false); 2065 setEmbeddedCheckoutModalViewMode('cart-editor'); 2066 setEmbeddedCheckoutModalLoadingState(false); 2067 2068 var cartEditorView = renderHTML(` 2069 <div style="padding: 8px 20px 28px;"> 2070 <div style="width: 100%; max-width: 920px; margin: 0 auto;"> 2071 <div style="display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 18px;"> 2072 <div style="font-family: 'Plus Jakarta Sans', sans-serif; font-size: 24px; font-weight: 800; color: #1D3A45;">Edit Cart</div> 2073 <div style="font-family: 'Plus Jakarta Sans', sans-serif; font-size: 16px; font-weight: 700; color: #1D3A45;">${formatPrice(cart.total || 0, cy)}</div> 2074 </div> 2075 <div id="embeddedCheckoutModalCartItems"></div> 2076 <div style="display: flex; justify-content: flex-end; margin-top: 20px;"> 2077 <button id="embeddedCheckoutModalCartUpdateButton" type="button" style="border: 0; background: #E87722; color: #ffffff; border-radius: 999px; padding: 16px 24px; font-family: 'Plus Jakarta Sans', sans-serif; font-size: 16px; font-weight: 800; line-height: 1; cursor: pointer;">Update Cart</button> 2078 </div> 2079 </div> 2080 </div> 2081 `); 2082 2083 var cartItemsContainer = cartEditorView.querySelector( 2084 '#embeddedCheckoutModalCartItems' 2085 ); 2086 2087 if (!cart.items || cart.items.length === 0) { 2088 cartItemsContainer.appendChild( 2089 renderHTML(` 2090 <div style="border: 1px dashed rgba(29, 58, 69, 0.16); border-radius: 16px; padding: 28px 20px; text-align: center; font-family: 'Plus Jakarta Sans', sans-serif; color: #1D3A45;"> 2091 Your cart is empty. 2092 </div> 2093 `) 2094 ); 2095 } else {
2096 cart.items.forEach(function (cartItem, index) { 2097 cartItemsContainer.appendChild( 2098 createEmbeddedCheckoutModalCartEditorItem(cartItem, index) 2099 ); 2100 }); 2101 } 2102 2103 cartEditorView.querySelector('#embeddedCheckoutModalCartUpdateButton').onclick = 2104 function () { 2105 window.embeddedCheckoutModalCartEditorActive = false; 2106 setEmbeddedCheckoutModalViewMode('checkout'); 2107 setEmbeddedCheckoutModalLoadingLabelText('Updating Cart'); 2108 loadEmbeddedCheckoutModalIframe(true); 2109 }; 2110 2111 elements.cartEditorContent.innerHTML = ''; 2112 elements.cartEditorContent.appendChild(cartEditorView); 2113 syncEmbeddedCheckoutModalHeight(); 2114} 2115 2116function syncEmbeddedCheckoutModalHeight() { 2117 var dialog = document.querySelector('#embeddedCheckoutModalDialog'); 2118 var intro = document.querySelector('#embeddedCheckoutModalIntro'); 2119 var iframeShell = document.querySelector('#embeddedCheckoutModalIframeShell'); 2120 var checkoutMount = document.querySelector('#embeddedCheckoutModalCheckoutMount'); 2121 var loadingLabel = document.querySelector('#embeddedCheckoutModalLoadingLabel'); 2122 2123 if (!dialog || !iframeShell || !checkoutMount) { 2124 return; 2125 } 2126 2127 var initialHeight = getEmbeddedCheckoutModalInitialHeight(); 2128 var initialWidth = getEmbeddedCheckoutModalInitialWidth(); 2129 var minimumWidth = getEmbeddedCheckoutModalMinimumWidth(); 2130 var introHeight = intro ? intro.getBoundingClientRect().height : 0; 2131 var isLoading = !!( 2132 loadingLabel && window.getComputedStyle(loadingLabel).display !== 'none' 2133 ); 2134 var iframeHeight = Math.max( 2135 420, 2136 initialHeight - introHeight, 2137 checkoutMount.scrollHeight || 0, 2138 checkoutMount.getBoundingClientRect().height || 0 2139 ); 2140 2141 dialog.style.width = '100%'; 2142 dialog.style.maxWidth = `${initialWidth}px`; 2143 dialog.style.minWidth = window.innerWidth > 700 ? `${minimumWidth}px` : '0'; 2144 if (window.innerWidth > 700) { 2145 dialog.style.minHeight = isLoading ? `${initialHeight}px` : '0'; 2146 dialog.style.height = 'auto'; 2147 dialog.style.maxHeight = 'none'; 2148 iframeShell.style.height = `${iframeHeight}px`; 2149 iframeShell.style.minHeight = ''; 2150 } else { 2151 var availableHeight = getEmbeddedCheckoutModalAvailableHeight(); 2152 2153 dialog.style.minHeight = `${availableHeight}px`; 2154 dialog.style.height = `${availableHeight}px`; 2155 dialog.style.maxHeight = `${availableHeight}px`; 2156 iframeShell.style.height = 'auto'; 2157 iframeShell.style.minHeight = `${iframeHeight}px`; 2158 } 2159 2160 checkoutMount.style.minHeight = `${iframeHeight}px`; 2161} 2162 2163function setEmbeddedCheckoutModalLoadingState(isLoading) { 2164 var loadingState = document.querySelector('#embeddedCheckoutModalLoading'); 2165 var loadingLabel = document.querySelector('#embeddedCheckoutModalLoadingLabel'); 2166 var checkoutMount = document.querySelector('#embeddedCheckoutModalCheckoutMount'); 2167 2168 if (!loadingState || !loadingLabel || !checkoutMount) { 2169 return; 2170 } 2171 2172 var isReceiptLoading = 2173 isLoading && loadingLabel.textContent.includes('Receipt'); 2174 2175 loadingState.style.display = isReceiptLoading ? 'block' : 'none'; 2176 loadingLabel.style.display = isLoading ? 'flex' : 'none'; 2177 checkoutMount.style.visibility = isReceiptLoading ? 'hidden' : 'visible'; 2178} 2179 2180function refreshEmbeddedCheckoutModalLayout() { 2181 try { 2182 window.dispatchEvent(new Event('resize')); 2183 } catch (error) { 2184 console.log('unable to refresh embedded checkout modal layout', { error }); 2185 } 2186} 2187 2188function scheduleEmbeddedCheckoutModalHeightSync() { 2189 syncEmbeddedCheckoutModalHeight(); 2190 setTimeout(function () { 2191 refreshEmbeddedCheckoutModalLayout(); 2192 syncEmbeddedCheckoutModalHeight(); 2193 }, 150); 2194 setTimeout(function () { 2195 refreshEmbeddedCheckoutModalLayout(); 2196 syncEmbeddedCheckoutModalHeight(); 2197 }, 500); 2198 setTimeout(function () { 2199 refreshEmbeddedCheckoutModalLayout(); 2200 syncEmbeddedCheckoutModalHeight(); 2201 }, 1000); 2202} 2203 2204function showEmbeddedCheckoutRedirectLoader(labelText = 'Loading Receipt Page') { 2205 if (!document.querySelector('#embeddedCheckoutModalOverlay')) { 2206 return; 2207 } 2208 2209 setEmbeddedCheckoutModalClosable(false); 2210 setEmbeddedCheckoutExitPromptVisible(false); 2211 setEmbeddedCheckoutModalLoadingLabelText(labelText); 2212 setEmbeddedCheckoutModalLoadingState(true); 2213 syncEmbeddedCheckoutModalHeight(); 2214} 2215 2216window.showEmbeddedCheckoutRedirectLoader = showEmbeddedCheckoutRedirectLoader; 2217 2218function getEmbeddedCheckoutModalStripeInstance() { 2219 if (window.embeddedCheckoutModalStripePromise) { 2220 return window.embeddedCheckoutModalStripePromise; 2221 } 2222 2223 window.embeddedCheckoutModalStripePromise = loadStripeJsOnce().then( 2224 function () { 2225 if (typeof Stripe == 'undefined' || typeof strpk == 'undefined') { 2226 throw new Error('Stripe is unavailable for embedded checkout modal'); 2227 } 2228 2229 return Stripe(strpk, { locale: getCookie('language') || 'en' }); 2230 } 2231 ); 2232 2233 return window.embeddedCheckoutModalStripePromise; 2234} 2235 2236function fetchEmbeddedCheckoutModalClientSecret( 2237 cartCacheKey, 2238 forceReload = false 2239) { 2240 if ( 2241 !forceReload && 2242 window.embeddedCheckoutModalClientSecret && 2243 window.embeddedCheckoutModalClientSecretCacheKey === cartCacheKey 2244 ) { 2245 return Promise.resolve(window.embeddedCheckoutModalClientSecret); 2246 } 2247 2248 if ( 2249 !forceReload && 2250 window.embeddedCheckoutModalClientSecretPromise && 2251 window.embeddedCheckoutModalClientSecretPromiseKey === cartCacheKey 2252 ) { 2253 return window.embeddedCheckoutModalClientSecretPromise; 2254 } 2255 2256 var requestUrl = buildEmbeddedCheckoutSessionUrl(cartCacheKey); 2257 2258 window.embeddedCheckoutModalClientSecretPromiseKey = cartCacheKey; 2259 window.embeddedCheckoutModalClientSecretPromise = fetch(requestUrl, { 2260 credentials: 'same-origin', 2261 }) 2262 .then(function (response) { 2263 if (!response.ok) { 2264 throw new Error( 2265 `Embedded checkout session request failed: ${response.status}` 2266 ); 2267 } 2268 2269 return response.json(); 2270 }) 2271 .then(function (payload) { 2272 if (!payload || !payload.client_secret) { 2273 throw new Error('Missing embedded checkout client secret'); 2274 } 2275 2276 window.embeddedCheckoutModalClientSecret = payload.client_secret; 2277 window.embeddedCheckoutModalClientSecretCacheKey = cartCacheKey; 2278 2279 return payload.client_secret; 2280 }) 2281 .finally(function () { 2282 window.embeddedCheckoutModalClientSecretPromise = null; 2283 window.embeddedCheckoutModalClientSecretPromiseKey = null; 2284 }); 2285 2286 return window.embeddedCheckoutModalClientSecretPromise; 2287} 2288 2289function attemptCloseEmbeddedCheckoutModal() { 2290 if (window.embeddedCheckoutModalClosable === false) { 2291 return false;
2292 } 2293 2294 setEmbeddedCheckoutExitPromptVisible(true); 2295 return false; 2296} 2297 2298function createEmbeddedCheckoutModal() { 2299 var modalContainer = getEmbeddedCheckoutModalContainer(); 2300 2301 if (!modalContainer) { 2302 return null; 2303 } 2304 2305 modalContainer.innerHTML = ` 2306 <div id="embeddedCheckoutModalOverlay" role="dialog" aria-modal="true" aria-label="Checkout" aria-hidden="true" style="position: fixed; inset: 0; z-index: 999999999999; background: rgba(0, 0, 0, 0.65); display: none; align-items: flex-start; justify-content: center; padding: 12px; overflow-y: auto;"> 2307 <div id="embeddedCheckoutModalDialog" style="position: relative; width: 100%; max-width: 1180px; background: #ffffff; border-radius: 20px; overflow: hidden; box-shadow: 0 24px 80px rgba(0, 0, 0, 0.28);"> 2308 <div id="embeddedCheckoutModalExitPrompt" role="alertdialog" aria-modal="true" aria-hidden="true" aria-labelledby="embeddedCheckoutModalExitPromptTitle" style="position: absolute; inset: 0; z-index: 4; display: none; align-items: flex-start; justify-content: center; background: rgba(29, 58, 69, 0.18); padding: 140px 20px 20px;"> 2309 <div style="width: 100%; max-width: 420px; background: #ffffff; border-radius: 20px; box-shadow: 0 24px 80px rgba(0, 0, 0, 0.2); padding: 28px 24px 24px; text-align: center;"> 2310 <div id="embeddedCheckoutModalExitPromptTitle" style="color: #1D3A45; font-size: 26px; font-weight: 700; line-height: 1.2;">Are you sure you want to close the checkout?</div> 2311 <div style="display: flex; gap: 12px; justify-content: center; margin-top: 24px; flex-wrap: wrap;"> 2312 <button id="embeddedCheckoutModalExitPromptStay" type="button" style="min-width: 170px; border: 0; background: #E87722; color: #ffffff; border-radius: 999px; font-size: 16px; font-weight: 700; line-height: 1; padding: 16px 20px; cursor: pointer;">Keep Checkout Open</button> 2313 <button id="embeddedCheckoutModalExitPromptLeave" type="button" style="min-width: 170px; border: 1px solid rgba(29, 58, 69, 0.18); background: #ffffff; color: #1D3A45; border-radius: 999px; font-size: 16px; font-weight: 700; line-height: 1; padding: 16px 20px; cursor: pointer;">Close Checkout</button> 2314 </div> 2315 </div> 2316 </div> 2317 <button id="embeddedCheckoutModalClose" type="button" aria-label="Close checkout" style="position: absolute; top: 14px; right: 14px; z-index: 2; width: 40px; height: 40px; border: 0; border-radius: 999px; background: rgba(29, 58, 69, 0.08); color: #1D3A45; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0;">${getEmbeddedCheckoutModalCloseIconSvg()}</button> 2318 ${getEmbeddedCheckoutIntroHtml()} 2319 <div id="embeddedCheckoutModalIframeShell" style="position: relative; width: 100%; min-height: 420px;"> 2320 <div id="embeddedCheckoutModalLoadingLabel" aria-live="polite" style="position: absolute; top: 50px; left: 50%; transform: translateX(-50%); z-index: 2; color: #FFFFFF; font-family: 'Plus Jakarta Sans', sans-serif; font-size: 21px; font-weight: 800; display: flex; align-items: center; justify-content: center; gap: 13px; text-align: center; background: rgba(17, 24, 39, 0.92); border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 999px; padding: 13px 21px; box-shadow: 0 12px 28px rgba(0, 0, 0, 0.18); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);">${getEmbeddedCheckoutModalLoadingLabelHtml()}</div> 2321 <div id="embeddedCheckoutModalLoading" aria-hidden="true" style="position: absolute; inset: 0; z-index: 1; display: none; background: #ffffff;"></div> 2322 <div id="embeddedCheckoutModalCheckoutMount" style="display: block; width: 100%; min-height: 420px; background: #ffffff; visibility: visible;"></div> 2323 </div> 2324 <div id="embeddedCheckoutModalCartEditor" style="display: none; width: 100%;"> 2325 <div id="embeddedCheckoutModalCartEditorContent"></div> 2326 </div> 2327 </div> 2328 </div> 2329 <style id="embeddedCheckoutModalStyles"> 2330 @keyframes embeddedCheckoutModalSpin { 2331 from { 2332 transform: rotate(0deg); 2333 } 2334 to { 2335 transform: rotate(360deg); 2336 } 2337 } 2338 2339 .embeddedCheckoutModalLoaderIcon { 2340 animation: embeddedCheckoutModalSpin 0.9s linear infinite; 2341 transform-origin: center; 2342 } 2343 2344 #embeddedCheckoutModalLoadingLabel { 2345 white-space: nowrap; 2346 } 2347 2348 @media (max-width: 700px) { 2349 #embeddedCheckoutModalOverlay { 2350 justify-content: stretch !important; 2351 padding: 12px 0 0 !important; 2352 overflow: hidden !important; 2353 } 2354 2355 #embeddedCheckoutModalDialog { 2356 width: 100vw !important; 2357 max-width: 100vw !important; 2358 margin: 0 !important; 2359 height: calc(100dvh - 12px) !important; 2360 max-height: calc(100dvh - 12px) !important; 2361 min-height: calc(100dvh - 12px) !important; 2362 border-radius: 20px 20px 0 0 !important; 2363 overflow-x: hidden !important; 2364 overflow-y: auto !important; 2365 -webkit-overflow-scrolling: touch; 2366 } 2367 2368 #embeddedCheckoutModalIntro { 2369 padding: 20px 20px 16px !important; 2370 } 2371 2372 #embeddedCheckoutModalIntroTop { 2373 align-items: flex-start !important; 2374 gap: 12px !important; 2375 } 2376 2377 #embeddedCheckoutModalTitleGroup { 2378 width: 100%; 2379 padding-right: 56px; 2380 } 2381 2382 #embeddedCheckoutModalTitle { 2383 font-size: 22px !important; 2384 } 2385 2386 #embeddedCheckoutModalLoadingLabel { 2387 top: 0 !important; 2388 max-width: calc(100vw - 24px); 2389 font-size: 18px !important; 2390 gap: 10px !important; 2391 padding: 12px 18px !important; 2392 white-space: nowrap !important; 2393 } 2394 2395 #embeddedCheckoutModalLoading { 2396 padding: 0 !important; 2397 } 2398 2399 #embeddedCheckoutModalExitPrompt { 2400 align-items: center !important; 2401 padding: 20px !important; 2402 } 2403 } 2404 </style> 2405 `; 2406 2407 var elements = getEmbeddedCheckoutModalElements(); 2408 2409 if ( 2410 !elements.closeButton || 2411 !elements.checkoutMount || 2412 !elements.loadingState || 2413 !elements.exitPromptStayButton || 2414 !elements.exitPromptLeaveButton || 2415 !elements.cartEditorShell || 2416 !elements.cartEditorContent 2417 ) { 2418 modalContainer.innerHTML = ''; 2419 return null; 2420 } 2421 2422 elements.closeButton.onclick = function () { 2423 attemptCloseEmbeddedCheckoutModal(); 2424 }; 2425 2426 elements.overlay.onclick = function (event) { 2427 if (event.target && event.target.id === 'embeddedCheckoutModalOverlay') { 2428 attemptCloseEmbeddedCheckoutModal(); 2429 } 2430 }; 2431 2432 elements.exitPromptStayButton.onclick = function () { 2433 setEmbeddedCheckoutExitPromptVisible(false); 2434 }; 2435 2436 elements.exitPromptLeaveButton.onclick = function () { 2437 closeEmbeddedCheckoutModal(); 2438 if (typeof window.openB2cExitFeedback === 'function') { 2439 window.openB2cExitFeedback('checkout_close'); 2440 } 2441 }; 2442 2443 syncEmbeddedCheckoutModalHeight(); 2444 setEmbeddedCheckoutModalViewMode('checkout'); 2445 2446 if (!window.embeddedCheckoutModalResizeHandler) { 2447 window.embeddedCheckoutModalResizeHandler = syncEmbeddedCheckoutModalHeight; 2448 window.addEventListener('resize', window.embeddedCheckoutModalResizeHandler); 2449 } 2450 2451 return elements; 2452} 2453 2454function ensureEmbeddedCheckoutModal() { 2455 var elements = getEmbeddedCheckoutModalElements(); 2456 2457 if (elements.overlay && elements.closeButton && elements.checkoutMount) { 2458 return elements; 2459 } 2460 2461 return createEmbeddedCheckoutModal(); 2462} 2463 2464function loadEmbeddedCheckoutModalIframe(forceReload = false) { 2465 var elements = ensureEmbeddedCheckoutModal(); 2466 2467 if (!elements || !elements.checkoutMount) { 2468 return false;
2469 } 2470 2471 var cartCacheKey = getEmbeddedCheckoutModalCartCacheKey(); 2472 var shouldReload = 2473 forceReload || 2474 window.embeddedCheckoutModalCartCacheKey !== cartCacheKey || 2475 !window.embeddedCheckoutModalLoaded || 2476 !window.embeddedCheckoutModalCheckoutInstance; 2477 2478 updateEmbeddedCheckoutModalIntro(); 2479 2480 if (!shouldReload) { 2481 setEmbeddedCheckoutModalLoadingState(false); 2482 scheduleEmbeddedCheckoutModalHeightSync(); 2483 return true; 2484 } 2485 2486 window.embeddedCheckoutModalCartCacheKey = cartCacheKey; 2487 window.embeddedCheckoutModalLoaded = false; 2488 window.embeddedCheckoutModalLoadToken = 2489 (window.embeddedCheckoutModalLoadToken || 0) + 1; 2490 var loadToken = window.embeddedCheckoutModalLoadToken; 2491 2492 if ( 2493 window.embeddedCheckoutModalCheckoutInstance && 2494 typeof window.embeddedCheckoutModalCheckoutInstance.destroy == 'function' 2495 ) { 2496 try { 2497 window.embeddedCheckoutModalCheckoutInstance.destroy(); 2498 } catch (error) { 2499 console.log('unable to destroy embedded checkout modal instance', { 2500 error, 2501 }); 2502 } 2503 } 2504 2505 window.embeddedCheckoutModalCheckoutInstance = null; 2506 elements.checkoutMount.innerHTML = ''; 2507 setEmbeddedCheckoutModalLoadingState(true); 2508 syncEmbeddedCheckoutModalHeight(); 2509 2510 Promise.all([ 2511 getEmbeddedCheckoutModalStripeInstance(), 2512 fetchEmbeddedCheckoutModalClientSecret(cartCacheKey, forceReload), 2513 ]) 2514 .then(function ([stripeInstance, clientSecret]) { 2515 if (loadToken !== window.embeddedCheckoutModalLoadToken) { 2516 return null; 2517 } 2518 2519 return stripeInstance.initEmbeddedCheckout({ 2520 fetchClientSecret: function () { 2521 return Promise.resolve(clientSecret); 2522 }, 2523 }); 2524 }) 2525 .then(function (checkoutInstance) { 2526 if (!checkoutInstance) { 2527 return; 2528 } 2529 2530 if (loadToken !== window.embeddedCheckoutModalLoadToken) { 2531 if (typeof checkoutInstance.destroy == 'function') { 2532 checkoutInstance.destroy(); 2533 } 2534 return; 2535 } 2536 2537 window.embeddedCheckoutModalCheckoutInstance = checkoutInstance; 2538 checkoutInstance.mount('#embeddedCheckoutModalCheckoutMount'); 2539 window.embeddedCheckoutModalLoaded = true; 2540 window.embeddedCheckoutModalCartEditorActive = false; 2541 setEmbeddedCheckoutModalLoadingLabelText('Loading Secure Checkout'); 2542 setEmbeddedCheckoutModalViewMode('checkout'); 2543 setEmbeddedCheckoutModalLoadingState(false); 2544 scheduleEmbeddedCheckoutModalHeightSync(); 2545 }) 2546 .catch(function (error) { 2547 console.log('unable to initialize embedded checkout modal', { error }); 2548 2549 if (loadToken !== window.embeddedCheckoutModalLoadToken) { 2550 return; 2551 } 2552 2553 window.location.href = buildCheckoutUrl({ 2554 includeCartInQuery: true, 2555 }); 2556 }); 2557 2558 return true; 2559} 2560
2561function invalidateEmbeddedCheckoutModalSession() { 2562 if (window.embeddedCheckoutModalPreloadTimeout) { 2563 clearTimeout(window.embeddedCheckoutModalPreloadTimeout); 2564 window.embeddedCheckoutModalPreloadTimeout = null; 2565 } 2566 2567 if ( 2568 window.embeddedCheckoutModalPreloadIdleCallback && 2569 typeof window.cancelIdleCallback == 'function' 2570 ) { 2571 window.cancelIdleCallback(window.embeddedCheckoutModalPreloadIdleCallback); 2572 window.embeddedCheckoutModalPreloadIdleCallback = null; 2573 } 2574 2575 window.embeddedCheckoutModalLoaded = false; 2576 window.embeddedCheckoutModalCartCacheKey = null; 2577 window.embeddedCheckoutModalClientSecret = null; 2578 window.embeddedCheckoutModalClientSecretCacheKey = null; 2579 window.embeddedCheckoutModalClientSecretPromise = null; 2580 window.embeddedCheckoutModalClientSecretPromiseKey = null; 2581} 2582 2583function openEmbeddedCheckoutModal() { 2584 var elements = ensureEmbeddedCheckoutModal(); 2585 2586 if (!elements) { 2587 return false; 2588 } 2589 2590 updateEmbeddedCheckoutModalIntro(); 2591 showEmbeddedCheckoutModalOverlay(); 2592 loadEmbeddedCheckoutModalIframe(); 2593 2594 return true; 2595} 2596 2597function goToCheckout(ignoreShowUpgrade = false) { 2598 trace(); 2599 console.log('gotocheckout', { ignoreShowUpgrade }); 2600 2601 // The pricing-checkout variant owns its full-page checkout. Its ticket CTA 2602 // already bypasses the legacy embedded modal; the shared floating cart bar 2603 // must do the same when (and only when) its cart matches that selection. 2604 var usePricingCheckoutV1 = 2605 typeof window.preparePricingCheckoutV1Handoff == 'function' && 2606 window.preparePricingCheckoutV1Handoff() === true; 2607 2608 let cartItemsData = []; 2609 2610 cart.items.map((cartItem) => { 2611 cartItemsData.push({ 2612 item_id: `${cartItem.bundleId}`, 2613 quantity: Number(cartItem.quantity), 2614 }); 2615 }); 2616 2617 gtag_and_microsoft_uet('event', 'begin_checkout', { 2618 currency: cy?.toUpperCase(), 2619 value: cart.total, 2620 items: [...cartItemsData], 2621 }); 2622 2623 setCookie('sch_cart', cart); 2624 setCookie('cart', cart); 2625 2626 if (!usePricingCheckoutV1 && isEmbeddedCheckoutModalEnabled()) { 2627 if (openEmbeddedCheckoutModal()) { 2628 return 'modal'; 2629 } 2630 } 2631 2632 var checkoutUrl = buildCheckoutUrl({ 2633 includeCartInQuery: true, 2634 }); 2635 2636 console.log({ checkoutUrl }); 2637 window.location.href = checkoutUrl; 2638 return 'redirect'; 2639} 2640 2641bindEmbeddedCheckoutModalWarmup(); 2642 2643// showing the cart on page load 2644var showConditions = 2645 (window.location.href.includes('cart') || 2646 window.location.href.includes('holiday') || 2647 (screen.width > 650 && window.location.href.includes('gift')) || 2648 ((screen.width > 650 || isCrossOrigin) && 2649 !slug_bundle && 2650 !isCrossOrigin)) && 2651 !window.location.href.includes('customize_your_giftcard'); 2652cart.showCart = false; 2653 2654function showCartClick(e) { 2655 if ( 2656 !window.location.href.includes('store') && 2657 (!cart.items || cart.items.length == 0) && 2658 WEBSITE_DOMAIN != 'afs' 2659 ) { 2660 console.log('going straight to store to save user a click'); 2661 return (window.location.href = base_url('/store')); 2662 } 2663 trace(); 2664 e.preventDefault(); 2665 cart.showCart = true; 2666 2667 // AB Test: Use modern cart view if redesign test is active 2668 if (getCookie('AB_LR_SCH_FULL_STORE_REDESIGN') === '1') { 2669 CartViewRender(); // Modern version from CartViewModern.js 2670 } else { 2671 CartViewRender(); // Original version from CartView.js 2672 } 2673} 2674 2675var showCartButtons = document.querySelectorAll('.showCart'); 2676showCartButtons.forEach(function (showCartButton) { 2677 showCartButton.onclick = showCartClick; 2678}); 2679 2680var rightButton = document.querySelector('#btnRightPanel'); 2681if (rightButton) { 2682 rightButton.onclick = showCartClick; 2683} 2684 2685var cart_total_currency = document.querySelectorAll('.cart_total_currency'); 2686cart_total_currency.forEach(function (item) { 2687 item.onclick = function (e) { 2688 e.preventDefault(); 2689 showCurrency = true; 2690 if (typeof window.lrModalAction === 'function') { 2691 lrModalAction('languageAndCurrencyModal', 'open'); 2692 } 2693 }; 2694}); 2695 2696function getFirstName(str) { 2697 trace(); 2698 if (!str) { 2699 return ''; 2700 } 2701 var arr = str.split(' '); 2702 if (arr.length === 1) { 2703 return arr[0]; 2704 } 2705 return arr.slice(0, -1).join(' '); // returns "Paul Steve" 2706} 2707 2708function getLastName(str, ifNone) { 2709 trace(); 2710 if (!str) { 2711 return ''; 2712 } 2713 var arr = str.split(' '); 2714 if (arr.length === 1) { 2715 return ifNone || '<None>'; 2716 } 2717 return arr.slice(-1).join(' '); 2718} 2719 2720function dataToURI(obj) { 2721 trace(); 2722 var str = []; 2723 for (var p in obj) 2724 if (obj.hasOwnProperty(p)) { 2725 // console.log({ p }); 2726 // correcting for pre-encoding of cookie 2727 var encodedData = 2728 p != 'cartOverride' ? encodeURIComponent(obj[p]) : obj[p]; 2729 str.push(encodeURIComponent(p) + '=' + encodedData); 2730 } 2731 return str.join('&'); 2732} 2733 2734if (typeof safeTippy != 'undefined' && !isCrossOrigin) { 2735 safeTippy('.tippy-info', { 2736 appendTo: 'parent', 2737 interactive: 'true', 2738 placement: 'right', 2739 animation: 'fade', 2740 animateFill: false, 2741 theme: 'kpi-tooltip', 2742 trigger: 'manual', 2743 interactive: true, 2744 onHidden: () => { 2745 tippyInstance.destroy(); 2746 }, 2747 allowHTML: true, 2748 appendTo: 'parent', 2749 }); 2750} 2751 2752ready(function () { 2753 initializeSchPaymentSdkIntent(); 2754 2755 if (typeof updateCurrencies == 'function') { 2756 updateCurrencies(); 2757 } 2758 2759 if ( 2760 window.location.href.includes('store') && 2761 slug_bundle && 2762 slug_bundle.bullet_description 2763 ) { 2764 console.log({ slug_bundle }); 2765 navigateToBundle(slug_bundle); 2766 } 2767 2768 // showing cart of bundles 2769 if (typeof showBundleOnLoad != 'undefined') { 2770 if (cart.items.length > 0) { 2771 cart.showCart = true; 2772 2773 // AB Test: Use modern cart view if redesign test is active 2774 if (getCookie('AB_LR_SCH_FULL_STORE_REDESIGN') === '1') { 2775 CartViewRender(); // Modern version from CartViewModern.js 2776 } else { 2777 CartViewRender(); // Original version from CartView.js 2778 } 2779 } else { 2780 navigateToBundle(getBundleInfo(showBundleOnLoad)); 2781 } 2782 } 2783 2784 if ( 2785 (window.location.href.includes('store') || 2786 window.location.href.includes('gift')) && 2787 !window.location.href.includes('receipt') 2788 ) { 2789 if (typeof fb_track_safe !== 'undefined') { 2790 ready(function () {
2791 fb_track_safe('track', 'StoreVisit'); 2792 }); 2793 } 2794 } 2795}); 2796 2797function updateCartStats() { 2798 // updating cart contents info 2799 cart.hasAnnualPass = 0; 2800 cart.annualPassCount = 0; 2801 cart.singleUseCount = 0; 2802 cart.hasIndividualTickets = 0; 2803 cart.hasSubscription = 0; 2804 cart.hasTrial = 0; 2805 cart.itemCount = 0; 2806 cart.items.map(function (cartItem) { 2807 const bundleInfo = getBundleInfo(cartItem.bundleId); 2808 const productInfo = getProductInfo(cartItem.productId); 2809 var cartItemQuantity = Math.max(1, Number(cartItem.quantity || 1) || 1); 2810 if (productInfo.plan_id) { 2811 cart.hasSubscription = 1; 2812 if (productInfo.trial_period_days) { 2813 cart.hasTrial = 1; 2814 cart.trialPeriodDays = productInfo.trial_period_days; 2815 } 2816 } 2817 console.log('updateCartStats', { cartItem, bundleInfo, productInfo }); 2818 if (bundleInfo.season_pass_tickets) { 2819 cart.hasAnnualPass = 1; 2820 cart.annualPassCount += cartItemQuantity; 2821 } else if (!cartItem.planId) { 2822 cart.hasIndividualTickets = 1; 2823 cart.singleUseCount += cartItemQuantity; 2824 } 2825 cart.itemCount += cartItemQuantity; 2826 }); 2827 2828 invalidateEmbeddedCheckoutModalSession(); 2829} 2830 2831function priceCart(discount_type = 'discounted') { 2832 var cartTotal = 0; 2833 cart.items.map((cartItem, index) => { 2834 var cost = calculateItemTotal(cartItem, cy, discount_type); 2835 const specialDiscount = cartItem.specialDiscount || ''; 2836 cartTotal += cost - specialDiscount; 2837 2838 if (discount_type == 'full') { 2839 cart.items[index].fullTotal = cost; 2840 } else if (discount_type == 'regular') { 2841 cart.items[index].regularTotal = cost - specialDiscount; 2842 } else if (discount_type == 'discounted') { 2843 cart.items[index].total = cost - specialDiscount; 2844 } 2845 }); 2846 2847 return cartTotal; 2848} 2849 2850function loadStripeAndQuickPay() { 2851 return loadStripeJsOnce() 2852 .then(function () { 2853 return loadQuickPayScriptOnce(); 2854 }) 2855 .catch(function (quickPayLoadError) { 2856 console.error('Unable to load Stripe quick pay', { 2857 quickPayLoadError, 2858 }); 2859 }); 2860}
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.