1<!doctype html> 2<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]--> 3<!--[if IE 7]><html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]--> 4<!--[if IE 8]><html class="no-js lt-ie9" lang="en"> <![endif]--> 5<!--[if IE 9 ]><html class="ie9 no-js"> <![endif]--> 6<!--[if (gt IE 9)|!(IE)]><!--> <html class="no-js"> <!--<![endif]--> 7<head> 8 9 <!-- Basic page needs ================================================== --> 10 <meta charset="utf-8"> 11 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 12 13 14 <link rel="icon" href="https://cdn.store-assets.com/s/485225/f/15541316.png" /> 15 16 17 <!-- Title and description ================================================== --> 18 <title> 19 Login – ZEAL RUNNING COMPANY 20 </title> 21 22 23 24 <!-- Social meta ================================================== --> 25 26 27 <meta property="og:type" content="website"> 28 <meta property="og:title" content="Login"> 29 <meta property="og:url" content="https://zealrunningcompany.com/account/login"> 30 31 <meta property="og:image" content="https://cdn.store-assets.com/s/485225/f/15541328.png?width=350&format=webp"> 32 <meta property="og:image:secure_url" content="https://cdn.store-assets.com/s/485225/f/15541328.png?width=350&format=webp"> 33 34 35 36<meta property="og:description" content="ZEAL RUNNING COMPANY"> 37<meta property="og:site_name" content="ZEAL RUNNING COMPANY"> 38 39 40 41 <meta name="twitter:card" content="summary"> 42 43 44 45 46 47 48 49 <!-- Helpers ================================================== --> 50 <link rel="canonical" href="https://zealrunningcompany.com/account/login"> 51 <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> 52 <meta name="theme-color" content=""> 53 54 <!-- CSS ================================================== --> 55 <link href="https://store-themes.easystore.co/485225/themes/1592/assets/timber.css?t=1787076082" rel="stylesheet" type="text/css" media="screen" /> 56 <link href="https://store-themes.easystore.co/485225/themes/1592/assets/theme.css?t=1787076082" rel="stylesheet" type="text/css" media="screen" /> 57 58 59 60 61 62 63
63<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" type="text/javascript" ></script>
63 64 <!-- Header hook for plugins ================================================== --> 65 66<!-- ScriptTags -->
67<script>window.__st={p: "customers",cid: null,cem: null,cph: null,cfn: null,cln: null,cge: null,cdb: null,ccc: null};</script>
67<script src='/assets/events.js'></script>
67<script>(function(){function asyncLoad(){var urls=['/assets/traffic.js?v=1'];for(var i=0;i<urls.length;i++){var s=document.createElement('script');s.type='text/javascript';s.async=true;s.src=urls[i];var x=document.getElementsByTagName('script')[0];x.parentNode.insertBefore(s, x);}}window.attachEvent ? window.attachEvent('onload', asyncLoad) : window.addEventListener('load', asyncLoad, false);})();</script>
67 68<!-- /ScriptTags --> 69 70 71 72<!--[if lt IE 9]>
73<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js" type="text/javascript" ></script>
vendor: 2 bytes, line 73
73
74<script src="https://store-themes.easystore.co/485225/themes/1592/assets/respond.min.js?t=1787076082" type="text/javascript" ></script>
74 75<link href="https://store-themes.easystore.co/485225/themes/1592/assets/respond-proxy.html" id="respond-proxy" rel="respond-proxy" /> 76<link href="//zealrunningcompany.com/search?q=253c481cc23378a02b6000f6e98ddb21" id="respond-redirect" rel="respond-redirect" />
77<script src="//zealrunningcompany.com/search?q=253c481cc23378a02b6000f6e98ddb21" type="text/javascript"></script>
77 78<![endif]--> 79 80 81 82
82<script src="https://store-themes.easystore.co/485225/themes/1592/assets/modernizr.min.js?t=1787076082" type="text/javascript" ></script>
82 83 84 85 86
86<script src="/assets/shop_common.js" type="text/javascript" ></script>
86 87
87<script src="/assets/customer_area.js" type="text/javascript" ></script>
87 88 89
89<script> 90 (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 91 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 92 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 93 })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); 94 95 ga('create', '', 'auto','myTracker'); 96 ga('myTracker.send', 'pageview'); 97 98 </script>
98 99 100</head> 101 102<body id="login" class="template-customers" > 103 104 <ul id="MobileNav" class="mobile-nav large--hide"> 105 106 107 108 <li class="mobile-nav__link" aria-haspopup="true"> 109 110 <a href="/" > 111 Home 112 </a> 113 114 </li> 115 116 117 <li class="mobile-nav__link" aria-haspopup="true"> 118 119 120 <a href="/collections/all" class="mobile-nav__parent-link"> 121 Catalog 122 </a> 123 <span class="mobile-nav__sublist-trigger"> 124 <span class="icon-fallback-text mobile-nav__sublist-expand"> 125 <span class="icon icon-plus" aria-hidden="true"></span> 126 <span class="fallback-text">+</span> 127</span> 128<span class="icon-fallback-text mobile-nav__sublist-contract"> 129 <span class="icon icon-minus" aria-hidden="true"></span> 130 <span class="fallback-text">-</span> 131</span> 132 133 </span> 134 <ul class="mobile-nav__sublist"> 135 136 137 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 138 139 <a href="/collections/no-off-season" > 140 NO OFF SEASON 141 </a> 142 143 </li> 144 145 146 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 147 148 <a href="/collections/we-run-the-streets" > 149 WE RUN THE STREETS 150 </a> 151 152 </li> 153 154 155 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 156 157 <a href="/collections/pb-killa-monster" > 158 PB KILLA 159 </a> 160 161 </li> 162 163 164 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 165 166 <a href="/collections/bad-air" > 167 BAD AIR 168 </a> 169 170 </li> 171 172 173 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 174 175 <a href="/collections/zeal-custom" > 176 ZEAL CUSTOM 177 </a> 178 179 </li> 180 181 182 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 183 184 <a href="/collections/zeal-x-vomos-airbreath" > 185 ZEAL x Vomos Airbreath+ 186 </a> 187 188 </li> 189 190 191 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 192 193 <a href="/collections/running-the-neighbourhood" > 194 RUNNING THE NEIGHBOURHOOD 195 </a> 196 197 </li> 198 199 200 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 201 202 <a href="/collections/zeal-we-shred-the-trails" > 203 WE SHRED THE TRAILS 204 </a> 205 206 </li> 207 208 209 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 210 211 <a href="/collections/3-suku-nyawa" > 212 TIGA SUKU NYAWA 213 </a> 214 215 </li> 216 217 218 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 219 220 <a href="/collections/zeal-pro-one" > 221 ZEAL PRO ONE 222 </a> 223 224 </li> 225 226 227 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 228 229 <a href="/collections/zeal-cult-of-speed" > 230 ZEAL 'CULT OF SPEED' 231 </a> 232 233 </li> 234 235 236 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 237 238 <a href="/collections/zeal-run-and-destroy" > 239 ZEAL RUN AND DESTROY 240 </a> 241 242 </li> 243 244 245 <li class="mobile-nav__sublist-link" aria-haspopup="true"> 246 247 <a href="/collections/zeal-x-adx-n-stuff-collab" > 248 ZEAL X ADX N STUFF COLLAB 249 </a> 250 251 </li> 252 253 </ul> 254 255 </li> 256 257 258 259 260 261 262 263 <li class="mobile-nav__link"> 264 <a href="/account/login">Log in</a> 265 </li> 266 267 <li class="mobile-nav__link"> 268 <a href="/account/register">Create account</a> 269 </li> 270 271 272 273 274 275 <li class="mobile-nav__link"> 276 277 278 279 280 281 </li> 282 283 284 <li class="mobile-nav__link header-bar__search-wrapper"> 285 286 <div class="header-bar__module header-bar__search"> 287 288 <a class="popup-with-form medium-down--hide" href="#test-form"> 289 <span class="icon icon-search" aria-hidden="true"></span> 290 </a> 291 <form action="/search" method="get" class="header-bar__search-form clearfix large--hide" role="search"> 292 293 <button type="submit" class="btn icon-fallback-text header-bar__search-submit">
294 <span class="icon icon-search" aria-hidden="true"></span> 295 <span class="fallback-text">Search</span> 296 </button> 297 <input type="search" name="q" value="" aria-label="Search" class="header-bar__search-input" placeholder="Search" autocomplete="off"> 298 <div class="dropdown" id="searchDropdown"></div> 299 <input type="hidden" name="search_history" id="search_history"> 300 </form> 301 302 303 304<!-- form itself --> 305<div id="test-form" class="white-popup-block mfp-hide popup-search"> 306 <div class="popup-search-content"> 307 <form action="/search" method="get" class="input-group search-bar" role="search"> 308 309 <input type="search" name="q" value="" placeholder="Search" class="input-group-field" aria-label="Search" placeholder="Search" autocomplete="off"> 310 <div class="dropdown" id="searchDropdown"></div> 311 <input type="hidden" name="search_history" id="search_history"> 312 <span class="input-group-btn"> 313 <button type="submit" class="btn icon-fallback-text"> 314 <span class="icon icon-search" aria-hidden="true"></span> 315 <span class="fallback-text">Search</span> 316 </button> 317 </span> 318 </form> 319 </div> 320</div> 321
322<script src="https://store-themes.easystore.co/485225/themes/1592/assets/magnific-popup.min.js?t=1787076082" type="text/javascript" ></script>
vendor: 1 bytes, line 322
322
323<script> 324$(document).ready(function() { 325 $('.popup-with-form').magnificPopup({ 326 type: 'inline', 327 preloader: false, 328 focus: '#name', 329 mainClass: 'popup-search-bg-wrapper', 330 331 // When elemened is focused, some mobile browsers in some cases zoom in 332 // It looks not nice, so we disable it: 333 callbacks: { 334 beforeOpen: function() { 335 if($(window).width() < 700) { 336 this.st.focus = false; 337 } else { 338 this.st.focus = '#name'; 339 } 340 } 341 } 342 }); 343}); 344</script>
344 345 346
347<script> 348 var _search_history_listings = "" 349 if(_search_history_listings != "") localStorage.setItem('searchHistory', JSON.stringify(_search_history_listings)); 350 351 function clearAll() { 352 localStorage.removeItem('searchHistory'); 353 354 var customer = ""; 355 if(customer) { 356 // Your logic to clear all data or call an endpoint 357 fetch('/account/search_histories', { 358 method: 'DELETE', 359 headers: { 360 "Content-Type": "application/json", 361 "X-Requested-With": "XMLHttpRequest" 362 }, 363 body: JSON.stringify({ 364 _token: "HeKmVdWeCUM4crjXSgLVQe9JPMMtVsBhjXSm9Rep" 365 }), 366 }) 367 .then(response => response.json()) 368 } 369 } 370 // End - store view history in local storage 371 372 // search history dropdown 373 var searchInputs = document.querySelectorAll('input[type=search]'); 374 375 if(searchInputs.length > 0) { 376 377 searchInputs.forEach((searchInput)=>{ 378 379 searchInput.addEventListener('focus', function() { 380 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 381 searchDropdown.innerHTML = ''; // Clear existing items 382 383 // retrieve data from local storage 384 var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || []; 385 386 // Convert JSON to string 387 var search_history_json = JSON.stringify(searchHistoryData); 388 389 // Set the value of the hidden input 390 searchInput.closest('form').querySelector("#search_history").value = search_history_json; 391 392 // create dropdown items 393 var clearAllItem = document.createElement('div'); 394 clearAllItem.className = 'dropdown-item clear-all'; 395 clearAllItem.textContent = 'Clear'; 396 clearAllItem.addEventListener('click', function() { 397 clearAll(); 398 searchDropdown.style.display = 'none'; 399 searchInput.classList.remove('is-focus'); 400 }); 401 searchDropdown.appendChild(clearAllItem); 402 403 // create dropdown items 404 searchHistoryData.forEach(function(item) { 405 var dropdownItem = document.createElement('div'); 406 dropdownItem.className = 'dropdown-item'; 407 dropdownItem.textContent = item.term; 408 dropdownItem.addEventListener('click', function() { 409 searchInput.value = item.term; 410 searchDropdown.style.display = 'none'; 411 }); 412 searchDropdown.appendChild(dropdownItem); 413 }); 414 415 if(searchHistoryData.length > 0){ 416 // display the dropdown 417 searchInput.classList.add('is-focus'); 418 document.body.classList.add('search-input-focus'); 419 searchDropdown.style.display = 'block'; 420 } 421 }); 422 423 searchInput.addEventListener("focusout", (event) => { 424 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 425 searchInput.classList.remove('is-focus'); 426 searchDropdown.classList.add('transparent'); 427 setTimeout(()=>{ 428 searchDropdown.style.display = 'none'; 429 searchDropdown.classList.remove('transparent'); 430 document.body.classList.remove('search-input-focus'); 431 }, 400); 432 }); 433 }) 434 } 435 // End - search history dropdown 436</script>
436 437 </div> 438 439 </li> 440 441 442</ul> 443<div id="MobileNavOutside" class="mobile-nav-outside"></div> 444 445 446<div id="PageContainer" class="page-container"> 447 448<!-- Snippet:global/body_start: Console Extension --> 449<div id='es_console' style='display: none;'>485225</div> 450<!-- /Snippet --> 451 452 453 <style> 454 .search-modal__form{ 455 position: relative; 456 } 457 458 .dropdown-wrapper { 459 position: relative; 460 } 461 462 .dropdown-wrapper:hover .dropdown { 463 display: block; 464 } 465 466 .header-icon-nav .dropdown { 467 left: -80px; 468 } 469 470 .dropdown { 471 display: none; 472 position: absolute; 473 top: 100%; 474 left: 0px; 475 width: 100%; 476 padding: 8px; 477 background-color: #fff; 478 z-index: 1000; 479 border-radius: 5px; 480 border: 1px solid rgba(var(--color-foreground), 1); 481 border-top: none; 482 overflow-x: hidden; 483 overflow-y: auto; 484 max-height: 350px; 485 min-width: 150px; 486 box-shadow: 0 0 5px rgba(0,0,0,0.1); 487 } 488 489 .dropdown a{ 490 text-decoration: none; 491 color: #000 !important; 492 } 493 494 .dropdown-item { 495 padding: 0.4rem 2rem; 496 cursor: pointer; 497 line-height: 1.4; 498 overflow: hidden; 499 text-overflow: ellipsis; 500 white-space: nowrap; 501 } 502 503 .dropdown-item:hover{ 504 background-color: #f3f3f3; 505 } 506 507 .search__input.is-focus{ 508 border-radius: 15px; 509 border-bottom-left-radius: 0; 510 border-bottom-right-radius: 0; 511 border: 1px solid rgba(var(--color-foreground), 1); 512 border-bottom: none; 513 box-shadow: none; 514 } 515 516 .clear-all { 517 text-align: right; 518 padding: 0 2rem 0.2rem; 519 line-height: 1; 520 font-size: 70%; 521 margin-bottom: -2px; 522 } 523 524 .clear-all:hover{ 525 background-color: #fff; 526 } 527 528 .referral-notification { 529 position: absolute; 530 top: 100%; 531 right: -12px; 532 background: white; 533 border: 1px solid #e0e0e0; 534 border-radius: 8px; 535 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 536 width: 280px; 537 z-index: 1000; 538 padding: 16px; 539 margin-top: 8px; 540 font-size: 14px; 541 line-height: 1.4; 542 } 543 544 .referral-notification::before { 545 content: ''; 546 position: absolute; 547 top: -8px; 548 right: 20px; 549 width: 0; 550 height: 0; 551 border-left: 8px solid transparent; 552 border-right: 8px solid transparent; 553 border-bottom: 8px solid white; 554 } 555 556 .referral-notification::after { 557 content: ''; 558 position: absolute; 559 top: -9px; 560 right: 20px; 561 width: 0; 562 height: 0; 563 border-left: 8px solid transparent; 564 border-right: 8px solid transparent; 565 border-bottom: 8px solid #e0e0e0; 566 } 567 568 .referral-notification h4 { 569 margin: 0 0 8px 0; 570 color: #2196F3; 571 font-size: 16px; 572 font-weight: 600; 573 } 574 575 .referral-notification p { 576 margin: 0 0 12px 0; 577 color: #666; 578 } 579 580 .referral-notification .referral-code { 581 background: #f5f5f5; 582 padding: 8px; 583 border-radius: 4px; 584 font-family: monospace; 585 font-size: 13px; 586 text-align: center; 587 margin: 8px 0; 588 border: 1px solid #ddd; 589 } 590 591 .referral-notification .close-btn { 592 position: absolute; 593 top: 8px; 594 right: 8px; 595 background: none; 596 border: none; 597 font-size: 18px; 598 color: #999; 599 cursor: pointer; 600 padding: 0; 601 width: 20px; 602 height: 20px; 603 line-height: 1; 604 } 605 606 .referral-notification .close-btn:hover { 607 color: #333; 608 } 609 610 .referral-notification .action-btn { 611 background: #2196F3; 612 color: white; 613 border: none; 614 padding: 8px 16px; 615 border-radius: 4px; 616 cursor: pointer; 617 font-size: 12px; 618 margin-right: 8px; 619 margin-top: 8px; 620 } 621 622 .referral-notification .action-btn:hover { 623 background: #1976D2; 624 } 625 626 .referral-notification .dismiss-btn { 627 background: transparent; 628 color: #666; 629 border: 1px solid #ddd; 630 padding: 8px 16px; 631 border-radius: 4px; 632 cursor: pointer; 633 font-size: 12px; 634 margin-top: 8px; 635 } 636 637 .referral-notification .dismiss-btn:hover { 638 background: #f5f5f5; 639 } 640 .referral-modal__dialog { 641 transform: translate(-50%, 0); 642 transition: transform var(--duration-default) ease, visibility 0s; 643 z-index: 10000; 644 position: fixed; 645 top: 20vh; 646 left: 50%; 647 width: 100%; 648 max-width: 350px; 649 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 650 border-radius: 12px; 651 background-color: #fff; 652 color: #000; 653 padding: 20px; 654 text-align: center; 655 } 656 .modal-overlay.referral-modal-overlay { 657 position: fixed; 658 top: 0; 659 left: 0; 660 width: 100%; 661 height: 100%; 662 background-color: rgba(0, 0, 0, 0.7); 663 z-index: 2001; 664 display: block; 665 opacity: 1; 666 transition: opacity var(--duration-default) ease, visibility 0s; 667 } 668</style> 669 670<header class="header-bar"> 671 <div class="header-wrapper wrapper"> 672 673 <!-- Mobile hamburger --> 674 <div class="large--hide"> 675 <button type="button" class="mobile-nav-trigger" id="MobileNavTrigger">
676 <span class="icon icon-hamburger" aria-hidden="true"></span> 677 </button> 678 </div> 679 680 <div class="logo-header" role="banner"> 681 682 683 <div class="h1 site-header__logo" itemscope itemtype="http://schema.org/Organization"> 684 685 686 687 688 689 <a href="/" class="logo-wrapper" itemprop="url"> 690 <img src="https://cdn.store-assets.com/s/485225/f/15541328.png?width=350&format=webp" alt="ZEAL RUNNING COMPANY" itemprop="logo"> 691 </a> 692 693 694 695 696 697 </div> 698 699 700 </div> 701 702 <div class="desktop-header-nav medium-down--hide"> 703 704 <div class="header-nav-bar"> 705 706<ul class="site-nav" id="AccessibleNav"> 707 708 709 710 <li > 711 <a href="/" class="site-nav__link">Home</a> 712 </li> 713 714 715 716 717 718 <li class="site-nav--has-dropdown" aria-haspopup="true"> 719 <a href="/collections/all" class="site-nav__link"> 720 Catalog 721 <span class="icon-fallback-text"> 722 <span class="icon icon-arrow-down" aria-hidden="true"></span> 723 </span> 724 </a> 725 <ul class="site-nav__dropdown"> 726 727 728 729 <li > 730 <a href="/collections/no-off-season" class="site-nav__link">NO OFF SEASON</a> 731 </li> 732 733 734 735 736 <li > 737 <a href="/collections/we-run-the-streets" class="site-nav__link">WE RUN THE STREETS</a> 738 </li> 739 740 741 742 743 <li > 744 <a href="/collections/pb-killa-monster" class="site-nav__link">PB KILLA</a> 745 </li> 746 747 748 749 750 <li > 751 <a href="/collections/bad-air" class="site-nav__link">BAD AIR</a> 752 </li> 753 754 755 756 757 <li > 758 <a href="/collections/zeal-custom" class="site-nav__link">ZEAL CUSTOM</a> 759 </li> 760 761 762 763 764 <li > 765 <a href="/collections/zeal-x-vomos-airbreath" class="site-nav__link">ZEAL x Vomos Airbreath+</a> 766 </li> 767 768 769 770 771 <li > 772 <a href="/collections/running-the-neighbourhood" class="site-nav__link">RUNNING THE NEIGHBOURHOOD</a> 773 </li> 774 775 776 777 778 <li > 779 <a href="/collections/zeal-we-shred-the-trails" class="site-nav__link">WE SHRED THE TRAILS</a> 780 </li> 781 782 783 784 785 <li > 786 <a href="/collections/3-suku-nyawa" class="site-nav__link">TIGA SUKU NYAWA</a> 787 </li> 788 789 790 791 792 <li > 793 <a href="/collections/zeal-pro-one" class="site-nav__link">ZEAL PRO ONE</a> 794 </li> 795 796 797 798 799 <li > 800 <a href="/collections/zeal-cult-of-speed" class="site-nav__link">ZEAL 'CULT OF SPEED'</a> 801 </li> 802 803 804 805 806 <li > 807 <a href="/collections/zeal-run-and-destroy" class="site-nav__link">ZEAL RUN AND DESTROY</a> 808 </li> 809 810 811 812 813 <li > 814 <a href="/collections/zeal-x-adx-n-stuff-collab" class="site-nav__link">ZEAL X ADX N STUFF COLLAB</a> 815 </li> 816 817 818 </ul> 819 </li> 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834</ul> 835 836 </div> 837 838 <div class="header-subnav"> 839 840 841 842 843 844 845 846 <div class="header-icon-nav"> 847 848 849 850 851 852 853 854 855 <div class="header-bar__module"> 856 857 <a class="popup-with-form medium-down--hide" href="#test-form"> 858 <span class="icon icon-search" aria-hidden="true"></span> 859 </a> 860 <form action="/search" method="get" class="header-bar__search-form clearfix large--hide" role="search"> 861 862 <button type="submit" class="btn icon-fallback-text header-bar__search-submit">
863 <span class="icon icon-search" aria-hidden="true"></span> 864 <span class="fallback-text">Search</span> 865 </button> 866 <input type="search" name="q" value="" aria-label="Search" class="header-bar__search-input" placeholder="Search" autocomplete="off"> 867 <div class="dropdown" id="searchDropdown"></div> 868 <input type="hidden" name="search_history" id="search_history"> 869 </form> 870 871 872 873<!-- form itself --> 874<div id="test-form" class="white-popup-block mfp-hide popup-search"> 875 <div class="popup-search-content"> 876 <form action="/search" method="get" class="input-group search-bar" role="search"> 877 878 <input type="search" name="q" value="" placeholder="Search" class="input-group-field" aria-label="Search" placeholder="Search" autocomplete="off"> 879 <div class="dropdown" id="searchDropdown"></div> 880 <input type="hidden" name="search_history" id="search_history"> 881 <span class="input-group-btn"> 882 <button type="submit" class="btn icon-fallback-text"> 883 <span class="icon icon-search" aria-hidden="true"></span> 884 <span class="fallback-text">Search</span> 885 </button> 886 </span> 887 </form> 888 </div> 889</div> 890
891<script src="https://store-themes.easystore.co/485225/themes/1592/assets/magnific-popup.min.js?t=1787076082" type="text/javascript" ></script>
vendor: 1 bytes, line 891
891
892<script> 893$(document).ready(function() { 894 $('.popup-with-form').magnificPopup({ 895 type: 'inline', 896 preloader: false, 897 focus: '#name', 898 mainClass: 'popup-search-bg-wrapper', 899 900 // When elemened is focused, some mobile browsers in some cases zoom in 901 // It looks not nice, so we disable it: 902 callbacks: { 903 beforeOpen: function() { 904 if($(window).width() < 700) { 905 this.st.focus = false; 906 } else { 907 this.st.focus = '#name'; 908 } 909 } 910 } 911 }); 912}); 913</script>
913 914 915
916<script> 917 var _search_history_listings = "" 918 if(_search_history_listings != "") localStorage.setItem('searchHistory', JSON.stringify(_search_history_listings)); 919 920 function clearAll() { 921 localStorage.removeItem('searchHistory'); 922 923 var customer = ""; 924 if(customer) { 925 // Your logic to clear all data or call an endpoint 926 fetch('/account/search_histories', { 927 method: 'DELETE', 928 headers: { 929 "Content-Type": "application/json", 930 "X-Requested-With": "XMLHttpRequest" 931 }, 932 body: JSON.stringify({ 933 _token: "HeKmVdWeCUM4crjXSgLVQe9JPMMtVsBhjXSm9Rep" 934 }), 935 }) 936 .then(response => response.json()) 937 } 938 } 939 // End - store view history in local storage 940 941 // search history dropdown 942 var searchInputs = document.querySelectorAll('input[type=search]'); 943 944 if(searchInputs.length > 0) { 945 946 searchInputs.forEach((searchInput)=>{ 947 948 searchInput.addEventListener('focus', function() { 949 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 950 searchDropdown.innerHTML = ''; // Clear existing items 951 952 // retrieve data from local storage 953 var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || []; 954 955 // Convert JSON to string 956 var search_history_json = JSON.stringify(searchHistoryData); 957 958 // Set the value of the hidden input 959 searchInput.closest('form').querySelector("#search_history").value = search_history_json; 960 961 // create dropdown items 962 var clearAllItem = document.createElement('div'); 963 clearAllItem.className = 'dropdown-item clear-all'; 964 clearAllItem.textContent = 'Clear'; 965 clearAllItem.addEventListener('click', function() { 966 clearAll(); 967 searchDropdown.style.display = 'none'; 968 searchInput.classList.remove('is-focus'); 969 }); 970 searchDropdown.appendChild(clearAllItem); 971 972 // create dropdown items 973 searchHistoryData.forEach(function(item) { 974 var dropdownItem = document.createElement('div'); 975 dropdownItem.className = 'dropdown-item'; 976 dropdownItem.textContent = item.term; 977 dropdownItem.addEventListener('click', function() { 978 searchInput.value = item.term; 979 searchDropdown.style.display = 'none'; 980 }); 981 searchDropdown.appendChild(dropdownItem); 982 }); 983 984 if(searchHistoryData.length > 0){ 985 // display the dropdown 986 searchInput.classList.add('is-focus'); 987 document.body.classList.add('search-input-focus'); 988 searchDropdown.style.display = 'block'; 989 } 990 }); 991 992 searchInput.addEventListener("focusout", (event) => { 993 var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown'); 994 searchInput.classList.remove('is-focus'); 995 searchDropdown.classList.add('transparent'); 996 setTimeout(()=>{ 997 searchDropdown.style.display = 'none'; 998 searchDropdown.classList.remove('transparent'); 999 document.body.classList.remove('search-input-focus'); 1000 }, 400); 1001 }); 1002 }) 1003 } 1004 // End - search history dropdown 1005</script>
1005 1006 </div> 1007 1008 1009 1010 1011 <div class="header-bar__module dropdown-wrapper"> 1012 1013 <a href="/account/login"> 1014 1015 1016 1017 <svg class="svg-icon" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><title>icon-profile</title><path d="M50,51.8A24.4,24.4,0,1,0,25.6,27.4,24.43,24.43,0,0,0,50,51.8ZM50,10A17.4,17.4,0,1,1,32.6,27.4,17.43,17.43,0,0,1,50,10Z"/><path d="M62.66,57.66H37.34a30.54,30.54,0,0,0-30.5,30.5V93.5a3.5,3.5,0,0,0,3.5,3.5H89.66a3.5,3.5,0,0,0,3.5-3.5V88.16A30.54,30.54,0,0,0,62.66,57.66ZM86.16,90H13.84V88.16a23.53,23.53,0,0,1,23.5-23.5H62.66a23.53,23.53,0,0,1,23.5,23.5Z"/></svg> 1018 1019 1020</a> 1021 1022 1023 <!-- Referral Notification Popup for Desktop --> 1024 <div id="referralNotification" class="referral-notification" style="display: none;"> 1025 <button class="close-btn" onclick="dismissReferralNotification()">×</button> 1026 <div style="text-align: center; margin-bottom: 16px;"> 1027 <div style="width: 100px; height: 100px; margin: 0 auto;"> 1028 <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg"> 1029 </div> 1030 </div> 1031 <p id="referralSignupMessage" style="text-align: center; font-size: 14px; color: #666; margin: 0 0 20px 0;"> 1032 Your friend gifted you credit! Sign up now to redeem. 1033 </p> 1034 <div style="text-align: center;"> 1035 <button class="btn" onclick="goToSignupPage()" style="width: 100%; color: #fff;"> 1036 Sign Up 1037 </button> 1038 </div> 1039 </div> 1040 </div> 1041 1042 1043 <div class="header-bar__module cart-page-link-wrapper"> 1044 <span class="header-bar__sep" aria-hidden="true"></span> 1045 <a href="/cart" class="cart-page-link"> 1046 <span class="icon icon-cart header-bar__cart-icon" aria-hidden="true"></span> 1047 <span class="cart-count header-bar__cart-count hidden-count">0</span> 1048 </a> 1049 </div> 1050 1051 1052 1053 1054 1055 1056 1057 </div> 1058 </div> 1059 1060 1061 1062 </div> 1063 1064 1065 1066 <!-- Mobile cart --> 1067 <div class="large--hide"> 1068 <a href="/cart" class="cart-page-link mobile-cart-page-link"> 1069 <span class="icon icon-cart header-bar__cart-icon" aria-hidden="true"></span> 1070 <span class="cart-count hidden-count">0</span> 1071 </a> 1072 </div> 1073 1074 </div> 1075 1076 1077 1078</header> 1079 1080 1081 1082 1083 1084 <main class="wrapper main-content" role="main"> 1085 <div class="grid"> 1086 <div class="grid__item">
vendor: 100 bytes, lines 1086-1090
1086 1087 1088 1089 1090<script src="https://www.recaptcha.net/recaptcha/enterprise.js?render=
10906LdMNdIqAAAAALegJp7y4weVcCIlnwmIN8TWseEF
vendor: 12 bytes, line 1090
1090"></script>
1091<link rel="preload" href="https://store-themes.easystore.co/485225/themes/1592/assets/customer.css?t=1787076082" as="style" onload="this.onload=null;this.rel='stylesheet'"> 1092<style> 1093 main.main-content .field > label{ 1094 display: none; 1095 } 1096 .h3{ 1097 font-size: 18px; 1098 } 1099 .button--full-width{ 1100 width: 100%; 1101 } 1102 .tab-wrapper{ 1103 display: inline-flex; 1104 justify-content: center; 1105 align-items: center; 1106 margin: 10px auto 20px; 1107 background-color: #eaeaea; 1108 border-radius: 200px; 1109 padding: 5px; 1110 gap: 10px; 1111 } 1112 .tab-wrapper .tab-label { 1113 display: inline-block; 1114 min-width: 130px; 1115 padding: 8px 15px; 1116 border-radius: 100px; 1117 cursor: pointer; 1118 font-size: 17px; 1119 line-height: 1.1; 1120 user-select: none; 1121 margin: 0; 1122 color: #000; 1123 } 1124 #register-tos a { 1125 display: inline; 1126 } 1127 @media screen and (max-width: 400px){ 1128 .tab-wrapper .tab-label { 1129 min-width: 110px; 1130 } 1131 } 1132 .tab-wrapper input[type='radio']:checked + .tab-label { 1133 background-color: #fff; 1134 box-shadow: 2px 2px 25px -10px #333; 1135 } 1136 1137 @media screen and (min-width: 500px){ 1138 .large--five-twelfths{ 1139 min-width: 420px; 1140 } 1141 } 1142</style> 1143 1144 1145 1146 1147<div class="customer login section-width-control small-width large--five-twelfths text-center wrapper"> 1148 <div class="card"> 1149 <h1 id="login" tabindex="-1" class="mb-0"> 1150 Welcome 1151 </h1> 1152 <p class="h3 mt-0"> 1153 1154 Sign up or log in to continue 1155 1156 </p> 1157 <div> 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 <div class="tab-wrapper"> 1176 <div> 1177 <input type="radio" name="type" id="tab-register" class="hide hidden" checked> 1178 <label for="tab-register" class="tab-label"> 1179 Sign up 1180 </label> 1181 </div> 1182 <div> 1183 <input type="radio" name="type" id="tab-login" class="hide hidden"> 1184 <label for="tab-login" class="tab-label"> 1185 Login 1186 </label> 1187 </div> 1188 </div> 1189 1190 1191 <form id="form-login" action="/account/auth" method="post" class="mt-2"> 1192 <input type="hidden" name="_token" value="HeKmVdWeCUM4crjXSgLVQe9JPMMtVsBhjXSm9Rep"> 1193 <input type="hidden" name="location_id" value=""> 1194 <input type="hidden" name="staff_id" value=""> 1195 <input type="hidden" id="recaptchaResponse" name="g-recaptcha-response"> 1196 1197 1198 <div id="error-content"></div> 1199 1200 <div class="field"> 1201 <input 1202 type="text" 1203 name="customer[email_or_phone]" 1204 id="CustomerDetail" 1205 autocorrect="off" 1206 autocapitalize="off" 1207 placeholder="Email" 1208 required 1209 > 1210 <label for="CustomerDetail"> 1211 Email 1212 </label> 1213 </div> 1214 1215 <button 1216 type="submit" 1217 form="form-login" 1218 class="btn button--full-width g-recaptcha"> 1219 Continue 1220 </button> 1221 1222 <div class="button-snippet"> 1223 1224 </div> 1225 1226 1227 1228 <div id="register-tos"> 1229 By signing up, I agree to the ZEAL RUNNING COMPANY's <a target="_blank" href="/legal/terms-of-service">Terms of Service</a>, <a target="_blank" href="/legal/privacy-policy">Privacy Policy</a> and <a target="_blank" href="/legal/refund-policy">Refund Policy</a>. 1230 </div> 1231 1232 </form> 1233 </div> 1234 </div> 1235 1236</div> 1237 1238 1239
1240<script> 1241 const register_tab = document.querySelector('#tab-register'); 1242 const login_tab = document.querySelector('#tab-login'); 1243 const register_tos = document.querySelector('#register-tos'); 1244 const isRegistrationEnabled = "1"; 1245 1246 if (register_tab) { 1247 register_tab.addEventListener('click', function() { 1248 if (register_tos) { 1249 register_tos.style.display = 'block'; 1250 } 1251 }); 1252 } 1253 if (login_tab) { 1254 login_tab.addEventListener('click', function() { 1255 if (register_tos) { 1256 register_tos.style.display = 'none'; 1257 } 1258 }); 1259 } 1260 1261 const methodSwitchBtn = document.getElementById('phone-login-btn'); 1262 if (methodSwitchBtn) { 1263 methodSwitchBtn.onclick = function () { 1264 var type = (register_tab && register_tab.checked) ? 'register' : 'login'; 1265 window.location.href = '/account/login?method=phone&type=' + type; 1266 }; 1267 } 1268 1269 let lastPathSegment = window.location.pathname.split('/').filter(segment => segment.length > 0).pop(); 1270 1271 // Redirect to login if trying to access register when self registration is disabled 1272 if (!isRegistrationEnabled) { 1273 if (lastPathSegment === 'register') { 1274 window.location.href = '/account/login'; 1275 } else if (lastPathSegment === 'login' || lastPathSegment === 'auth') { 1276 if (register_tos) { 1277 register_tos.style.display = 'none'; 1278 } 1279 } 1280 } else { 1281 // Only proceed with tab logic if not redirecting 1282 if(lastPathSegment === 'login') { 1283 if (login_tab) { 1284 login_tab.checked = true; 1285 } 1286 if (register_tos) { 1287 register_tos.style.display = 'none'; 1288 } 1289 } else { 1290 if (register_tos) { 1291 register_tos.style.display = 'block'; 1292 } 1293 } 1294 } 1295 1296 const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; 1297 const phonePattern = /^(?:\+?\d{1,3}[\s-]?)?(?:\d{1,14}[\s-]?){1,5}$/; 1298 1299 let form = document.querySelector('#form-login'), 1300 input = document.querySelector('#CustomerDetail'), 1301 error_content = document.querySelector('#error-content'); 1302 1303 1304 // One attempt at a time: the reCAPTCHA wait below is async, so without 1305 // this a double-click starts two continuations and posts the form twice. 1306 var submitting = false; 1307 1308 form.addEventListener('submit', async function (event) { 1309 // preventDefault FIRST: a re-entrant submit must still be cancelled, or the 1310 // browser performs a native post with no captcha token. 1311 event.preventDefault(); 1312 if (submitting) return; 1313 1314 let input_value = input.value 1315 error_content.innerHTML = ''; 1316 if (!input_value.match(emailPattern) && !input_value.match(phonePattern)) { 1317 error_content.innerHTML = `<div class="errors note">Invalid Email or Phone</div>`; 1318 return false; 1319 } 1320 1321 submitting = true; 1322 document.querySelector('#form-login .btn').classList.add('btn--loading','loading'); 1323 1324 // reCAPTCHA is unreachable from some regions (google.com is blocked in 1325 // mainland China). Fail open the same way checkout and forgot-password do: 1326 // submit without a token rather than leave the button spinning forever. 1327 try { 1328 if (window.grecaptcha && typeof window.grecaptcha.enterprise === 'object') { 1329 // The loader defines a stub {ready} synchronously and fetches the real 1330 // implementation asynchronously, so execute() may not exist yet. 1331 // ready() queues until it does; the timeout stops a bundle that never 1332 // arrives from hanging the button. 1333 await new Promise(function (resolve) { 1334 setTimeout(resolve, 3000); 1335 try { grecaptcha.enterprise.ready(resolve); } catch (e) { resolve(); } 1336 }); 1337 1338 const token = await grecaptcha.enterprise.execute('6LdMNdIqAAAAALegJp7y4weVcCIlnwmIN8TWseEF', { action: 'LOGIN' }); 1339 document.getElementById('recaptchaResponse').value = token; 1340 } 1341 } catch (e) { /* fail open */ } 1342 1343 document.getElementById('form-login').submit(); 1344 }); 1345 1346 1347</script>
1347 1348 1349 1350 1351 </div> 1352 </div> 1353 1354 </main> 1355 1356 <footer class="site-footer small--text-center" role="contentinfo"> 1357 1358 <div class="wrapper"> 1359 1360 <div class="grid-uniform"> 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 <div class="grid__item large--one-half medium--one-half"> 1383 1384 <h4>Quick Links</h4> 1385 1386 <ul class="site-footer__links"> 1387 1388 <li><a href="/a/contact-form" >Contact us</a></li> 1389 1390 1391 </ul> 1392 </div> 1393 1394 1395 1396 <div class="grid__item large--one-half medium--one-half"> 1397 <h4>Follow Us</h4> 1398 1399 <ul class="inline-list social-icons"> 1400 1401 1402 <li> 1403 <a class="icon-fallback-text" href="https://www.facebook.com/ZEAL-Running-Company-128912228905778" title="ZEAL RUNNING COMPANY on Facebook" target="_blank"> 1404 1405 1406 1407 1408 <svg xmlns="http://www.w3.org/2000/svg" class="facebook-icon-svg social-icon-svg" viewBox="0 0 1024 1024"> 1409 <title>icon-facebook</title> 1410 <path d="M837.66,223.9a33.73,33.73,0,0,0-3.11-15c-6.78-13.85-17.87-21.09-33.37-21.09q-288.46,0-576.91,0c-.62,0-1.24,0-1.85,0a34.51,34.51,0,0,0-25.88,12.11c-6.31,7.13-8.85,15.57-8.85,25.07q.08,287.7,0,575.4c0,1,0,1.9,0,2.86A32.93,32.93,0,0,0,190,814.71c4.45,11.79,16.3,23.11,35,23.1q153.61-.1,307.24,0c2.36,0,2.36,0,2.36-2.37q0-123.3,0-246.6c0-2.55,0-2.55-2.53-2.55H452.27c-2.26,0-2.26,0-2.26-2.17v-96.3h84.63v-2.46c0-22.12-.11-44.24.06-66.36.07-8.29.57-16.59,1.28-24.85a129.58,129.58,0,0,1,7.43-33c10.86-30,30.59-51.74,60-64.51A133.44,133.44,0,0,1,653,285.82c12.45-.37,24.93,0,37.38.34,9.64.27,19.27.95,28.9,1.6,5.36.36,10.7,1.07,16.06,1.5,1.46.12,1.65.75,1.65,2q0,42.2,0,84.39c0,.59-.06,1.18-.09,1.85h-2.39c-16.28,0-32.56,0-48.84.05-7.63,0-15.23.54-22.65,2.61-11.61,3.23-19.86,10.09-23.65,21.78a55.66,55.66,0,0,0-2.74,16.86c-.14,22.23-.1,44.47-.13,66.7,0,2.25,0,2.25,2.31,2.25h94.66a15.13,15.13,0,0,1,0,1.54c-.38,2.94-.81,5.88-1.18,8.82-1.17,9.16-2.3,18.33-3.48,27.5-1.29,10-2.63,20-3.94,30-1.23,9.44-2.43,18.88-3.67,28.32-.31,2.32-.35,2.32-2.78,2.32h-79a4.62,4.62,0,0,0-1.67,0,2.5,2.5,0,0,0-1.2,1.16,3.68,3.68,0,0,0,0,1.49V835.21c0,2.56,0,2.56,2.53,2.56H797.83c2.13,0,4.27-.07,6.39-.21,11.56-.78,20.61-6.07,27.23-15.48,4.66-6.6,6.24-14.09,6.24-22.11q-.06-287.19,0-574.38Z" fill="#999"/> 1411 </svg> 1412 1413 1414 1415 <span class="fallback-text">Facebook</span> 1416 </a> 1417 </li> 1418 1419 1420 1421 1422 <li> 1423 <a class="icon-fallback-text" href="https://www.instagram.com/run_with_zeal/" title="ZEAL RUNNING COMPANY on Instagram" target="_blank"> 1424 1425 1426 1427 1428 <svg xmlns="http://www.w3.org/2000/svg" class="instagram-icon-svg social-icon-svg" viewBox="0 0 1024 1024"> 1429 <title>icon-instagram</title> 1430 <path d="M834.35,341.22a231.23,231.23,0,0,0-9.59-46.45,166.71,166.71,0,0,0-52.17-78.33c-17-14.41-36.33-24.44-57.44-31.3-21.52-7-43.69-10.21-66.19-11.12-22.28-.9-44.58-1.73-66.87-1.85-47.68-.26-95.37-.16-143.06,0-27.47.11-54.95.69-82.32,3.39a220.7,220.7,0,0,0-37.43,6.95c-26.2,7.26-50,19-70.24,37.45-18.06,16.4-32.3,35.52-41.87,58.05-9.89,23.29-15.13,47.68-16.69,72.82-1.23,19.78-2.06,39.6-2.32,59.41-.38,28.91-.1,57.82-.1,86.73-.23,39.92-.67,79.85,1,119.76.72,17.66,1.57,35.3,4.6,52.76,3.22,18.52,8.32,36.51,16.71,53.34C232.83,768,268.81,797,317.12,811a246.28,246.28,0,0,0,59.24,9.11c25.3.95,50.63,1.78,75.95,1.94,43.83.28,87.66.1,131.5,0,26-.08,52.08-.72,78.06-2.74a234.52,234.52,0,0,0,45.76-8c24.54-6.92,46.82-18.12,66.22-34.79,24.65-21.17,41.5-47.44,51.3-78.36,6.7-21.14,9.83-42.88,10.73-64.94.9-21.84,1.73-43.69,1.82-65.55q.33-78.21-.15-156.44C837.42,387.82,836.72,364.47,834.35,341.22Zm-55.3,232.84c-.12,20.41-1,40.84-2,61.24-1,19.2-4.13,38.08-11.74,55.92q-18.43,43.24-62.47,60c-14.36,5.48-29.3,8.3-44.55,9.53-27.07,2.18-54.21,2.63-81.36,2.73-21.31.07-42.62,0-63.93,0v-.16c-28.47,0-56.94.22-85.4-.09-17.5-.18-35-1-52.49-1.89-19.94-1-39.51-4.31-57.95-12.38q-41.6-18.2-58-60.68a162.37,162.37,0,0,1-9.95-45.62c-2-24.66-2.62-49.38-2.66-74.1-.09-50.88-.16-101.77.12-152.65.11-19,1-38.09,2-57.11a180,180,0,0,1,8.78-48.23c8.32-24.84,23.63-44.14,45.66-58.12,11.78-7.48,24.85-11.91,38.36-15,15.57-3.61,31.43-4.65,47.34-5.32,54.32-2.28,108.68-1.46,163-1.5,18.67,0,37.34.12,56,.56,15.84.38,31.7,1,47.51,2,18.33,1.18,36.27,4.59,53.19,12q41.67,18.25,58.1,60.83c5.67,14.7,8.64,30,9.91,45.63,2,25,2.63,50,2.67,75.09C779.25,475.82,779.35,524.94,779.05,574.06Z" fill="#999"/><path d="M513,330.12c-92-.34-167,74.55-167.08,166.87s74.71,167,167,167A166.86,166.86,0,0,0,679.77,497.12C679.87,405,605.46,330.45,513,330.12Zm-.29,275.31A108.38,108.38,0,1,1,621.21,497.15,108.38,108.38,0,0,1,512.7,605.43Z" fill="#999"/><path d="M686.47,284.5a39,39,0,1,0,38.92,39.14A39,39,0,0,0,686.47,284.5Z" fill="#999"/> 1431 </svg> 1432 1433 1434
1435 <span class="fallback-text">Instagram</span> 1436 </a> 1437 </li> 1438 1439 1440 1441 1442 1443 1444 <li> 1445 <a class="icon-fallback-text" href="https://whatsapp.com/" title="ZEAL RUNNING COMPANY on Whatsapp" target="_blank"> 1446 1447 1448 1449 1450 <svg xmlns="http://www.w3.org/2000/svg" class="whatsapp-icon-svg social-icon-svg" viewBox="0 0 1024 1024"> 1451 <title>icon-whatsapp</title> 1452 <path d="M816.7,348.82A345.81,345.81,0,0,0,694.1,218.71c-44.79-28-93.6-44.39-146.07-49.88a345.45,345.45,0,0,0-92,2.72,339.05,339.05,0,0,0-94.38,29.87A343.85,343.85,0,0,0,238,302.05Q177.25,381,167.56,480.22a345,345,0,0,0,43.29,203.46,6.68,6.68,0,0,1,.57,4.56q-16.36,60.35-32.93,120.63c-5.08,18.56-10.2,37.12-15.43,56.13,1.15-.24,1.8-.34,2.43-.51Q254.72,841.08,344,817.7a7.88,7.88,0,0,1,4.84.57c11.92,5.41,23.56,11.5,35.68,16.39a344.42,344.42,0,0,0,274.43-8.3,343.9,343.9,0,0,0,122.89-97q64.35-80.48,74.57-183.1a344.59,344.59,0,0,0-2.88-89.12A336.49,336.49,0,0,0,816.7,348.82ZM799.12,528.11c-3.35,60.82-23.74,115.33-61.56,163C695.72,743.88,641.71,778,576.15,793.47A277.11,277.11,0,0,1,491.09,800a284.89,284.89,0,0,1-129.36-41.68,16.37,16.37,0,0,0-14.17-2c-33.08,8.93-66.26,17.47-99.4,26.13-.46.12-.93.19-2,.42,1.61-5.94,3.07-11.39,4.56-16.83q11.91-43.44,23.73-86.9a6.64,6.64,0,0,0-.91-4.73c-11.53-18-21.73-36.58-29.45-56.51a287.49,287.49,0,0,1-17.41-68.71c-5.7-46-.87-90.81,15-134.35a287.26,287.26,0,0,1,479.82-98.72c32.53,34.66,55.29,74.85,67.86,120.72A284,284,0,0,1,799.12,528.11Z" fill="#999"/><path d="M679.23,590c-12.9-6.08-25.57-12.63-38.44-18.75-10.69-5.09-21.41-10.15-32.36-14.63-8.48-3.47-12.2-1.6-17.82,5.65-8.75,11.27-17.79,22.32-26.93,33.28-4.38,5.25-8.82,6.33-15,3.54-11.48-5.18-23.13-10.16-34.09-16.32C477.68,562,449.73,532.17,428.22,496c-4.54-7.64-4-11.33,2-17.83,8.45-9.23,17.15-18.29,22.45-29.93a16.29,16.29,0,0,0,.44-13.68c-8.9-21.42-17.75-42.87-26.8-64.23a70.6,70.6,0,0,0-6.52-11.83c-2.39-3.56-6.15-5.12-10.51-5-3.28,0-6.56,0-9.84,0,0-.17,0-.34,0-.52-5.1.27-10.26.1-15.27.89-8.07,1.27-14,6.29-19.53,12.06-23.72,24.67-32.22,53.95-26.71,87.44a135.88,135.88,0,0,0,19.34,50.09c9.28,14.85,19.38,29.25,29.94,43.23a405.65,405.65,0,0,0,65.73,68.21c29.34,24.26,62.45,41.51,98.38,53.66,15,5.07,29.89,10.33,46,10.64,10.73.21,21.46.08,31.83-3a103.21,103.21,0,0,0,39.24-22c5.11-4.48,9.77-9.49,12.29-15.89a103.2,103.2,0,0,0,7.06-34.67C687.88,597,685.22,592.79,679.23,590Z" fill="#999"/> 1453 </svg> 1454 1455 1456 1457 <span class="fallback-text">Whatsapp</span> 1458 </a> 1459 </li> 1460 1461 1462 1463 1464</ul> 1465 1466 </div> 1467 1468 </div> 1469 1470 <hr class="hr--small hr--clear"> 1471 1472 1473 <div class="grid"> 1474 1475 <div class="grid__item text-center"> 1476 <ul class="inline-list payment-icons"> 1477 1478 1479 1480 1481 1482 1483 </ul> 1484 </div> 1485 1486 1487 <div class="grid__item text-center"> 1488 <ul class="inline-list payment-icons"> 1489 1490 <li> 1491 <img src="https://s3.dualstack.ap-southeast-1.amazonaws.com/eesb.public/images/payment/payments_bank-transfer.svg" alt="payment_bank-transfer"> 1492 </li> 1493 1494 <li> 1495 <img src="https://s3.dualstack.ap-southeast-1.amazonaws.com/eesb.public/images/payment/payments_ipay88.svg" alt="payment_ipay88"> 1496 </li> 1497 1498 <li> 1499 <img src="https://s3.dualstack.ap-southeast-1.amazonaws.com/eesb.public/images/payment/payments_stripe.svg" alt="payment_stripe"> 1500 </li> 1501 1502 <li> 1503 <img src="https://s3.dualstack.ap-southeast-1.amazonaws.com/eesb.public/images/payment/payments_paypal.svg" alt="payment_paypal"> 1504 </li> 1505 1506 </ul> 1507 </div> 1508 1509 1510 <div class="grid__item text-center"> 1511 <ul class="inline-list payment-icons"> 1512 <li> 1513 <img src="https://s3-ap-southeast-1.amazonaws.com/eesb.public/images/payment/ssl_certified.png"> 1514 </li> 1515 </ul> 1516 </div> 1517 1518 </div> 1519 1520 1521 <div class="grid"> 1522 <div class="grid__item text-center"> 1523 <p class="site-footer__links">Copyright © 2026 zealrunningcompany. E-commerce Powered by <a href="http://www.easystore.co/?utm_source=storefront&utm_medium=sf_ref_footer&utm_campaign=sf_ref">EasyStore</a></p> 1524 1525 <p class="site-footer__links"> 1526 1527 1528 1529 <a href="/legal/terms-of-service">Terms of Service</a> 1530 1531 1532 1533 1534 | <a href="/legal/privacy-policy">Privacy Policy</a> 1535 1536 1537 1538 1539 | <a href="/legal/refund-policy">Refund Policy</a> 1540 1541 1542 1543 </p> 1544 1545 </div> 1546 </div> 1547 1548 </div> 1549 </footer> 1550 1551 1552 1553
1553<script src="https://store-themes.easystore.co/485225/themes/1592/assets/fastclick.min.js?t=1787076082" type="text/javascript" ></script>
1553 1554
1554<script src="https://store-themes.easystore.co/485225/themes/1592/assets/timber.js?t=1787076082" type="text/javascript" ></script>
1554 1555
1555<script src="https://store-themes.easystore.co/485225/themes/1592/assets/theme.js?t=1787076082" type="text/javascript" ></script>
1555 1556 1557 1558 1559 1560 1561 1562
1563<script src="/assets/currencies.js" type="text/javascript" ></script>
vendor: 2 bytes, line 1563
1563
1564<script src="/assets/jquery.currencies.min.js" type="text/javascript" ></script>
vendor: 2 bytes, line 1564
1564
1565<script src="/assets/currencies_format.js" type="text/javascript" ></script>
1565 1566
1567<script> 1568Currency.format = "money_with_currency_format"; 1569var shopCurrency = 'MYR'; 1570var selectedCurrency = ''; 1571 1572 1573 Currency.convert = function(amount, from, to) { 1574 return amount; 1575 }; 1576 1577 1578if( $.cookie("currency") == null ){ 1579 1580 if( selectedCurrency != false ) { 1581 1582 Currency.convertAll(shopCurrency, selectedCurrency); 1583 jQuery('.selected-currency').text(Currency.currentCurrency); 1584 1585 } 1586 1587} 1588 1589/* Sometimes merchants change their shop currency, let's tell our JavaScript file */ 1590// Currency.moneyFormats[shopCurrency].money_with_currency_format = ""; 1591// Currency.moneyFormats[shopCurrency].money_format = "RM {{amount}} "; 1592 1593/* Default currency */ 1594var defaultCurrency = 'MYR'; 1595 1596/* Cookie currency */ 1597var cookieCurrency = Currency.cookie.read(); 1598 1599$("input[name=current_currency]").val(cookieCurrency); 1600if(cookieCurrency == null){ 1601 cookieCurrency = shopCurrency; 1602 Currency.cookie.write(shopCurrency); 1603} 1604/* Fix for customer account pages */ 1605jQuery('span.money span.money').each(function() { 1606 jQuery(this).parents('span.money').removeClass('money'); 1607}); 1608/* Saving the current price */ 1609jQuery('span.money').each(function() { 1610 jQuery(this).attr('data-currency-MYR', jQuery(this).html()); 1611}); 1612// If there's no cookie. 1613if (cookieCurrency == null) { 1614 if (shopCurrency !== defaultCurrency) { 1615 Currency.convertAll(shopCurrency, defaultCurrency); 1616 } 1617 else { 1618 Currency.currentCurrency = defaultCurrency; 1619 } 1620} 1621// If the cookie value does not correspond to any value in the currency dropdown. 1622else if (jQuery('[name=currencies]').size() && jQuery('[name=currencies] option[value=' + cookieCurrency + ']').size() === 0) { 1623 Currency.currentCurrency = shopCurrency; 1624 Currency.cookie.write(shopCurrency); 1625} 1626else if (cookieCurrency === shopCurrency) { 1627 Currency.currentCurrency = shopCurrency; 1628 Currency.convertAll(shopCurrency, cookieCurrency); 1629} 1630else { 1631 Currency.convertAll(shopCurrency, cookieCurrency); 1632} 1633jQuery('[name=currencies]').val(Currency.currentCurrency).change(function() { 1634 var newCurrency = jQuery(this).val(); 1635 1636 1637 Currency.cookie.write(newCurrency) 1638 if ('customers' == 'cart') { 1639 const params = new URLSearchParams(window.location.search); 1640 params.set('delete_cache', 1); 1641 window.location.search = params; 1642 } else { 1643 window.location.reload(); 1644 } 1645 1646}); 1647var original_selectCallback = window.selectCallback; 1648var selectCallback = function(variant, selector) { 1649 var currencies = null; 1650 original_selectCallback(variant, selector); 1651 if(typeof jQuery('[name=currencies]').val() == "undefined"){ 1652 currencies = shopCurrency; 1653 } 1654 else{ 1655 currencies = jQuery('[name=currencies]').val(); 1656 } 1657 Currency.convertAll(shopCurrency, currencies); 1658 jQuery('.selected-currency').text(Currency.currentCurrency); 1659}; 1660$('body').on('ajaxCart.afterCartLoad', function(cart) { 1661 Currency.convertAll(shopCurrency, jQuery('[name=currencies]').val()); 1662 jQuery('.selected-currency').text(Currency.currentCurrency); 1663}); 1664jQuery('.selected-currency').text(Currency.currentCurrency); 1665</script>
1665 1666 1667 1668
1668<script> 1669 1670 /* 1671 1672 ------ 1673 Events 1674 ------ 1675 1676 pages/viewed 1677 1678 customers/signup 1679 1680 customers/login 1681 1682 products/searched 1683 1684 collections/viewed 1685 1686 products/viewed 1687 1688 products/shared 1689 1690 wishlists/item_added 1691 1692 carts/items_added 1693 1694 carts/viewed 1695 1696 carts/item_removed 1697 1698 checkouts/initiated 1699 1700 checkouts/shipping_info_added 1701 1702 checkouts/payment_info_added 1703 1704 checkouts/completed 1705 1706 orders/placed 1707 1708 orders/purchased 1709 1710 payments/captured 1711 1712 payments/failed 1713 1714 */ 1715 1716 window.__latest_cart = window.__latest_cart || null; 1717 1718 const _selector = document.querySelector.bind(document), 1719 _selectorAll = document.querySelectorAll.bind(document) 1720 1721 document.addEventListener('DOMContentLoaded', (event) => { 1722 1723 const default_currency = getCookie("currency") 1724 const customer_id = window.__st.cid 1725 const template = window.__st.p 1726 1727 onPageView() 1728 1729 //-----------------------// 1730 // Configs // 1731 //-----------------------// 1732 1733 window.dataLayer = window.dataLayer || [] 1734 1735 Array.prototype.last = Array.prototype.last || function() { 1736 return this[this.length - 1] || null 1737 } 1738 1739 Array.prototype.first = Array.prototype.first || function() { 1740 return this[0] || null 1741 } 1742 1743 //----------------------// 1744 // Triggers // 1745 //----------------------// 1746 1747 const XHR = window.XMLHttpRequest 1748 1749 function xhr() { 1750 1751 const xhr = new XHR() 1752 1753 xhr.addEventListener("readystatechange", function() { 1754 1755 if(xhr.readyState != 4) return 1756 1757 try { 1758 1759 const response_url = xhr.responseURL 1760 1761 if (response_url.includes("cart/add")) { 1762 1763 window.__latest_cart = JSON.parse(xhr.response) 1764 1765 onCartItemsAdded() // ok 1766 1767 } 1768 1769 if (response_url.includes("cart/remove_item_quantity")) { 1770 1771 window.__latest_cart = JSON.parse(xhr.response) 1772 1773 onCartItemRemoved() // ok 1774 1775 } 1776 1777 if (response_url.includes("new_cart?retrieve=true")) { 1778 1779 result = JSON.parse(xhr.response) 1780 1781 if (result.cart) { 1782 window.__latest_cart = result.cart 1783 } 1784 1785 } 1786 1787 } catch(e) { 1788 1789 console.error(e) 1790 1791 } 1792 1793 }, false); 1794 1795 return xhr 1796 1797 } 1798 1799 window.XMLHttpRequest = xhr 1800 1801 switch(template) { 1802 1803 case 'cart': onCartView() // ok 1804 break 1805 case 'product': onProductView() // ok 1806 break 1807 case 'collection': onCollectionView() // ok 1808 break 1809 case 'blog': onBlogView() 1810 break 1811 case 'article': onArticleView() 1812 break 1813 case 'payment_completed': onOrderPlace() 1814 break 1815 case 'payment_fail': onPaymentFail() 1816 break 1817 1818 } 1819 1820 // _selector('form[action="/checkout/payments"]').addEventListener("submit", onPaymentInfoAdded(_selector('form[action="/checkout/payments"]'))) 1821 if (_selector('form[action="/checkout/detail"]')) _selector('form[action="/checkout/detail"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/detail"]'))}) // ok 1822 if (_selector('form[action="/checkout/shipping"]')) _selector('form[action="/checkout/shipping"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/shipping"]'))}) // ok 1823 if (_selector('form[action="/account/register"]')) _selector('form[action="/account/register"]').addEventListener("submit", onSignUp) // ok 1824 if (_selector('form[action="/account/login"]')) _selector('form[action="/account/login"]').addEventListener("submit", onLogin) // ok 1825 if (_selector('form[action="/search"]')) _selector('form[action="/search"]').addEventListener("submit", onProductSearch()) // ok 1826 if (_selector('#line-login-btn')) _selector('#line-login-btn').addEventListener('click', onLineLogin) // ok 1827 if (_selector('#PlaceOrder')) _selector('#PlaceOrder').addEventListener("click", ()=>{onCheckoutComplete(_selector('form[action="/checkout/payments"]'))}); // ok 1828 if (_selector('#add_wishlist')) _selector('#add_wishlist').addEventListener("click", onWishlistItemAdded) // ok 1829 if (_selectorAll('a[href="/account/logout"]')) _selectorAll('a[href="/account/logout"]').forEach(logoutButton => logoutButton.addEventListener("click", onLogout)) // ok 1830 if (_selector('.CartDrawerTrigger.cart-page-link')) _selector('.CartDrawerTrigger.cart-page-link').addEventListener("click", onCartView) // ok 1831 if (_selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link')) _selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link').addEventListener("click", onCartView) // ok 1832 if (_selectorAll('a[class^="share-"]')) _selectorAll('a[class^="share-"]').forEach(shareButton => shareButton.addEventListener("click", ()=>{onProductShare(shareButton)}) ) // ok 1833 if (_selectorAll('[name$="checkout"]')) _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate)) 1834 1835 // For append elements 1836 const bodyMutationObserver = new MutationObserver(() => { 1837 if (_selector('#form__spc #PlaceOrder')) _selector('#form__spc #PlaceOrder').addEventListener("click", onSinglePageCheckout) // ok 1838 if (_selectorAll('[name$="checkout"]')) _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate)) 1839 }); 1840 bodyMutationObserver.observe(_selector("body"), {subtree: true, childList: true}); 1841 1842 //------------------------------// 1843 // Event handlers // 1844 //------------------------------// 1845 1846 function onPageView() { 1847 1848 EasyStore.Event.dispatch('pages/viewed', { 1849 page: { 1850 type: template, 1851 title: document.title, 1852 description: _selector('meta[name=description]') ? _selector('meta[name=description]').getAttribute('content') : null, 1853 url: location.href, 1854 } 1855 }) 1856 1857 } 1858 1859 function onSignUp() { 1860 1861 const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) 1862 const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/) 1863 1864 const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "") 1865 1866 let data = {} 1867 1868 if (email_regex.test(email_or_phone)) { 1869 data.method = 'email' 1870 data.email = email_or_phone 1871 } 1872 1873 if (phone_regex.test(email_or_phone)) { 1874 data.method = "phone" 1875 data.phone = email_or_phone 1876 } 1877 1878 if (!data.method) return 1879 1880 EasyStore.Event.dispatch('customers/signup', data) 1881 1882 } 1883 1884 function onLogin() { 1885 1886 const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) 1887 const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/) 1888 1889 const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "") 1890 1891 let data = {} 1892 1893 if (email_regex.test(email_or_phone)) { 1894 data.method = 'email' 1895 data.email = email_or_phone 1896 } 1897 1898 if (phone_regex.test(email_or_phone)) { 1899 data.method = "phone" 1900 data.phone = email_or_phone 1901 } 1902 1903 if (!data.method) return 1904 1905 EasyStore.Event.dispatch('customers/login', data) 1906 1907 } 1908 1909 function onLineLogin() { 1910 1911 EasyStore.Event.dispatch('customers/login', { method: 'line' }) 1912 1913 } 1914 1915 function onLogout() { 1916 1917 EasyStore.Event.dispatch('customers/logout', { customer_id }) 1918 1919 } 1920 1921 function onBlogView() { 1922 1923 const blog = "" 1924 1925 EasyStore.Event.dispatch('blogs/viewed', { blog }) 1926 1927 } 1928 1929 function onArticleView() { 1930 1931 const article = "" 1932 1933 EasyStore.Event.dispatch('articles/viewed', { article }) 1934 1935 } 1936 1937 function onProductSearch() { 1938 1939 const query = _selector('input[name=q]').value 1940 1941 if (!query) return 1942 1943 EasyStore.Event.dispatch('products/searched', { query }) 1944 1945 } 1946 1947 function onCollectionView() { 1948 1949 const collection = "" 1950 1951 EasyStore.Event.dispatch('collections/viewed', { collection }) 1952 1953 } 1954 1955 function onProductView() { 1956 1957 const product = "" 1958 1959 EasyStore.Event.dispatch("products/viewed", { product }) 1960 1961 } 1962 1963 function onProductShare(el) { 1964 1965 const product = "" 1966 1967 const channel = el.getAttribute("class").split("-").last() 1968 1969 EasyStore.Event.dispatch('products/shared', { product, channel }) 1970 1971 } 1972 1973 function onWishlistItemAdded() { 1974 1975 let product = "" 1976 const quantity = _selector("#Quantity").value 1977 1978 EasyStore.Event.dispatch('wishlists/item_added', { product }) 1979 1980 } 1981 1982 async function onCartItemsAdded() { 1983 1984 const cart = await getCart() 1985 1986 if(cart && cart.items != undefined && cart.items.length > 0) { 1987 1988 EasyStore.Event.dispatch('carts/item_added', { cart }) 1989 1990 } 1991 1992 } 1993 1994 async function onCartView() { 1995 1996 const cart = await getCart() 1997 1998 EasyStore.Event.dispatch('carts/viewed', { cart }) 1999 2000 } 2001 2002 async function onCartItemRemoved() { 2003 2004 const cart = await getCart() 2005 2006 cart.items = [] 2007 2008 if(cart) { 2009 2010 EasyStore.Event.dispatch('carts/item_removed', { cart }) 2011 2012 } 2013 2014 } 2015 2016 async function onCheckoutInitiate() { 2017 2018 const cart = await getCart() 2019 2020 EasyStore.Event.dispatch('checkouts/initiated', { cart }) 2021 2022 } 2023 2024 async function onShippingInfoAdded(form) { 2025 let checkout = getCheckout() 2026 2027 let form_data = {} 2028 new FormData(form).forEach((value, key) => form_data[key] = value) 2029 2030 let shipping_tier = null 2031 2032 if (form_data.type && form_data.type.startsWith("r_pickup")) { 2033 shipping_tier = `Pickup - ${form_data.pick_location}` 2034 } 2035 2036 if (form_data.s_id) {
2037 shipping_tier = _selector(`input[id='`+form_data.s_id+`']`).getAttribute("data-shipping-name") 2038 } 2039 2040 if (!shipping_tier) return 2041 2042 EasyStore.Event.dispatch('checkouts/shipping_info_added', { checkout, shipping_tier }) 2043 2044 } 2045 2046 async function onPaymentInfoAdded(form) { 2047 2048 let checkout = getCheckout() 2049 2050 let payment_type = new FormData(form).get('payment_method') 2051 2052 EasyStore.Event.dispatch("checkouts/payment_info_added", { checkout, payment_type }) 2053 2054 } 2055 2056 async function onOrderPlace() { 2057 2058 let cart_token = getCookie("cart_js") 2059 let previous_cart_token = getCookie("previous_cart_ga4_js") 2060 2061 if (previous_cart_token && previous_cart_token == cart_token) { 2062 // Prevent duplicate purchase tracking 2063 return 2064 } 2065 2066 let order = getOrder() 2067 2068 EasyStore.Event.dispatch('orders/placed', { order }) 2069 2070 if(order.is_manual_payment) { 2071 2072 EasyStore.Event.dispatch('orders/purchased', { order }) 2073 2074 } 2075 2076 const last_transaction = order.transactions.last() 2077 2078 if (last_transaction.status) { 2079 2080 EasyStore.Event.dispatch('orders/purchased', { order }) 2081 EasyStore.Event.dispatch('payments/captured', { order }) 2082 2083 } 2084 2085 } 2086 2087 async function onPaymentFail() { 2088 2089 const order = getOrder() 2090 2091 EasyStore.Event.dispatch('payments/failed', { order }) 2092 2093 } 2094 2095 async function onCheckoutComplete(form) { 2096 2097 onPaymentInfoAdded(form) 2098 2099 const checkout = getCheckout() 2100 2101 EasyStore.Event.dispatch('checkouts/completed', { checkout }) 2102 2103 } 2104 2105 async function onSinglePageCheckout() { 2106 2107 // let checkout = $("[data-app-checkout]").data("app-checkout") 2108 2109 let checkout = getCheckout() 2110 2111 // const payment_type = _selector("#app_spc_payment_method").find(`[class*="label-content"]`).first().find("b").first().text() 2112 const payment_type = _selector("#app_spc_payment_method").getElementsByClassName('label-content')[0].getElementsByTagName('b')[0].innerHTML 2113 2114 const shipping_method = _selector("#delivery_method").value 2115 2116 let shipping_tier = null 2117 let app_spc_customer_info_label = _selector("#app_spc_customer_info").getElementsByClassName('label-content') 2118 if (shipping_method == "shipping") { 2119 shipping_tier = app_spc_customer_info_label[app_spc_customer_info_label.length - 1].getElementsByTagName('b')[0].innerHTML 2120 } 2121 2122 if (shipping_method == "pickup") { 2123 shipping_tier = app_spc_customer_info_label[0].innerHTML 2124 } 2125 2126 if (shipping_tier) { 2127 2128 EasyStore.Event.dispatch('checkouts/shipping_info_added', { 2129 checkout, 2130 shipping_tier, 2131 }) 2132 2133 } 2134 2135 if (payment_type) { 2136 2137 EasyStore.Event.dispatch('checkouts/payment_info_added', { 2138 checkout, 2139 payment_type, 2140 }) 2141 2142 } 2143 2144 EasyStore.Event.dispatch('checkouts/completed', { checkout }) 2145 2146 } 2147 2148 }) 2149 2150 2151 //-----------------------// 2152 // Functions // 2153 //-----------------------// 2154 2155 function getCookie(name) { 2156 2157 name += "=" 2158 2159 decodedCookie = decodeURIComponent(document.cookie) 2160 2161 ca = decodedCookie.split(";") 2162 2163 for(i = 0; i < ca.length; i++) { 2164 c = ca[i] 2165 while (c.charAt(0) == " ") { 2166 c = c.substring(1) 2167 } 2168 if (c.indexOf(name) == 0) { 2169 return c.substring(name.length, c.length) 2170 } 2171 } 2172 2173 return "" 2174 2175 } 2176 2177 const parsePrice = price => { 2178 if(typeof price === 'string') { 2179 return parseFloat(price.split(',').join('')) 2180 } 2181 2182 return price 2183 } 2184 2185 const requestCart = async (method, data) => { 2186 2187 let response = await fetch('/cart.json', {method: 'GET',headers: {'Content-Type': 'application/json'}}) 2188 result = await response.json() 2189 2190 return result.cart 2191 2192 } 2193 const getCart = async (latest = false) => { 2194 2195 let cart = window.__latest_cart 2196 2197 const cart_invalid = !cart || !cart.items || (cart.total_price > 0 && !cart.items.length) 2198 2199 if(latest || cart_invalid) { 2200 cart = await requestCart() 2201 } 2202 2203 cart.items = cart.items || [] 2204 2205 return mapCart(cart) 2206 2207 } 2208 2209 const getCheckout = async () => { 2210 mapCheckout(window.__latest_cart || await requestCart()) 2211 } 2212 2213 const getOrder = async () => { 2214 mapOrder(window.__latest_cart || await requestCart()) 2215 } 2216 2217 //-----------------------// 2218 // Mappers // 2219 //-----------------------// 2220 2221 const fallbackAttribute = (object, attribute) => { 2222 2223 if(!Array.isArray(attribute)) { 2224 attribute = [attribute] 2225 } 2226 2227 let final_value = null 2228 2229 do { 2230 2231 final_value = object[attribute.shift()] 2232 2233 } while(!final_value && attribute.length) 2234 2235 return final_value 2236 2237 } 2238 2239 const map = (object, mapper) => { 2240 2241 const newObject = {} 2242 2243 for(const key in mapper) { 2244 2245 // Handle different keys between new and old format
2246 newObject[key] = fallbackAttribute(object, mapper[key]) 2247 2248 // Cast price to float 2249 if(newObject[key] && ['price', 'amount', 'discount', 'discounts'].some(x => key.endsWith(x))) { 2250 newObject[key] = parsePrice(newObject[key]) 2251 } 2252 2253 if(newObject[key] === undefined) { 2254 delete newObject[key] 2255 } 2256 2257 } 2258 2259 return newObject 2260 2261 } 2262 2263 const mapCart = cart => { 2264 2265 const oldCart = cart 2266 2267 const mapper = { 2268 id: 'id', 2269 currency: 'currency', 2270 item_count: 'item_count', 2271 items: 'items', 2272 total_price: 'total_price', 2273 latest_items: 'latest_items' 2274 } 2275 2276 cart = map(cart, mapper) 2277 2278 const discounts = (oldCart.storewide_discounts || []).concat((oldCart.voucher_discounts || [])) 2279 2280 cart.discount_applications = discounts.map(discount => ({ 2281 title: discount.voucher_code || null, 2282 value: parsePrice(discount.amount), 2283 })) 2284 2285 cart.original_total_price = cart.items.length 2286 ? cart.items 2287 .map(item => item.original_price) 2288 .reduce((sum, price) => sum + price) 2289 : 0 2290 2291 cart.total_discount = cart.discount_applications.length 2292 ? cart.discount_applications 2293 .map(discount => parsePrice(discount.value)) 2294 .reduce((sum, value) => sum + value) 2295 : 0 2296 2297 cart.items = cart.items.map(item => mapLineItem(item)) 2298 2299 return cart 2300 2301 } 2302 2303 const mapCheckout = checkout => { 2304 2305 const mapper = { 2306 note: 'note', 2307 attributes: 'note_attributes', 2308 billing_address: 'billing_address', 2309 currency: 'currency', 2310 customer_id: 'customer_id', 2311 discounts_amount: 'total_discount', 2312 id: 'id', 2313 line_items: 'order_item', 2314 order_number: 'order_number', 2315 shipping_address: 'shipping_address', 2316 shipping_price: 'shipping_tax', 2317 shipping_method: 'shipping_method_name', 2318 tax_price: 'total_tax', 2319 } 2320 2321 checkout = map(checkout, mapper) 2322 2323 checkout.requires_shipping = checkout.line_items.some(item => item.shipping_required) 2324 2325 checkout.line_items = checkout.line_items.map(item => mapLineItem(item)) 2326 2327 return checkout 2328 2329 } 2330 2331 const mapOrder = order => { 2332 2333 const mapper = { 2334 attributes: 'note_attributes', 2335 billing_address: 'billing_address', 2336 cancelled: 'is_cancelled', 2337 cancelled_at: 'cancelled_at', 2338 created_at: 'created_at', 2339 customer_id: 'customer_id', 2340 // discount_applications: 'discount_applications', 2341 email: 'email', 2342 financial_status: 'financial_status', 2343 fulfillment_status: 'fulfillment_status', 2344 line_items: 'order_item', 2345 note: 'note', 2346 order_number: 'order_number', 2347 phone: 'phone', 2348 shipping_address: 'shipping_address', 2349 shipping_methods: 'shipping_methods', 2350 shipping_price: 'total_shipping', 2351 subtotal_price: 'subtotal_price', 2352 // tax_lines: 'tax_lines', 2353 tax_price: 'total_tax', 2354 total_discounts: 'total_discount', 2355 total_net_amount: 'total_amount_include_transaction', 2356 total_price: 'total_price', 2357 transactions: 'transaction_records', 2358 is_manual_payment: 'is_manual_payment', 2359 } 2360 2361 order.email = order.billing_address.email 2362 order.phone = order.billing_address.phone 2363 order.shipping_method = order.shipping_method_name 2364 2365 order = map(order, mapper) 2366 2367 order.line_items = order.line_items.map(item => mapLineItem(item)) 2368 order.transactions = order.transactions.map(transaction => mapTransaction(transaction)) 2369 2370 return order 2371 2372 } 2373 2374 const mapLineItem = line_item => { 2375 2376 const old_line_item = line_item 2377 2378 const mapper = { 2379 final_price: 'price', 2380 image: 'img_url', 2381 message: 'message', 2382 original_line_price: 'original_line_price', 2383 original_price: 'original_price', 2384 properties: 'properties', 2385 quantity: 'quantity', 2386 requires_shipping: 'shipping_required', 2387 sku: 'sku', 2388 taxable: 'taxable', 2389 title: 'product_name', 2390 product_name: 'product_name', 2391 url: 'url', 2392 product_id: 'product_id', 2393 variant_id: 'variant_id', 2394 id: ['id', 'i_id'], 2395 } 2396 2397 line_item = map(line_item, mapper) 2398 2399 line_item.product_id = line_item.product_id || (old_line_item.product && old_line_item.product.id) || null 2400 line_item.variant_id = line_item.variant_id || (old_line_item.variant && old_line_item.variant.id) || null 2401 line_item.image = line_item.image || (old_line_item.image && old_line_item.image.url) || null 2402 2403 return line_item 2404 2405 } 2406 2407 const mapTransaction = transaction => { 2408 2409 const mapper = { 2410 amount: 'amount', 2411 created_at: 'created_at', 2412 gateway: 'gateway_type', 2413 id: 'id', 2414 status: 'status', 2415 } 2416 2417 transaction = map(transaction, mapper) 2418 2419 return transaction 2420 2421 } 2422 2423 2424</script>
2424 2425 2426</div> 2427</body> 2428</html>
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.