1 2 3 4<!DOCTYPE html> 5<html lang="en"> 6 <head> 7 <meta charset="UTF-8" /> 8 <meta name="viewport" content="width=device-width, initial-scale=1" /> 9 10 11 <title>Log in - Tribute.co</title> 12 <meta name="description" content=""> 13 <meta name="google-site-verification" content="2WtY3bhRsjnqyHR1MUoG5EFoyN4kKaTvIXcqskzs-n8" /> 14 15 16 <meta property="og:type" content="website"> 17 <meta property="og:site_name" content="Tribute"/> 18 <meta property="og:locale" content="en_US"/> 19 <meta property="og:url" content="https://www.tribute.co/"/> 20 <meta content="Tribute: Group video maker for special occasions" property="og:title"> 21 <meta content="Looking for a special, meaningful gift? Share your love and appreciation with a video tribute. Easy to create group videos - start a Tribute in 30 seconds!" property="og:description"> 22 <meta content="https://www.tribute.co/static/images/og-tribute.e5a7d9ca559d.png" property="og:image"> 23 <meta name="twitter:card" content="summary_large_image"> 24 <meta name="twitter:site" content="@wetribute"> 25 <meta name="twitter:title" content="Tribute: Group video maker for special occasions"> 26 <meta name="twitter:description" content="Looking for a special, meaningful gift? Share your love and appreciation with a video tribute. Easy to create group videos - start a Tribute in 30 seconds!"> 27 <meta name="twitter:image" content="https://www.tribute.co/static/images/og-tribute.e5a7d9ca559d.png"> 28 29 30 31 32 33 <link rel="canonical" href="https://www.tribute.co/accounts/login/" /> 34 35 36 37 38 39 40 41 42 43<link rel="icon" type="image/png" href="/static/images/60931d1461db6c37b395defc_tribute-favicon.1ef1c724343c.png"> 44<link rel="shortcut icon" href="/static/images/60931d1461db6c37b395defc_tribute-favicon.1ef1c724343c.png" type="image/png"> 45<link rel="apple-touch-icon" href="/static/images/60931d6999c69619c49f51c0_tribute-webclip.535aed6f885f.png" sizes="180x180"> 46<link rel="mask-icon" href="/static/mask-icon.497c67c66cca.svg" color="#ca210e"> 47 48 49<link rel="manifest" href="/site.webmanifest"> 50 51 52 <!-- Fonts --> 53 <link rel="preconnect" href="https://fonts.googleapis.com"> 54 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 55 <link href="https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,[email protected],100..1000&family=Newsreader:ital,opsz,wght@0,6..72,200..800;1,6..72,200..800&display=swap" rel="stylesheet"> 56 57 58 59 60 <!-- CSS --> 61 62 <link rel="stylesheet" href="/static/v3/homepage/homepage.ae3e30c9c4e1.css"> 63 <link rel="stylesheet" href="/static/v3/includes/aurora.c2d4797ed9ee.css"> 64 <link rel="stylesheet" href="/static/v3/account/account.589cffaeb352.css"> 65 <link rel="stylesheet" href="/static/v3/shared/glass-surfaces.b1e58450e0cc.css"> 66 67 68 <!-- Analytics --> 69 70 71<meta data-name="view" content="account" /> 72<meta data-name="pageType" content="Account" /> 73<meta data-name="userType" content="public" /> 74 75 76 77 78 79 80 81 82
83<script> 84 dataLayer = [ 85 86 ]; 87</script>
vendor: 68 bytes, lines 87-92
87 88 89 90 91 92<script async src="https://www.googletagmanager.com/gtag/js?id=
92G-YWJRZQMLTQ
vendor: 12 bytes, line 92
92"></script>
93<script> 94 window.dataLayer = window.dataLayer || []; 95 function gtag() { dataLayer.push(arguments); } 96 gtag('js', new Date()); 97</script>
97 98 99
100<script> 101 !function(t,e){var o,n,p,r;e.__SV||(window.posthog && window.posthog.__loaded)||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}p||((p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",p.onerror=function(){p=null},(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r));var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],Object.defineProperty(u,"toString",{configurable:!0,enumerable:!0,writable:!0,value:function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e}}),Object.defineProperty(u.people,"toString",{configurable:!0,enumerable:!0,writable:!0,value:function(){return u.toString(1)+".people (stub)"}}),o="Tl Ml El Il Al init Xl tu Jl Kl nu ho Yl au Gl capture getExtension eu xl vu calculateEventProperties du register register_once register_for_session unregister unregister_for_session gu Ql cu getFeatureFlag getFeatureFlagPayload getFeatureFlagResult getAllFeatureFlags isFeatureEnabled reloadFeatureFlags updateFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSurveysLoaded onSessionId getSurveys getActiveMatchingSurveys renderSurvey displaySurvey cancelPendingSurvey canRenderSurvey canRenderSurveyAsync mu identify setPersonProperties unsetPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset yu shutdown setIdentity clearIdentity get_distinct_id getGroups get_session_id get_session_replay_url alias set_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException addExceptionStep captureLog startExceptionAutocapture stopExceptionAutocapture loadToolbar get_property getSessionProperty fu uu createPersonProfile setInternalOrTestUser pu Fl Ol opt_in_capturing opt_out_capturing has_opted_in_capturing has_opted_out_capturing get_explicit_consent_status is_capturing clear_opt_in_out_capturing ou debug do ts getPageViewId captureTraceFeedback captureTraceMetric zl".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]); 102 /* 103 * Noise filter for PostHog error tracking (shared logic with 104 * tribute/v3/src/analytics/TrackingScripts.ts â update both together). 105 * 106 * These exceptions are not bugs in our code and there is nothing to fix in ours: 107 * 108 * 1. "Object Not Found Matching Id:5, MethodName:simulateEvent, ParamCount:1" 109 * Microsoft Outlook / Office "Safe Links" scanners open our pages when someone gets an 110 * email link. They inject their own script, which rejects promises with this string. 111 * One scanner visit fires dozens of them. 112 * 113 * 2. "ResizeObserver loop completed with undelivered notifications." (and the older 114 * "ResizeObserver loop limit exceeded"). The browser reports that a ResizeObserver 115 * callback changed layout, so delivery moved to the next frame. Nothing breaks, no 116 * stack trace comes with it, and both our code and third-party widgets raise it. 117 * 118 * 3. Browser extensions with an injected message bus (nuanria_messaging, anything on 119 * chrome-extension://). Their errors carry our page as the origin. 120 */ 121 window.tributeExceptionNoisePatterns = [ 122 /Object Not Found Matching Id:\s*\d+/i, 123 /ResizeObserver loop (completed with undelivered notifications|limit exceeded)/i, 124 /nuanria_messaging|chrome-extension:\/\//i 125 ]; 126 /* 127 * Our own lazy-chunk failures word themselves like third-party ones, so error tracking 128 * grouped them into a single generic TypeError issue with Shopify, OptiMonk and extension 129 * errors, and the first-party problem became invisible in triage. Give ours their own 130 * issue. Chrome and Firefox name the URL; Safari says only "Importing a module script 131 * failed.", so rule out the third parties that share our pages instead. 132 */ 133 window.tributeIsFirstPartyChunkFailure = function (text) { 134 if (!/failed to fetch dynamically imported module|error loading dynamically imported module|importing a module script failed/i.test(text)) { 135 return false;
136 } 137 if (/\/static\/v3\/dist\//.test(text)) return true; 138 return !/store\.tribute\.co|shopify|optimonk|chrome-extension:\/\//i.test(text); 139 }; 140 window.tributeExceptionText = function (captureResult) { 141 var props = captureResult.properties || {}; 142 var text = String(props.$exception_message || ''); 143 var list = props.$exception_list || []; 144 for (var i = 0; i < list.length; i++) { 145 var item = list[i] || {}; 146 text += ' ' + String(item.value || '') + ' ' + String(item.type || ''); 147 } 148 return text; 149 }; 150 window.tributeIsNoiseException = function (captureResult) { 151 try { 152 if (!captureResult || captureResult.event !== '$exception') return false; 153 var text = window.tributeExceptionText(captureResult); 154 return window.tributeExceptionNoisePatterns.some(function (pattern) { 155 return pattern.test(text); 156 }); 157 } catch (e) { 158 return false; 159 } 160 }; 161 /* 162 * Chunk failures have two unrelated causes that read identically: a deploy took the 163 * chunk away from a tab that was already open, and a fetch that failed while the chunk 164 * was being served normally. StaleBuildRecovery decides which and appends its verdict 165 * to the source it reports, so keep the causes in separate issues. Only the five known 166 * verdicts get their own, so a future source string cannot open an unbounded number. 167 * 168 * Keep in sync with chunkFailureFingerprint in 169 * tribute/v3/src/analytics/TrackingScripts.ts. 170 */ 171 window.tributeChunkFailureFingerprint = function (source) { 172 var diagnosis = typeof source === 'string' ? source.split(':').pop() : ''; 173 return ['stale-build', 'stale-entry', 'offline', 'available', 'unknown'].indexOf(diagnosis) !== -1 174 ? 'v3-chunk-load-failure-' + diagnosis 175 : 'v3-chunk-load-failure'; 176 }; 177 window.tributeGroupChunkFailures = function (captureResult) { 178 try { 179 if (!captureResult || captureResult.event !== '$exception') return; 180 if (!window.tributeIsFirstPartyChunkFailure(window.tributeExceptionText(captureResult))) return; 181 captureResult.properties = captureResult.properties || {}; 182 captureResult.properties.$exception_fingerprint = 183 window.tributeChunkFailureFingerprint(captureResult.properties.tribute_error_source); 184 } catch (e) { 185 /* Never lose an event because the grouping hint failed */ 186 } 187 }; 188 posthog.init('phc_bGxnTTiLMHCPS1pr4JL75aTCC5j1FYC28jboWWQDutU', { 189 api_host: 'https://p.tribute.co', 190 ui_host: 'https://us.posthog.com', 191 defaults: '2026-05-30', 192 person_profiles: 'identified_only', 193 autocapture: false, 194 /* Manual $pageview so we can attach view / page_type / user_type from meta tags */ 195 capture_pageview: false, 196 opt_in_site_apps: true, 197 before_send: function (captureResult) { 198 if (window.tributeIsNoiseException(captureResult)) return null; 199 window.tributeGroupChunkFailures(captureResult); 200 return captureResult; 201 }, 202 loaded: function (posthog) { 203 try { 204 var vm = document.querySelector('meta[data-name="view"]'); 205 var v = vm && vm.getAttribute('content'); 206 var m = document.querySelector('meta[data-name="pageType"]'); 207 var pt = m && m.getAttribute('content'); 208 var um = document.querySelector('meta[data-name="userType"]'); 209 var ut = um && um.getAttribute('content'); 210 var props = { user_type: ut || 'public' }; 211 if (v) props.view = v; 212 if (pt) props.page_type = pt; 213 if (typeof posthog.register === 'function') posthog.register(props); 214 posthog.capture('$pageview', props); 215 } catch (e) {} 216 } 217 }) 218</script>
218 219 220
221<script type="text/javascript"> 222 (function (c, l, a, r, i, t, y) { 223 c[a] = c[a] || function () { (c[a].q = c[a].q || []).push(arguments) }; 224 t = l.createElement(r); t.async = 1; t.src = "https://www.clarity.ms/tag/" + i; 225 y = l.getElementsByTagName(r)[0]; y.parentNode.insertBefore(t, y); 226 227 })(window, document, "clarity", "script", "ic398qfzu9"); 228</script>
228 229 230
231<script 232 src="https://cdn.growify.ai/pixel.min.js" 233 data-website-id="016de0488d3e1eb736764c468f882dea:16cb25b31bda0218c48c11fb5265b98951410279ae20a26b381389664e198a725b51087a6e4127ab35480d999d8ee4c2" 234 data-endpoint="api_v2" 235 data-platform="web" 236 data-external-site="true" 237></script>
237 238 239 240 241 242 243 244 245 246 247 248 249<div id="fb-root"></div>
250<script id="allauth-facebook-settings" type="application/json">{"appId": "291721287847610", "version": "v5.0", "sdkUrl": "//connect.facebook.net/en_US/sdk.js", "initParams": {"appId": "291721287847610", "version": "v5.0"}, "loginOptions": {"scope": "email"}, "loginByTokenUrl": "https://www.tribute.co/accounts/facebook/login/token/", "cancelUrl": "https://www.tribute.co/accounts/3rdparty/login/cancelled/", "logoutUrl": "https://www.tribute.co/accounts/logout/", "loginUrl": "https://www.tribute.co/accounts/facebook/login/", "errorUrl": "https://www.tribute.co/accounts/3rdparty/login/error/", "csrfToken": "2X5RRxjstyPa1wptPtbOJKDgQdRRjjyqSYCxs8vQYG8XYHqZRsGiAfuKxxfcTjK6"}</script>
vendor: 1 bytes, line 250
250
251<script type="text/javascript" src="/static/facebook/js/fbconnect.f7d3f8c2d23e.js"></script>
251 252 253 254 255 </head> 256 <body class="account-page"> 257 258 259 260<div id="tribute-consent-banner" class="tribute-consent-banner" role="dialog" aria-label="Cookie consent" aria-describedby="consent-banner-text" style="display: none;" data-cf-country="US"> 261 <div class="tribute-consent-banner-inner"> 262 <p id="consent-banner-text" class="tribute-consent-banner-text"> 263 We use cookies and similar technologies to improve your experience and for advertising purposes. 264 By clicking "Accept", you consent to our use of cookies. You can change your preferences at any time in our 265 266 <a href="/privacy/" class="tribute-consent-link">Privacy Policy</a>. 267 </p> 268 <div class="tribute-consent-banner-actions"> 269 <button type="button" id="tribute-consent-accept" class="tribute-consent-btn tribute-consent-accept">Accept</button> 270 <button type="button" id="tribute-consent-reject" class="tribute-consent-btn tribute-consent-reject">Reject</button> 271 </div> 272 </div> 273</div> 274 275<style> 276.tribute-consent-banner { 277 position: fixed; 278 bottom: 0; 279 left: 0; 280 right: 0; 281 z-index: 9999; 282 background: #1f2937; 283 color: #f9fafb; 284 padding: 1rem 1.5rem; 285 box-shadow: 0 -4px 20px rgba(0,0,0,0.2); 286 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; 287} 288.tribute-consent-banner-inner { 289 max-width: 1120px; 290 margin: 0 auto; 291 display: flex; 292 flex-wrap: wrap; 293 align-items: center; 294 gap: 1rem; 295 justify-content: space-between; 296} 297.tribute-consent-banner-text { 298 margin: 0; 299 font-size: 0.875rem; 300 line-height: 1.5; 301 flex: 1; 302 min-width: 200px; 303} 304.tribute-consent-link { 305 color: #93c5fd; 306 text-decoration: underline; 307} 308.tribute-consent-banner-actions { 309 display: flex; 310 gap: 0.75rem; 311 flex-shrink: 0; 312} 313.tribute-consent-btn { 314 padding: 0.5rem 1rem; 315 border: none; 316 border-radius: 0.375rem; 317 font-size: 0.875rem; 318 font-weight: 500; 319 cursor: pointer; 320} 321.tribute-consent-accept { 322 background: #c71f0d; 323 color: white; 324} 325.tribute-consent-accept:hover { 326 background: #a01808; 327} 328.tribute-consent-reject { 329 background: rgba(255,255,255,0.15); 330 color: #f9fafb; 331} 332.tribute-consent-reject:hover { 333 background: rgba(255,255,255,0.25); 334} 335</style> 336
337<script> 338(function() { 339 var COOKIE_NAME = 'tribute_consent'; 340 var COOKIE_MAX_AGE = 365 * 24 * 60 * 60; // 1 year 341 342 var EEA_COUNTRIES = ['AT','BE','BG','HR','CY','CZ','DK','EE','FI','FR','DE','GR','HU','IE','IT','LV','LT','LU','MT','NL','PL','PT','RO','SK','SI','ES','SE','GB','CH','NO','IS','LI']; 343 344 function getCookie(name) { 345 var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)')); 346 return match ? match[2] : null; 347 } 348 349 function setCookie(name, value, maxAge) { 350 document.cookie = name + '=' + value + ';path=/;max-age=' + maxAge + ';SameSite=Lax'; 351 } 352 353 function setUETConsent(granted) { 354 window.uetq = window.uetq || []; 355 window.uetq.push('consent', 'update', { 'ad_storage': granted ? 'granted' : 'denied' }); 356 } 357 358 function setUETConsentDefault(denied) { 359 window.uetq = window.uetq || []; 360 window.uetq.push('consent', 'default', { 'ad_storage': denied ? 'denied' : 'granted' }); 361 } 362 363 function loadUET() { 364 if (window._tributeUETLoaded) return; 365 window._tributeUETLoaded = true; 366 var w = window, d = document, t = 'script', u = 'uetq', o = { ti: '187239820', enableAutoSpaTracking: true, ts: (new Date()).getTime() }; 367 var n = d.createElement(t); 368 n.src = 'https://bat.bing.net/bat.js?ti=' + o.ti; 369 n.async = 1; 370 n.onload = n.onreadystatechange = function() { 371 var s = this.readyState; 372 if (!s || s === 'loaded' || s === 'complete') { 373 n.onload = n.onreadystatechange = null; 374 /* 375 * bat.js can load and still leave no UET constructor behind (a content blocker 376 * answering with an empty body, a proxy, a truncated response). The old fallback, 377 * `new (w.UET || function(){})(o)`, built an object with no push, so the next line 378 * threw anyway. Bail out instead and leave window.uetq the plain array it was, so 379 * consent updates keep queueing. 380 * 381 * Keep in sync with activateUetTag in tribute/v3/src/analytics/TrackingScripts.ts. 382 */ 383 if (typeof w.UET !== 'function') return; 384 try { 385 o.q = w[u]; 386 w[u] = new w.UET(o); 387 w[u].push('pageLoad'); 388 } catch (e) { 389 /* A UET constructor that throws is Microsoft's to fix, not ours to report. */ 390 } 391 } 392 }; 393 var i = d.getElementsByTagName(t)[0]; 394 i.parentNode.insertBefore(n, i); 395 } 396 397 function showBanner() { 398 var banner = document.getElementById('tribute-consent-banner'); 399 if (banner) banner.style.display = 'block'; 400 } 401 402 function hideBanner() { 403 var banner = document.getElementById('tribute-consent-banner'); 404 if (banner) banner.style.display = 'none'; 405 } 406 407 function onAccept() { 408 setCookie(COOKIE_NAME, 'accept', COOKIE_MAX_AGE); 409 setUETConsent(true); 410 loadUET(); 411 hideBanner(); 412 } 413 414 function onReject() { 415 setCookie(COOKIE_NAME, 'reject', COOKIE_MAX_AGE); 416 setUETConsent(false); 417 hideBanner(); 418 } 419 420 function handleCountry(country) { 421 var isEEA = EEA_COUNTRIES.indexOf(country) !== -1; 422 if (isEEA) { 423 setUETConsentDefault(true); 424 showBanner(); 425 } else { 426 setUETConsent(true); 427 loadUET(); 428 } 429 } 430 431 function getCountryFromAPI() { 432 var cached = null; 433 try { cached = sessionStorage.getItem('tribute_geo_country'); } catch(e) {} 434 if (cached) { 435 handleCountry(cached); 436 return; 437 } 438 439 fetch('https://ipapi.co/json/') 440 .then(function(r) { return r.json(); }) 441 .then(function(data) { 442 var country = (data.country_code || '').toUpperCase(); 443 try { sessionStorage.setItem('tribute_geo_country', country); } catch(e) {} 444 handleCountry(country); 445 }) 446 .catch(function() { 447 setUETConsent(true); 448 loadUET(); 449 }); 450 } 451 452 function init() { 453 window.uetq = window.uetq || []; 454 var existing = getCookie(COOKIE_NAME); 455 456 if (existing === 'accept') { 457 setUETConsent(true); 458 loadUET(); 459 return; 460 } 461 if (existing === 'reject') { 462 setUETConsent(false); 463 return; 464 } 465 466 var banner = document.getElementById('tribute-consent-banner'); 467 var cfCountry = banner ? (banner.getAttribute('data-cf-country') || '').toUpperCase() : ''; 468 469 if (cfCountry) { 470 handleCountry(cfCountry); 471 } else { 472 getCountryFromAPI(); 473 } 474 } 475 476 document.addEventListener('DOMContentLoaded', function() { 477 var acceptBtn = document.getElementById('tribute-consent-accept'); 478 var rejectBtn = document.getElementById('tribute-consent-reject'); 479 if (acceptBtn) acceptBtn.addEventListener('click', onAccept); 480 if (rejectBtn) rejectBtn.addEventListener('click', onReject); 481 }); 482 483 if (document.readyState === 'loading') { 484 document.addEventListener('DOMContentLoaded', init); 485 } else { 486 init(); 487 } 488})(); 489</script>
489 490 491 492 493 494 <div class="v3-aurora" aria-hidden="true"> 495 <span class="v3-aurora__blob v3-aurora__blob--1"></span> 496 <span class="v3-aurora__blob v3-aurora__blob--2"></span> 497 <span class="v3-aurora__blob v3-aurora__blob--3"></span> 498 <span class="v3-aurora__blob v3-aurora__blob--4"></span> 499 <span class="v3-aurora__blob v3-aurora__blob--5"></span> 500 <span class="v3-aurora__blob v3-aurora__blob--6"></span> 501 </div> 502 503 504 505 <div class="account-topbar"> 506 <a href="/" aria-label="Tribute home"> 507 <img src="/static/v3/images/tribute/tribute-logo-light.60a9f907bddc.svg" alt="Tribute"> 508 </a> 509 </div> 510 511 512 513 514 <main class="account-main account-main--centered"> 515 516 <div class="account-card account-card--auth"> 517 <h1 class="account-title">Welcome back</h1> 518 <p class="account-subtitle">Log in to manage your Tributes.</p> 519 520 521 522 523 524 525 526<div class="account-social"> 527 <a id="login-continue-with-google" class="account-btn account-btn--social" href="/accounts/google/login/"> 528 <img src="/static/images/google_login_logo.181214770223.svg" alt=""> 529 Continue with Google 530 </a> 531 532 <a id="login-continue-with-facebook" class="account-btn account-btn--social" href="javascript:allauth.facebook.login%28%27%27%2C%20%27authenticate%27%2C%20%27login%27%2C%20%27%27%29"> 533 <img src="/static/images/facebook_login_logo.ed783345ed1d.svg" alt=""> 534 Continue with Facebook 535 </a> 536 537</div> 538 539 540 <div class="account-divider"><span>or continue with email</span></div> 541 542 <form method="POST" action="/accounts/login/" class="account-form" novalidate> 543 <input type="hidden" name="csrfmiddlewaretoken" value="GsGZqnJrP3fqd8OP3uNvCSZ2Oy2tLQ9UwtdF1YVPkbydajPl5tiZtnQwvSqOlQlA"> 544 545 546 547 548 549 550<div class="account-field"> 551 <label for="id_login">Email</label> 552 553 <input type="email" name="login" placeholder="[email protected]" autocomplete="email" maxlength="320" required id="id_login"> 554 555 <p class="account-error" id="id_login-error"></p> 556</div> 557 558 559 560 561 562<div class="account-field"> 563 564 <div class="account-field-head"> 565 <label for="id_password">Password</label> 566 <a class="account-link" href="/accounts/password/reset/">Forgot password?</a> 567 </div> 568 569 <div class="account-password"> 570 571 <input type="password" name="password" placeholder="Your password" autocomplete="current-password" required id="id_password"> 572 573 <button type="button" class="account-password-toggle" aria-label="Show password" aria-pressed="false"> 574 <svg class="icon-show" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg> 575 <svg class="icon-hide" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg> 576 </button> 577 </div> 578 <p class="account-error" id="id_password-error"></p> 579</div> 580 581 582 <button type="submit" class="account-btn account-btn--primary account-btn--block">Log In</button> 583 </form> 584 585 <p class="account-switch"> 586 New to Tribute?<a class="account-link" href="/accounts/signup/">Create an account</a> 587 </p> 588 589 </div> 590 591 <p class="account-legal"> 592 By continuing you agree to our <a href="/termsofservice/">Terms of Service</a> and <a href="/privacy/">Privacy Policy</a>. 593 </p> 594 595 </main> 596 597 598 599 <footer class="account-footer"> 600 <span>© 2026 Tribute</span> 601 <a href="/termsofservice/">Terms of Service</a> 602 <a href="/privacy/">Privacy Policy</a> 603 <a href="mailto:[email protected]">[email protected]</a> 604 </footer> 605 606 607 608 <!-- Javascript --> 609 610 611 612
613<script type="text/javascript"> 614 615 window.video_editor_static_url = "/static/editor/video-editor.8d5d60ff1962.js"; 616 617 618 var isTribeLeader = false; 619 620 621 function stringToBoolean(value){ 622 return value.toLowerCase().trim() === "true"; 623 } 624 625 626 var user = { 627 'is_authenticated': false 628 }; 629 630 window.marketplace_enabled = stringToBoolean(""); 631 632 633</script>
633 634 635 636 637 <!-- Preserve UTM parameters on start page links --> 638
638<script> 639 (function () { 640 // TODO(attribution-rollout): Remove UTM/promo copying from Start links after 641 // server-side attribution is verified in production. Preserve affiliate behavior 642 // until it has its own replacement. See docs/purchase-attribution.md. 643 const PRESERVE_PARAMS = ['utm_campaign', 'utm_source', 'utm_medium', 'promo_code', 'affiliate_id'] 644 const current = new URLSearchParams(window.location.search) 645 const preserve = new URLSearchParams() 646 647 PRESERVE_PARAMS.forEach(param => { 648 if (current.has(param)) { 649 preserve.set(param, current.get(param)) 650 } 651 }) 652 653 if (!Array.from(preserve.keys()).length) return 654 655 function appendParams(link) { 656 const url = new URL(link.getAttribute('href'), window.location.href) 657 658 if (!url.pathname.startsWith('/start')) return 659 660 preserve.forEach((value, key) => { 661 if (!url.searchParams.has(key)) { 662 url.searchParams.set(key, value) 663 } 664 }) 665 666 link.href = url.toString() 667 } 668 669 document.addEventListener('DOMContentLoaded', () => { 670 document.querySelectorAll('a[href*="/start"]').forEach(appendParams) 671 }) 672 })() 673 </script>
673 674 675 676 677
677<script> 678 (function () { 679 // Show / hide password. One button per field, sits inside .account-password. 680 document.querySelectorAll('.account-password-toggle').forEach(function (btn) { 681 var input = btn.parentElement.querySelector('input'); 682 if (!input) return; 683 btn.addEventListener('click', function () { 684 var show = input.type === 'password'; 685 input.type = show ? 'text' : 'password'; 686 btn.setAttribute('aria-pressed', show ? 'true' : 'false'); 687 btn.setAttribute('aria-label', show ? 'Hide password' : 'Show password'); 688 input.focus({ preventScroll: true }); 689 }); 690 }); 691 692 // Avatars: uploaded photo first (data-avatar-url), else the emoji 693 // derived from the email. Same mapping as v3/base.html and 694 // tribute/v3/src/lib/EmojiAvatar.ts â keep them in step. 695 function emojiAvatarPath(email) { 696 var letter = email.charAt(email.length > 1 ? 1 : 0).toUpperCase(); 697 var code = letter.charCodeAt(0); 698 var n = (code < 65 || code > 90) ? 1 : Math.min(Math.floor((code - 65) / 2) + 1, 12); 699 return '/static/v3/images/emojis/emoji' + n + '.svg'; 700 } 701 window.tributeEmojiAvatarPath = emojiAvatarPath; 702 document.querySelectorAll('img[data-email]').forEach(function (img) { 703 var avatarUrl = img.getAttribute('data-avatar-url'); 704 var email = img.getAttribute('data-email'); 705 if (avatarUrl) { 706 img.src = avatarUrl; 707 } else if (email) { 708 img.src = emojiAvatarPath(email); 709 } 710 }); 711 })(); 712 </script>
712 713 714 715 716 717 718 <!-- Avatar initialization (for v3 nav) --> 719
719<script> 720 // Emoji avatar logic from v3 721 function getEmojiAvatar(email) { 722 if (!email || typeof email !== 'string') { 723 return 'emoji1'; // Default fallback 724 } 725 726 // Use second letter if available, otherwise fall back to first letter 727 const letterIndex = email.length > 1 ? 1 : 0; 728 const letter = email.charAt(letterIndex).toUpperCase(); 729 const charCode = letter.charCodeAt(0); 730 731 // A = 65, Z = 90 732 if (charCode < 65 || charCode > 90) { 733 return 'emoji1'; // Default for non-letters 734 } 735 736 // Map A-Z to 1-12 emojis 737 const emojiIndex = Math.floor((charCode - 65) / 2) + 1; 738 return `emoji${Math.min(emojiIndex, 12)}`; 739 } 740 741 function getEmojiAvatarPath(email) { 742 const emojiName = getEmojiAvatar(email); 743 return `/static/v3/images/emojis/${emojiName}.svg`; 744 } 745 746 // Initialize avatars 747 function initAvatars() { 748 // Set avatar for dropdown 749 const dropdownAvatar = document.querySelector('.dropdown-user-avatar'); 750 if (dropdownAvatar) { 751 // Uploaded photo first (UserProfile.avatar), emoji otherwise. 752 const avatarUrl = dropdownAvatar.getAttribute('data-avatar-url'); 753 const email = dropdownAvatar.getAttribute('data-email'); 754 if (avatarUrl) { 755 dropdownAvatar.src = avatarUrl; 756 } else if (email) { 757 dropdownAvatar.src = getEmojiAvatarPath(email); 758 } 759 } 760 } 761 762 // Initialize on page load 763 if (document.readyState === 'loading') { 764 document.addEventListener('DOMContentLoaded', initAvatars); 765 } else { 766 initAvatars(); 767 } 768 </script>
768 769 770 771 772<div id="support-widget" class="support-widget"> 773 <button id="support-widget-fab" class="support-widget-fab" aria-label="Support" title="Support"> 774 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> 775 <path d="M3 7.8C3 6.11984 3 5.27976 3.32698 4.63803C3.6146 4.07354 4.07354 3.6146 4.63803 3.32698C5.27976 3 6.11984 3 7.8 3H16.2C17.8802 3 18.7202 3 19.362 3.32698C19.9265 3.6146 20.3854 4.07354 20.673 4.63803C21 5.27976 21 6.11984 21 7.8V13.2C21 14.8802 21 15.7202 20.673 16.362C20.3854 16.9265 19.9265 17.3854 19.362 17.673C18.7202 18 17.8802 18 16.2 18H9.68375C9.0597 18 8.74767 18 8.44921 18.0613C8.18443 18.1156 7.9282 18.2055 7.68749 18.3285C7.41617 18.4671 7.17252 18.662 6.68521 19.0518L4.29976 20.9602C3.88367 21.2931 3.67563 21.4595 3.50054 21.4597C3.34827 21.4599 3.20422 21.3906 3.10923 21.2716C3 21.1348 3 20.8684 3 20.3355V7.8Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> 776 </svg> 777 </button> 778 <div id="support-widget-popup" class="support-widget-popup" hidden> 779 <div class="support-widget-popup-header"> 780 <span class="support-widget-title-row"> 781 <span>Support</span> 782 <span id="support-widget-badge" class="support-widget-badge"></span> 783 </span> 784 <button id="support-widget-close" class="support-widget-close" aria-label="Close">×</button> 785 </div> 786 <div class="support-widget-popup-body"> 787 <p class="support-widget-availability">Our support team is available:</p> 788 <p class="support-widget-days"><strong>Mon</strong> 11:00 AM â 9:00 PM ET</p> 789 <p class="support-widget-days"><strong>Tue â Fri</strong> 11:00 AM â 10:00 PM ET</p> 790 <p class="support-widget-days"><strong>Sat</strong> 12:00 PM â 8:00 PM ET</p> 791 <p class="support-widget-days" style="margin-bottom: 12px"><strong>Sun</strong> 12:00 PM â 5:00 PM ET</p> 792 <a href="mailto:[email protected]" class="support-widget-email-btn">Email [email protected]</a> 793 </div> 794 </div> 795</div> 796 797<style> 798.support-widget { 799 position: fixed; 800 bottom: 24px; 801 right: 24px; 802 z-index: 9999; 803 font-family: 'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; 804} 805 806.support-widget-fab { 807 width: 56px; 808 height: 56px; 809 border-radius: 50%; 810 border: none; 811 background-color: #0B1222; 812 color: #fff; 813 cursor: pointer; 814 display: flex; 815 align-items: center; 816 justify-content: center; 817 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25); 818 transition: transform 0.2s, box-shadow 0.2s; 819} 820 821.support-widget-fab:hover { 822 transform: scale(1.05); 823 box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25); 824} 825 826.support-widget-fab.light-bg { 827 background-color: #ffffff; 828 color: #0B1222; 829 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); 830} 831 832.support-widget-fab.light-bg:hover { 833 box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15); 834} 835 836.support-widget-fab svg { 837 width: 24px; 838 height: 24px; 839} 840 841.support-widget-popup { 842 position: absolute; 843 bottom: calc(100% + 12px); 844 right: 0; 845 width: 288px; 846 background: #fff; 847 border-radius: 12px; 848 box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); 849 overflow: hidden; 850} 851 852.support-widget-popup[hidden] { 853 display: none !important; 854} 855 856.support-widget-popup-header { 857 background-color: #0B1222; 858 color: #fff; 859 padding: 12px 16px; 860 display: flex; 861 align-items: center; 862 justify-content: space-between; 863 font-weight: 600; 864 font-size: 15px; 865} 866 867.support-widget-title-row { 868 display: flex; 869 align-items: center; 870 gap: 8px; 871} 872 873.support-widget-close { 874 background: none; 875 border: none; 876 color: #fff; 877 font-size: 20px; 878 line-height: 1; 879 cursor: pointer; 880 padding: 0; 881 opacity: 0.9; 882} 883 884.support-widget-close:hover { 885 opacity: 1; 886} 887 888.support-widget-popup-body { 889 padding: 16px; 890} 891 892.support-widget-availability { 893 margin: 0 0 8px; 894 font-size: 14px; 895 color: #475569; 896} 897 898.support-widget-days { 899 margin: 0 0 4px; 900 font-size: 14px; 901 color: #0f172a; 902} 903 904.support-widget-hours { 905 margin: 0 0 12px; 906 font-size: 14px; 907 color: #64748b; 908} 909 910.support-widget-badge { 911 display: inline-block; 912 padding: 4px 10px; 913 border-radius: 9999px; 914 font-size: 12px; 915 font-weight: 600; 916} 917 918.support-widget-badge.open { 919 background-color: #dcfce7; 920 color: #166534; 921} 922 923.support-widget-badge.closed { 924 background-color: #fee2e2; 925 color: #991b1b; 926} 927 928.support-widget-email-btn { 929 display: block; 930 width: 100%; 931 padding: 12px 16px; 932 background-color: #fff; 933 color: #0B1222 !important; 934 text-align: center; 935 font-weight: 600; 936 font-size: 14px; 937 border-radius: 8px; 938 text-decoration: none; 939 border: 1px solid #e2e8f0; 940 cursor: pointer; 941 transition: background-color 0.2s, border-color 0.2s; 942} 943 944.support-widget-email-btn:hover { 945 background-color: #f8fafc; 946 border-color: #cbd5e1; 947 color: #0B1222 !important; 948} 949 950</style> 951
952<script> 953(function() { 954 function isSupportOpen() { 955 var now = new Date(); 956 var etHour = parseInt(now.toLocaleString('en-US', { timeZone: 'America/New_York', hour: 'numeric', hour12: false }), 10); 957 var etMinute = parseInt(now.toLocaleString('en-US', { timeZone: 'America/New_York', minute: 'numeric' }), 10); 958 var etWeekday = now.toLocaleString('en-US', { timeZone: 'America/New_York', weekday: 'short' }); 959 var minutesSinceMidnight = etHour * 60 + etMinute; 960 var schedule = { 961 Mon: [11 * 60, 21 * 60], 962 Tue: [11 * 60, 22 * 60], 963 Wed: [11 * 60, 22 * 60], 964 Thu: [11 * 60, 22 * 60], 965 Fri: [11 * 60, 22 * 60], 966 Sat: [12 * 60, 20 * 60], 967 Sun: [12 * 60, 17 * 60] 968 }; 969 var hours = schedule[etWeekday]; 970 if (!hours) return false; 971 return minutesSinceMidnight >= hours[0] && minutesSinceMidnight < hours[1]; 972 } 973 974 function initSupportWidget() { 975 var widget = document.getElementById('support-widget'); 976 var fab = document.getElementById('support-widget-fab'); 977 var popup = document.getElementById('support-widget-popup'); 978 var closeBtn = document.getElementById('support-widget-close'); 979 var badge = document.getElementById('support-widget-badge'); 980 981 if (!widget || !fab || !popup) return; 982 983 function updateBadge() { 984 if (badge) { 985 var open = isSupportOpen(); 986 badge.textContent = open ? 'Open' : 'Closed'; 987 badge.className = 'support-widget-badge ' + (open ? 'open' : 'closed'); 988 } 989 } 990 991 function togglePopup() { 992 var isHidden = popup.hasAttribute('hidden'); 993 if (isHidden) { 994 popup.removeAttribute('hidden'); 995 updateBadge(); 996 } else { 997 popup.setAttribute('hidden', ''); 998 } 999 } 1000 1001 function closePopup() { 1002 popup.setAttribute('hidden', ''); 1003 } 1004 1005 fab.addEventListener('click', togglePopup); 1006 if (closeBtn) closeBtn.addEventListener('click', closePopup); 1007 1008 document.addEventListener('click', function(e) { 1009 if (popup.hasAttribute('hidden')) return; 1010 if (!widget.contains(e.target)) { 1011 closePopup(); 1012 } 1013 }); 1014 } 1015 1016 if (document.readyState === 'loading') { 1017 document.addEventListener('DOMContentLoaded', initSupportWidget); 1018 } else { 1019 initSupportWidget(); 1020 } 1021})(); 1022</script>
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
1034<script> 1035 gtag("config", "G\u002DYWJRZQMLTQ"); 1036 1037 1038 1039 // Get the client_id in case we need to pass it to the backend 1040 gtag("get", "G\u002DYWJRZQMLTQ", "client_id", (client_id) => { 1041 window.tribute_ga4_client_id = client_id; 1042 }); 1043 1044 // Login and signup events 1045 if (document.referrer.indexOf("/accounts/signup/") >= 0) { 1046 gtag("event", "sign_up"); 1047 }; 1048 1049 if (document.referrer.indexOf("/accounts/login/") >= 0) { 1050 gtag("event", "login"); 1051 }; 1052 </script>
1052 1053 1054 1055
1055<script type="text/javascript"> 1056 var _cio = _cio || []; 1057 (function () { 1058 var a, b, c; a = function (f) { 1059 return function () { 1060 _cio.push([f]. 1061 concat(Array.prototype.slice.call(arguments, 0))) 1062 }; 1063 }; b = ["load", "identify", 1064 "sidentify", "track", "page", "on", "off"]; for (c = 0; c < b.length; c++) { _cio[b[c]] = a(b[c]) }; 1065 var t = document.createElement("script"), 1066 s = document.getElementsByTagName("script")[0]; 1067 t.async = true; 1068 t.id = "cio-tracker"; 1069 t.setAttribute("data-site-id", "7bd678b3e5fb4bc5ea3f"); 1070 t.setAttribute("data-use-array-params", "true"); 1071 t.setAttribute("data-use-in-app", "false"); 1072 t.setAttribute("data-auto-track-page", "false"); 1073 t.setAttribute("data-cross-site-support", "true"); 1074 t.src = "https://assets.customer.io/assets/track.js"; 1075 s.parentNode.insertBefore(t, s); 1076 })(); 1077 </script>
1077 1078 1079 1080
1080<script> 1081 !function (f, b, e, v, n, t, s) { 1082 if (f.fbq) return; n = f.fbq = function () { 1083 n.callMethod ? 1084 n.callMethod.apply(n, arguments) : n.queue.push(arguments) 1085 }; 1086 if (!f._fbq) f._fbq = n; n.push = n; n.loaded = !0; n.version = "2.0"; 1087 n.queue = []; t = b.createElement(e); t.async = !0; 1088 t.src = v; s = b.getElementsByTagName(e)[0]; 1089 s.parentNode.insertBefore(t, s) 1090 }(window, document, "script", 1091 "https://connect.facebook.net/en_US/fbevents.js"); 1092 1093 // Only initialize once to prevent duplicate pixel warnings 1094 if (!window._fbPixelInitialized) { 1095 1096 fbq("init", "913958168690957"); 1097 1098 window._fbPixelInitialized = true; 1099 } 1100 fbq("track", "PageView"); 1101 </script>
1101 1102 1103 1104 1105
1105<script> 1106 (function (e) { 1107 if (!window.pintrk) { 1108 window.pintrk = function () { 1109 window.pintrk.queue.push(Array.prototype.slice.call(arguments)); 1110 }; 1111 var n = window.pintrk; n.queue = [], n.version = "3.0"; var t = document.createElement("script"); 1112 t.async = true; t.src = e; var r = document.getElementsByTagName("script")[0]; 1113 r.parentNode.insertBefore(t, r); 1114 } 1115 })("https://s.pinimg.com/ct/core.js"); 1116 1117 1118 pintrk("load", "2613473115354"); 1119 1120 pintrk("page"); 1121 </script>
1121 1122 <noscript> 1123 <img height="1" width="1" style="display:none;" alt="Pinterest" src="https://ct.pinterest.com/v3/?event=init&tid=2613473115354&noscript=1" /> 1124 </noscript> 1125 1126 1127 1128 1129
1129<script type="text/javascript"> 1130 window._qevents = window._qevents || []; 1131 (function () { 1132 var elem = document.createElement("script"); 1133 elem.src = (document.location.protocol == "https:" ? "https://secure" : "http://edge") + ".quantserve.com/quant.js"; 1134 elem.async = true; 1135 elem.type = "text/javascript"; 1136 var scpt = document.getElementsByTagName("script")[0]; 1137 scpt.parentNode.insertBefore(elem, scpt); 1138 })(); 1139 window._qevents.push({ 1140 qacct: "p-hJNMajSvN7QWE" 1141 }); 1142 </script>
1142 1143 <noscript> 1144 <div style="display:none;"> 1145 <img src="https://pixel.quantserve.com/pixel/p-hJNMajSvN7QWE.gif" border="0" height="1" width="1" alt="Quantcast" /> 1146 </div> 1147 </noscript> 1148 1149 1150 1151
1151<script type="text/javascript"> 1152 (function () { 1153 var s = document.createElement("script"), 1154 h = document.head; 1155 s.async = 1; 1156 s.src = "https://monitor.fraudblocker.com/fbt.js?sid=2fbvVHDcPZbmCVruF-GTC"; 1157 h.appendChild(s); 1158 })(); 1159 </script>
1159 1160 <noscript> 1161 <a href="https://fraudblocker.com" rel="nofollow"> 1162 <img src="https://monitor.fraudblocker.com/fbt.gif?sid=2fbvVHDcPZbmCVruF-GTC" alt="Fraud Blocker" /> 1163 </a> 1164 </noscript> 1165 1166 1167
1167<script> 1168 1169 function captureEvent(eventName = "", eventData = {}, { customerio = true } = {}) { 1170 console.log(`Event: ${eventName}`, eventData); 1171 1172 // Replace any special characters or spaces in eventName with an underscore for GA4 1173 const gaEventName = eventName.replace(/[\W\s]+/g, "_"); 1174 1175 // PostHog 1176 if (typeof posthog !== "undefined") { 1177 posthog.capture(eventName, eventData); 1178 }; 1179 1180 // GA4 1181 gtag("event", gaEventName, eventData); 1182 1183 // Customer.io 1184 if (customerio && typeof _cio !== "undefined") { 1185 _cio.track(eventName, eventData); 1186 }; 1187 }; 1188 </script>
1188 1189 1190 1191
1191<script> 1192 // Identify user 1193 1194 </script>
1194 1195 1196 1197
1197<script> 1198 // Function to parse query string parameters into an object 1199 function getQueryParams() { 1200 const params = new URLSearchParams(window.location.search); 1201 const queryObject = {}; 1202 params.forEach((value, key) => { 1203 queryObject[key] = value; 1204 }); 1205 return queryObject; 1206 }; 1207 1208 // Function to update session storage with query parameters 1209 function updateSessionStorage(newParams) { 1210 try { 1211 const storedParams = JSON.parse(sessionStorage.getItem("queryParams")) || {}; 1212 1213 // Merge new parameters with stored parameters 1214 const updatedParams = { ...storedParams, ...newParams }; 1215 1216 // Store the updated parameters in session storage 1217 sessionStorage.setItem("queryParams", JSON.stringify(updatedParams)); 1218 } catch (e) { 1219 // Attribution is optional when browser storage is unavailable or invalid. 1220 } 1221 }; 1222 1223 // Function to initialize query parameter handling 1224 function initQueryParams() { 1225 // Get query parameters from the URL 1226 const queryParams = getQueryParams(); 1227 1228 // If there are query parameters, update session storage 1229 if (Object.keys(queryParams).length > 0) { 1230 updateSessionStorage(queryParams); 1231 }; 1232 }; 1233 1234 // Initialize on page load 1235 document.addEventListener("DOMContentLoaded", initQueryParams); 1236 </script>
1236 1237 1238 1239
1239<script> 1240 document.addEventListener("DOMContentLoaded", function() { 1241 // Find all links with the 'logout' class 1242 const logoutLinks = document.querySelectorAll("a.logout"); 1243 1244 if (logoutLinks.length > 0) { 1245 // Add the event listener only once to the parent (event delegation) 1246 document.addEventListener("click", function(event) { 1247 const target = event.target.closest("a.logout"); // Check if clicked element or parent has 'logout' class 1248 if (!target) return; // Exit if it's not a valid 'logout' link 1249 1250 // Reset _cio and PostHog 1251 if (typeof _cio !== "undefined" && _cio.reset) { 1252 _cio.reset(); 1253 } 1254 if (typeof posthog !== "undefined" && posthog.reset) { 1255 posthog.reset(); 1256 } 1257 }); 1258 } 1259 }); 1260 </script>
1260 1261 1262 1263
1263<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"21edc733b6e545df9366ee7f9f6acc04","spa":2}' crossorigin="anonymous"></script>
1263 1264</body> 1265</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.