PageSourceSearch

https://lab.simone-dev.com/tarot

html simone-dev.com collected 2026-10-06 13:36:14 UTC 12,345 bytes, 190 lines download raw bytes

1<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><meta name="format-detection" content="telephone=no"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"><meta name="apple-mobile-web-app-title" content="Simone Andreotti - Web Developer Portfolio"><meta name="theme-color" content="#000000"><meta name="robots" content="index, follow"><meta name="author" content="Simone Andreotti"><meta name="description" content="Simone Andreotti - Frontend developer - Personal portfolio and curricum to show off my life, experiences and works"><meta name="keywords" content="simone, simone andreotti, web development, portfolio, curriculum, web design, front-end developer, threejs, website development, 3d, vr, vr website, webxr"><meta name="language" content="English"><meta name="generator" content="Astro v5.16.0"><title>Simone Andreotti - Web Developer Portfolio</title><link rel="canonical" href="https://lab.simone-dev.com"><meta property="og:type" content="website"><meta property="og:url" content="https://lab.simone-dev.com"><meta property="og:title" content="Simone Andreotti - Web Developer Portfolio"><meta property="og:description" content="Explore my portfolio!"><meta property="og:image" content="https://lab.simone-dev.com/socialImage.png"><meta property="og:image:width" content="1200"><meta property="og:image:height" content="630"><meta property="og:locale" content="en_US"><meta property="og:site_name" content="Simone Andreotti Portfolio"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:url" content="https://lab.simone-dev.com"><meta name="twitter:title" content="Simone Andreotti - Web Developer Portfolio"><meta name="twitter:description" content="Explore my portfolio!"><meta name="twitter:image" content="https://lab.simone-dev.com/socialImage.png"><link rel="alternate" hreflang="en" href="https://lab.simone-dev.com"><link rel="alternate" hreflang="x-default" href="https://lab.simone-dev.com"><link rel="icon" type="image/png" href="/favicon/favicon-96x96.png" sizes="96x96"><link rel="icon" type="image/svg+xml" href="/favicon/favicon.svg"><link rel="shortcut icon" href="/favicon/favicon.ico"><link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png"><link rel="manifest" href="/manifest.json">
1<script>(function installSceneExportBridge() {
2	const EXPORT_PARAM = 'scene-export';
3
4	function largestCanvas() {
5		return [...document.querySelectorAll('canvas')]
6			.filter((canvas) => canvas.width > 0 && canvas.height > 0)
7			.sort((a, b) => (b.width * b.height) - (a.width * a.height))[0] || null;
8	}
9
10	const searchParams = new URLSearchParams(window.location.search);
11	if (searchParams.get(EXPORT_PARAM) !== '1' || window.__sceneExport) return;
12	const headless = searchParams.get('scene-headless') === '1';
13	document.documentElement.toggleAttribute('data-scene-headless', headless);
14
15	let virtualTime = 0;
16	let nextHandle = 1;
17	let callbacks = new Map();
18	const nativeRequestAnimationFrame = window.requestAnimationFrame?.bind(window);
19	const nativeCancelAnimationFrame = window.cancelAnimationFrame?.bind(window);
20	const nativeNow = window.performance?.now?.bind(window.performance) || Date.now;
21
22	window.requestAnimationFrame = (callback) => {
23		const handle = nextHandle++;
24		callbacks.set(handle, callback);
25		return handle;
26	};
27	window.cancelAnimationFrame = (handle) => callbacks.delete(handle);
28	try {
29		if (!window.performance) Object.defineProperty(window, 'performance', { configurable: true, value: {} });
30		Object.defineProperty(window.performance, 'now', { configurable: true, value: () => virtualTime });
31	} catch {
32		// Exact callback timestamps still cover scenes that use the RAF argument directly.
33	}
34	try {
35		Object.defineProperty(window, 'devicePixelRatio', { configurable: true, value: 1 });
36	} catch {
37		// The iframe viewport still requests the exact output size when DPR cannot be overridden.
38	}
39
40	const api = {
41		version: 1,
42		getCanvas: largestCanvas,
43		hasAudio() { return typeof window.__sceneAudioExport?.renderChunk === 'function'; },
44		renderAudioChunk(options) {
45			return window.__sceneAudioExport?.renderChunk?.(options) ?? null;
46		},
47		get time() {
48			return virtualTime;
49		},
50		async step(timeMs) {
51			virtualTime = Math.max(0, Number(timeMs) || 0);
52			const frameCallbacks = callbacks;
53			callbacks = new Map();
54			let firstError = null;
55			for (const callback of frameCallbacks.values()) {
56				try {
57					callback(virtualTime);
58				} catch (error) {
59					firstError ||= error;
60				}
61			}
62			await Promise.resolve();
63			if (firstError) throw firstError;
64			const canvas = largestCanvas();
65			return canvas ? { width: canvas.width, height: canvas.height, callbacks: frameCallbacks.size } : null;
66		},
67		setRecording(active, settings = {}) {
68			document.documentElement.toggleAttribute('data-scene-export', Boolean(active));
69			document.documentElement.toggleAttribute('data-scene-headless', headless);
70			window.dispatchEvent(new CustomEvent('scene-export-mode', {
71				detail: { ...settings, active: Boolean(active), headless },
72			}));
73		},
74		restore() {
75			if (nativeRequestAnimationFrame) window.requestAnimationFrame = nativeRequestAnimationFrame;
76			if (nativeCancelAnimationFrame) window.cancelAnimationFrame = nativeCancelAnimationFrame;
77			try {
78				Object.defineProperty(window.performance, 'now', { configurable: true, value: nativeNow });
79			} catch {
80				// The page is normally discarded with its iframe after export.
81			}
82		},
83	};
84
85	window.__sceneExport = api;
86	window.parent?.postMessage({ type: 'scene-export-ready', version: api.version }, window.location.origin);
87}());
88</script>
88<script type="application/ld+json">{"@context":"https://schema.org","@type":"Person","name":"Simone Andreotti","jobTitle":"Web Developer","description":"I am a web developer specialized in creating innovative websites with complex ui.","url":"https://lab.simone-dev.com","image":"https://lab.simone-dev.com/socialImage.png","sameAs":["https://www.linkedin.com/in/simone-andreotti/"],"worksFor":{"@type":"Person","name":"Simone Andreotti","url":"https://lab.simone-dev.com"},"makesOffer":{"@type":"Offer","itemOffered":{"@type":"Service","name":"Website Development","description":"Professional web development services to build unique, modern, responsive websites tailored to your needs.","provider":{"@type":"Person","name":"Simone Andreotti"}},"priceSpecification":{"@type":"PriceSpecification","priceCurrency":"EUR","price":"Custom"},"availability":"https://schema.org/InStock","url":"https://lab.simone-dev.com?section=contact"}}</script>
88<script type="application/ld+json">{"@context":"https://schema.org","@type":"LocalBusiness","@id":"https://lab.simone-dev.com/#localbusiness","name":"Simone Andreotti","description":"Simone Andreotti - Frontend developer - Personal portfolio and curricum to show off my life, experiences and works","url":"https://lab.simone-dev.com","email":"[email protected]","priceRange":"$$","image":"https://lab.simone-dev.com/socialImage.png","openingHoursSpecification":[{"@type":"OpeningHoursSpecification","dayOfWeek":["Monday","Tuesday","Wednesday","Thursday","Friday"],"opens":"09:00","closes":"17:00"}],"sameAs":["https://www.linkedin.com/in/simone-andreotti/"]}</script>
88<script type="application/ld+json">{"@context":"https://schema.org","@type":"Organization","@id":"https://lab.simone-dev.com/#organization","name":"Simone Andreotti","url":"https://lab.simone-dev.com","logo":{"@type":"ImageObject","url":"https://lab.simone-dev.com/socialImage.png"},"contactPoint":{"@type":"ContactPoint","contactType":"customer service","email":"[email protected]","availableLanguage":["English","Italian"]},"sameAs":["https://www.linkedin.com/in/simone-andreotti/"]}</script>
88<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","@id":"https://lab.simone-dev.com/#website","url":"https://lab.simone-dev.com","name":"Simone Andreotti - Web Developer Portfolio","description":"Simone Andreotti - Frontend developer - Personal portfolio and curricum to show off my life, experiences and works","inLanguage":"en-US"}</script>
88<script>
89			const devHosts = new Set(['localhost', '127.0.0.1']);
90			const isDevHost = devHosts.has(window.location.hostname);
91
92			function forceDocumentNavigation(event) {
93				if (event.defaultPrevented) return;
94				if (event.button !== 0) return;
95				if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
96
97				const anchor = event.target instanceof Element
98					? event.target.closest('a[href]')
99					: null;
100				if (!(anchor instanceof HTMLAnchorElement)) return;
101				if (anchor.target && anchor.target.toLowerCase() !== '_self') return;
102				if (anchor.hasAttribute('download')) return;
103
104				const href = anchor.getAttribute('href');
105				if (!href || href.startsWith('#')) return;
106
107				const url = new URL(anchor.href, window.location.href);
108				if (url.origin !== window.location.origin) return;
109
110				event.preventDefault();
111				window.location.assign(url.href);
112			}
113
114			function reloadOnHistoryNavigation(event) {
115				const navEntry = performance.getEntriesByType('navigation')[0];
116				const isBackForward = navEntry && navEntry.type === 'back_forward';
117
118				if (event.persisted || isBackForward) {
119					window.location.reload();
120				}
121			}
122
123			async function clearDevServiceWorkerState() {
124				if (!('serviceWorker' in navigator)) return;
125
126				const registrations = await navigator.serviceWorker.getRegistrations();
127				if (registrations.length === 0) return;
128
129				await Promise.all(registrations.map((registration) => registration.unregister()));
130
131				if ('caches' in window) {
132					const keys = await caches.keys();
133					await Promise.all(keys.map((key) => caches.delete(key)));
134				}
135
136				const reloadMarker = '__dev_sw_cache_cleared__';
137				if (!sessionStorage.getItem(reloadMarker)) {
138					sessionStorage.setItem(reloadMarker, '1');
139					window.location.reload();
140				}
141			}
142
143			if ('serviceWorker' in navigator) {
144				window.addEventListener('load', async () => {
145					if (isDevHost) {
146						await clearDevServiceWorkerState();
147						return;
148					}
149
150					try {
151						const swExists = await fetch('/sw.js', { method: 'HEAD', cache: 'no-store' })
152							.then((response) => response.ok)
153							.catch(() => false);
154
155						if (!swExists) return;
156
157						const registration = await navigator.serviceWorker.register('/sw.js');
158						console.log('Service Worker registered:', registration.scope);
159
160						setInterval(() => {
161							registration.update();
162						}, 60000);
163
164						registration.addEventListener('updatefound', () => {
165							const newWorker = registration.installing;
166							newWorker.addEventListener('statechange', () => {
167								if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
168									console.log('New Service Worker available, updating');
169									newWorker.postMessage({ type: 'SKIP_WAITING' });
170								}
171							});
172						});
173					} catch (error) {
174						console.warn('Service Worker registration failed:', error);
175					}
176				});
177			}
178
179			document.addEventListener('click', forceDocumentNavigation, true);
180			window.addEventListener('pageshow', reloadOnHistoryNavigation);
181
182			if (navigator.storage && navigator.storage.persist) {
183				navigator.storage.persist().then(persistent => {
184					if (persistent) {
185						console.log('Persistent storage granted');
186					}
187				});
188			}
189		</script>
189<link rel="stylesheet" href="/_astro/blackhole-slider.BSodS520.css"></head> <body>  <section class=""> <div id="cards-container" style="width: 100%; height: 100vh;"></div> </section> 
189<script type="module" src="/_astro/cards.astro_astro_type_script_index_0_lang.dcsrVkU_.js"></script>
189  
189<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":"6ee11fde4f1d47dabe3003f46747e56a","r":1,"spa":2}' crossorigin="anonymous"></script>
189
190</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.