1<!DOCTYPE html> 2<html><head><meta charset="utf-8"><meta content="ie=edge" http-equiv="x-ua-compatible"><meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"><title>Whimsical Login</title><link href="/s/images/apple-touch-icon-180_df3b1343f6670c1fe2d90b1e1425bb08.png" rel="apple-touch-icon" sizes="180x180">
2<script data-manifest="/a/manifest_442927702.json" nonce="MFPhca1nwE/CS6tNfb28zBOapxicV7Q/XFVfVxdym1Y=">(function () { 3 // Keep manifest updates for installed apps without promoting installs in tabs. 4 // Fullscreen alone is not an installed-app signal: browser tabs can use it too. 5 if ( 6 navigator.standalone || 7 window.matchMedia( 8 "(display-mode: standalone), (display-mode: minimal-ui), (display-mode: window-controls-overlay)" 9 ).matches 10 ) { 11 var manifest = document.createElement("link"); 12 manifest.rel = "manifest"; 13 manifest.href = document.currentScript.getAttribute("data-manifest"); 14 document.head.appendChild(manifest); 15 } 16})(); 17</script>
17<link href="/s/images/favicon-32_0bf25248ca6544a80f6af799d9b5be51.png" rel="icon" sizes="32x32" type="image/png"><link href="https://whimsical.com/releases/feeds/main" rel="alternate" title="Whimsical Product Updates" type="application/atom+xml"><link href="/s/css/fonts.min_0e4a678dc96c27a92828a6728183459c.css" rel="stylesheet"><link href="https://whimsical.com/login" rel="canonical"><meta content="Log into Whimsical with your email or single sign-on account. " name="description"><meta content="Whimsical Login" property="og:title"><meta content="website" property="og:type"><meta content="en_US" property="og:locale"><meta content="Whimsical" property="og:site_name"><meta content="https://whimsical.com/assets/cards/redesign-2025/default.png" property="og:image"><meta content="Log into Whimsical with your email or single sign-on account. " property="og:description"><meta content="https://whimsical.com/login" property="og:url"><meta content="@whimsical" name="twitter:site"><meta content="summary_large_image" name="twitter:card"><meta content="https://whimsical.com/assets/cards/redesign-2025/default.png" name="twitter:image"><meta content="Whimsical Login" name="twitter:title"><meta content="Log into Whimsical with your email or single sign-on account. " name="twitter:description">
17<script nonce="MFPhca1nwE/CS6tNfb28zBOapxicV7Q/XFVfVxdym1Y=">// Suppress automatic install prompts independently of service worker support. 18window.addEventListener("beforeinstallprompt", function (event) { 19 event.preventDefault(); 20}); 21</script>
21<script 22 src="https://browser.sentry-cdn.com/10.45.0/bundle.tracing.min.js" 23 integrity="sha384-ZE5gmGUOoa9DS6XtledlDlf2IcepU+WXjngGpQw1iHa8mYdrTk5G1KBqehdaA+K3" 24 crossorigin="anonymous" 25 nonce=MFPhca1nwE/CS6tNfb28zBOapxicV7Q/XFVfVxdym1Y= 26></script>
vendor: 1 bytes, line 26
26
27<script nonce=MFPhca1nwE/CS6tNfb28zBOapxicV7Q/XFVfVxdym1Y= > 28 29 30 31 try { Error.stackTraceLimit = 100000; } catch (e) {} 32 33 window.Sentry.init({ 34 dsn: "https://[email protected]/6692856", 35 integrations: [Sentry.browserTracingIntegration()], 36 37 tracesSampleRate: 0.01, 38 release: "264e1f917dac5c5a8f9e5dc4f18808f589b420a0", 39 environment: "production", 40 initialScope: {tags: {mode: "default"}}, 41 ignoreErrors: [ 42 43 /Java object is gone/, 44 45 /Object Not Found Matching Id:\d+, MethodName:update, ParamCount:4/, 46 47 /ResizeObserver loop completed with undelivered notifications/, 48 /ResizeObserver loop limit exceeded/, 49 ], 50 51 beforeSend: function (event, hint) { 52 try { 53 var ex = hint && hint.originalException; 54 var exVal = event.exception && event.exception.values && event.exception.values[0]; 55 var msg = (ex && ex.message) || (exVal && exVal.value) || event.message || ""; 56 if (/Maximum call stack size exceeded/i.test(msg)) { 57 var hasStack = !!(ex && ex.stack); 58 var origin = !ex ? "no-error-object" : (hasStack ? "has-stack" : "empty-stack"); 59 var lines = hasStack ? String(ex.stack).split("\n") : null; 60 61 if (hasStack 62 && lines.length > 20 63 && String(ex.stack).indexOf("://") === -1 64 && !/:\d+:\d+/.test(ex.stack)) { 65 return null; 66 } 67 68 69 var htmlClass = document.documentElement.classList; 70 var translated = htmlClass.contains("translated-ltr") 71 || htmlClass.contains("translated-rtl") 72 || (event.tags && event.tags["whim.translated"] === "chrome-translate"); 73 var userAgent = navigator.userAgent || ""; 74 var iosBrowser = /iP(?:hone|ad|od)/.test(userAgent); 75 var iosGoogleBrowser = iosBrowser && /(?:CriOS|GSA)\//.test(userAgent); 76 if (hasStack 77 && lines.length > 20 78 && iosBrowser 79 && (translated || iosGoogleBrowser)) { 80 var documentFrameCounts = Object.create(null); 81 for (var i = 0; i < lines.length; i++) { 82 var frame = lines[i].match(/^(?:[^@]*)@(.+):\d+:\d+$/); 83 if (!frame) continue; 84 try { 85 var frameUrl = new URL(frame[1], window.location.href); 86 if (frameUrl.origin === window.location.origin 87 && !/\.js$/i.test(frameUrl.pathname)) { 88 documentFrameCounts[lines[i]] = (documentFrameCounts[lines[i]] || 0) + 1; 89 } 90 } catch (e) {} 91 } 92 var repeatedDocumentFrames = Object.keys(documentFrameCounts) 93 .filter(function (frame) { return documentFrameCounts[frame] >= 10; }); 94 if (repeatedDocumentFrames.length >= 2) { 95 return null; 96 } 97 } 98 99 event.extra = Object.assign({}, event.extra, { 100 "raw-error-type": (ex && ex.constructor && ex.constructor.name) || null, 101 "raw-error-string": ex ? String(ex) : "<no originalException; onerror error=null>", 102 "raw-stack-frames": lines ? lines.length : 0, 103 "raw-stack-head": lines ? lines.slice(0, 15).join("\n").slice(0, 2000) 104 : (ex ? "<empty .stack>" : "<no originalException; onerror error=null>"), 105 106 "raw-stack-tail": (lines && lines.length > 15) ? lines.slice(-40).join("\n").slice(-4000) : null 107 }); 108 event.tags = Object.assign({}, event.tags, { "whim.overflow-origin": origin }); 109 } 110 } catch (e) {} 111 return event; 112 }, 113 }); 114</script>
vendor: 1 bytes, line 114
114
115<script nonce="zzUEiTPThTp+jJr01HMtvsqXZvsxPzNx5nZjJA6O4pQ=" src="/s/js/gate.min_2f50744a2829199227d7e0dfa59ee554.js"></script>
115<script nonce="zzUEiTPThTp+jJr01HMtvsqXZvsxPzNx5nZjJA6O4pQ=">try {wh.init({"API":"","T":true,"CID":"069ffcf0-766c-48ee-82dd-8414d7fe7ea0"})}catch(e){console.error(e)}</script>
115<link href="/s/css/auth.min_4a0235018dc9bc59482d4b53606f275e.css" rel="stylesheet">
115<script defer="true" nonce="zzUEiTPThTp+jJr01HMtvsqXZvsxPzNx5nZjJA6O4pQ=" src="https://challenges.cloudflare.com/turnstile/v0/api.js"></script>
115<script data-domain="whimsical.com" defer nonce="zzUEiTPThTp+jJr01HMtvsqXZvsxPzNx5nZjJA6O4pQ=" src="https://plausible.io/js/plausible.js"></script>
115<script nonce="zzUEiTPThTp+jJr01HMtvsqXZvsxPzNx5nZjJA6O4pQ=">window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
115<script defer nonce="zzUEiTPThTp+jJr01HMtvsqXZvsxPzNx5nZjJA6O4pQ=" referrer-policy="origin" src="/cdn-cgi/zaraz/i.js"></script>
115</head><body translate="no"><div id="root">
115<script nonce=zzUEiTPThTp+jJr01HMtvsqXZvsxPzNx5nZjJA6O4pQ=> 116 var buttons = { 117 "saml-login-button": () => { 118 window.location = '/saml/' + document.getElementById('saml-workspace-id').textContent 119 }, 120 "saml-email-login-button": () => { 121 wh.flip('#login-saml', '#login-email'); 122 wh.loginInit('#login-email') 123 }, 124 "saml-google-login-button": () => { 125 wh.startGoogleLogin('.login') 126 }, 127 "google-login-button": () => { 128 wh.startGoogleLogin('#login-email') 129 }, 130 "saml-sso-login-button-flipped": () => { 131 window.location = '/saml/' + document.getElementById('saml-workspace-id').textContent 132 } 133 } 134 135 136 // JS redirect flow from Okta has window.opener, but forbids accessing it's location. This block is to safely check whether we can access window.opener 137 var windowLocation = null; 138 try { 139 windowLocation = window.opener.location.href; 140 } catch (e) { 141 // continue 142 } 143 if (windowLocation != null) { 144 document.body.classList.add("popup"); 145 document.body.classList.add("hidden"); 146 wh.validateCookies(function () { 147 document.body.classList.remove("hidden"); 148 }); 149 wh.saveReturnTo(); 150 } else { 151 wh.loadAppIfLoggedIn(); 152 wh.saveAuthContext(); 153 } 154 155 document.addEventListener('DOMContentLoaded', function () { 156 for (var [button, fn] of Object.entries(buttons)) { 157 var but = document.getElementById(button) 158 if (but) { 159 but.onclick = fn 160 } 161 } 162 163 // Prevents a mysterious and harmless (but noisy) error that sometimes happens 164 // to Safari users here 165 if (document && document.getElementById('login-email')) { 166 document.getElementById('login-email').onsubmit = (e) => wh.login(e, '#login-email'); 167 } else { 168 return 169 } 170 171 172 wh.loginInit("#login-email"); 173 174 }); 175</script>
175 176 177 178 179<div class="account"> 180 <div class="account-bg" data-bg-key="mount-whimsy"></div> 181 <div class="o-wrapper"> 182 <header class="header"> 183 <nav class="i-wrapper"> 184 <a class="logo" href="/"> 185 <img src="/s/images/auth/logo-v2-dark.svg" class="logo-img" alt="Whimsical"> 186 </a> 187 188 <div class="nav-utility"> 189 <a href="https://whimsical.com/learn/contact-us" class="nav-support-link"><span>Contact</span> support</a> 190 <a href="/signup" id="">Sign up</a> 191 </div> 192 193 </nav> 194</header> 195 196 197 <div class="content"> 198 <div class="i-wrapper"> 199 200 201 <form id="login-email" class="login box" method="POST" 202 > 203 <h1 class="box-header"> 204 205 Welcome back! 206 207 </h1> 208 <div class="notice" style="display: none"></div> 209 <div class="error" style="display: none"></div> 210 <noscript> 211 <div class="error">Please enable JavaScript to log in</div> 212 </noscript> 213 214 <button id="google-login-button" 215 class="button google-login " 216 type="button"> 217 Log in with Google 218 </button> 219 <div class="or"><span>or</span></div> 220 <label for="email" class="label"> 221 Email 222 </label> 223 <input id="email" name="email" class="text email" type="email" placeholder="[email protected]" autocomplete="username" 224 data-wc="login-email"> 225 <label for="password" class="label"> 226 Password 227 </label> 228 <input id="password" name="password" class="text password" type="password" placeholder="12 - 64 characters" 229 autocomplete="current-password" data-wc="login-password" enterkeyhint="go"> 230 <button name="submit" class="button -invert" type="submit" disabled> 231 Log in 232 </button> 233 <a class="small" href="/forgot-password">Forgot password?</a> 234 235 </form> 236 <div class="alt"> 237 <span>Don't have an account?</span> <a href="/signup">Sign up</a> 238 </div> 239 </div> 240 </div> 241 </div> 242</div> 243</div>
243<script nonce="zzUEiTPThTp+jJr01HMtvsqXZvsxPzNx5nZjJA6O4pQ=">(function(){function c(){var b=a.contentDocument||(a.contentWindow&&a.contentWindow.document);if(b){var d=b.createElement('script');d.nonce='zzUEiTPThTp+jJr01HMtvsqXZvsxPzNx5nZjJA6O4pQ=';d.innerHTML="window.__CF$cv$params={r:'a40066301b67b083',t:'MTc5MDIzODMzMw=='};var a=document.createElement('script');a.nonce='zzUEiTPThTp+jJr01HMtvsqXZvsxPzNx5nZjJA6O4pQ=';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>
243</body></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.