1 2
3<script type="text/javascript"> 4 (function(c,l,a,r,i,t,y){ 5 c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)}; 6 t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i; 7 y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y); 8 })(window, document, "clarity", "script", "vm6y569o5p"); 9</script>
9 10 11<!-- Google tag (gtag.js) -->
vendor: 65 bytes, lines 11-12
11 12<script async src="https://www.googletagmanager.com/gtag/js?id=
12AW-10996390203
vendor: 13 bytes, line 12
12"></script>
13<script> 14
vendor: 138 bytes, lines 14-18
14window.dataLayer = window.dataLayer || []; 15 function gtag(){dataLayer.push(arguments);} 16 gtag('js', new Date()); 17 18 gtag('config', '
18AW-10996390203
vendor: 5 bytes, line 18
18');
19</script>
19 20 21<!-- Google tag (gtag.js) -->
vendor: 65 bytes, lines 21-22
21 22<script async src="https://www.googletagmanager.com/gtag/js?id=
22G-2ZKMMGQKY8
vendor: 13 bytes, line 22
22"></script>
23<script> 24
vendor: 138 bytes, lines 24-28
24window.dataLayer = window.dataLayer || []; 25 function gtag(){dataLayer.push(arguments);} 26 gtag('js', new Date()); 27 28 gtag('config', '
28G-2ZKMMGQKY8
vendor: 5 bytes, line 28
28');
29</script>
29 30 31<!-- Affiliatable Base Code -->
31<script src="https://cdn.affiliatable.io/5670e55e4d3459091885818c74beba82.js" async></script>
31 <!-- /Affiliatable Base Code --> 32 33 34<!-- Meta Pixel Code -->
35<script>
vendor: 408 bytes, lines 35-44
35 36!function(f,b,e,v,n,t,s) 37{if(f.fbq)return;n=f.fbq=function(){n.callMethod? 38n.callMethod.apply(n,arguments):n.queue.push(arguments)}; 39if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0'; 40n.queue=[];t=b.createElement(e);t.async=!0; 41t.src=v;s=b.getElementsByTagName(e)[0]; 42s.parentNode.insertBefore(t,s)}(window, document,'script', 43'https://connect.facebook.net/en_US/fbevents.js'); 44fbq('init', '
44379186429790656
vendor: 32 bytes, lines 44-45
44'); 45fbq('track', 'PageView');
46</script>
46 47<noscript><img height="1" width="1" style="display:none" 48src="https://www.facebook.com/tr?id=1746627840101898&ev=PageView&noscript=1" 49/></noscript> 50<!-- End Meta Pixel Code --> 51 52 53 54 55<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> 56<link rel="icon" type="image/png" href="/static/images/favicon.png"> 57<title>EV Quotes Login</title> 58<link rel="stylesheet" href="/static/css/login.css"> 59<link rel="stylesheet" href="/static/css/style.css"> 60<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> 61<link href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" rel="stylesheet"> 62 63<!-- SEO Meta Tags --> 64<meta name="title" content="EV Quotes Login"> 65<meta name="description" content=""> 66<meta name="keywords" content=""> 67 68<style> 69 .leaf-top-right { 70 position: absolute; 71 top: 0; 72 right: 0; 73 width: 70px; 74 z-index: 1; 75 } 76 77 .leaf-bottom-left { 78 position: absolute; 79 bottom: -4; 80 left: 38px; 81 width: 150px; 82 z-index: 1; 83 } 84 85 .text-color { 86 color: #012152; 87 } 88 89 .btn-color-blue { 90 background: #377FFE; 91 color: #ffffff; 92 } 93 94 .btn-color-blue:hover { 95 background: #1a68f0; 96 } 97 98 .emailinput { 99 height: 61px; 100 } 101 102 .emailinput { 103 height: 61px; 104 } 105 106 .passwordinput { 107 height: 61px; 108 109 } 110 111 .form-label { 112 font-size: 17px; 113 } 114</style> 115 116 117 118 119<!-- Leaf Images --> 120<img src="/static/images/login/icon-bottom.png" class="leaf-bottom-left" alt="Leaf Bottom"> 121<img src="/static/images/login/circle-top.png" class="leaf-top-right" alt="Leaf Top"> 122<!-- Toaster Notification System - Reusable Component --> 123<!-- Include this in any template where you want toaster notifications --> 124 125<!-- Toast Container --> 126<div id="toast-container" class="toast-container"></div> 127 128<!-- Toaster Styles --> 129<style> 130 /* Toaster Notification Styles */ 131 .toast-container { 132 position: fixed; 133 top: 20px; 134 right: 20px; 135 z-index: 1000; 136 max-width: 400px; 137 pointer-events: none; 138 } 139 140 .toast { 141 display: flex; 142 align-items: center; 143 gap: 12px; 144 margin-bottom: 12px; 145 padding: 16px; 146 border-radius: 8px; 147 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 148 font-weight: 500; 149 pointer-events: auto; 150 transform: translateX(100%); 151 opacity: 0; 152 transition: all 0.3s ease; 153 max-width: 100%; 154 word-wrap: break-word; 155 } 156 157 .toast.show { 158 transform: translateX(0); 159 opacity: 1; 160 } 161 162 .toast.success { 163 background-color: #10b981; 164 color: white; 165 border-left: 4px solid #059669; 166 } 167 168 .toast.error { 169 background-color: #ef4444; 170 color: white; 171 border-left: 4px solid #dc2626; 172 } 173 174 .toast.warning { 175 background-color: #f59e0b; 176 color: white; 177 border-left: 4px solid #d97706; 178 } 179 180 .toast.info { 181 background-color: #3b82f6; 182 color: white; 183 border-left: 4px solid #2563eb; 184 } 185 186 .toast-icon { 187 flex-shrink: 0; 188 width: 20px; 189 height: 20px; 190 } 191 192 .toast-content { 193 flex: 1; 194 font-size: 14px; 195 line-height: 1.4; 196 } 197 198 .toast-close { 199 background: none; 200 border: none; 201 color: inherit; 202 cursor: pointer; 203 padding: 0; 204 width: 20px; 205 height: 20px; 206 display: flex; 207 align-items: center; 208 justify-content: center; 209 border-radius: 4px; 210 transition: background-color 0.2s ease; 211 flex-shrink: 0; 212 } 213 214 .toast-close:hover { 215 background-color: rgba(255, 255, 255, 0.2); 216 } 217 218 @media (max-width: 640px) { 219 .toast-container { 220 top: 10px; 221 right: 10px; 222 left: 10px; 223 max-width: none; 224 } 225 } 226</style> 227 228<!-- Toaster JavaScript -->
229<script> 230 // Toaster Notification System 231 class ToastManager { 232 constructor() { 233 this.container = document.getElementById('toast-container'); 234 this.toasts = []; 235 } 236 237 show(message, type = 'info', duration = 5000) { 238 const toast = this.createToast(message, type); 239 this.container.appendChild(toast); 240 this.toasts.push(toast); 241 242 // Trigger animation 243 setTimeout(() => { 244 toast.classList.add('show'); 245 }, 10); 246 247 // Auto remove 248 setTimeout(() => { 249 this.remove(toast); 250 }, duration); 251 252 return toast; 253 } 254 255 createToast(message, type) { 256 const toast = document.createElement('div'); 257 toast.className = `toast ${type}`; 258 259 const icon = this.getIcon(type); 260 261 toast.innerHTML = ` 262 <div class="toast-icon">${icon}</div> 263 <div class="toast-content">${message}</div> 264 <button class="toast-close" onclick="window.toastManager.remove(this.parentElement)"> 265 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 266 <line x1="18" y1="6" x2="6" y2="18"></line> 267 <line x1="6" y1="6" x2="18" y2="18"></line> 268 </svg> 269 </button> 270 `; 271 272 return toast; 273 } 274 275 getIcon(type) { 276 const icons = { 277 success: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 278 <polyline points="20,6 9,17 4,12"></polyline> 279 </svg>`, 280 error: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 281 <circle cx="12" cy="12" r="10"></circle> 282 <line x1="15" y1="9" x2="9" y2="15"></line> 283 <line x1="9" y1="9" x2="15" y2="15"></line> 284 </svg>`, 285 warning: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 286 <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"></path> 287 <line x1="12" y1="9" x2="12" y2="13"></line> 288 <line x1="12" y1="17" x2="12.01" y2="17"></line> 289 </svg>`, 290 info: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 291 <circle cx="12" cy="12" r="10"></circle> 292 <line x1="12" y1="16" x2="12" y2="12"></line> 293 <line x1="12" y1="8" x2="12.01" y2="8"></line> 294 </svg>` 295 }; 296 return icons[type] || icons.info; 297 } 298 299 remove(toast) { 300 if (!toast || !toast.parentElement) return; 301 302 toast.classList.remove('show'); 303 304 setTimeout(() => { 305 if (toast.parentElement) { 306 toast.parentElement.removeChild(toast); 307 } 308 this.toasts = this.toasts.filter(t => t !== toast); 309 }, 300); 310 } 311 312 success(message, duration = 5000) { 313 return this.show(message, 'success', duration); 314 } 315 316 error(message, duration = 7000) { 317 return this.show(message, 'error', duration); 318 } 319 320 warning(message, duration = 6000) { 321 return this.show(message, 'warning', duration); 322 } 323 324 info(message, duration = 5000) { 325 return this.show(message, 'info', duration); 326 } 327 } 328 329 // Initialize toast manager globally 330 if (typeof window.toastManager === 'undefined') { 331 window.toastManager = new ToastManager(); 332 } 333 334 // Global helper functions 335 window.showSuccessToast = function(message, duration) { 336 return window.toastManager.success(message, duration); 337 }; 338 339 window.showErrorToast = function(message, duration) { 340 return window.toastManager.error(message, duration); 341 }; 342 343 window.showWarningToast = function(message, duration) { 344 return window.toastManager.warning(message, duration); 345 }; 346 347 window.showInfoToast = function(message, duration) { 348 return window.toastManager.info(message, duration); 349 }; 350</script>
350 351<!-- Include Django Messages Integration --> 352<!-- Django Messages to Toaster Integration --> 353<!-- Include this AFTER including toaster.html to automatically show Django messages as toasts --> 354 355 356 357<section class="bg-image d-flex align-items-center justify-content-center min-vh-100 px-3 text-color"> 358 <div class="container"> 359 <div class="row align-items-center justify-content-center"> 360 <!-- Left Welcome Text --> 361 <div class="col-12 col-lg-6 mb-5 mb-lg-0 text-center text-lg-start"> 362 <div class="d-flex align-items-center justify-content-center justify-content-lg-start mb-4"> 363 <img src="/static/images/logo.png" alt="EV Logo" height="40" class="logo-img"> 364 </div> 365 <h1 class="fw-semibold text-color fs-60 welcome-title">Welcome to EV Quotes</h1> 366 </div> 367 368 <!-- Right Login Card --> 369 <div class="col-12 col-lg-5"> 370 <div class="login-card"> 371 <h2 class="mb-4 fw-semibold text-color fs-36">Sign In</h2> 372 373 <form method="POST" action="/accounts/login/" novalidate> 374 <input type="hidden" name="csrfmiddlewaretoken" value="HA4teJwBzhQwfiTJI4wyFhDvleF5EHi2bDPfPtDOywWK1acre408WX4IxsGy0ql1"> 375 376 377 <!-- Messages Section --> 378 379 380 381 382 <div class="mb-4"> 383 384 385 386 387 <div id="div_id_username" class="mb-3"> 388 389 390 <label 391 for="id_username" class="form-label requiredField"> 392 Email<span class="asteriskField">*</span> 393 </label> 394 395 396 397 398 399 400 401 402 <input type="email" name="username" class="form-control emailinput" placeholder="Email" maxlength="254" required id="id_username"> 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 </div> 423 424 425 426 </div> 427 428 <div class="mb-1 position-relative"> 429 430 431 432 433 <div id="div_id_password" class="mb-3"> 434 435 436 <label 437 for="id_password" class="form-label requiredField"> 438 Password<span class="asteriskField">*</span> 439 </label> 440 441 442 443 444 445 446 447 448 <input type="password" name="password" class="form-control passwordinput" placeholder="Password" required id="id_password"> 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 </div> 469 470 471 472 </div> 473 474 <div class="d-flex justify-content-end mb-4 w-100"> 475 <a href="/accounts/password-reset/" class="text-decoration-none text-color fs-17">Forgot password?</a> 476 </div> 477 478 <button type="submit" class="btn w-100 py-3 btn-color-blue fw-bold">Sign in</button> 479 480 <div class="text-center mt-3"> 481 <span class="text-color fw-light fs-18">Create an account. </span> 482 <a href="/accounts/register/" 483 class="text-color fs-18 fw-bold text-decoration-none">Sign 484 up here.</a> 485 </div> 486 </form> 487 </div> 488 </div> 489 </div> 490 </div> 491</section> 492 493 494 495
496<script> 497 document.addEventListener('DOMContentLoaded', function () { 498 const togglePassword = document.querySelector('#togglePassword'); 499 const password = document.querySelector('#id_password'); 500 501 if (togglePassword && password) { 502 togglePassword.addEventListener('click', function () { 503 const type = password.getAttribute('type') === 'password' ? 'text' : 'password'; 504 password.setAttribute('type', type); 505 this.querySelector('i').classList.toggle('bi-eye'); 506 this.querySelector('i').classList.toggle('bi-eye-slash'); 507 }); 508 } 509 }); 510</script>
vendor: 1 bytes, line 510
510
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.