PageSourceSearch

https://ptti.my/account/register

html ptti.my collected 2026-10-08 08:57:47 UTC 106,804 bytes, 3,210 lines download raw bytes

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/897413/f/8318815.jpeg" />
15  
16
17  <!-- Title and description ================================================== -->
18  <title>
19  Login &ndash; PTTI
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://ptti.my/account/login">
30  
31  <meta property="og:image" content="https://cdn.store-assets.com/s/897413/f/8248207.jpeg?width=350&format=webp">
32  <meta property="og:image:secure_url" content="https://cdn.store-assets.com/s/897413/f/8248207.jpeg?width=350&format=webp">
33  
34
35
36<meta property="og:description" content="PTTI is an Award Winning Online Tuition SPM Class for Form 5, 4, 3, 2, 1 and Year 6 students.">
37<meta property="og:site_name" content="PTTI">
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://ptti.my/account/login">
51  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=3.0">
52  <meta name="theme-color" content="">
53
54  <!-- CSS ================================================== -->
55  <link href="https://store-themes.easystore.co/897413/themes/2877/assets/timber.css?t=1791441402" rel="stylesheet" type="text/css" media="screen" />
56  <link href="https://store-themes.easystore.co/897413/themes/2877/assets/theme.css?t=1791441402" rel="stylesheet" type="text/css" media="screen" />
57
58  
59
60
61
62<link href="https://fonts.googleapis.com/css?family=Rajdhani:400,600&display=swap" rel="stylesheet">
63
64
65  
65<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" type="text/javascript" ></script>
65
66  <!-- Header hook for plugins ================================================== -->
67  
68<!-- ScriptTags -->
69<script>window.__st={p: "customers",cid: null,cem: null,cph: null,cfn: null,cln: null,cge: null,cdb: null,ccc: null};</script>
69<script src='/assets/events.js'></script>
69<script>(function(){function asyncLoad(){var urls=['/assets/facebook-pixel.js?v=1.2.1701504180','/assets/traffic.js?v=1','https://apps.easystore.co/sales-pop/script.js?shop=pttiptti.easy.co','https://smartarget.online/loader.js?type=int&u=ff30bff8d40f585fc830e546ea7171440e47c924&source=easystore_social_proof_sales','https://apps.easystore.co/facebook-login/script.js?shop=pttiptti.easy.co'];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>
69
70<!-- /ScriptTags -->
71
72
73  
74<!--[if lt IE 9]>
75<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js" type="text/javascript" ></script>
vendor: 2 bytes, line 75
75
76<script src="https://store-themes.easystore.co/897413/themes/2877/assets/respond.min.js?t=1791441402" type="text/javascript" ></script>
76
77<link href="https://store-themes.easystore.co/897413/themes/2877/assets/respond-proxy.html" id="respond-proxy" rel="respond-proxy" />
78<link href="//ptti.my/search?q=7568e8aae51f634de7b35ee2e709fe8d" id="respond-redirect" rel="respond-redirect" />
79<script src="//ptti.my/search?q=7568e8aae51f634de7b35ee2e709fe8d" type="text/javascript"></script>
79
80<![endif]-->
81
82
83
84  
84<script src="https://store-themes.easystore.co/897413/themes/2877/assets/modernizr.min.js?t=1791441402" type="text/javascript" ></script>
84
85
86  
87  
88    
88<script src="/assets/shop_common.js" type="text/javascript" ></script>
88
89    
89<script src="/assets/customer_area.js" type="text/javascript" ></script>
89
90  
91  
91<script>
92  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
93  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
94  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
95  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
96
97  ga('create', '', 'auto','myTracker');
98  ga('myTracker.send', 'pageview');
99
100  </script>
100
101  
102<!-- Snippet:global/head: ActionPop Email Popups & Upsell by OnVoard -->
103<script>
104  (function() {
105    window.OnVoard = window.OnVoard || function() {
106      (window.OnVoard.q = window.OnVoard.q || []).push(arguments);
107    };
108    var script = document.createElement("script");
109    var parent = document.getElementsByTagName("script")[0].parentNode;
110    script.async = 1;
111
112    
113    script.src = "https://scripts.onvoard.com/apps/loader.js";
114    
115    parent.appendChild(script);
116  })();
117</script>
117
118
119
120<script>
121
122var ovData = {};
123ovData["ecommerce_platform"] = "easystore";
124ovData["account_id"] = "acct_i56nf98ua40ya24";
125
126
127  ovData["template"] = "customers";
128  ovData["cart"] = {"item_count":0,"total_price":0,"announcements":[]};
129  ovData["product"] = "";
130  ovData["shop"] = {};
131  ovData["customer"] = {};
132
133  
134    ovData["shop"] = {
135      "currency": "MYR",
136      "domain": "ptti.my",
137      "url": "https://ptti.my",
138      "money_format": "<span class=money data-ori-price='{{amount}}'>RM {{amount}} </span>",
139    };
140  
141
142  
143
144  window.OnVoardData = ovData;
145</script>
145
146
147<!-- /Snippet -->
148
149<!-- Snippet:global/head: Insert Code -->
150
151<!--Hotjar -->
152<!-- Hotjar Tracking Code for https://ptti.my -->
153<script>
vendor: 128 bytes, lines 153-156
153
154    (function(h,o,t,j,a,r){
155        h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
156        h._hjSettings={hjid:
1566397015
vendor: 264 bytes, lines 156-161
156,hjsv:6};
157        a=o.getElementsByTagName('head')[0];
158        r=o.createElement('script');r.async=1;
159        r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
160        a.appendChild(r);
161    })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
162</script>
162
163<!-- /Snippet -->
164
165</head>
166
167<body id="login" class="template-customers  " >
168
169  <ul id="MobileNav" class="mobile-nav">
170  
171  <li class="mobile-nav_icon-x">
172    
173      
174
175
176  	
177  	<span class="MobileNavTrigger icon icon-x"></span>
178  </li>
179  
180  
181  <li class="mobile-nav__link" aria-haspopup="true">
182    
183    <a href="/" >
184      Home
185    </a>
186    
187  </li>
188  
189  
190  <li class="mobile-nav__link" aria-haspopup="true">
191    
192    <a href="/pages/apa-itu-otc" >
193      Apa itu OTC?
194    </a>
195    
196  </li>
197  
198  
199  <li class="mobile-nav__link" aria-haspopup="true">
200    
201    
202    <a href="/pages/free-trial" class="mobile-nav__parent-link">
203      Free Trial
204    </a>
205    <span class="mobile-nav__sublist-trigger">
206      <span class="icon-fallback-text mobile-nav__sublist-expand">
207  <span class="icon icon-plus" aria-hidden="true"></span>
208  <span class="fallback-text">+</span>
209</span>
210<span class="icon-fallback-text mobile-nav__sublist-contract">
211  <span class="icon icon-minus" aria-hidden="true"></span>
212  <span class="fallback-text">-</span>
213</span>
214
215    </span>
216    <ul class="mobile-nav__sublist">
217      
218      
219      <li class="mobile-nav__sublist-link" aria-haspopup="true">
220        
221        <a href="/pages/form-5-sains-tulen" >
222          Form 5 Sains Tulen
223        </a>
224        
225      </li>
226      
227      
228      <li class="mobile-nav__sublist-link" aria-haspopup="true">
229        
230        <a href="/pages/form-5-bukan-sains-tulen-teras" >
231          Form 5 Bukan Sains Tulen (Teras)
232        </a>
233        
234      </li>
235      
236      
237      <li class="mobile-nav__sublist-link" aria-haspopup="true">
238        
239        <a href="/pages/form-4-sains-tulen" >
240          Form 4 Sains Tulen
241        </a>
242        
243      </li>
244      
245      
246      <li class="mobile-nav__sublist-link" aria-haspopup="true">
247        
248        <a href="/pages/form-4-bukan-sains-tulen-teras" >
249          Form 4 Bukan Sains Tulen (Teras)
250        </a>
251        
252      </li>
253      
254      
255      <li class="mobile-nav__sublist-link" aria-haspopup="true">
256        
257        <a href="/pages/form-3" >
258          Form 3
259        </a>
260        
261      </li>
262      
263      
264      <li class="mobile-nav__sublist-link" aria-haspopup="true">
265        
266        <a href="/pages/form-2" >
267          Form 2
268        </a>
269        
270      </li>
271      
272      
273      <li class="mobile-nav__sublist-link" aria-haspopup="true">
274        
275        <a href="/pages/form-1" >
276          Form 1
277        </a>
278        
279      </li>
280      
281    </ul>
282    
283  </li>
284  
285  
286  <li class="mobile-nav__link" aria-haspopup="true">
287    
288    <a href="/pages/better-result" >
289      Our Students
290    </a>
291    
292  </li>
293  
294  
295  <li class="mobile-nav__link" aria-haspopup="true">
296    
297    <a href="/pages/ask-ptti" >
298      Ask PTTI
299    </a>
300    
301  </li>
302  
303
304  
305
306  
307  
308  
309  <li class="mobile-nav__link">
310    <a href="/account/login">Log in</a>
311  </li>
312  
313  <li class="mobile-nav__link">
314    <a href="/account/register">Create account</a>
315  </li>
316  
317  
318  
319  
320  <li class="mobile-nav__link header-bar__search-wrapper">
321    
322    <div class="header-bar__module header-bar__search mobile-nav_search">
323      
324  <form action="/search" method="get" class="header-bar__search-form clearfix" role="search">
325    
326    <button type="submit" class="btn icon-fallback-text header-bar__search-submit">
327      <span class="icon icon-search" aria-hidden="true"></span>
328      <span class="fallback-text">Search</span>
329    </button>
330    <input type="search" name="q" value="" aria-label="Search" class="header-bar__search-input" placeholder="Search" autocomplete="off">
331    <div class="dropdown" id="searchDropdown"></div>
332    <input type="hidden" name="search_history" id="search_history">
333  </form>
334
335
336
337
338<script>
339  var _search_history_listings = ""
340  if(_search_history_listings != "") localStorage.setItem('searchHistory', JSON.stringify(_search_history_listings));
341
342  function clearAll() {
343    localStorage.removeItem('searchHistory');
344  
345    var customer = "";
346    if(customer) {
347      // Your logic to clear all data or call an endpoint
348      fetch('/account/search_histories', {
349          method: 'DELETE',
350          headers: {
351            "Content-Type": "application/json",
352            "X-Requested-With": "XMLHttpRequest"
353          },
354          body: JSON.stringify({
355            _token: "yNIxW1hoq0dss3xoPWARy0Hj9gwch3wF69BmtQmj"
356          }),
357      })
358      .then(response => response.json())
359    }
360  }
361  // End - store view history in local storage
362  
363  // search history dropdown  
364  var searchInputs = document.querySelectorAll('input[type=search]');
365  
366  if(searchInputs.length > 0) {
367    
368    searchInputs.forEach((searchInput)=>{
369    
370      searchInput.addEventListener('focus', function() {
371        var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown');
372        searchDropdown.innerHTML = ''; // Clear existing items
373  
374        // retrieve data from local storage
375        var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || [];
376  
377        // Convert JSON to string
378        var search_history_json = JSON.stringify(searchHistoryData);
379  
380        // Set the value of the hidden input
381        searchInput.closest('form').querySelector("#search_history").value = search_history_json;
382  
383        // create dropdown items
384        var clearAllItem = document.createElement('div');
385        clearAllItem.className = 'dropdown-item clear-all';
386        clearAllItem.textContent = 'Clear';
387        clearAllItem.addEventListener('click', function() {
388            clearAll();
389            searchDropdown.style.display = 'none';
390            searchInput.classList.remove('is-focus');
391        });
392        searchDropdown.appendChild(clearAllItem);
393  
394        // create dropdown items
395        searchHistoryData.forEach(function(item) {
396          var dropdownItem = document.createElement('div');
397          dropdownItem.className = 'dropdown-item';
398          dropdownItem.textContent = item.term;
399          dropdownItem.addEventListener('click', function() {
400            searchInput.value = item.term;
401            searchDropdown.style.display = 'none';
402          });
403          searchDropdown.appendChild(dropdownItem);
404        });
405  
406        if(searchHistoryData.length > 0){
407          // display the dropdown
408          searchInput.classList.add('is-focus');
409          document.body.classList.add('search-input-focus');
410          searchDropdown.style.display = 'block';
411        }
412      });
413  
414      searchInput.addEventListener("focusout", (event) => {
415        var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown');
416        searchInput.classList.remove('is-focus');
417        searchDropdown.classList.add('transparent');
418        setTimeout(()=>{
419          searchDropdown.style.display = 'none';
420          searchDropdown.classList.remove('transparent');
421          document.body.classList.remove('search-input-focus');
422        }, 400);
423      });
424    })
425  }
426  // End - search history dropdown
427</script>
427
428    </div>
429    
430  </li>
431  
432  
433</ul>
434<div id="MobileNavOutside" class="mobile-nav-outside"></div>
435
436
437<div id="PageContainer" class="page-container">
438  
439<!-- Snippet:global/body_start: Console Extension -->
440<div id='es_console' style='display: none;'>897413</div>
441<!-- /Snippet -->
442
443  
444    <style>
445  .search-modal__form{
446    position: relative;
447  }
448  
449  .dropdown-wrapper {
450    position: relative;
451  }
452  
453  .dropdown-wrapper:hover .dropdown {
454    display: block;
455  }
456  
457  .header-icon-nav .dropdown {
458    left: -80px;
459  }
460  
461  .dropdown {
462    display: none;
463    position: absolute;
464    top: 100%;
465    left: 0px;
466    width: 100%;
467    padding: 8px;
468    background-color: #fff;
469    z-index: 1000;
470    border-radius: 5px;
471    border: 1px solid rgba(var(--color-foreground), 1);
472    border-top: none;
473    overflow-x: hidden;
474    overflow-y: auto;
475    max-height: 350px;
476    min-width: 150px;
477    box-shadow: 0 0 5px rgba(0,0,0,0.1);
478  }
479    
480  .dropdown a{
481    text-decoration: none;
482    color: #000 !important;
483  }
484  
485  .dropdown-item {
486    padding: 0.4rem 2rem;
487    cursor: pointer;
488    line-height: 1.4;
489    overflow: hidden;
490    text-overflow: ellipsis;
491    white-space: nowrap;
492  }
493  
494  .dropdown-item:hover{
495    background-color: #f3f3f3;
496  }
497  
498  .search__input.is-focus{
499    border-radius: 15px;
500    border-bottom-left-radius: 0;
501    border-bottom-right-radius: 0;
502    border: 1px solid rgba(var(--color-foreground), 1);
503    border-bottom: none;
504    box-shadow: none;
505  }
506  
507  .clear-all {
508    text-align: right;
509    padding: 0 2rem 0.2rem;
510    line-height: 1;
511    font-size: 70%;
512    margin-bottom: -2px;
513  }
514  
515  .clear-all:hover{
516    background-color: #fff;
517  }
518  
519  .referral-notification {
520    position: absolute;
521    top: 100%;
522    right: -12px;
523    background: white;
524    border: 1px solid #e0e0e0;
525    border-radius: 8px;
526    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
527    width: 280px;
528    z-index: 1000;
529    padding: 16px;
530    margin-top: 8px;
531    font-size: 14px;
532    line-height: 1.4;
533  }
534  
535  .referral-notification::before {
536    content: '';
537    position: absolute;
538    top: -8px;
539    right: 20px;
540    width: 0;
541    height: 0;
542    border-left: 8px solid transparent;
543    border-right: 8px solid transparent;
544    border-bottom: 8px solid white;
545  }
546  
547  .referral-notification::after {
548    content: '';
549    position: absolute;
550    top: -9px;
551    right: 20px;
552    width: 0;
553    height: 0;
554    border-left: 8px solid transparent;
555    border-right: 8px solid transparent;
556    border-bottom: 8px solid #e0e0e0;
557  }
558  
559  .referral-notification h4 {
560    margin: 0 0 8px 0;
561    color: #2196F3;
562    font-size: 16px;
563    font-weight: 600;
564  }
565  
566  .referral-notification p {
567    margin: 0 0 12px 0;
568    color: #666;
569  }
570  
571  .referral-notification .referral-code {
572    background: #f5f5f5;
573    padding: 8px;
574    border-radius: 4px;
575    font-family: monospace;
576    font-size: 13px;
577    text-align: center;
578    margin: 8px 0;
579    border: 1px solid #ddd;
580  }
581  
582  .referral-notification .close-btn {
583    position: absolute;
584    top: 8px;
585    right: 8px;
586    background: none;
587    border: none;
588    font-size: 18px;
589    color: #999;
590    cursor: pointer;
591    padding: 0;
592    width: 20px;
593    height: 20px;
594    line-height: 1;
595  }
596  
597  .referral-notification .close-btn:hover {
598    color: #333;
599  }
600  
601  .referral-notification .action-btn {
602    background: #2196F3;
603    color: white;
604    border: none;
605    padding: 8px 16px;
606    border-radius: 4px;
607    cursor: pointer;
608    font-size: 12px;
609    margin-right: 8px;
610    margin-top: 8px;
611  }
612  
613  .referral-notification .action-btn:hover {
614    background: #1976D2;
615  }
616  
617  .referral-notification .dismiss-btn {
618    background: transparent;
619    color: #666;
620    border: 1px solid #ddd;
621    padding: 8px 16px;
622    border-radius: 4px;
623    cursor: pointer;
624    font-size: 12px;
625    margin-top: 8px;
626  }
627  
628  .referral-notification .dismiss-btn:hover {
629    background: #f5f5f5;
630  }
631  .referral-modal__dialog {
632    transform: translate(-50%, 0);
633    transition: transform var(--duration-default) ease, visibility 0s;
634    z-index: 10000;
635    position: fixed;
636    top: 20vh;
637    left: 50%;
638    width: 100%;
639    max-width: 350px;
640    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
641    border-radius: 12px;
642    background-color: #fff;
643    color: #000;
644    padding: 20px;
645    text-align: center;
646  }
647  .modal-overlay.referral-modal-overlay {
648    position: fixed;
649    top: 0;
650    left: 0;
651    width: 100%;
652    height: 100%;
653    background-color: rgba(0, 0, 0, 0.7);
654    z-index: 2001;
655    display: block;
656    opacity: 1;
657    transition: opacity var(--duration-default) ease, visibility 0s;
658  }
659</style>
660
661<header class="header-bar  sticky-topbar">
662  <div class="header-bg-wrapper">
663    <div class="header-wrapper wrapper">
664      
665
666      <div class="logo-header" role="banner">
667
668              
669                    <div class="h1 site-header__logo" itemscope itemtype="http://schema.org/Organization">
670              
671                    
672                        
673                      	
674                          <a href="/" class="logo-wrapper" itemprop="url">
675                            <img src="https://cdn.store-assets.com/s/897413/f/8248207.jpeg?width=350&format=webp" alt="PTTI" itemprop="logo">
676                          </a>
677                        
678
679                    
680              
681                </div>
682              
683
684      </div>
685
686      <div class="header-nav-bar medium-down--hide">
687          
688<ul class="site-nav large--text-center" id="AccessibleNav">
689  
690    
691    
692      <li >
693        <a href="/"  class="site-nav__link">Home</a>
694      </li>
695    
696  
697    
698    
699      <li >
700        <a href="/pages/apa-itu-otc"  class="site-nav__link">Apa itu OTC?</a>
701      </li>
702    
703  
704    
705    
706      
707      <li class="site-nav--has-dropdown" aria-haspopup="true">
708        <a href="/pages/free-trial"  class="site-nav__link">
709          Free Trial
710          <span class="arrow-icon">
711            <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><title>arrow down</title><path d="M50,78.18A7.35,7.35,0,0,1,44.82,76L3.15,34.36A7.35,7.35,0,1,1,13.55,24L50,60.44,86.45,24a7.35,7.35,0,1,1,10.4,10.4L55.21,76A7.32,7.32,0,0,1,50,78.18Z"/></svg>
712          </span>
713        </a>
714        <ul class="site-nav__dropdown">
715          
716            
717            
718              <li >
719                <a href="/pages/form-5-sains-tulen"  class="site-nav__link">Form 5 Sains Tulen</a>
720              </li>
721            
722          
723            
724            
725              <li >
726                <a href="/pages/form-5-bukan-sains-tulen-teras"  class="site-nav__link">Form 5 Bukan Sains Tulen (Teras)</a>
727              </li>
728            
729          
730            
731            
732              <li >
733                <a href="/pages/form-4-sains-tulen"  class="site-nav__link">Form 4 Sains Tulen</a>
734              </li>
735            
736          
737            
738            
739              <li >
740                <a href="/pages/form-4-bukan-sains-tulen-teras"  class="site-nav__link">Form 4 Bukan Sains Tulen (Teras)</a>
741              </li>
742            
743          
744            
745            
746              <li >
747                <a href="/pages/form-3"  class="site-nav__link">Form 3</a>
748              </li>
749            
750          
751            
752            
753              <li >
754                <a href="/pages/form-2"  class="site-nav__link">Form 2</a>
755              </li>
756            
757          
758            
759            
760              <li >
761                <a href="/pages/form-1"  class="site-nav__link">Form 1</a>
762              </li>
763            
764          
765        </ul>
766      </li>
767    
768  
769    
770    
771      <li >
772        <a href="/pages/better-result"  class="site-nav__link">Our Students</a>
773      </li>
774    
775  
776    
777    
778      <li >
779        <a href="/pages/ask-ptti"  class="site-nav__link">Ask PTTI</a>
780      </li>
781    
782  
783  
784  
785      
786        
787          
788        
789          
790        
791      
792  
793  
794  
795</ul>
796
797      </div>
798
799      <div class="desktop-header-nav medium-down--hide">
800
801
802        <div class="header-subnav">
803          
804
805
806
807
808          <div class="header-icon-nav">
809
810                
811
812                
813
814
815                
816                  
817                    <div class="header-bar__module">
818                      
819  <a class="popup-with-form" href="#search-form">
820    
821
822
823
824	<svg class="icon-search svg-icon" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><title>icon-search</title><path d="M68.5,65.87a35.27,35.27,0,1,0-5.4,4.5l23.11,23.1a3.5,3.5,0,1,0,5-4.94ZM14.82,41A28.47,28.47,0,1,1,43.28,69.43,28.5,28.5,0,0,1,14.82,41Z"/></svg>    
825
826  
827
828  </a>
829
830
831
832<!-- form itself -->
833<div id="search-form" class="white-popup-block mfp-hide popup-search">
834  <div class="popup-search-content">
835    <form action="/search" method="get" class="input-group search-bar" role="search">
836      
837      <input type="search" name="q" value="" placeholder="Search" class="input-group-field" aria-label="Search" placeholder="Search" autocomplete="off">
838      <div class="dropdown" id="searchDropdown"></div>
839      <input type="hidden" name="search_history" id="search_history">
840      <span class="input-group-btn">
841        <button type="submit" class="btn icon-fallback-text">
842          <span class="icon icon-search" aria-hidden="true"></span>
843          <span class="fallback-text">Search</span>
844        </button>
845      </span>
846    </form>
847  </div>
848</div>
849
850<script src="https://store-themes.easystore.co/897413/themes/2877/assets/magnific-popup.min.js?t=1791441402" type="text/javascript" ></script>
vendor: 1 bytes, line 850
850
851<script>
852$(document).ready(function() {
853	$('.popup-with-form').magnificPopup({
854		type: 'inline',
855		preloader: false,
856		focus: '#name',
857      	mainClass: 'popup-search-bg-wrapper',
858
859		// When elemened is focused, some mobile browsers in some cases zoom in
860		// It looks not nice, so we disable it:
861		callbacks: {
862			beforeOpen: function() {
863				if($(window).width() < 700) {
864					this.st.focus = false;
865				} else {
866					this.st.focus = '#name';
867				}
868			}
869		}
870	});
871  	$('.popup-search-content').click(function(event) {
872      	if($(event.target).attr('class') == "popup-search-content") {
873          $.magnificPopup.close();
874        }
875    });
876});
877</script>
877
878
879
880<script>
881  var _search_history_listings = ""
882  if(_search_history_listings != "") localStorage.setItem('searchHistory', JSON.stringify(_search_history_listings));
883
884  function clearAll() {
885    localStorage.removeItem('searchHistory');
886  
887    var customer = "";
888    if(customer) {
889      // Your logic to clear all data or call an endpoint
890      fetch('/account/search_histories', {
891          method: 'DELETE',
892          headers: {
893            "Content-Type": "application/json",
894            "X-Requested-With": "XMLHttpRequest"
895          },
896          body: JSON.stringify({
897            _token: "yNIxW1hoq0dss3xoPWARy0Hj9gwch3wF69BmtQmj"
898          }),
899      })
900      .then(response => response.json())
901    }
902  }
903  // End - store view history in local storage
904  
905  // search history dropdown  
906  var searchInputs = document.querySelectorAll('input[type=search]');
907  
908  if(searchInputs.length > 0) {
909    
910    searchInputs.forEach((searchInput)=>{
911    
912      searchInput.addEventListener('focus', function() {
913        var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown');
914        searchDropdown.innerHTML = ''; // Clear existing items
915  
916        // retrieve data from local storage
917        var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || [];
918  
919        // Convert JSON to string
920        var search_history_json = JSON.stringify(searchHistoryData);
921  
922        // Set the value of the hidden input
923        searchInput.closest('form').querySelector("#search_history").value = search_history_json;
924  
925        // create dropdown items
926        var clearAllItem = document.createElement('div');
927        clearAllItem.className = 'dropdown-item clear-all';
928        clearAllItem.textContent = 'Clear';
929        clearAllItem.addEventListener('click', function() {
930            clearAll();
931            searchDropdown.style.display = 'none';
932            searchInput.classList.remove('is-focus');
933        });
934        searchDropdown.appendChild(clearAllItem);
935  
936        // create dropdown items
937        searchHistoryData.forEach(function(item) {
938          var dropdownItem = document.createElement('div');
939          dropdownItem.className = 'dropdown-item';
940          dropdownItem.textContent = item.term;
941          dropdownItem.addEventListener('click', function() {
942            searchInput.value = item.term;
943            searchDropdown.style.display = 'none';
944          });
945          searchDropdown.appendChild(dropdownItem);
946        });
947  
948        if(searchHistoryData.length > 0){
949          // display the dropdown
950          searchInput.classList.add('is-focus');
951          document.body.classList.add('search-input-focus');
952          searchDropdown.style.display = 'block';
953        }
954      });
955  
956      searchInput.addEventListener("focusout", (event) => {
957        var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown');
958        searchInput.classList.remove('is-focus');
959        searchDropdown.classList.add('transparent');
960        setTimeout(()=>{
961          searchDropdown.style.display = 'none';
962          searchDropdown.classList.remove('transparent');
963          document.body.classList.remove('search-input-focus');
964        }, 400);
965      });
966    })
967  }
968  // End - search history dropdown
969</script>
969
970                    </div>
971                  
972                
973
974
975
976
977                
978                  <div class="header-bar__module dropdown-wrapper">
979                    
980                      <a href="/account/login">
981
982
983
984    <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>
985
986  
987</a>
988
989                      <!-- Referral Notification Popup for Desktop -->
990                      <div id="referralNotification" class="referral-notification" style="display: none;">
991                        <button class="close-btn" onclick="dismissReferralNotification()">&times;</button>
992                        <div style="text-align: center; margin-bottom: 16px;">
993                          <div style="width: 100px; height: 100px; margin: 0 auto;">
994                            <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg">
995                          </div>
996                        </div>
997                        <p id="referralSignupMessage" style="text-align: center; font-size: 14px; color: #666; margin: 0 0 20px 0;">
998                          Your friend gifted you   credit! Sign up now to redeem.
999                        </p>
1000                        <div style="text-align: center;">
1001                          <button class="btn" onclick="goToSignupPage()" style="width: 100%; color: #fff;">
1002                            Sign Up
1003                          </button>
1004                        </div>
1005                      </div>
1006                    
1007                  </div>
1008                
1009
1010                <div class="header-bar__module cart-page-link-wrapper">
1011                  <span class="header-bar__sep" aria-hidden="true"></span>
1012                  <a class="CartDrawerTrigger cart-page-link">
1013                    
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-bag</title><path d="M91.78,93.11,84.17,24.44a3.5,3.5,0,0,0-3.48-3.11H69.06C67.53,10.94,59.57,3,50,3S32.47,10.94,30.94,21.33H19.31a3.5,3.5,0,0,0-3.48,3.11L8.22,93.11A3.49,3.49,0,0,0,11.69,97H88.31a3.49,3.49,0,0,0,3.47-3.89ZM50,10c5.76,0,10.6,4.83,12,11.33H38.05C39.4,14.83,44.24,10,50,10ZM15.6,90l6.84-61.67h8.23v9.84a3.5,3.5,0,0,0,7,0V28.33H62.33v9.84a3.5,3.5,0,0,0,7,0V28.33h8.23L84.4,90Z"/></svg>	
1018
1019  
1020
1021                    <span class="cart-count header-bar__cart-count hidden-count">0</span>
1022                  </a>
1023                </div>
1024
1025          </div>
1026        </div>
1027
1028
1029
1030      </div>
1031      
1032	  <div class="mobile-header-icons large--hide">
1033        
1034        <div class="large--hide">
1035          
1036  <a class="popup-with-form" href="#search-form">
1037    
1038
1039
1040
1041	<svg class="icon-search svg-icon" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><title>icon-search</title><path d="M68.5,65.87a35.27,35.27,0,1,0-5.4,4.5l23.11,23.1a3.5,3.5,0,1,0,5-4.94ZM14.82,41A28.47,28.47,0,1,1,43.28,69.43,28.5,28.5,0,0,1,14.82,41Z"/></svg>    
1042
1043  
1044
1045  </a>
1046
1047
1048
1049<!-- form itself -->
1050<div id="search-form" class="white-popup-block mfp-hide popup-search">
1051  <div class="popup-search-content">
1052    <form action="/search" method="get" class="input-group search-bar" role="search">
1053      
1054      <input type="search" name="q" value="" placeholder="Search" class="input-group-field" aria-label="Search" placeholder="Search" autocomplete="off">
1055      <div class="dropdown" id="searchDropdown"></div>
1056      <input type="hidden" name="search_history" id="search_history">
1057      <span class="input-group-btn">
1058        <button type="submit" class="btn icon-fallback-text">
1059          <span class="icon icon-search" aria-hidden="true"></span>
1060          <span class="fallback-text">Search</span>
1061        </button>
1062      </span>
1063    </form>
1064  </div>
1065</div>
1066
1067<script src="https://store-themes.easystore.co/897413/themes/2877/assets/magnific-popup.min.js?t=1791441402" type="text/javascript" ></script>
vendor: 1 bytes, line 1067
1067
1068<script>
1069$(document).ready(function() {
1070	$('.popup-with-form').magnificPopup({
1071		type: 'inline',
1072		preloader: false,
1073		focus: '#name',
1074      	mainClass: 'popup-search-bg-wrapper',
1075
1076		// When elemened is focused, some mobile browsers in some cases zoom in
1077		// It looks not nice, so we disable it:
1078		callbacks: {
1079			beforeOpen: function() {
1080				if($(window).width() < 700) {
1081					this.st.focus = false;
1082				} else {
1083					this.st.focus = '#name';
1084				}
1085			}
1086		}
1087	});
1088  	$('.popup-search-content').click(function(event) {
1089      	if($(event.target).attr('class') == "popup-search-content") {
1090          $.magnificPopup.close();
1091        }
1092    });
1093});
1094</script>
1094
1095
1096
1097<script>
1098  var _search_history_listings = ""
1099  if(_search_history_listings != "") localStorage.setItem('searchHistory', JSON.stringify(_search_history_listings));
1100
1101  function clearAll() {
1102    localStorage.removeItem('searchHistory');
1103  
1104    var customer = "";
1105    if(customer) {
1106      // Your logic to clear all data or call an endpoint
1107      fetch('/account/search_histories', {
1108          method: 'DELETE',
1109          headers: {
1110            "Content-Type": "application/json",
1111            "X-Requested-With": "XMLHttpRequest"
1112          },
1113          body: JSON.stringify({
1114            _token: "yNIxW1hoq0dss3xoPWARy0Hj9gwch3wF69BmtQmj"
1115          }),
1116      })
1117      .then(response => response.json())
1118    }
1119  }
1120  // End - store view history in local storage
1121  
1122  // search history dropdown  
1123  var searchInputs = document.querySelectorAll('input[type=search]');
1124  
1125  if(searchInputs.length > 0) {
1126    
1127    searchInputs.forEach((searchInput)=>{
1128    
1129      searchInput.addEventListener('focus', function() {
1130        var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown');
1131        searchDropdown.innerHTML = ''; // Clear existing items
1132  
1133        // retrieve data from local storage
1134        var searchHistoryData = JSON.parse(localStorage.getItem('searchHistory')) || [];
1135  
1136        // Convert JSON to string
1137        var search_history_json = JSON.stringify(searchHistoryData);
1138  
1139        // Set the value of the hidden input
1140        searchInput.closest('form').querySelector("#search_history").value = search_history_json;
1141  
1142        // create dropdown items
1143        var clearAllItem = document.createElement('div');
1144        clearAllItem.className = 'dropdown-item clear-all';
1145        clearAllItem.textContent = 'Clear';
1146        clearAllItem.addEventListener('click', function() {
1147            clearAll();
1148            searchDropdown.style.display = 'none';
1149            searchInput.classList.remove('is-focus');
1150        });
1151        searchDropdown.appendChild(clearAllItem);
1152  
1153        // create dropdown items
1154        searchHistoryData.forEach(function(item) {
1155          var dropdownItem = document.createElement('div');
1156          dropdownItem.className = 'dropdown-item';
1157          dropdownItem.textContent = item.term;
1158          dropdownItem.addEventListener('click', function() {
1159            searchInput.value = item.term;
1160            searchDropdown.style.display = 'none';
1161          });
1162          searchDropdown.appendChild(dropdownItem);
1163        });
1164  
1165        if(searchHistoryData.length > 0){
1166          // display the dropdown
1167          searchInput.classList.add('is-focus');
1168          document.body.classList.add('search-input-focus');
1169          searchDropdown.style.display = 'block';
1170        }
1171      });
1172  
1173      searchInput.addEventListener("focusout", (event) => {
1174        var searchDropdown = searchInput.closest('form').querySelector('#searchDropdown');
1175        searchInput.classList.remove('is-focus');
1176        searchDropdown.classList.add('transparent');
1177        setTimeout(()=>{
1178          searchDropdown.style.display = 'none';
1179          searchDropdown.classList.remove('transparent');
1180          document.body.classList.remove('search-input-focus');
1181        }, 400);
1182      });
1183    })
1184  }
1185  // End - search history dropdown
1186</script>
1186
1187        </div>
1188
1189
1190        <!--  Mobile cart  -->
1191        <div class="large--hide">
1192          <a class="CartDrawerTrigger cart-page-link mobile-cart-page-link">
1193            
1194
1195
1196
1197	<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-bag</title><path d="M91.78,93.11,84.17,24.44a3.5,3.5,0,0,0-3.48-3.11H69.06C67.53,10.94,59.57,3,50,3S32.47,10.94,30.94,21.33H19.31a3.5,3.5,0,0,0-3.48,3.11L8.22,93.11A3.49,3.49,0,0,0,11.69,97H88.31a3.49,3.49,0,0,0,3.47-3.89ZM50,10c5.76,0,10.6,4.83,12,11.33H38.05C39.4,14.83,44.24,10,50,10ZM15.6,90l6.84-61.67h8.23v9.84a3.5,3.5,0,0,0,7,0V28.33H62.33v9.84a3.5,3.5,0,0,0,7,0V28.33h8.23L84.4,90Z"/></svg>	
1198
1199  
1200
1201            <span class="cart-count hidden-count">0</span>
1202          </a>
1203        </div>
1204
1205        <!--  Mobile hamburger  -->
1206        <div class="large--hide">
1207          <a class="mobile-nav-trigger MobileNavTrigger">
1208            
1209
1210
1211
1212    <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-nav-menu</title><path d="M6.7,26.34H93a3.5,3.5,0,0,0,0-7H6.7a3.5,3.5,0,0,0,0,7Z"/><path d="M93.3,46.5H7a3.5,3.5,0,0,0,0,7H93.3a3.5,3.5,0,1,0,0-7Z"/><path d="M93.3,73.66H7a3.5,3.5,0,1,0,0,7H93.3a3.5,3.5,0,0,0,0-7Z"/></svg>
1213
1214  
1215
1216          </a>
1217        </div>
1218      
1219        
1220          
1221          <!-- Referral Notification Modal for Mobile -->
1222          <details-modal class="referral-modal" id="referralMobileModal">
1223            <details>
1224              <summary class="referral-modal__toggle" aria-haspopup="dialog" aria-label="Open referral modal" style="display: none;">
1225              </summary>
1226              <div class="modal-overlay referral-modal-overlay"></div>
1227              <div class="referral-modal__dialog" role="dialog" aria-modal="true" aria-label="Referral notification">
1228                <div class="referral-modal__content">
1229                  <button type="button" class="modal__close-button" aria-label="Close" onclick="closeMobileReferralModal()" style="position: absolute; top: 16px; right: 16px; background: none; border: none; font-size: 24px; cursor: pointer;">
1230                    &times;
1231                  </button>
1232
1233                  <div style="margin-bottom: 24px;">
1234                    <div style="width: 120px; height: 120px; margin: 0 auto 20px;">
1235                      <img src="https://resources.easystore.co/storefront/icons/channels/vector_referral_program.svg" style="width: 100%; height: 100%;">
1236                    </div>
1237                  </div>
1238
1239                  <p id="referralSignupMessageMobile" style="font-size: 16px; color: #333; margin: 0 0 30px 0; line-height: 1.5;">
1240                    Your friend gifted you   credit! Sign up now to redeem.
1241                  </p>
1242
1243                  <button type="button" class="btn" onclick="goToSignupPageFromMobile()" style="width: 100%; color: #fff;">
1244                    Sign Up
1245                  </button>
1246                </div>
1247              </div>
1248            </details>
1249          </details-modal>
1250          
1251        
1252      
1253      </div>
1254
1255
1256    </div>
1257  </div>
1258</header>
1259
1260
1261
1262
1263
1264
1265    
1266    <main class="wrapper main-content" role="main">
1267      <div class="grid">
1268          <div class="grid__item">
vendor: 100 bytes, lines 1268-1272
1268
1269            
1270  
1271            
1272<script src="https://www.recaptcha.net/recaptcha/enterprise.js?render=
12726LdMNdIqAAAAALegJp7y4weVcCIlnwmIN8TWseEF
vendor: 12 bytes, line 1272
1272"></script>
1273<link rel="preload" href="https://store-themes.easystore.co/897413/themes/2877/assets/customer.css?t=1791441402" as="style" onload="this.onload=null;this.rel='stylesheet'">
1274<style>
1275  main.main-content .field > label{
1276    display: none;
1277  }
1278  .h3{
1279    font-size: 18px;
1280  }
1281  .button--full-width{
1282    width: 100%;
1283  }
1284  .tab-wrapper{
1285    display: inline-flex;
1286    justify-content: center;
1287    align-items: center;
1288    margin: 10px auto 20px;
1289    background-color: #eaeaea;
1290    border-radius: 200px;
1291    padding: 5px;
1292    gap: 10px;
1293  }
1294  .tab-wrapper .tab-label {
1295    display: inline-block;
1296    min-width: 130px;
1297    padding: 8px 15px;
1298    border-radius: 100px;
1299    cursor: pointer;
1300    font-size: 17px;
1301    line-height: 1.1;
1302    user-select: none;
1303    margin: 0;
1304    color: #000;
1305  }
1306  #register-tos a {
1307    display: inline;
1308  }
1309  @media screen and (max-width: 400px){
1310    .tab-wrapper .tab-label {
1311      min-width: 110px;
1312    }
1313  }
1314  .tab-wrapper input[type='radio']:checked + .tab-label {
1315    background-color: #fff;
1316    box-shadow: 2px 2px 25px -10px #333;
1317  }
1318
1319  @media screen and (min-width: 500px){
1320    .large--five-twelfths{
1321      min-width: 420px;
1322    }
1323  }
1324</style>
1325
1326
1327
1328
1329<div class="customer login section-width-control small-width large--five-twelfths text-center wrapper">
1330  <div class="card">
1331    <h1 id="login" tabindex="-1" class="mb-0">
1332      Welcome
1333    </h1>
1334    <p class="h3 mt-0">
1335      
1336        Sign up or log in to continue
1337      
1338    </p>
1339    <div>
1340      
1341
1342      
1343
1344      
1345
1346      
1347
1348      
1349
1350      
1351
1352      
1353
1354      
1355
1356      
1357      <div class="tab-wrapper">
1358        <div>
1359          <input type="radio" name="type" id="tab-register" class="hide hidden" checked>
1360          <label for="tab-register" class="tab-label">
1361            Sign up
1362          </label>
1363        </div>
1364        <div>
1365          <input type="radio" name="type" id="tab-login" class="hide hidden">
1366          <label for="tab-login" class="tab-label">
1367            Login
1368          </label>
1369        </div>
1370      </div>
1371      
1372
1373      <form id="form-login" action="/account/auth" method="post" class="mt-2">
1374        <input type="hidden" name="_token" value="yNIxW1hoq0dss3xoPWARy0Hj9gwch3wF69BmtQmj">
1375        <input type="hidden" name="location_id" value="">
1376        <input type="hidden" name="staff_id" value="">
1377        <input type="hidden" id="recaptchaResponse" name="g-recaptcha-response">
1378
1379        
1380        <div id="error-content"></div>
1381
1382        <div class="field">
1383          <input
1384            type="text"
1385            name="customer[email_or_phone]"
1386            id="CustomerDetail"
1387            autocorrect="off"
1388            autocapitalize="off"
1389            placeholder="Email"
1390            required
1391          >
1392          <label for="CustomerDetail">
1393            Email
1394          </label>
1395        </div>
1396
1397        <button
1398          type="submit"
1399          form="form-login"
1400          class="btn button--full-width g-recaptcha">
1401          Continue
1402        </button>
1403
1404        <div class="button-snippet">
1405          
1406<!-- Snippet:login/button: Facebook Login -->
1407                <button id="fb-login-btn" type="button"  class="btn"  onclick="fb_login()" style="background-color: #3a5795; color: white; font-weight: bold;"><span class="icon icon-facebook" aria-hidden="true"></span> Continue with Facebook</button>
1408
1409                
1409<script>
1410                    function fb_login(){
1411                        location.href = 'https://apps.easystore.co/facebook-login/run?domain='+window.location.protocol+'//'+window.location.hostname+'&shop=pttiptti.easy.co';
1412                    }
1413                </script>
1413
1414<!-- /Snippet -->
1415                
1416        </div>
1417
1418        
1419
1420        <div id="register-tos">
1421          By signing up, I agree to the PTTI'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>.
1422        </div>
1423
1424      </form>
1425    </div>
1426  </div>
1427
1428</div>
1429
1430
1431
1432<script>
1433  const register_tab = document.querySelector('#tab-register');
1434  const login_tab = document.querySelector('#tab-login');
1435  const register_tos = document.querySelector('#register-tos');
1436  const isRegistrationEnabled = "1";
1437
1438  if (register_tab) {
1439    register_tab.addEventListener('click', function() {
1440      if (register_tos) {
1441        register_tos.style.display = 'block';
1442      }
1443    });
1444  }
1445  if (login_tab) {
1446    login_tab.addEventListener('click', function() {
1447      if (register_tos) {
1448        register_tos.style.display = 'none';
1449      }
1450    });
1451  }
1452
1453  const methodSwitchBtn = document.getElementById('phone-login-btn');
1454  if (methodSwitchBtn) {
1455    methodSwitchBtn.onclick = function () {
1456      var type = (register_tab && register_tab.checked) ? 'register' : 'login';
1457      window.location.href = '/account/login?method=phone&type=' + type;
1458    };
1459  }
1460
1461  let lastPathSegment = window.location.pathname.split('/').filter(segment => segment.length > 0).pop();
1462  
1463  // Redirect to login if trying to access register when self registration is disabled
1464  if (!isRegistrationEnabled) {
1465    if (lastPathSegment === 'register') {
1466      window.location.href = '/account/login';
1467    } else if (lastPathSegment === 'login' || lastPathSegment === 'auth') {
1468      if (register_tos) {
1469        register_tos.style.display = 'none';
1470      }
1471    } 
1472  } else {
1473    // Only proceed with tab logic if not redirecting
1474    if(lastPathSegment === 'login') {
1475      if (login_tab) {
1476        login_tab.checked = true;
1477      }
1478      if (register_tos) {
1479        register_tos.style.display = 'none';
1480      }
1481    } else {
1482      if (register_tos) {
1483        register_tos.style.display = 'block';
1484      }
1485    }
1486  }
1487
1488  const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
1489  const phonePattern = /^(?:\+?\d{1,3}[\s-]?)?(?:\d{1,14}[\s-]?){1,5}$/;
1490
1491  let form = document.querySelector('#form-login'),
1492      input = document.querySelector('#CustomerDetail'),
1493      error_content = document.querySelector('#error-content');
1494
1495
1496  // One attempt at a time: the reCAPTCHA wait below is async, so without
1497  // this a double-click starts two continuations and posts the form twice.
1498  var submitting = false;
1499
1500  form.addEventListener('submit', async function (event) {
1501    // preventDefault FIRST: a re-entrant submit must still be cancelled, or the
1502    // browser performs a native post with no captcha token.
1503    event.preventDefault();
1504    if (submitting) return;
1505
1506    let input_value = input.value
1507    error_content.innerHTML = '';
1508    if (!input_value.match(emailPattern) && !input_value.match(phonePattern)) {
1509      error_content.innerHTML = `<div class="errors note">Invalid Email or Phone</div>`;
1510      return false;
1511    }
1512
1513    submitting = true;
1514    document.querySelector('#form-login .btn').classList.add('btn--loading','loading');
1515
1516    // reCAPTCHA is unreachable from some regions (google.com is blocked in
1517    // mainland China). Fail open the same way checkout and forgot-password do:
1518    // submit without a token rather than leave the button spinning forever.
1519    try {
1520      if (window.grecaptcha && typeof window.grecaptcha.enterprise === 'object') {
1521        // The loader defines a stub {ready} synchronously and fetches the real
1522        // implementation asynchronously, so execute() may not exist yet.
1523        // ready() queues until it does; the timeout stops a bundle that never
1524        // arrives from hanging the button.
1525        await new Promise(function (resolve) {
1526          setTimeout(resolve, 3000);
1527          try { grecaptcha.enterprise.ready(resolve); } catch (e) { resolve(); }
1528        });
1529
1530        const token = await grecaptcha.enterprise.execute('6LdMNdIqAAAAALegJp7y4weVcCIlnwmIN8TWseEF', { action: 'LOGIN' });
1531        document.getElementById('recaptchaResponse').value = token;
1532      }
1533    } catch (e) { /* fail open */ }
1534
1535    document.getElementById('form-login').submit();
1536  });
1537
1538
1539</script>
1539
1540
1541  
1542            
1543          </div>
1544      </div>
1545      
1546      
1547  
1548    </main>
1549  
1550    <footer class="site-footer small--text-center" role="contentinfo">
1551      
1552      
1553      
1554      <div class="wrapper">
1555  
1556        <div class="grid-uniform">
1557  
1558          
1559          
1560          
1561          
1562            
1563          
1564          
1565          
1566            
1567          
1568          
1569          
1570  
1571          
1572              
1573            
1574  
1575          
1576      
1577          
1578          
1579          <div class="grid__item large--one-half ">
1580            <a href="/" class="logo-wrapper" itemprop="url" >
1581              
1582                <img style="max-width: 250px" src="https://cdn.store-assets.com/s/897413/f/8257285.png?width=350&format=webp" alt="PTTI" itemprop="logo">
1583              
1584            </a>
1585            <p class="site-footer__links">© 2026 PTTI GROUP SDN BHD</p>
1586          </div>
1587          
1588          
1589            <div class="grid__item large--one-quarter medium--one-half">
1590              
1591              <h4>Quick Links</h4>
1592              
1593              <ul class="site-footer__links">
1594                
1595                  <li><a href="/pages/news-coverage" >News Coverage</a></li>
1596                
1597                  <li><a href="/pages/careers-we-are-hiring" >Careers (We Are Hiring!)</a></li>
1598                
1599                  <li><a href="/pages/download-ptti-app-free" >Download PTTI APP (Free)</a></li>
1600                
1601                
1602              </ul>
1603            </div>
1604          
1605  
1606          
1607            <div class="grid__item large--one-quarter medium--one-half">
1608              <h4>Follow Us</h4>
1609                
1610                <ul class="inline-list social-icons">
1611  
1612  
1613  
1614  
1615    <li>
1616      <a class="icon-fallback-text" href="https://instagram.com/pttionline?utm_medium=copy_link" title="PTTI on Instagram" target="_blank">
1617        
1618
1619
1620
1621    <svg xmlns="http://www.w3.org/2000/svg" class="instagram-icon-svg social-icon-svg" viewBox="0 0 1024 1024">
1622        <title>icon-instagram</title>
1623        <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"/>
1624    </svg>
1625
1626  
1627
1628        <span class="fallback-text">Instagram</span>
1629      </a>
1630    </li>
1631  
1632  
1633  
1634  
1635  
1636  
1637    <li>
1638      <a class="icon-fallback-text" href="https://WebsitePTTI.wasap.my " title="PTTI on Whatsapp" target="_blank">
1639        
1640
1641
1642
1643    <svg xmlns="http://www.w3.org/2000/svg" class="whatsapp-icon-svg social-icon-svg" viewBox="0 0 1024 1024">
1644        <title>icon-whatsapp</title>
1645        <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"/>
1646    </svg>
1647
1648  
1649
1650        <span class="fallback-text">Whatsapp</span>
1651      </a>
1652    </li>
1653    
1654  
1655  
1656  
1657</ul>
1658
1659            </div>
1660          
1661        </div>
1662  
1663        <hr class="hr--small hr--clear">
1664  
1665        
1666          <div class="grid">
1667            
1668             <div class="grid__item text-center">
1669               <ul class="inline-list payment-icons">
1670                  
1671                    <li>
1672                      <span class="icon-fallback-text">
1673                        <span class="icon icon-visa" aria-hidden="true"></span>
1674                        <span class="fallback-text">Visa</span>
1675                      </span>
1676                    </li>
1677                  
1678                  
1679                    <li>
1680                      <span class="icon-fallback-text">
1681                        <span class="icon icon-master" aria-hidden="true"></span>
1682                        <span class="fallback-text">Master</span>
1683                      </span>
1684                    </li>
1685                  
1686                  
1687                  
1688                  
1689                  
1690               </ul>
1691             </div>
1692             
1693             
1694             <div class="grid__item text-center">
1695               <ul class="inline-list payment-icons">
1696                 
1697                    <li>
1698                    <img src="https://s3.dualstack.ap-southeast-1.amazonaws.com/eesb.public/images/payment/payments_billplz.svg" alt="payment_billplz">
1699                    </li>
1700                 
1701                    <li>
1702                    <img src="https://s3.dualstack.ap-southeast-1.amazonaws.com/eesb.public/images/payment/payments_razerms.svg" alt="payment_razerms">
1703                    </li>
1704                 
1705                    <li>
1706                    <img src="https://s3.dualstack.ap-southeast-1.amazonaws.com/eesb.public/images/payment/payments_atome.svg" alt="payment_atome">
1707                    </li>
1708                 
1709               </ul>
1710             </div>
1711            
1712           
1713             <div class="grid__item text-center">
1714               <ul class="inline-list payment-icons">
1715                    <li>
1716                    <img src="https://s3-ap-southeast-1.amazonaws.com/eesb.public/images/payment/ssl_certified.png">
1717                    </li>
1718               </ul>
1719             </div>
1720           
1721           </div>
1722         
1723  
1724         <div class="grid">
1725           <div class="grid__item text-center">
1726             
1727             
1728             <p class="site-footer__links">
1729              
1730              
1731                
1732                  <a href="/legal/terms-of-service">Terms of Service</a>
1733                
1734                
1735              
1736                
1737                  | <a href="/legal/privacy-policy">Privacy Policy</a>
1738                
1739                
1740              
1741                
1742                  | <a href="/legal/refund-policy">Refund Policy</a>
1743                
1744                
1745              
1746             </p>
1747             
1748           </div>
1749         </div>
1750  
1751      </div>
1752    </footer>
1753    
1754      
1755<div class="footer-bar large--hide">
1756  <div>
1757    
1758        
1759        
1760        
1761    
1762        
1763        <a href="https://www.ptti.my/pages/better-result">
1764          
1765          	<img src="https://cdn.store-assets.com/s/897413/f/8327050.png?width=150&format=webp"/>
1766          
1767            <div>
1768              Our Students
1769            </div>
1770        </a>
1771        
1772
1773    
1774        
1775        
1776        
1777    
1778        
1779        <a href="https://www.ptti.my/pages/free-trial">
1780          
1781          	<img src="https://cdn.store-assets.com/s/897413/f/8327783.gif"/>
1782          
1783            <div>
1784              Free Trial
1785            </div>
1786        </a>
1787        
1788
1789    
1790        
1791        
1792        
1793    
1794        
1795        <a href="https://www.ptti.my/pages/choose-your-level">
1796          
1797          	<img src="https://cdn.store-assets.com/s/897413/f/8327612.gif"/>
1798          
1799            <div>
1800              Join OTC
1801            </div>
1802        </a>
1803        
1804
1805    
1806        
1807        
1808        
1809    
1810        
1811        <a href="https://www.ptti.my/pages/ask-ptti">
1812          
1813          	<img src="https://cdn.store-assets.com/s/897413/f/8335499.png?width=150&format=webp"/>
1814          
1815            <div>
1816              Ask PTTI
1817            </div>
1818        </a>
1819        
1820
1821    
1822  </div>
1823</div>
1824
1825
1826    
1827
1828    
1829    
1830      <div id="scrollTopButton" class="on-right" style="display: none">
1831        <svg class="svg-icon" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
1831<path d="M22,18.25a1.21,1.21,0,0,1-.88-.37L12,8.77,2.88,17.88a1.24,1.24,0,0,1-1.76-1.76l10-10a1.24,1.24,0,0,1,1.76,0l10,10a1.24,1.24,0,0,1,0,1.76A1.21,1.21,0,0,1,22,18.25Z"/></svg>
1832      </div>
1833      
1833<script>
1834        $( document ).ready(function() {
1835          var winScroll = $(this).scrollTop(),
1836          this_el = $("#scrollTopButton");
1837
1838          // Header bar
1839          if(winScroll > 400){
1840            this_el.fadeIn();
1841          }else{
1842            this_el.fadeOut();
1843          }
1844
1845          $("#scrollTopButton").click(function() {
1846            $('html,body').animate({ scrollTop: 0 });
1847          });
1848
1849          $(window).scroll(function(){
1850            var winScroll = $(this).scrollTop();
1851
1852            // Header bar
1853            if(winScroll > 400){
1854              this_el.fadeIn();
1855            }else{
1856              this_el.fadeOut();
1857            }
1858
1859          });
1860        });
1861      </script>
1861
1862    
1863
1864  
1865    
1866  
1867    
1867<script src="https://store-themes.easystore.co/897413/themes/2877/assets/fastclick.min.js?t=1791441402" type="text/javascript" ></script>
1867
1868    
1868<script src="https://store-themes.easystore.co/897413/themes/2877/assets/timber.js?v1.1?t=1791441402" type="text/javascript" ></script>
1868
1869    
1869<script src="https://store-themes.easystore.co/897413/themes/2877/assets/theme.js?t=1791441402" type="text/javascript" ></script>
1869
1870  
1871    
1872  
1873    
1874  
1875    
1876
1877<script src="/assets/currencies.js" type="text/javascript" ></script>
vendor: 1 bytes, line 1877
1877
1878<script src="/assets/jquery.currencies.min.js" type="text/javascript" ></script>
vendor: 1 bytes, line 1878
1878
1879<script src="/assets/currencies_format.js" type="text/javascript" ></script>
1879
1880
1881<script>
1882Currency.format = "money_with_currency_format";
1883var shopCurrency = 'MYR';
1884var selectedCurrency = '';
1885
1886
1887  Currency.convert = function(amount, from, to) {
1888    return amount;
1889  };
1890
1891  
1892if( $.cookie("currency") == null ){
1893  
1894  if( selectedCurrency != false ) {
1895
1896  Currency.convertAll(shopCurrency, selectedCurrency);
1897  jQuery('.selected-currency').text(Currency.currentCurrency);  
1898
1899  }
1900
1901}
1902
1903/* Sometimes merchants change their shop currency, let's tell our JavaScript file */
1904// Currency.moneyFormats[shopCurrency].money_with_currency_format = "";
1905// Currency.moneyFormats[shopCurrency].money_format = "RM {{amount}} ";
1906  
1907/* Default currency */
1908var defaultCurrency = 'MYR';
1909  
1910/* Cookie currency */
1911var cookieCurrency = Currency.cookie.read();
1912
1913  cookieCurrency = shopCurrency;
1914
1915$("input[name=current_currency]").val(cookieCurrency);
1916if(cookieCurrency == null){
1917  cookieCurrency = shopCurrency;
1918  Currency.cookie.write(shopCurrency);
1919}
1920/* Fix for customer account pages */
1921jQuery('span.money span.money').each(function() {
1922  jQuery(this).parents('span.money').removeClass('money');
1923});
1924/* Saving the current price */
1925jQuery('span.money').each(function() {
1926  jQuery(this).attr('data-currency-MYR', jQuery(this).html());
1927});
1928// If there's no cookie.
1929if (cookieCurrency == null) {
1930  if (shopCurrency !== defaultCurrency) {
1931    Currency.convertAll(shopCurrency, defaultCurrency);
1932  }
1933  else {
1934    Currency.currentCurrency = defaultCurrency;
1935  }
1936}
1937// If the cookie value does not correspond to any value in the currency dropdown.
1938else if (jQuery('[name=currencies]').size() && jQuery('[name=currencies] option[value=' + cookieCurrency + ']').size() === 0) {
1939  Currency.currentCurrency = shopCurrency;
1940  Currency.cookie.write(shopCurrency);
1941}
1942else if (cookieCurrency === shopCurrency) {
1943  Currency.currentCurrency = shopCurrency;
1944  Currency.convertAll(shopCurrency, cookieCurrency);
1945}
1946else {
1947  Currency.convertAll(shopCurrency, cookieCurrency);
1948}
1949jQuery('[name=currencies]').val(Currency.currentCurrency).change(function() {
1950  var newCurrency = jQuery(this).val();
1951  
1952  
1953    Currency.cookie.write(newCurrency)
1954    if ('customers' == 'cart') {
1955      const params = new URLSearchParams(window.location.search);
1956      params.set('delete_cache', 1);
1957      window.location.search = params;
1958    } else {
1959      window.location.reload();
1960    }
1961  
1962});
1963var original_selectCallback = window.selectCallback;
1964var selectCallback = function(variant, selector) {
1965  var currencies = null;
1966  original_selectCallback(variant, selector);
1967  if(typeof jQuery('[name=currencies]').val() == "undefined"){
1968    currencies = shopCurrency;
1969  }
1970  else{
1971    currencies = jQuery('[name=currencies]').val();
1972  }
1973  Currency.convertAll(shopCurrency, currencies);
1974  jQuery('.selected-currency').text(Currency.currentCurrency);
1975};
1976$('body').on('ajaxCart.afterCartLoad', function(cart) {
1977  Currency.convertAll(shopCurrency, jQuery('[name=currencies]').val());
1978  jQuery('.selected-currency').text(Currency.currentCurrency);  
1979});
1980jQuery('.selected-currency').text(Currency.currentCurrency);
1981</script>
1981
1982
1983
1984  
1984<script>
1985
1986  /*
1987
1988    ------
1989    Events
1990    ------
1991
1992    pages/viewed
1993
1994    customers/signup
1995
1996    customers/login
1997
1998    products/searched
1999
2000    collections/viewed
2001
2002    products/viewed
2003
2004    products/shared
2005
2006    wishlists/item_added
2007
2008    carts/items_added
2009
2010    carts/viewed
2011
2012    carts/item_removed
2013
2014    checkouts/initiated
2015
2016    checkouts/shipping_info_added
2017
2018    checkouts/payment_info_added
2019
2020    checkouts/completed
2021
2022    orders/placed
2023
2024    orders/purchased
2025
2026    payments/captured
2027
2028    payments/failed
2029
2030  */
2031
2032  window.__latest_cart = window.__latest_cart || null;
2033
2034  const _selector = document.querySelector.bind(document),
2035        _selectorAll = document.querySelectorAll.bind(document)
2036
2037  document.addEventListener('DOMContentLoaded', (event) => {
2038
2039    const default_currency = getCookie("currency")
2040    const customer_id = window.__st.cid
2041    const template    = window.__st.p
2042
2043    onPageView()
2044
2045    //-----------------------//
2046    //        Configs        //
2047    //-----------------------//
2048
2049    window.dataLayer = window.dataLayer || []
2050
2051    Array.prototype.last = Array.prototype.last || function() {
2052      return this[this.length - 1] || null
2053    }
2054
2055    Array.prototype.first = Array.prototype.first || function() {
2056      return this[0] || null
2057    }
2058
2059    //----------------------//
2060    //       Triggers       //
2061    //----------------------//
2062
2063    const XHR = window.XMLHttpRequest
2064
2065    function xhr() {
2066
2067      const xhr = new XHR()
2068
2069      xhr.addEventListener("readystatechange", function() {
2070
2071        if(xhr.readyState != 4) return
2072
2073        try {
2074
2075          const response_url = xhr.responseURL
2076
2077          if (response_url.includes("cart/add")) {
2078
2079            window.__latest_cart = JSON.parse(xhr.response)
2080
2081            onCartItemsAdded() // ok
2082
2083          }
2084
2085          if (response_url.includes("cart/remove_item_quantity")) {
2086
2087            window.__latest_cart = JSON.parse(xhr.response)
2088
2089            onCartItemRemoved() // ok
2090
2091          }
2092
2093          if (response_url.includes("new_cart?retrieve=true")) {
2094
2095            result = JSON.parse(xhr.response)
2096
2097            if (result.cart) {
2098              window.__latest_cart = result.cart
2099            }
2100
2101          }
2102
2103        } catch(e) {
2104
2105          console.error(e)
2106
2107        }
2108
2109      }, false);
2110
2111      return xhr
2112
2113    }
2114
2115    window.XMLHttpRequest = xhr
2116
2117    switch(template) {
2118
2119      case 'cart': onCartView() // ok
2120      break
2121      case 'product': onProductView() // ok
2122      break
2123      case 'collection': onCollectionView() // ok
2124      break
2125      case 'blog': onBlogView()
2126      break
2127      case 'article': onArticleView()
2128      break
2129      case 'payment_completed': onOrderPlace()
2130      break
2131      case 'payment_fail': onPaymentFail()
2132      break
2133
2134    }
2135
2136    // _selector('form[action="/checkout/payments"]').addEventListener("submit", onPaymentInfoAdded(_selector('form[action="/checkout/payments"]')))
2137    if (_selector('form[action="/checkout/detail"]'))                            _selector('form[action="/checkout/detail"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/detail"]'))})  // ok
2138    if (_selector('form[action="/checkout/shipping"]'))                          _selector('form[action="/checkout/shipping"]').addEventListener("submit", ()=>{onShippingInfoAdded(_selector('form[action="/checkout/shipping"]'))})  // ok
2139    if (_selector('form[action="/account/register"]'))                           _selector('form[action="/account/register"]').addEventListener("submit", onSignUp)  // ok
2140    if (_selector('form[action="/account/login"]'))                              _selector('form[action="/account/login"]').addEventListener("submit", onLogin)  // ok
2141    if (_selector('form[action="/search"]'))                                     _selector('form[action="/search"]').addEventListener("submit", onProductSearch()) // ok
2142    if (_selector('#line-login-btn'))                                            _selector('#line-login-btn').addEventListener('click', onLineLogin) // ok
2143    if (_selector('#PlaceOrder'))                                                _selector('#PlaceOrder').addEventListener("click", ()=>{onCheckoutComplete(_selector('form[action="/checkout/payments"]'))});  // ok
2144    if (_selector('#add_wishlist'))                                              _selector('#add_wishlist').addEventListener("click", onWishlistItemAdded) // ok
2145    if (_selectorAll('a[href="/account/logout"]'))                               _selectorAll('a[href="/account/logout"]').forEach(logoutButton => logoutButton.addEventListener("click", onLogout)) // ok
2146    if (_selector('.CartDrawerTrigger.cart-page-link'))                          _selector('.CartDrawerTrigger.cart-page-link').addEventListener("click", onCartView) // ok
2147    if (_selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link'))    _selector('.CartDrawerTrigger.cart-page-link.mobile-cart-page-link').addEventListener("click", onCartView) // ok
2148    if (_selectorAll('a[class^="share-"]'))                                      _selectorAll('a[class^="share-"]').forEach(shareButton => shareButton.addEventListener("click", ()=>{onProductShare(shareButton)}) ) // ok
2149    if (_selectorAll('[name$="checkout"]'))                                      _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate))
2150
2151    // For append elements
2152    const bodyMutationObserver = new MutationObserver(() => {
2153      if (_selector('#form__spc #PlaceOrder'))             _selector('#form__spc #PlaceOrder').addEventListener("click", onSinglePageCheckout) // ok
2154      if (_selectorAll('[name$="checkout"]'))              _selectorAll('[name$="checkout"]').forEach(checkoutButton => checkoutButton.addEventListener("click", onCheckoutInitiate))
2155    });
2156    bodyMutationObserver.observe(_selector("body"), {subtree: true, childList: true});
2157
2158    //------------------------------//
2159    //        Event handlers        //
2160    //------------------------------//
2161
2162    function onPageView() {
2163
2164      EasyStore.Event.dispatch('pages/viewed', {
2165        page: {
2166          type: template,
2167          title: document.title,
2168          description: _selector('meta[name=description]') ? _selector('meta[name=description]').getAttribute('content') : null,
2169          url: location.href,
2170        }
2171      })
2172
2173    }
2174
2175    function onSignUp() {
2176
2177      const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/)
2178      const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/)
2179
2180      const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "")
2181
2182      let data = {}
2183
2184      if (email_regex.test(email_or_phone)) {
2185        data.method = 'email'
2186        data.email = email_or_phone
2187      }
2188
2189      if (phone_regex.test(email_or_phone)) {
2190        data.method = "phone"
2191        data.phone = email_or_phone
2192      }
2193
2194      if (!data.method) return
2195
2196      EasyStore.Event.dispatch('customers/signup', data)
2197
2198    }
2199
2200    function onLogin() {
2201
2202      const email_regex = new RegExp(/^[a-zA-Z0-9.!#$%&"*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/)
2203      const phone_regex = new RegExp(/^(\+?6?01)[0-46-9]-*[0-9]{7,8}$/)
2204
2205      const email_or_phone = _selector(`input[name="customer[email_or_phone]"]`).value.replace("+", "").replace(/\s+/, "")
2206
2207      let data = {}
2208
2209      if (email_regex.test(email_or_phone)) {
2210        data.method = 'email'
2211        data.email = email_or_phone
2212      }
2213
2214      if (phone_regex.test(email_or_phone)) {
2215        data.method = "phone"
2216        data.phone = email_or_phone
2217      }
2218
2219      if (!data.method) return
2220
2221      EasyStore.Event.dispatch('customers/login', data)
2222
2223    }
2224
2225    function onLineLogin() {
2226
2227      EasyStore.Event.dispatch('customers/login', { method: 'line' })
2228
2229    }
2230
2231    function onLogout() {
2232
2233      EasyStore.Event.dispatch('customers/logout', { customer_id })
2234
2235    }
2236
2237    function onBlogView() {
2238
2239      const blog = ""
2240
2241      EasyStore.Event.dispatch('blogs/viewed', { blog })
2242
2243    }
2244
2245    function onArticleView() {
2246
2247      const article = ""
2248
2249      EasyStore.Event.dispatch('articles/viewed', { article })
2250
2251    }
2252
2253    function onProductSearch() {
2254
2255      const query = _selector('input[name=q]').value
2256
2257      if (!query) return
2258
2259      EasyStore.Event.dispatch('products/searched', { query })
2260
2261    }
2262
2263    function onCollectionView() {
2264
2265      const collection = ""
2266
2267      EasyStore.Event.dispatch('collections/viewed', { collection })
2268
2269    }
2270
2271    function onProductView() {
2272
2273      const product = ""
2274
2275      EasyStore.Event.dispatch("products/viewed", { product })
2276
2277    }
2278
2279    function onProductShare(el) {
2280
2281      const product = ""
2282
2283      const channel = el.getAttribute("class").split("-").last()
2284
2285      EasyStore.Event.dispatch('products/shared', { product, channel })
2286
2287    }
2288
2289    function onWishlistItemAdded() {
2290
2291      let product  = ""
2292      const quantity = _selector("#Quantity").value
2293
2294      EasyStore.Event.dispatch('wishlists/item_added', { product })
2295
2296    }
2297
2298    async function onCartItemsAdded() {
2299
2300      const cart = await getCart()
2301
2302      if(cart && cart.items != undefined && cart.items.length > 0) {
2303
2304        EasyStore.Event.dispatch('carts/item_added', { cart })
2305
2306      }
2307
2308    }
2309
2310    async function onCartView() {
2311
2312      const cart = await getCart()
2313
2314      EasyStore.Event.dispatch('carts/viewed', { cart })
2315
2316    }
2317
2318    async function onCartItemRemoved() {
2319
2320      const cart = await getCart()
2321
2322      cart.items = []
2323
2324      if(cart) {
2325
2326        EasyStore.Event.dispatch('carts/item_removed', { cart })
2327
2328      }
2329
2330    }
2331
2332    async function onCheckoutInitiate() {
2333
2334      const cart = await getCart()
2335
2336      EasyStore.Event.dispatch('checkouts/initiated', { cart })
2337
2338    }
2339
2340    async function onShippingInfoAdded(form) {
2341      let checkout = getCheckout()
2342
2343      let form_data = {}
2344      new FormData(form).forEach((value, key) => form_data[key] = value)
2345
2346      let shipping_tier = null
2347
2348      if (form_data.type && form_data.type.startsWith("r_pickup")) {
2349        shipping_tier = `Pickup - ${form_data.pick_location}`
2350      }
2351
2352      if (form_data.s_id) {
2353        shipping_tier = _selector(`input[id='`+form_data.s_id+`']`).getAttribute("data-shipping-name")
2354      }
2355
2356      if (!shipping_tier) return
2357
2358      EasyStore.Event.dispatch('checkouts/shipping_info_added', { checkout, shipping_tier })
2359
2360    }
2361
2362    async function onPaymentInfoAdded(form) {
2363
2364      let checkout = getCheckout()
2365
2366      let payment_type = new FormData(form).get('payment_method')
2367
2368      EasyStore.Event.dispatch("checkouts/payment_info_added", { checkout, payment_type })
2369
2370    }
2371
2372    async function onOrderPlace() {
2373
2374      let cart_token  = getCookie("cart_js")
2375      let previous_cart_token = getCookie("previous_cart_ga4_js")
2376
2377      if (previous_cart_token && previous_cart_token == cart_token) {
2378        // Prevent duplicate purchase tracking
2379        return
2380      }
2381
2382      let order = getOrder()
2383
2384      EasyStore.Event.dispatch('orders/placed', { order })
2385
2386      if(order.is_manual_payment) {
2387
2388        EasyStore.Event.dispatch('orders/purchased', { order })
2389
2390      }
2391
2392      const last_transaction = order.transactions.last()
2393
2394      if (last_transaction.status) {
2395
2396        EasyStore.Event.dispatch('orders/purchased', { order })
2397        EasyStore.Event.dispatch('payments/captured', { order })
2398
2399      }
2400
2401    }
2402
2403    async function onPaymentFail() {
2404
2405      const order = getOrder()
2406
2407      EasyStore.Event.dispatch('payments/failed', { order })
2408
2409    }
2410
2411    async function onCheckoutComplete(form) {
2412
2413      onPaymentInfoAdded(form)
2414
2415      const checkout = getCheckout()
2416
2417      EasyStore.Event.dispatch('checkouts/completed', { checkout })
2418
2419    }
2420
2421    async function onSinglePageCheckout() {
2422
2423      // let checkout = $("[data-app-checkout]").data("app-checkout")
2424
2425      let checkout = getCheckout()
2426
2427      // const payment_type = _selector("#app_spc_payment_method").find(`[class*="label-content"]`).first().find("b").first().text()
2428      const payment_type = _selector("#app_spc_payment_method").getElementsByClassName('label-content')[0].getElementsByTagName('b')[0].innerHTML
2429
2430      const shipping_method = _selector("#delivery_method").value
2431
2432      let shipping_tier = null
2433      let app_spc_customer_info_label = _selector("#app_spc_customer_info").getElementsByClassName('label-content')
2434      if (shipping_method == "shipping") {
2435        shipping_tier = app_spc_customer_info_label[app_spc_customer_info_label.length - 1].getElementsByTagName('b')[0].innerHTML
2436      }
2437
2438      if (shipping_method == "pickup") {
2439        shipping_tier = app_spc_customer_info_label[0].innerHTML
2440      }
2441
2442      if (shipping_tier) {
2443
2444        EasyStore.Event.dispatch('checkouts/shipping_info_added', {
2445          checkout,
2446          shipping_tier,
2447        })
2448
2449      }
2450
2451      if (payment_type) {
2452
2453        EasyStore.Event.dispatch('checkouts/payment_info_added', {
2454          checkout,
2455          payment_type,
2456        })
2457
2458      }
2459
2460      EasyStore.Event.dispatch('checkouts/completed', { checkout })
2461
2462    }
2463
2464  })
2465
2466
2467  //-----------------------//
2468  //       Functions       //
2469  //-----------------------//
2470
2471  function getCookie(name) {
2472
2473    name += "="
2474
2475    decodedCookie = decodeURIComponent(document.cookie)
2476
2477    ca = decodedCookie.split(";")
2478
2479    for(i = 0; i < ca.length; i++) {
2480      c = ca[i]
2481      while (c.charAt(0) == " ") {
2482        c = c.substring(1)
2483      }
2484      if (c.indexOf(name) == 0) {
2485        return c.substring(name.length, c.length)
2486      }
2487    }
2488
2489    return ""
2490
2491  }
2492
2493  const parsePrice = price => {
2494    if(typeof price === 'string') {
2495      return parseFloat(price.split(',').join(''))
2496    }
2497
2498    return price
2499  }
2500
2501  const requestCart = async (method, data) => {
2502
2503  let response = await fetch('/cart.json', {method: 'GET',headers: {'Content-Type': 'application/json'}})
2504    result = await response.json()
2505
2506    return result.cart
2507
2508  }
2509  const getCart = async (latest = false) => {
2510
2511    let cart = window.__latest_cart
2512
2513    const cart_invalid = !cart || !cart.items || (cart.total_price > 0 && !cart.items.length)
2514
2515    if(latest || cart_invalid) {
2516      cart = await requestCart()
2517    }
2518
2519    cart.items = cart.items || []
2520
2521    return mapCart(cart)
2522
2523  }
2524
2525  const getCheckout = async () => {
2526    mapCheckout(window.__latest_cart || await requestCart())
2527  }
2528
2529  const getOrder = async () => {
2530    mapOrder(window.__latest_cart || await requestCart())
2531  }
2532
2533  //-----------------------//
2534  //        Mappers        //
2535  //-----------------------//
2536
2537  const fallbackAttribute = (object, attribute) => {
2538
2539    if(!Array.isArray(attribute)) {
2540      attribute = [attribute]
2541    }
2542
2543    let final_value = null
2544
2545    do {
2546
2547      final_value = object[attribute.shift()]
2548
2549    } while(!final_value && attribute.length)
2550
2551    return final_value
2552
2553  }
2554
2555  const map = (object, mapper) => {
2556
2557    const newObject = {}
2558
2559    for(const key in mapper) {
2560
2561      // Handle different keys between new and old format
2562      newObject[key] = fallbackAttribute(object, mapper[key])
2563
2564      // Cast price to float
2565      if(newObject[key] && ['price', 'amount', 'discount', 'discounts'].some(x => key.endsWith(x))) {
2566        newObject[key] = parsePrice(newObject[key])
2567      }
2568
2569      if(newObject[key] === undefined) {
2570        delete newObject[key]
2571      }
2572
2573    }
2574
2575    return newObject
2576
2577  }
2578
2579  const mapCart = cart => {
2580
2581    const oldCart = cart
2582
2583    const mapper = {
2584      id: 'id',
2585      currency: 'currency',
2586      item_count: 'item_count',
2587      items: 'items',
2588      total_price: 'total_price',
2589      latest_items: 'latest_items'
2590    }
2591
2592    cart = map(cart, mapper)
2593
2594    const discounts = (oldCart.storewide_discounts || []).concat((oldCart.voucher_discounts || []))
2595
2596    cart.discount_applications = discounts.map(discount => ({
2597      title: discount.voucher_code || null,
2598      value: parsePrice(discount.amount),
2599    }))
2600
2601    cart.original_total_price = cart.items.length
2602    ? cart.items
2603      .map(item => item.original_price)
2604      .reduce((sum, price) => sum + price)
2605    : 0
2606
2607    cart.total_discount = cart.discount_applications.length
2608    ? cart.discount_applications
2609      .map(discount => parsePrice(discount.value))
2610      .reduce((sum, value) => sum + value)
2611    : 0
2612
2613    cart.items = cart.items.map(item => mapLineItem(item))
2614
2615    return cart
2616
2617  }
2618
2619  const mapCheckout = checkout => {
2620
2621    const mapper = {
2622      note: 'note',
2623      attributes: 'note_attributes',
2624      billing_address: 'billing_address',
2625      currency: 'currency',
2626      customer_id: 'customer_id',
2627      discounts_amount: 'total_discount',
2628      id: 'id',
2629      line_items: 'order_item',
2630      order_number: 'order_number',
2631      shipping_address: 'shipping_address',
2632      shipping_price: 'shipping_tax',
2633      shipping_method: 'shipping_method_name',
2634      tax_price: 'total_tax',
2635    }
2636
2637    checkout = map(checkout, mapper)
2638
2639    checkout.requires_shipping = checkout.line_items.some(item => item.shipping_required)
2640
2641    checkout.line_items = checkout.line_items.map(item => mapLineItem(item))
2642
2643    return checkout
2644
2645  }
2646
2647  const mapOrder = order => {
2648
2649    const mapper = {
2650      attributes: 'note_attributes',
2651      billing_address: 'billing_address',
2652      cancelled: 'is_cancelled',
2653      cancelled_at: 'cancelled_at',
2654      created_at: 'created_at',
2655      customer_id: 'customer_id',
2656      // discount_applications: 'discount_applications',
2657      email: 'email',
2658      financial_status: 'financial_status',
2659      fulfillment_status: 'fulfillment_status',
2660      line_items: 'order_item',
2661      note: 'note',
2662      order_number: 'order_number',
2663      phone: 'phone',
2664      shipping_address: 'shipping_address',
2665      shipping_methods: 'shipping_methods',
2666      shipping_price: 'total_shipping',
2667      subtotal_price: 'subtotal_price',
2668      // tax_lines: 'tax_lines',
2669      tax_price: 'total_tax',
2670      total_discounts: 'total_discount',
2671      total_net_amount: 'total_amount_include_transaction',
2672      total_price: 'total_price',
2673      transactions: 'transaction_records',
2674      is_manual_payment: 'is_manual_payment',
2675    }
2676
2677    order.email = order.billing_address.email
2678    order.phone = order.billing_address.phone
2679    order.shipping_method = order.shipping_method_name
2680
2681    order = map(order, mapper)
2682
2683    order.line_items = order.line_items.map(item => mapLineItem(item))
2684    order.transactions = order.transactions.map(transaction => mapTransaction(transaction))
2685
2686    return order
2687
2688  }
2689
2690  const mapLineItem = line_item => {
2691
2692    const old_line_item = line_item
2693
2694    const mapper = {
2695      final_price: 'price',
2696      image: 'img_url',
2697      message: 'message',
2698      original_line_price: 'original_line_price',
2699      original_price: 'original_price',
2700      properties: 'properties',
2701      quantity: 'quantity',
2702      requires_shipping: 'shipping_required',
2703      sku: 'sku',
2704      taxable: 'taxable',
2705      title: 'product_name',
2706      product_name: 'product_name',
2707      url: 'url',
2708      product_id: 'product_id',
2709      variant_id: 'variant_id',
2710      id: ['id', 'i_id'],
2711    }
2712
2713    line_item = map(line_item, mapper)
2714
2715    line_item.product_id = line_item.product_id || (old_line_item.product && old_line_item.product.id) || null
2716    line_item.variant_id = line_item.variant_id || (old_line_item.variant && old_line_item.variant.id) || null
2717    line_item.image      = line_item.image || (old_line_item.image && old_line_item.image.url) || null
2718
2719    return line_item
2720
2721  }
2722
2723  const mapTransaction = transaction => {
2724
2725    const mapper = {
2726      amount: 'amount',
2727      created_at: 'created_at',
2728      gateway: 'gateway_type',
2729      id: 'id',
2730      status: 'status',
2731    }
2732
2733    transaction = map(transaction, mapper)
2734
2735    return transaction
2736
2737  }
2738
2739
2740</script>
2740
2741
2742</div>
2743
2744  
2745    
2746<style>
2747  #CartTemplate{
2748    min-height: 80vh;
2749  }
2750  .cart-drawer .cart__row .small--one-whole,
2751  .cart-drawer .cart-sticky-button-wrapper{
2752    width: 100%;
2753  }
2754  .cart-drawer .promotion__code-input .input-group{
2755    margin-top: 20px;
2756    max-width: 100%;
2757  }
2758  .cart-drawer-wrapper{
2759    display: flex;
2760    flex-wrap: wrap;
2761    flex-direction: row;
2762  }
2763  .cart-drawer-wrapper > div{
2764    width: 100%;
2765  }
2766  vouchers-modal .vouchers-modal.active ,
2767  vouchers-modal #vouchers-modal-backdrop.active{
2768    z-index: 2147483647;
2769  }
2770</style>
2771
2772<div id="CartDrawer" class="cart-drawer" data-fetch="0">
2773  
2774
2775  <div class="cart-drawer-wrapper">
2776    <div id="cart-promotion-top"></div>
2777
2778
2779    <div id="CartTemplate">
2780      
2781
2782
2783  
2784
2785  <div id="noCartItem" class="cart-drawer-content">
2786    <div class="cart-drawer-content-wrapper text-center">
2787      <div class="section-header">
2788        <span></span>
2789        <span class="CartDrawerTrigger icon icon-x"></span>
2790      </div>
2791      <div class="section-header__title h2">Your cart is currently empty.</div>
2792      <a class="btn btn--secondary" href="/collections/all">Continue shopping</a>
2793    </div>
2794  </div>
2795
2796
2797
2798    </div>
2799
2800    <link href="/assets/css/promotion.css?v2.94" rel="stylesheet" type="text/css" media="screen" />
2801<div id="cart-promotion-section"></div>
2802
2803<script>var shop_money_format = "<span class=money data-ori-price='{{amount}}'>RM {{amount}} </span>";</script>
vendor: 1 bytes, line 2803
2803
2804<script src="/assets/js/promotion/promotion.js?v1.11" type="text/javascript"></script>
2804
2805
2806<script>
2807
2808    window.EasyStore = window.EasyStore || {};
2809    window.EasyStore.Promotion = window.EasyStore.Promotion || {};
2810
2811    var get_cart_promo_initial = false,
2812        current_template = 'customers';
2813
2814    window.EasyStore.Promotion.updateCartPromotion = function (){
2815        get_cart_promo_initial = true
2816        $.ajax({
2817        type: "GET",
2818        dataType: 'json',
2819        url: "/new_cart/promotion",
2820        success: function(response){
2821            $("#cart-promotion-section").html(response["cart/content_bottom"].trim());
2822            $("#cart-promotion-top").html(response["cart/content_top"].trim());
2823
2824            promoVariantDetailInitial()
2825        },
2826        error: function(xhr){
2827        }
2828        });
2829    }
2830
2831
2832    if(current_template == 'cart') {
2833        document.addEventListener("DOMContentLoaded", function() {
2834            window.EasyStore.Promotion.updateCartPromotion()
2835        });
2836    }
2837
2838</script>
vendor: 1 bytes, line 2838
2838
2839<script>
2840  document.addEventListener('DOMContentLoaded', function () {
2841    window._getVoucherErrorTranslation = Object.assign(window._getVoucherErrorTranslation || {}, {
2842      "condition_not_matched":    "Voucher condition not matched",
2843      "promotion_unavailable":    "This promotion is currently unavailable",
2844      "available_on":             "Available on channels",
2845      "available_on_only":        "Available on channels only",
2846      "available_with_locations": "Available on channels (locations only)",
2847      "pos_at_locations":         "Retail Store at locations only",
2848      "channel_website":          "Website",
2849      "channel_mobile":           "Mobile Apps",
2850      "channel_pos":              "Retail Store"
2851    });
2852  });
2853</script>
2853
2854
2855  </div>
2856  
2857
2858  
2859</div>
2860
2861<div id="toast"><div id="toastContent"></div></div>
2862<style>
2863  .cart-drawer .cart-drawer-content .cart-sticky-button-wrapper a.btn.CartDrawerTrigger{margin-bottom: 10px !important;}
2864  #toastContent a{color: #fff;text-decoration: underline;margin-top: 10px;display: block;}
2865  #toastContent .svg-icon{margin-right: 8px;margin-top: -1px;}
2866</style>
2867
2868<script type="text/javascript">
2869  $('body').on("submit", "#CartForm", function() {
2870    $(this).find('[type=submit]').addClass('btn--loading');
2871  });
2872  
2873  $("input[name=current_currency]").val($( "select.currency-picker" ).val());
2874  $( "select.currency-picker" ).change(function(){
2875    $("select.currency-picker").val($(this).val());
2876    url=window.location.href;
2877    newParam="currency=" + $( "select.currency-picker" ).val();
2878    if(url.indexOf("currency=")===-1){
2879      separator = (url.indexOf("?")===-1)?"?":"&";
2880      newUrl= url + separator + newParam;
2881    }else{
2882      oldParam= new URL(url);
2883      oldParam = oldParam.searchParams.get("currency");
2884      newParam= $(this).val();
2885      newUrl=url.replace(oldParam,newParam);
2886    }
2887    $("input[name=current_currency]").val($( "select.currency-picker" ).val());
2888    // window.location.href =newUrl;
2889    $('#CartDrawer').attr('data-fetch', 0);
2890  });
2891
2892  $("body").on("click", ".cart__remove", function() {
2893    $('#CartTemplate').addClass('is-loading');
2894    $.ajax({
2895      type: 'POST',
2896      url: '/cart/remove_item_quantity',
2897      data: {
2898        variant_id: $(this).data( "variant-id"),
2899        item_id: $(this).data( "item-id"),
2900        quantity: $(this).data( "quantity"),
2901        i_id: $(this).data("i_id"),
2902      },
2903      dataType: 'json',
2904      success: function(response){
2905
2906        theme.cartDrawer(response);
2907        $('#CartTemplate').removeClass('is-loading');
2908
2909        if (window.checkProductProperties !== undefined){
2910          window.checkProductProperties();
2911        }      
2912      },
2913      error: function(xhr){
2914        console.log('error',xhr);
2915        $('#CartTemplate').removeClass('is-loading');
2916      }
2917    });
2918
2919  });
2920
2921
2922  $('body').on("click", "#applycode",function() {
2923    
2924    if($("input[name='voucher_code']").val() != '') {
2925
2926      $('#CartTemplate').addClass('is-loading');
2927
2928      $.ajax({
2929        type: 'POST',
2930        url: '/new_cart/voucher',
2931        data: {
2932          voucher_code: $("input[name='voucher_code']").val(),
2933          category: 'create'
2934        },
2935        dataType: 'json',
2936        success: function(response){
2937
2938          // console.log(response);
2939
2940          if(response.error != undefined){
2941            
2942            if(response.error.message != undefined) popToast(response.error.message); 
2943          
2944            $("input[name='voucher_code']").val('')
2945          
2946          } 
2947          
2948          if(response.cart_content != undefined) theme.cartDrawer(response); 
2949
2950          
2951          $('#CartTemplate').removeClass('is-loading');
2952          
2953        },
2954        error: function(xhr){
2955          console.log('error',xhr);
2956          $('#CartTemplate').removeClass('is-loading');
2957        }
2958      });
2959
2960    }
2961
2962  });
2963
2964
2965  $("body").on("click", ".remove_voucher_btn", function() {
2966        $('#CartTemplate').addClass('is-loading');
2967        $.ajax({
2968          type: 'DELETE',
2969          url: '/new_cart/voucher',
2970          data: {
2971            category: 'remove',
2972            order_discount_id: $(this).data( "discount-id")
2973          },
2974          dataType: 'json',
2975          success: function(data){
2976            // console.log(data);
2977            theme.cartDrawer(data);
2978            $('#CartTemplate').removeClass('is-loading');
2979          },
2980          error: function(xhr){
2981            console.log('error',xhr);
2982            $('#CartTemplate').removeClass('is-loading');
2983          }
2984        });
2985
2986    });
2987  
2988
2989  theme.cartDrawer = function(data){
2990    
2991      $('#CartDrawer').attr('data-fetch', 1);
2992      $('#CartTemplate').addClass('is-loading');
2993
2994      
2995      if(typeof data.cart_content  == 'string'){
2996        $('#CartTemplate').html(data.cart_content);
2997      }
2998
2999      let cart_item_count = data.item_count || data.cart.item_count;
3000
3001      if(cart_item_count > 0){
3002        $('.cart-count').removeClass('hidden-count');
3003      }else{
3004        $('.cart-count').addClass('hidden-count');
3005      }
3006
3007      $('.cart-count').text(cart_item_count);
3008      $('#CartTemplate').removeClass('is-loading');
3009      $(".cart-drawer-content").animate({ scrollTop: 0 });
3010
3011      if(window.EasyStore != undefined && window.EasyStore.Promotion != undefined && window.EasyStore.Promotion.updateCartPromotion != undefined) window.EasyStore.Promotion.updateCartPromotion()
3012
3013  }
3014
3015  theme.fetchCartDrawer = function(data){
3016      $('#CartTemplate').addClass('is-loading');
3017      $.ajax({
3018        url: '/new_cart?retrieve=true',
3019        type: 'GET',
3020        success: function(data, status) {
3021          // console.log(data);
3022          theme.cartDrawer(data);
3023
3024          $('#CartTemplate').removeClass('is-loading');
3025
3026          if (window.checkProductProperties !== undefined){
3027            window.checkProductProperties();
3028          }
3029        },
3030        error: function(XMLHttpRequest, textStatus) {
3031          console.log('error',XMLHttpRequest,textStatus);
3032          $('#CartTemplate').removeClass('is-loading');
3033        }
3034      });
3035  }
3036
3037  theme.updateCartDrawer = function(data){
3038    $('#CartTemplate').addClass('is-loading');
3039
3040    $.ajax({
3041      url: '/new_cart/update',
3042      type: 'PUT',
3043      dataType: 'json',
3044      data: $('#CartDrawer form').serialize(),
3045      success: function(data, status) {
3046        theme.cartDrawer(data);
3047
3048        if (window.checkProductProperties !== undefined){
3049          window.checkProductProperties();
3050        }
3051      },
3052      error: function(XMLHttpRequest, textStatus) {
3053        console.log('error',XMLHttpRequest,textStatus);
3054      }
3055    });
3056  }
3057
3058  function debounce(func, wait, immediate) {
3059    var timeout;
3060    return function() {
3061        var context = this, args = arguments;
3062        var later = function() {
3063            timeout = null;
3064            if (!immediate) func.apply(context, args);
3065        };
3066        var callNow = immediate && !timeout;
3067        clearTimeout(timeout);
3068        timeout = setTimeout(later, wait);
3069        if (callNow) func.apply(context, args);
3070    };
3071  };
3072
3073  $('body').on("change", 'input.cart__quantity-selector', function (){
3074    theme.updateCartDrawer();
3075  });
3076
3077
3078  $('#updateCartDrawer').click(function() {
3079    theme.updateCartDrawer();
3080  });
3081
3082  $('body').on("click", ".btn-qty-adjust", function() {
3083
3084    var $button = $(this);
3085    var oldValue = $button.parent().find("input.cart__quantity-selector").val();
3086
3087    if ($button.attr('data-adjust') == 1) {
3088      var newVal = parseFloat(oldValue) + 1;
3089    } else {
3090    // Don't allow decrementing below zero
3091      if (oldValue > 0) {
3092        var newVal = parseFloat(oldValue) - 1;
3093      } else {
3094        newVal = 0;
3095      }
3096    }
3097
3098    $button.parent().find("input").val(newVal);
3099  });
3100    
3101  $('body').on("click", ".btn-qty-adjust", debounce(function() {
3102    theme.updateCartDrawer();
3103  },350));
3104
3105  $('button.checkout').click(function() {
3106    $(this).addClass('btn--loading');
3107  });
3108
3109  var add_cart_success_html = '<svg class="svg-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"> <g> <g> <path d="M383.841,171.838c-7.881-8.31-21.02-8.676-29.343-0.775L221.987,296.732l-63.204-64.893 c-8.005-8.213-21.13-8.393-29.35-0.387c-8.213,7.998-8.386,21.137-0.388,29.35l77.492,79.561 c4.061,4.172,9.458,6.275,14.869,6.275c5.134,0,10.268-1.896,14.288-5.694l147.373-139.762 C391.383,193.294,391.735,180.155,383.841,171.838z"/> </g> </g> <g> <g> <path d="M256,0C114.84,0,0,114.84,0,256s114.84,256,256,256s256-114.84,256-256S397.16,0,256,0z M256,470.487 c-118.265,0-214.487-96.214-214.487-214.487c0-118.265,96.221-214.487,214.487-214.487c118.272,0,214.487,96.221,214.487,214.487 C470.487,374.272,374.272,470.487,256,470.487z"/> </g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> </svg>';
3110      add_cart_success_html += 'Added to cart <br><a class="CartDrawerTrigger">View cart</a>';
3111
3112  function popToast(content) {
3113    var x = document.getElementById("toast"),
3114        y = document.getElementById("toastContent");
3115
3116    y.innerHTML = content;
3117    x.className += " show";
3118    
3119    var hideToast = setTimeout(function(){ x.className = x.className.replace(" show", ""); }, 3000);
3120  }
3121
3122</script>
3122
3123
3124<link href="/assets/css/vouchers.css?v1.2" rel="stylesheet" type="text/css" media="screen" />
3125<link href="/assets/account/vouchers/vouchers.css" rel="stylesheet" type="text/css" media="screen" />
3126<link href="/assets/account/vouchers/voucher-widget.css" rel="stylesheet" type="text/css" media="screen" />
3127<script src="/assets/js/promotion/vouchers.js?v1.3" type="text/javascript" ></script>
vendor: 1 bytes, line 3127
3127
3128<script src="/assets/account/vouchers/voucher-widget.js" type="text/javascript" ></script>
3128
3129
3130<vouchers-modal>
3131  <div id="vouchers-modal-backdrop" class="vouchers-modal__close"></div>
3132  <div class="vouchers-modal-wrapper page-width">
3133    <div id="vouchers-modal" class="vouchers-modal focus-inset" aria-modal="true" role="dialog" tabindex="-1">
3134      <div class="vouchers-modal__header">
3135        <div class="vouchers-modal__heading">Vouchers</div>
3136        <button type="button" class="vouchers-modal__close modal__close-button link link--text focus-inset" aria-label="accessibility.close">
3137          <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" role="presentation" class="icon icon-close " fill="none" viewBox="0 0 18 17">
3138            <path d="M.865 15.978a.5.5 0 00.707.707l7.433-7.431 7.579 7.282a.501.501 0 00.846-.37.5.5 0 00-.153-.351L9.712 8.546l7.417-7.416a.5.5 0 10-.707-.708L8.991 7.853 1.413.573a.5.5 0 10-.693.72l7.563 7.268-7.418 7.417z" fill="currentColor">
3139            </path>
3140          </svg>
3141        </button>
3142      </div>
3143
3144      <discount-input>
3145        <div class="field">
3146          <input type="text" id="input-discount_code" class="search__input field__input" name="voucher_code" placeholder="Discount code">
3147          <button type="button" name="apply" class="btn btn--secondary button button--secondary">Apply</button>
3148        </div>
3149        <div class="form__message hidden" tabindex="-1" autofocus>
3150          <svg aria-hidden="true" focusable="false" role="presentation" class="icon icon-error " viewBox="0 0 13 13">
3151            <circle cx="6.5" cy="6.50049" r="5.5" stroke="white" stroke-width="2"></circle>
3152            <circle cx="6.5" cy="6.5" r="5.5" fill="#EB001B" stroke="#EB001B" stroke-width="0.7"></circle>
3153            <path d="M5.87413 3.52832L5.97439 7.57216H7.02713L7.12739 3.52832H5.87413ZM6.50076 9.66091C6.88091 9.66091 7.18169 9.37267 7.18169 9.00504C7.18169 8.63742 6.88091 8.34917 6.50076 8.34917C6.12061 8.34917 5.81982 8.63742 5.81982 9.00504C5.81982 9.37267 6.12061 9.66091 6.50076 9.66091Z" fill="white"></path>
3154            <path d="M5.87413 3.17832H5.51535L5.52424 3.537L5.6245 7.58083L5.63296 7.92216H5.97439H7.02713H7.36856L7.37702 7.58083L7.47728 3.537L7.48617 3.17832H7.12739H5.87413ZM6.50076 10.0109C7.06121 10.0109 7.5317 9.57872 7.5317 9.00504C7.5317 8.43137 7.06121 7.99918 6.50076 7.99918C5.94031 7.99918 5.46982 8.43137 5.46982 9.00504C5.46982 9.57872 5.94031 10.0109 6.50076 10.0109Z" fill="white" stroke="#EB001B" stroke-width="0.7"></path>
3155          </svg>
3156          <div class="js-error-content"></div>
3157        </div>
3158      </discount-input>
3159      <br>
3160
3161      
3162      
3163        <div class="empty-vouchers_placeholder">No available vouchers</div>
3164      
3165
3166       <!-- For voucher widget -->
3167      
3167<script type="text/javascript">
3168        let settings = {"logo_use_image":"1","logo_img":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/8248207.jpeg?width=350&format=webp","footer_logo_img":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/8257285.png?width=350&format=webp","nav_below_logo":"","logo_alignment":"center","heading_font_family":["'HelveticaNeue','Helvetica Neue',Helvetica,Arial,sans-serif"],"left_aligned_logo":"0","favicon_enable":"1","favicon_img":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/8318815.jpeg","header_message":"","header_search_enable":true,"topbar_sticky":true,"footer_quicklinks_enable":true,"footer_quicklinks_linklist":"footer","footer_social_enable":true,"footer_show_credit_card_logo":"1","footer_show_methods_of_payment":true,"footer_visa":"1","footer_master":"1","footer_american_express":0,"footer_jcb":0,"footer_diners_club":0,"footer_discover":0,"footer_ssl":true,"show_footer_lines":"1","home_section_1":"highlight-section","home_section_2":"featured-product","home_section_3":"img-text-section","home_section_4":"parallax-section","home_section_5":"","home_section_6":"","featured_title":"","featured_1_img":"","featured_1_text":"","featured_1_link":"","featured_2_img":"","featured_2_text":"","featured_2_link":"","featured_3_img":"","featured_3_text":"","featured_3_link":"","featured_4_img":"","featured_4_text":"","featured_4_link":"","featured_5_img":"","featured_5_text":"","featured_5_link":"","featured_6_img":"","featured_6_text":"","featured_6_link":"","featured_7_img":"","featured_7_text":"","featured_7_link":"","featured_8_img":"","featured_8_text":"","featured_8_link":"","parallax_img":"","parallax_mobile_img":"","parallax_title":"","parallax_subtitle":"","parallax_button_text":"","parallax_button_link":"","parallax_full_width":"1","slider_home_auto":"1","slider_home_show_dots":"1","slider_home_rate":"4000","slider_home_transition":"fade","slider_full_screen":"0","slide_1":"1","slide_1_jpg":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/17889576.png?width=1500&format=webp","slide_1_mobile_jpg":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/17889577.png?width=900&format=webp","slide_1_link":"https:\/\/linktr.ee\/StudyGroupPTTI","slide_1_alt":"","slide_1_title":"","slide_1_subtitle":"","slide_1_button_text":"Daftar sekarang","slide_2":"1","slide_2_mobile_jpg":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/17808842.jpg?width=900&format=webp","slide_2_link":"https:\/\/ptti.onpay.my\/order\/form\/1104\/1033","slide_2_alt":"","slide_2_title":"","slide_2_subtitle":"","slide_2_button_text":"DAFTAR SEKARANG","slide_3":"","slide_3_jpg":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/17862245.png?width=1500&format=webp","slide_3_mobile_jpg":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/17862244.jpg?width=900&format=webp","slide_3_link":"https:\/\/ptti.onpay.my\/order\/form\/472\/1033","slide_3_alt":"","slide_3_title":"","slide_3_subtitle":"","slide_3_button_text":"Daftar sekarang","slide_4":"","slide_4_jpg":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/17873233.png?width=1500&format=webp","slide_4_mobile_jpg":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/17873235.png?width=900&format=webp","slide_4_link":"https:\/\/tinyurl.com\/batch10PTTI","slide_4_alt":"","slide_4_title":"","slide_4_subtitle":"","slide_4_button_text":"Join Channel Form 4","slide_5":"","slide_5_jpg":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/17852772.png?width=1500&format=webp","slide_5_mobile_jpg":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/17777593.jpg?width=900&format=webp","slide_5_link":"https:\/\/wa.link\/e0aw80","slide_5_alt":"","slide_5_title":"","slide_5_subtitle":"","slide_5_button_text":"Info lanjut","slide_6":"","slide_6_jpg":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/17850552.png?width=1500&format=webp","slide_6_mobile_jpg":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/17850562.png?width=900&format=webp","slide_6_link":"https:\/\/wa.me\/601133417834","slide_6_alt":"","slide_6_title":"","slide_6_subtitle":"","slide_6_button_text":"INFO LANJUT","testimonial_slide_img_crop":0,"testimonial_slide_1_img":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/15295405.png?width=1500&format=webp","testimonial_slide_
31681_title":"","testimonial_slide_1_content":"","testimonial_slide_1_text_link":"","testimonial_slide_1_link":"https:\/\/ptti.store\/otc\/?utm_source=pttimy&utm_medium=banner&utm_campaign=easystore-otc&utm_id=easystore&utm_content=easystore","testimonial_slide_2_img":"","testimonial_slide_2_title":"","testimonial_slide_2_content":"","testimonial_slide_2_text_link":"","testimonial_slide_2_link":"","testimonial_slide_3_img":"","testimonial_slide_3_title":"","testimonial_slide_3_content":"","testimonial_slide_3_text_link":"","testimonial_slide_3_link":"","testimonial_slide_4_img":"","testimonial_slide_4_title":"","testimonial_slide_4_content":"","testimonial_slide_4_text_link":"","testimonial_slide_4_link":"","testimonial_slide_5_img":"","testimonial_slide_5_title":"","testimonial_slide_5_content":"","testimonial_slide_5_text_link":"","testimonial_slide_5_link":"","testimonial_slide_6_img":"","testimonial_slide_6_title":"","testimonial_slide_6_content":"","testimonial_slide_6_text_link":"","testimonial_slide_6_link":"","logo_list_on_footer":0,"logo_list_title":"","logo_list_1_img":"","logo_list_1_link":"","logo_list_2_img":"","logo_list_2_link":"\/collections\/all","logo_list_3_img":"","logo_list_3_link":"\/collections\/all","logo_list_4_img":"","logo_list_4_link":"\/collections\/all","logo_list_5_img":"","logo_list_5_link":"\/collections\/all","logo_list_6_img":"","logo_list_6_link":"\/collections\/all","logo_list_7_img":"","logo_list_7_link":"\/collections\/all","logo_list_8_img":"","logo_list_8_link":"\/collections\/all","home_featured_products":"feature-on-homepage","home_featured_products_num":"20","home_featured_products_row_num":"7","home_featured_products_show_heading":"","home_page_content":"home","home_page_show_heading":"0","home_page_add_to_cart":true,"scroll_to_top_button":"on-right","product_quantity_enable":"1","product_image_zoom_type":"lightbox","product_thumbnails_position":"below","product_related_enable":true,"products_per_row":4,"products_list_per_row":"4","product_page_float_btn":"1","product_page_variants_tag":"1","featured_product_title":"Online Tuition Class (OTC)","product_img_res":"grande","product_img_crop":"product_img-crop ratio_1-1","collections_show_sale_circle":"1","collections_show_sold_out_circle":"1","collections_sort_enable":true,"collections_tags_enable":"0","collections_products_per_row":"3","collections_rows":"6","footer_bar":"1","footer_bar_icon_product_page":"1","footer_bar_icon_1":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/8327050.png?width=150&format=webp","footer_bar_icon_1_text":"Our Students","footer_bar_icon_1_link":"https:\/\/www.ptti.my\/pages\/better-result","footer_bar_icon_2":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/8327783.gif","footer_bar_icon_2_text":"Free Trial","footer_bar_icon_2_link":"https:\/\/www.ptti.my\/pages\/free-trial","footer_bar_icon_3":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/8327612.gif","footer_bar_icon_3_text":"Join OTC","footer_bar_icon_3_link":"https:\/\/www.ptti.my\/pages\/choose-your-level","footer_bar_icon_4":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/8335499.png?width=150&format=webp","footer_bar_icon_4_text":"Ask PTTI","footer_bar_icon_4_link":"https:\/\/www.ptti.my\/pages\/ask-ptti","cart_enable_ajax":"1","social_sharing_products":"1","social_sharing_blog":"1","social_sharing_count":"1","share_facebook":"1","share_twitter":"1","share_line":"1","share_pinterest":"1","facebook_url":"","twitter_url":"","pinterest_url":"","instagram_url":"https:\/\/instagram.com\/pttionline?utm_medium=copy_link","tumblr_url":"","youtube_url":"","vimeo_url":"","wechat_url":"","whatsapp_url":"https:\/\/WebsitePTTI.wasap.my ","line_url":"","featured_blog":"","featured_blog_title":"Blog","articles_handle_1":"","articles_handle_2":"","articles_handle_3":"","use_original_image":0,"slide_2_jpg":"https:\/\/cdn.store-assets.com\/s\/897413\/f\/17852763.png?width=1500&format=webp","promotion_uis":{"primary_color":"#E44040","header_bg_color":"#E44040","header_text_color":"#fff","recommendation":{"is_show_product_page":true,"is_show_cart_page_top":true,"is_show_cart_page_bottom":true},"voucher_widget":{"primary_color":"#4089e4"}},"show_multiple_currencies":true,"supported_currencies":"MYR ","theme_id":2877,"theme_is_edited":1,"theme_updated_at":"2026-10-08T06:36:42.000Z","phone_account_enabled":false,"line_login_enabled":false,"apple_login_enabled":false,"timezone":"Asia\/Kuala_Lumpur","is_server_side_currency_conversion":true,"is_self_registration_enabled":true,"is_highlight_enabled":false,"is_auto_gen_highlight_enabled":false,"is_common_question_enabled":false,"is_auto_gen_common_question_enabled":false,"highlight_section_title":"Highlights","common_question_section_title":"Frequently asked questions","is_new_promotion_enabled":true}
3169        if (settings.promotion_uis.voucher_widget != null) {
3170          setVoucherTheme(settings.promotion_uis.voucher_widget)
3171        }
3172        var shop = {
3173          money_prefix: "",
3174          format_decimals: ""
3175        };
3176        var _getEntitlementTranslation = {
3177          "free_shipping": "FREE SHIPPING",
3178          "free_of_charge": "FREE GIFT",
3179        }
3180        var _getTargetTypeTranslation = {
3181          "amount_credit": " CREDIT",
3182          "amount_off": " OFF",
3183        }
3184        var _getPrerequisiteTranslation = {
3185          "min_quantity": "Min formatValue item(s) purchase",
3186          "every_quantity": "Every formatValue item(s) purchase",
3187          "min_amount": "Min formatCurrency spend",
3188          "every_amount": "Every formatCurrency spend"
3189        }
3190        var _getPrerequisiteConditionTranslation = {
3191          "selected_items": "Selected Items",
3192          "selected_collections": "Selected Collections",
3193          "storewide": "Storewide",
3194          "order_subtotal": "Order Subtotal"
3195        }
3196        var _getVoucherButtonTextTranslation = {
3197          "apply": "Apply",
3198        }
3199        var _getVoucherErrorTranslation = {
3200          "condition_not_matched": "Voucher condition not matched"
3201        }
3202      </script>
3202
3203
3204    </div>
3205  </div>
3206</vouchers-modal>
3207  
3208  
3209</body>
3210</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.