1 2<!DOCTYPE html> 3<html lang=ar dir=rtl> 4<head> 5 6 <base href="https://brandfull.com" target="_top"> 7 <link rel="dns-prefetch" href="https://brandfull.com" /> 8 <link rel="preconnect" href="https://cdn.brandfull.com"> 9 <link rel="preconnect" href="https://cdn.brandfull.com" crossorigin> 10 <link rel="dns-prefetch" href="https://cdn.brandfull.com"> 11 <link rel="preconnect" href="https://brandfullsapi.azurewebsites.net" crossorigin> 12 13 14 15 16 <title> - Ø¨Ø±Ø§ÙØ¯ÙÙ</title> 17 <meta charset="utf-8"> 18 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 19 <meta http-equiv="content-type" content="text/html; charset=utf-8"> 20 <meta http-equiv="content-language" content="ar"> 21 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=5, shrink-to-fit=no" /> 22 23 <meta name="robots" content="index,follow"> 24 <meta name="googlebot" content="index,follow"> 25 26 <!-- Loading JS & CSS --> 27
27<script>!function(){var o=EventTarget.prototype.addEventListener;EventTarget.prototype.addEventListener=function(e,t,n){"touchstart"!==e&&"touchmove"!==e&&"wheel"!==e||("object"!=typeof n&&(n={capture:!!n}),n.passive=!0),o.call(this,e,t,n)}}();</script>
27 28 29 <link rel="stylesheet" href="/site-Ar.min.css?v=639260136226636726"> 30<link rel="preload" href="https://cdn.brandfull.com/Themes/Cartzilla/_Font/IBMPlexSansArabic-Light.woff2" as="font" fetchpriority="low" crossorigin="anonymous"> 31<link rel="preload" href="https://cdn.brandfull.com/Themes/Cartzilla/_Font/IBMPlexSansArabic-Regular.woff2" as="font" crossorigin="anonymous"> 32<link rel="preload" href="https://cdn.brandfull.com/Themes/Cartzilla/_Font/IBMPlexSansArabic-Bold.woff2" as="font" crossorigin="anonymous"> 33<link rel="preload" href="https://cdn.brandfull.com/Themes/Cartzilla/Assets/fonts/cartzilla-icons-sub.woff2?v=1" as="font" fetchpriority="low" crossorigin="anonymous"> 34<style> 35 36 37@font-face { 38 font-family: 'IBMPlexSansArabic'; 39 font-style: normal; 40 font-weight: 300; 41 src: url(https://cdn.brandfull.com/Themes/Cartzilla/_Font/IBMPlexSansArabic-Light.woff2) format('woff2'); 42 font-display: swap; 43} 44 45@font-face { 46 font-family: 'IBMPlexSansArabic'; 47 font-style: normal; 48 font-weight: 400; 49 src: url(https://cdn.brandfull.com/Themes/Cartzilla/_Font/IBMPlexSansArabic-Regular.woff2) format('woff2'); 50 font-display: swap; 51} 52 53@font-face { 54 font-family: 'IBMPlexSansArabic'; 55 font-style: normal; 56 font-weight: 700; 57 src: url(https://cdn.brandfull.com/Themes/Cartzilla/_Font/IBMPlexSansArabic-Bold.woff2) format('woff2'); 58 font-display: swap; 59} 60 61 62 63@font-face { 64 font-family: "cartzilla-icons"; 65 src: url(https://cdn.brandfull.com/Themes/Cartzilla/Assets/fonts/cartzilla-icons.woff2?v=6) format("woff2"); 66 font-weight: normal; 67 font-style: normal; 68 font-display: block; 69} 70 71@font-face { 72 font-family: "cartzilla-icons"; 73 src: url(https://cdn.brandfull.com/Themes/Cartzilla/Assets/fonts/cartzilla-icons-sub.woff2?v=1) format("woff2"); 74 font-weight: normal; 75 font-style: normal; 76 font-display: block; 77 unicode-range: U+E902,U+E903,U+E904,U+E906,U+E908,U+E90A,U+E90C,U+E90F,U+E910,U+E912,U+E914,U+E916,U+E918,U+E919,U+E91A,U+E91B,U+E91C,U+E91D,U+E91F,U+E920,U+E921,U+E922,U+E923,U+E926,U+E928,U+E929,U+E92C,U+E92D,U+E92F,U+E933,U+E937,U+E938,U+E939,U+E93B,U+E93F,U+E940,U+E944,U+E945,U+E946,U+E947,U+E948,U+E94A,U+E94C,U+E94D,U+E952,U+E953,U+E954,U+E956,U+E957,U+E959,U+E95A,U+E95D,U+E95E,U+E963,U+E964,U+E965,U+E969,U+E96A,U+E96B,U+E96E,U+E970,U+E972,U+E974,U+E97A,U+E97F,U+E980,U+E982,U+E983,U+E985,U+E986,U+E987,U+E98A,U+E98B,U+E98C,U+E98D,U+E98F,U+E991,U+E994,U+E99C,U+E99F,U+E9A6,U+E9AA,U+E9AB,U+E9AE,U+E9BE,U+E9BF,U+E9C1,U+E9C3,U+E9D5,U+E9DA,U+E9DB,U+E9DD,U+E9DF,U+E9E0,U+E9E1,U+E9E2,U+E9E4,U+E9E5,U+E9E6; 78} 79 80@font-face { 81 font-family: "cartzilla-icons"; 82 src: url(data:font/woff2;base64,d09GMgABAAAAAA7YAAsAAAAAGQgAAA6KAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAAgSwRCAqrNKQCATYCJAMqCyoABCAFgRAHIBtpFFGUj1YN4OeB7ciNNa7Y8fpdT0YrmhkhyewP/DZ7RArzW19BPiIWKRysgsgd2Fg4XamThTfcias2cNHWospcpXKtXhXOla7VgRS7q740EAw4G0GKDdbZ/6T4SJ7ouzB4UtsP3qDJNbkOuvJgpbZrtQ0sksuddi/x4SkFJVSlAv9vLbW7QVL3ogAtCZeoxKGOsHHzJ7fvzb9N2oXQXBiP567MLqogbIWaKwEJ1TpUFbqKhDI1QtTWqM2CptBZ8p65IUZqZQyYtPES+69e0lsAAuEzbhOQAPA1+McAsFE/PtwzUOJo0GpDQFR5id6/CW2+toMEhuzOOA+dV1S8SsBgT8fp2UTYxfnAo18T3kv0Ur2IN9Ab5uV5VV6DN9vr9C7yrvJWe/d4u71/+3wUv3p13qy/MT2EfkL70T70Ofoveg+9jZ5H69BtaDW6GnWio1AZ4OACKMT5fLRjg1WBMjmJsruLpvl0uPXyRMABBUhAzqYBHgk3kg4SgQRWCB4YNowRGqzPLplE1DNRKo3DjCbSGFIOQqPR6f6I/6hYTigWEBoYTg7zHzYsSMi47iWax2TM/SLTb5gfh6OURccIdNJIZOPP/E1UxlaeQuM8D1FDyjIAYF0I+w+i2gBbbET9bMUoAb4nHnU+eYSIlga3Ged5CSd4s6lxscYYyZTu4RD5JfG5AWJizYBfoPVwYCzw6o7Mb/gZ0R0ieW3LVNoaw8W6oapkmwPkElIHJQAV+2u4swKUZKRr6bAd762SfrkX7LZH87Ihdq/3zZpXa1+8XgfW/+3sKBW+WoBFK1gKVf99tWJAmAObqF+IjDCyr5pZ0pvqm60lGYHMEuVf7uHlvpOuCzc0iObsZa2hH6ivnHomjdINwwq9O8uzHQruXVMnUXuxS9Zz6E+SjaF0f+ATHs6v7RjEuh/Jtf6VRLPidEu+mkH0Zq6YbgNVZ1oLtewLIoCloJwwTkHdaeRVjZ5UIcBDPOGZkAGqObOeDiOev+RfSIF3XRwZqzUUe0XDBYTR855arIkvSad7DcMSX6xyZVMzvFMJu0HQpo3ciyRJdHFGTcDaA7Ui1XqHP1xskGvJCKw7WCfTbS8j2co9CFflnpdRVL2vmiWar0WjmduD3FuzH74aSDGmsn1QXpRyvfwC1dC98mTLbfFoSeQ69d+Hz7ZJf91BxM61s8XC333XM/mOXoVp3kO5Ja0ytlkB+FlBXIsdpZWoPNtWrOeuUiro4YbFqL/ZPRkuh5sQIOxQECw/hRF2VfE0z6/4dZ/Gc4aU++JJKXpCMAATjMUujUie2Su9pNB9TQy9WGW0T3j6HbmSLaQq5/Pf21as9yF6OZNPVih2Na9UuuEnLPda865y01lxGqgFgZcGxshc7qHlvpv8vLUVlRFdPPtVb9tbhV2VZ4CR17ipsid/JxtJ4ItXHbUbRMQcDK6lw4jak+FS/QUCpMAT2eyNyb0WHDCVgO/X766+rnaJP3WnZddb5H7+KaeO8SoVQCIQxVL8uoZc6l9JlJ8IfqVoCdr25ocZq+nVXDFd1XdXe1oLtV4Ivpge
82kwA4FNS/6q90/bviOl+naXEtnhVsHjuwJyt5psaf5hkn+7GWGdb7wxe75HwexcQ1nmtnkxlI7s2JXCfAGD8SRvhXkSsFR2h/V4/QKdVbQxzTAxLBGMecRs3+cateHjFVUD0zetxKSxr+M8guUZt+I5pP4y1jJ+0GVarQYQC3yRyvYIQ4dsItM/TBH0CBj0Weqs88VlBg6xWxJ/rzQLggQFUy/sx4GsoyQEoPjz7XnvjciZS/88UFxgRDwhojjDLBaCo0nWF02xBM3cyhGZPpCsygs4ixQOlM2ApjviVy2e72hXPyZjoRe4jRb5AMBWy4aiiJw5yBZX2SEmK9mgMMwZEMUlL0Zk7mu07ehU5Ry97AtX6WaVec7+DVzHt63B91cnS4fCTi1UdPBGMu/l6sajweJhxPWr7CFD1h1r97XVVARbqhdgJJLnWHh8YgGhfTpd6/V5EsrQC672z1nKbF49JOQX5GjmCJr6sEv0jLZ1MtS1qmMm2lvR869bXEDB66kRWjKRiN07z74vPs7ADVqt2TZD7jO0BE7Yhq7Oh8IV3icg+vZo77p1u4s0L57yXxtSO0Y0mr2TArGJ6rBWN72DVuSIaDsmgrdZgQJvVyrhHClb29JF/NXG/oUXRh07RsL6uC4+j3CGAZD6lnRH1h8e/TVpttm0pzxJvhNWQuFrQijl3juiKB3R6L0nJZDHOJAwDlYQRereYb7YwFc0xmIl47RQUwZpYou0GsTbLrlSEOFdunSOo1YFUqsSSaJzpi3Bw5cTmCykqBazocIcuZmDN3cdh2hrqMfOCKPTHyNl0ucSfa7ZXEFN0ru82D8Q+Sj6RbA7HJCJ/v3xk6v2GyGOhQPOY/Nv4AcKv11qke/IcHvAMD2RE3U8fM4X4XhMA/GAEoYabhBF2MNMlYwFjN8N1d9niK8GmRIp35s7Ocs8tfVoG5LxxLN4C+XZxyI+wRETYbc3OysIJHgOTW0+jSpcsglse2seUFsHgRuvCMnyoLfNxZErssW5+Wrp33q/n41p935DpgTNIZvuf3CGtLe+4E1do9WQYfTIixGvlyo2ESEKF1tnCLaLkq92kL1/K7Ryc0ptssLA/ysf5p4iQrboqll6+HeqrEEzrHVmMqOvZd0Pd5N7sZzO6bxTcV00fTw82pqSnysQHz31rfruc8FocPUqV29oyG1SyWgb//5tYti51weIer4C4A+BbLN2/+lcWSy1ns37ZslmfUX1iEtvZiy35ZpTY3V3utjR0njI49z4NQ/u8bTQ5qCObCWFgh5vNSDGK1hE6eK16FXBdW9OlKwJPjRqe4PbDciQQvNtWiBoOlteFQq6DJJ2hXr/rDp48/3tuDtHH60D3bNHawXYwZpw/XxfwQOi0kf1A8+NYo8AhN5MuOqyzfOzspHbiiOLtZUd73/xZxln/3C+//KJn1eWiB0f/OpSwHW8NWE8z/lBTvDzp4QZj34H70Lht2+LIws7098Z9p05uSX7+W5bz/f+7hJQ00tmz6Dz/ENa3fPvPJz4LCK1dGN+D1G8NUtlk7tn++06D79rZoevdDrdq/ZJVtRvMpig5Z/nXvQPy0b7/T7ycZ21uyZ948D5JvlZ5Nm3oFYTICnsBuXuvT6LT6be6DBwEuHdrm1ug0+qHtzWx/Gu3XVVteEfGEsN/aT6zf6fvFWXeivT3ULJoxUjNuoGBkbFKlWaDZQ6rla167l1SsUY/TjJNGjY7CVOPU48vX1tf7R+hJO4vFmipzEgDE78an7MJppxMALM3NOQYtEUktu21mmdm1RNwfcxuLFOcllZPeisVvSeVJeWLknI0dSaM2SZzOu93d9q7u2xAxyelLakh6qjKnDvupQ+YpxqCllmyulZktMJHPvlw6SSlzXt4MY+yujUgZp+xmD1bIK8MWc5AHDwb6ZZ5qT667sanHg7kwAKjmqOf19DTpG12XXTqI79gf1BhkNOkdy+uS3utBwQTEgnFo4EifSFD0W8empIwt+S2daHBXhyADU7S5072eksl2p97fGuQUpnTQGetq1i+uriavJ2srMQsMN6ImOr35qXv8kWQG8d0XbB1AEjONkMhIhq5//3nBTRgOOBiR4Bh6auXyA5BA5stfajzxIG88g882HVfL3cIwBRoDer3eGl5NY+So8+GmMy25eZ8GTKZnn/ykljOQy8odeGYMDACgQ2QfY503z3pvKZNrNPJnUuVD8+o2Pooax58+nT9OAQBw5+e3bKwUq2YdxtA7j+8wFPVeAJDlKaPTwf1YAmV2EqdwS2NpLqD74B3y9toH4I8/cFqLEAU5T/JQrBA3zHJgHms6V1/smjbN9U7PLrJWW2167jsovzhcv84MHTUoeUfWchjJV3EN8hXt/UtGGviGJSN8t86tNHDzTWkjx0/IyJhgRYKZXETNZHMnaJSGycQ3o7ljHBIsKvkTuCF2OS0xeezb+32YTlQmEpr7UvGG7+k7ZY/SZZJT0q1pY8fJTSn5q1li3mPe+CkT/zCNo2K205iv6OLTxqS1W4osbT7XBD6t8srlSUkh6MSJKGli0uUrI0bkiO8iSXLIJLmCEePx1F87Gh9/7Gr9ccUgSVePJR+99pzpfX0zJLKRt4AIB1I1VWRUUiBCSVXa1EP9ZJlkxnn8tauzdGKNSFOCpCMXLZuv1yNWF+muXYMxQW1dErVa2oXYECUuz0c6eSYWKUB+bcZOQGh1St2okhUrUYmXO3NLXbt4NRVGdvmyMoQfyxQSDArmNbyKigcAlJbmvvz8gtJh5AWxtq7OHhNGU86yx2XHllfE5cTaHVreMoGJyjDlLOGqwGF/eEVFrHtPDmTPppiso0er/4exDu4gpUEkrPmqL2L+hEye5ebznRZcW6bItf5LblzsL79Md3K/LHOJcBmRFtjO+Q6ffM+4Lbqo6as68rNuxqRv2rqqXnbfkFlUFusmj4gVExThhhmrPBQyk0wJLa8BuVxmjQl897aqeNmbLPuF/E19in0FtgBizN3VsKXrOF+AGY7XGLgCgYF7rJZrEPBPUL/XBQy3UIo5ifwAYjg7nBjAT+QUU6fodN9TU3R+L/yMmZKykC5WKh1LpqfqdNu7WqiL40csUCqNEdwMpXJmBD/eLtmbH/i0sbE3kB3Y23ji18D8fdK7VCTUh4b6QhHWD5I46fcfNftlKHoRGkxqfQUAvrYok9BW4vtzrhBud8XgiH22EdbxpyQMbs5nL7rGaFJf0xhUt7pxAHfJfu4/zXn+499S/R7aJv+xkY264Rt83yra/+cHVMADjCJA3yKADuU9ZDdzaR4cERCHxWCcCVBk84cvGRKAALi/pXC1fjEehgF3Z4JtZ6IUkwAFiU4W+QyYBk5YAIugCObckEFpdLEZUAzzoARSIB8K4evCnZBO6Hz0Io/vnAdfQDzIgQAXAAA=) format("woff2"); 83 font-weight: normal; 84 font-style: normal; 85 font-display: block; 86 unicode-range: U+E904,U+E908,U+E910,U+E912,U+E918,U+E920,U+E940,U+E944,U+E945,U+E946,U+E959,U+E95A,U+E972,U+E97A,U+E982,U+E98D,U+E99F,U+E9DB,U+E9E4; 87} 88 89 90 91@font-face { 92 font-family: "digital"; 93 src: url(https://cdn.brandfull.com/Themes/Cartzilla/_Font/digital-7.woff2) format('woff2'); 94 font-weight: normal; 95 font-style: normal; 96 font-display: swap; 97}</style> 98 <link rel="preload" href="https://cdn.brandfull.com/script.min.js?v=639260136226636726" as="script" fetchpriority="high"> 99 100 <link rel="preload" href="https://cdn.brandfull.com/InitData.ar.js?v=639260136446764345" as="script"> 101 <style> 102 .cart-drawer{position:fixed;top:0;right:0;width:380px;max-width:92vw;
102height:100vh;transform:translateX(var(--cart-hide-tx,100%));visibility:hidden} 103 [dir="rtl"] .cart-drawer{right:auto;left:0} 104 [dir="rtl"]{--cart-hide-tx:-100%} 105 .filter-drawer{position:fixed;top:0;left:0;width:340px;max-width:88vw;transform:translateX(var(--filter-hide-tx,-100%));visibility:hidden} 106 [dir="rtl"] .filter-drawer{left:auto;right:0} 107 [dir="rtl"]{--filter-hide-tx:100%} 108 .modal{display:none} 109 .seo-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0} 110 </style> 111 <!-- ios support --> 112 <meta name="mobile-web-app-capable" content="yes" /> 113 <meta name="apple-mobile-web-app-capable" content="yes" /> 114 <meta name="application-name" content="PWA Workshop" /> 115 <meta name="apple-mobile-web-app-title" content="PWA Workshop" /> 116 <meta name="msapplication-starturl" content="/" /> 117 <link rel="apple-touch-icon" sizes="180x180" href="https://cdn.brandfull.com/Media/BrandFull/apple-touch-icon.png?version=639260136446764345"> 118 <meta name="apple-mobile-web-app-status-bar" content="#34200C" /> 119 <meta name="msapplication-TileColor" content="#34200C" /> 120 <meta name="theme-color" content="#34200C" /> 121 122 <!-- Favicon Icon --> 123 <link rel="icon" type="image/x-icon" href="https://cdn.brandfull.com/Media/BrandFull/favicon.png?version=639260136446764345" /> 124 <link rel="icon" type="image/png" sizes="32x32" href="https://cdn.brandfull.com/Media/BrandFull/favicon-32x32.png?version=639260136446764345"> 125 <link rel="mask-icon" href="https://cdn.brandfull.com/Media/BrandFull/safari-pinned-tab.svg?version=639260136446764345" color="#5bbad5"> 126 <link rel="shortcut icon" href="https://cdn.brandfull.com/Media/BrandFull/safari-pinned-tab.svg?version=639260136446764345" color="#5bbad5"> 127 128 <!--====== Required meta tags ======--> 129 130 131 132 133<meta name="title" content="Ø§ÙØ³Ø¹ÙØ¯ÙØ© | اÙÙ ÙØ¶Ø© ÙØ§ÙØ±ÙØ§ÙÙØ©"> 134<meta name="description"> 135<meta name="keywords"> 136 137<meta itemprop="name" content="Ø§ÙØ³Ø¹ÙØ¯ÙØ© | اÙÙ ÙØ¶Ø© ÙØ§ÙØ±ÙØ§ÙÙØ©"> 138<meta itemprop="description"> 139<meta itemprop="image" content="https://cdn.brandfull.com/Media/BrandFull/social-logo.png?version=639260136446764345"> 140 141<meta property="og:url" content="https://brandfull.com/ar-sa/Checkout"> 142 143 144<meta property="og:title" content="Ø§ÙØ³Ø¹ÙØ¯ÙØ© | اÙÙ ÙØ¶Ø© ÙØ§ÙØ±ÙØ§ÙÙØ©"> 145<meta property="og:description"> 146<meta property="og:type" content="website"> 147<meta property="og:image" itemprop="image" content="https://cdn.brandfull.com/Media/BrandFull/social-logo.png?version=639260136446764345"> 148 149<meta name="twitter:card" content="summary_large_image"> 150<meta name="twitter:title" content="Ø§ÙØ³Ø¹ÙØ¯ÙØ© | اÙÙ ÙØ¶Ø© ÙØ§ÙØ±ÙØ§ÙÙØ©"> 151<meta name="twitter:description"> 152<meta name="twitter:creator" content="Brandfull"> 153<meta name="twitter:image" content="https://cdn.brandfull.com/Media/BrandFull/social-logo.png?version=639260136446764345"> 154 155 156 157<link rel="canonical" href="https://brandfull.com/ar-sa/Checkout"/> 158 159 <meta name="robots" content="noindex, nofollow"> 160 161 162 163 164
165<script type="application/javascript"> 166 var m_loadIndex = 0; 167 var m_listScript = []; 168 169 // GTM's snippet used to create this at head-parse time; it is deferred now (see the 170 // <template id="UI_headScript"> injector at the bottom of this file), and 171 // Tools/Deferred/ThirdParty.js -- the only other place that declares the name -- is fetched 172 // on idle. Anything touching bare `dataLayer` before either arrives throws a ReferenceError, 173 // and a Portal-authored blob does exactly that from inside a doLoadScript callback, which 174 // fires long before both. Seed the array here: GTM's own `w[l] = w[l] || []` adopts THIS 175 // array, so events pushed before gtm.js loads are still replayed rather than lost. 176 // Safe against every later writer -- `var dataLayer;` in ThirdParty.js keeps the existing 177 // value (a var redeclaration of a live global does not reset it), and doSetThirdParty only 178 // assigns when its argument is non-null. 179 window.dataLayer = window.dataLayer || []; 180 181 // On the CDN with every other script the app loads -- scriptPage.min.js, scriptGallery.min.js, 182 // Handlers/Pages/*.js, Tools/Deferred/ThirdParty.js. /InitData.js is the single exception and 183 // has to stay: it is generated per language and company by our own HostController. 184 // 185 // It MUST stay in step with the <link rel=preload as=script> in both themes' _Layout: 186 // doGetVersionedUrl appends the same ?v= the preload carries, so the two URLs match byte for 187 // byte and the preloaded bytes are the ones that run. Point one at the CDN and the other at this 188 // origin and the bundle is simply downloaded twice. Neither carries crossorigin, so both are 189 // no-cors fetches and the preload is reused -- adding it to one alone would split them again. 190 // 191 // m_CDNUrl is empty on any build that serves its own assets, so this is "/script.min.js" 192 // unchanged in local dev, and doCheckOwnAsset answers true either way (leading '/', or the 193 // m_cdnBase prefix), which is what keeps the ?v= and the async-and-first placement. 194 var defaultScript = "https://cdn.brandfull.com/script.min.js"; 195 var m_isEnumReady = false; 196 197 // The whole-site blobs -- the category tree, the company and country lists, the enum translation 198 // dictionary -- served as one cacheable file by HostController instead of being inlined into 199 // every HTML response (~280 KB of a 784 KB page, the category tree alone 270 KB of it). 200 // 201 // On the CDN like every other script, even though this one is an MVC route rather than a file -- 202 // so is scriptPage.min.js, which has always been served from there. The response is a pure 203 // function of (lang, v): HostController composes it from statics keyed on nothing else, and the 204 // action drops the Set-Cookie headers the middleware seeds, which is what a CDN refuses to cache 205 // against. 206 // 207 // The language is in the URL because a script element sends no custom headers, so the `lang` 208 // header the rest of the app rides on is not available to it - and it is a PATH segment rather 209 // than ?lang= so that a CDN cannot cache one language and serve it to every visitor. See 210 // SettingManager.doGetInitDataPath, which the preload in _Layout builds from too. 211 // 212 // ?v= is written here rather than left to doGetVersionedUrl, and it is m_version -- the API's 213 // data version -- because this file IS API data: the category tree, the company and country 214 // lists, the enum translations. An /AutoRefresh that changes them without a redeploy has to 215 // change this url, and the build token would not move. doGetVersionedUrl sees the v= and adds 216 // nothing, so this stays byte-identical to the preload in _Layout, which spells it the same way. 217 var m_initDataUrl = "https://cdn.brandfull.com/InitData.ar.js?v=639260136446764345"; 218 219 // Where the fold is, straight from the value doGenerateContentfull (called in _LayoutPreload) 220 // used to pick which div templates to inline and which image to preload. One number, one 221 // definition (SettingManager.m_foldHeight). The client no longer walks the fold to decide which 222 // sections reserve a height -- every un-hydrated section holds the same 320px floor -- but the 223 // value is still read by the div loader, so it stays emitted here. 224 var m_foldHeight = 700; 225 226 // event.persisted == restored from the back/forward cache: the whole page came back frozen from 227 // memory, so nothing re-ran and m_currentCart still holds whatever it held when the visitor left. 228 // This used to call document.location.reload(), which fixed the staleness by throwing away the 229 // free instant restore -- re-downloading script.min.js, re-binding every Knockout template and 230 // re-issuing the div-section calls, on every single back navigation. 231 // doInitDataPageCart() re-fetches just the cart (CartService.GetInitData) and repopulates 232 // m_currentCart, which is what the header badge, the drawer and the totals all read. Its default 233 // arguments (reloadPage = false, url = '') mean it never navigates or reloads. 234 window.addEventListener('pageshow', function(event) { 235 if (!event.persisted) 236 return; 237 // Guard: the handler is created in the doLoadScript callback below. A restore always implies a 238 // fully-initialised page, but a restore racing a failed script load would otherwise throw here. 239 if (typeof m_handlerSession == "object" && m_handlerSession != null) 240 m_handlerSession.doInitDataPageCart(); 241 });
242 243 function doLoadReady(url) { 244 var item = m_listScript.find(item => item._url == url); 245 if (item._isLoaded == false) 246 { 247 item._isLoaded = true; 248 doRunOnReady(url, true); 249 } 250 } 251 252 var m_cdnBase = "https://cdn.brandfull.com"; 253 254 // The BUILD's token (SettingManager.m_assetVersion), not the API's data version. It buys nothing 255 // here to spend a thought on which: the bundles this versions ship with the binary, and the one 256 // url that is API data -- /InitData.js -- carries its own ?v= already, which doGetVersionedUrl 257 // leaves alone. Read the comment on SettingManager.m_assetVersion for why the two were split: 258 // versioning script.min.js with a number the API owns meant a front-only deploy re-served the 259 // same immutable url, and visitors ran an old bundle behind new markup. 260 var m_assetVersion = "639260136226636726"; 261 262 // Free-shipping teaser sentences, whole rather than assembled from labels. The teaser used to be 263 // built in the view out of "You already have" + a number + "off your shipping" + ..., and the 264 // translation service sees each fragment alone: "off your shipping" came back as the imperative 265 // "Ø§ÙØ²Ù Ù Ù Ø´ØÙÙ" ("get off your shipment"), and the Arabic sentence read as nonsense. One label per 266 // sentence gives the translator the whole clause and lets it place the number itself, which RTL 267 // needs. Substitution is doGetShipmentTeaserMessage in Handler_Session. Json.Serialize, not bare 268 // quotes: these strings are machine-translated and may legitimately contain a quote. 269 var m_textShipmentTeaserSaved = "\u0644\u0642\u062F \u0648\u0641\u0631\u062A {0} {1} \u0645\u0646 \u062A\u0643\u0644\u0641\u0629 \u0627\u0644\u0634\u062D\u0646"; 270 var m_textShipmentTeaserDiscount = "\u0644\u062F\u064A\u0643 \u0628\u0627\u0644\u0641\u0639\u0644 \u062E\u0635\u0645 \u0634\u062D\u0646"; 271 var m_textShipmentTeaserTopUp = "\u0623\u0636\u0641 \u0627\u0644\u0645\u0632\u064A\u062F \u0645\u0646 {0} {1} \u0644\u0644\u062D\u0635\u0648\u0644 \u0639\u0644\u0649 \u0634\u062D\u0646 \u0645\u062C\u0627\u0646\u064A"; 272 273 // Is this one of our own assets, as opposed to a third-party SDK? 274 // 275 // The old test was `url.indexOf('@SettingManager.m_CDNUrl') == -1`. m_CDNUrl is an empty 276 // string whenever the app serves its own assets (local dev, and any deployment without a 277 // separate CDN host) -- and "anything".indexOf("") is 0, never -1. Every URL therefore 278 // looked like ours, which mattered because the branches below both version the URL and 279 // choose defer-vs-async from this answer. 280 // A root-relative URL is same-origin by definition, and it is answered before the CDN test: 281 // /InitData.js is served by our own HostController, never by the CDN host, so with a CDN 282 // configured the old form called it third-party -- which skipped the ?v= cache-bust that is the 283 // only thing invalidating it across deploys. 284 function doCheckOwnAsset(url) { 285 if (url.charAt(0) === '/') 286 return true; 287 return m_cdnBase ? url.indexOf(m_cdnBase) === 0 : false; 288 } 289 290 // Cache-bust our own assets so a deploy is actually picked up, and never touch a 291 // third-party URL: several already carry a query string (Google Maps key/callback, 292 // MISPay authorize, Checkout.com), and a second "?" makes them malformed. 293 function doGetVersionedUrl(url) { 294 if (!doCheckOwnAsset(url)) 295 return url; 296 297 // Already versioned by the server -- /InitData.js, which is API data and so carries 298 // m_version rather than the build token. Appending a second v= here would both make it a 299 // different url from the <link rel=preload> in _Layout (two downloads of the same file) and 300 // hand the server two values for one parameter. 301 if (url.indexOf('?v=') !== -1 || url.indexOf('&v=') !== -1) 302 return url; 303 304 return url + (url.indexOf('?') === -1 ? '?' : '&') + 'v=' + m_assetVersion; 305 } 306 307 function doLoadScript(callBack, url = defaultScript, isModule = false) { 308 var item = m_listScript.find(item => item._url == url); 309 if (!item) { 310 item = { _isReady: false, _url: url, _callBack: [callBack], _isLoaded: false }; 311 m_listScript.push(item); 312 313 var script = document.createElement("script"); 314 if (typeof callBack == "function" && !isModule) 315 script.type = "application/javascript"; 316 else { 317 script.type = "module"; 318 script.innerText = (callBack + "").replace("URL", url); 319 } 320 script.src = doGetVersionedUrl(url); 321 322 //script.defer = true; 323 script.charset = "utf-8"; 324 script.addEventListener('load', function () { 325 doLoadReady(url); 326 }); 327 328 script.onerror = function () { 329 item._isError = true; 330 console.log("Error loading " + url); 331 // Never leave the queue standing behind a script that is not coming. doRunOnReady 332 // steps over errored items when it picks the head, but nothing else would wake it, 333 // and for /InitData.js this is also what releases doSetEnumManager's fallback. 334 doRunOnReady(url, true); 335 }; 336 337 try { 338 // Third-party SDKs are deferred and appended; ours are async and put first so 339 // they start downloading as early as possible. 340 if (!doCheckOwnAsset(url)) 341 { 342 script.defer = true; 343 document.head.appendChild(script); 344 } 345 else{ 346 script.async = true; 347 var head = document.getElementsByTagName("head")[0]; 348 head.insertBefore(script, head.firstChild); 349 } 350 } catch (error) { 351 //once load before 352 console.log(error); 353 setTimeout(doRunOnReady, 1000, url, true); 354 return false; 355 } 356 } 357 else if (item._isReady === true) { 358 // Synchronous, because the script this callback waited for has already loaded. That is
359 // exactly the state an ajax view swap runs in: doHtmlSetInner evaluates the swapped-in 360 // page's inline block, it calls doLoadScript for a bundle that is already _isReady, and 361 // the callback runs right here, inside that eval. doLoadViewAjax now compares 362 // X-Asset-Version against m_assetVersion and navigates instead of swapping, so a skew 363 // introduced by the RESPONSE no longer reaches this line -- see doRunCallBack below for 364 // what still does. 365 if (typeof callBack == "function") 366 doRunCallBack(callBack); 367 } 368 else { 369 item._callBack.push(callBack); 370 } 371 } 372 373 // Run one page callback, and treat a missing symbol as a bundle that cannot serve this markup. 374 // 375 // A ReferenceError out of a page's own callback -- "doFinishPaintEarly is not defined", 376 // "doSetHandlerPageScroller is not defined" -- is never a typo in the view: those calls sit INSIDE a 377 // doLoadScript callback, so the bundle demonstrably arrived. It means the bundle that arrived is 378 // an OLD build. A tab held open across a deploy keeps the script.min.js it loaded then, and an 379 // ajax swap pulls markup from the server as it is NOW; ?v= cannot repair that, because the swap 380 // never re-loads the bundle and the old one is already parsed. A stale or failed 381 // Handlers/Pages/*.js throws the identical error and is fixed by the identical answer. 382 // 383 // Second line of defence since doLoadViewAjax gained its X-Asset-Version check, which stops the 384 // skew before anything is swapped. What still lands here is what no response header can see: a 385 // stale or failed Handlers/Pages/*.js, a bundle the CDN served old under a current ?v=, and the 386 // one navigation per build doClaimBuildNavigation lets through so a mixed fleet cannot ping-pong. 387 // 388 // The answer is to stop and let the browser fetch the document properly: the new document carries 389 // a new m_assetVersion, and every ?v= in it then points at the matching build. 390 // 391 // Keyed on m_assetVersion so it cannot loop -- the flag records the build we already reloaded 392 // for, so a genuine bug in the current build reloads once and then stops. A storage failure 393 // (Safari private mode) means no flag can be kept, so it does not reload at all. 394 function doReloadOnceForBuild() { 395 try { 396 if (sessionStorage.getItem('bundleReload') == m_assetVersion) 397 return false; 398 sessionStorage.setItem('bundleReload', m_assetVersion); 399 } 400 catch (storageError) { return false; } 401 window.location.reload(); 402 return true; 403 } 404 405 function doRunCallBack(callBack) { 406 try { 407 callBack(); 408 } 409 catch (error) { 410 console.log(error); 411 if (!(error instanceof ReferenceError)) 412 return; 413 doReloadOnceForBuild(); 414 } 415 } 416 417 // /InitData.js carries the 111 enums, m_jsonTranslate and the three jsonList* blobs. It is 418 // fetched, not inlined, so it can fail -- and if it does, every one of those globals is missing 419 // and nothing on the page would ever run. Deliberately keyed on _isError and not on a timeout, 420 // so a slow file is waited for rather than given up on. 421 function doCheckInitDataFailed() { 422 var item = m_listScript.find(item => item._url == m_initDataUrl); 423 return item ? item._isError === true : false; 424 } 425 426 function doSetEnumManager(url) { 427 // TranslateEnum used to arrive with script.min.js and only m_jsonTranslate came from 428 // /InitData.js. The enums moved there too, so both tests now answer the same question -- 429 // "has /InitData.js landed" -- and are asked together. Neither says anything about the 430 // bundle any more; that is what the doApplyTranslations test further down is for. 431 // 432 // Not here yet -> "not yet". Gone for good -> RELOAD, once per build, on the same 433 // sessionStorage guard doRunCallBack uses. Standing empty objects up is no longer a 434 // degraded-but-working page the way it was when the enums were in the bundle: every page on 435 // the site has a binding that reads one, so an empty stand-in trades one failed request for 436 // a page of failed bindings. A reload is the only thing that can actually fix it, and the 437 // guard is what stops it looping. 438 // 439 // If the reload has already been spent on this build (or sessionStorage is unavailable, as 440 // in Safari private mode), fall through to the old behaviour: empty lists, keys for labels,
441 // no category menu. Worse than it was, but still a page. 442 if (typeof TranslateEnum != "object" || typeof m_jsonTranslate != "object") { 443 if (!doCheckInitDataFailed()) 444 return false; 445 if (doReloadOnceForBuild()) 446 return false; 447 448 if (typeof TranslateEnum == "undefined") TranslateEnum = {}; 449 if (typeof m_jsonTranslate != "object") m_jsonTranslate = {}; 450 if (typeof jsonListCategory == "undefined") jsonListCategory = []; 451 if (typeof jsonListCompany == "undefined") jsonListCompany = []; 452 if (typeof jsonListCountry == "undefined") jsonListCountry = []; 453 } 454 455 // Comes from _LayoutScriptTail at the foot of the document. Same "not yet" answer as the 456 // tests above: doRunOnReady waits on DOMContentLoaded, which is the instant it comes into 457 // being. 458 // 459 // Never write a literal body tag in a comment inside an inline script. doLoadViewAjax 460 // pulls a full-page ajax response apart by searching the TEXT for one, so a mention in 461 // the head matches 20 KB before the real element and the rest of this script gets 462 // written into the page as visible text. That shipped. Ajax.ts no longer scans for it, 463 // but the phrasing here stays deliberate. 464 // doApplyTranslations comes from script.min.js (Tools/Enums.ts). Nothing above tests for the 465 // bundle any more: TranslateEnum moved to /InitData.js with the other 110 enums, so the 466 // TranslateEnum test now proves /InitData.js landed and says nothing about the bundle. Without 467 // this, /InitData.js winning the race against the bundle threw 468 // "doApplyTranslations is not defined" out of the try below on every such load. 469 if (typeof doApplyTranslations != "function" || typeof doApplySettingByCompany != "function") 470 return false; 471 472 try { 473 doApplyTranslations(m_jsonTranslate); 474 doApplySettingByCompany(); 475 } catch (error) {console.log(error); return false;} 476 477 m_isEnumReady = true; 478 return true; 479 } 480 481 482 // Nothing may run before the document has finished parsing, and the two things that gate a 483 // callback resolve on their own events: doApplySettingByCompany appears when the parser reaches 484 // _LayoutScriptTail, and TranslateEnum / m_jsonTranslate appear when script.min.js and 485 // /InitData.js load. So this is entirely event-driven -- there is no timer left in it. 486 // 487 // It used to be setTimeout(..., sleepTime) with sleepTime += 50 on every miss -- 50, 100, 150, 488 // 200 -- and the escalated value was then carried into the readyState test and into the 489 // queue-order test, where scriptPage.min.js polled behind script.min.js on its own growing timer. 490 // Dead latency sitting in front of doSetSetting, i.e. in front of the page's bind, and the page 491 // gate charges every millisecond of it to LCP. 492 // 493 // The `url` argument is now only a hint about WHY we were woken. What actually runs is decided by 494 // walking the queue from its head, which is what makes the ordering safe no matter which script 495 // wins the race: whoever arrives last finds everything before it already loaded and drains the 496 // lot. Draining only `url` would deadlock -- the head could be ready with nobody left to notice. 497 function doRunOnReady(url, byscript = false) { 498 if (document.readyState === "loading") { 499 document.addEventListener('DOMContentLoaded', function () { doRunOnReady(url, byscript); }, { once: true }); 500 return ; 501 } 502 503 // Still missing a dependency. Do NOT schedule a retry: every one of them arrives on a load 504 // event that calls straight back in here. 505 if(m_isEnumReady == false && !doSetEnumManager(url)) 506 return ; 507 508 try { 509 //console.log("ByScript " + byscript + ", " + url + " "+document.readyState) 510 for (;;) { 511 // The head of the queue: the first script still owing its callbacks. One that failed 512 // to load is stepped over rather than left at the head -- it is never becoming ready, 513 // and leaving it there would wedge everything behind it. 514 var item = m_listScript.find(x => x._isReady == false && x._isError != true); 515 516 // Nothing waiting, or the head has not arrived yet -- and callbacks run in request 517 // order, so anything behind it waits for its load event. 518 if (!item || item._isLoaded != true) 519 return ; 520 521 while (item._callBack.length != 0) { 522 var callBack = item._callBack.shift(); 523 // Detached by setTimeout, so the try around this loop never sees what the 524 // callback throws -- doRunCallBack is the only thing that can. 525 if (typeof callBack == "function") 526 setTimeout(doRunCallBack, 0, callBack); 527 } 528 529 item._isReady = true; 530 //console.log("ByScript " + item._url + " is passed") 531 } 532 }catch (error) { 533 console.log(error); 534 } 535 } 536 537</script>
537 538 539
539<script> 540 function doGetBrowserName() { 541 var nAgt = navigator.userAgent; 542 var browserName = navigator.appName; 543 var nameOffset, verOffset; 544 545 if ((verOffset = nAgt.indexOf("OPR/")) != -1) 546 browserName = "Opera"; 547 else if ((verOffset = nAgt.indexOf("Opera")) != -1) 548 browserName = "Opera"; 549 else if ((verOffset = nAgt.indexOf("MSIE")) != -1) 550 browserName = "Microsoft Internet Explorer"; 551 else if ((verOffset = nAgt.indexOf("Chrome")) != -1) 552 browserName = "Chrome"; 553 else if ((verOffset = nAgt.indexOf("Safari")) != -1) 554 browserName = "Safari"; 555 else if ((verOffset = nAgt.indexOf("Firefox")) != -1) 556 browserName = "Firefox"; 557 else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < 558 (verOffset = nAgt.lastIndexOf('/'))) { 559 browserName = nAgt.substring(nameOffset, verOffset); 560 if (browserName.toLowerCase() == browserName.toUpperCase()) 561 browserName = navigator.appName; 562 } 563 return browserName; 564 } 565 566 function doGetSystemInfo() { 567 var browserName = doGetBrowserName(); 568 var nav = navigator || {}; 569 var scr = (typeof screen != "undefined") ? screen : {}; 570 var data = decodeURI(window.location.href) + "#" + browserName + "#" + nav.platform + "#" 571 + "\nUA: " + nav.userAgent 572 + "\nViewport: " + window.innerWidth + "x" + window.innerHeight + " @" + (window.devicePixelRatio || 1) + "x" 573 + "\nScreen: " + (scr.width || "?") + "x" + (scr.height || "?") 574 + "\nLang: " + (nav.language || "?") + " | Online: " + nav.onLine + " | Mem: " + (nav.deviceMemory ? nav.deviceMemory + "GB" : "?") 575 + "\nReferrer: " + document.referrer; 576 return data; 577 } 578 579 // Client-side dedupe. The hash identifies the *fault*, not the visit: page URLs, 580 // line/col and cache-busting query strings are deliberately left out, so the same 581 // error raised on 500 product pages collapses to one hash and is posted once. 582 // Kept in localStorage so it also survives reloads and in-app-browser page hops -- 583 // repeat visits from the same device stop re-posting a fault we already have. 584 var m_sentHash = {}; // this page load; still works when storage is blocked 585 var m_hashKey = "errHash", m_hashMax = 100; 586 587 function doGetStackSignature(stack) { 588 var lines = ("" + stack).split("\n"), out = [], i, m; 589 for (i = 0; i < lines.length && out.length < 5; i++) { // 5 frames: deep recursion collapses 590 m = lines[i].match(/^\s*at\s+([^\s(]+)/) // Chrome/Edge: " at doFoo (url:1:2)" 591 || lines[i].match(/^\s*([^\s@]+)@/); // Safari/Firefox: "doFoo@url:1:2" 592 if (m && m[1]) 593 out.push(m[1]); 594 } 595 return out.join(">"); 596 } 597 598 function doGetHash(text) { 599 var h = 0x811c9dc5; // FNV-1a, 32-bit 600 for (var i = 0; i < text.length; i++) { 601 h ^= text.charCodeAt(i); 602 h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0; 603 } 604 return h.toString(36); 605 } 606 607 // true = already reported, skip. Marks as seen on first call. 608 function doCheckSentBefore(hash) { 609 if (m_sentHash[hash] === true) 610 return true; 611 m_sentHash[hash] = true; 612 var list = []; 613 try { list = (localStorage.getItem(m_hashKey) || "").split(","); } catch (e) { } 614 if (list.indexOf(hash) != -1) 615 return true; 616 list.push(hash); 617 if (list.length > m_hashMax) // bounded ring, oldest hashes fall off 618 list = list.slice(list.length - m_hashMax); 619 try { localStorage.setItem(m_hashKey, list.join(",")); } catch (e) { } 620 return false; 621 } 622 623 function doReportError(kind, message, source, lineno, colno, error) { 624 var msgStr = (message == null) ? "" : ("" + message); 625 if (msgStr == "Script error." || msgStr.indexOf("_AutofillCallbackHandler") != -1) 626 return; 627 // Third-party noise, not our code -> ignore. Six families: 628 // 1. In-app browsers (Meta/IG/FB/Snapchat) inject native bridges that throw in non-native webviews. 629 // 2. Android/iOS WebView bridge objects get torn down on navigation ("Java object is gone"). 630 // 3. Injected analytics (GTM Custom HTML tags) throw from their own host, not ours. 631 // 4. Browser reader-mode shims (Brave/Firefox iOS inject window.__firefox__) throw before .reader exists. 632 // 5. MS Office/Outlook link-handler bridge rejects on a torn-down object id, on pages opened from email. 633 // 6. TikTok/Bytedance webview (musical_ly UA, FalconTag) injects its own script that handshakes 634 // with a parent iframe bridge that doesn't exist in the ad-preview dialog. 635 var stackStr = (error && error.stack) ? ("" + error.stack) : ""; 636 var noise = [ 637 "window.webkit.messageHandlers", // iOS webkit bridge (Meta/IG/FB) 638 "WebJSBridge", // Snapchat bridge 639 "sendDataToNative",
640 "sendPageShowMessage", 641 "Java object is gone", // Android WebView bridge torn down (IG keyboard/nav loggers) 642 "googletagmanager.com", // GTM Custom HTML tags 643 "__firefox__", // Brave/Firefox iOS reader-mode injection 644 "Object Not Found Matching Id:", // MS Office/Outlook bridge, e.g. "...Id:6, MethodName:update, ParamCount:4" 645 "iframeBridge", // TikTok FalconTag handshake into a parent bridge that isn't there 646 "user-script:" // frames from webview-injected scripts (TikTok/Bytedance); ours are https:// URLs 647 ]; 648 var haystack = msgStr + "\n" + stackStr + "\n" + (source == null ? "" : source); 649 for (var i = 0; i < noise.length; i++) 650 if (haystack.indexOf(noise[i]) != -1) 651 return; 652 // In-app browsers run injected scripts under a private "<name>js://" URL scheme 653 // (iabjs:// = Instagram). Our own code only ever runs from http(s):// -> any *js:// frame is theirs. 654 if (/[a-z0-9_]+js:\/\//i.test(stackStr)) 655 return; 656 // ServiceWorker registration failing to *fetch the script* (AbortError) = in-app browsers / 657 // blocked-storage contexts that can't install a SW. Benign, non-actionable. Deliberately narrow: 658 // real breakage (bad HTTP 404, SecurityError, parse error) has a different message and still logs. 659 if (msgStr.indexOf("Failed to register a ServiceWorker") != -1 && msgStr.indexOf("fetching the script") != -1) 660 return; 661 // Benign network/fetch-abort promise rejections (flaky mobile networks, in-app browsers, 662 // navigation aborting an in-flight request, blocked third-party trackers). No stack, not 663 // actionable. Scoped to promise rejections so real TypeErrors in our code still log. 664 if (kind == "promise" && (msgStr == "Load failed" 665 || msgStr.indexOf("Failed to fetch") != -1 666 || msgStr.indexOf("NetworkError") != -1 667 || msgStr.indexOf("network connection was lost") != -1 668 || msgStr.indexOf("cancelled") != -1 669 || msgStr.indexOf("appears to be offline") != -1)) 670 return; 671 // Benign browser notice, not an exception: an observer callback resized things again, so the 672 // browser deferred the remaining notifications to the next frame. Comes from third-party 673 // swiper/animation code, has no stack, and nothing breaks. Both wordings ("loop limit exceeded" 674 // = Chrome, "loop completed with undelivered notifications" = Safari/Chrome) are the same event. 675 if (msgStr.indexOf("ResizeObserver loop") != -1) 676 return; 677 var parameters = {}; 678 try { 679 var name = (error && error.name) ? error.name : ""; 680 var realMsg = (error && error.message) ? error.message : msgStr; 681 var stack = (error && error.stack) ? error.stack : "(no stack available)"; 682 parameters["_exceptionMessage"] = "[" + kind + "] " + (name ? name + ": " : "") + realMsg; 683 parameters["_methodName"] = source + " -- Row N° " + lineno + " Col N° " + colno; 684 parameters["_exception"] = doGetSystemInfo() + "\n\n" + stack; 685 686 687 if (typeof doSendAjax == "function") { 688 var hash = doGetHash(kind + "|" + name + "|" + realMsg + "|" + doGetStackSignature(stack)); 689 if (!doCheckSentBefore(hash)) 690 doSendAjax(RequestCode.SystemService.SaveExceptionJS, ko.toJSON(parameters), null, null); 691 } 692 } 693 catch (e) { console.log(e); } 694 } 695 696 window.onerror = function doErrorHandler(message, source, lineno, colno, error) { 697 doReportError("onerror", message, source, lineno, colno, error); 698 return true; 699 }; 700 701 window.addEventListener('unhandledrejection', function (e) { 702 var reason = e ? e.reason : null; 703 var msg = (reason && reason.message) ? reason.message : ("" + reason); 704 doReportError("promise", msg, 705 (reason && reason.fileName) || "", 706 (reason && reason.lineNumber) || 0, 707 (reason && reason.columnNumber) || 0, 708 reason); 709 }); 710 </script>
vendor: 2 bytes, line 710
710
711<script type="application/javascript"> 712 m_isCrawlByBot = 'True' == 'True'; 713 714 window.addEventListener('resize', function() 715 { 716 if(typeof m_handlerLayout != "object" || m_handlerLayout == null) 717 return; 718 719 if(typeof m_handlerLayout.m_isViewMobile == "function") 720 m_handlerLayout.m_isViewMobile('False' == 'True' || window.innerWidth < 768); 721 722 if(typeof m_handlerLayout.m_isMenuMobile == "function") 723 m_handlerLayout.m_isMenuMobile(window.innerWidth < 992); 724 }); 725 726 727 window.doOpenCropper = function (handler, folder, item) {} 728 729 // Requested FIRST, so it sits at the head of m_listScript and no page callback can run before its 730 // globals exist -- doSetEnumManager reads m_jsonTranslate, and the callback below reads all three 731 // jsonList* blobs. It carries no callback of its own; being in the queue is the whole point. 732 // It is a parallel fetch, not a serial one: it goes out alongside script.min.js, and the bundle is 733 // the bigger of the two. 734 doLoadScript(function () { }, m_initDataUrl); 735 736 doLoadScript(function () { 737 m_version = '639260136446764345'; 738 doSetSetting('https://brandfullsapi.azurewebsites.net', 'ar', 'sa', 'https://cdn.brandfull.com', 'BrandFull', "", "{\u0022_bundleSelectPercentage\u0022:40,\u0022_addCartQuantityLimit\u0022:\u0022100\u0022,\u0022_showObjectHtml\u0022:true,\u0022_showObjectExtras\u0022:true,\u0022_showObjectIsReturnable\u0022:true,\u0022_showObjectCounter\u0022:true,\u0022_showObjectDeliveryTime\u0022:false,\u0022_returnPolicyDays\u0022:\u00227\u0022,\u0022_returnPolicyFees\u0022:0,\u0022_returnPolicyMethod\u0022:0,\u0022_returnPolicyRefundType\u0022:0,\u0022_returnPolicyCountry\u0022:\u0022SA\u0022,\u0022_isBarCodeOptional\u0022:true,\u0022_allowPriceSaleAbovePriceRegulare\u0022:true}"); 739 740 741 if (doGetParamFromURL('Cookies') == "delete") 742 { 743 doSetCookie('cart', null, 1); 744 doGetSessionID(); 745 746 doRemoveURLParam("Cookies"); 747 } 748 749 m_handlerSession = new Handler_Session(); 750 m_handlerSession.doInitData(jsonListCompany, jsonListCountry); 751 doSetHandlerSession(m_handlerSession); 752 m_handlerLayout = new Handler_Layout(); 753 m_handlerLayout.m_isViewMobile('False' == 'True' || window.innerWidth < 768); 754 m_handlerLayout.doInitData(jsonListCategory); 755 m_handlerLayout.m_currentCategoryShortName('Checkout'); 756 m_handlerLayout.m_search(""); 757 doSetHandlerLayout(m_handlerLayout); 758 759 760 }); 761 762 // scriptPage.min.js -- bootstrap.bundle plus the Google-Maps position helper -- is NOT requested 763 // here any more. It was, on every page, with the empty callback this comment replaced: nothing 764 // waited on it, so 82 KB was parsed and compiled on the main thread ahead of the page's bind for 765 // no reader. Its entire consumer surface is interaction-driven: bootstrap.Modal (Tools/Html.ts), 766 // bootstrap.Collapse (Handler_PageCheckout), doGetCurrentPosition, and the data-api attributes in 767 // the markup -- dropdown, collapse, tab, dismiss. None of it runs at load. 768 // 769 // Defined here rather than in the bundle because callers reach it from inline script. 770 var m_pageScriptUrl = "https://cdn.brandfull.com/scriptPage.min.js"; 771 772 function doLoadPageScript(callBack = function () { }) { 773 doLoadScript(callBack, m_pageScriptUrl); 774 } 775 776 // Google Maps, requested once per document rather than once per view. 777 // 778 // doLoadScript dedupes by exact url string, and five views asked for Maps with four different 779 // strings -- two callback names (doInitMap, doInitGoogleMap), and Page_CreateSupport on 780 // maps.google.com rather than maps.googleapis.com, without libraries=places. Ajax navigation 781 // never reloads the document, so visiting two of those pages in one session appended two script 782 // tags for the same library: "You have included the Google Maps JavaScript API multiple times", 783 // followed by the custom elements it registers being defined twice 784 // (Element with name "gmp-internal-dialog" already defined). 785 // 786 // So: one url, and one name for Google to call. Pages hand their own initializer to 787 // doLoadGoogleMaps instead of naming it in a query string. Note the initializer
787s are read at 788 // call time, which is what keeps Page_About and Page_CreateSupport from fighting over the 789 // window.doInitGoogleMap they both define -- each view's inline block re-runs on its own ajax 790 // swap, so the one queued is always the current page's. 791 var m_googleMapUrl = "https://maps.googleapis.com/maps/api/js?libraries=places&key=AIzaSyBELKgTURcJMCbnFgFY4aizo0dbwokRqU4&callback=doGoogleMapsReady&loading=async&language=ar"; 792 var m_isGoogleMapsReady = false; 793 var m_listGoogleMapsReady = []; 794 795 // The single name in the url above. Global because Google resolves it off window. 796 function doGoogleMapsReady() { 797 m_isGoogleMapsReady = true; 798 while (m_listGoogleMapsReady.length > 0) 799 doRunCallBack(m_listGoogleMapsReady.shift()); 800 } 801 802 function doLoadGoogleMaps(callBack = function () { }) { 803 // scriptPage.min.js first: every page initializer this fans out to reaches into 804 // _Js/GoogleMapGetCurrentLocation.js -- doInitMap is defined there outright, and 805 // Page_About / Page_CreateSupport push into the `markers` array it declares. 806 doLoadPageScript(function () { 807 if (m_isGoogleMapsReady) { 808 doRunCallBack(callBack); 809 return; 810 } 811 812 m_listGoogleMapsReady.push(callBack); 813 doLoadScript(function () { }, m_googleMapUrl); 814 }); 815 } 816 817 // Bootstrap installs its data-api listeners on document when it evaluates, so a click that lands 818 // before the file does is a click that does nothing. Hence arming on the earliest signals a real 819 // visitor produces -- hover and scroll both precede the first tap far more often than not -- and 820 // not merely on the click itself. Capture phase so a stopPropagation somewhere cannot hide them. 821 // 822 // The load-event fallback is for the visitor who reads without touching anything. It is behind 823 // `load` on purpose: an idle callback armed any earlier competes with the page's own bind for the 824 // main thread, which is the cost this whole change exists to remove. 825 (function () { 826 var isArmed = false; 827 828 function doArmPageScript() { 829 if (isArmed) 830 return; 831 isArmed = true; 832 doLoadPageScript(); 833 } 834 835 var listEvent = ['pointerover', 'pointerdown', 'touchstart', 'keydown', 'scroll']; 836 for (var i = 0; i < listEvent.length; i++) 837 window.addEventListener(listEvent[i], doArmPageScript, { capture: true, once: true, passive: true }); 838 839 window.addEventListener('load', function () { 840 if (typeof window.requestIdleCallback == "function") 841 window.requestIdleCallback(doArmPageScript, { timeout: 3000 }); 842 else 843 setTimeout(doArmPageScript, 1000); 844 }); 845 })(); 846 847 // The Portal's head hook -- GTM, and through GTM's Custom HTML tags the Facebook, Snapchat and 848 // TikTok pixels -- injected on the same signals as scriptPage.min.js instead of parsed inline. 849 // 850 // It used to sit below this script as raw markup, which meant every visitor parsed, compiled and 851 // EXECUTED a tag manager plus three pixels before the browser had seen a single byte of <body>. 852 // Measured on the Blends home page: TBT 1,700ms, FCP 3.3s, and three rounds of asset trimming 853 // ahead of this moved FCP by 0.1s because none of them touched the thing actually holding the 854 // main thread. The error-swallow list at the top of this file already names googletagmanager.com 855 // and the Snapchat WebJSBridge -- the cost was known, only its timing was not. 856 // 857 // A <template> because its content is INERT: the parser builds the nodes but runs no script and 858 // fetches no src, which is the whole point. innerHTML would have been inert too, but only by 859 // accident and only for scripts -- an <img> in the blob would still have been fetched. 860 (function () { 861 var isArmed = false; 862 var isInjected = false; 863 864 function doInjectHeadScript() { 865 if (isInjected) 866 return; 867 isInjected = true; 868 869 var holder = document.getElementById('UI_headScript'); 870 if (!holder) 871 return; 872 873 var fragment = holder.content.cloneNode(true); 874 var listNode = Array.prototype.slice.call(fragment.childNodes); 875 876 for (var i = 0; i < listNode.length; i++) { 877 var node = listNode[i]; 878 879 // A
879<script> moved out of a template stays inert -- "already started" is not the 880 // flag, but a parser-inserted script that was never executed will not execute on 881 // insertion either. It has to be re-created as a fresh element. 882 if (node.nodeName == 'SCRIPT') { 883 var script = document.createElement('script'); 884 for (var a = 0; a < node.attributes.length; a++) 885 script.setAttribute(node.attributes[a].name, node.attributes[a].value); 886 script.text = node.text; 887 888 // async=false on a DYNAMICALLY created script means "in-order", not "blocking": 889 // externals then execute in insertion order relative to each other. GTM's inline 890 // snippet seeds window.dataLayer and must run before gtm.js reads it, and the 891 // default async=true would have let that race. 892 if (script.src) 893 script.async = false; 894 895 document.head.appendChild(script); 896 } 897 else 898 document.head.appendChild(node); 899 } 900 } 901 902 function doArmHeadScript() { 903 if (isArmed) 904 return; 905 isArmed = true; 906 907 // The blob calls doSetThirdParty (see Tools/ThirdPartyDefer.ts, which stubs that name 908 // for exactly this reason). The stub ships in script.min.js, which is fetched async, so 909 // waiting on its ready callback is what guarantees the call lands somewhere. In the old 910 // inline arrangement it did not: the blob ran at parse time, well before the bundle. 911 if (typeof window.doSetThirdParty == "function") { 912 doInjectHeadScript(); 913 return; 914 } 915 916 doLoadScript(doInjectHeadScript); 917 918 // Backstop, because a callback registered on script.min.js never fires if that bundle 919 // errors -- and "the bundle failed" must not also mean "no analytics for that visit". 920 // doInjectHeadScript is idempotent, so whichever path arrives first wins. 921 setTimeout(doInjectHeadScript, 4000); 922 } 923 924 var listHeadEvent = ['pointerover', 'pointerdown', 'touchstart', 'keydown', 'scroll']; 925 for (var h = 0; h < listHeadEvent.length; h++) 926 window.addEventListener(listHeadEvent[h], doArmHeadScript, { capture: true, once: true, passive: true }); 927 928 // WHEN the blob runs, and the reason it is not simply "on load, then idle" any more. 929 // 930 // Measured on the Blends home page: the tag manager and the pixels it injects through its 931 // Custom HTML tags cost 2,217 ms of main-thread CPU -- more than every first-party script 932 // on the page put together (1,944 ms). Five Google containers alone are 1,204 ms of that, 933 // then Facebook 417, Clarity 252, TikTok 137, Pinterest 110, Snapchat 97. 934 // 935 // The old trigger was `load` plus requestIdleCallback(timeout 3000). Both fire while the 936 // page is still doing its own work: `load` only means subresources finished, not that the 937 // bind and the div hydration have, and a 3-second timeout fires whether or not an idle slot 938 // ever appeared. So 2.2 seconds of vendor script landed on a main thread that was still 939 // building the page. 940 // 941 // "Stable" is defined here as the browser itself defines it -- no long task for a 942 // continuous stretch -- rather than as a delay someone picked. Every long task pushes the 943 // decision back; when the page finally goes quiet for m_headQuietMs the blob goes in on the 944 // next idle slot. That is the same shape as TTI with a shorter quiet window, which is the 945 // point: analytics should start as soon as the page has actually settled, not at a fixed 946 // time that is too early on a slow device and too late on a fast one. 947 // 948 // Interaction still wins outright, above: a visitor who is already touching the page has a 949 // usable page by definition, and their session is the one most worth recording. 950 var m_headQuietMs = 2000; // continuous no-long-task stretch that counts as settled 951 var m_headCapMs = 10000; // hard backstop -- see below 952 var m_headQuietTimer = null; 953 954 function doDelayHeadScript() { 955 clearTimeout(m_headQuietTimer); 956 m_headQuietTimer = setTimeout(function () { 957 if (typeof window.requestIdleCallback == "function") 958 window.requestIdleCallback(doArmHeadScript, { timeout: 2000 }); 959 else 960 doArmHeadScript(); 961 }, m_headQuietMs); 962 } 963 964 window.addEventListener('load', function () { 965 // A main thread that never goes quiet -- a slow device, a runaway third-party, a tab 966 // that stays busy -- must not mean no analytics at all for that visit. This fires 967 // regardless; doArmHeadScript is idempotent, so whichever path gets there first wins. 968 setTimeout(doArmHeadScript, m_headCapMs); 969 970 // longtask is Chromium-only. Where it is missing (Safari, Firefox) there is nothing to 971 // observe, so the quiet timer simply runs once from load and behaves like the old 972 // fixed delay -- degraded to the previous behaviour, not to no behaviour. 973 try { 974 if (typeof PerformanceObserver == "function" 975 && PerformanceObserver.supportedEntryTypes 976 && PerformanceObserver.supportedEntryTypes.indexOf('longtask') != -1) { 977 new PerformanceObserver(function () { 978 if (!isArmed) 979 doDelayHeadScript(); // still busy -- restart the quiet window 980 }).observe({ type: 'longtask', buffered: false }); 981 } 982 } 983 catch (error) { console.log(error); } 984 985 doDelayHeadScript(); 986 }); 987 })(); 988 989</script>
vendor: 2 bytes, line 989
989
990<script> 991 (function () { 992 // The reference file is NOT a stylesheet -- it opens with an HTML comment header and 993 // wraps the payload in <style>, exactly as the Portal field must. So it cannot be a 994 // <link>: the header would be a parse error and the tags are not CSS. Fetch it and 995 // hand the browser the same string @Html.Raw would have emitted. 996 var url = 'https://brandfull.com/Themes/Cartzilla/_Css/BrandFull/StyleCss_Script.reference.css?version=639260136446764345'; 997 998 fetch(url, { cache: 'no-store' }) 999 .then(function (response) { 1000 if (!response.ok) 1001 throw new Error('StyleCss_Script.reference.css -> HTTP ' + response.status); 1002 1003 return response.text(); 1004 }) 1005 .then(function (text) { 1006 // Take what is BETWEEN the tags. Assigning the raw text to innerHTML would put a 1007 // literal <style> inside a <style>, which parses as nothing at all. 1008 var match = /<style[^>]*>([\s\S]*?)<\/style>/i.exec(text); 1009 if (!match) { 1010 console.warn('[StyleCss_Script test] no <style> block in ' + url); 1011 return; 1012 } 1013 1014 // Appended to <head> AFTER the site bundle link, so a :root here outranks the 1015 // same :root in StyleApp.css -- the same seam the Portal value occupies. 1016 var style = document.createElement('style'); 1017 style.id = 'UI_styleCssScriptTest'; 1018 style.textContent = match[1]; 1019 document.head.appendChild(style); 1020 }) 1021 .catch(function (error) { console.warn('[StyleCss_Script test] ' + error.message); }); 1022 })(); 1023</script>
1023 1024<template id="UI_headScript"> 1025<!-- Google Tag Manager -->
1026<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s);j.async=true;j.src="https://shn.brandfull.com/cjbruxijtzaj.js?"+i;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','ezx8gtx3=AwVHMz4kVSU%2BKzA3PSU0UxxcSFpbTxwbVwMIFQQNHgAGDVQXBQQ%3D');</script>
1026 1027<!-- End Google Tag Manager --> 1028 1029</template> 1030 1031</head> 1032 1033<body id="UI_body" style="overflow-y: clip;" class="noPadding"> 1034 1035 1036 1037 1038 1039 1040 <h1 class="seo-hidden"></h1> 1041 <h2 class="seo-hidden"></h2> 1042 1043
1043<script type="application/ld+json"> 1044 { 1045 "@context": "https://schema.org", 1046 "@type": "OnlineStore", 1047 "name": "Brandfull", 1048 "alternateName": "Brandfull", 1049 "description": "At Brandfull we believe in second chances and the thrill of discovering hidden treasures. Our journey began with a simple idea: to bring new life into pre-loved items while offering our customers unique finds that resonate with their individuality.", 1050 "knowsLanguage": "AR,EN", 1051 "sameAs": [ 1052 "https://www.facebook.com/brandfullCom/", 1053 "https://twitter.com/brandful_l", 1054 "https://www.instagram.com/brandfull_ksa/", 1055 "https://api.whatsapp.com/send?phone=966592905003", 1056 "https://www.snapchat.com/add/brandful_l" 1057 ], 1058 "url": "https://brandfull.com", 1059 "logo": "https://brandfull.com/_Image/favicon.png","hasMerchantReturnPolicy":{"@type":"MerchantReturnPolicy","applicableCountry":"SA","returnPolicyCategory":"https://schema.org/MerchantReturnFiniteReturnWindow","merchantReturnDays":7,"returnMethod":"https://schema.org/ReturnByMail","returnFees":"https://schema.org/FreeReturn","refundType":"https://schema.org/FullRefund"} 1060 } 1061 </script>
1061 1062 1063
1063<script type="application/ld+json"> 1064 { 1065 "@context": "https://schema.org", 1066 "@type": "ContactPoint", 1067 "@contactType": "Customer Service", 1068 "availableLanguage": "AR,EN", 1069 "email": "[email protected]", 1070 "telephone": "966592905003" 1071 } 1072 </script>
1072 1073
1073<script type="application/ld+json"> 1074 { 1075 "@context": "https://schema.org", 1076 "@type": "WebSite", 1077 "name": "WebSite Brandfull", 1078 "url": "https://brandfull.com", 1079 "potentialAction": [ 1080 { 1081 "@type": "SearchAction", 1082 "target": "https:/brandfull.com/Shop/search?q={search_term_string}", 1083 "query-input": "required name=search_term_string" 1084 } 1085 ] 1086 } 1087 </script>
1087 1088 1089 1090 <!-- Home Popup Section --> 1091 <!-- End Screen Load Popup Section --> 1092 <!-- START HEADER --> 1093 1094 1095 1096
1097<script type="application/javascript"> 1098 1099 window.doClosePopUp = function () { 1100 document.querySelectorAll('.dropdown-menu.show').forEach(function (option) { 1101 option.classList.remove('show'); 1102 }); 1103 document.querySelectorAll('.dropdown-menu.hide').forEach(function (option) { 1104 option.classList.remove('hide'); 1105 }); 1106 } 1107 1108 window.doShowQuickPopup = function (id, isFocus) { 1109 if (isFocus == true) 1110 m_handlerLayout.doGetQuickFilter(); 1111 else 1112 setTimeout(function () { 1113 m_handlerLayout.m_showQuickPopUp(false); 1114 }, 250) 1115 } 1116 1117 window.doJSClickSearch = function (){ 1118 var searchSection = document.querySelector('#UI_searchSection'); 1119 if(searchSection.classList.contains('show')) 1120 searchSection.classList.remove('show'); 1121 else 1122 searchSection.classList.add('show'); 1123 1124 var searchIcon = document.querySelector('#UI_searchIcon'); 1125 if(searchIcon.classList.contains('ci-search')){ 1126 searchIcon.classList.remove('ci-search'); 1127 searchIcon.classList.add('ci-close'); 1128 } 1129 else{ 1130 searchIcon.classList.remove('ci-close'); 1131 searchIcon.classList.add('ci-search'); 1132 } 1133 } 1134 doLoadScript(function () { 1135 if (!ko.dataFor(document.getElementById('UI_headerSession'))) { 1136 ko.applyBindings(m_handlerSession, document.getElementById("UI_headerSession")); 1137 } 1138 1139 if (!ko.dataFor(document.getElementById('UI_LayoutHeader'))) { 1140 ko.applyBindings(m_handlerLayout, document.getElementById("UI_LayoutHeader")); 1141 ko.applyBindings(m_handlerLayout, document.getElementById("UI_preLoader")); 1142 } 1143 1144 var navBar = document.getElementById("UI_menuNavBar"); 1145 if (navBar) navBar.style.visibility = "visible"; 1146 var searchPopup = document.getElementById("UI_searchQuickPopup"); 1147 if (searchPopup) searchPopup.style.visibility = "visible"; 1148 var layoutHeader = document.getElementById("UI_LayoutHeader"); 1149 if (layoutHeader) layoutHeader.style.visibility = "visible"; 1150 // After applyBindings above, so every marked block already carries the inline display its 1151 // binding gave it and nothing flashes as the gate lifts. 1152 if (layoutHeader) layoutHeader.classList.remove("ko-pending"); 1153 1154 doJsDropdownSelect(); 1155 1156 }); 1157 1158</script>
1158 1159 1160 1161<header id="UI_LayoutHeader" class="bg-light shadow-sm fixHeightHeader ko-pending"> 1162 1163 <div id="UI_menuQuick" class="topbar topbar-dark bg-darker py-sm-1 py-md-0"> 1164 <div class="container"> 1165 <div class="topbar-text dropdown d-md-none"> 1166 <a class="topbar-link dropdown-toggle" href="#" data-bs-toggle="dropdown">Ø±ÙØ§Ø¨Ø· Ù ÙÙØ¯Ø©</a> 1167 <ul class="dropdown-menu"> 1168 <li> 1169 <a class="dropdown-item textAlignAuto" enable-href="false" href="/Support"><i class="ci-support text-muted me-2-Auto"></i>Ø§ØªØµÙ Ø¨ÙØ§</a> 1170 </li> 1171 <li> 1172 <a class="dropdown-item textAlignAuto" href="#" target="_blank" enable-href="true" data-bind="attr:{href:m_handlerSession.m_currentCompany._whatsappLink}" rel="noreferrer"> 1173 <i class="ci-whatsapp text-muted me-2-Auto"></i>ÙØ§ØªØ³ اب 1174 </a> 1175 </li> 1176 </ul> 1177 </div> 1178 <div class="topbar-text text-nowrap d-none d-md-inline-block"> 1179 <a class="topbar-link" enable-href="false" href="/Support"><i class="ci-support me-2-Auto"></i>Ø§ØªØµÙ Ø¨ÙØ§</a> 1180 <!-- ko if: !doCheckEmptyData(m_handlerSession.m_currentCompany._whatsappLink()) --> 1181 <a class="btn-social bs-light bs-whatsapp me-1-Auto mb-1" href="#" enable-href="true" data-bind="attr:{href:m_handlerSession.m_currentCompany._whatsappLink}" target="_blank" rel="noreferrer" aria-label="Share WhatsApp"> 1182 <i class="ci-whatsapp font-size-14"></i> 1183 </a> 1184 <!-- /ko --> 1185 </div> 1186 1187 <slotHeader class="bf-announceSlot"></slotHeader> 1188 1189 <div class="text-nowrap"> 1190 <div class="topbar-text dropdown disable-autohide"> 1191 <a class="topbar-link dropdown-toggle" href="#" data-bs-toggle="dropdown"> 1192 <span class="px-1" data-bind="text: doGetCulture()=='ar'? 'عربÙ':'English'"></span> 1193 <span class="px-1">/</span><span class="px-1" data-bind="text: m_handlerSession.m_currentCurrency._code"></span> 1194 </a> 1195 1196 <ul class="dropdown-menu dropdown-menu-end"> 1197 <!-- ko if: m_handlerSession.m_currentCompany._currences().length > 1 --> 1198 <li class="dropdown-item"> 1199 <select class="form-select form-select-sm" style=" padding: 5px;" data-bind="value: m_handlerSession.m_currentCurrency._code, options: m_handlerSession.m_currentCompany._currences, optionsText: '_code', optionsValue: '_code'"> 1200 </select> 1201 </li> 1202 <!-- /ko --> 1203 <!-- ko if: m_handlerSession.m_listCompany().length > 1 --> 1204 <li class="dropdown-item"> 1205 <div class="fs-sm fw-medium mb-1 w-100 textAlignAuto">Ø¨ÙØ¯</div> 1206 <select class="form-select" style=" padding: 5px;" data-bind="value: m_handlerSession.m_currentCompany._id, options: m_handlerSession.m_listCompany, optionsText: '_countryName', optionsValue: '_id'"> 1207 </select> 1208 </li> 1209 <!-- /ko --> 1210 <li> 1211 <button class="dropdown-item d-flex align-items-center font-size-10" onclick="m_handlerSession.doSetCulture('ar')"> 1212 <span class="langImage me-2-Auto" data-bind="style:{'background-position-x': doGetlangImage('ar')}" style="background-image: url(https://cdn.brandfull.com/Media/BrandFull/images.png?version=639260136446764345)"></span> 1213 <span>عربÙ</span> 1214 </button> 1215 </li> 1216 <li> 1217 <button class="dropdown-item d-flex align-items-center font-size-10" onclick="m_handlerSession.doSetCulture('en')">
1218 <span class="langImage me-2-Auto" data-bind="style:{'background-position-x': doGetlangImage('en')}" style="background-image: url(https://cdn.brandfull.com/Media/BrandFull/images.png?version=639260136446764345)"></span> 1219 <span>English</span> 1220 </button> 1221 </li> 1222 </ul> 1223 </div> 1224 </div> 1225 </div> 1226 </div> 1227 <div class="navbar-sticky bg-light pt-1"> 1228 <div class="navbar navbar-expand-lg navbar-light py-0"> 1229 <div class="container bf-headerRow"> 1230 <div id="UI_searchSection" class="input-group widthSearch mt-sm-2 collapse"> 1231 <div class="input-group d-lg-flex m-0 "> 1232 <input autocomplete="off" class="form-control focus-black m_search" type="text" data-bind="value: m_search" onfocusin="doShowQuickPopup('UI_searchQuickPopup', true)" onfocusout="doShowQuickPopup('UI_searchQuickPopup', false)" placeholder="Ø§ÙØ¨ØØ« Ø¹Ù Ø§ÙØ¹Ùا٠ة Ø§ÙØªØ¬Ø§Ø±ÙØ©" /> 1233 <div class="m_searchIcons position-absolute top-50 translate-middle-y text-muted"> 1234 <i class="ci-camera pointer" data-bind="click: window.doOpenCropper.bind($root, $root, GlobalSettingTranslateEnum.PathObjectPicture, m_currentPicture)"></i> 1235 <i class="ci-search pointer" data-bind="click: $root.doSearchByWord.bind($root)"></i> 1236 </div> 1237 </div> 1238 1239 1240 1241<div id="UI_searchQuickPopup" data-koPending class="quickPopUp border rounded-1 p-3 mt-md-n1 bg-white" data-bind="visible:m_showQuickPopUp()"> 1242 1243 <!-- ko if: m_listQuickFilterCategory().length != 0 --> 1244 <b class="font-size-10 fw-bolder mt-2 mb-1 text-accent">ÙØ¦Ø§Øª Ù ÙØ¶ÙØ© ÙØ¯ÙÙÙ </b> 1245 <div class="d-flex flex-wrap align-content-around" data-bind="foreach: m_listQuickFilterCategory"> 1246 <a class=" border rounded me-1 mb-1" href="#" enable-href="false" data-bind="click: doLoadMenuLink.bind($root, doGetLinkQuickFilter($data._value())) , attr:{href: doGetLinkQuickFilter($data._value()) }"> 1247 <div class="btn btn-sm p-1 font-size-10" data-bind=" text: $data._name()"> 1248 </div> 1249 </a> 1250 </div> 1251 <!-- /ko --> 1252 <!-- ko if: m_listQuickFilterColor().length != 0 --> 1253 <b class="font-size-10 fw-bolder mt-3 mb-1 text-accent ">اÙÙÙ٠ذات شعبÙÙ</b> 1254 <div class="d-flex flex-wrap align-content-around" data-bind="foreach: m_listQuickFilterColor"> 1255 <a class=" border rounded me-1 mb-1" href="#" enable-href="false" data-bind="click: m_handlerLayout.doSetSearch.bind($root, $data._name()), attr:{href: doGetLinkQuickFilter($data._name()) }"> 1256 <div class="btn btn-sm p-1 font-size-10" data-bind=" text: $data._name()"> 1257 </div> 1258 </a> 1259 </div> 1260 <!-- /ko --> 1261 <!-- ko if: m_listQuickFilterTag().length != 0 --> 1262 <b class="font-size-10 fw-bolder mt-3 mb-1 text-accent">اÙÙ Ø§Ø±ÙØ§Øª Ø§ÙØ£Ùثر Ø´Ø¹Ø¨ÙØ©</b> 1263 <div class="d-flex flex-wrap align-content-around" data-bind="foreach: m_listQuickFilterTag"> 1264 <a class=" border rounded me-1 mb-1" href="#" enable-href="false" data-bind="click: m_handlerLayout.doSetSearch.bind($root, $data._name()), attr:{href: doGetLinkQuickFilter($data._name()) }"> 1265 <div class="btn btn-sm p-1 font-size-10" data-bind=" text: $data._name()"> 1266 </div> 1267 </a> 1268 </div> 1269 <!-- /ko --> 1270 1271</div> 1272 1273 </div> 1274 <div class="bf-headerRow-lead"> 1275 <a class="navbar-tool d-lg-none" href="/#UI_menuSection" aria-label="menu" name="menu" onclick="doClosePo
1275pUp()" data-bs-toggle="collapse" role="button" aria-expanded="false" aria-controls="UI_menuSection"> 1276 <span class="navbar-tool-icon-box"><i class="navbar-toggler-icon mt-1"></i></span> 1277 </a> 1278 </div> 1279 <div class="bf-headerRow-brand"> 1280 <a class="navbar-brand textAlignAuto" href="https://brandfull.com" enable-href="true"> 1281 <img class="headerBrandLogo" style="--logo-width: 125px; --logo-height: 41px;" fetchpriority="high" decoding="async" src="https://cdn.brandfull.com/Media/BrandFull/headerDesktopLogo_ar.png?format=webp&size=Thumb&version=639260136446764345" width="905" height="297" alt="AltLogo" title="Ø§ÙØ¹ÙÙØ§ÙØ§ÙØ´Ø¹Ø§Ø±" /> 1282 </a> 1283 </div> 1284 <!-- ko stopBinding: true --> 1285 <div id="UI_headerSession" class="navbar-toolbar d-flex flex-shrink-0 align-items-center bf-headerRow-trail"> 1286 1287 <!-- ko if: doCheckUUID(m_currentUser._id()) --> 1288 <a name="Favorites" aria-label="Favorites" class="navbar-tool-icon-box dropdown-toggle flipAuto d-lg-block d-md-none d-sm-none" enable-href="false" href="/Account/Favorites"> 1289 <i class="navbar-tool-icon ci-heart" style="width: 45px;"></i> 1290 </a> 1291 <div class="navbar-tool dropdown pointer d-lg-flex d-md-none d-sm-none" data-bind="visible: doCheckUUID(m_currentUser._id())" onmouseenter="doPrepareAdvertisement()"> 1292 <span class="navbar-tool-icon-box dropdown-toggle flipAuto" onclick="doOpenAdvertisement()"> 1293 <span class="navbar-tool-label flipAuto" data-bind="text: m_countAdvertisement() > 99 ? '99+' : m_countAdvertisement()"></span> 1294 <i class="navbar-tool-icon ci-bell" style="width: 45px;"></i> 1295 </span> 1296 <div id="UI_menuWebAdvertisement" class="dropdown-menu dropdown-menu-end textAlignAuto"> 1297 <div class="widget widget-cart px-3 pt-2 pb-0"> 1298 <div class="d-flex align-items-center justify-content-between"> 1299 <!-- ko if: !m_handlerLayout.m_isViewMobile() --> 1300 <div class="col-md-10"> 1301 <!-- ko if: m_enableNotifGrant() --> 1302 <button id="UI_notifGrant" class="btn d-flex align-content-between align-items-center font-size-10 p-1 " onclick="doGetPermissionNotification()"> 1303 <i class="ci-settings me-2-Auto font-size-14 "></i> 1304 <span class="form-check-label elide text-black fw-bolder heartbeat" for="UI_agreeWebPush"> 1305 ابÙÙ٠عÙÙ Ø§Ø·ÙØ§Ø¹ 1306 </span> 1307 </button> 1308 <!-- /ko --> 1309 <!-- ko if: m_enableNotifDenied() --> 1310 <div id="UI_notifDenied" class="d-flex align-content-between align-items-center font-size-10 p-1 "> 1311 <i class="ci-announcement me-2-Auto font-size-14 fw-bolder"></i> 1312 <span class="form-check-label elide text-danger fw-bolder heartbeat"> 1313 Ø§ÙØ¥Ø´Ø¹Ø§Ø±Ø§Øª Ù ØØ¬Ùبة. شغÙÙØ§ Ù٠إعدادات اÙÙ ØªØµÙØ ÙØªØØµÙ عÙÙ ØªÙØ¨ÙÙØ§Øª. 1314 </span> 1315 </div> 1316 <!-- /ko --> 1317 1318 </div> 1319 <!-- /ko --> 1320 </div> 1321 1322 <div id="UI_notificationList" data-simplebar data-simplebar-auto-hide="false" style="overflow-x: hidden;max-height: 21rem;" data-bind="visible: m_listAdvertisement().length!=0, foreach: { data: m_showAdvertisement() ? m_listAdvertisement() : [] }"> 1323 <div class="border-bottom py-1 me-3-Auto d-flex justify-content-between border-danger" style=" border-bottom-style: dotted !important;" data-bs-dismiss=""> 1324 <label class="form-text elide w-75 pointer" data-bind="click: $root.doSetTaged.bind($root, $data, true), text:$data._subject()"></label> 1325 <b class="form-check-label textAlignReverse font-size-10 d-inline-block mb-n2 fw-light" data-bind="click: $root.doSetTaged.bind($root, $data, true), text: doCalcDateDifference(doCastFromUTC($data._dateCreate()))"></b> 1326 </div> 1327</div> 1328 1329 </div> 1330 </div> 1331 </div> 1332 1333 1334 <!-- /ko --> 1335 <div id="UI_userSession" class="navbar-tool dropdown pointer d-lg-flex d-md-none d-sm-none">
1336 <span class="navbar-tool-icon-box " onclick="doOpenProfile()"> 1337 <i class="navbar-tool-icon ci-user "></i> 1338 </span> 1339 1340 <span class=" d-none d-lg-flex" style="padding-left:unset; max-width: 75px;" href="#"> 1341 <!-- ko if: doCheckUUID(m_currentUser._id()) --> 1342 <small class="elide text-black" data-bind="text: m_currentUser._name()"></small> 1343 <!-- /ko --> 1344 <!-- ko if: !doCheckUUID(m_currentUser._id()) --> 1345 <small class="elide text-black">ØØ³Ø§Ø¨</small> 1346 <!-- /ko --> 1347 </span> 1348 <!-- Session dropdown--> 1349 <!-- ko if: doCheckUUID(m_currentUser._id()) --> 1350 <div class="dropdown-menu dropdown-menu-end"> 1351 <div class="widget widget-cart px-3 pt-2 pb-3 textAlignAuto"> 1352 <!-- ko if: doCheckUUID(m_currentUser._id()) --> 1353 <div class="fs-sm fw-medium mb-1">ØØ³Ø§Ø¨</div> 1354 <a class="dropdown-item d-flex align-items-center py-1" enable-href="false" href="/Account/Profile"> 1355 <i class="ci-user opacity-60 me-2-Auto"></i>اÙÙ ÙÙ Ø§ÙØ´Ø®ØµÙ 1356 </a> 1357 <a class="dropdown-item d-flex align-items-center py-1" enable-href="false" href="/Account/Invoices"> 1358 <i class="ci-basket opacity-60 me-2-Auto"></i>اÙÙÙØ§ØªÙر 1359 </a> 1360 <a class="dropdown-item d-flex align-items-center py-1" enable-href="false" href="/Account/Supports"> 1361 <i class="ci-help opacity-60 me-2-Auto"></i>ØªØ°Ø§ÙØ± 1362 </a> 1363 <a class="dropdown-item d-flex align-items-center py-1" enable-href="false" href="/Account/Messages"> 1364 <i class="ci-message opacity-60 me-2-Auto"></i>رسائ٠1365 </a> 1366 1367 <div class="dropdown-divider"></div> 1368 <a class="dropdown-item d-flex align-items-center py-1" href="#" enable-href="false" data-bind="click: $root.doLogOut.bind($root, '/Account/LogOff?Value=https%3A%2F%2Fbrandfull.com%2FCheckout')"> 1369 <i class="ci-sign-out opacity-60 me-2-Auto"></i>تسجÙÙ Ø§ÙØ®Ø±Ùج 1370 </a> 1371 <!-- /ko --> 1372 </div> 1373 </div> 1374 <!-- /ko --> 1375 </div> 1376 1377 <a href="#" aria-label="Ø§ÙØ¨ØØ«" name="Search" class="navbar-tool-icon-box dropdown-toggle flipAuto" enable-href="false" onclick="doJSClickSearch()"> 1378 <i id="UI_searchIcon" class="navbar-tool-icon ci-search animate-target" style="width: 45px;"></i> 1379 </a> 1380 <div id="UI_shopNav" class="navbar-tool pointer" onclick="m_handlerSession.doOpenCartDrawer();"> 1381 <span class="navbar-tool-icon-box flipAuto"> 1382 <span class="navbar-tool-label flipAuto" data-bind="text: doGetCartCount()"></span> 1383 <i class="navbar-tool-icon bold ci-card-bag"></i> 1384 </span> 1385 <span class="d-flex flex-column d-none d-md-flex ps-2-Auto"> 1386 <small class="font-size-10 text-black">Ø³ÙØ© Ø§ÙØªØ³ÙÙ</small> 1387 <!-- ko if: m_currentCart._listCartDetailModel().length!=0 --> 1388 <span class="text-accent fs-base font-size-12" data-bind="html: $root.doCalcPriceDynamic(m_currentCart._total(), true)"></span> 1389 <!-- /ko --> 1390 </span> 1391 </div> 1392 1393 </div> 1394 <!-- /ko --> 1395 </div> 1396 <!-- Search--> 1397 </div> 1398 1399 1400 <div id="UI_menuNavBar" class="navbar navbar-expand-lg navbar-light navbar-stuck-menu mt-n2 pt-0 pb-2" style="visibility: hidden; margin-top: auto !important;"> 1401 <div class="container "> 1402 <div id="UI_menuSection" class="navbar-collapse collapse" data-bind="class: m_listCategoryMenuDepartmentHeader().length ==0 ? 'justify-content-around':''"> 1403 1404<style> 1405 1406 /* The sprite URL is per-request (CDN base + m_version), so it cannot live in the bundled 1407 CSS. It is emitted once here and read by .categoryMerge in StyleCartzilla-Menu.css. 1408 It used to be a full inline `background: url(...)` on EVERY category node -- in this file 1409 and, worse, inside Template_ItemDeskMenu / Template_ItemMobileMenu, which recurse, so the 1410 whole CDN path was re-emitted into the live DOM once per category at every depth. */ 1411 :root { 1412 --category-sprite: url('https://cdn.brandfull.com/Content/category/Merge.png?v=639260136446764345'); 1413 } 1414 1415 .quickPopUp { 1416 visibility: hidden; 1417 z-index: +100; 1418 position: absolute; 1419 top: 47px; 1420 } 1421 1422 [lang="ar"] .quickPopUp { 1423 right: 1px; 1424 } 1425 1426 [lang="en"] .quickPopUp { 1427 left: 1px; 1428 } 1429 1430 1431 @media screen and (max-width:767px) { 1432 .quickPopUp { 1433 z-index: +1; 1434 position: unset; 1435 top: 81px; 1436 width: 100%; 1437 border: hidden !important; 1438 } 1439 } 1440</style> 1441
1442<script id="Template_ItemDeskMenu" type="text/html"> 1443 1444 1445 <ul class="dropdown-menu " data-bind="foreach: $data._list, css:{'d-block fixRtl': $data.mode=='block' }"> 1446 <li class="" data-bind="class: $data._list() != 0 ? 'dropdown':''"> 1447 <a class="dropdown-item d-flex" href="#" enable-href="false" data-bind=" 1448 class: $data._list() != 0 ? 'dropdown-toggle':'', 1449 attr:{href: doGetLinkCategory($data) }"> 1450 <!-- ko ifnot: doCheckEmptyData($data._pictureName()) --> 1451 <span class="categoryMerge" data-bind="style:{'background-position-x': $data._picturePosition()+'px', 'alt': $data._code()}"> 1452 </span> 1453 <!-- /ko --> 1454 <span class="categoryColor menuSpan" data-bind="text: $data._name, attr:{'data-code': $data._code}, style:{'--data-categoryColor': $data._colorDesktopHex()}"></span> 1455 </a> 1456 <!--ko if : $data._list() != 0 --> 1457 <!-- ko run: $data.mode='' --><!-- /ko --> 1458 <!-- ko template: { name: 'Template_ItemDeskMenu' , data:$data} --><!-- /ko --> 1459 <!-- /ko --> 1460 </li> 1461 </ul> 1462 1463</script>
vendor: 2 bytes, line 1463
1463
1464<script id="Template_ItemDeskMegaMenu" type="text/html"> 1465 1466 <ul class="dropdown-menu " data-bind="foreach: $data._list"> 1467 <li class="dropdown mega-dropdown"> 1468 <a class="dropdown-item dropdown-toggle d-flex" href="#" enable-href="false" data-bind="class: $data._list() != 0 ? 'dropdown-toggle':'', attr:{href: !doCheckEmptyData($data._link())? $data._link() : '/Shop'+'/'+$data._code() }" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="true"> 1469 <!-- ko ifnot: doCheckEmptyData($data._pictureName()) --> 1470 <span class="categoryMerge" data-bind="style:{'background-position-x': $data._picturePosition()+'px', 'alt': $data._code()}"> 1471 </span> 1472 <!-- /ko --> 1473 <span class="categoryColor menuSpan " data-bind="text: $data._name, attr:{'data-code': $data._code}, style:{'--data-categoryColor': $data._colorDesktopHex()}"></span> 1474 </a> 1475 </li> 1476 </ul> 1477 1478 1479</script>
vendor: 2 bytes, line 1479
1479
1480<script id="Template_ItemMobileMenu" type="text/html"> 1481 1482 <ul class="widget-list mt-1" data-bind="attr:{'id': 'UI_'+$data._id()}, css:{'collapse collapseShow mx-3': $data.mode=='block'}, foreach: $data._list"> 1483 <li class="widget-list-item"> 1484 <a class="dropdown-item d-flex" href="#" enable-href="false" data-bind="attr:{'aria-controls': 'UI_'+$data._id(), 'data-bs-target':'#UI_'+$data._id(), href: doGetLinkCategory($data) }"> 1485 <!-- ko ifnot: doCheckEmptyData($data._pictureName()) --> 1486 <span class="categoryMerge" data-bind="style:{'background-position-x': $data._picturePosition()+'px', 'alt': $data._code()}"> 1487 </span> 1488 <!-- /ko --> 1489 <span class="categoryColor font-size-14" data-bind="class: ($data._list() != 0 && $parent.mode=='block') ? 'fw-medium':'fw-light', text: $data._name, attr:{'data-code': $data._code}, click: doLoadMenu.bind($root, $data, 'Shop'), style:{'--data-categoryColor': $data._colorMobileHex()}"></span> 1490 </a> 1491 <!--ko if : $data._list() != 0 --> 1492 <!-- ko template: { name: 'Template_ItemMobileMenu' , data:$data} --><!-- /ko --> 1493 <!-- /ko --> 1494 </li> 1495 </ul> 1496 1497</script>
1497 1498 1499 1500 1501<!-- ko ifnot: m_isMenuMobile() --> 1502<!-- ko if: $root.m_listCategoryMenuDepartmentHeader().length!=0 --> 1503<ul class="navbar-nav d-none d-lg-flex navbar-mega-nav pe-lg-2-Auto me-lg-2-Auto" style="padding-right:unset !important"> 1504 <li class="nav-item dropdown"> 1505 <a class="nav-link dropdown-toggle ps-lg-0-Auto " href="#" data-bs-toggle="dropdown" data-bs-auto-close="outside"> 1506 <i class="ci-menu align-middle mt-n1 me-2-Auto"></i> 1507 Ø§ÙØ§Ø¯Ø§Ø±Ø§Øª 1508 </a> 1509 <ul class="dropdown-menu " data-bind="foreach: $root.m_listCategoryMenuDepartmentHeader"> 1510 <li class="dropdown mega-dropdown"> 1511 <a class="dropdown-item dropdown-toggle d-flex" href="#" enable-href="false" data-bind="class: $data._list() != 0 ? 'dropdown-toggle':'', attr:{href: doGetLinkCategory($data) }" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="true"> 1512 <!-- ko ifnot: doCheckEmptyData($data._pictureName()) --> 1513 <span class="categoryMerge" data-bind="style:{'background-position-x': $data._picturePosition()+'px', 'alt': $data._code()}"> 1514 </span> 1515 <!-- /ko --> 1516 <span class="categoryColor menuSpan" data-bind="text: $data._name, attr:{'data-code': $data._code}, click: doLoadMenu.bind($root, $data, 'Shop'), style:{'--data-categoryColor': $data._colorDesktopHex()}"></span> 1517 </a> 1518 <div class="dropdown-menu p-0 megaMenuRtl" data-bind="style: {'min-width': doCheckEmptyData($data._bannerName()) ? '0rem':'12rem'}"> 1519 <div class="d-flex flex-wrap flex-sm-nowrap p-2"> 1520 <div style="max-width: 12rem;" data-bind="class: doCheckEmptyData($data._bannerName()) ? '':'mega-dropdown-column'"> 1521 <!--ko if : $data._list() != 0 --> 1522 <!-- ko run: $data.mode='block' --><!-- /ko --> 1523 <!-- ko template: { name: 'Template_ItemDeskMenu' , data:$data} --><!-- /ko --> 1524 <!-- /ko --> 1525 </div> 1526 <!--ko if : !doCheckEmptyData($data._bannerName()) --> 1527 <div class="mega-dropdown-column d-none d-lg-block text-center"> 1528 <img width="100%" data-bind="attr:{ src: GlobalSettingTranslateEnum.PathCategoryPicture + $data._bannerName(), 'alt': $data._code()}" alt="Menu"> 1529 </div> 1530 <!-- /ko --> 1531 </div> 1532 </div> 1533 </li> 1534 </ul> 1535 </li> 1536</ul> 1537<!-- /ko --> 1538<!-- Primary menu--> 1539<ul class="navbar-nav d-none d-lg-flex" data-bind="css:{'hide': m_listCategoryMenuHeader().length==0}, foreach: m_listCategoryMenuHeader"> 1540 <li class="nav-item dropdown"> 1541 <a class="nav-link dropdown-toggle" enable-href="false" href="#" data-bs-auto-close="outside" data-bind="attr:{href: doGetLinkCategory($data)}"> 1542 <span class="categoryColor bolder" data-bind="text: $data._name, attr:{'data-code': $data._code}, style:{'--data-categoryColor': $data._colorDesktopHex()}"></span> 1543 </a> 1544 <!-- ko if: $data._list().length!=0 --> 1545 <!-- ko run: $data.mode='' --><!-- /ko --> 1546 <!-- ko template: { name: 'Template_ItemDeskMenu' , data:$data} --><!-- /ko --> 1547 <!-- /ko --> 1548 </li> 1549</ul> 1550 1551<!-- Tag menu --> 1552<ul class="navbar-nav d-none d-lg-flex ms-auto align-items-center" data-bind="css:{'hide': m_listCategoryMenuTag().length==0}, foreach: m_listCategoryMenuTag"> 1553 <li class="nav-item me-2-Auto"> 1554 <a class="btn btn-sm rounded-pill border px-3 categoryColor" enable-href="false" href="#" data-bind=" 1555 attr:{href: doGetLinkCategory($data), 'data-code': $data._code}, 1556 text: $data._name, 1557 style:{'--data-categoryColor': $data._colorDesktopHex()}"></a> 1558 </li> 1559</ul> 1560<!-- /ko --> 1561 1562<!-- ko if: m_isMenuMobile() --> 1563<aside class="w-100 zindex-lg-5 pt-lg-5 d-lg-none" aria-modal="true" role="dialog"> 1564 <div class="pt-2 d-none d-lg-block"></div> 1565 1566 <!--ko if : m_listCategoryMenuDepartmentHeader().length!=0--> 1567 <ul class="nav nav-tabs nav-justified mt-4 mt-lg-5 mb-0" role="tablist" style="min-height: 3rem;"> 1568 <li class="nav-item" role="presentation"> 1569 <a class="nav-link fw-medium" href="#UI_departments" data-bs-toggle="tab" role="tab" aria-selected="false" tabindex="-1"> 1570 Ø§ÙØ§Ø¯Ø§Ø±Ø§Øª 1571 </a> 1572 </li> 1573 <li class="nav-item" role="presentation"> 1574 <a class="nav-link fw-medium active" href="#UI_headers" data-bs-toggle="tab" role="tab" aria-selected="true"> 1575 ÙØ§Ø¦Ù Ø© 1576 </a> 1577 </li> 1578 </ul> 1579 <!-- /ko --> 1580 1581 <div class="offcanvas-body px-0 pt-3" data-simplebar="init" data-simplebar-auto-hide="false" style="height: calc( 100% - 35px);"> 1582 <div class="tab-content"> 1583 1584 <!--ko if : m_listCategoryMenuDepartmentHeader().length!=0--> 1585 <div class="sidebar-nav tab-pane fade" id="UI_departments" role="tabpanel"> 1586 <div class="widget widget-categories accordion " id="shop-categories" data-bind="foreach: m_listCategoryMenuDepartmentHeader"> 1587 <div class="accordion-item border-bottom accordion-header pe-2-Auto"> 1588 <button class="accordion-button collapsed fw-bold d-flex align-items-center" type="button" data-bs-toggle="collapse" data-bind="attr:{'aria-controls': 'UI_'+$data._id(), 'data-bs-target':'#UI_'+$data._id()}" aria-expanded="false"> 1589 <!-- ko ifnot: doCheckEmptyData($data._pictureName()) -->
1590 <span class="categoryMerge" data-bind="style:{'background-position-x': $data._picturePosition()+'px', 'alt': $data._code()}"> 1591 </span> 1592 <!-- /ko --> 1593 <span class="categoryColor menuSpan " data-bind="text: $data._name, attr:{'data-code': $data._code}, click: doLoadMenu.bind($root, $data, 'Shop'), style:{'--data-categoryColor': $data._colorMobileHex()}"></span> 1594 1595 </button> 1596 <!-- ko run: $data.mode='block' --><!-- /ko --> 1597 <!-- ko template: { name: 'Template_ItemMobileMenu' , data:$data} --><!-- /ko --> 1598 </div> 1599 </div> 1600 </div> 1601 <!-- /ko --> 1602 1603 <div class="sidebar-nav tab-pane fade active show" id="UI_headers" role="tabpanel"> 1604 <div class="widget widget-categories accordion" data-bind="css:{'hide': m_listCategoryMenuHeader().length==0}, foreach: m_listCategoryMenuHeader"> 1605 <div class="accordion-item accordion-header"> 1606 <button class="categoryBgColor accordion-button collapsed d-flex align-items-center px-1 py-3" style="padding-top: .75rem; padding-bottom: .75rem;" type="button" data-bs-toggle="collapse" data-bind="css:{'hideAfter': $data._list().length==0}, attr:{'aria-controls': 'UI_'+$data._id(), 'data-bs-target':'#UI_'+$data._id()}, style:{'--data-categoryBgColor': $data._colorBackgroundHex()}" aria-expanded="false"> 1607 <!-- ko ifnot: doCheckEmptyData($data._pictureName()) --> 1608 <span class="categoryMerge" data-bind="style:{'background-position-x': $data._picturePosition()+'px', 'alt': $data._code()}"> 1609 </span> 1610 <!-- /ko --> 1611 <span onclick="" class="categoryColor font-size-18 menuSpan" data-bind="text: $data._name, attr:{'data-code': $data._code}, click: doLoadMenu.bind($root, $data, 'Shop'), style:{'--data-categoryColor': $data._colorMobileHex()}"></span> 1612 </button> 1613 1614 <!--ko if : $data._list().length!=0 --> 1615 <!-- ko run: $data.mode='block' --><!-- /ko --> 1616 <!-- ko template: { name: 'Template_ItemMobileMenu' , data:$data} --><!-- /ko --> 1617 <!-- /ko --> 1618 1619 </div> 1620 </div> 1621 </div> 1622 1623 </div> 1624 </div> 1625</aside> 1626<!-- /ko --> 1627 1628 1629 </div> 1630 </div> 1631 </div> 1632 1633 </div> 1634</header> 1635 1636 1637 <!-- END HEADER --> 1638 <div style="min-height: 60vh;"> 1639 <div id="UI_AjaxLoader" class="page-wrapper" style="display: none;"> 1640 <div id="UI_LayoutBody" class="main_content"> 1641 1642 1643 1644 1645<link rel="stylesheet" media="print" onload="this.media='all'" href="https://cdn.brandfull.com/cssPage.min.css?v=639260136226636726"> 1646 1647 1648<style> 1649 1650 .grid-checkbox:last-child:nth-child(odd) { 1651 grid-column: 1 / -1 !important; 1652 } 1653 1654 [lang="en"] .coupon-card { 1655 border-left: 4px solid rgba(var(--cz-primary-rgb)); 1656 margin-bottom: 15px; 1657 border-radius: 0.75rem; 1658 } 1659 1660 [lang="ar"] .coupon-card { 1661 border-right: 4px solid rgba(var(--cz-primary-rgb)); 1662 margin-bottom: 15px; 1663 border-radius: 0.75rem; 1664 } 1665 1666 .coupon-code { 1667 background-color: #f8f9fa; 1668 border: 1px dashed #dee2e6; 1669 padding: 5px; 1670 border-radius: 0.5rem; 1671 font-family: monospace; 1672 font-weight: bold; 1673 } 1674 1675 .gridyBox{ 1676 display: grid; 1677 grid-template-columns: 1fr 1fr; 1678 gap: 5px; 1679 } 1680 1681 .gridyBox .fullWidth { 1682 grid-column: 1 / -1 !important; 1683 } 1684 1685 .pulseAnimation { 1686 display: inline-block; 1687 animation: pulseAnimation 1.5s ease-in-out infinite; 1688 font-size: 24px; 1689 font-weight: bold; 1690 } 1691 1692 @keyframes pulseAnimation { 1693 0%, 100% { 1694 transform: scale(1); 1695 } 1696 10% { 1697 transform: scale(1.1); 1698 } 1699 20% { 1700 transform: scale(1); 1701 } 1702 30% { 1703 transform: scale(1.1); 1704 } 1705 40% { 1706 transform: scale(1); 1707 } 1708 } 1709 1710 1711 footer, .footer { display: none !important; } 1712 1713 .checkout-accordion .accordion-button { 1714 background-color: #f8f9fa; 1715 border-bottom: 2px solid rgba(var(--cz-primary-rgb), 0.15); 1716 font-weight: 600; 1717 padding: 0.85rem 1rem; 1718 border-radius: 0.5rem 0.5rem 0 0; 1719 } 1720 1721 .checkout-accordion .accordion-button:not(.collapsed) { 1722 background-color: rgba(var(--cz-primary-rgb), 0.06); 1723 color: rgba(var(--cz-primary-rgb)); 1724 box-shadow: none; 1725 } 1726 1727 .checkout-accordion .accordion-button:not(.collapsed) i { 1728 color: rgba(var(--cz-primary-rgb)); 1729 } 1730 1731 .checkout-card { 1732 background: #fff; 1733 transition: box-shadow 0.2s ease; 1734 } 1735 1736 .checkout-card-header { 1737 background: #fafbfc;
1738 border-bottom: 1px solid #f0f0f0; 1739 user-select: none; 1740 } 1741 1742 .checkout-card-header[aria-expanded="false"] .ci-chevron-down, 1743 .checkout-card-header.collapsed .ci-chevron-down { 1744 transform: rotate(-90deg); 1745 } 1746 1747 .checkout-card-header .ci-chevron-down { 1748 transition: transform 0.25s ease; 1749 } 1750 1751 .checkout-layout, 1752 .checkout-layout-sub { 1753 display: flex; 1754 flex-wrap: wrap; 1755 gap: 1.5rem; 1756 padding-bottom: 3rem; 1757 align-items: flex-start; 1758 } 1759 .checkout-layout > *, 1760 .checkout-layout-sub > * { 1761 flex: 1 1 0%; 1762 min-width: min(100%, 320px); 1763 } 1764 /* The crossed-out price is a note, not an alarm: muted ink, the sale price beside it 1765 carries the emphasis. Token first so an app can restate it; the fallback is the 1766 shared muted grey, not the red this used to be. */ 1767 .checkout-item-price del.discount.text-accent { 1768 font-size: .75rem !important; 1769 font-weight: 600 !important; 1770 color: var(--brand-price-old-color, var(--brand-muted, #6b7078)) !important; 1771 } 1772 @media (max-width: 575.98px) { 1773 .checkout-item-price { 1774 display: flex; 1775 flex-direction: row; 1776 align-items: baseline; 1777 font-size: .75rem !important; 1778 } 1779 .checkout-item-price del.discount.text-accent { 1780 margin: 0px 5px !important; 1781 font-size: .6rem !important; 1782 } 1783 } 1784 1785</style>
1786<script> 1787if (window.innerWidth >= 684) { 1788 window.addEventListener('load', function () { 1789 var sidebar = document.getElementById('UI_orderSidebar'); 1790 if (!sidebar) return; 1791 var layout = sidebar.closest('.checkout-layout'); 1792 var topGap = 16; 1793 1794 window.addEventListener('scroll', function () { 1795 var layoutRect = layout.getBoundingClientRect(); 1796 var sidebarHeight = sidebar.offsetHeight; 1797 var sidebarTop = sidebar.getBoundingClientRect().top; 1798 var maxShift = layout.offsetHeight - sidebarHeight; 1799 var shift = -layoutRect.top + topGap; 1800 1801 if (shift < 0) shift = 0; 1802 if (shift > maxShift) shift = maxShift; 1803 1804 sidebar.style.transform = 'translateY(' + shift + 'px)'; 1805 }); 1806 }); 1807} 1808</script>
1808 1809 1810 1811 1812<style> 1813 #UI_GetMapLocation, #UI_GetMapLocation .modal-body, #UI_GetMapLocation #UI_divMap { 1814 overscroll-behavior: contain; 1815 } 1816</style> 1817 1818<div class="modal fade" id="UI_GetMapLocation" tabindex="-1" role="dialog"> 1819 <div class="modal-dialog modal-dialog-centered modal-lg"> 1820 <div class="modal-content border-0 rounded-4 overflow-hidden"> 1821 <div class="modal-header border-0 px-4 py-3"> 1822 <div class="d-flex align-items-center gap-2"> 1823 <i class="ci-location fs-lg" style="color: rgba(var(--cz-primary-rgb));"></i> 1824 <h5 class="modal-title fw-semibold mb-0">Ù ÙØ§Ù!</h5> 1825 </div> 1826 <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button> 1827 </div> 1828 <div class="modal-body p-0 position-relative"> 1829 <div id="UI_divMap" style="height:450px;"></div> 1830 <input type="hidden" id="UI_Lat" name="Lat" value="24.7056348"> 1831 <input type="hidden" id="UI_Long" name="Long" value="46.696471"> 1832 <div class="position-absolute pointer" onclick="window.doGetCurrentPosition()" style="bottom: 20px; right: 20px; z-index: 10; width: 48px; height: 48px; border-radius: 50%; background: #fff; box-shadow: 0 2px 8px rgba(0,0,0,0.2); display: flex; align-items: center; justify-content: center;"> 1833 <i class="ci-target fs-lg text-dark"></i> 1834 </div> 1835 </div> 1836 <div class="modal-footer border-0 px-4 py-3 justify-content-center"> 1837 <button id="UI_getAddress" class="btn btn-primary px-5 rounded-pill" data-bs-dismiss="modal" aria-label="Close"> 1838 <i class="ci-check me-2-Auto"></i>Ø§ØØµÙ عÙÙ Ø§ÙØ¹ÙÙØ§Ù 1839 </button> 1840 </div> 1841 </div> 1842 </div> 1843</div> 1844
1845<script> 1846 // Pages that own a single address form (checkout, profile) are matched by name; any other page 1847 // registers itself through window.m_mapLocationTarget before opening the popup. 1848 function doConfirmMapAddress() { 1849 var lat = document.getElementById('UI_Lat').value; 1850 var lng = document.getElementById('UI_Long').value; 1851 var handler = window.m_mapLocationTarget 1852 || (typeof m_handlerPageCheckout !== 'undefined' ? m_handlerPageCheckout : m_handlerPageProfile); 1853 handler.doGetAddress(lat, lng); 1854 } 1855 window.doConfirmMapAddress = doConfirmMapAddress; 1856 document.getElementById('UI_getAddress').addEventListener('click', doConfirmMapAddress); 1857 1858 // Bootstrap's scroll lock only sets overflow on <body>, but this layout scrolls the document 1859 // element - so wheeling to zoom the map moved the page underneath. Lock both while the map is 1860 // up and restore whatever was there before (never assume the previous value was ""). 1861 (function () { 1862 var ui = document.getElementById('UI_GetMapLocation'); 1863 if (!ui) 1864 return; 1865 1866 var previous = null; 1867 1868 ui.addEventListener('shown.bs.modal', function () { 1869 if (previous) 1870 return; 1871 1872 previous = { 1873 html: document.documentElement.style.overflow, 1874 body: document.body.style.overflow 1875 }; 1876 document.documentElement.style.overflow = 'hidden'; 1877 document.body.style.overflow = 'hidden'; 1878 }); 1879 1880 ui.addEventListener('hidden.bs.modal', function () { 1881 if (!previous) 1882 return; 1883 1884 document.documentElement.style.overflow = previous.html; 1885 document.body.style.overflow = previous.body; 1886 previous = null; 1887 }); 1888 })(); 1889</script>
1889 1890
1891<script type="application/javascript"> 1892 var m_handlerPageCheckout; 1893 1894 // The one page that still asks for scriptPage.min.js up front. Everywhere else it now waits for 1895 // the visitor (see the arming block in _LayoutScript), which costs at worst one ignored tap on a 1896 // dropdown -- but checkout drives bootstrap.Collapse from validation results 1897 // (Handler_PageCheckout.doAutoCollapseSection and the error handler above it), and those calls 1898 // sit inside a `catch {}` that would swallow a missing library and simply leave the accordion 1899 // shut. A page reached only by someone already mid-purchase is the wrong place to trade 1900 // correctness for the load time of one file. 1901 doLoadPageScript(); 1902 1903 doLoadScript(function () { 1904 var dataJson = {"requestCode":4003,"requestData":{"_page":{"_pageType":5,"_styleCss":"","_pageStatus":1,"_showMenu":false,"_listDivModel":[{"_loopCount":0,"_order":0,"_classCss":"","_divObjectFilterType":16,"_divSurveyFilterType":0,"_divFilterParameters":"","_divTemplateModel":{"_code":"AreaSlick","_divTemplateItemType":1,"_itemCount":10,"_pictureModel":{"_name":"b36b2eb9-ab2a-4506-9ea4-855886920e1b.png","_pictureType":0,"_order":0,"_dimension":"1144x396","_id":"dc99a84d-75a0-46a6-bc82-295ebad6390d","_dateCreate":"2023-01-26T11:55:31.0000000","_dateUpdate":"2024-11-14T12:57:15.9775906"},"_isDynamicCount":true,"_isAdvance":true,"_id":"2804b7e9-b773-4e65-98ea-22365e7e2475","_dateCreate":"2023-01-26T11:55:31.0000000","_dateUpdate":"2026-08-16T15:04:01.5367590"},"_autoHideArea":false,"_enableTimer":false,"_id":"fd1fa49a-cc28-4d49-a3ab-5cf32ac6d2e7","_hasLoadListObject":false}],"_id":"b67d9e85-e291-49b4-a25e-7125c2176df5","_dateCreate":"2023-09-05T22:49:02.0000000","_dateUpdate":"2023-09-05T22:49:02.0000000","_link":""}}}; 1905 m_handlerLayout.doSetCurrentPage(dataJson.requestData._page); 1906 1907 m_handlerPageCheckout = new Handler_PageCheckout(); 1908 doSetHandlerPageScroller(m_handlerPageCheckout); 1909 m_handlerPageCheckout.doInitData(); 1910 1911 ko.applyBindings(m_handlerPageCheckout, document.getElementById('UI_checkoutPage')); 1912 1913 // Wrapped, not passed by reference: doInitMap is itself a scriptPage.min.js symbol, so 1914 // naming it in the argument list would evaluate it before doLoadGoogleMaps can fetch it. 1915 doLoadGoogleMaps(function () { doInitMap(); }); 1916 1917 doLoadScript(function () { 1918 }, "https://cdn.checkout.com/js/framesv2.min.js"); 1919 1920 doLoadScript(function () { 1921 }, "https://applepay.cdn-apple.com/jsapi/1.latest/apple-pay-sdk.js"); // ---> ios18 and later "https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js" "https://applepay.cdn-apple.com/jsapi/1.latest/apple-pay-sdk.js" 1922 1923 doJsPasswordVisibilityToggle();
1924 const checkoutInputs = ["UI_checkoutCode1", "UI_checkoutCode2", "UI_checkoutCode3", "UI_checkoutCode4"]; 1925 doInitCodeInput(checkoutInputs, m_handlerPageCheckout.m_code, m_handlerPageCheckout, m_handlerPageCheckout.doEventSendCode); 1926 1927 // Timer and DOM glue for the OTP popup lives here, not in the handler: the 60 s countdown to 1928 // the resend button, clearing the four boxes whenever a fresh code token arrives (Place Order 1929 // or Resend), and stopping the clock when the popup closes. 1930 window.UICheckoutOtp = (function () { 1931 var timer = null; 1932 var modal = document.getElementById('UI_popUpSMSCode'); 1933 function stop() { 1934 if (timer) { 1935 clearInterval(timer); 1936 timer = null; 1937 } 1938 } 1939 function start() { 1940 stop(); 1941 m_handlerPageCheckout.m_canResend(false); 1942 m_handlerPageCheckout.m_resendSecond(60); 1943 timer = setInterval(function () { 1944 var left = m_handlerPageCheckout.m_resendSecond() - 1; 1945 m_handlerPageCheckout.m_resendSecond(left); 1946 if (left <= 0) { 1947 stop(); 1948 m_handlerPageCheckout.m_canResend(true); 1949 } 1950 }, 1000); 1951 } 1952 function reset() { 1953 doResetCodeInput(checkoutInputs); 1954 m_handlerPageCheckout.m_code(""); 1955 } 1956 if (modal) { 1957 modal.addEventListener('shown.bs.modal', function () { reset(); start(); }); 1958 modal.addEventListener('hidden.bs.modal', stop); 1959 } 1960 // a new token while the popup is up means a new code went out: the old digits are dead 1961 m_handlerPageCheckout.m_tokenValidation.subscribe(function (value) { 1962 if (doCheckEmptyData(value) || !modal || !modal.classList.contains('show')) 1963 return; 1964 reset(); 1965 start(); 1966 }); 1967 return { start: start, stop: stop }; 1968 })(); 1969 }, "https://cdn.brandfull.com/Handlers/Pages/Handler_PageCheckout.js"); 1970 1971</script>
vendor: 2 bytes, line 1971
1971
1972<script type="application/javascript"> 1973 1974 const successCallback = (position) => { 1975 document.getElementById("UI_Lat").value = position.coords.latitude; 1976 document.getElementById("UI_Long").value = position.coords.longitude; 1977 doInitMap(); 1978 }; 1979 const errorCallback = (error) => { 1980 console.log(error); 1981 }; 1982 1983 1984 //Coupon rule sentences, keyed by CouponConditionTypeEnum; Handler_PageCheckout.doHtmlCondition adds the names / amount / date. 1985 window.m_couponConditionLabel = { 1986 0: 'ØºÙØ± ØµØ§ÙØ عÙÙ', 1987 1: 'ÙÙØ· عÙÙ', 1988 2: 'ØºÙØ± ØµØ§ÙØ عÙÙ', 1989 3: 'ÙÙØ· عÙÙ', 1990 4: 'Ø§ÙØØ¯ Ø§ÙØ£Ø¯ÙÙ ÙÙØªØ±ØªÙب', 1991 5: 'Ø§ÙØªØ±ØªÙب Ø§ÙØ£ÙصÙ', 1992 6: 'ÙÙØªÙÙ ÙÙ', 1993 7: 'Ø§ÙØ¯Ùع ب', 1994 8: 'ÙÙØ³ ٠ع Ø§ÙØ¯Ùع', 1995 9: 'Ø§ÙØªØ³ÙÙÙ Ø¨ÙØ§Ø³Ø·Ø©', 1996 10: 'ÙÙØ³ ٠ع Ø§ÙØ´ØÙ عبر Ø§ÙØ¥ÙØªØ±ÙØª', 1997 11: 'ÙÙØ· ÙÙ', 1998 12: 'ÙÙØ· ÙÙ', 1999 13: 'Ø¨Ø·Ø§ÙØ§Øª بÙÙÙØ© ٠ختارة ÙÙØ·', 2000 14: 'Ø§Ø³ØªØ®Ø¯Ø§Ù ÙØ§ØØ¯ ÙÙ٠ع٠ÙÙ', 2001 15: 'اØÙظ ØØªÙ', 2002 16: 'ÙØ§ ÙÙ ÙÙ Ø¯Ù Ø¬ÙØ§ ٠ع ÙÙØ¨ÙÙØ§Øª أخرÙ', 2003 17: 'ÙÙØ· عÙÙ', 2004 18: 'ØºÙØ± ØµØ§ÙØ عÙÙ', 2005 19: 'ØºÙØ± ØµØ§ÙØ عÙÙ', 2006 20: 'ÙØ¬Ø¨ Ø´ØÙ Ø¬Ù ÙØ¹ Ø§ÙØ¹Ùاصر ٠عا', 2007 21: 'ÙÙØ· ÙÙØØ³Ø§Ø¨ Ø§ÙØ°Ù ت٠إصدار٠ÙÙ', 2008 22: 'ÙÙØ³ ÙÙØØ³Ø§Ø¨ Ø§ÙØ°Ù ÙÙ ÙÙÙ' 2009 }; 2010 2011 window.doShowPopUpCoupon = function () { 2012 var el = document.getElementById("UI_popUpCouponCode"); 2013 if (el && !ko.dataFor(el)) { 2014 ko.applyBindings(m_handlerPageCheckout, el); 2015 } 2016 doShowModal("UI_popUpCouponCode"); 2017 } 2018 //Manual form and saved list swap places. doShowAddressForm is what the row's edit button, the add button 2019 //and the empty state use; doToggleAddressView stays for anything that wants the flip. 2020 window.doShowAddressForm = function (show) { 2021 var list = document.getElementById('UI_addressListItems'); 2022 var form = document.getElementById('UI_addressEditForm'); 2023 var open = (show === undefined) ? true : !!show; 2024 if (form) form.style.display = open ? 'block' : 'none'; 2025 if (list) list.style.display = open ? 'none' : 'block'; 2026 //the header swaps its tools on this, so keep it in step when the DOM path is used directly 2027 if (typeof m_handlerPageCheckout !== 'undefined' && m_handlerPageCheckout.m_showAddressForm) 2028 m_handlerPageCheckout.m_showAddressForm(open); 2029 } 2030 2031 window.doToggleAddressView = function () { 2032 var form = document.getElementById('UI_addressEditForm'); 2033 window.doShowAddressForm(!(form && form.style.display !== 'none')); 2034 } 2035 2036 2037 window.doRenderAmwal = function (id) { 2038 doLoadScript(function () { 2039 }, "https://cdn.jsdelivr.net/npm/amwal-checkout-button@latest/dist/checkout/checkout.esm.js", true); 2040 } 2041 2042 window.doRenderTamara = function (id) { 2043 doLoadScript(function () { 2044 window.TamaraInstallmentPlan.init({ 2045 lang: doGetCulture(), 2046 price: m_handlerPageCheckout.m_currentInvoice._total(), 2047 currency: m_handlerSession.doGetCompanyCurrencyEn(), // or SAR, BHD, KWD 2048 numberOfInstallments: 4 2049 }); 2050 window.TamaraInstallmentPlan.render() 2051 }, "https://cdn.tamara.co/widget/installment-plan.min.js"); 2052 } 2053 window.doRenderTabby = function (id) { 2054 doLoadScript(function () { 2055 new TabbyCard({ 2056 selector: "#" + id, // empty div for TabbyCard 2057 currency: m_handlerSession.doGetCompanyCurrencyEn(), // or SAR, BHD, KWD 2058 lang: doGetCulture(), // or ar 2059 price: m_handlerPageCheckout.m_currentInvoice._total(), 2060 size: 'narrow', // or wide, depending on the width 2061 theme: 'default', // or can be black
2062 header: false // if there is a Payment method name already 2063 }); 2064 }, "https://checkout.tabby.ai/tabby-card.js"); 2065 } 2066 2067</script>
2067 2068 2069 2070<div id="UI_checkoutPage"> 2071<!-- Page title + breadcrumb--> 2072<div class="bg-BreadCrumb pt-4 py-2"> 2073 <div class="container breadcrumbContainer"> 2074 <div class="breadcrumbLink mb-3 "> 2075 <nav aria-label="breadcrumb"> 2076 <ol class="breadcrumb flex-lg-nowrap justify-content-start"> 2077 <li class="breadcrumb-item"><a class="text-nowrap" href="/" enable-href="false"><i class="ci-home"></i>Ø§ÙØµÙØØ© Ø§ÙØ±Ø¦ÙØ³ÙØ©</a></li> 2078 <li class="breadcrumb-item text-nowrap active"> 2079 Ø§ÙØ¯Ùع 2080 </li> 2081 </ol> 2082 </nav> 2083 </div> 2084 <div class="breadcrumbTitle pe-lg-4-Auto"> 2085 <h4 class="h4 text-black mb-0">ع٠ÙÙØ© Ø§ÙØ¯Ùع</h4> 2086 </div> 2087 </div> 2088</div> 2089<!-- Content--> 2090<section class="container"> 2091 <div class="pt-2"> 2092 <div class="checkout-layout"> 2093 2094 <!-- ======== FORM AREA ======== --> 2095 <div id="UI_userSidebar" data-bind="css:{'checkout-layout-sub': $root.m_enableQuickProcess}"> 2096 2097 <!-- ko ifnot: $root.m_enableQuickProcess --> 2098 <!-- ko if: !doCheckUUID(m_currentInvoice._userModel._id()) --> 2099 <div class="card border shadow-sm rounded-3 mb-2"> 2100 <div class="card-body p-3"> 2101 <h6 class="d-flex align-items-center gap-2 mb-2"> 2102 <i class="ci-user text-muted"></i> 2103 ٠عÙÙ٠ات اÙÙÙØªØ±Ø© 2104 </h6> 2105 <span class="align-content-center"> 2106 ع٠ÙÙ Ø¹Ø§Ø¦Ø¯Ø 2107 <a href="javascript: void(0)" listener="false" onclick="doOpenProfile()"> 2108 اضغط ÙÙØ§ ÙØªØ³Ø¬ÙÙ Ø§ÙØ¯Ø®ÙÙ 2109 </a> 2110 </span> 2111 </div> 2112 </div> 2113 <!-- /ko --> 2114 <!--/ko--> 2115 2116 2117 <!-- ko if: $root.m_enableQuickProcess --> 2118 <!-- ko run: ko.applyBindings(m_handlerSession, document.getElementById("UI_quickAccount")); --><!--/ko--> 2119 <!-- ko stopBinding: true --> 2120 <div id="UI_quickAccount" class="card border shadow-sm rounded-3 mb-2"> 2121 <div class="card-body p-3"> 2122 <h6 class="d-flex align-items-center gap-2 mb-3"> 2123 <i class="ci-user text-muted"></i> 2124 Ø®Ø·ÙØ§Øª Ø³Ø±ÙØ¹Ø© 2125 </h6> 2126 <p class="fs-sm text-body-secondary mb-3"> 2127 Ø£Ø¶Ù Ø¨Ø±ÙØ¯Ù Ø§ÙØ¥ÙÙØªØ±ÙÙÙ Ø£Ù ÙØ§ØªÙÙ Ø£Ø¯ÙØ§Ù Ø ÙØ³ÙØªÙ Ø¥Ø±Ø³Ø§Ù Ø±Ø³Ø§ÙØ© ÙÙØªØÙÙ. 2128 </p> 2129 <form class="needs-validation" autocomplete="off" novalidate> 2130 <div class="mb-3"> 2131 <div class="d-flex justify-content-between gap-2"> 2132 <div class="flex-grow-1"> 2133 <input autocomplete="tel" id="UI_quickAccountPhoneInput" data-bind="value : m_currentStructUser._phone,valueUpdate: ['afterkeydown', 'input'], css:{'is-invalid': !doCheckEmptyData(m_errorStructUser._phone())}" class="form-control" type="tel" lang=ar dir=rtl placeholder="رÙ٠اÙÙØ§ØªÙ" required> 2134 <!-- ko if: !doCheckEmptyData(m_errorStructUser._phone()) --> 2135 <div data-bind="text: m_errorStructUser._phone" class="invalid-feedback"></div> 2136 <!-- /ko --> 2137 </div> 2138 <div style="width: 100px;"> 2139 <select class="form-select" id="UI_quickAccountCountry" data-bind="css:{'is-invalid':!doCheckEmptyData(m_errorUser.m_errorCountryModel())}, options: m_listCountry, value: m_currentUser._countryModel._id,optionsText: '_code', optionsValue: '_id'"> 2140 </select> 2141 </div> 2142 </div> 2143 <div class="d-flex text-center my-1 align-items-center"> 2144 <hr class="w-25 mx-auto">
2145 <span class="fs-sm fw-semibold">Ø£Ù</span> 2146 <hr class="w-25 mx-auto"> 2147 </div> 2148 <input autocomplete="email" data-bind="value : m_currentStructUser._email, css:{'is-invalid': !doCheckEmptyData(m_errorStructUser._email())}" class="form-control" type="email" placeholder="[email protected]" required> 2149 <!-- ko if: !doCheckEmptyData(m_errorStructUser._email()) --> 2150 <div id="UI_errorEmailModal" data-bind="text: m_errorStructUser._email" class="invalid-feedback"></div> 2151 <!-- /ko --> 2152 </div> 2153 <div class="mb-3" data-bind="class:'ar' == 'en'? 'form-check':'form-check-reverse'"> 2154 <input class="form-check-input" type="checkbox" id="UI_agreeCheckoutPage" value="" data-bind="attr:{checked: m_isAgree()}, value: m_isAgree(),click: $root.doSetAgree.bind($root)"> 2155 <label class="form-check-label" for="UI_agreeCheckoutPage"> 2156 <span>Ø£ÙØ§Ù٠عÙÙ Ø§ÙØ´Ø±ÙØ· ÙØ§ÙØ³ÙØ§Ø³Ø©</span> 2157 </label> 2158 <a href="/About/TermsandCondition" target="_blank" enable-href="true" class="readMore">Ø§ÙØ±Ø£</a> 2159 </div> 2160 <button data-bind="click : $root.doForgetPassword.bind($root, true), attr:{'disabled': !m_isAgree()}" class="btn btn-primary w-100" type="button">Ø§Ø±Ø³Ù Ø§ÙØ±Ù ز</button> 2161 </form> 2162 <div class="pt-3 mt-3 border-top text-center"> 2163 <span class="fs-sm"> 2164 <i class="ci-user me-1-Auto"></i> 2165 ع٠ÙÙ Ø¹Ø§Ø¦Ø¯Ø 2166 <a class="btn-link text-decoration-underline" href="javascript: void(0)" listener="false" onclick="doOpenProfile()"> 2167 اضغط ÙÙØ§ ÙØªØ³Ø¬ÙÙ Ø§ÙØ¯Ø®ÙÙ 2168 </a> 2169 </span> 2170 </div> 2171 </div> 2172 </div> 2173 <!--/ko--> 2174 <!--/ko--> 2175 2176 <div> 2177 <!-- ko if : doGetCouponNudges().length --> 2178 <div class="coupon-nudges mb-3"> 2179 <!-- ko foreach: doGetCouponNudges() --> 2180 <div class="coupon-nudge"> 2181 <div class="coupon-nudge-hero"> 2182 <span class="coupon-nudge-value" data-bind="html: $root.doHtmlNudgeValue($data)"></span> 2183 <small data-bind="text: $data._code"></small> 2184 </div> 2185 <div class="coupon-nudge-body"> 2186 <!-- ko ifnot: doCheckEmptyData($data._description()) --> 2187 <div class="coupon-nudge-title" data-bind="html: $data._description"></div> 2188 <!-- /ko --> 2189 <!-- ko if: doCheckEmptyData($data._description()) --> 2190 <div class="coupon-nudge-title" data-bind="html: 2191 $data._couponType() == CouponTypeEnum.Shipment ? 'ØªÙØµÙ٠٠جاÙÙ ÙÙØ°Ø§ Ø§ÙØ·Ùب' : 2192 $data._couponDiscountType() == CouponDiscountTypeEnum.DiscountTypeByPercent ? 'ØÙظ ' + $data._discount() + '% عÙ٠عربت٠ÙÙÙØ§' : 2193 $data._couponDiscountType() == CouponDiscountTypeEnum.DiscountTypeByLowPrice ? 'ØÙظ ' + $data._discount() + '% عÙ٠أرخص Ù ÙØªØ¬' : 2194 $data._couponDiscountType() == CouponDiscountTypeEnum.DiscountTypeByFixedAmount || $data._couponDiscountType() == CouponDiscountTypeEnum.DiscountTypeByAmount ? 'ØÙظ ' + m_handlerLayout.doCalcPriceDynamic($data._discount(), true, 0) + ' Ø¨ÙØ°Ø§ Ø§ÙØ£Ù ر' : 2195 'اشتر Ø£ÙØ«Ø±Ø ÙØ§Ø¯Ùع Ø£ÙÙ: خص٠عÙÙ ÙÙ Ø¹ÙØµØ± إضاÙÙ' 2196 "></div> 2197 <!-- /ko --> 2198 <!-- ko template: { name: 'Template_CheckoutCouponCondition', data: $data } --><!-- /ko --> 2199 <!-- ko if: $data._amountToReach() > 0 --> 2200 <div class="coupon-nudge-gap">
2200Ø£ÙØª ÙØ°ÙÙ <b data-bind="text: Math.ceil($data._amountToReach())"></b> <b data-bind="text: doGetCurrentCurrency()"></b> Ø¨Ø¹ÙØ¯Ø§. أض٠اÙÙ Ø²ÙØ¯ Ø¥ÙÙ Ø³ÙØ© Ø§ÙØªØ³ÙÙ Ø§ÙØ®Ø§ØµØ© Ø¨Ù ÙØ³Ùت٠تطبÙÙ ÙØ°Ø§ Ø§ÙØ®ØµÙ تÙÙØ§Ø¦Ùا Ø¹ÙØ¯ Ø§ÙØ¯Ùع.</div> 2201 <div class="coupon-nudge-bar"><i data-bind="style: { width: $root.doGetNudgeProgress($data) + '%' }"></i></div> 2202 <!-- /ko --> 2203 <!-- ko if: $data._amountToReach() <= 0 && $data._listCategoryModel().length --> 2204 <div class="coupon-nudge-gap">ÙØ°Ø§ Ø§ÙØ¹Ø±Ø¶ ÙØØªØ§Ø¬ Ø¥ÙÙ Ù ÙØªØ¬ Ù Ù Ø¥ØØ¯Ù ÙØ°Ù اÙÙØ¦Ø§Øª. Ø£Ø¶Ù Ù ÙØªØ¬Ø§ Ø¥ÙÙ Ø³ÙØ© Ø§ÙØªØ³ÙÙ ÙØ³Ùت٠تطبÙÙ٠تÙÙØ§Ø¦Ùا.</div> 2205 <div class="coupon-nudge-cats"> 2206 <!-- ko template: { name: 'Template_CheckoutCouponCategoryChip', foreach: $data._listCategoryModel } --><!-- /ko --> 2207 </div> 2208 <!-- /ko --> 2209 </div> 2210 <!-- ko if: !doCheckEmptyData($data._earnLink()) --> 2211 <a class="coupon-nudge-cta is-solid" data-bind="attr: { href: $data._earnLink() }">Ø§ÙØ³Ø¨Ùا</a> 2212 <!-- /ko --> 2213 <!-- ko if: doCheckEmptyData($data._earnLink()) && $data._amountToReach() > 0 --> 2214 <a class="coupon-nudge-cta" href="/Shop">اÙ٠تجر</a> 2215 <!-- /ko --> 2216 </div> 2217 <!-- /ko --> 2218 <!-- ko if: m_listCouponSuggest().length > doGetCouponNudges().length --> 2219 <div class="coupon-nudge-more"> 2220 <a href="javascript:void(0)" listener="false" onclick="doShowPopUpCoupon()">Ø¬Ù ÙØ¹ اÙÙØ³Ø§Ø¦Ù (<span data-bind="text: m_listCouponSuggest().length + m_listCouponCompany().length"></span>)</a> 2221 </div> 2222 <!-- /ko --> 2223 </div> 2224 <!-- /ko --> 2225 <!-- ======== CART DETAILS ======== --> 2226 <div class="card border shadow-sm rounded-3 mb-2"> 2227 <div class="card-body p-3"> 2228 <h6 class="d-flex align-items-center gap-2 mb-3"> 2229 <i class="ci-cart text-muted"></i> 2230 ØªÙØ§ØµÙÙ Ø³ÙØ© Ø§ÙØªØ³ÙÙ 2231 </h6> 2232 2233 <div class="d-flex flex-column gap-3 mb-3" data-bind="foreach: { data: doGetCartGroups(), as: 'group' }"> 2234 <div class="checkout-seller-group" data-bind="css: { 'has-header': group._showHeader, 'is-store': group._isStore }"> 2235 <!-- ko if: group._showHeader --> 2236 <div class="checkout-seller-head"> 2237 <!-- ko if: group._isStore --> 2238 <i class="ci-home"></i> 2239 <span>Ù ØªØ¬Ø±ÙØ§</span> 2240 <!-- /ko --> 2241 <!-- ko if: !group._isStore --> 2242 <i class="ci-store"></i> 2243 <span class="checkout-seller-label">Ø¨ÙØ¹Øª Ø¨ÙØ§Ø³Ø·Ø©</span> 2244 <b class="elide" data-bind="text: group._sellerName"></b> 2245 <!-- /ko --> 2246 <span class="checkout-seller-count" data-bind="text: group._items.length"></span> 2247 </div> 2248 <!-- /ko --> 2249 <div class="d-flex flex-column gap-2" data-bind="foreach: group._items"> 2250 <!-- ko if: $data._invoiceDetailType() != InvoiceDetailTypeEnum.FromBundle --> 2251 <div class="pb-2 checkout-item-row"> 2252 <div class="d-flex gap-3"> 2253 <a href="#" class="position-relative flex-shrink-0 rounded-3 overflow-hidden" style="width: 64px; height: 64px;" data-bind="attr:{href: doGetLinkObject($data._objectModel)}"> 2254 <img loading="lazy" class="w-100 h-100" style="object-fit: cover;" data-bind="attr:{ src: doGetDefaultPictureByObject($data._objectModel, true), alt: $data._objectModel._name}"> 2255 <!-- ko if: $data._quantity() > 1 -->
2256 <span class="position-absolute top-0 start-0 badge bg-dark bg-opacity-75 rounded-pill" style="padding: 1px 5px; font-size: 10px; margin: 2px;" data-bind="text: 'x' + $data._quantity()"></span> 2257 <!-- /ko --> 2258 </a> 2259 <div class="flex-grow-1" style="min-width: 0;"> 2260 <div class="d-flex justify-content-between align-items-start"> 2261 <span class="fs-xs text-body-secondary" data-bind="text: $data._objectModel._code"></span> 2262 <span class="fw-semibold fs-sm flex-shrink-0 ms-2-Auto checkout-item-price" data-bind="html: $root.doHtmlPriceByCurrency($data)"></span> 2263 </div> 2264 <span class="fs-sm fw-semibold d-block" style="word-break: break-word;" data-bind="text: $data._objectModel._name"></span> 2265 <!-- ko foreach: doArrayByString($data._description()) --> 2266 <span class="me-1-Auto font-size-10 ms-2-Auto" data-bind="text: $data"></span> 2267 <!-- /ko --> 2268 <!-- ko if: $data._objectModel._objectStockModel._objectStockStatus() == ObjectStockStatusEnum.Preserved --> 2269 <div class="d-inline-flex align-items-center gap-2 mt-2 fs-xs fw-medium text-white" style="background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); border-radius: 999px; padding: 4px 12px 4px 4px; box-shadow: 0 1px 3px rgba(217,119,6,0.25);"> 2270 <span class="d-inline-flex align-items-center justify-content-center rounded-circle flex-shrink-0" style="width: 20px; height: 20px; background: rgba(255,255,255,0.22);"> 2271 <i class="ci-truck flipAuto" style="font-size: 12px;" data-bind="css:{'icon-flip-horizontal': doGetCulture() =='en'}"></i> 2272 </span> 2273 <!-- ko if: doGetCountryShortNameByCurrentCompany() == 'sa' --> 2274 <span data-bind="text: doFormatPreserved($data._objectModel._objectStockModel._datePreserved(), 15, doGetCulture())"></span> 2275 <!-- /ko --> 2276 <!-- ko if: doGetCountryShortNameByCurrentCompany() == 'ae' --> 2277 <span data-bind="text: doFormatPreserved($data._objectModel._objectStockModel._datePreserved(), 7, doGetCulture())"></span> 2278 <!-- /ko --> 2279 </div> 2280 <!-- /ko --> 2281 </div> 2282 </div> 2283 <!-- ko if: $data._invoiceDetailType() == InvoiceDetailTypeEnum.Bundle --> 2284 <div class="d-flex flex-wrap gap-1 mt-2" style="padding-inline-start: 4px;" data-bind="foreach: $root.doGetBundleItems($data)"> 2285 <a href="#" class="rounded-2 overflow-hidden border" style="width: 36px; height: 36px;" data-bind="attr:{href: doGetLinkObject($data._objectModel), title: $data._objectModel._name()}"> 2286 <img loading="lazy" class="w-100 h-100" style="object-fit: cover;" data-bind="attr:{ src: doGetDefaultPictureByObject($data._objectModel, true), alt: $data._objectModel._name}"> 2287 </a> 2288 </div> 2289 <!-- /ko --> 2290 <!-- ko if: $data._objectModel._objectSection() == ObjectSectionEnum.GiftCard --> 2291 <div class="pt-3 mt-2 checkout-gift-block" style="padding-inline-start: 16px;"> 2292 <div class="d-flex align-items-center gap-2 mb-2"> 2293 <input class="form-check-input m-0" type="checkbox" data-bind="checked: $data._invoiceDetailDataModel._isShared"> 2294 <label class="form-check-label fs-sm pointer" data-bind="click: function(){ $data._invoiceDetailDataModel._isShared(!$data._invoiceDetailDataModel._isShared()); return true; }">ت٠ÙÙÙ ÙØ°Ø§ Ø§ÙØ®Ùار ÙÙ Ø´Ø§Ø±ÙØ© Ø§ÙØ±Ù ز Ø§ÙØ®Ø§Øµ بÙ</label> 2295 </div> 2296 <!-- ko if: $data._invoiceDetailDataModel._isShared() --> 2297 <div class="row g-2"> 2298 <div class="col-12"> 2299 <input autocomplete="name" placeholder="اس٠اÙ٠ستÙÙ *" class="form-control form-control-sm" type="text" data-bind="value: $data._invoiceDetailDataModel._fullName, css:{'is-invalid':!doCheckEmptyData($data.m_errorGiftCard.m_errorFullName())}"> 2300 <div data-bind="text: $data.m_errorGiftCard.m_errorFullName" class="invalid-feedback"></div> 2301 </div> 2302 <div class="col-sm-6"> 2303 <input autocomplete="tel" class="form-control form-control-sm letterSpacing-1" type="text" placeholder="اÙÙØ§ØªÙ*" data-bind="attr:{id: 'UI_phoneReceiver_'+$data._objectModel._id()}, value: $data._invoiceDetailDataModel._phone, valueUpdate: ['afterkeydown', 'input'], css:{'is-invalid':!doCheckEmptyData($data.m_errorGiftCard.m_errorPhone())}"> 2304 <div data-bind="text: $data.m_errorGiftCard.m_errorPhone" class="invalid-feedback"></div> 2305 </div> 2306 <div class="col-sm-6"> 2307 <input autocomplete="email" class="form-control form-control-sm" type="text" placeholder="Ø§ÙØ¨Ø±Ùد Ø§ÙØ¥ÙÙØªØ±ÙÙÙ" data-bind="value: $data._invoiceDetailDataModel._email, css:{'is-invalid':!doCheckEmptyData($data.m_errorGiftCard.m_errorEmail())}"> 2308 <div data-bind="text: $data.m_errorGiftCard.m_errorEmail" class="invalid-feedback"></div> 2309 </div> 2310 <div class="col-12"> 2311 <textarea class="form-control form-control-sm" placeholder="Ø±Ø³Ø§ÙØ©*" data-bind="value: $data._invoiceDetailDataModel._message, css:{'is-invalid':!doCheckEmptyData($data.m_errorGiftCard.m_errorMessage())}" maxlength="75"></textarea> 2312 <div data-bind="text: $data.m_errorGiftCard.m_errorMessage" class="invalid-feedback"></div> 2313 </div> 2314 </div> 2315 <!-- /ko --> 2316 </div> 2317 <!-- /ko --> 2318 </div> 2319 <!-- /ko --> 2320 </div> 2321 </div> 2322 </div> 2323 </div> 2324 </div> 2325 2326 <!-- ======== COUPONS & DISCOUNTS ======== --> 2327 <div class="card border shadow-sm rounded-3 mb-2"> 2328 <div class="card-body p-3"> 2329 <!-- Coupon input --> 2330 <div id="UI_coupon"> 2331 <div class="input-group flex-nowrap"> 2332 <i class="ci-coupon position-absolute top-50 translate-middle-y text-muted fs-base ms-3-Auto zindex-10"></i> 2333 <input autocomplete="off" class="form-control rounded-start-Auto" type="email" data-bind="value: m_inputCoupon, style:{'border-color': doCheckCoupnApply(m_inputCoupon())? 'green':'' }, css:{'is-invalid':!doCheckEmptyData(m_errorInvoice.m_errorListAppliedCouponModel())}" placeholder="اÙÙØ³Ø§Ø¦Ù ÙØ§ÙخصÙ٠ات"> 2334 <button class="btn btn-dark" type="button" data-bind="click : doApplyCouponByInput()"> 2335 طب٠2336 </button> 2337 </div> 2338 <!-- ko if: !doCheckEmptyData(m_errorInvoice.m_errorListAppliedCouponModel()) && m_listCouponRejectC
2338ondition().length == 0 --> 2339 <ul class="coupon-rules coupon-error mt-1"> 2340 <li class="coupon-rule"><i class="ci-close-circle is-except"></i><span data-bind="text: m_errorInvoice.m_errorListAppliedCouponModel"></span></li> 2341 </ul> 2342 <!-- /ko --> 2343 <!-- ko foreach: m_listCouponRejectCondition --> 2344 <ul class="coupon-rules coupon-error mt-1"> 2345 <!-- ko if: $parent.m_listCouponRejectCondition().length > 1 --> 2346 <li class="coupon-rule"><b data-bind="text: $data._code"></b></li> 2347 <!-- /ko --> 2348 <!-- ko foreach: $data._listCondition --> 2349 <li class="coupon-rule"> 2350 <i data-bind="attr: { class: m_handlerPageCheckout.doGetConditionIcon($data) }"></i> 2351 <span data-bind="html: m_handlerPageCheckout.doHtmlCondition($data)"></span> 2352 </li> 2353 <!-- /ko --> 2354 </ul> 2355 <!-- /ko --> 2356 </div> 2357 <!-- ko if: m_listCouponCompany().length != 0 || m_listCouponSuggest().length != 0 --> 2358 <button class="btn btn-danger btn-sm w-100 mt-2" type="button" onclick="doShowPopUpCoupon()">Ø¬Ù ÙØ¹ اÙÙØ³Ø§Ø¦Ù </button> 2359 <!-- /ko --> 2360 <!-- Applied coupons --> 2361 <!-- ko if: m_currentInvoice._listAppliedCouponModel().length != 0 --> 2362 <div class="mt-2"> 2363 <div class="d-flex flex-wrap gap-1"> 2364 <!-- ko foreach: m_currentInvoice._listAppliedCouponModel() --> 2365 <span class="badge bg-success bg-opacity-10 text-success d-inline-flex align-items-center py-1 px-2 rounded-pill pointer font-size-10" data-bind="click: $root.doRemoveCouponUsed.bind($root, $data)"> 2366 <span data-bind="text: $data._couponModel._code()"></span> 2367 <i class="ci-close font-size-8 ms-1-Auto"></i> 2368 </span> 2369 <!-- /ko --> 2370 </div> 2371 </div> 2372 <!-- /ko --> 2373 <!-- User's own coupons --> 2374 <!-- ko if: m_listCouponUser().length != 0 --> 2375 <div class="mt-3 pt-3 border-top"> 2376 <div class="d-flex align-items-center gap-1 mb-2"> 2377 <i class="ci-lable text-primary"></i> 2378 <span class="fw-semibold fs-xs">ÙÙ ÙÙÙ Ø§Ø®ØªÙØ§Ø± ÙØ³Ù٠تÙ!</span> 2379 </div> 2380 <div class="coupon-card-list" data-bind="foreach: m_listCouponUser"> 2381 <div class="coupon-card" data-bind="click: $root.doApplyCoupon.bind($root, $data), 2382 css: { 'is-selected': $root.doCheckCouponUsed($data) }"> 2383 <span class="coupon-card-hero"> 2384 <!-- ko if: $data._couponDiscountType() == CouponDiscountTypeEnum.DiscountTypeByPercent --> 2385 <span class="coupon-card-value" data-bind="text: $data._discount() + '%'"></span> 2386 <!-- /ko --> 2387 <!-- ko if: $data._couponDiscountType() == CouponDiscountTypeEnum.DiscountTypeByAmount -->
2388 <span class="coupon-card-value" data-bind="html: m_handlerLayout.doCalcPriceDynamic($data._discount(), true)"></span> 2389 <!-- /ko --> 2390 </span> 2391 <span class="coupon-card-info"> 2392 <span class="coupon-card-info-top"> 2393 <span class="coupon-card-code" data-bind="text: $data._code"></span> 2394 <span class="coupon-card-hero-label" title="خص٠"> 2395 <i data-bind="attr: { class: $root.doCheckCouponUsed($data) ? 'ci-check-circle' : 'ci-tag' }"></i> 2396 </span> 2397 </span> 2398 <span class="coupon-card-meta"> 2399 <!-- ko if: $data._isIncludeVat() --> 2400 <span class="coupon-card-vat is-incl">ب٠ا Ù٠ذÙÙ Ø¶Ø±ÙØ¨Ø© اÙÙÙÙ Ø© اÙÙ Ø¶Ø§ÙØ©</span> 2401 <!-- /ko --> 2402 <!-- ko ifnot: $data._isIncludeVat() --> 2403 <span class="coupon-card-vat is-excl">Ø§Ø³ØªØ«ÙØ§Ø¡. Ø¶Ø±ÙØ¨Ø© اÙÙÙÙ Ø© اÙÙ Ø¶Ø§ÙØ©</span> 2404 <!-- /ko --> 2405 <span class="coupon-card-meta-dot"></span> 2406 <span class="coupon-card-expiry"> 2407 <i class="ci-time"></i> 2408 <span data-bind="text: doCalcDateDifference(doCastFromUTC($data._dateEnd()))"></span> 2409 </span> 2410 </span> 2411 <!-- ko template: { name: 'Template_CheckoutCouponCondition', data: $data } --><!-- /ko --> 2412 </span> 2413 </div> 2414 </div> 2415 </div> 2416 <!-- /ko --> 2417 <!-- Loyalty balance --> 2418 <!-- ko if: m_userPointBalance() > 0 --> 2419 <div class="mt-3 pt-3 border-top"> 2420 <div class="d-flex align-items-center mb-2"> 2421 <i class="ci-announcement text-warning me-1-Auto"></i> 2422 <span class="fw-semibold fs-xs">ÙÙ ÙÙÙ Ø§ÙØ§Ø³ØªÙادة Ù Ù ÙØ¸Ø§Ù اÙÙÙØ§Ø¡.</span> 2423 </div> 2424 <a class="btn btn-sm btn-dark w-100" data-bind="click: $root.doSendExchange.bind($root)"> 2425 Ø§Ø³ØªØ®Ø¯Ø§Ù Ø±ØµÙØ¯Ù <span class="fw-semibold" data-bind="text: m_userPointBalance()"></span> ÙÙÙÙÙ 2426 <i class="ci-chevron-right fs-lg ms-1 me-n1"></i> 2427 </a> 2428 <div data-bind="text: m_errorExchange, css:{'d-block':!doCheckEmptyData(m_errorExchange())}" class="invalid-feedback"></div> 2429 </div> 2430 <!-- /ko --> 2431 </div> 2432 </div> 2433 2434 <!-- ======== ORDER SUMMARY ======== --> 2435 <div class="card border shadow-sm rounded-3 mb-2"> 2436 <div class="card-body p-3"> 2437 2438 <!-- Saved money --> 2439 <!-- ko if : m_savedMoney() > 0 --> 2440 <div class="d-flex align-items-center justify-content-center gap-2 p-3 mb-3 rounded-3 checkout-saved"> 2441 <img alt="" loading="lazy" src="https://cdn.brandfull.com/Themes/Cartzilla/_Image/gift.png" width="20" />
2442 <span class="fs-sm">٠برÙÙ! ÙÙØ¯ Ù٠ت Ø¨Ø§ÙØÙØ¸ <span class="fw-semibold text-success" data-bind="html: m_handlerLayout.doCalcPriceDynamic(m_savedMoney(), true)"></span></span> 2443 </div> 2444 <!-- /ko --> 2445 <!-- Price summary --> 2446 <div class="d-flex flex-column gap-2 fs-sm"> 2447 <div class="d-flex justify-content-between"> 2448 <span class="text-body-secondary">اÙÙ Ø¬Ù ÙØ¹ اÙÙØ±Ø¹Ù</span> 2449 <span data-bind="html: m_handlerLayout.doCalcPriceDynamic(m_currentInvoice._subTotal(), true)"></span> 2450 </div> 2451 <div class="d-flex justify-content-between"> 2452 <span class="text-body-secondary">Ø´ØÙ</span> 2453 <span data-bind="html: m_handlerLayout.doCalcPriceDynamic(m_currentInvoice._deliveryCharge(), true)"></span> 2454 </div> 2455 <!-- ko if: m_currentInvoice._extraCharge()!=0 --> 2456 <div class="d-flex justify-content-between"> 2457 <span class="text-body-secondary">رسÙ٠إضاÙÙØ©</span> 2458 <span data-bind="html: m_handlerLayout.doCalcPriceDynamic(m_currentInvoice._extraCharge(), true)"></span> 2459 </div> 2460 <!-- /ko --> 2461 <div class="d-flex justify-content-between"> 2462 <span class="text-body-secondary">Ø§ÙØ¥Ø¬Ù اÙÙ ÙØ¨Ù Ø¶Ø±ÙØ¨Ø© اÙÙÙÙ Ø© اÙÙ Ø¶Ø§ÙØ©</span> 2463 <span data-bind="html: m_handlerLayout.doCalcPriceDynamic(m_currentInvoice._subTotal() + m_currentInvoice._deliveryCharge() + m_currentInvoice._extraCharge(), true)"></span> 2464 </div> 2465 <div class="d-flex justify-content-between"> 2466 <span class="text-body-secondary">Ø¶Ø±ÙØ¨Ù اÙÙÙ٠٠اÙ٠ضاÙÙ</span> 2467 <span data-bind="html: m_handlerLayout.doCalcPriceDynamic(m_currentInvoice._vatTotal(), true)"></span> 2468 </div> 2469 <div class="d-flex justify-content-between fw-semibold"> 2470 <span>Ù Ø¬Ù ÙØ¹</span> 2471 <span data-bind="html: m_handlerLayout.doCalcPriceDynamic(m_currentInvoice._subTotal() + m_currentInvoice._deliveryCharge() + m_currentInvoice._extraCharge() + m_currentInvoice._vatTotal(), true)"></span> 2472 </div> 2473 <!-- ko if: m_currentInvoice._discountSubTotal()!=0 --> 2474 <div class="d-flex justify-content-between align-items-center px-2 py-1 rounded-2 checkout-discount-row"> 2475 <span class="fw-semibold text-success d-inline-flex align-items-center gap-1"> 2476 <i class="ci-percent fs-xs me-1-Auto"></i>خص٠إضاÙÙ 2477 <span class="badge bg-secondary bg-opacity-10 text-body-secondary fw-normal rounded-pill px-2" style="font-size: 10px;">Ø§Ø³ØªØ«ÙØ§Ø¡. Ø¶Ø±ÙØ¨Ø© اÙÙÙÙ Ø© اÙÙ Ø¶Ø§ÙØ©</span> 2478 </span> 2479 <span class="fw-bold text-success" data-bind="html: '- ' + m_handlerLayout.doCalcPriceDynamic(m_currentInvoice._discountSubTotal(), true)"></span> 2480 </div> 2481 <!-- /ko --> 2482 <!-- ko if: m_currentInvoice._discountDeliveryCharge()!=0 --> 2483 <div class="d-flex justify-content-between align-items-center px-2 py-1 rounded-2 checkout-discount-row">
2484 <span class="fw-semibold text-success"><i class="ci-delivery fs-xs me-1-Auto flipAuto"></i>Ø´ØÙØ© Ù Ø®ÙØ¶Ø©</span> 2485 <span class="fw-bold text-success" data-bind="html: '- ' + m_handlerLayout.doCalcPriceDynamic(m_currentInvoice._discountDeliveryCharge(), true)"></span> 2486 </div> 2487 <!-- /ko --> 2488 <hr class="my-1"> 2489 <div class="d-flex justify-content-between fw-bold fs-base"> 2490 <span>Ø§ÙØªÙتا٠اÙÙØ¨Ùر</span> 2491 <span data-bind="html: m_handlerLayout.doCalcPriceDynamic(m_currentInvoice._total(), true)"></span> 2492 </div> 2493 <!-- ko if: m_currentInvoice._listAppliedCouponModel().length != 0 --> 2494 <div class="mt-2 pt-2 border-top"> 2495 <div class="fw-semibold text-body-secondary mb-1 fs-xs">اÙÙØ³Ø§Ø¦Ù Ø§ÙØªØ·Ø¨ÙÙÙØ©</div> 2496 <div class="d-flex flex-column gap-1"> 2497 <!-- ko foreach: m_currentInvoice._listAppliedCouponModel() --> 2498 <div class="d-flex justify-content-between align-items-center fs-xs"> 2499 <span class="d-inline-flex align-items-center"> 2500 <i class="ci-coupon text-success me-1-Auto"></i> 2501 <span class="fw-semibold" data-bind="text: $data._couponModel._code()"></span> 2502 </span> 2503 <span class="text-success fw-semibold" data-bind="html: '- ' + m_handlerLayout.doCalcPriceDynamic($data._amount(), true)"></span> 2504 </div> 2505 <!-- /ko --> 2506 </div> 2507 </div> 2508 <!-- /ko --> 2509 </div> 2510 </div> 2511 </div> 2512 </div> 2513 </div> 2514 2515 <!-- END FORM AREA --> 2516 <!-- ko ifnot: $root.m_enableQuickProcess --> 2517 <!-- ======== SIDEBAR ======== --> 2518 <div id="UI_orderSidebar"> 2519 2520 <!-- ko if: doCheckUUID($root.m_currentInvoice._userModel._id()) --> 2521 <!-- ======== SHIPPING ADDRESS ======== --> 2522 <div class="card border shadow-sm rounded-3 mb-2 position-relative" id="UI_accordionAddress" 2523 data-bind="style:{'border-color': !doCheckEmptyData(m_errorAddress.m_errorFullName()) || !doCheckEmptyData(m_errorAddress.m_errorPhone()) || !doCheckEmptyData(m_errorAddress.m_errorPhoneValid()) || !doCheckEmptyData(m_errorAddress.m_errorEmail()) || !doCheckEmptyData(m_errorAddress.m_errorStreet()) || !doCheckEmptyData(m_errorAddress.m_errorCountryModel()) || !doCheckEmptyData(m_errorAddress.m_errorCityModel()) || !doCheckEmptyData(m_errorAddress.m_errorState()) || !doCheckEmptyData(m_errorAddress.m_errorZipCode()) || !doCheckEmptyData(m_errorAddress.m_errorNationalAddress()) || !doCheckEmptyData(m_errorAddress.m_errorReceiverPhone()) || !doCheckEmptyData(m_errorAddress.m_errorReceiverFullName()) ? 'var(--cz-danger, #f34770)' : ''}"> 2524 <div class="card-body p-3"> 2525 <div class="addr-card-head" data-bind="css:{'mb-3': ($root.m_editAddress ? $root.m_editAddress() : true) || doCheckEmptyData(m_selectedAddress())}"> 2526 <h6 class="addr-card-title mb-0"> 2527 <i class="ci-location text-muted"></i> 2528 عÙÙØ§Ù Ø§ÙØ´ØÙ 2529 </h6>
2530 <span class="addr-tools"> 2531 <!-- editing or adding: the corner carries the two saves instead of the close --> 2532 <!-- ko if: m_showAddressForm() --> 2533 <!-- a successful save closes the form; cancel drops the typing and closes it too --> 2534 <button class="addr-tool is-close" type="button" title="Ø¥ÙØºØ§Ø¡" aria-label="Ø¥ÙØºØ§Ø¡" 2535 data-bind="click: $root.doCancelAddressForm.bind($root), enable: !m_savingAddress()"> 2536 <i class="ci-close"></i> 2537 </button> 2538 <button class="addr-tool is-save has-label" type="button" title="ØÙظ" aria-label="ØÙظ" 2539 data-bind="click: $root.doSaveAddress.bind($root, false), enable: doCheckAddressComplete() && !m_savingAddress()"> 2540 <!-- ko if: m_savingAddress() --> 2541 <span class="addr-save-spinner"></span> 2542 <!-- /ko --> 2543 <!-- ko if: !m_savingAddress() && m_savedAddress() --> 2544 <i class="ci-check-circle"></i> 2545 <!-- /ko --> 2546 <!-- ko if: !m_savingAddress() && !m_savedAddress() --> 2547 <i class="ci-check"></i> 2548 <!-- /ko --> 2549 <span class="addr-tool-text">ØÙظ</span> 2550 </button> 2551 <button class="addr-tool is-default has-label" type="button" title="اØÙظ ÙØ¹ÙÙØ§Ù Ø§ÙØªØ±Ø§Ø¶Ù" aria-label="اØÙظ ÙØ¹ÙÙØ§Ù Ø§ÙØªØ±Ø§Ø¶Ù" 2552 data-bind="click: $root.doSaveAddress.bind($root, true), enable: doCheckAddressComplete() && !m_savingAddress()"> 2553 <i class="ci-star"></i> 2554 <span class="addr-tool-text">Ø§ÙØ§ÙتراضÙ</span> 2555 </button> 2556 <!-- /ko --> 2557 2558 <!-- browsing the saved list --> 2559 <!-- ko if: !m_showAddressForm() --> 2560 <!-- the row buttons only ever edit an existing address, so adding one needs its own control --> 2561 <button class="addr-tool is-add" type="button" title="Ø¥Ø¶Ø§ÙØ© عÙÙØ§Ù Ø¬Ø¯ÙØ¯" aria-label="Ø¥Ø¶Ø§ÙØ© عÙÙØ§Ù Ø¬Ø¯ÙØ¯" data-bind="click: $root.doAddNewAddress.bind($root)"> 2562 <i class="ci-add-location"></i> 2563 </button> 2564 <!-- ko if: !doCheckEmptyData(m_selectedAddress()) --> 2565 <button type="button" class="addr-tool is-close" title="تعدÙÙ" aria-label="تعدÙÙ" data-bind="click: function(){ $root.m_editAddress(!$root.m_editAddress()); }"> 2566 <!-- ko if: !($root.m_editAddress ? $root.m_editAddress() : true) --> 2567 <i class="ci-edit"></i> 2568 <!-- /ko --> 2569 <!-- ko if: ($root.m_editAddress ? $root.m_editAddress() : true) --> 2570 <i class="ci-close"></i> 2571 <!-- /ko --> 2572 </button> 2573 <!-- /ko --> 2574 <!-- /ko --> 2575 </span> 2576 </div> 2577 <!-- ko if: !doCheckEmptyData(m_selectedAddress()) && !($root.m_editAddress ? $root.m_editAddress() : true) -->
2578 <span class="fw-normal text-truncate d-block" style="padding-inline-start: 26px; font-size: 0.7rem; color: rgba(var(--cz-primary-rgb), 0.7);" data-bind="text: m_currentInvoice._shipmentModel._addressModel._fullName() + ' · ' + m_currentInvoice._shipmentModel._addressModel._phone()"></span> 2579 <span class="fw-normal text-truncate d-block" style="padding-inline-start: 26px; font-size: 0.7rem; color: rgba(var(--cz-primary-rgb), 0.7);" data-bind="text: m_currentInvoice._shipmentModel._addressModel._cityModel._name() + ' · ' + m_currentInvoice._shipmentModel._addressModel._state() + ', ' + m_currentInvoice._shipmentModel._addressModel._street()"></span> 2580 <!-- /ko --> 2581 2582 <!-- ko if: ($root.m_editAddress ? $root.m_editAddress() : true) || doCheckEmptyData(m_selectedAddress()) --> 2583 <!-- ko if: m_listAddress().length > 0 --> 2584 2585 <!-- Address list --> 2586 <div id="UI_addressListItems"> 2587 <div class="addr-list mb-3" data-bind="foreach: m_listAddress"> 2588 <div class="addr-row" data-bind="click: $root.doSetAddress.bind($root, $data._id()), css:{'is-selected': $data._id() == $root.m_selectedAddress()}"> 2589 <!-- ko if: $data._id() == $root.m_selectedAddress() --> 2590 <i class="ci-check-circle addr-row-mark"></i> 2591 <!-- /ko --> 2592 <!-- ko if: $data._id() != $root.m_selectedAddress() --> 2593 <i class="ci-location addr-row-mark"></i> 2594 <!-- /ko --> 2595 <label class="addr-row-text" data-bind="attr:{'for': 'UI_address'+$data._id()}"> 2596 <span class="addr-row-city"> 2597 <span data-bind="html: $data._cityModel._name()"></span> 2598 <!-- ko if: $data._isDefault() --> 2599 <span class="addr-badge">Ø§ÙØ§ÙتراضÙ</span> 2600 <!-- /ko --> 2601 </span> 2602 <span class="addr-row-line" data-bind="html: $data._state() + ', ' + $data._street()"></span> 2603 <span class="addr-row-line" data-bind="text: $data._fullName() + ' · ' + $data._phone()"></span> 2604 </label> 2605 <input class="form-check-input m-0 flex-shrink-0 d-none" type="radio" data-bind="checkedValue: $data._id(), checked: $root.m_selectedAddress(), attr:{'id': 'UI_address'+$data._id(), value: $data._id, title: $data._street()}"> 2606 2607 <!-- opens this address in the edit form; the row body stays click-to-select --> 2608 <span class="addr-menu"> 2609 <button class="addr-menu-btn" type="button" title="تعدÙÙ Ø§ÙØ¹ÙÙØ§Ù" aria-label="تعدÙÙ Ø§ÙØ¹ÙÙØ§Ù" data-bind="click: $root.doEditAddressDetail.bind($root, $data)"> 2610 <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><circle cx="5" cy="12" r="1.8"></circle><circle cx="12" cy="12" r="1.8"></circle><circle cx="19" cy="12" r="1.8"></circle></svg> 2611 </button> 2612 </span> 2613 </div> 2614 </div> 2615 </div> 2616 2617 <!-- /ko --> 2618 2619 <!-- === EMPTY STATE (when no addresses) === --> 2620 <!-- the per-row menu is the only route to map / manual entry, so with no rows 2621 at all the empty state has to carry those two itself --> 2622 <!-- ko if: m_listAddress().length == 0 && doCheckEmptyData(m_currentInvoice._shipmentModel._addressModel._street()) --> 2623 <div class="text-center py-4"> 2624 <i class="ci-location d-block mb-2 checkout-empty-icon" style="font-size: 2rem;"></i> 2625 <p class="text-body-secondary fs-sm mb-3">ÙÙ ÙØªÙ Ø§ÙØ¹Ø«Ùر عÙ٠عÙÙØ§Ù Ù ØÙÙØ¸</p> 2626 <div class="d-flex gap-2 flex-wrap justify-content-center"> 2627 <button class="btn btn-outline-primary btn-sm d-flex align-items-center gap-1" type="button" data-bind="click: $root.doGetMapLocation.bind($root)"> 2628 <i class="ci-map"></i> Ø§Ø¨ØØ« عÙÙ Ø§ÙØ®Ø±Ùطة 2629 </button> 2630 <button class="btn btn-outline-secondary btn-sm d-flex align-items-center gap-1" type="button" onclick="window.doShowAddressForm()"> 2631 <i class="ci-edit"></i> Ø¥Ø¯Ø®Ø§Ù ÙØ¯ÙÙØ§ 2632 </button> 2633 </div> 2634 </div> 2635 <!-- /ko --> 2636 2637 <!-- === EDIT ADDRESS FORM === --> 2638 <div id="UI_addressEditForm" style="display:none;"> 2639 <div class="border-top pt-3 mt-1"> 2640 <form class="needs-validation" autocomplete="off" novalidate> 2641 <div class="row g-3"> 2642 <div class="col-12"> 2643 <div class="fs-sm fw-semibold text-body-secondary d-flex align-items-center gap-2"> 2644 <i class="ci-user"></i> 2645 ٠عÙÙ٠ات اÙÙÙØªØ±Ø© 2646 </div> 2647 </div> 2648 <div class="col-12"> 2649 <label class="form-label" for="UI_fullName">Ø§ÙØ§Ø³Ù اÙÙØ§Ù Ù<span class='text-danger'>*</span></label> 2650 <input autocomplete="name" class="form-control" type="text" id="UI_fullName" required placeholder="Ø§ÙØ§Ø³Ù اÙÙØ§Ù Ù" data-bind="value : m_currentInvoice._shipmentModel._addressModel._fullName, css:{'is-invalid':!doCheckEmptyData(m_errorAddress.m_errorFullName())}"> 2651 <div class="invalid-feedback" data-bind="text: m_errorAddress.m_errorFullName"></div> 2652 </div> 2653 <div class="col-sm-6"> 2654 <label class="form-label" for="UI_phoneCheckout">اÙÙØ§ØªÙ<span class='text-danger'>*</span></label> 2655 <div data-bind="class: (doCheckEmptyData(m_errorAddress.m_errorPhone()) && doCheckEmptyData(m_errorAddress.m_errorPhoneValid()) && m_currentInvoice._shipmentModel._addressModel._phoneValid())? 'flexAuto':''"> 2656 <input autocomplete="tel" class="form-control letterSpacing-1" type="tel" lang=ar dir=rtl id="UI_phoneCheckout" required placeholder="اÙÙØ§ØªÙ" data-bind="value : m_currentInvoice._shipmentModel._addressModel._phone, valueUpdate: ['afterkeydown', 'input'], css:{'is-invalid':!doCheckEmptyData(m_errorAddress.m_errorPhone()) || !doCheckEmptyData(m_errorAddress.m_errorPhoneValid())}"> 2657 <!-- ko if: doCheckEmptyData(m_errorAddress.m_errorPhone()) && doCheckEmptyData(m_errorAddress.m_errorPhoneValid()) && m_currentInvoice._shipmentModel._addressModel._phoneValid() --> 2658 <button aria-label="ØªÙ Ø§ÙØªØ£ÙÙØ¯" class="btn btn-sm text-success" type="button"><i class="ci-check-circle" style="font-size: 24px"></i></button> 2659 <!-- /ko --> 2660 <div class="invalid-feedback" data-bind="text: !doCheckEmptyData(m_errorAddress.m_errorPhone()) ? m_errorAddress.m_errorPhone() : m_errorAddress.m_errorPhoneValid()"></div> 2661 </div> 2662 </div> 2663 <div class="col-sm-6"> 2664 <label class="form-label" for="UI_email">Ø§ÙØ¨Ø±Ùد Ø§ÙØ¥ÙÙØªØ±ÙÙÙ<span class='text-danger'>*</span></label> 2665 <input autocomplete="email" class="form-control" type="text" id="UI_email" required placeholder="Ø§ÙØ¨Ø±Ùد Ø§ÙØ¥ÙÙØªØ±ÙÙÙ" data-bind="value : m_currentInvoice._shipmentModel._addressModel._email, css:{'is-invalid':!doCheckEmptyData(m_errorAddress.m_errorEmail())}"> 2666 <div class="invalid-feedback" data-bind="text: m_errorAddress.m_errorEmail"></div> 2667 </div> 2668 <div class="col-12"><hr class="my-1"></div> 2669 <div class="col-sm-6"> 2670 <label class="form-label" for="UI_addressCountry">Ø¨ÙØ¯<span class='text-danger'>*</span></label> 2671 <select class="form-select" id="UI_addressCountry" data-bind="valueAllowUnset: true, options: m_listCountry, value: m_currentInvoice._shipmentModel._addressModel._cityModel._countryModel._id , option: m_currentInvoice._shipmentModel._addressModel._cityModel._countryModel._id, optionsText: '_name', optionsValue: '_id', css:{'is-invalid':!doCheckEmptyData(m_errorAddress.m_errorCountryModel())}"> 2672 </select> 2673 <div class="invalid-feedback" data-bind="text : m_errorAddress.m_errorCountryModel"></div> 2674 </div> 2675 <div class="col-sm-6"> 2676 <label class="form-label" for="UI_addressCity">٠دÙÙØ©<span class='text-danger'>*</span></label> 2677 <select class="form-select" id="UI_addressCity" data-bind="valueAllowUnset: true, options: m_listCity, value: m_currentInvoice._shipmentModel._addressModel._cityModel._id , option: m_currentInvoice._shipmentModel._addressModel._cityModel._id,optionsText: '_name', optionsValue: '_id', optionsCaption: 'اختر اÙ٠دÙÙØ©...', css:{'is-invalid':!doCheckEmptyData(m_errorAddress.m_errorCityModel())}"> 2678 </select> 2679 <div class="invalid-feedback" data-bind="text : m_errorAddress.m_errorCityModel"></div> 2680 </div> 2681 <div class="col-sm-6"> 2682 <label class="form-label" for="UI_state">Ø§ÙØÙ<span class='text-danger'>*</span></label> 2683 <input autocomplete="off" class="form-control" type="text" id="UI_state" required placeholder="Ø§ÙØÙ" data-bind="value : m_currentInvoice._shipmentModel._addressModel._state, css:{'is-invalid':!doCheckEmptyData(m_errorAddress.m_errorState())}"> 2684 <div class="invalid-feedback" data-bind="text: m_errorAddress.m_errorState"></div> 2685 </div> 2686 <!-- ko if: !doCheckEmptyData(m_currentInvoice._shipmentModel._addressModel._cityModel._countryModel._regexNationalAddress()) --> 2687 <div class="col-sm-6"> 2688 <label class="form-label" for="UI_nationalAddress">Ø§ÙØ¹ÙÙØ§Ù اÙÙØ·ÙÙ</label> 2689 <input autocomplete="off" class="form-control" type="text" id="UI_nationalAddress" data-bind="value : m_currentInvoice._shipmentModel._addressModel._nationalAddress, css:{'is-invalid':!doCheckEmptyData(m_errorAddress.m_errorNationalAddress())}" placeholder="ABCD1234" required> 2690 <div id="UI_errorNationalAddress" data-bind="text: m_errorAddress.m_errorNationalAddress" class="invalid-feedback"></div> 2691 </div> 2692 <!--/ko--> 2693 <div class="col-12"> 2694 <label class="form-label" for="UI_street">شارع<span class='text-danger'>*</span></label> 2695 <div class="input-group"> 2696 <input autocomplete="off" class="form-control rounded-start-Auto" type="text" data-bind="value : m_currentInvoice._shipmentModel._addressModel._street, css:{'is-invalid':!doCheckEmptyData(m_errorAddress.m_errorStreet())}" placeholder="عÙÙØ§Ù Ø§ÙØ´Ø§Ø±Ø¹"> 2697 <button class="btn btn-dark btn-sm d-flex align-items-center gap-1 px-3" type="button" data-bind="click: $root.doGetMapLocation.bind($root)"> 2698 <i class="ci-location"></i> 2699 Ø§ÙØ®Ø±Ùطة 2700 </button> 2701 </div> 2702 <div data-bind="text: m_errorAddress.m_errorStreet, css:{'d-block':!doCheckEmptyData(m_errorAddress.m_errorStreet())}" class="invalid-feedback"></div> 2703 </div> 2704 2705 <!-- ko if: !doCheckUUID(m_currentInvoice._userModel._id()) --> 2706 <div class="col-12 pt-2 border-top"> 2707 <div class="d-flex align-items-center gap-2 mb-2"> 2708 <input class="form-check-input m-0" type="checkbox" id="UI_agree" data-bind="value: m_agree, checked: m_agree"> 2709 <label class="form-check-label" for="UI_agree">Ø¥ÙØ´Ø§Ø¡ ØØ³Ø§Ø¨Ø</label> 2710 </div> 2711 <input class="d-none" type="text" autocomplete="username" tabindex="-1" aria-hidden="true" data-bind="value: m_currentInvoice._shipmentModel
2711._addressModel._email"> 2712 <label class="form-label" for="UI_password">ÙÙÙ Ø© اÙÙ Ø±ÙØ± Ø§ÙØ®Ø§ØµØ© بÙ</label> 2713 <div class="password-toggle"> 2714 <input id="UI_password" class="form-control" type="password" required autocomplete="new-password" data-bind="value: m_currentInvoice._userModel._passwordHash"> 2715 <label class="password-toggle-btn" aria-label="Show/hide password"> 2716 <input class="password-toggle-check" type="checkbox"><span class="password-toggle-indicator"></span> 2717 </label> 2718 </div> 2719 </div> 2720 <!-- /ko --> 2721 2722 </div> 2723 2724 <!-- saving and the route back to the saved list both live in the card header --> 2725 </form> 2726 </div> 2727 </div> 2728 2729 <!-- /ko --> 2730 </div> 2731 </div> 2732 <!-- /ko --> 2733 2734 <!-- ======== SHIPMENT METHOD ======== --> 2735 <!-- ko if: doCheckUUID($root.m_currentInvoice._userModel._id()) --> 2736 <!-- shipping cost and payment restrictions are both derived from the address, so neither card 2737 means anything until the address is complete - same test the save tools use --> 2738 <div class="card border shadow-sm rounded-3 mb-2" 2739 data-bind="css:{'checkout-locked': !doCheckAddressComplete()}, style:{'border-color': !doCheckEmptyData(m_errorInvoice.m_errorShipmentModel()) ? 'var(--cz-danger, #f34770)' : ''}"> 2740 <div class="card-body p-3"> 2741 <h6 class="d-flex align-items-center gap-2 mb-3"> 2742 <i class="ci-truck text-muted"></i> 2743 طرÙÙØ© Ø§ÙØ´ØÙ 2744 <!-- ko if: doCheckUUID(m_currentInvoice._shipmentModel._shipmentMethodModel._id()) --> 2745 <span class="text-body-secondary fw-normal fs-xs">â <span data-bind="text: m_currentInvoice._shipmentModel._shipmentMethodModel._name()"></span></span> 2746 <!-- /ko --> 2747 </h6> 2748 <!-- ko if: !doCheckAddressComplete() --> 2749 <p class="checkout-locked-note">Ø£Ù٠٠عÙÙØ§Ù Ø§ÙØ´ØÙ Ø£ÙÙØ§</p> 2750 <!-- /ko --> 2751 2752 <div id="UI_shipmentMethods" class="table-responsive"> 2753 <!-- ko if: doCheckShipmentRestriction() --> 2754 <div class="form-check mb-0 bg-warning rounded bg-opacity-25" style="padding:15px !important"> 2755 <h6 class="mb-0">ØªÙØ¨ÙÙ...</h6> 2756 <p>ÙØ§ ØªÙØ¬Ø¯ طرÙÙØ© Ø´ØÙ ÙÙØ°Ø§ Ø§ÙØ¥Ø¹Ø¯Ø§Ø¯</p> 2757 </div> 2758 <!-- /ko --> 2759 <!-- ko if: !doCheckShipmentRestriction() --> 2760 <div> 2761 <div data-bind="foreach: m_listFilterShipmentMethod"> 2762 <div class="shipment-option" data-bind="css:{'is-selected': $data._id() == $root.m_currentInvoice._shipmentModel._shipmentMethodModel._id(), 'has-coupon': $data._hasShipmentCoupon()}"> 2763 <!-- ko if: $data._hasShipmentCoupon() -->
2764 <span class="shipment-option-ribbon">Ø´ØÙ ٠جاÙÙ</span> 2765 <!-- /ko --> 2766 <input class="form-check-input shipment-option-radio" type="radio" data-bind="checkedValue: $data._id(), checked: $root.m_currentInvoice._shipmentModel._shipmentMethodModel._id(), attr:{'id': 'UI_shipment'+$data._id(), value: $data._id, title: $data._name()}, click: $root.doSetShipmentMethod.bind($root, $data._id())"> 2767 <label class="shipment-option-body" data-bind="attr:{'for': 'UI_shipment'+$data._id()}"> 2768 <img loading="lazy" class="shipment-option-logo" data-bind="attr:{ src: 'https://cdn.brandfull.com/Content/shipmentMethod/'+ $data._pictureModel._name(), alt: $data._name() }"> 2769 <span class="shipment-option-info"> 2770 <!-- ko if: !doCheckEmptyData($data._description()) --> 2771 <span class="shipment-option-desc" data-bind="html: $data._description"></span> 2772 <!-- /ko --> 2773 <!-- ko if: !doCheckEmptyData($data._pickTime()) && !doCheckEmptyData($root.doCalcPickup($data._pickTime())) --> 2774 <span class="shipment-option-pickup"> 2775 <i class="ci-time"></i>Ø§ÙØ´Ø±Ø§Ø¡ Ø§ÙØªØ§ÙÙ ÙÙ <strong data-bind="html: $root.doCalcPickup($data._pickTime())"></strong> 2776 </span> 2777 <!-- /ko --> 2778 </span> 2779 </label> 2780 </div> 2781 </div> 2782 <span class="invalid-feedback alert alert-danger" data-bind="text: m_errorInvoice.m_errorShipmentModel, css:{'d-block':!doCheckEmptyData(m_errorInvoice.m_errorShipmentModel())}"></span> 2783 2784 <!--ko if: m_pickTimeWareHouse() != 0 --> 2785 <div class="font-size-10 text-success mt-1"> 2786 <strong><span data-bind="text: m_pickTimeWareHouse"></span> Ø£ÙØ§Ù Ø£Ù Ø£ÙØ§Ù </strong> 2787 ØªØ£Ø®ÙØ± إضاÙÙ! 2788 </div> 2789 <!-- /ko --> 2790 2791 <!-- ko if: doGetDeliveryCountOptions().length > 0 --> 2792 <div class="mt-3 pt-3 border-top"> 2793 <label class="form-label fw-semibold mb-2 d-flex align-items-center gap-2"> 2794 <i class="ci-package text-muted"></i>عدد Ø§ÙØªÙصÙÙØ§Øª 2795 </label> 2796 <div class="delivery-count-cards d-flex flex-wrap gap-2" data-bind="foreach: doGetDeliveryCountOptions()"> 2797 <button type="button" class="delivery-count-card" 2798 data-bind="css: { 'is-selected': $data == $root.m_currentInvoice._deliveryCount() }, click: $root.doSetDeliveryCount.bind($root, $data)"> 2799 <span class="delivery-count-card-top"> 2800 <i class="ci-truck delivery-count-card-icon flipAuto"></i> 2801 <span class="delivery-count-card-num" data-bind="text: $data"></span> 2802 </span> 2803 <!-- ko if: $data == 1 -->
2804 <span class="delivery-count-card-label">Ø§ÙØªØ³ÙÙÙ </span> 2805 <!-- /ko --> 2806 <!-- ko if: $data != 1 --> 2807 <span class="delivery-count-card-label">Ø§ÙØªÙصÙÙØ§Øª</span> 2808 <!-- /ko --> 2809 </button> 2810 </div> 2811 <small class="text-muted font-size-11 d-block mt-1">ÙØ³Ù Ø·ÙØ¨Ù Ø¥Ù٠ع٠ÙÙØ§Øª ØªÙØµÙÙ Ù ÙÙØµÙØ© â ÙÙØ¯ تÙÙ٠تÙÙÙØ© Ø£Ù٠أÙÙ ÙÙ Ø§ÙØªÙصÙÙØ§Øª.</small> 2812 </div> 2813 <!-- /ko --> 2814 </div> 2815 <!-- /ko --> 2816 </div> 2817 2818 </div> 2819 </div> 2820 2821 <!-- ======== MOBILE MINI SUMMARY (stacked layout only: the full order summary is a whole 2822 column above, so restate the grand total + applied coupons next to the payment choice) --> 2823 <!-- ko if: doCheckUUID($root.m_currentInvoice._userModel._id()) --> 2824 <div class="card border shadow-sm rounded-3 mb-2 d-md-none"> 2825 <div class="card-body p-3"> 2826 <div class="d-flex justify-content-between fw-bold fs-base"> 2827 <span>Ø§ÙØªÙتا٠اÙÙØ¨Ùر</span> 2828 <span data-bind="html: m_handlerLayout.doCalcPriceDynamic(m_currentInvoice._total(), true)"></span> 2829 </div> 2830 <!-- ko if: m_currentInvoice._listAppliedCouponModel().length != 0 --> 2831 <div class="mt-2 pt-2 border-top"> 2832 <div class="fw-semibold text-body-secondary mb-1 fs-xs">اÙÙØ³Ø§Ø¦Ù Ø§ÙØªØ·Ø¨ÙÙÙØ©</div> 2833 <div class="d-flex flex-column gap-1"> 2834 <!-- ko foreach: m_currentInvoice._listAppliedCouponModel() --> 2835 <div class="d-flex justify-content-between align-items-center fs-xs"> 2836 <span class="d-inline-flex align-items-center"> 2837 <i class="ci-coupon text-success me-1-Auto"></i> 2838 <span class="fw-semibold" data-bind="text: $data._couponModel._code()"></span> 2839 </span> 2840 <span class="text-success fw-semibold" data-bind="html: '- ' + m_handlerLayout.doCalcPriceDynamic($data._amount(), true)"></span> 2841 </div> 2842 <!-- /ko --> 2843 </div> 2844 </div> 2845 <!-- /ko --> 2846 </div> 2847 </div> 2848 <!-- /ko --> 2849 2850 <!-- ======== PAYMENT INFO ======== --> 2851 <!-- ko if: doCheckUUID($root.m_currentInvoice._userModel._id()) --> 2852 <div class="card border shadow-sm rounded-3 mb-2" data-bind="css:{'checkout-locked': !doCheckAddressComplete()}"> 2853 <div class="card-body p-3"> 2854 2855 <!-- ko if: m_currentInvoice._listInvoiceDetailModel().length != 0 --> 2856 <div id="UI_checkoutForm"> 2857 2858 <div id="UI_paymentMethods"> 2859 <!-- ko if: doCheckPaymentRestriction() --> 2860 <div class="form-check mb-0 bg-warning rounded bg-opacity-25" style="padding:15px !important"> 2861 <h6 class="mb-0">ØªÙØ¨ÙÙ...</h6> 2862 <p>ÙØ§ ØªÙØ¬Ø¯ طرÙÙØ© Ø¯ÙØ¹ ÙÙØ°Ø§ Ø§ÙØ¥Ø¹Ø¯Ø§Ø¯</p> 2863 </div> 2864 <!-- /ko --> 2865 <div id="UI_paymentPanels" 2866 data-bind="style:{'border-color': !doCheckEmptyData(m_errorInvoice.m_errorPaymentModel()) ? 'var(--cz-danger, #f34770)' : ''}"> 2867 <!-- ko if: !doCheckPaymentRestriction() --> 2868 <div> 2869 <h6 class="d-flex align-items-center gap-2 mb-3"> 2870 <i class="ci-card text-muted"></i> 2871 طرÙÙØ© Ø§ÙØ¯Ùع 2872 <!-- ko if: doCheckUUID(m_currentInvoice._paymentModel._paymentMethodModel._id()) -->
2873 <span class="text-body-secondary fw-normal fs-xs">â <span data-bind="text: m_currentInvoice._paymentModel._paymentMethodModel._name()"></span></span> 2874 <!-- /ko --> 2875 </h6> 2876 <div> 2877 <div class="fs-sm"> 2878 <div class="gridyBox" data-bind="foreach : m_listFilterPaymentMethod"> 2879 <div class="rounded grid-checkbox d-flex align-items-center p-0 checkout-pay-option" data-bind="class:'ar' == 'en'? 'form-check':'form-check-reverse'"> 2880 <div class=" ms-2-Auto" style="min-width: 16px;"> 2881 <input class="form-check-input m-0" type="radio" data-bind="checkedValue: $data._id(), checked: $root.m_currentInvoice._paymentModel._paymentMethodModel._id() , attr:{'id': 'UI_payment'+$data._id(), value: $data._id, title: $data._name() }, click: $root.doSetPaymentMethod.bind($root, $data._id())" /> 2882 </div> 2883 <label class="form-check-label ms-1-Auto" data-bind="attr:{'for': 'UI_payment'+$data._id()}"> 2884 <img loading="lazy" class="px-1 py-2 my-1" height="36" style=" height: 36px !important;object-fit: contain;" data-bind="attr:{ src: 'https://cdn.brandfull.com/Content/paymentMethod/'+ $data._pictureModel._name(), alt: $data._name() }"> 2885 <!-- ko if: doCheckEmptyData($data._pictureModel._name()) && !doCheckEmptyData($data._description()) --> 2886 <small class="font-size-10" data-bind="html: $data._description"></small> 2887 <!-- /ko --> 2888 </label> 2889 </div> 2890 </div> 2891 <span class="invalid-feedback alert alert-danger" data-bind="text: m_errorInvoice.m_errorPaymentModel,css:{'d-block':!doCheckEmptyData(m_errorInvoice.m_errorPaymentModel())}"></span> 2892 </div> 2893 </div> 2894 </div> 2895 <!-- /ko --> 2896 </div> 2897 2898 <!-- ko if: $root.m_currentInvoice._paymentModel._paymentMethodModel._paymentMethodType() == PaymentMethodTypeEnum.Tamara--> 2899 <hr class="checkout-pay-hr" /> 2900 <div class="paymentmethod textAlignAuto"> 2901 <div class="mb-2 mt-2"> 2902 <h4>إعداد ت٠ارا</h4> 2903 <!-- ko if: $root.m_listTamaraPaymentOption().length == 0 --> 2904 <small class="text-danger" style="width: 100%" data-bind="text: 'ÙØ§ ØªÙØ¬Ø¯ خد٠ة Ù ØªØ§ØØ© ÙØªÙ ارا.'"></small> 2905 <!-- /ko --> 2906 </div> 2907 <div class="payment_option d-flex flex-column mx-3" data-bind="foreach: m_listTamaraPaymentOption"> 2908 <div class="col-md-12" data-bind="class:'ar' == 'en'? 'form-check':'form-check-reverse'"> 2909 <input class="form-check-input" type="radio" data-bind="checkedValue: $data._id(), checked: $root.m_selectedTamara(), attr:{'id': $data._id}, click: $root.doSetTamaraSetting.bind($root, $data._id())"> 2910 <label class="form-check-label" data-bind="attr:{for: $data._id}, text: $data._name"> 2911 <small data-bind="text:$data._name"></small> 2912 </label> 2913 </div> 2914 </div> 2915 <!-- ko if: $root.m_listTamaraPaymentOption().length != 0 --> 2916 <br /> 2917 <div class="tamara-installment-plan-widget" style="padding: 10px !important; background-color: white" id="UI_tamara" data-bind="init: doRenderTamara('UI_tamara')"></div> 2918 <!-- /ko --> 2919 </div> 2920 <!-- /ko --> 2921 2922 <!-- ko if: $root.m_currentInvoice._paymentModel._paymentMethodModel._paymentMethodType() == PaymentMethodTypeEnum.Tabby--> 2923 <hr class="checkout-pay-hr" /> 2924 <div class="paymentmethod textAlignAuto"> 2925 <!-- ko if: $root.m_listTabbyPaymentOption().length == 0 --> 2926 <div class="checkout-pay-unavailable" role="alert"> 2927 <i class="ci-close-circle"></i> 2928 <div> 2929 <div class="checkout-pay-unavailable-title">ÙØ§ ØªÙØ¬Ø¯ خد٠ة Ù ØªØ§ØØ© ٠٠تابÙ.</div> 2930 <div class="checkout-pay-unavailable-hint">ÙØ±Ø¬Ù Ø§Ø®ØªÙØ§Ø± طرÙÙØ© Ø¯ÙØ¹ أخر٠ÙÙØ§Ø³ØªÙ رار.</div> 2931 </div> 2932 </div> 2933 <!-- /ko --> 2934 <!-- ko if: $root.m_listTabbyPaymentOption().length != 0 --> 2935 <h6 class="d-flex align-items-center gap-2 mb-3"> 2936 <i class="ci-time text-muted"></i> 2937 إعداد تاب٠2938 </h6> 2939 <div class="payment_option d-flex flex-column mx-3" data-bind="foreach: m_listTabbyPaymentOption"> 2940 <div class="col-md-12" data-bind="class:'ar' == 'en'? 'form-check':'form-check-reverse'"> 2941 <input class="form-check-input" type="radio" data-bind="checkedValue: $data._id(), checked: $root.m_selectedTabby(), attr:{'id': $data._id}, click: $root.doSetTabbySetting.bind($root, $data._id())"> 2942 <label class="form-check-label" data-bind="attr:{for: $data._id}, text: $data._name"><small data-bind="text:$data._name"></small></label> 2943 </div> 2944 </div> 2945 <br /> 2946 <div style="padding: 10px !important; background-color: white" id="UI_tabby" data-bind="init: doRenderTabby('UI_tabby')"></div> 2947 <!-- /ko --> 2948 </div> 2949 <!-- /ko --> 2950 2951 <!-- ko if: $root.m_currentInvoice._paymentModel._paymentMethodModel._paymentMethodType() == PaymentMethodTypeEnum.Amwal && m_listAmwalPaymentOption().length != 0--> 2952 <hr class="checkout-pay-hr" /> 2953 <div class="paymentmethod textAlignAuto"> 2954 <div class="mb-2 mt-2"> 2955 <h4>إعداد Ø£Ù ÙØ§Ù</h4> 2956 </div> 2957 <div class="payment_option d-flex flex-column mx-3" data-bind="foreach: m_listAmwalPaymentOption"> 2958 <div class="col-md-12" data-bind="class:'ar' == 'en'? 'form-check':'form-check-reverse'"> 2959 <input class="form-check-input" type="radio" data-bind="checkedValue: $data._id(), checked: $root.m_selectedAmwal(), attr:{'id': $data._id}, click: $root.doSetAmwalSetting.bind($root, $data._id())"> 2960 <label class="form-check-label" data-bind="attr:{for: $data._id}, text: $data._name"><small data-bind="text:$data._name"></small></label> 2961 </div> 2962 </div> 2963 <br /> 2964 <div style="padding: 10px !important; background-color: white" id="UI_amwal" data-bind="init: doRenderAmwal('UI_amwal')"> 2965 <amwal-installments-timeline amount="4200" 2966 installments-count="12" 2967 installment-data='[]' 2968 enable-installments="true" 2969 max-visible-installments="4" 2970 locale="ar" 2971 border="true" 2972 timeline-style="default" 2973 footer-message="" 2974 decimal-places="2" 2975 debug="false" data-bind="attr:{'locale': doGetCulture(), 'amount': m_currentInvoice._total(), 'installments-count': $root.m_selectedAmwal()}"> 2976 </amwal-installments-timeline> 2977 </div> 2978 </div> 2979 <!-- /ko --> 2980 </div> 2981 2982 <!-- ko if: m_currentInvoice._listInvoiceDetailModel().length !=0 && m_listPaymentMethod().length !=0 --> 2983 <div class="pt-2"> 2984 <button class="btn btn-primary d-block w-100" type="submit" data-bind="click: $root.doSave.bind($root)">ضع Ø§ÙØ·Ùب</button> 2985 </div> 2986 <!-- /ko --> 2987 <!-- ko if: m_currentInvoice._listInvoiceDetailModel().length ==0 --> 2988 <div class="textAlignAuto"> 2989 <div class="form-check mb-0 bg-warning rounded bg-opacity-25" style="padding:15px !important"> 2990 <h6 class="mb-0">ØªÙØ¨ÙÙ...</h6> 2991 <p class="mb-0">ÙØ§ ÙÙØ¬Ø¯ Ù ÙØªØ¬ ÙÙ Ø§ÙØ¨Ø§Ø³ÙÙØª Ø§ÙØ®Ø§Øµ بÙ</p> 2992 </div> 2993 </div> 2994 <!-- /ko --> 2995 <!-- ko if: m_listPaymentMethod().length ==0 --> 2996 <div class="textAlignAuto"> 2997 <div class="form-check mb-0 bg-warning rounded bg-opacity-25" style="padding:15px !important"> 2998 <h6 class="mb-0">ØªÙØ¨ÙÙ...</h6> 2999 <p>ÙØ§ ÙÙØ¬Ø¯ إعداد Ø¯ÙØ¹ ÙØªÙÙ Ø§ÙØ´Ø±ÙØ©</p> 3000 </div> 3001 </div> 3002 <!-- /ko --> 3003 </div> 3004 <!-- /ko --> 3005 </div> 3006 </div> 3007 <!-- /ko --> 3008 3009 </div> 3010 <!-- END SIDEBAR --> 3011 <!-- /ko --> 3012 </div> 3013 </div> 3014 3015 <!-- MODALS --> 3016 <div id="UI_successCouponDataModalPopUp" class="modal fade" tabindex="-1"> 3017 <div class="modal-dialog modal-dialog-centered" role="document"> 3018 <div class="modal-content"> 3019 <div class="modal-header ">
3020 <span class=" bg-success me-2-Auto rounded-circle text-center" style="height:24px; width:24px"> 3021 <i class="ci-tag text-white"></i> 3022 </span> 3023 <b class="text-success">خص٠!</b> 3024 <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button> 3025 </div> 3026 <div class="modal-body coupon-success-body"> 3027 <span class="coupon-success-icon"> 3028 <i class="ci-check-circle"></i> 3029 </span> 3030 <p class="coupon-success-message">ت٠تطبÙ٠اÙÙØ³ÙÙ Ø© Ø§ÙØ®Ø§ØµØ© بÙ.</p> 3031 <!-- ko ifnot: doCheckEmptyData(m_appliedCouponCode()) --> 3032 <div class="coupon-success-saving"> 3033 <i class="ci-coins"></i> 3034 <span class="coupon-success-code" data-bind="text: m_appliedCouponCode"></span> 3035 </div> 3036 <!-- /ko --> 3037 </div> 3038 </div> 3039 </div> 3040 </div> 3041 3042 <div id="UI_failInvoiceDataModalPopUp" class="modal fade" tabindex="-1"> 3043 <div class="modal-dialog modal-dialog-centered" role="document"> 3044 <div class="modal-content border-0 rounded-4 overflow-hidden shadow-lg"> 3045 <div class="modal-header border-0 pb-0 px-4 pt-4"> 3046 <h5 class="modal-title fw-bold text-danger mb-0">عÙÙØ§!</h5> 3047 <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button> 3048 </div> 3049 <div class="modal-body text-center px-4 pt-3 pb-4"> 3050 <div class="mx-auto mb-3 d-inline-flex align-items-center justify-content-center rounded-circle" 3051 style="width:96px; height:96px; background: rgba(var(--cz-danger-rgb, 243, 71, 112), .08);"> 3052 <div class="d-inline-flex align-items-center justify-content-center rounded-circle" 3053 style="width:68px; height:68px; background: rgba(var(--cz-danger-rgb, 243, 71, 112), .16);"> 3054 <i class="ci-bell" style="font-size: 32px; color: var(--cz-danger, #f34770);"></i> 3055 </div> 3056 </div> 3057 <!-- ko if: m_listErrorCart().length --> 3058 <p class="fw-bold mb-2 checkout-modal-title" style="font-size:1.05rem;">ØªÙØ¨ÙÙ!</p> 3059 <!-- ko foreach: m_listErrorCart --> 3060 <p class="text-muted mb-1" style="font-size:.85rem;" data-bind="html: $data._name"></p> 3061 <!-- /ko --> 3062 <div class="mb-4"></div> 3063 <!-- /ko --> 3064 <!-- ko ifnot: m_listErrorCart().length --> 3065 <p class="fw-bold mb-1 checkout-modal-title" style="font-size:1.05rem;">Ø¨ÙØ§ÙØ§ØªÙ ØºÙØ± Ù ÙØªÙ ÙØ©.</p> 3066 <!-- ko if: !doCheckEmptyData(m_errorInvoice.m_errorListInvoiceDetailModel()) --> 3067 <p class="text-muted mb-4" style="font-size:.85rem;" data-bind="text: m_errorInvoice.m_errorListInvoiceDetailModel"></p> 3068 <!-- /ko --> 3069 <!-- ko if: doCheckEmptyData(m_errorInvoice.m_errorListInvoiceDetailModel()) --> 3070 <p class="text-muted mb-4" style="font-size:.85rem;">ÙØ±Ø¬Ù ٠راجعة Ø§ÙØÙÙ٠اÙÙ Ù ÙØ²Ø© ÙØ§ÙÙ ØØ§ÙÙØ© ٠رة أخرÙ.</p> 3071 <!-- /ko --> 3072 <!-- /ko --> 3073 <button class="btn btn-danger px-5 py-2 rounded-pill fw-semibold" type="button" data-bs-dismiss="modal"> 3074 Ø¥ØºÙØ§Ù 3075 </button> 3076 </div> 3077 </div> 3078 </div> 3079 </div> 3080 3081
3081<script type="text/html" id="Template_CheckoutCouponCard"> 3082 <div class="card coupon-card" data-bind="style:{'border-color': $root.doCheckCouponUsed($data) ? '#42d697':'' }"> 3083 <div class="card-body py-2 px-3"> 3084 <div class="d-flex align-items-center gap-2 flex-wrap mb-1"> 3085 <span class="h6 mb-0 d-block" data-bind="html: 3086 $data._couponType() == CouponTypeEnum.Shipment ? 'Ø´ØÙØ© Ù Ø®ÙØ¶Ø©' : 3087 $data._couponDiscountType() == CouponDiscountTypeEnum.DiscountTypeByPercent ? 'ÙØ³Ø¨Ø© Ø§ÙØ®ØµÙ ' + $data._discount() + '%' : 3088 $data._couponDiscountType() == CouponDiscountTypeEnum.DiscountTypeByLowPrice ? 'Ø®ØµÙ Ø§ÙØ³Ø¹Ø± اÙÙ ÙØ®Ùض ' + $data._discount() + '%' : 3089 $data._couponDiscountType() == CouponDiscountTypeEnum.DiscountTypeByFixedAmount ? 'Ù Ø¨ÙØº Ø§ÙØ®ØµÙ Ø§ÙØ«Ø§Ø¨Øª ' + m_handlerLayout.doCalcPriceDynamic($data._discount(), true, 0) : 3090 $data._couponDiscountType() == CouponDiscountTypeEnum.DiscountTypeByAmount ? 'Ù Ø¨ÙØº Ø§ÙØ®ØµÙ ' + m_handlerLayout.doCalcPriceDynamic($data._discount(), true, 0) : 3091 $data._couponDiscountType() == CouponDiscountTypeEnum.DiscountTypeByMultiAmount ? 'Ø®ØµÙ Ù Ø¨ÙØº ٠تعدد' : 3092 $data._couponDiscountType() == CouponDiscountTypeEnum.DiscountTypeByMultiPercent ? 'خص٠٠تعدد اÙÙØ³Ø¨Ø© اÙ٠ئÙÙØ©' : '' 3093 "></span> 3094 <!-- ko if: $data._isIncludeVat() --> 3095 <span class="badge bg-success bg-opacity-10 text-success fw-normal rounded-pill px-2" style="font-size: 10px;">ب٠ا Ù٠ذÙÙ Ø¶Ø±ÙØ¨Ø© اÙÙÙÙ Ø© اÙÙ Ø¶Ø§ÙØ©</span> 3096 <!-- /ko --> 3097 <!-- ko ifnot: $data._isIncludeVat() --> 3098 <span class="badge bg-secondary bg-opacity-10 text-body-secondary fw-normal rounded-pill px-2" style="font-size: 10px;">Ø§Ø³ØªØ«ÙØ§Ø¡. Ø¶Ø±ÙØ¨Ø© اÙÙÙÙ Ø© اÙÙ Ø¶Ø§ÙØ©</span> 3099 <!-- /ko --> 3100 </div> 3101 <p class="card-text font-size-10 mb-2 text-body-secondary" data-bind="html: $data._description"></p> 3102 <!-- ko template: { name: 'Template_CheckoutCouponCondition', data: $data } --><!-- /ko --> 3103 <div class="d-flex align-items-center gap-2"> 3104 <div class="coupon-code flex-grow-1" data-bind="text: $data._code"></div> 3105 <!-- ko ifnot: $root.doIsCouponSuggest($data) --> 3106 <button class="btn btn-outline-dark btn-sm rounded-pill px-3" type="button" data-bs-dismiss="modal" aria-label="Close" data-bind="click : $root.doApplyCoupon.bind($root, $data)"> 3107 تطبÙÙ 3108 </button> 3109 <!-- /ko --> 3110 <!-- ko if: $root.doIsCouponSuggest($data) --> 3111 <!-- ko if: $data._amountToReach() > 0 --> 3112 <span class="font-size-10 text-body-secondary text-nowrap">اشتر <b data-bind="text: Math.ceil($data._amountToReach())"></b> <span data-bind="text: doGetCurrentCurrency()"></span> اÙÙ Ø²ÙØ¯ ÙØªØØµÙ عÙÙÙ</span> 3113 <!-- /ko --> 3114 <!-- ko if: !doCheckEmptyData($data._earnLink()) --> 3115 <a class="btn btn-outline-dark btn-sm rounded-pill px-3 text-nowrap" data-bind="attr: { href: $data._earnLink() }">Ø§ÙØ³Ø¨Ùا</a> 3116 <!-- /ko --> 3117 <!-- ko if: $data._amountToReach() <= 0 && doCheckEmptyData($data._earnLink()) && $data._listCategoryModel().length --> 3118 <!-- ko template: { name: 'Template_CheckoutCouponCategoryChip', foreach: $data._listCategoryModel } --><!-- /ko --> 3119 <!-- /ko --> 3120 <!-- /ko --> 3121 </div> 3122 </div> 3123 </div> 3124 </script>
3124 3125 3126
3126<script type="text/html" id="Template_CheckoutCouponCondition"> 3127 <!-- ko if: $data._listCondition().length --> 3128 <ul class="coupon-rules"> 3129 <!-- ko foreach: m_handlerPageCheckout.doGetListCondition($data) --> 3130 <li class="coupon-rule"> 3131 <i data-bind="attr: { class: m_handlerPageCheckout.doGetConditionIcon($data, $parent) }"></i> 3132 <!-- ko if: $data._listCategoryModel.length --> 3133 <span><span data-bind="text: m_handlerPageCheckout.doGetConditionLabel($data)"></span> 3134 <!-- ko foreach: $data._listCategoryModel --> 3135 <a href="javascript:void(0)" data-bind="click: doLoadMenu.bind($root, $data, 'Shop'), clickBubble: false, text: $data._name"></a><!-- ko if: $index() < $parent._listCategoryModel.length - 1 -->, <!-- /ko --> 3136 <!-- /ko --> 3137 </span> 3138 <!-- /ko --> 3139 <!-- ko ifnot: $data._listCategoryModel.length --> 3140 <span data-bind="html: m_handlerPageCheckout.doHtmlCondition($data)"></span> 3141 <!-- /ko --> 3142 </li> 3143 <!-- /ko --> 3144 <li class="coupon-rule-more"> 3145 <a href="javascript:void(0)" data-bind="click: m_handlerPageCheckout.doToggleCondition.bind(m_handlerPageCheckout, $data), clickBubble: false"> 3146 <!-- ko if: m_handlerPageCheckout.m_couponConditionOpenID() == $data._id() -->عرض Ø£ÙÙ<!-- /ko --> 3147 <!-- ko ifnot: m_handlerPageCheckout.m_couponConditionOpenID() == $data._id() -->Ø¬Ù ÙØ¹ Ø§ÙØ´Ø±ÙØ·<!-- /ko --> 3148 </a> 3149 </li> 3150 </ul> 3151 <!-- /ko --> 3152 </script>
3152 3153 3154
3154<script type="text/html" id="Template_CheckoutCouponCategoryChip"> 3155 <!-- ko if : doCheckUUID($data._id()) --> 3156 <a href="#" class="d-inline-flex align-items-center gap-1 px-3 py-1 rounded-pill border fs-xs fw-medium text-decoration-none" data-bind="click: doLoadMenu.bind($root, $data,'Shop'), style: {'border-color': m_handlerLayout.m_isViewMobile() ? $data._colorMobileHex() : $data._colorDesktopHex(), 'color': m_handlerLayout.m_isViewMobile() ? $data._colorMobileHex() : $data._colorDesktopHex()}"> 3157 <i class="ci-tag"></i> 3158 <span data-bind="text: $data._name"></span> 3159 </a> 3160 <!-- /ko --> 3161 </script>
3161 3162 3163 <div id="UI_popUpCouponCode" class="modal fade" tabindex="-1"> 3164 <div class="modal-dialog modal-dialog-centered" role="document"> 3165 <div class="modal-content border-0 rounded-4 overflow-hidden"> 3166 <div class="modal-header border-0 px-4 py-3"> 3167 <div class="d-flex align-items-center gap-2"> 3168 <i class="ci-coupon fs-lg" style="color: rgba(var(--cz-primary-rgb));"></i> 3169 <h5 class="modal-title fw-semibold mb-0">ÙØ§Ø¦Ù Ø© اÙÙØ³ÙÙ Ø©!</h5> 3170 </div> 3171 <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button> 3172 </div> 3173 <div class="modal-body px-4 py-3"> 3174 <div class="mb-1" style="overflow-y: auto; max-height: 30rem;"> 3175 <!-- ko foreach: $root.m_listCouponCompany --> 3176 <!-- ko template: 'Template_CheckoutCouponCard' --><!-- /ko --> 3177 <!-- /ko --> 3178 3179 <!-- ko if: $root.m_listCouponSuggest().length != 0 --> 3180 <div class="fs-sm fw-semibold text-body-secondary pt-3 mt-2 mb-2 border-top">Ø§ÙØªØ اÙÙ Ø²ÙØ¯</div> 3181 <div data-bind="template: { name: 'Template_CheckoutCouponCard', foreach: $root.m_listCouponSuggest }"></div> 3182 <!-- /ko --> 3183 </div> 3184 </div> 3185 </div> 3186 </div> 3187 </div> 3188 3189 <div id="UI_popUpSMSCode" class="modal fade" tabindex="-1"> 3190 <div class="modal-dialog modal-dialog-centered" role="document"> 3191 <div class="modal-content"> 3192 <div class="modal-header "> 3193 <span class=" bg-accent me-2-Auto rounded-circle text-center" style="height:24px; width:24px"> 3194 <i class="ci-check text-white"></i> 3195 </span> 3196 <b class="text-accent">تØÙ٠٠٠رÙ٠اÙÙØ§ØªÙ!</b> 3197 <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button> 3198 </div> 3199 <div class="modal-body pb-3 pt-5"> 3200 <p class="fs-md"> ÙØ°Ù Ø§ÙØ®Ø·ÙØ© Ø¥ÙØ²Ø§Ù ÙØ© ÙØ¥ÙÙ Ø§Ù Ø§ÙØ¯Ùع.</p> 3201 <div class="mb-3"> 3202 <label class="form-label" for="UI_code">أدخ٠ر٠ز Ø§ÙØ±Ø³Ø§ÙØ© اÙÙØµÙØ© اÙÙØµÙرة Ø§ÙØ®Ø§Øµ بÙ</label> 3203 <div class="form-control d-flex align-items-center justify-content-center" dir="ltr" id='UI_checkoutCodeInputs' data-bind=" css:{'is-invalid': !doCheckEmptyData(m_errorAddress.m_errorPhoneValid())}"> 3204 <input class="codeInput" id='UI_checkoutCode1' type="text" inputmode="numeric" maxlength="1" autocomplete="one-time-code" /> 3205 <input class="codeInput" id='UI_checkoutCode2' type="text" inputmode="numeric" maxlength="1" /> 3206 <input class="codeInput" id='UI_checkoutCode3' type="text" inputmode="numeric" maxlength="1" /> 3207 <input class="codeInput" id='UI_checkoutCode4' type="text" inputmode="numeric" maxlength="1" /> 3208 </div> 3209 <div id="UI_errorCode" data-bind="text: m_errorAddress.m_errorPhoneValid" class="invalid-feedback"></div> 3210 </div> 3211 <div class="text-center py-2 px-3" style=" display: flow-root;"> 3212 <button class="btn btn-sm btn-primary col-md-6" data-bind="click : $root.doSendCode.bind($root)" type="button">إرساÙ</button> 3213 </div> 3214 <div class="text-center"> 3215 <button id="UI_checkoutResendCode" class="btn btn-link btn-sm" type="button" data-bind="click: $root.doResendCode.bind($root), enable: m_canResend"> 3216 <!-- ko if: m_canResend() -->ÙÙØ¯ إعادة Ø§ÙØ¥Ø±Ø³Ø§Ù<!-- /ko --> 3217 <!-- ko if: !m_canResend() -->إعادة Ø¥Ø±Ø³Ø§Ù Ø§ÙØ±Ù ز <span data-bind="text: m_resendSecond"></span>s<!-- /ko --> 3218 </button> 3219 </div> 3220 </div> 3221 </div> 3222 </div> 3223 </div> 3224 3225 3226<!-- ko if: doCheckUUID(m_handlerLayout.m_currentPage._id()) --> 3227<!-- ko run: doInjectStyleCss(m_handlerLayout.m_currentPage._styleCss())
3227--><!-- /ko --> 3228<!-- ko foreach: m_handlerLayout.m_currentPage._listDivModel(), childrenComplete: doApplyDivSlots --> 3229<div class="sectionShow" data-bind="class: $data._classCss(), 3230 attr:{'data-div': $data._id(), 'data-div-slot': doGetDivSlotName($data), 'data-div-epoch': m_divEpoch, 3231 'data-div-wait': doCheckDivWaitsForData($data) ? '1' : null}, 3232 style:{'display': doCheckDivPageAllowed($data) ? '' : 'none'}"> 3233 <!-- ko if: doCheckDivRender($data) --> 3234 <!-- ko template: { name: doGetDivTemplateName($data), data: $data} --><!-- /ko --> 3235 <!-- /ko --> 3236</div> 3237<!-- /ko --> 3238<!-- /ko --> 3239 3240 <br /> 3241</section> 3242</div> 3243 3244 3245 </div> 3246 </div> 3247 </div> 3248 <!-- START FOOTER --> 3249 3250<style> 3251 .codeInput { 3252 width: 32px; 3253 height: 32px; 3254 text-align: center; 3255 border: none; 3256 border-bottom: 1.5px solid #d2d2d2; 3257 margin: 0 10px; 3258 } 3259 3260 .codeInput:focus { 3261 border-bottom: 1.5px solid deepskyblue; 3262 outline: none; 3263 } 3264 3265 /* Shared content modal (#UI_slideModal): the body is Portal-authored HTML, so give the tags an 3266 admin actually types a sane default rather than leaving them at browser sizes. */ 3267 .slideModal-body { 3268 font-size: .9rem; 3269 line-height: 1.7; 3270 color: #374151; 3271 } 3272 3273 .slideModal-body ul, 3274 .slideModal-body ol { 3275 padding-inline-start: 18px; 3276 margin-bottom: 0; 3277 } 3278 3279 .slideModal-body p:last-child { 3280 margin-bottom: 0; 3281 } 3282</style> 3283 3284 3285 3286<!-- Sign in / sign up / forgot Password modal--> 3287<div id="UI_sessionModal" class="modal fade noPadding" tabindex="-1" role="dialog"> 3288 <div class="modal-dialog modal-dialog-centered" role="document"> 3289 <div class="modal-content"> 3290 <div class="modal-header bg-secondary"> 3291 <ul class="nav nav-tabs card-header-tabs" role="tablist"> 3292 <li class="nav-item"><a id="UI_signinTab" data-bind="click : doResetUserError" class="nav-link fw-medium active" href="#signin-tab" data-bs-toggle="tab" role="tab" aria-selected="true"><i class="ci-unlocked me-2-Auto mt-n1"></i>تسجÙÙ Ø§ÙØ¯Ø®ÙÙ</a></li> 3293 <li class="nav-item"><a id="UI_signupTab" data-bind="click : doResetUserError" class="nav-link fw-medium" href="#signup-tab" data-bs-toggle="tab" role="tab" aria-selected="false"><i class="ci-user me-2-Auto mt-n1"></i>Ø§ÙØªØ³Ø¬ÙÙ</a></li> 3294 </ul> 3295 <button class="btn-close adjustBtnClose" style="" type="button" data-bs-dismiss="modal" aria-label="Close" onclick="doRedirection()"></button> 3296 </div> 3297 <div class="modal-body tab-content py-4"> 3298 <div id="UI_socialAccount" class="py-2"> 3299 <h3 class="d-inline-block align-middle fs-base fw-medium mb-2">٠ع ØØ³Ø§Ø¨ اجت٠اعÙ</h3> 3300 <div class="row"> 3301 <div id="UI_buttonGoogle" class="col-md-6 my-1" style="height: 40px;"></div> 3302 <div id="appleid-signin" class="col-md-6 my-1" style="height: 40px;" data-color="black" data-border="true" data-type="sign in"></div> 3303 </div> 3304 </div> 3305 <form class="needs-validation tab-pane fade show active" autocomplete="off" novalidate id="signin-tab"> 3306 <div class="mb-3"> 3307 <label class="form-label" for="UI_emailModal">Ø§ÙØ¨Ø±Ùد Ø§ÙØ¥ÙÙØªØ±ÙÙÙ ÙØ§ÙÙØ§ØªÙ</label> 3308 <input autocomplete="username" id="UI_emailModal" data-bind="value : m_currentStructUser._email, css:{'is-invalid': !doCheckEmptyData(m_errorStructUser._email()) || !doCheckEmptyData(m_errorStructUser._phone())}" class="form-control" type="email" placeholder="[email protected]" required> 3309 <div data-bind="text: m_errorStructUser._email" class="invalid-feedback"></div> 3310 <div data-bind="text: m_errorStructUser._phone" class="invalid-feedback"></div> 3311 </div> 3312 <div class="mb-3"> 3313 <label class="form-label" for="UI_passwordModal">ÙÙÙ Ø© اÙÙ Ø±ÙØ± Ø§ÙØ®Ø§ØµØ© بÙ</label> 3314 <div class="password-toggle"> 3315 <input data-bind="value : m_currentStructUser._password, css:{'is-invalid':!doCheckEmptyData(m_errorStructUser._password())}" class="form-control" type="password" id="UI_passwordModal" required autocomplete="current-password"> 3316 <label class="password-toggle-btn" aria-label="Show/hide password"> 3317 <input class="password-toggle-check" type="checkbox"><span class="password-toggle-indicator"></span> 3318 </label> 3319 </div> 3320 <div data-bind="style:{display:!doCheckEmptyData(m_errorStructUser._password())?'block':'none'} , text: m_errorStructUser._password" class="invalid-feedback"></div> 3321 </div> 3322 <div class="mb-3 d-flex flex-wrap justify-content-between"> 3323 <div class="mb-2" data-bind="class:'ar' == 'en'? 'form-check':'form-check-reverse'"> 3324 </div> 3325 <a class="fs-sm" href="#" onclick="doShowModal('UI_forgotModal');" data-bs-dismiss="modal" aria-label="Close">ÙÙ ÙØ³Ùت ÙÙÙ Ø© اÙÙ Ø±ÙØ±Ø</a> 3326 </div> 3327 <button data-bind="click : doSignUser" class="btn btn-primary btn-shadow d-block w-100" type="button">تسجÙÙ Ø§ÙØ¯Ø®ÙÙ</button> 3328 </form> 3329 3330 <form class="needs-validation tab-pane fade" autocomplete="off" novalidate id="signup-tab" novalidate> 3331 <p class="list-unstyled fs-md"> 3332 Ø£Ø¶Ù Ø¨Ø±ÙØ¯Ù Ø§ÙØ¥ÙÙØªØ±ÙÙÙ Ø£Ù ÙØ§ØªÙÙ Ø£Ø¯ÙØ§Ù Ø ÙØ³ÙØªÙ Ø¥Ø±Ø³Ø§Ù Ø±Ø³Ø§ÙØ© ÙÙØªØÙÙ. 3333 </p> 3334 <div class="mt-4 bg-white"> 3335 <div class="mb-3"> 3336 <div class="d-flex justify-content-between"> 3337 <div class="col-8"> 3338 <input autocomplete="tel" id="UI_quickPhoneInput" data-bind="value : m_currentStructUser._phone,valueUpdate: ['afterkeydown', 'input'], css:{'is-invalid': !doCheckEmptyData(m_errorStructUser._phone())}" class="form-control " type="tel" lang=ar dir=rtl placeholder="رÙ٠اÙÙØ§ØªÙ" required> 3339 3340 <!-- ko if: !doCheckEmptyData(m_errorStructUser._phone()) --> 3341 <div data-bind="text: m_errorStructUser._phone" class="invalid-feedback"></div> 3342 <!-- /ko --> 3343 </div> 3344 <div class="col-3"> 3345 <select class="form-select" id="UI_quickCountry" data-bind="css:{'is-invalid':!doCheckEmptyData(m_errorUser.m_errorCountryModel())}, options: m_listCountry, value: m_currentUser._countryModel._id,optionsText: '_code', optionsValue: '_id'"> 3346 </select> 3347 </div> 3348 </div> 3349 <div class="d-flex text-center my-4 align-items-center"> 3350 <hr class="w-25 mx-auto">
3351 <span class="h6">Ø£Ù</span> 3352 <hr class="w-25 mx-auto"> 3353 </div> 3354 <input autocomplete="email" data-bind="value : m_currentStructUser._email, css:{'is-invalid': !doCheckEmptyData(m_errorStructUser._email())}" class="form-control" type="email" placeholder="[email protected]" required> 3355 <!-- ko if: !doCheckEmptyData(m_errorStructUser._email()) --> 3356 <div id="UI_errorEmailModal" data-bind="text: m_errorStructUser._email" class="invalid-feedback"></div> 3357 <!-- /ko --> 3358 </div> 3359 <div class=" mb-3" data-bind="class:'ar' == 'en'? 'form-check':'form-check-reverse'"> 3360 <input class="form-check-input" type="checkbox" id="UI_agreePage" value="" data-bind="attr:{checked: m_isAgree()}, value: m_isAgree(),click: $root.doSetAgree.bind($root)"> 3361 <label class="form-check-label" for="UI_agreePage"> 3362 <span>Ø£ÙØ§Ù٠عÙÙ Ø§ÙØ´Ø±ÙØ· ÙØ§ÙØ³ÙØ§Ø³Ø©</span> 3363 </label> 3364 3365 <a href="/About/TermsandCondition" target="_blank" enable-href="true" class="readMore">Ø§ÙØ±Ø£</a> 3366 </div> 3367 <!-- ko if: m_isAgree() --> 3368 <button data-bind="click : $root.doForgetPassword.bind($root, true)" class="btn btn-primary w-100" type="button">Ø§Ø±Ø³Ù Ø§ÙØ±Ù ز</button> 3369 <!-- /ko --> 3370 3371 </div> 3372 </form> 3373 3374 3375 3376 </div> 3377 </div> 3378 </div> 3379</div> 3380 3381 3382<div id="UI_forgotModal" class="modal fade" tabindex="-1" role="dialog"> 3383 <div class="modal-dialog modal-dialog-centered" role="document"> 3384 <div class="modal-content"> 3385 <div class="modal-header bg-secondary"> 3386 <ul class="nav nav-tabs card-header-tabs" role="tablist"> 3387 <li class="nav-item"><a id="UI_signinTab" data-bind="click : doResetUserError" class="nav-link fw-medium active" data-bs-toggle="tab" role="tab" aria-selected="true"><i class="ci-help me-2-Auto mt-n1"></i>ÙØ³Ùت ÙÙÙ Ø© اÙÙ Ø±ÙØ±</a></li> 3388 </ul> 3389 <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close" onclick="doRedirection()"></button> 3390 </div> 3391 <div class="modal-body tab-content py-4"> 3392 <form class="needs-validation tab-pane fade show active" autocomplete="off" novalidate> 3393 <p class="fs-md">Ù٠بتغÙÙØ± ÙÙÙ Ø© اÙÙ Ø±ÙØ± Ø§ÙØ®Ø§ØµØ© ب٠ÙÙ Ø«ÙØ§Ø« Ø®Ø·ÙØ§Øª سÙÙØ©. ÙØ³Ø§Ø¹Ø¯ ÙØ°Ø§ ÙÙ Ø§ÙØÙØ§Ø¸ عÙ٠أ٠ا٠ÙÙÙ Ø© اÙÙ Ø±ÙØ± Ø§ÙØ¬Ø¯Ùدة.</p> 3394 <ol class="list-unstyled fs-md"> 3395 <li><span class="text-primary me-2-Auto">1.</span>Ø§Ù ÙØ£ عÙÙØ§Ù Ø¨Ø±ÙØ¯Ù Ø§ÙØ¥ÙÙØªØ±ÙÙÙ Ø£Ø¯ÙØ§Ù.</li> 3396 <li><span class="text-primary me-2-Auto">2.</span>Ø³ÙØ±Ø³Ù Ø¥ÙÙ٠ر٠زا Ù Ø¤ÙØªØ§ عبر Ø§ÙØ¨Ø±Ùد Ø§ÙØ¥ÙÙØªØ±ÙÙÙ.</li> 3397 <li><span class="text-primary me-2-Auto">3.</span>Ø§Ø³ØªØ®Ø¯Ù Ø§ÙØ±Ù ز ÙØªØºÙÙØ± ÙÙÙ Ø© اÙÙ Ø±ÙØ± Ø§ÙØ®Ø§ØµØ© ب٠عÙÙ Ù ÙÙØ¹Ùا Ø§ÙØ¢Ù Ù.</li> 3398 </ol> 3399 <div class="py-2 mt-4"> 3400 <div class="mb-3"> 3401 <input autocomplete="email" id="UI_popuEmailInput" data-bind="value : m_currentStructUser._email, css:{'is-invalid': !doCheckEmptyData(m_errorStructUser._email()) || !doCheckEmptyData(m_errorStructUser._phone())}" class="form-control" type="email" placeholder="[email protected]" required> 3402 <!-- ko if: !doCheckEmptyData(m_errorStructUser._email()) --> 3403 <div data-bind="text: m_errorStructUser._email" class="invalid-feedback"></div> 3404 <!-- /ko --> 3405 <div class="d-flex text-center my-4 align-items-center"> 3406 <hr class="w-25 mx-auto">
3407 <span class="h6">Ø£Ù</span> 3408 <hr class="w-25 mx-auto"> 3409 </div> 3410 <div class="d-flex justify-content-between"> 3411 <div class="col-8"> 3412 <input autocomplete="tel" id="UI_popuPhoneInput" data-bind="value : m_currentStructUser._phone, css:{'is-invalid': !doCheckEmptyData(m_errorStructUser._phone()) || !doCheckEmptyData(m_errorStructUser._phone())}" class="form-control " type="number" placeholder="رÙ٠اÙÙØ§ØªÙ" required> 3413 3414 </div> 3415 <div class="col-3"> 3416 <select class="form-select" id="UI_popupCountry" data-bind="css:{'is-invalid':!doCheckEmptyData(m_errorUser.m_errorCountryModel())}, options: m_listCountry, value: m_currentUser._countryModel._id,optionsText: '_code', optionsValue: '_id'"> 3417 </select> 3418 </div> 3419 </div> 3420 <!-- ko if: !doCheckEmptyData(m_errorStructUser._phone()) --> 3421 <div data-bind="text: m_errorStructUser._phone" class="invalid-feedback"></div> 3422 <!-- /ko --> 3423 </div> 3424 <button data-bind="click : $root.doForgetPassword.bind($root, false)" class="btn btn-primary w-100" type="button" data-bs-dismiss="modal" aria-label="Close">Ø§Ø±Ø³Ù Ø§ÙØ±Ù ز</button> 3425 </div> 3426 </form> 3427 </div> 3428 </div> 3429 </div> 3430</div> 3431 3432 3433<div id="UI_validationModal" class="modal fade" tabindex="-1" role="dialog"> 3434 <div class="modal-dialog modal-dialog-centered" role="document"> 3435 <div class="modal-content"> 3436 <div class="modal-header bg-secondary"> 3437 <ul class="nav nav-tabs card-header-tabs" role="tablist"> 3438 <li class="nav-item"><a id="UI_validationTab" data-bind="click : doResetUserError" class="nav-link fw-medium active" data-bs-toggle="tab" role="tab" aria-selected="true"><i class="ci-key me-2-Auto mt-n1"></i>ÙÙÙ Ø© Ù Ø±ÙØ± Ø§ÙØªØÙÙ Ù Ù Ø§ÙØµØØ©</a></li> 3439 </ul> 3440 <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close" onclick="doRedirection()"></button> 3441 </div> 3442 <div class="modal-body tab-content py-4"> 3443 <form class="needs-validation tab-pane fade show active" autocomplete="off" novalidate> 3444 <!-- ko if: !doCheckEmptyData(m_currentStructUser._email()) --> 3445 <p class="fs-md" data-bind="text: 'ÙØ±Ø¬Ù Ø§ÙØªØÙÙ Ù Ù Ø¨Ø±ÙØ¯Ù Ø§ÙØ¥ÙÙØªØ±ÙÙÙ' + ': (' + m_currentStructUser._email() + ')' "></p> 3446 <!-- /ko --> 3447 <!-- ko if: !doCheckEmptyData(m_currentStructUser._phone()) --> 3448 <p class="fs-md" data-bind="text: 'ÙØ±Ø¬Ù Ø§ÙØªØÙ٠٠٠رÙÙ ÙØ§ØªÙÙ' + ': (' + m_currentStructUser._phone() + ')' "></p> 3449 <!-- /ko --> 3450 <div class="mb-3"> 3451 <label class="form-label">Ø£Ø¯Ø®Ù Ø§ÙØ±Ù ز Ø§ÙØ®Ø§Øµ بÙ</label> 3452 <div class="form-control d-flex align-items-center justify-content-center" dir="ltr" id='UI_sessionCodeInputs' data-bind=" css:{'is-invalid': !m_isVerifyed()}"> 3453 <input class="codeInput" id="UI_sessionCode1" type="text" inputmode="numeric" maxlength="1" autocomplete="one-time-code" /> 3454 <input class="codeInput" id="UI_sessionCode2" type="text" inputmode="numeric" maxlength="1" /> 3455 <input class="codeInput" id="UI_sessionCode3" type="text" inputmode="numeric" maxlength="1" /> 3456 <input class="codeInput" id="UI_sessionCode4" type="text" inputmode="numeric" maxlength="1" /> 3457 </div> 3458 <!-- ko if: !doCheckEmptyData(m_errorStructUser._code()) --> 3459 <div id="UI_errorCodeModal" data-bind="text: m_errorStructUser._code" class="invalid-feedback"></div> 3460 <!-- /ko --> 3461 <!-- ko if: !doCheckEmptyData(m_errorStructUser._phone) --> 3462 <div id="UI_errorPhoneModal" data-bind="text: m_errorStructUser._phone" class="invalid-feedback"></div> 3463 <!-- /ko --> 3464 </div> 3465 <div class="text-center py-2 px-3" style=" display: flow-root;"> 3466 <button class="btn btn-sm btn-primary col-md-6" data-bind="click : $root.doSendCode.bind($root)" type="button">إرساÙ</button> 3467 </div> 3468 </form> 3469 </div> 3470 </div> 3471 </div> 3472</div> 3473 3474 3475<div id="UI_resetPasswordModal" class="modal fade" tabindex="-1" role="dialog"> 3476 <div class="modal-dialog modal-dialog-centered" role="document"> 3477 <div class="modal-content"> 3478 <div class="modal-header bg-secondary"> 3479 <ul class="nav nav-tabs card-header-tabs" role="tablist"> 3480 <li class="nav-item"><a id="UI_resetPasswordTab" data-bind="click : doResetUserError" class="nav-link fw-medium active" data-bs-toggle="tab" role="tab" aria-selected="true"><i class="ci-key me-2-Auto mt-n1"></i>إعادة تعÙÙÙ ÙÙÙ Ø© اÙÙ Ø±ÙØ±</a></li> 3481 </ul> 3482 <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close" onclick="doRedirection()"></button> 3483 </div> 3484 <div class="modal-body tab-content py-4"> 3485 <form class="needs-validation tab-pane fade show active" autocomplete="off" novalidate> 3486 <p>ÙÙ ÙÙ٠تغÙÙØ± ÙÙÙ Ø© اÙÙ Ø±ÙØ± Ø§ÙØ®Ø§ØµØ© Ø¨Ù ÙØ£Ø³Ø¨Ø§Ø¨ Ø£Ù ÙÙØ© أ٠إعادة تعÙÙÙÙØ§ إذا ÙØ³ÙØªÙØ§.</p> 3487 <!-- ko if: !doCheckEmptyData(m_errorStructUser._token()) --> 3488 <div id="UI_errorToken" data-bind="text: m_errorStructUser._token" class="invalid-feedback"></div> 3489 <!-- /ko --> 3490 <!-- ko if: m_isSuccess()--> 3491 <p>ØªÙ ØªØØ¯ÙØ« ÙÙÙ Ø© اÙÙ Ø±ÙØ± Ø§ÙØ®Ø§ØµØ© بÙ</p> 3492 <!-- /ko --> 3493 <!-- ko if : !m_isSuccess() --> 3494 <input class="d-none" type="text" autocomplete="username" tabindex="-1" aria-hidden="true" data-bind="value: m_currentStructUser._email"> 3495 <div class="mb-3"> 3496 <label class="form-label" for="UI_resetPasswordH
3496ashModal">ÙÙÙ Ø© اÙÙ Ø±ÙØ± Ø§ÙØ®Ø§ØµØ© بÙ</label> 3497 <input class="form-control" type="password" data-bind="value : m_currentStructUser._password, css:{'is-invalid':!doCheckEmptyData(m_errorStructUser._password())}" id="UI_resetPasswordHashModal" required autocomplete="new-password"> 3498 <div id="UI_errorPasswordModal" data-bind="text: m_errorStructUser._password" class="invalid-feedback"></div> 3499 </div> 3500 <div class="mb-3"> 3501 <label class="form-label" for="UI_resetConfirmPasswordModal">تأÙÙØ¯ ÙÙÙ Ø© اÙÙ Ø±ÙØ±</label> 3502 <input data-bind="value : m_currentStructUser._confirmation, css:{'is-invalid':!doCheckEmptyData(m_errorStructUser._confirmation())}" id="UI_resetConfirmPasswordModal" class="form-control" type="password" required autocomplete="new-password"> 3503 <div id="UI_errorConfirmPasswordModal" data-bind="text: m_errorStructUser._confirmation" class="invalid-feedback"></div> 3504 </div> 3505 <!-- /ko --> 3506 <button data-bind="click: $root.doUpdatePassword.bind($root)" class="btn btn-primary btn-shadow d-block w-100" type="button">ØÙظ</button> 3507 </form> 3508 </div> 3509 </div> 3510 </div> 3511</div> 3512 3513 3514<div id="UI_successRegisterModalPopUp" class="modal fade" tabindex="-1"> 3515 <div class="modal-dialog modal-dialog-centered" role="document"> 3516 <div class="modal-content border-0 rounded-4 overflow-hidden shadow-lg"> 3517 <div class="modal-header border-0 pb-0 px-4 pt-4"> 3518 <h5 class="modal-title fw-bold text-primary mb-0">تسجÙÙ!</h5> 3519 <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button> 3520 </div> 3521 <div class="modal-body text-center px-4 pt-3 pb-4"> 3522 <div class="mx-auto mb-3 d-inline-flex align-items-center justify-content-center rounded-circle" 3523 style="width:96px; height:96px; background: rgba(var(--cz-primary-rgb), .08);"> 3524 <div class="d-inline-flex align-items-center justify-content-center rounded-circle" 3525 style="width:68px; height:68px; background: rgba(var(--cz-primary-rgb), .16);"> 3526 <i class="ci-check" style="font-size: 32px; color: rgba(var(--cz-primary-rgb));"></i> 3527 </div> 3528 </div> 3529 <p class="fw-bold mb-0" style="font-size:1.05rem; color:#1f2937;">ت٠تأÙÙØ¯ Ø¨ÙØ§ÙاتÙ.</p> 3530 </div> 3531 </div> 3532 </div> 3533</div> 3534 3535<div id="UI_popUpNewsLetterSubmit" class="modal fade" tabindex="-1"> 3536 <div class="modal-dialog modal-dialog-centered" role="document"> 3537 <div class="modal-content border-0 rounded-4 overflow-hidden shadow-lg"> 3538 <div class="modal-header border-0 pb-0 px-4 pt-4"> 3539 <h5 class="modal-title fw-bold text-primary mb-0">Ø§ÙØ±Ø³Ø§ÙÙ Ø§ÙØ§Ø®Ø¨Ø§Ø±ÙÙ!</h5> 3540 <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button> 3541 </div> 3542 <div class="modal-body text-center px-4 pt-3 pb-4"> 3543 <div class="mx-auto mb-3 d-inline-flex align-items-center justify-content-center rounded-circle" 3544 style="width:96px; height:96px; background: rgba(var(--cz-primary-rgb), .08);"> 3545 <div class="d-inline-flex align-items-center justify-content-center rounded-circle" 3546 style="width:68px; height:68px; background: rgba(var(--cz-primary-rgb), .16);"> 3547 <i class="ci-check" style="font-size: 32px; color: rgba(var(--cz-primary-rgb));"></i> 3548 </div> 3549 </div> 3550 <p class="fw-bold mb-0" style="font-size:1.05rem; color:#1f2937;">ت٠ØÙظ Ø¬ÙØ© Ø§ÙØ§ØªØµØ§Ù.</p> 3551 </div> 3552 </div> 3553 </div> 3554</div> 3555 3556 3557<div id="UI_slideModal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
3558 <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable" role="document"> 3559 <div class="modal-content"> 3560 <div class="modal-header bg-secondary"> 3561 <ul class="nav nav-tabs card-header-tabs" role="tablist"> 3562 <li class="nav-item"><a class="nav-link fw-medium active" role="tab" aria-selected="true"><i class="ci-announcement me-2-Auto mt-n1"></i><span data-bind="text: m_currentSlideModal._title"></span></a></li> 3563 </ul> 3564 <button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Close"></button> 3565 </div> 3566 <div class="modal-body py-4"> 3567 <div class="slideModal-body textAlignAuto" data-bind="html: m_currentSlideModal._description"></div> 3568 3569 <!-- ko ifnot: doCheckEmptyData(m_currentSlideModal._link()) --> 3570 <a class="btn btn-primary d-block w-100 mt-3" href="#" enable-href="true" data-bind="attr:{href: m_currentSlideModal._link}"> 3571 <!-- ko if: doCheckEmptyData(m_currentSlideModal._button()) -->Ø£ÙØ«Ø±<!-- /ko --> 3572 <!-- ko ifnot: doCheckEmptyData(m_currentSlideModal._button()) --><span data-bind="text: m_currentSlideModal._button"></span><!-- /ko --> 3573 </a> 3574 <!-- /ko --> 3575 </div> 3576 </div> 3577 </div> 3578</div> 3579 3580 3581<!-- Cart Drawer Backdrop --> 3582<div id="UI_cartDrawerBackdrop" class="cart-drawer-backdrop" style="display:none" 3583 data-bind="visible: m_currentPopUpMessage._isVisible(), click: doCloseCartDrawer"></div> 3584 3585<!-- Cart Drawer --> 3586<div id="UI_cartDrawer" class="cart-drawer" 3587 data-bind="css: { 'cart-drawer-open': m_currentPopUpMessage._isVisible(), 'cart-drawer-short': m_drawerShortMode(), 'cart-drawer-alert-only': m_drawerShortMode() && m_currentCart._listCartDetailModel().length == 0 }"> 3588 3589 <!-- Drawer Header --> 3590 <!-- ko if: !(m_drawerShortMode() && m_currentCart._listCartDetailModel().length == 0) --> 3591 <div class="cart-drawer-header"> 3592 <h5 class="mb-0 fw-bold"> 3593 عربة Ø§ÙØªØ³ÙÙ 3594 </h5> 3595 <button class="btn-close" type="button" aria-label="Close" data-bind="click: doCloseCartDrawer"></button> 3596 </div> 3597 <!-- /ko --> 3598 3599 <!-- Added Item Notification --> 3600 <!-- ko if: m_currentPopUpMessage._popUpMessageType() >= 0 --> 3601 <div class="cart-drawer-alert" data-bind="css: doGetClassDrawerAlert()"> 3602 <div class="d-flex align-items-center gap-2"> 3603 <!-- ko if: m_currentPopUpMessage._pictureUrl() && !(m_drawerShortMode() && m_currentCart._listCartDetailModel().length > 0) --> 3604 <img alt="" loading="lazy" class="rounded flex-shrink-0" style="width:40px; height:40px; object-fit:cover;" data-bind="attr:{ src: m_currentPopUpMessage._pictureUrl() }"> 3605 <!-- /ko --> 3606 <div class="flex-grow-1 font-size-12" data-bind="html: doGetDrawerAlertMessage()"></div> 3607 <!-- ko if: m_drawerShortMode() && m_currentCart._listCartDetailModel().length == 0 --> 3608 <button class="btn-close flex-shrink-0" type="button" style="font-size: 10px;" aria-label="Close" data-bind="click: doCloseCartDrawer"></button> 3609 <!-- /ko --> 3610 </div> 3611 <!-- ko if: m_currentPopUpMessage._hasCouponShipment() --> 3612 <div class="shipteaser shipteaser-sm mt-2" data-bind="css: { 'shipteaser-done': !m_currentPopUpMessage._hasPartialShipmentDiscount() && m_currentPopUpMessage._drawLine() == 100 }" > 3613 <span class="shipteaser-icon"><i class="ci-delivery flipAuto"></i></span> 3614 <div class="shipteaser-body"> 3615 <!-- ko if: m_currentPopUpMessage._hasPartialShipmentDiscount() --> 3616 <p class="shipteaser-text" data-bind="html: doGetShipmentTeaserMessage()"></p> 3617 <!-- /ko --> 3618 3619 <!-- ko if: !m_currentPopUpMessage._hasPartialShipmentDiscount() && m_currentPopUpMessage._drawLine() != 100 --> 3620 <p class="shipteaser-text">شراء <span class="shipteaser-value" data-bind="text: m_currentPopUpMessage._couponAmount()"></span> <span class="shipteaser-value" data-bind="text: doGetCurrentCurrency()"></span> اÙÙ Ø²ÙØ¯ ÙÙØØµÙ٠عÙÙÙ <strong>Ø´ØÙ ٠جاÙÙ</strong></p> 3621 <!-- /ko --> 3622 3623 <!-- ko if: !m_currentPopUpMessage._hasPartialShipmentDiscount() && m_currentPopUpMessage._drawLine() == 100 --> 3624 <p class="shipteaser-text">خد٠ة Ø§ÙØ´ØÙ اÙ٠جاÙÙ</p> 3625 <!-- /ko --> 3626 3627 <!-- ko if: m_currentPopUpMessage._drawLine() != 100 --> 3628 <div class="shipteaser-track" role="progressbar" aria-label="Free shipping progress"> 3629 <div class="shipteaser-fill" data-bind="style:{'width': m_currentPopUpMessage._drawLine()+'%'}"></div> 3630 </div> 3631 <!-- /ko --> 3632 </div> 3633 </div> 3634 <!-- /ko --> 3635 </div> 3636 <!-- /ko --> 3637 3638 <!-- Drawer Body - Cart Items --> 3639 <div class="cart-drawer-body"> 3640 <!-- ko if: m_currentCart._listCartDetailModel().length != 0 --> 3641 <div data-bind="foreach: { data: m_showCartDrawer() ? doGetFilterCart() : [] }"> 3642 <div class="cart-drawer-item"> 3643 <div class="d-flex gap-2 align-items-start"> 3644 <div class="flex-shrink-0 position-relative"> 3645 <a class="cart-drawer-item-img d-block" enable-href="false" data-bind="attr:{href: doGetLinkObject($data._objectModel)}"> 3646 <img loading="lazy" data-bind="attr:{ src: doGetDefaultPictureByObject($data._objectModel, true), alt: $data._objectModel._name }"> 3647 </a> 3648 <button class="cart-drawer-item-remove" 3649 data-bind="click: $root.doRemoveCartDetail.bind($root, $data)" 3650 type="button" aria-label="Remove"> 3651 <i class="ci-trash"></i> 3652 </button> 3653 </div> 3654 <div class="flex-grow-1" style="min-width:0;"> 3655 <a enable-href="true" class="cart-drawer-item-title" data-bind="text: $data._objectModel._name, attr:{href: doGetLinkObject($data._objectModel)}"></a> 3656 <div class="d-flex justify-content-between align-items-center mt-1"> 3657 <div class="text-accent fw-bold" data-bind="html: $root.doGetHtmlCartDetailPrice($data, true, true)"></div> 3658 <!-- ko if: $data._cartDetailType() != CartDetailTypeEnum.FromBundle --> 3659 <!-- ko if: $data._objectModel._objectSection() != ObjectSectionEnum.GiftCard && $data._objectModel._objectSection() != ObjectSectionEnum.Service --> 3660 <div class="count-input count-input-xs rounded-pill flex-shrink-0"> 3661 <button type="button" class="btn btn-icon" data-bind="click: $root.doSetQuantity.bind($root, $data, QuantityActionEnum.Remove)">
3662 <span class="fw-bold">â</span> 3663 </button> 3664 <input autocomplete="off" type="number" class="form-control text-center" readonly="true" data-bind="value: $data._quantity"> 3665 <button type="button" class="btn btn-icon" data-bind="click: $root.doSetQuantity.bind($root, $data, QuantityActionEnum.Add)"> 3666 <span class="fw-bold">+</span> 3667 </button> 3668 </div> 3669 <!-- /ko --> 3670 <!-- /ko --> 3671 </div> 3672 <!-- ko if: $data._objectModel._objectStockModel._objectStockStatus() == ObjectStockStatusEnum.Preserved --> 3673 <div class="cart-drawer-item-preorder d-flex align-items-center mt-1"> 3674 <i class="ci-truck flipAuto me-1-Auto" data-bind="css:{'icon-flip-horizontal': doGetCulture() =='en'}"></i> 3675 <!-- ko if: doGetCountryShortNameByCurrentCompany() == 'sa' --> 3676 <span data-bind="text: doFormatPreserved($data._objectModel._objectStockModel._datePreserved(), 15, doGetCulture())"></span> 3677 <!-- /ko --> 3678 <!-- ko if: doGetCountryShortNameByCurrentCompany() == 'ae' --> 3679 <span data-bind="text: doFormatPreserved($data._objectModel._objectStockModel._datePreserved(), 7, doGetCulture())"></span> 3680 <!-- /ko --> 3681 </div> 3682 <!-- /ko --> 3683 </div> 3684 </div> 3685 </div> 3686 </div> 3687 <!-- ko if: m_drawerShortMode() && m_currentCart._listCartDetailModel().length > 1 --> 3688 <div class="text-center py-2 border-top"> 3689 <button type="button" class="btn btn-link p-0 text-decoration-none fw-semibold font-size-12" 3690 style="color: rgba(var(--cz-primary-rgb));" 3691 data-bind="click: function(){ m_drawerShortMode(false); }, text: 'عرض Ø§ÙØ¬Ù ÙØ¹ ' + doGetCartCount() + ' اÙÙ ÙØªØ¬Ø§Øª'"> 3692 </button> 3693 </div> 3694 <!-- /ko --> 3695 <!-- ko if: m_drawerShortMode() && m_currentCart._listCartDetailModel().length > 0 --> 3696 <div class="px-3 pb-2"> 3697 <a class="btn btn-sm d-block w-100 cart-drawer-checkout" 3698 href="/Checkout" enable-href="false" 3699 onclick="m_handlerSession.doCloseCartDrawer()" 3700 style="font-size: 12px; padding: 6px 12px;"> 3701 <i class="ci-card me-2-Auto fs-sm align-middle flipAuto"></i>Ø§ÙØ¯Ùع 3702 </a> 3703 </div> 3704 <!-- /ko --> 3705 <!-- /ko --> 3706 3707 <!-- ko if: m_currentCart._listCartDetailModel().length == 0 && !m_drawerShortMode() --> 3708 <div class="text-center py-5 px-3"> 3709 <i class="ci-card-bag" style="font-size:48px; color:#ccc;"></i> 3710 <h6 class="mt-3 text-muted">ÙØ§ ØªÙØ¬Ø¯ Ù ÙØªØ¬Ø§Øª ÙÙ Ø³ÙØ© Ø§ÙØªØ³ÙÙ Ø§ÙØ®Ø§ØµØ© بÙ.</h6> 3711 </div> 3712 <!-- /ko --> 3713 </div> 3714 3715 <!-- Drawer Footer --> 3716 <!-- ko if: m_currentCart._listCartDetailModel().length != 0 && !m_drawerShortMode() --> 3717 <div class="cart-drawer-footer pb-sm-5 pb-md-4"> 3718 <div class="d-flex justify-content-between align-items-start mb-3"> 3719 <div class="textAlignAuto"> 3720 <span class="text-accent fw-semibold">Ù Ø¬Ù ÙØ¹</span> 3721 <span class="text-muted font-size-10">(ØªØ´Ù Ù Ø¶Ø±ÙØ¨Ø© اÙÙÙÙ Ø© اÙÙ Ø¶Ø§ÙØ©)</span> 3722 <div class="fs-lg fw-bold" style="color: var(--cz-heading-color, #222);" data-bind="html: $root.doCalcPriceDynamic(m_currentCart._total(), true)"></div> 3723 </div> 3724 <!-- ko if: doGetCartTotalSaved() > 0 --> 3725 <div class="font-size-11 text-success fw-semibold textAlignAuto" style="margin-top: 4px;"> 3726 <i class="ci-star font-size-10"></i> ÙÙØ¯ Ø£ÙÙØ°Øª 3727 <div class="fs-sm fw-bold" data-bind="html: $root.doCalcPriceDynamic(doGetCartTotalSaved(), true)"></div> 3728 </div> 3729 <!-- /ko --> 3730 </div>
3731 <a class="btn d-block w-100 cart-drawer-checkout mb-2" href="/Checkout" enable-href="false" onclick="m_handlerSession.doCloseCartDrawer()"> 3732 <i class="ci-card me-2-Auto fs-base align-middle flipAuto"></i>Ø§ÙØ¯Ùع 3733 </a> 3734 </div> 3735 <!-- /ko --> 3736</div> 3737 3738 3739 3740 3741
3742<script type="application/javascript"> 3743 window.doRedirection = function () { 3744 if (window.location.pathname.indexOf("CreateSell") != -1) 3745 window.location = window.location.origin; 3746 } 3747 3748 // The notification dropdown renders a row per advertisement, and it is in the header of every 3749 // page â so the whole list was bound on every page load for a panel most visitors never open. 3750 // The markup only foreaches once this says so; the flag stays true afterwards, since a second 3751 // open should cost nothing. 3752 // 3753 // Filling it is deliberately separate from opening it. On desktop the panel is opened by CSS 3754 // alone (.dropdown:hover > .dropdown-menu in StyleCartzilla-Menu.css), which no click handler 3755 // ever sees â so hovering showed the panel with nothing in it. The wrapper calls this on 3756 // pointer enter, which is the earliest moment either path can start. 3757 window.doPrepareAdvertisement = function () { 3758 if (typeof m_handlerSession != "undefined") 3759 m_handlerSession.m_showAdvertisement(true); 3760 } 3761 3762 window.doOpenAdvertisement = function () { 3763 doPrepareAdvertisement(); 3764 doJsShowMenu('UI_menuWebAdvertisement'); 3765 } 3766 3767 // Mobile renders its own copy of the same list, inside a modal opened from the footer 3768 // toolbar. Same gate, same flag: the rows exist once either surface is asked for. 3769 window.doOpenAdvertisementModal = function () { 3770 doPrepareAdvertisement(); 3771 doShowModal('UI_userModalAdvertisement'); 3772 } 3773 3774 window.doOpenProfile = function () { 3775 if (doCheckUUID(m_handlerSession.m_currentUser._id())){ 3776 if(window.innerWidth <= 992) 3777 doShowModal('UI_menuUserMobile'); 3778 else { 3779 var el = document.querySelector('#UI_userSession .dropdown-menu'); 3780 if (el) el.classList.toggle('show'); 3781 } 3782 } 3783 else { 3784 doShowModal('UI_sessionModal'); 3785 } 3786 } 3787 3788 3789 doLoadScript(function () { 3790 doJsPasswordVisibilityToggle(); // wire modal password eye toggles (login/register/reset) 3791 const sessionInputs = ["UI_sessionCode1", "UI_sessionCode2", "UI_sessionCode3", "UI_sessionCode4"]; 3792 doInitCodeInput(sessionInputs, m_handlerSession.m_currentStructUser._code, m_handlerSession, m_handlerSession.doEventSendCode); 3793 3794 var googleClientID = '316328785783-gk72dnq33tchhr0kdrtidg7enq1arami.apps.googleusercontent.com'; 3795 var googleBtn = document.getElementById("UI_buttonGoogle"); 3796 if (googleClientID != "" && googleBtn) { 3797 if (window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.NativeAuth) 3798 { 3799 googleBtn.innerHTML = 3800 '<button class="btn btn-outline-dark w-100">Sign in with Google</button>'; 3801 googleBtn.onclick = async function () { 3802 try { 3803 // Native plugin reads serverClientId from google-services.json / 3804 // GoogleService-Info.plist; web doesn't need to pass it. 3805 var res = await window.Capacitor.Plugins.NativeAuth.signInWithGoogle({}); 3806 m_handlerSession.doGoogleCredentialResponse({ credential: res.idToken }); 3807 } catch (error) { 3808 console.log(error); 3809 } 3810 }; 3811 } 3812 // Web (browser) Google Sign-In client is heavy (~69 KiB). Don't load it at 3813 // page load â defer to the first time the session modal opens. See 3814 // window.doInitGoogleSignIn + the shown.bs.modal listener below. 3815 } 3816 3817 var m_gsiLoaded = false; 3818 window.doInitGoogleSignIn = function () { 3819 if (m_gsiLoaded) 3820 return; 3821 3822 var googleClientID = '316328785783-gk72dnq33tchhr0kdrtidg7enq1arami.apps.googleusercontent.com'; 3823 var googleBtn = document.getElementById("UI_buttonGoogle"); 3824 var isNative = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.NativeAuth; 3825 3826 // Native wires googleBtn.onclick at page load and loads no web script â skip here. 3827 if (googleClientID == "" || !googleBtn || isNative) 3828 return; 3829 3830 m_gsiLoaded = true; 3831 doLoadScript(function () { 3832 try{ 3833 google.accounts.id.initialize({ 3834 client_id: googleClientID, 3835 callback: m_handlerSession.doGoogleCredentialResponse 3836 }); 3837 google.accounts.id.renderButton( 3838 googleBtn, 3839 { theme: "outline", size: "large" } // customization attributes 3840 ); 3841 } 3842 catch(error){ 3843 console.log(error); 3844 } 3845 3846 }, "https://accounts.google.com/gsi/client"); 3847 }; 3848 3849 // The Google and Apple origins used to be preconnected from the head of every page, where 3850 // they were two handshakes nobody spent on a visit that never opens this modal. Warm them 3851 // here instead, on `show` rather than `shown`: the two doInit* handlers below fetch the SDKs 3852 // on `shown`, so this puts the connection one modal fade (~150-300 ms) ahead of the request 3853 // instead of in the same tick, which is the whole point of a preconnect.
3854 var m_signInWarmed = false; 3855 function doWarmSignInOrigins() { 3856 if (m_signInWarmed) 3857 return; 3858 m_signInWarmed = true; 3859 3860 var origins = ["https://accounts.google.com", "https://appleid.cdn-apple.com"]; 3861 for (var w = 0; w < origins.length; w++) { 3862 var hint = document.createElement("link"); 3863 hint.rel = "preconnect"; 3864 hint.href = origins[w]; 3865 hint.crossOrigin = "anonymous"; 3866 document.head.appendChild(hint); 3867 } 3868 } 3869 3870 var sessionModalEl = document.getElementById("UI_sessionModal"); 3871 if (sessionModalEl) 3872 sessionModalEl.addEventListener("show.bs.modal", doWarmSignInOrigins); 3873 if (sessionModalEl) 3874 sessionModalEl.addEventListener("shown.bs.modal", window.doInitGoogleSignIn); 3875 3876 var appleClientID = 'com.root.login.brandfull'; 3877 var appleBtn = document.getElementById("appleid-signin"); 3878 if (appleClientID != "" && appleBtn) { 3879 var capPlatform = (window.Capacitor && window.Capacitor.getPlatform) ? window.Capacitor.getPlatform() : ""; 3880 var isNative = (capPlatform === "ios" || capPlatform === "android") 3881 && window.Capacitor.Plugins && window.Capacitor.Plugins.NativeAuth; 3882 3883 if (isNative) { 3884 // iOS: ASAuthorization (bundle ID is the audience â pass {}). 3885 // Android: Custom Tab to appleid.apple.com, deep-link back via the 3886 // intent-filter on blendshome.com/auth/android. 3887 appleBtn.innerHTML = 3888 '<button class="btn btn-dark w-100">Sign in with Apple</button>'; 3889 appleBtn.onclick = async function () { 3890 try { 3891 var args = (capPlatform === "android") 3892 ? { clientId: appleClientID, redirectUri: 'https://brandfull.com/auth/android' } 3893 : {}; 3894 var res = await window.Capacitor.Plugins.NativeAuth.signInWithApple(args); 3895 m_handlerSession.doAppleCredentialResponse(res.idToken); 3896 } catch (error) { 3897 console.log(error); 3898 } 3899 }; 3900 } 3901 // Web Apple Sign-In JS deferred to first modal open â see window.doInitAppleSignIn. 3902 } 3903 3904 var m_appleLoaded = false; 3905 window.doInitAppleSignIn = function () { 3906 if (m_appleLoaded) 3907 return; 3908 3909 var appleClientID = 'com.root.login.brandfull'; 3910 var appleBtn = document.getElementById("appleid-signin"); 3911 var capPlatform = (window.Capacitor && window.Capacitor.getPlatform) ? window.Capacitor.getPlatform() : ""; 3912 var isNative = (capPlatform === "ios" || capPlatform === "android") 3913 && window.Capacitor.Plugins && window.Capacitor.Plugins.NativeAuth; 3914 3915 // Native wires appleBtn.onclick at page load and loads no web script â skip here. 3916 if (appleClientID == "" || !appleBtn || isNative) 3917 return; 3918 3919 m_appleLoaded = true; 3920 doLoadScript(function () { 3921 3922 AppleID.auth.init({ 3923 clientId: appleClientID, 3924 redirectURI: 'https://brandfull.com', 3925 scope: 'name email', 3926 usePopup: true, 3927 onSuccess: (response) => console.log('responseApple - response', response), 3928 onError: (error) => console.log('responseApple - error', error), 3929 }); 3930 3931 document.addEventListener('AppleIDSignInOnSuccess', (event) => { 3932 // Handle successful response. 3933 console.log('AppleIDSignInOnSuccess', event.detail.authorization.id_token); 3934 m_handlerSession.doAppleCredentialResponse(event.detail.authorization.id_token) 3935 }); 3936 3937 3938 // Listen for authorization failures. 3939 document.addEventListener('AppleIDSignInOnFailure', (event) => { 3940 // Handle error. 3941 console.log('AppleIDSignInOnFailure', event); 3942 }); 3943 }, "https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js"); 3944 }; 3945 3946 if (sessionModalEl) 3947 sessionModalEl.addEventListener("shown.bs.modal", window.doInitAppleSign
3947In); 3948 }) 3949</script>
3949 3950 3951 3952 3953<input autocomplete="off" style="visibility: hidden;display: none;" type="file" id="UI_addPicture" multiple accept="image/x-png,image/jpeg" /> 3954<div id="UI_uploadImageModal" class="modal" tabindex="-1" role="dialog" style="z-index: 100000;"> 3955 <div class="modal-dialog" style=" width: auto;"> 3956 <div class="modal-content"> 3957 <div class="modal-header"> 3958 <div class="modal-title h4"> تØÙ ÙÙ Ø§ÙØµÙرة </div> 3959 <button type="button" class="btn border-0 bg-transparent p-0" data-bs-dismiss="modal" aria-label="غÙÙ" style="position: inherit; " data-bind="style:{'float': doGetCulture() == 'en'? 'right':'left'}"> 3960 <i class="ci-close"></i> 3961 </button> 3962 </div> 3963 <div class="modal-body pt-1 px-0 pb-0" id="UI_bodyImageModal"> 3964 <div id="image_demo"></div> 3965 </div> 3966 <div class="modal-footer py-1"> 3967 <div class="w-100" style="text-align: center;"> 3968 <button class="btn btn-primary crop_image py-1" id="crop_image"> 3969 <i class="ci-reduce"></i> 3970 Ø§Ø¶Ù ØµÙØ±Ø© 3971 </button> 3972 <button class="btn btn-secondary RotateRight py-1"> 3973 <i class="ci-compare"></i> 3974 Ø¯ÙØ±Ø§Ù 3975 </button> 3976 </div> 3977 </div> 3978 </div> 3979 </div> 3980</div> 3981 3982<style> 3983 /* Cropper look & feel â id-scoped so these win over micro-cropper.js's injected global rules */ 3984 #UI_uploadImageModal .modal-dialog { max-width: 480px; } 3985 #UI_uploadImageModal .modal-content { 3986 border: 0; 3987 border-radius: 18px; 3988 overflow: hidden; 3989 box-shadow: 0 24px 60px -14px rgba(17, 20, 28, .38); 3990 } 3991 #UI_uploadImageModal .modal-body { 3992 background: linear-gradient(180deg, #f6f7f9 0%, #eef0f3 100%); 3993 } 3994 #UI_uploadImageModal .croppie-container { padding: 16px 0 6px; } 3995 3996 /* darkened surround + rounded stage */ 3997 #UI_uploadImageModal .cr-boundary { 3998 border-radius: 14px; 3999 box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .06); 4000 } 4001 /* crop window: soft white frame + subtle ring, keep Croppie's giant darken shadow */ 4002 #UI_uploadImageModal .cr-viewport { 4003 border: 3px solid #fff; 4004 border-radius: 16px; 4005 box-shadow: 0 0 0 1px rgba(0, 0, 0, .18), 0 0 2000px 2000px rgba(17, 20, 28, .55); 4006 } 4007 4008 /* zoom slider */ 4009 #UI_uploadImageModal .cr-slider-wrap { width: 82%; margin: 8px auto 18px; } 4010 #UI_uploadImageModal .cr-slider { padding: 10px 0; } 4011 #UI_uploadImageModal .cr-slider::-webkit-slider-runnable-track { 4012 height: 6px; border-radius: 6px; background: rgba(17, 20, 28, .14); 4013 } 4014 #UI_uploadImageModal .cr-slider::-webkit-slider-thumb { 4015 height: 20px; width: 20px; margin-top: -7px; border-radius: 50%; 4016 background: var(--theme-color, #fd5631); border: 2px solid #fff; 4017 box-shadow: 0 2px 6px rgba(0, 0, 0, .3); transition: transform .15s ease; 4018 } 4019 #UI_uploadImageModal .cr-slider:active::-webkit-slider-thumb { transform: scale(1.15); } 4020 #UI_uploadImageModal .cr-slider::-moz-range-track { 4021 height: 6px; border-radius: 6px; background: rgba(17, 20, 28, .14); 4022 } 4023 #UI_uploadImageModal .cr-slider::-moz-range-thumb { 4024 height: 20px; width: 20px; border-radius: 50%; 4025 background: var(--theme-color, #fd5631); border: 2px solid #fff; 4026 box-shadow: 0 2px 6px rgba(0, 0, 0, .3); 4027 } 4028 4029 /* footer actions */ 4030 #UI_uploadImageModal .modal-footer { 4031 background: #fff; border-top: 1px solid rgba(0, 0, 0, .06); padding: 14px; 4032 } 4033 #UI_uploadImageModal .modal-footer .w-100 { 4034 display: flex; justify-content: center; gap: 10px; 4035 } 4036 #UI_uploadImageModal .modal-footer .btn { 4037 border-radius: 12px; padding: .55rem 1.15rem; font-weight: 600; 4038 display: inline-flex; align-items: center; gap: .4rem; 4039 } 4040 #UI_uploadImageModal .modal-footer .btn i { font-size: 1.05rem; } 4041</style> 4042 4043
4044<script type="application/javascript"> 4045 4046 var image_crop = null; 4047 var image_handler = null; 4048 var image_id = null; 4049 var image_name = null; 4050 var image_param = null; 4051 var image_input = null; 4052 var image_object = null; 4053 var image_folder = null; 4054 var image_index = 0; 4055 var _cropperLoaded = false; 4056 4057 // Lazy-load micro-cropper.js on first use 4058 function doLoadCropper() { 4059 return new Promise(function (resolve) { 4060 if (_cropperLoaded || typeof Croppie !== 'undefined') { _cropperLoaded = true; resolve(); return; } 4061 var s = document.createElement('script'); 4062 // Versioned like every other asset. This one builds its own
4062<script> instead of 4063 // going through doLoadScript, so it does not inherit the cache-busting there and 4064 // a deploy would keep serving the previously cached copy. 4065 s.src = 'https://cdn.brandfull.com/_Js/micro-cropper.js?v=639260136226636726'; 4066 s.onload = function () { _cropperLoaded = true; resolve(); }; 4067 document.head.appendChild(s); 4068 }); 4069 } 4070 4071 document.getElementById("UI_addPicture").addEventListener('change', function () { 4072 doShowModal('UI_uploadImageModal'); 4073 4074 image_input = document.getElementById("UI_addPicture"); 4075 image_index = image_input.files.length - 1; 4076 doLoadCropper().then(function () { 4077 doInitImageTool(image_input, image_object._dimension(), null, image_object._order(), null); 4078 }); 4079 }); 4080 4081 document.getElementById("UI_uploadImageModal").addEventListener('hidden.bs.modal', function() { 4082 document.getElementById("UI_addPicture").value = ''; 4083 }); 4084 4085 var m_currentPicture = null; 4086 window.doOpenCropper = function (handler, folder, item) { 4087 image_handler = handler; 4088 image_folder = folder; 4089 image_object = item; 4090 doLoadCropper().then(function () { 4091 if (item._binary()) { 4092 doShowModal('UI_uploadImageModal'); 4093 doInitImageTool(document.getElementById("UI_addPicture"), item._dimension(), item._binary(), item._order(), item._name()); 4094 } 4095 else if (item._name()) { 4096 doShowModal('UI_uploadImageModal'); 4097 doInitImageTool(document.getElementById("UI_addPicture"), item._dimension(), image_folder + '/' + item._name(), item._order(), item._name()); 4098 } 4099 else 4100 document.getElementById("UI_addPicture").click(); 4101 }); 4102 } 4103 4104 function doInitImageTool(input, dimension, imagepath = null, entityId = null, entityName = null) { 4105 var image_demo = document.querySelector('#image_demo'); 4106 image_id = entityId; 4107 image_name = entityName; 4108 image_input = input; 4109 image_param = doGetParamPicture(dimension); 4110 if (image_crop != null) 4111 image_crop.destroy(); 4112 4113 var xW = image_param.size.width / Math.max(image_param.size.height, image_param.size.width); 4114 image_param.viewport.width = image_param.viewport.width * xW; 4115 var xH = image_param.size.height / Math.max(image_param.size.height, image_param.size.width); 4116 image_param.viewport.height = image_param.viewport.height * xH; 4117 image_crop = new Croppie(image_demo, { 4118 showZoomer: true, 4119 enableResize: false, 4120 enableOrientation: true, 4121 enforceBoundary: true, 4122 mouseWheelZoom: true, 4123 enableExif: true, 4124 viewport: image_param.viewport, 4125 boundary: image_param.boundary 4126 }); 4127 4128 var reader = new FileReader(); 4129 reader.onload = function (event) { 4130 image_crop.bind({ 4131 url: event.target.result, 4132 }).then(function () { 4133 image_crop.setZoom(0); 4134 }); 4135 }; 4136 4137 if (imagepath != null) { 4138 var base64Rejex = /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i; 4139 var isBase64Valid = base64Rejex.test(imagepath); 4140 if (isBase64Valid) { 4141 var url = "data:image/png;base64," + imagepath; 4142 var byteString = atob(url.split(',')[1]); 4143 var ab = new ArrayBuffer(byteString.length); 4144 var ia = new Uint8Array(ab); 4145 for (var i = 0; i < byteString.length; i++) { 4146 ia[i] = byteString.charCodeAt(i); 4147 } 4148 var blob = new Blob([ab], { type: image_param.format ? 'image/' + image_param.format : 'image/jpeg' }); 4149 reader.readAsDataURL(blob); 4150 } 4151 else { 4152 var request = new XMLHttpRequest(); 4153 request.open("POST", '/ConvertBinary?imageUrl=' + imagepath, true); 4154 request.onreadystatechange = function () { 4155 if (request.readyState == 4) 4156 { 4157 if (request.status == 200) { 4158 try { 4159 response = JSON.parse(request.responseText); 4160 var url = "data:image/png;base64," + response.imageData; 4161 var byteString = atob(url.split(',')[1]); 4162 var ab = new ArrayBuffer(byteString.length); 4163 var ia = new Uint8Array(ab); 4164 for (var i = 0; i < byteString.length; i++) { 4165 ia[i] = byteString.charCodeAt(i); 4166 } 4167 var blob = new Blob([ab], { type: image_param.format ? 'image/' + image_param.format : 'image/jpeg' });
4168 reader.readAsDataURL(blob); 4169 } 4170 catch (error) { response = request.responseText; } 4171 } 4172 } 4173 }; 4174 request.send(); 4175 } 4176 } 4177 else if (input.files.length != 0) { 4178 reader.readAsDataURL(input.files[image_index]); 4179 } 4180 } 4181 4182 4183 function doGetParamPicture(dimension) { 4184 var pSize = document.getElementById('UI_bodyImageModal').clientWidth; 4185 4186 var dimensions = dimension.split("x"); 4187 if (dimensions.length != 2) 4188 dimensions = dimension.split("X"); 4189 if (dimensions.length != 2) 4190 dimensions = dimension.split("*"); 4191 return { 4192 size: { width: dimensions[0], height: dimensions[1] }, 4193 viewport: { width: pSize * 0.75, height: pSize * 0.75, type: 'square' }, 4194 boundary: { width: pSize - 30, height: pSize - 30 } 4195 }; 4196 } 4197 function doClickCrop() { 4198 if (image_crop == null) 4199 return; 4200 4201 image_crop.result({ 4202 type: 'canvas', 4203 size: image_param.size, 4204 format: image_param.format ? image_param.format : "jpeg", 4205 quality: image_param.quality ? image_param.quality.value : 0.5 4206 }).then(function (response) { 4207 var size = response.length / (1024 * 1024); 4208 if (response && size < 4) 4209 { 4210 image_object = image_handler.doAddImage(image_input ? image_input.id : null, image_id, image_name, response.split(";base64,")[1], response.split(";base64,")[0].split("/")[1]); 4211 if (image_index != 0 && image_object != null && image_object != undefined) { 4212 image_index = image_index - 1; 4213 setTimeout(doInitImageTool.bind(null, image_input, image_object._dimension(), null, image_object._order(), null), 250); 4214 } 4215 else 4216 doHideModal('UI_uploadImageModal'); 4217 } 4218 }); 4219 } 4220 function doClickRotateRight() { 4221 if (image_crop != null) 4222 image_crop.rotate(90); 4223 } 4224 4225 document.querySelector("#crop_image").removeEventListener('click', doClickCrop); 4226 document.querySelector('#crop_image').addEventListener('click', doClickCrop); 4227 4228 document.querySelector(".RotateRight").removeEventListener('click', doClickRotateRight); 4229 document.querySelector('.RotateRight').addEventListener('click', doClickRotateRight); 4230 4231</script>
4231 4232 4233 4234 4235 4236 4237 4238 4239 4240
4241<script type="application/javascript"> 4242 // Body lives in Tools/Cartzilla/Footer.ts -- the three app footers each carried their own 4243 // near-identical copy of it. 4244 // 4245 // Must go through doLoadScript: Footer.ts is compiled into script.min.js, which is fetched 4246 // asynchronously, so doInitLayoutFooter does not exist yet when this inline script parses. 4247 // Calling it bare threw "doInitLayoutFooter is not defined" on every page. doLoadScript is 4248 // defined by _LayoutScript, which _Layout renders well before this partial, and it is 4249 // idempotent -- the bundle is requested once and later callbacks fire immediately. 4250 doLoadScript(function () { doInitLayoutFooter(); }); 4251</script>
4251 4252 4253<!-- Footer--> 4254 4255 4256<footer id="UI_LayoutFooter" class="footer bg-secondary" style="visibility: hidden;"> 4257 4258 4259 4260 <div id="UI_social" class="bf-surfaceBand px-lg-3"> 4261 <div class="container d-flex flex-md-row flex-sm-column py-sm-3 py-md-2 py-lg-3"> 4262 <div class="col-md-6 col-12 text-center mx-auto"> 4263 <h3 class="pb-1 text-accent mb-2">Ø§ÙØ¶Ù Ø¥ÙÙ ÙØ´Ø±ØªÙا Ø§ÙØ¥Ø®Ø¨Ø§Ø±ÙØ© Ø§ÙØ¢Ù</h3> 4264 <p class="fs-sm d-sm-none text-white">تÙÙ٠آخر Ø§ÙØªØØ¯Ùثات ØÙÙ Ø§ÙØ¹Ø±Ùض Ø§ÙØªØ±ÙÙØ¬ÙØ© ÙÙ ÙØªØ¬Ø§ØªÙا</p> 4265 4266 </div> 4267 <div class="d-flex flex-wrap align-items-center col-md-6 col-12"> 4268 <div class="input-group flex-nowrap"> 4269 <i class="ci-mail position-absolute top-50 translate-middle-y text-muted fs-base ms-3-Auto zindex-10"></i> 4270 <input autocomplete="email" class="form-floating form-control rounded-start-Auto" type="email" data-bind="value : m_emailNewsletter" placeholder="Ø§ÙØ¨Ø±Ùد Ø§ÙØ¥ÙÙØªØ±ÙÙÙ"> 4271 <button class=" btn btn-primary" type="button" data-bind="click : doSaveNewsletter"> 4272 ارس٠4273 </button> 4274 </div> 4275 <!-- ko if: !doCheckEmptyData(m_errorNewsletter()) --> 4276 <small class="text-danger" data-bind="text: m_errorNewsletter"></small> 4277 <!-- /ko --> 4278 <div class="subscription-status"></div> 4279 </div> 4280 </div> 4281 4282 </div> 4283 4284 <div class="p-lg-3 p-md-2 mb-2"> 4285 <div class="mx-auto px-1 row" style="max-width: 80rem;"> 4286 4287 <div id="UI_companyContact" class="col-md-4 col-12 order-sm-first"> 4288 4289 <div class="form-text text-black"> 4290 <div class="widget widget-light pb-2 mb-md-4"> 4291 <!-- ko if: !doCheckEmptyData(m_currentCompany._whatsappLink()) --> 4292 <a name="supportwhatsapp" class="btn-social bs-light bs-whatsapp me-1-Auto mb-1" href="#" aria-label="whatsapp" data-bind="attr:{href:m_currentCompany._whatsappLink}" target="_blank" enable-href="true" rel="noreferrer"> 4293 <i class="ci-whatsapp font-size-20"></i> 4294 </a> 4295 <!-- /ko --> 4296 <!-- ko if: !doCheckEmptyData(m_currentCompany._facebookLink()) --> 4297 <a name="supportfacebook" class="btn-social bs-light bs-facebook me-1-Auto mb-1" href="#" aria-label="facebook" data-bind="attr:{href:m_currentCompany._facebookLink}" target="_blank" enable-href="true" rel="noreferrer"> 4298 <i class="ci-facebook font-size-20"></i> 4299 </a> 4300 <!-- /ko --> 4301 <!-- ko if: !doCheckEmptyData(m_currentCompany._twitterLink()) --> 4302 <a name="supporttwitter" class="btn-social bs-light bs-twitter me-1-Auto mb-1" href="#" aria-label="twitter" data-bind="attr:{href:m_currentCompany._twitterLink}" target="_blank" enable-href="true" rel="noreferrer"> 4303 <i class="ci-twitter font-size-20"></i> 4304 </a> 4305 <!-- /ko --> 4306 <!-- ko if: !doCheckEmptyData(m_currentCompany._instagramLink()) --> 4307 <a name="supportinstagram" class="btn-social bs-light bs-instagram me-1-Auto mb-1" href="#" aria-label="instagram" data-bind="attr:{href:m_currentCompany._instagramLink}" target="_blank" enable-href="true" rel="noreferrer"> 4308 <i class="ci-instagram font-size-20"></i> 4309 </a> 4310 <!-- /ko --> 4311 <!-- ko if: !doCheckEmptyData(m_currentCompany._snapchatLink()) --> 4312 <a name="supportsnapchat" class="btn-social bs-light bs-facebook me-1-Auto mb-1" href="#" aria-label="snapchat" data-bind="attr:{href:m_currentCompany._snapchatLink}" target="_blank" enable-href="true" rel="noreferrer"> 4313 <i class="ci-snapchat font-size-20"></i> 4314 </a> 4315 <!-- /ko --> 4316 <!-- ko if: !doCheckEmptyData(m_currentCompany._tiktokLink()) --> 4317 <a name="supporttiktok" class="btn-social bs-light bs-facebook me-1-Auto mb
4317-1" href="#" aria-label="tiktok" data-bind="attr:{href:m_currentCompany._tiktokLink}" target="_blank" enable-href="true" rel="noreferrer"> 4318 <i class="ci-tiktok font-size-20"></i> 4319 </a> 4320 <!-- /ko --> 4321 </div> 4322 </div> 4323 4324 4325 <div class="d-grid col-12"> 4326 <div class="form-text text-white me-2-Auto"> 4327 <i class="ci-location"></i> 4328 <span data-bind="html: doGetAddress(m_currentCompany._addressModel, '</br>')"> 4329 </span> 4330 </div> 4331 <div class="d-flex flex-wrap text-white"> 4332 <div class="me-2-Auto widget-light"> 4333 <i class="ci-mail"></i> 4334 <a href="#" class="widget-list-link d-inline " data-bind="attr:{href: 'mailto:'+ m_currentCompany._addressModel._email()}" target="_blank" enable-href="true" rel="noreferrer"> 4335 <b data-bind="text:m_currentCompany._addressModel._email"></b> 4336 </a> 4337 </div> 4338 <div class="me-2-Auto widget-light widget-list-item"> 4339 <i class="ci-phone"></i> 4340 <a href="#" class="widget-list-link d-inline" data-bind="attr:{href: 'tel:'+ m_currentCompany._addressModel._phone()}" target="_blank" enable-href="true" rel="noreferrer"> 4341 <b data-bind="text:m_currentCompany._addressModel._phone"></b> 4342 </a> 4343 </div> 4344 </div> 4345 4346 </div> 4347 4348 </div> 4349 4350 4351 <div id="UI_companyInfo" class="col-md-4 col-12 px-md-0 mb-2 m-sm-3"> 4352 <div class=" row mt-n1 form-text text-black mb-1"> 4353 <div class="col-3 "> 4354 <a class="d-inline-block align-middle" href="#"> 4355 <!-- ko if: !doCheckEmptyData(m_currentCompany._pictureModel._name()) --> 4356 <img loading="lazy" width="72" height="40" class="d-block" data-bind="attr:{src: doGetWebpLink('https://cdn.brandfull.com/Content/company/'+ m_currentCompany._pictureModel._name()), title: m_currentCompany._name, alt: m_currentCompany._name}" alt="company"> 4357 <!-- /ko --> 4358 </a> 4359 </div> 4360 <div class="col-9"> 4361 <div class="form-text text-accent"> 4362 <strong class="font-size-16" data-bind="text: m_currentCompany._name()"></strong> 4363 </div> 4364 <div class="form-text text-white pb-2 mt-3"> 4365 <span class="" data-bind="text: m_currentCompany._description()"></span> 4366 4367 <div class="d-flex mt-sm-2" data-bind="foreach: { data: m_handlerLayout.m_listCategoryMenuDepartmentFooter, as: 'subCategory' }"> 4368 <a class="col-2" href="#" enable-href="false" data-bind="attr:{ href: doGetLinkLoadMenu (subCategory, 'About')}"> 4369 <!-- ko if: !doCheckEmptyData(subCategory._pictureName()) --> 4370 <img loading="lazy" class="p-1" data-bind="attr:{src: doGetWebpLink('https://cdn.brandfull.com/Content/category/'+subCategory._pictureName()), title:subCategory._name, alt:subCategory._name}" width="100%" height="100%" alt="category" /> 4371 <!-- /ko --> 4372 </a> 4373 </div> 4374 </div> 4375 </div> 4376 4377 </div> 4378 </div> 4379 4380 <div id="UI_companyLinks" class="col-md-4 col-12 mb-sm-5" style="display:flex; flex-wrap: wrap"> 4381 <!-- ko foreach: m_listCategoryMenuFooter --> 4382 <div class=" col-12 active footer-links " data-bind=" class: $root.m_listCategoryMenuFooter().length == 2? 'col-sm-6' : 'col-sm-4' ,attr:{'id': 'footing_'+ $index() }"> 4383 <div class="widget textAlignAuto"> 4384 <div class="widget widget-links widget-light mb-4"> 4385 <div class="h6 widget-title text-accent pb-1" data-bind="text: $data._name()"></div> 4386 <!-- ko if: $data._list().length!=0 --> 4387 <ul class="widget-list" data-bind="foreach: { data: $data._list(), as: 'subCategory' }"> 4388 <li class="widget-list-item"> 4389 <a class="widget-list-link" href="#" enable-href="false" data-bind="attr:{ href: doGetLinkLoadMenu (subCategory, 'About')}"> 4390 <!-- ko if: !doCheckEmptyData(subCategory._pictureName()) --> 4391 <i><img alt="" loading="lazy" data-bind="attr:{src: doGetWebpLink('https://cdn.brandfull.com/Content/category/'+subCategory._pictureName()), title:subCategory._name}" width="18" height="18" /></i> 4392 <!-- /ko -->
4393 <span data-bind="text: subCategory._name"></span> 4394 </a> 4395 </li> 4396 </ul> 4397 <!-- /ko --> 4398 </div> 4399 </div> 4400 </div> 4401 <!-- /ko --> 4402 </div> 4403 4404 </div> 4405 </div> 4406</footer> 4407 4408<!-- Back To Top Button--> 4409<a id="UI_topArraw" class="btn-scroll-top" onclick="doScrollToTop()"> 4410 <span class="btn-scroll-top-tooltip text-muted fs-sm me-2">أعÙÙ</span> 4411 <i class="btn-scroll-top-icon ci-arrow-up"></i> 4412</a> 4413 4414 4415<div id="UI_menuUserMobile" class="modal fade slide-up" tabindex="-1" role="dialog" aria-labelledby="UI_menuUserMobileLabel" aria-modal="true"> 4416 <div class="modal-dialog" role="document"> 4417 <div class="modal-content"> 4418 <div class="modal-header border-bottom"> 4419 <h5 class="modal-title fw-bold" id="UI_menuUserMobileLabel">ÙØ§Ø¦Ù Ø© اÙÙ ÙÙ Ø§ÙØ´Ø®ØµÙ</h5> 4420 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 4421 </div> 4422 <div class="modal-body p-4"> 4423 <div class="widget widget-cart px-3 pt-2 pb-3 textAlignAuto"> 4424 <a class="dropdown-item d-flex align-items-center py-1" enable-href="false" href="/Account/Profile" data-bs-dismiss="modal" aria-label="Close"> 4425 <i class="ci-user opacity-60 me-2-Auto"></i>اÙÙ ÙÙ Ø§ÙØ´Ø®ØµÙ 4426 </a> 4427 <a class="dropdown-item d-flex align-items-center py-1" enable-href="false" href="/Account/Invoices" data-bs-dismiss="modal" aria-label="Close"> 4428 <i class="ci-basket opacity-60 me-2-Auto"></i>اÙÙÙØ§ØªÙر 4429 </a> 4430 <a class="dropdown-item d-flex align-items-center py-1" enable-href="false" href="/Account/Supports" data-bs-dismiss="modal" aria-label="Close"> 4431 <i class="ci-help opacity-60 me-2-Auto"></i>ØªØ°Ø§ÙØ± 4432 </a> 4433 <a class="dropdown-item d-flex align-items-center py-1" enable-href="false" href="/Account/Messages" data-bs-dismiss="modal" aria-label="Close"> 4434 <i class="ci-message opacity-60 me-2-Auto"></i>رسائ٠4435 </a> 4436 4437 <div class="dropdown-divider"></div> 4438 <a class="dropdown-item d-flex align-items-center py-1" href="#" enable-href="false" data-bind="click: $root.doLogOut.bind($root, '/Account/LogOff?Value=https%3A%2F%2Fbrandfull.com%2FCheckout')" data-bs-dismiss="modal" aria-label="Close"> 4439 <i class="ci-sign-out opacity-60 me-2-Auto"></i>تسجÙÙ Ø§ÙØ®Ø±Ùج 4440 </a> 4441 </div> 4442 </div> 4443 </div> 4444 </div> 4445</div> 4446 4447 4448<div id="UI_userModalAdvertisement" class="modal fade slide-up" tabindex="-1" role="dialog" aria-labelledby="UI_userModalAdvertisementLabel" aria-modal="true"> 4449 <div class="modal-dialog" role="document"> 4450 <div class="modal-content overflow-hidden"> 4451 <div class="modal-header border-bottom"> 4452 <h5 class="modal-title fw-bold" id="UI_userModalAdvertisementLabel">إشعار</h5> 4453 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 4454 </div> 4455 <div class="modal-body"> 4456 <div class="widget widget-cart pt-2 pb-0"> 4457 <div class="d-flex align-items-center justify-content-between"> 4458 <div class="col-md-10"> 4459 4460 <!-- ko if: m_handlerLayout.m_isViewMobile() --> 4461 <!-- ko if: m_enableNotifGrant() --> 4462 <button id="UI_notifGrant" class="btn d-flex align-content-between align-items-center font-size-10 p-1 " onclick="doGetPermissionNotification()"> 4463 <i class="ci-settings me-2-Auto font-size-14 "></i>
4464 <span class="form-check-label elide text-black fw-bolder heartbeat" for="UI_agreeWebPush"> 4465 ابÙÙ٠عÙÙ Ø§Ø·ÙØ§Ø¹ 4466 </span> 4467 </button> 4468 <!-- /ko --> 4469 <!-- ko if: m_enableNotifDenied() --> 4470 <div id="UI_notifDenied" class="d-flex align-content-between align-items-center font-size-10 p-1 "> 4471 <i class="ci-announcement me-2-Auto font-size-14 fw-bolder"></i> 4472 <span class="form-check-label elide text-danger fw-bolder heartbeat"> 4473 Ø§ÙØ¥Ø´Ø¹Ø§Ø±Ø§Øª Ù ØØ¬Ùبة. شغÙÙØ§ Ù٠إعدادات اÙÙ ØªØµÙØ ÙØªØØµÙ عÙÙ ØªÙØ¨ÙÙØ§Øª. 4474 </span> 4475 </div> 4476 <!-- /ko --> 4477 <!-- /ko --> 4478 </div> 4479 </div> 4480 4481 <div id="UI_notificationList" data-simplebar data-simplebar-auto-hide="false" style="overflow-x: hidden;max-height: 21rem;" data-bind="visible: m_listAdvertisement().length!=0, foreach: { data: m_showAdvertisement() ? m_listAdvertisement() : [] }"> 4482 <div class="border-bottom py-1 me-3-Auto d-flex justify-content-between border-danger" style=" border-bottom-style: dotted !important;" data-bs-dismiss="modal"> 4483 <label class="form-text elide w-75 pointer" data-bind="click: $root.doSetTaged.bind($root, $data, true), text:$data._subject()"></label> 4484 <b class="form-check-label textAlignReverse font-size-10 d-inline-block mb-n2 fw-light" data-bind="click: $root.doSetTaged.bind($root, $data, true), text: doCalcDateDifference(doCastFromUTC($data._dateCreate()))"></b> 4485 </div> 4486</div> 4487 4488 </div> 4489 4490 </div> 4491 </div> 4492 </div> 4493</div> 4494<div id="UI_footerMenu" class="handheld-toolbar position-fixed show" style="height: 3.5rem;"> 4495 <div class="d-table table-layout-fixed w-100 pt-1" style="height: 100%"> 4496 4497 <a name="footer-home" class="d-table-cell handheld-toolbar-item" href="/" rel="nofollow" enable-href="false" aria-label="go to home"> 4498 <span class="handheld-toolbar-icon"><i class="ci-home"></i></span> 4499 </a> 4500 <a name="footer-user" class="d-table-cell handheld-toolbar-item" aria-label="ÙØ§Ø¦Ù Ø© اÙÙ ÙÙ Ø§ÙØ´Ø®ØµÙ" href="javascript:void(0)" enable-href="false" rel="nofollow" listener="false" onclick="doOpenProfile()"> 4501 <span class="handheld-toolbar-icon"><i class="ci-user"></i></span> 4502 </a> 4503 4504 4505 <!-- ko if: doCheckUUID(m_currentUser._id()) --> 4506 <a name="footer-favorites" class="d-table-cell handheld-toolbar-item" aria-label="اÙÙ ÙØ¶ÙÙ" href="/Account/Favorites" rel="nofollow" enable-href="false"> 4507 <span class="handheld-toolbar-icon"><i class="ci-heart"></i></span> 4508 </a> 4509 4510 <a name="footer-notes" class="d-table-cell handheld-toolbar-item" aria-label="إشعار" href="javascript:void(0)" rel="nofollow" enable-href="false" listener="false" onclick="doOpenAdvertisementModal()"> 4511 <span class="handheld-toolbar-icon"> 4512 <!-- ko if: m_countAdvertisement() != 0 --> 4513 <span class="bg-danger font-size-10 text-white counterAdv" data-bind="text: m_countAdvertisement() > 99 ? '99+' : m_countAdvertisement()"></span> 4514 <!-- /ko --> 4515 <i class="ci-bell"></i> 4516 </span> 4517 </a> 4518 <!-- /ko --> 4519 4520 </div> 4521</div> 4522 4523 4524 4525 <!-- END FOOTER --> 4526 <div id="UI_preLoader" class="nav-progress" role="progressbar" aria-live="polite" 4527 style="display: none;" 4528 data-bind="visible: m_handlerLayout.m_customLoader()"> 4529 <span class="nav-progress-bar"></span> 4530 <span class="seo-hidden">تØÙ ÙÙ</span> 4531 </div> 4532 <!-- Google Tag Manager -->
4533<script> 4534 //we need it for GTMManager 4535 doLoadScript(function() { 4536 doSetThirdParty(window.dataLayer); 4537 }); 4538</script>
4538 4539<!-- End Google Tag Manager --> 4540<!-- Google Tag Manager (noscript) -->
vendor: 68 bytes, lines 4540-4541
4540 4541<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
4541GTM-PTJJCWLL
vendor: 83 bytes, line 4541
4541" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
4542<!-- End Google Tag Manager (noscript) --> 4543 4544 4545 4546<noscript> 4547 <img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=602667531455664&ev=PageView&noscript=1" /> 4548</noscript> 4549<!-- End Meta Pixel Code --> 4550 <svg id="8dfd9ecb-4c59-4082-9d62-10717474add2.svg" style="display: none;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1124.14 1256.39"> 4551 <path class="cls-1" d="M699.62,1113.02h0c-20.06,44.48-33.32,92.75-38.4,143.37l424.51-90.24c20.06-44.47,33.31-92.75,38.4-143.37l-424.51,90.24Z"></path> 4552 <path class="cls-1" d="M1085.73,895.8c20.06-44.47,33.32-92.75,38.4-143.37l-330.68,70.33v-135.2l292.27-62.11c20.06-44.47,33.32-92.75,38.4-143.37l-330.68,70.27V66.13c-50.67,28.45-95.67,66.32-132.25,110.99v403.35l-132.25,28.11V0c-50.67,28.44-95.67,66.32-132.25,110.99v525.69l-295.91,62.88c-20.06,44.47-33.33,92.75-38.42,143.37l334.33-71.05v170.26l-358.3,76.14c-20.06,44.47-33.32,92.75-38.4,143.37l375.04-79.7c30.53-6.35,56.77-24.4,73.83-49.24l68.78-101.97v-.02c7.14-10.55,11.3-23.27,11.3-36.97v-149.98l132.25-28.11v270.4l424.53-90.28Z"></path> 4553</svg> 4554 4555 4556
4557<script type="application/javascript"> 4558 // What is left here is what is genuinely PER-REQUEST. m_jsonTranslate, jsonListCategory, 4559 // jsonListCompany and jsonListCountry have all moved to /InitData.js (HostController), because 4560 // none of them varies by anything but language: inlining them meant re-sending ~280 KB, the 4561 // category tree alone 270 KB of a 784 KB document, on every navigation and cached by nothing. 4562 // _LayoutScript requests that file first, ahead of the bundle, and the ready queue will not run a 4563 // callback until it has landed. 4564 // 4565 // Property writes onto GlobalSettingTranslateEnum. This one stays: it is resolved from the 4566 // request's companyID header, so it is not the same answer for two visitors on one deployment. 4567 // The body has to stay unevaluated until doSetEnumManager calls it -- GlobalSettingTranslateEnum 4568 // comes from /InitData.js along with the other 110 enums, and does not exist at this point in 4569 // the parse. (It was a script.min.js symbol until the enums moved; same answer either way.) 4570 function doApplySettingByCompany() { 4571 GlobalSettingTranslateEnum.PathCategoryPicture = "https://cdn.brandfull.com/Content/category/"; 4572GlobalSettingTranslateEnum.PathObjectTypePicture = "https://cdn.brandfull.com/Content/objecttype/"; 4573GlobalSettingTranslateEnum.PathObjectPicture = "https://cdn.brandfull.com/Content/object/"; 4574GlobalSettingTranslateEnum.PathPaymentMethodPicture = "https://cdn.brandfull.com/Content/paymentMethod/"; 4575GlobalSettingTranslateEnum.PathTrackerPicture = "https://cdn.brandfull.com/Content/tracker/"; 4576GlobalSettingTranslateEnum.PathShipmentMethodPicture = "https://cdn.brandfull.com/Content/shipmentMethod/"; 4577GlobalSettingTranslateEnum.PathCountryPicture = "https://cdn.brandfull.com/Content/country/"; 4578GlobalSettingTranslateEnum.BaseUrlAPI = "https://brandfullsapi.azurewebsites.net"; 4579GlobalSettingTranslateEnum.BaseUrl = "https://brandfull.com"; 4580GlobalSettingTranslateEnum.Take = "8"; 4581GlobalSettingTranslateEnum.CdnUrl = "https://cdn.brandfull.com"; 4582GlobalSettingTranslateEnum.RedirectUrlPaymentWeb = "https://brandfull.com/Invoice/Edit"; 4583GlobalSettingTranslateEnum.PathCompanyPicture = "https://cdn.brandfull.com/Content/company/"; 4584GlobalSettingTranslateEnum.TicketLifeTime = ""; 4585GlobalSettingTranslateEnum.AppName = "Brandfull"; 4586GlobalSettingTranslateEnum.PathSlidePicture = "https://cdn.brandfull.com/Content/slide/"; 4587GlobalSettingTranslateEnum.TakeObjectShop = "20"; 4588GlobalSettingTranslateEnum.PathReplayPicture = "https://cdn.brandfull.com/Content/replay/"; 4589GlobalSettingTranslateEnum.MessageServiceStatus = "true"; 4590GlobalSettingTranslateEnum.SmartPricingServiceStatus = ""; 4591GlobalSettingTranslateEnum.PathChatPicture = "https://cdn.brandfull.com/Content/chat/"; 4592GlobalSettingTranslateEnum.PathDetailPicture = "https://cdn.brandfull.com/Content/detail/"; 4593GlobalSettingTranslateEnum.PathColorPicture = "https://cdn.brandfull.com/Content/color/"; 4594GlobalSettingTranslateEnum.LimitAddCartQuantity = ""; 4595GlobalSettingTranslateEnum.MaketPlaceServiceStatus = "true"; 4596GlobalSettingTranslateEnum.PathDivPicture = "https://cdn.brandfull.com/Content/divTemplate/"; 4597GlobalSettingTranslateEnum.PathProfilePicture = "https://cdn.brandfull.com/Content/profile/"; 4598GlobalSettingTranslateEnum.PathMessagePicture = "https://cdn.brandfull.com/Content/message/"; 4599GlobalSettingTranslateEnum.PathSurveyPicture = "https://cdn.brandfull.com/Content/survey/"; 4600GlobalSettingTranslateEnum.PathInvoiceDetailStatusPicture = "https://cdn.brandfull.com/Content/invoiceDetailStatus/"; 4601 4602 } 4603</script>
4603 4604 4605 4606
4607<script id="Template_Empty" type="text/html"></script>
4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620
4621<script id="Template_ItemComponent_ObjectDefault" type="text/html"><div class="card product-card shadow-none" data-bind="class: $data.mode"><!--ko if : $data._listCategoryTop().length != 0 --><div class="badge p-0 d-flex flex-column gap-1"><!-- ko foreach: $data._listCategoryTop --><a class="bg-danger rounded-2 px-1 font-size-10" href="#" enable-href="false" data-bind=" 4622 html: doGenerateLabel($data._label()), 4623 style:{'background-color': doCheckIsLink($data._label())? 'transparent' : $data._colorBackgroundHex(), 'color': $data._colorLabelHex()}, 4624 attr:{href: doGetLinkCategory($data), 'data-divID': $parent.divID }"></a><!-- /ko --></div><!-- /ko --><!--ko if : $data._deliveryType() == DeliveryTypeEnum.Wanted --><div class="position-sticky overflow-hidden " ><a class="card-img-top d-block h-100 overflow-hidden" href="javascript: void(0)" aria-label="product" enable-href="false" data-bind="css:{'card-img-bottom': $data.mode != ''}"><img loading="lazy" class="rounded" style="max-height: 100%; height: 100%; object-fit: cover;" data-bind="attr:{ title: $data._name, src: doGetDefaultPictureByObject($data, $data.pictureSize), loading: $data.isAboveFold ? 'eager' : 'lazy', fetchpriority: $data.isLcp ? 'high' : null}" alt="Product"></a></div><div class="card-body p-0" data-bind="css:{'mb-4': ($data.mode =='OnePicture' && m_handlerLayout.m_isViewMobile() == true)}"><a class="elide mb-1" href="javascript: void(0)" aria-label="stock" name="stock" enable-href="false" data-bind="text: $data._name"></a><p data-bind="text: $data._description"></p><!--ko if : $data._listCategoryBottom().length != 0 --><div class="d-flex flex-column"><!-- ko foreach: $data._listCategoryBottom --><a class="font-size-10 elide w-100" href="#" aria-label="category" name="category" enable-href="false" data-bind=" 4625 html: doGenerateLabel($data._label()), 4626 style:{'background-color': doCheckIsLink($data._label())? 'transparent' : $data._colorBackgroundHex(), 'color': $data._colorLabelHex()}, 4627 attr:{href: doGetLinkCategory($data) , 'data-divID': $parent.divID}"></a><!-- /ko --></div><!-- /ko --></div><!-- /ko --><!--ko if : $data._deliveryType() != DeliveryTypeEnum.Wanted --><button class="btn-wishlist btn-sm " type="button" title="Ø£ÙØ§ Ø£ØØ¨" data-bind="style: { color: $data._likeCount()!=0 ? 'red' : '' }, click: m_handlerLayout.doSaveLike.bind(m_handlerLayout, $data)"><i class="fs-6" data-bind="class: $data._hasLike() ? 'ci-heart-filled ':'ci-heart', css:{'hasLike':$data._hasLike()==true}, "></i></button><div class="position-sticky overflow-hidden" ><a class="card-img-top d-block h-100 overflow-hidden" href="#" aria-label="product" enable-href="false" data-bind="css:{'card-img-bottom': $data.mode != ''}, attr:{href: doGetLinkObject($data), 'data-divID':$data.divID}"><img loading="lazy" class="h-100" data-bind="attr:{ title: $data._name, src: doGetDefaultPictureByObject($data, $data.pictureSize), loading: $data.isAboveFold ? 'eager' : 'lazy', fetchpriority: $data.isLcp ? 'high' : null}" alt="Product"></a><div class="d-flex w-100 mb-n3 zindex-10" style=" position: absolute; bottom: 42px;"><!--ko if : $data._objectStockModel._enableBidding() && $data._objectStockModel._enableTimerBidding() --><div class="countdown w-100 mb-0 rounded-bottom px-1 justify-content-start align-items-baseline" style="height:32px;" data-bind="attr:{id: doGetTimerID($data._objectStockModel, 'UI_timerBidding')}, childrenComplete : doJsCountDown(doGetTimerID($data._objectStockModel, 'UI_timerBidding'), true, $data._objectStockModel)"><div class="countdown-label w-100 text-light m-0 font-size-10" style="height:10px" ></div><div class="countdown-days w-25 countdown-value text-light bold m-0 font-size-16" ></div><div class="countdown-hours w-25 countdown-value text-light bold m-0 font-size-16"></div><div class="countdown-minutes w-25 countdown-value text-light bold m-0 font-size-16"></div><div class="countdown-seconds w-25 countdown-value text-light bold m-0 font-size-16"></div><div class="hide countdown-time w-100 countdown-value text-light m-0 font-size-16"></div></div><!-- /ko --></div><div class="fs-sm w-100 px-1 d-flex align-items-center justify-content-between" style="height: 26p
4627x"><div class="float-start mt-1" data-bind="foreach: $data._listColorSimiler"><a href="#" aria-label="color" name="color" class="colorSimiler" enable-href="false" data-bind="title: doGetDefaultNameColor($data), attr:{href: doGetLinkObject($data), 'data-divID':$parent.divID, 'id':'UI_sc_' +$parent._code()+'_'+$data._code()}"><label class="form-option-label rounded-circle" data-bind="attr:{'for':'UI_sc_' +$parent._code()+'_'+$data._code()}"><span class="form-option-color rounded-circle" data-bind="title: $data._objectName(), style:{'background': '-webkit-linear-gradient(45deg, ' + $data._hexName() + ' 60%, ' + doGetDefaultHexColor($data) + ' 40%)'}"></span></label></a></div><!--ko if : doCheckUUID($data._sizeModel._id()) --><a href="#" aria-label="size" name="size" class="float-end" enable-href="true" data-bind="text: $data._sizeModel._name(), attr:{href: doGetURL('Shop/search/') + $data._sizeModel._name(), 'data-divID':$data.divID}"></a><!-- /ko --></div></div><div class="card-body p-0" data-bind="css:{'mb-4': ($data.mode =='OnePicture' && m_handlerLayout.m_isViewMobile() == true)}"><div class="product-title fs-sm"><div class="brandRow"><!--ko with : doGetCategoryByType($data, CategoryTypeEnum.Brand) --><a class="brandRow-name fw-semibold text-decoration-none" href="#" aria-label="brand" name="brand" enable-href="false" 4628 data-bind="text: $data._name, attr:{ href: doGetLinkCategory($data), 'data-divID': $parent.divID }"></a><!-- /ko --><!--ko if : $data._sellMode() != SellModeEnum.SellWithOtherOnly && $data._objectStockModel._priceSale() != 0 && $data._objectStockModel._objectStockStatus() != ObjectStockStatusEnum.OutStock && $data._objectStockModel._objectStockStatus() != ObjectStockStatusEnum.Solded --><a class="btn-cart-inline pointer" href="#" name="addcart" aria-label="buy" title="buy" data-bind="click: m_handlerSession.doAddCart.bind(m_handlerSession, $data, 1, null, null, $data.divID)"><i class="ci-card-bag flipAuto"></i></a><!-- /ko --></div><a class="elide mb-1" href="#" aria-label="product" name="product" enable-href="false" data-bind="attr:{href: doGetLinkObject($data), 'data-divID':$data.divID}"><h2 class="font-size-14" data-bind="text: $data._name"></h2></a><div class="d-flex justify-content-between text-accent rounded-1" style="min-height: 2.5rem;"><!--ko if : $data._objectStockModel._priceSale() !=0 --><div class="text-accent sale w-100" style="display: flex;flex-wrap: wrap; align-items: baseline; column-gap: .4rem;" data-bind="html: m_handlerLayout.doHtmlPriceByCurrency($data, false, 0, true)"></div><!-- /ko --><!--ko if : $data._objectStockModel._objectStockStatus() == ObjectStockStatusEnum.Solded --><a href="#" aria-label="Solded" name="Solded" class="btn btn-sm px-2 py-1 pointer bg-black text-white font-size-10" style="height: fit-content;" title="Re-Buy" data-bind="attr:{href: doGetLinkObject($data), 'data-divID':$data.divID}"> 4629 ٠باع 4630 </a><!-- /ko --><!--ko if : $data._objectStockModel._objectStockStatus() == ObjectStockStatusEnum.OutStock --><a href="#" aria-label="OutStock" name="OutStock" class="btn btn-sm px-2 py-1 pointer bg-danger text-white font-size-10" style="height: fit-content;" title="Re-Buy" data-bind="attr:{href: doGetLinkObject($data), 'data-divID':$data.divID}"> 4631 ÙØ§ ÙÙØ¬Ø¯ ٠خزÙÙ 4632 </a><!-- /ko --></div></div><!--ko if : $data._listCategoryBottom().length != 0 --><div class="d-flex flex-column"><!-- ko foreach: $data._listCategoryBottom --><a class="font-size-10 elide w-100" href="#" aria-label="category" name="category" enable-href="false" data-bind=" 4633 html: doGenerateLabel($data._label()), 4634 style:{'background-color': doCheckIsLink($data._label())? 'transparent' : $data._colorBackgroundHex(), 'color': $data._colorLabelHex()}, 4635 attr:{href: doGetLinkCategory($data), 'data-divID':$parent.divID }"></a><!-- /ko --></div><!-- /ko --></div><!-- /ko --></div></script>
4635<script id="Template_ItemComponent_AdvanceAuto" type="text/html"><!--ko if : doGetSlideTitleVisible($data) || doGetSlideDescriptionVisible($data) || doGetSlideButtonVisible($data)--><div class="AdvanceAuto" data-bind="class: doGetSlideDescriptionVisible($data) ? '':'mb-3'"><div class="AdvanceAuto_lead"><div class="bf-sectionHead"><span class="h4" data-bind="visible: doGetSlideTitleVisible($data), text: $data._title"></span></div><p class="AdvanceAuto_note text-muted font-size-12" data-bind="visible: doGetSlideDescriptionVisible($data), html: $data._description, style:{color: $data._descriptionHex}"></p></div><!--ko if : doGetSlideButtonVisible($data)--><a class="bf-viewAll" href="#" aria-label="subdiv" name="subdiv" enable-href="true" data-bind="attr:{ href: doGetURL($data._link()), 'aria-label':$data._title}"><span data-bind="text: $data._button"></span><i data-bind="class: doGetCulture() =='en'? 'ci-arrow-right':'ci-arrow-left' "></i></a><!-- /ko --></div><!-- /ko --></script>
4635 4636<style> 4637 .product-card.shadow-none { 4638 box-shadow: unset !important; 4639 background-color: transparent; 4640 } 4641 4642 [lang="en"] .magicFlex a:last-of-type { 4643 margin-left: auto !important; 4644 } 4645 4646 [lang="ar"] .magicFlex a:last-of-type { 4647 margin-right: auto !important; 4648 } 4649 4650 .BigPicture , .BigPicture .position-sticky{ 4651 height: 100%; 4652 } 4653 4654.brandRow { 4655 display: flex; 4656 align-items: center; 4657 gap: .35rem; 4658 margin-bottom: .25rem; 4659 min-height: 1.75rem; 4660 } 4661 4662 .brandRow-name { 4663 font-size: 11px; 4664 color: #444; 4665 letter-spacing: .3px; 4666 flex: 0 1 auto; 4667 min-width: 0; 4668 overflow: hidden; 4669 text-overflow: ellipsis; 4670 white-space: nowrap; 4671 } 4672 4673 @media screen and (max-width:992px) { 4674 4675 .BigPicture , .OnePicture{ 4676 flex-direction: row !important; 4677 align-items: flex-end !important; 4678 padding-bottom: 0px !important; 4679 } 4680 4681 .BigPicture .position-sticky, .OnePicture .position-sticky { 4682 width: 45% !important; 4683 height: 100% !important; 4684 padding-right: 10px !important; 4685 padding-left: 10px !important; 4686 } 4687 4688 .BigPicture .position-sticky .bg-opacity-75, .OnePicture .position-sticky .bg-opacity-75 { 4689 width: calc(100% - 20px) !important; 4690 } 4691 4692 .BigPicture .card-body, .OnePicture .card-body { 4693 width: 50% !important; 4694 } 4695 } 4696</style> 4697<style> 4698 .AdvanceAuto { 4699 position: relative; 4700 margin-top: .5rem; 4701 } 4702 4703 .AdvanceAuto .AdvanceAuto_lead { 4704 width: 100%; 4705 } 4706 4707 .AdvanceAuto .AdvanceAuto_note { 4708 margin: -.75rem 0 0; 4709 text-align: center; 4710 } 4711 4712@media screen and (min-width: 768px) { 4713 .AdvanceAuto .bf-viewAll { 4714 position: absolute; 4715 top: 0; 4716 inset-inline-end: 0; 4717 } 4718 } 4719 4720 @media screen and (max-width: 767px) { 4721 .AdvanceAuto { 4722 display: flex; 4723 flex-direction: column; 4724 align-items: center; 4725 } 4726 } 4727</style> 4728 4729 4730 4731 4732</body> 4733</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.