PageSourceSearch

https://workshop.ai/config.js

js workshop.ai collected 2026-10-05 16:19:27 UTC 13,912 bytes, 412 lines download raw bytes

1<!doctype html>
2<html lang="en">
3	<head>
4		<meta charset="utf-8" />
5		<!-- Keep this as the first executable element in <head>. A secret-bearing auth
6		     entry is moved through sessionStorage and hard-navigated to a clean document
7		     before analytics can start. The clean document removes the storage record
8		     before exposing a one-shot handoff to first-party auth code. If storage is
9		     unavailable, the current document remains permanently analytics-blocked.
10		     Ordinary marketing/UTM URLs are left byte-for-byte intact. -->
11		<script>
12			(function () {
13				var storageKey = '__workshop_auth_entry_v1';
14				var maxAgeMs = 10 * 60 * 1000;
15
16				function isSensitiveAuthEntry(url) {
17					var params = url.searchParams;
18					var state = params.get('state');
19					var isAuthRoute = url.pathname === '/signin' || url.pathname === '/signup';
20					var hasAuthMarker =
21						params.has('auth_tx') || (isAuthRoute && !!state && /^[A-Za-z0-9_-]{43}$/.test(state));
22					var hasEmailActionMarker =
23						isAuthRoute && (params.has('oobCode') || (params.has('apiKey') && params.has('mode')));
24					return hasAuthMarker || hasEmailActionMarker;
25				}
26
27				function exposeOneShot(capturedUrl) {
28					window.__workshopAuthAnalyticsBlocked = true;
29					Object.defineProperty(window, '__takeWorkshopAuthEntry', {
30						value: function () {
31							var entry = capturedUrl ? { url: capturedUrl } : null;
32							capturedUrl = null;
33							delete window.__takeWorkshopAuthEntry;
34							return entry;
35						},
36						configurable: true
37					});
38				}
39
40				function suppressSensitiveNavigationReferrer() {
41					try {
42						var referrerPolicy = document.createElement('meta');
43						referrerPolicy.name = 'referrer';
44						referrerPolicy.content = 'no-referrer';
45						document.head.appendChild(referrerPolicy);
46					} catch (e) {}
47				}
48
49				try {
50					var url = new URL(window.location.href);
51					if (isSensitiveAuthEntry(url)) {
52						var capturedUrl = url.toString();
53						window.__workshopAuthAnalyticsBlocked = true;
54						window.__workshopAuthEntryDocumentUnsafe = true;
55						suppressSensitiveNavigationReferrer();
56						var handoffStored = false;
57						try {
58							window.sessionStorage.setItem(
59								storageKey,
60								JSON.stringify({
61									url: capturedUrl,
62									createdAt: Date.now()
63								})
64							);
65							handoffStored = true;
66							window.__workshopAuthEntryHardNavigationPending = true;
67							// Scrub before navigating so the clean document cannot inherit the
68							// secret-bearing URL through document.referrer or the Referer header.
69							window.history.replaceState(window.history.state, '', url.pathname);
70							window.location.replace(url.pathname);
71							return;
72						} catch (storageOrNavigationError) {
73							var handoffCleared = !handoffStored;
74							if (handoffStored) {
75								try {
76									window.sessionStorage.removeItem(storageKey);
77									handoffCleared = true;
78								} catch (e) {}
79							}
80							if (!handoffCleared) {
81								window.__workshopAuthEntryHardNavigationPending = true;
82								window.history.replaceState(window.history.state, '', url.pathname);
83								return;
84							}
85							window.__workshopAuthEntryHardNavigationPending = false;
86							exposeOneShot(capturedUrl);
87							window.history.replaceState(window.history.state, '', url.pathname);
88							return;
89						}
90					}
91
92					var stored = null;
93					try {
94						stored = window.sessionStorage.getItem(storageKey);
95						if (stored !== null) window.sessionStorage.removeItem(storageKey);
96					} catch (storageReadError) {
97						return;
98					}
99					if (!stored) return;
100
101					try {
102						var record = JSON.parse(stored);
103						var now = Date.now();
104						var storedUrl = new URL(record.url);
105						var isFresh =
106							typeof record.createdAt === 'number' &&
107							record.createdAt <= now + 60 * 1000 &&
108							now - record.createdAt <= maxAgeMs;
109						if (
110							!isFresh ||
111							storedUrl.origin !== url.origin ||
112							storedUrl.pathname !== url.pathname ||
113							!isSensitiveAuthEntry(storedUrl)
114						)
115							return;
116						exposeOneShot(storedUrl.toString());
117					} catch (invalidRecordError) {}
118				} catch (e) {}
119			})();
120		</script>
121		<script>
122			// The cross-origin prompt handoff arrives in the fragment, which keeps it
123			// out of request logs and out of the Referer header — but a fragment is
124			// still readable by anything running in this document, and GTM loads
125			// further down and reports location.href. The block above does not catch
126			// it: it only recognises auth markers, and all of those are query params.
127			//
128			// So the prompt is moved into the same localStorage inbox the auth screens
129			// already read from, and scrubbed off the URL, here — ahead of every tag.
130			// adoptHandoffPrompt() still runs later and is simply a no-op for the
131			// prompt once this has taken it; it goes on clearing theme and from.
132			(function () {
133				try {
134					if (!window.location.hash) return;
135					var fragment = new URLSearchParams(window.location.hash.slice(1));
136					var handedPrompt = fragment.get('prompt');
137					if (!handedPrompt) return;
138
139					try {
140						window.localStorage.setItem('memex-cached-prompt', handedPrompt);
141					} catch (storageError) {
142						// Private browsing: dropping the prompt beats leaving it on the
143						// URL for the tags below to collect.
144					}
145
146					fragment.delete('prompt');
147					var rest = fragment.toString();
148					window.history.replaceState(
149						window.history.state,
150						'',
151						window.location.pathname + window.location.search + (rest ? '#' + rest : '')
152					);
153				} catch (e) {}
154			})();
155		</script>
156		<meta name="viewport" content="width=device-width, initial-scale=1" />
157
158		<!-- Preload critical fonts: heading (Sohne Halbfett) to minimize font-swap CLS -->
159	<link rel="preload" href="/fonts/Sohne-Halbfett.woff2" as="font" type="font/woff2" crossorigin />
160	<!-- Preconnect to CDN for images and partner logos -->
161	<link rel="preconnect" href="https://static.workshop.ai" crossorigin />
162
163	<!-- Critical CSS for layout stability - prevents CLS on slow connections -->
164		<style>
165			/* Base layout stability - loads immediately before any JS/CSS bundles */
166			html, body {
167				margin: 0;
168				padding: 0;
169				background-color: var(--color-bg-base, #0a0a0a);
170				color: white;
171				min-height: var(--stable-100vh, 100vh);
172			}
173			
174			/* Reserve space for fixed header to prevent content jump */
175			.page-layout {
176				min-height: var(--stable-100vh, 100vh);
177				background-color: var(--color-bg-base, #0a0a0a);
178			}
179			
180			/* Fixed header dimensions - prevents layout shift */
181			.desktop-header,
182			.mobile-header {
183				position: fixed;
184				top: 0;
185				left: 0;
186				right: 0;
187				height: 64px;
188				z-index: 50;
189			}
190			
191			/* Content area reserves space for fixed header */
192			.content-area {
193				padding-top: 64px;
194			}
195			
196			/* Prevent logo flash: hide all logo variants and constrain size before component CSS loads */
197			.logo-memex, .logo-workshop-dark, .logo-workshop-light { display: none; height: 2rem; width: auto; }
198			.theme-memex .logo-memex { display: block; }
199			.theme-workshop-dark .logo-workshop-dark { display: block; }
200			.theme-workshop-light .logo-workshop-light { display: block; }
201
202			/* Hide desktop header on mobile, show mobile header */
203			.desktop-header { display: none; }
204			.mobile-header { display: block; }
205			
206			@media (min-width: 768px) {
207				.desktop-header { display: flex; }
208				.mobile-header { display: none !important; }
209			}
210			
211			/* Skip link for accessibility - visually hidden until focused */
212			.skip-link {
213				position: absolute;
214				width: 1px;
215				height: 1px;
216				padding: 0;
217				margin: -1px;
218				overflow: hidden;
219				clip: rect(0, 0, 0, 0);
220				white-space: nowrap;
221				border: 0;
222			}
223			.skip-link:focus {
224				position: fixed;
225				top: 0;
226				left: 0;
227				width: auto;
228				height: auto;
229				padding: 8px 16px;
230				margin: 0;
231				overflow: visible;
232				clip: auto;
233				white-space: normal;
234				background: #1d4ed8;
235				color: white;
236				z-index: 9999;
237				text-decoration: none;
238				font-weight: 500;
239				border-radius: 0 0 4px 0;
240				outline: 2px solid white;
241				outline-offset: 2px;
242			}
243		</style>
244
245		<!-- Theme initialization - runs synchronously before first paint to prevent FOUC -->
246		<script>
247		(function() {
248			var host = window.location.hostname;
249			var isWorkshop = host.includes('workshop.ai') || host === 'localhost' || host === '127.0.0.1';
250			var h = document.documentElement;
251
252			if (!isWorkshop) {
253				h.className = 'dark theme-memex';
254				return;
255			}
256
257			var stored = null;
258			try { stored = localStorage.getItem('beta-theme'); } catch(e) {}
259
260			// A ?theme= handed over from rayline.ai. localStorage cannot cross an
261			// origin, so without this a visitor who was on dark Rayline lands on
262			// whatever their OS prefers. Handled here rather than in the theme
263			// store because it has to resolve before first paint, and it is
264			// persisted so the rest of the Workshop session matches.
265			var handed = null;
266			try {
267				handed = new URLSearchParams(window.location.search).get('theme');
268				if (handed !== 'dark' && handed !== 'light') handed = null;
269				if (handed) { stored = handed; localStorage.setItem('beta-theme', handed); }
270			} catch(e) {}
271
272			var pref = 'system';
273			if (stored === 'dark' || stored === 'workshop-dark') pref = 'dark';
274			else if (stored === 'light' || stored === 'workshop-light') pref = 'light';
275			else if (stored === 'system') pref = 'system';
276
277			var isDark;
278			if (pref === 'dark') isDark = true;
279			else if (pref === 'light') isDark = false;
280			else isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
281
282			var theme = isDark ? 'workshop-dark' : 'workshop-light';
283			h.className = 'theme-' + theme + (isDark ? ' dark' : '');
284		})();
285		</script>
286
287		<!-- Lock the initial viewport height to prevent layout shift when mobile browser
288		     toolbar hides on scroll. CSS viewport units (vh/svh/dvh) all resize dynamically
289		     in Chromium-based mobile browsers, so we capture the stable value once via JS.
290		     Large viewport changes (DevTools resize, orientation change) still update the
291		     locked value; only small changes (<15%, typical of toolbar hide/show) are ignored. -->
292		<script>
293		(function(){
294			var s=window.innerHeight;
295			document.documentElement.style.setProperty('--stable-100vh',s+'px');
296			window.addEventListener('resize',function(){
297				var h=window.innerHeight;
298				if(Math.abs(h-s)/s>0.15){s=h;document.documentElement.style.setProperty('--stable-100vh',h+'px');}
299			});
300		})();
301		</script>
302
303	<!-- Akkurat body font (self-hosted, non-critical body text) -->
304
305	<!-- Preload LCP hero background image (same-origin, runs after theme detection) -->
306	<script>
307	(function(){
308		var isDark = document.documentElement.classList.contains('dark');
309		var isWorkshop = window.location.hostname.includes('workshop.ai');
310		if (!isWorkshop) return;
311		var w = window.innerWidth;
312		var size = w >= 1920 ? 'xl' : w >= 1024 ? 'lg' : w >= 640 ? 'md' : 'sm';
313		var theme = isDark ? 'dark-' : '';
314		var l = document.createElement('link');
315		l.rel = 'preload';
316		l.as = 'image';
317		l.type = 'image/avif';
318		l.fetchPriority = 'high';
319		l.href = '/images/hero/leonardo-workshop-' + theme + size + '.avif';
320		document.head.appendChild(l);
321	})();
322	</script>
323
324		<!-- Google Tag Manager. Auth-entry documents defer this idempotent starter
325		     until first-party code has consumed the private handoff. -->
326		<script>
327			(function (w, d) {
328				var started = false;
329				Object.defineProperty(w, '__startWorkshopGtm', {
330					value: function () {
331						if (started || w.__workshopAuthAnalyticsBlocked === true) return false;
332						started = true;
333						var hn = w.location.hostname;
334						var isLocal = hn === 'localhost' || hn === '127.0.0.1';
335						var h =
336							hn.includes('workshop.ai') && !hn.includes('dev')
337								? 'g.workshop.ai'
338								: hn.includes('memex.tech')
339									? 'g.memex.tech'
340									: 'g-preview.workshop.ai';
341						if (!isLocal) {
342							var preconnect = d.createElement('link');
343							preconnect.rel = 'preconnect';
344							preconnect.href = 'https://' + h;
345							d.head.appendChild(preconnect);
346						}
347						w.dataLayer = w.dataLayer || [];
348						w.dataLayer.push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });
349						if (isLocal) return true;
350						var f = d.getElementsByTagName('script')[0],
351							j = d.createElement('script');
352						j.async = true;
353						j.src = 'https://' + h + '/gtm.js?id=GTM-NJ8V8F5T';
354						f.parentNode.insertBefore(j, f);
355						return true;
356					},
357					configurable: true
358				});
359				w.__startWorkshopGtm();
360			})(window, document);
361		</script>
362		<!-- End Google Tag Manager -->
363
364		
365		<link rel="modulepreload" href="/_app/immutable/entry/start.n_qAlcin.js">
366		
367		
368		
369		
370		
371		
372		<link rel="modulepreload" href="/_app/immutable/entry/app.CKszG7GY.js">
373		
374		
375		
376		
377		
378		
379		
380	</head>
381	<body data-sveltekit-preload-data="hover">
382		<!-- Google Tag Manager (noscript) -->
383		<noscript>
384		<iframe src="https://g.memex.tech/ns.html?id=GTM-NJ8V8F5T"
385		height="0" width="0" style="display:none;visibility:hidden" title="Google Tag Manager"></iframe>
386		<iframe src="https://g.workshop.ai/ns.html?id=GTM-NJ8V8F5T"
387		height="0" width="0" style="display:none;visibility:hidden" title="Google Tag Manager"></iframe>
388		</noscript>
389		<!-- End Google Tag Manager (noscript) -->
390		<!-- Skip to main content link for keyboard users -->
391		<a href="#main-content" class="skip-link">Skip to main content</a>
392		<div style="display: contents">
393			<script>
394				{
395					__sveltekit_5fsdv4 = {
396						base: ""
397					};
398
399					const element = document.currentScript.parentElement;
400
401					Promise.all([
402						import("/_app/immutable/entry/start.n_qAlcin.js"),
403						import("/_app/immutable/entry/app.CKszG7GY.js")
404					]).then(([kit, app]) => {
405						kit.start(app, element);
406					});
407				}
408			</script>
409		</div>
410
411	</body>
412</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.