1<!DOCTYPE html> 2<html lang="vi"> 3 4 5<head> 6 <title>ÄÄng nháºp</title> 7 8 9 <meta charset="UTF-8"> 10 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1"> 11 <meta name="robots" content="noindex"> 12 <meta property="og:image" content="/static/images/0/register.png"> 13 <link rel="stylesheet/less" type="text/css" href="/static/images/0/custom.less"/> 14 15 <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" 16 integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> 17
17<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" 18 integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" 19 crossorigin="anonymous"></script>
19 20 <link rel="stylesheet/less" type="text/css" href="/static/less/authentication.less"/> 21 <link rel="stylesheet/less" type="text/css" href="/static/less/wallet.less"/> 22
22<script src="https://cdnjs.cloudflare.com/ajax/libs/less.js/4.2.0/less.min.js" type="text/javascript"></script>
22 23
23<script src="https://code.jquery.com/jquery-3.7.0.min.js" 24 integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>
24 25 26
26<script type="text/javascript" src="/static/js/scripts.js"></script>
vendor: 89 bytes, lines 26-29
26 27 28 29 <script src="https://www.recaptcha.net/recaptcha/enterprise.js?render=
296LfuugMgAAAAAI5jv19Xo-to6pu9hm-49nodLqJM
vendor: 40 bytes, lines 29-34
29"></script> 30 31 32 33 34
34<script type="text/javascript"> 35 const appTrackingID = '6544aba4-4cf3-4afb-ac8e-8f2b65a07411'; 36 if (appTrackingID !== '') { 37 !function (a, d, e, g, b, h, c, f) { 38 a[b] || (a.GlobalTrackerNamespace = a.GlobalTrackerNamespace || [], a.GlobalTrackerNamespace.push(b), a.GlobalTrackerNamespace.push(h), a[b] = function () { 39 (a[b].q = a[b].q || []).push(arguments) 40 }, a[b].q = a[b].q || [], (c = d.createElement(e)).async = !0, c.src = g, (f = d.getElementsByTagName(e)[0]).parentNode.insertBefore(c, f), window.onerror = function (c, e, f, g, d) { 41 return a[b]("exception", {msg: c, error: d}), !1 42 }, window.onunhandledrejection = function (c) { 43 return a[b]("exception", {msg: c.reason, error: "unhandledrejection"}), !1 44 }) 45 }(window, document, "script", "https://cdn.tekoapis.com/tracker/dist/v2/tracker.full.min.js", "track", "https://tracking.tekoapis.com"); 46 track("init", appTrackingID); 47 track("useSubDomain", true); 48 track("enablePageView"); 49 track("enableLinkClick"); 50 track("enableFormTracking", { 51 fields: { 52 blacklist: [ 53 "password", "password2", 54 "newPassword", "newPassword2", 55 "csrf" 56 ] 57 } 58 }); 59 track("enableFocusForm"); 60 track("enableChangeForm"); 61 track("enableSubmitForm"); 62 } 63 </script>
63 64 65 66</head> 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93<body> 94 95 96 97 98 <nav style="z-index: 100" 99 class="navbar navbar-expand-lg navbar-light col-sm-1 overlay-div"> 100 <div class="container-fluid"> 101 <div class="collapse navbar-collapse" id="navbarNav"> 102 <ul class="navbar-nav ms-auto"> 103 <li class="nav-item dropdown"> 104 <a class="nav-link dropdown-toggle" href="#" id="languageDropdown" role="button" 105 data-bs-toggle="dropdown" aria-expanded="false"> 106 <img id="selectedFlag" class="me-2 rounded-circle" width="25" height="25"> 107 </a> 108 <ul id="languages-list" class="dropdown-menu dropdown-menu-end" 109 aria-labelledby="languageDropdown"> 110 </ul> 111 </li> 112 </ul> 113 </div> 114 </div> 115 </nav> 116 117
117<script> 118 function getCookie(name) { 119 const nameEQ = name + "="; 120 const ca = document.cookie.split(';'); 121 for (let i = 0; i < ca.length; i++) { 122 let c = ca[i].trim(); 123 if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); 124 } 125 return null; 126 } 127 128 function setLanguage(lang) { 129 const flag = document.querySelector(`.language-item[data-value="${lang}"]`).getAttribute('data-flag'); 130 document.getElementById('selectedFlag').src = flag; 131 document.cookie = `language=${lang};path=/`; 132 133 const url = new URL(window.location.href); 134 url.searchParams.delete('lang'); 135 const newUrl = url.toString(); 136 137 138 window.history.pushState({}, '', newUrl); 139 window.location.reload() 140 } 141 142 function highlightSelectedLanguage() { 143 const savedLanguage = getCookie('language') || 'en'; 144 document.querySelectorAll('.language-item').forEach(function (item) { 145 if (item.getAttribute('data-value') === savedLanguage) { 146 item.classList.add('selected'); 147 } else { 148 item.classList.remove('selected'); 149 } 150 }); 151 } 152 153 document.addEventListener('DOMContentLoaded', function () { 154 const LANGUAGE_MAPPING = { 155 'vi': 'Tiếng Viá»t', 156 'en': 'English' 157 } 158 const languages = ["vi","en"]; 159 const languageDropdown = document.getElementById("languageDropdown") 160 const languageList = document.getElementById("languages-list") 161 162 languages?.forEach(lang => { 163 var li = document.createElement('li') 164 li.innerHTML = `<a class="dropdown-item language-item" href="#" data-value="${lang}" 165 data-flag="/static/images/country/${lang}.png" data-lang="${LANGUAGE_MAPPING[lang]}"> 166 <img src="/static/images/country/${lang}.png" alt="${LANGUAGE_MAPPING[lang]}" 167 class="me-2 rounded-circle" width="25" height="25"/> 168 <span>${LANGUAGE_MAPPING[lang]}</span> 169 </a>` 170 languageList.append(li) 171 }); 172 173 const savedLanguage = getCookie('language') || 'en'; 174 const selectedFlag = document.getElementById('selectedFlag') 175 selectedFlag.src = document.querySelector(`.language-item[data-value="${savedLanguage}"]`).getAttribute('data-flag'); 176 selectedFlag.alt = LANGUAGE_MAPPING[savedLanguage]; 177 178 if (typeof track == "function") { 179 track("customEvent", "enterPage", { 180 action: "loginScreen", 181 label: savedLanguage, 182 }); 183 } 184 document.querySelectorAll('.language-item').forEach(function (item) { 185 item.addEventListener('click', function (event) { 186 event.preventDefault(); 187 const lang = this.getAttribute('data-value'); 188 if (typeof track == "function") 189 track('manualTrackInteractionContent', { 190 interaction: 'click', 191 contentName: lang, 192 regionName: 'languageSelector', 193 payload: JSON.stringify({ 194 screenName: "loginScreen" 195 }), 196 }); 197 setLanguage(lang); 198 }); 199 }); 200 201 202 document.getElementById('languageDropdown').addEventListener('show.bs.dropdown', highlightSelectedLanguage); 203 }); 204 </script>
204 205 <style type="text/css"> 206 .overlay-div { 207 position: absolute; 208 right: 0; 209 z-index: 1; 210 } 211 212 .language-item.selected { 213 background-color: #F0F0F0; 214 } 215 216 .inactive-account { 217 opacity: 0.4; 218 pointer-events: none; 219 } 220 </style> 221 222 223 224 225 226 227 228 <div class="position-fixed top-0 end-0 mt-2 p-3" style="z-index: 9999"> 229 <div id="alertToast" class="toast hide" role="alert" aria-live="assertive" aria-atomic="true"> 230 <div class="toast-header"> 231 <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" 232 fill="none"> 233 <g clip-path="url(#clip0_7578_1116)"> 234 <path 235 d="M9 16.875C6.91142 16.875 4.90838 16.0453 3.43153 14.5685C1.95468 13.0916 1.125 11.0886 1.125 9C1.125 6.91142 1.95468 4.90838 3.43153 3.43153C4.90838 1.95468 6.91142 1.125 9 1.125C11.0886 1.125 13.0916 1.95468 14.5685 3.43153C16.0453 4.90838 16.875 6.91142 16.875 9C16.875 11.0886 16.0453 13.0916 14.5685 14.5685C13.0916 16.0453 11.0886 16.875 9 16.875ZM9 18C11.3869 18 13.6761 17.0518 15.364 15.364C17.0518 13.6761 18 11.3869 18 9C18 6.61305 17.0518 4.32387 15.364 2.63604C13.6761 0.948212 11.3869 0 9 0C6.61305 0 4.32387 0.948212 2.63604 2.63604C0.948212 4.32387 0 6.61305 0 9C0 11.3869 0.948212 13.6761 2.63604 15.364C4.32387 17.0518 6.61305 18 9 18Z" 236 fill="#DD3444"/> 237 <path 238 d="M7.8772 12.375C7.8772 12.2273 7.9063 12.081 7.96283 11.9445C8.01937 11.808 8.10224 11.684 8.2067 11.5795C8.31117 11.475 8.43519 11.3922 8.57168 11.3356C8.70817 11.2791 8.85446 11.25 9.0022 11.25C9.14993 11.25 9.29623 11.2791 9.43272 11.3356C9.56921 11.3922 9.69323 11.475 9.79769 11.5795C9.90216 11.684 9.98503 11.808 10.0416 11.9445C10.0981 12.081 10.1272 12.2273 10.1272 12.375C10.1272 12.6734 10.0087 12.9595 9.79769 13.1705C9.58671 13.3815 9.30057 13.5 9.0022 13.5C8.70383 13.5 8.41768 13.3815 8.2067 13.1705C7.99572 12.9595 7.8772 12.6734 7.8772 12.375ZM7.98745 5.61938C7.97247 5.47746 7.98749 5.33396 8.03155 5.19822C8.0756 5.06247 8.14771 4.9375 8.24318 4.83142C8.33865 4.72534 8.45536 4.64052 8.58573 4.58245C8.71611 4.52439 8.85723 4.49438 8.99995 4.49438C9.14266 4.49438 9.28379 4.52439 9.41416 4.58245C9.54453 4.64052 9.66124 4.72534 9.75671 4.83142C9.85219 4.9375 9.92429 5.06247 9.96835 5.19822C10.0124 5.33396 10.0274 5.47746 10.0124 5.61938L9.6187 9.56476C9.60547 9.71975 9.53455 9.86414 9.41997 9.96935C9.3054 10.0746 9.1555 10.1329 8.99995 10.1329C8.84439 10.1329 8.6945 10.0746 8.57992 9.96935C8.46534 9.86414 8.39443 9.71975 8.3812 9.56476L7.98745 5.61938Z" 239 fill="#DD3444"/> 240 </g> 241 <defs> 242 <clipPath id="clip0_7578_1116"> 243 <rect width="18" height="18" fill="white"/> 244 </clipPath> 245 </defs> 246 </svg> 247 <strong class="ms-2 me-auto">Thông báo</strong> 248 <button type="button" class="btn-close" data-bs-dismiss="toast" 249 aria-label="Close"></button> 250 </div> 251 <div class="toast-body"><span id="alertToastMsg"></span></div> 252 </div> 253 </div> 254
254<script> 255 const errorMsg = { 256 "connectWallet": "Kết ná»i và thất bại. Vui lòng kết ná»i lại và và thá» lại" 257 } 258 function showToast(msgKey){ 259 var toastEl = document.getElementById('alertToast') 260 var msg = document.getElementById('alertToastMsg') 261 msg.innerHTML=errorMsg[msgKey] 262 let toast = new bootstrap.Toast(toastEl) 263 toast.show() 264 } 265 </script>
265 266 267 268 269 270 <div class="auth-wrapper auth-cover pinpos-custom"> 271 <div class="row auth-inner m-0"> 272 <div class="modal fade" id="wallet-modal" tabindex="-1" aria-labelledby="walletModalLabel" 273 aria-hidden="true"> 274 <div class="modal-dialog" style="max-width: 350px;"> 275 <div class="modal-content"> 276 <div class="modal-body"> 277 <div class="mt-2 mb-3"> 278 <h3 class="modal-title text-center" style="font-size: 24px;"> 279 <strong>Kết ná»i vÃ</strong></h3> 280 </div> 281 <div id="wallet-options" class="mb-2"></div> 282 </div> 283 </div> 284 </div> 285 </div> 286 <div class="col-no-padding col-lg-8 col-sm-12 ps-4 pt-4 pb-4 "> 287 <div class=" d-none d-lg-flex align-items-center login-cover w-100 h-100"> 288 <div class="w-100 d-lg-flex align-items-center justify-content-center px-5"> 289 <img class="login-img" 290 src="/static/images/0/login.png" alt="Login Cover"/> 291 </div> 292 <img alt="mask" class="shadow-img" src="/static/images/0/mask.png"> 293 </div> 294 </div> 295 <div class="col d-flex align-items-center auth-bg col-lg-4 col-sm-12 position-relative"> 296 <div class="col px-xl-2 mx-auto col-sm-8 col-md-8 col-lg-9"> 297 <h2 class="card-title login-title fw-bold mb-1"> 298 Chà o mừng bạn quay trá» lại 299 <br/> SnapAI!ð 300 </h2> 301 302 <div class="mt-4"> 303 <div class='d-flex align-items-center justify-content-center google'> 304 <img className='icon' alt='Google' src="/static/icon/google.svg" style="width: 22px;"/> 305 <span style="width: 165px;"> ÄÄng nháºp vá»i Google</span> 306 <div id='btn-gg'/> 307 </div> 308 </div> 309 310 311 312 <div class="mt-2"> 313 <div id="fbLoginBtn" class='d-flex align-items-center justify-content-center google' 314 onclick="handleClickFbBtn()"> 315 <img className='icon' alt='Facebook' src="/static/icon/facebook.svg" 316 style="width: 22px;"/> 317 <span style="width: 165px;min-inline-size: fit-content;">ÄÄng nháºp vá»i Facebook</span> 318 </div> 319
319<script> 320 function handleClickFbBtn() { 321 if (typeof FB !== 'undefined') { 322 handleFacebookLogin(); 323 } else { 324 window.fbAsyncInit = function () { 325 FB.init({ 326 appId: "1124987958814666", 327 cookie: true, 328 xfbml: true, 329 version: 'v22.0' 330 }); 331 handleFacebookLogin(); 332 }; 333 (function (d, s, id) { 334 var js, fjs = d.getElementsByTagName(s)[0]; 335 if (d.getElementById(id)) return; 336 js = d.createElement(s); 337 js.id = id; 338 js.src = "https://connect.facebook.net/en_US/sdk.js"; 339 fjs.parentNode.insertBefore(js, fjs); 340 }(document, 'script', 'facebook-jssdk')); 341 } 342 } 343 </script>
343 344 </div> 345 346 347 348 349 <div class="separator">hoặc</div> 350 351 352 353 354 <form id="form" class="auth-login-form" 355 onsubmit="submitWithRecaptcha({"Enabled":true,"FormKey":"g-recaptcha-response","SiteKey":"6LfuugMgAAAAAI5jv19Xo-to6pu9hm-49nodLqJM","RecaptchaURL":"\u003cscript src=\"https://www.recaptcha.net/recaptcha/enterprise.js?render=6LfuugMgAAAAAI5jv19Xo-to6pu9hm-49nodLqJM\"\u003e\u003c/script\u003e"}, 'LOGIN_FROM_APP'); return false;" 356 method="post"> 357 <input type="hidden" name="csrf" value="B3c2ibwK8ksQKJaEdof01hbBjnkUos2u"> 358 359 360 361 <input type="hidden" id="g-recaptcha-response" name="g-recaptcha-response"> 362 <input type="hidden" name="action" value="LOGIN_FROM_APP"> 363 364 <div class="mb-1"> 365 <label class="form-label mb-0 upper-first-letter" 366 for="username">email hoặc sá» Äiá»n thoại</label> 367 <input id="username" name="username" class="form-control" value="" 368 oninput="validateUsername( true , true )" 369 placeholder="Nháºp email hoặc sá» Äiá»n thoại cá»§a bạn" 370 autofocus/> 371 <div class="invalid-feedback upper-first-letter"> 372 email hoặc sá» Äiá»n thoại không hợp lá» 373 </div> 374 </div> 375 376 <div class="d-flex justify-content-between mt-3"> 377 <button class="button-secondary button btn" type="button" disabled> 378 <svg xmlns="http://www.w3.org/2000/svg" 379 aria-hidden="true" role="img" tag="i" 380 class="v-icon notranslate v-theme--light v-icon--size-default v-icon--start flip-in-rtl iconify iconify--tabler" 381 width="1em" height="1em" viewBox="0 0 24 24"> 382 <path fill="none" stroke="currentColor" stroke-linecap="round" 383 stroke-linejoin="round" stroke-width="1.5" d="M5 12h14M5 12l6 6m-6-6l6-6"> 384 </path> 385 </svg> 386 <span class="align-middle d-sm-inline-block d-none">Quay lại</span> 387 </button> 388 <button id="btn-submit" disabled type="submit" class="button-primary button btn"> 389 <span class="align-middle d-sm-inline-block d-none">Tiếp</span> 390 <div id="icon-submit" class="d-inline-block"> 391 <svg xmlns="http://www.w3.org/2000/svg" 392 aria-hidden="true" role="img" tag="i" 393 class="v-icon notranslate v-theme--light v-icon--size-default v-icon--end flip-in-rtl iconify iconify--tabler" 394 width="1em" height="1em" viewBox="0 0 24 24"> 395 <path fill="none" stroke="currentColor" stroke-linecap="round" 396 stroke-linejoin="round" stroke-width="1.5" d="M5 12h14m-6 6l6-6m-6-6l6 6"> 397 </path> 398 </svg> 399 </div> 400 <span id="icon-loading" class="spinner-border spinner-border-sm d-none" 401 role="status"></span> 402 </button> 403 404 <input type="hidden" name="credential"> 405 <input type="hidden" name="type"> 406 407 </div> 408 </form> 409 410 <p class="text-center position-absolute mb-4 w-100 start-0 bottom-0">
411 <span class="me-25">Chưa có tà i khoản?</span> 412 <a href="/register?loginUrl=%2Flogin%3FredirectTo%3Dhttps%253A%252F%252Fapp.snapai.ai"> 413 <span>ÄÄng ký</span> 414 </a> 415 </p> 416 </div> 417 </div> 418 </div> 419 </div> 420 421 422 423
423<script> 424 window.addEventListener('pageshow', function (event) { 425 if (event.persisted) { 426 location.reload(); 427 } 428 }); 429 430 431 </script>
431 432 433
433<script src="https://accounts.google.com/gsi/client" async defer></script>
433 434
434<script> 435 function handleCredentialResponse(auth) { 436 const form = document.querySelector("#form"); 437 form.type.value = "google"; 438 form.credential.value = auth.credential; 439 form.submit(); 440 manualTrackInteractionContent( 441 'loginWithGoogleButton', 442 'registerWithGoogle', 443 { 444 screenName: "login", 445 trigger: "Success login with Google" 446 }) 447 } 448 449 function handleClickGoogleBtn() { 450 manualTrackInteractionContent( 451 'loginWithGoogleButton', 452 'registerWithGoogle', 453 { 454 screenName: "login", 455 trigger: "Click loginWithGoogleButton" 456 }) 457 } 458 </script>
458 459 460 461 462
462<script> 463 window.onload = () => { 464 465 466 467 468 google.accounts.id.initialize({ 469 use_fedcm_for_prompt: true, 470 ux_mode: "popup", 471 client_id: "684346886708-92m73c0lqd15kj41s4hefru4kbkgkgdf.apps.googleusercontent.com", 472 callback: handleCredentialResponse 473 }); 474 google.accounts.id.prompt(); 475 google.accounts.id.renderButton(document.getElementById("btn-gg"), { 476 width: 354, 477 click_listener: handleClickGoogleBtn 478 }); 479 480 481 const queryString = window.location.search; 482 483 const urlParams = new URLSearchParams(queryString); 484 485 const autologinValue = urlParams.get('autologin'); 486 if (autologinValue) { 487 if (autologinValue === 'facebook') { 488 handleClickFbBtn() 489 } else if (autologinValue === 'google') { 490 491 const container = document.getElementById("btn-gg"); 492 493 494 const googleButton = container.querySelector('div[role="button"]'); 495 496 497 if (googleButton) { 498 googleButton.click(); 499 console.log("Google button clicked"); 500 } else { 501 console.log("Google button not found"); 502 } 503 } 504 } 505 506 } 507 </script>
507 508 509 510
510<script> 511 window.fbAsyncInit = function () { 512 FB.init({ 513 appId: "1124987958814666", 514 cookie: true, 515 xfbml: true, 516 version: 'v22.0' 517 }); 518 519 FB.AppEvents.logPageView(); 520 521 }; 522 523 (function (d, s, id) { 524 var js, fjs = d.getElementsByTagName(s)[0]; 525 if (d.getElementById(id)) { 526 return; 527 } 528 js = d.createElement(s); 529 js.id = id; 530 js.src = "https://connect.facebook.net/en_US/sdk.js"; 531 fjs.parentNode.insertBefore(js, fjs); 532 }(document, 'script', 'facebook-jssdk')); 533 </script>
533 534 535 536 537 538
538<script> 539 function handleFacebookLogin() { 540 const button = document.getElementById('fbLoginBtn'); 541 button.disabled = true; 542 543 544 FB.getLoginStatus(function (statusResponse) { 545 if (statusResponse.status === 'connected' && statusResponse.authResponse) { 546 547 processFacebookLogin(statusResponse); 548 } else { 549 550 FB.login(function (loginResponse) { 551 if (loginResponse.authResponse && loginResponse.status === 'connected') { 552 553 processFacebookLogin(loginResponse); 554 } else { 555 556 button.disabled = false; 557 } 558 }, { 559 scope: 'public_profile,email', 560 return_scopes: true, 561 auth_type: 'rerequest' 562 }); 563 } 564 }); 565 566 567 function processFacebookLogin(response) { 568 const form = document.querySelector("#form"); 569 form.type.value = "facebook"; 570 form.credential.value = response.authResponse.accessToken; 571 form.submit(); 572 manualTrackInteractionContent( 573 'loginWithFacebook', 574 'loginWithFacebook', 575 { 576 screenName: "login", 577 trigger: "Success login with Facebook", 578 }); 579 } 580 } 581 </script>
581 582 583</div> 584</body> 585</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.