eco_net_2.0

🤖
ECO-HACKER:
NEXUS_RIDER
ECONET
🔊 📷 0 💎 0 🔓 0 ⭐ XP: 0 🌍 0 wO x2
ECONET
Non tutto è come appare.
Riprendi il Controllo dei tuoi device.
CODICE CRITTOGRAFATO PER IDENTIFICARE LA TUA SQUADRA
👩🏻‍🎤
🛸
🧙‍♀️
🥷
🧑🏾‍🚀
🐦‍🔥
🦊
👻

FASE 1: SCANNER LOCALE

AZIONE: Per ogni oggetto seleziona il target, configura i parametri e calcola il consumo energetico e l’eventuale Vampire Drain.
SYS_OP: ONLINE
NET: SCANNING…
LAT: 45.4642 N | LON: 9.1900 E
> Analyzing target… > Reading thermal signature… > Calculating Watt/h… > Detecting standby power… > Warning: Vampire drain possible. > Standby cycle initiated… > Target lock optimized.
📊 NODI REGISTRATI NELLA TUA STANZA

FASE 2: PROFILAZIONE CLOUD

AZIONE: A seconda del tuo uso di internet inserisci il numero di ore/giorno nelle diverse opzioni.
💎 HACKER TIP: Clicca sui diamanti criptati per svelare i retroscena dei server e guadagnare +20 XP ciascuno!

⚠️ FIREWALL: DATA CLASH

DOMANDA 1 / 4
✔️ FIREWALL BYPASSATO. IDENTITÀ CONFERMATA.

⚠️ DATA ANALYSIS: L’ICEBERG PERSONALE

1. IL TUO ICEBERG (ANNUALE)
🏠 ENERGIA UTILE (HARDWARE IN USO)
0 kWh/ANNO
⚡ VAMPIRE DRAIN (SPRECO HARDWARE)
0 kWh/ANNO
👻 CLOUD BACKGROUND (NOTIFICHE E PATCH)
0 GB -> 0 kWh/ANNO
☁ CLOUD ATTIVO (LE TUE AZIONI)
0 GB -> 0 kWh/ANNO
2. L’IMPRONTA DELLA TUA GENERAZIONE
EMISSIONI CO2 ANNUALI PER SINGOLO STUDENTE (USO SOCIAL E WEB)
MEDIA STUDENTI99 kg CO₂
IL TUO PROFILO ATTUALE (STIMA)0 kg CO₂
🌍 TRADUTTORE DI REALTÀ
quante volte potresti caricare da 0 a 100% il tuo cellulare ogni singolo giorno usando solo l’energia che i server bruciano per il tuo traffico dati?
UNA, DIECI, CENTO BATTERIE!
TOTALE: 0 RICARICHE AL GIORNO
MALUS: STAI PAGANDO INUTILMENTE SULLA BOLLETTA PER IL VAMPIRE DRAIN LOCALE.

🌍 L’ICEBERG GLOBALE (SETTORE ICT)

Il peso reale del mondo digitale sull’intero pianeta.
1. LA NAZIONE INVISIBILE
CLASSIFICA DEI CONSUMI ELETTRICI (TERAWATT-ORA ALL’ANNO)
🇨🇳 CINA~ 10.000 TWh
🇺🇸 STATI UNITI~ 4.500 TWh
🌐 INTERNET E SETTORE DIGITALE (ICT)~ 2.500 TWh
🇮🇹 ITALIA~ 300 TWh
2. IL 10% DEL PIANETA TERRA
TUTTA L’ELETTRICITÀ PRODOTTA NEL MONDO25.000 TWh
QUOTA ASSORBITA DAL DIGITALE (ICT)10%
3. IL PESO DEL VIRTUALE SUL REALE
CONFRONTO DI ASSORBIMENTO (SOLO ELETTRICITÀ)
TUTTE LE CASE DEL MONDO (Residenziale)~ 6.750 TWh
TUTTI GLI UFFICI/NEGOZI (Commerciale e Servizi)~ 5.250 TWh
L’INTERO MONDO DIGITALE (Settore ICT)~ 2.500 TWh
TRASPORTI ELETTRICI (Treni, Metro, Auto EV)~ 500 TWh

ZONA DI OVERRIDE

SCONFIGGI LE IMPOSTAZIONI DI FABBRICA (DEFAULT)
IL CODICE DELL’ECO-HACKER
CODICE 01: BYPASS DI RETE
ENERGIA PER TRASPORTARE 1 GB DI DATI
FIBRA + WI-FI DI CASA~50 Wh
WI-FI PUBBLICO / SCUOLA~80 Wh
RETE MOBILE (4G/5G)~250 Wh
CODICE 02: DOWNGRADE VIDEO
IMPATTO PER 1 ORA DI CONTENUTO
TESTO E IMMAGINI WEB~0.1 GB
VIDEO STANDARD / HD~1.0 GB
VIDEO 4K ULTRA HD~7.0 GB
CODICE 03: CONTENIMENTO I.A.
ENERGIA PER UNA SINGOLA OPERAZIONE
RICERCA WEB CLASSICA~0.3 Wh
TESTO I.A. (ES. CHATGPT)~3.0 Wh
GENERARE 1 IMMAGINE I.A.~15.0 Wh
GENERARE 1 VIDEO I.A.~50.0 Wh
CODICE 04: BLOCCO PRE-LOAD
IMPATTO PER 1 ORA DI UTILIZZO
CHAT E TESTO< 0.1 GB
SCROLL FOTO (PINTEREST, X)~ 0.5 GB
VIDEO E REELS (INSTAGRAM)~ 1.5 GB
PRE-LOAD AGGRESSIVO (TIKTOK)~ 2.5 GB
CODICE 05: STOP VAMPIRE DRAIN
PARADOSSO CONSOLE (2H GIOCO VS 22H STANDBY)
ATTIVA (GIOCANDO PER 2 ORE)~300 Wh
STANDBY DI RETE (RESTANTI 22 ORE)~330 Wh
CODICE 06: LONGEVITÀ DEL LITIO
IMPATTO REALE (CO2)
ELETTRICITÀ RICARICHE (10 ANNI DI FILA)~20 kg
PRODUZIONE DI UN SOLO TELEFONO NUOVO~80 kg
ORA APPLICA IL CODICE: SELEZIONA UN NODO E SEGUI LE ISTRUZIONI PER HACKERARE GLI SPRECHI NELLE TUE APP.

📊 RIEPILOGO DEBRIEFING

🤖
ANALISI COMPORTAMENTALE: TITOLO ASSEGNATO
…
…
LA TUA IMPRONTA VS MEDIA STUDENTI
MEDIA ANNUALE DI UN COETANEO99 kg CO₂
LA TUA IMPRONTA DOPO GLI HACK… kg CO₂
Più la barra è corta, meglio è per il pianeta.
LOOT / VANTAGGIO REALE PER LA FAMIGLIA
💵BOLLETTA:≈ –0 €/y
📶GIGA SALVATI:≈ 0 GB/y
☁CO2 EVITATA:≈ 0 kg/y
🔋BATTERIA:≈ +0 h/g
🏆
PATTO DI FAMIGLIA
DIVENTA ENERGY MANAGER E SCATTA IL SELFIE SQUADRA
🛡️
PATTO ENERGIADI
FIRMA E RADDOPPIA I wattORO
DEFAULT: ANALISI IN CORSO…
📱
SYS_OP: OVERRIDE_MODE
STATUS: SEARCHING…
SEC_LVL: ENCRYPTED
> Scanning device settings…
> Bypassing factory default…
> Looking for data saver flag…
> Awaiting agent verification…
PERCORSO GUIDATO: Seleziona il tuo sistema operativo per sbloccare la missione.
🔍 CACCIA AL TESORO: Trova la voce sul tuo schermo e inserisci la parola chiave qui sotto.
Congratulazioni! Sei stato investito ufficialmente del ruolo di Energy Manager / Energy Hacker di casa.
Coinvolgi genitori, fratelli e sorelle per eliminare gli sprechi in standby e lo streaming non necessario.
📷 SELFIE DI SQUADRA (FOTO-PROVA LIVE)
SELFIE ACQUISITO CORRETTAMENTE ✔️
Scatta un selfie in famiglia direttamente con la fotocamera del tuo dispositivo vicino alla ciabatta spenta o al logbook.
STATO: PATTO NON ANCORA FIRMATO CON IL SELFIE
Eco hacker … hai raggiunto nuove conoscenze, è ora di agire! Firma il patto con le Energiadi, mantieni le app hackerate per almeno 8 settimane e compila il CRONACHE ECO-HACKER (Diario di Bordo). In cambio le Energiadi raddoppiano i tuoi punti xp e li trasformano in wattORO, utile per vincere la gara delle Energiadi.
FIRMA DIGITALE A PRESSIONE
TIENI PREMUTO PER 2 SECONDI PER FIRMARE IL PATTO
✔️ PATTO FIRMATO CON SUCCESSO! WattORO Raddoppiati (x2).
REGISTRA IL TUO CONTROLLO PERIODICO (MAX 1 VOLTA AL GIORNO):
`; throw new Error("Security Override: Domain Mismatch."); } const audioFX = { ctx: null, bgGain: null, isMuted: false, initialized: false, init: function() { if (this.initialized) return; window.AudioContext = window.AudioContext || window.webkitAudioContext; if(!window.AudioContext) return; this.ctx = new AudioContext(); this.initialized = true; this.startCyberDrone(); document.getElementById('btn-audio').innerText = "🔊"; }, toggleMute: function() { if (!this.initialized) { this.init(); return; } this.isMuted = !this.isMuted; if (this.bgGain) this.bgGain.gain.setTargetAtTime(this.isMuted ? 0 : 0.20, this.ctx.currentTime, 0.1); document.getElementById('btn-audio').innerText = this.isMuted ? "🔇" : "🔊"; }, startCyberDrone: function() { if (!this.ctx) return; this.bgGain = this.ctx.createGain(); this.bgGain.gain.value = this.isMuted ? 0 : 0.20; this.bgGain.connect(this.ctx.destination); const arpPattern = [130.81, 155.56, 130.81, 196.00, 130.81, 233.08, 130.81, 196.00]; let step = 0; setInterval(() => { if (this.isMuted) return; const now = this.ctx.currentTime; const currentStep = step % 8; if (currentStep % 4 === 0) { const kickOsc = this.ctx.createOscillator(); const kickGain = this.ctx.createGain(); kickOsc.frequency.setValueAtTime(100, now); kickOsc.frequency.exponentialRampToValueAtTime(10, now + 0.15); kickGain.gain.setValueAtTime(0.8, now); kickGain.gain.exponentialRampToValueAtTime(0.01, now + 0.15); kickOsc.connect(kickGain); kickGain.connect(this.bgGain); kickOsc.start(now); kickOsc.stop(now + 0.2); } const freq = arpPattern[currentStep]; if (freq) { const osc = this.ctx.createOscillator(); const gain = this.ctx.createGain(); osc.type = 'sawtooth'; osc.frequency.value = freq; gain.gain.setValueAtTime(0.1, now); gain.gain.exponentialRampToValueAtTime(0.01, now + 0.1); osc.connect(gain); gain.connect(this.bgGain); osc.start(now); osc.stop(now + 0.15); } step++; }, 140); }, playClick: function() { if (!this.ctx || this.isMuted) return; const osc = this.ctx.createOscillator(); const gain = this.ctx.createGain(); osc.type = 'square'; osc.frequency.setValueAtTime(800, this.ctx.currentTime); osc.frequency.exponentialRampToValueAtTime(300, this.ctx.currentTime + 0.05); gain.gain.setValueAtTime(0.05, this.ctx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, this.ctx.currentTime + 0.05); osc.connect(gain); gain.connect(this.ctx.destination); osc.start(); osc.stop(this.ctx.currentTime + 0.05); }, playTransition: function() { if (!this.ctx || this.isMuted) return; const osc = this.ctx.createOscillator(); const gain = this.ctx.createGain(); osc.type = 'sine'; osc.frequency.setValueAtTime(400, this.ctx.currentTime); osc.frequency.exponentialRampToValueAtTime(100, this.ctx.currentTime + 0.2); gain.gain.setValueAtTime(0.1, this.ctx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, this.ctx.currentTime + 0.2); osc.connect(gain); gain.connect(this.ctx.destination); osc.start(); osc.stop(this.ctx.currentTime + 0.2); }, playError: function() { if (!this.ctx || this.isMuted) return; const osc = this.ctx.createOscillator(); const gain = this.ctx.createGain(); osc.type = 'sawtooth'; osc.frequency.setValueAtTime(150, this.ctx.currentTime); osc.frequency.exponentialRampToValueAtTime(80, this.ctx.currentTime + 0.3); gain.gain.setValueAtTime(0.2, this.ctx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, this.ctx.currentTime + 0.3); osc.connect(gain); gain.connect(this.ctx.destination); osc.start(); osc.stop(this.ctx.currentTime + 0.3); }, playSuccess: function() { if (!this.ctx || this.isMuted) return; const now = this.ctx.currentTime; const playNote = (freq, time) => { const osc = this.ctx.createOscillator(); const gain = this.ctx.createGain(); osc.frequency.value = freq; gain.gain.setValueAtTime(0.15, time); gain.gain.exponentialRampToValueAtTime(0.001, time + 0.4); osc.connect(gain); gain.connect(this.ctx.destination); osc.start(time); osc.stop(time + 0.4); }; playNote(523.25, now); playNote(659.25, now + 0.1); playNote(783.99, now + 0.2); playNote(1046.50, now + 0.3); } }; const app = { player: { avatar: '🤖', gametag: '', missionCode: '', xp: 0, profileName: '' }, currentStage: 0, currentTarget: 'pc', currentSelectedOS: null, capturedNodesCount: 0, localUsefulKwh: 0, localWasteKwh: 0, hwCloudBgGB: 0, cloudActiveGB: 0, cloudBackgroundGB: 0, cloudActiveKwh: 0, cloudBackgroundKwh: 0, dailyCharges: 0, tatticheCompletate: 0, ninjaCompletate: 0, typeWriterInterval: null, introShown: false, dossierArchive: [], viewedDiamonds: new Set(), clashCurrentIndex: 0, currentOverrideTarget: null, scannedTargets: new Set(), wattOro: 0, isPattoSigned: false, isFamilyPattoSigned: false, familyPhotoBase64: '', bioTimer: null, currentDiaryGametag: '', actionKeys: 0, unlockedActions: new Set(), strategyData: { 'strat-rete': { tech: "DATI DECRITTATI: L'EFFETTO PONTE RADIO\n\nTrasmettere dati via etere (4G/5G) richiede enormi antenne sempre attive. Il Wi-Fi usa i cavi fisici e richiede fino a 5 volte meno energia.", action: "Scarica film, giochi o aggiornamenti pesanti SOLO quando sei connesso al Wi-Fi. Oltre a non esaurire i Giga del tuo piano tariffario, abbatterai drasticamente l'energia bruciata dalla rete mobile!" }, 'strat-res': { tech: "DATI DECRITTATI: LA TRAPPOLA DEI PIXEL\n\nPer trasmettere un video in 4K il datacenter deve calcolare e inviare fino a 7 volte più dati rispetto al normale HD.", action: "Imposta YouTube o Netflix a 1080p o 720p quando sei su cellulare. Il tuo occhio non noterà alcuna differenza sullo schermo piccolo, ma risparmierai una quantità immensa di dati e batteria!" }, 'strat-ai': { tech: "DATI DECRITTATI: IL CERVELLO DI SILICIO\n\nLe I.A. per generare risposte usano potentissime schede video nei server, consumando tantissima elettricità e acqua per il raffreddamento.", action: "Usa le I.A. generative (come ChatGPT) solo per compiti scolastici complessi, riassunti o creatività. Se ti serve solo trovare un sito, una definizione o il meteo, usa il motore di ricerca classico: risparmierai 10 volte l'energia per lo stesso identico risultato!" }, 'strat-social': { tech: "DATI DECRITTATI: IL PARADOSSO SOCIAL\n\nPer garantirti zero attese mentre fai scroll, i Social scaricano di nascosto decine di video che forse non guarderai mai.", action: "Entra nelle impostazioni (TikTok, Instagram) e attiva il 'Risparmio Dati'. Toglierai il pilota automatico all'app, costringendo i server a inviare i dati solo per i video che decidi tu di riprodurre." }, 'strat-vampire': { tech: "DATI DECRITTATI: L'ILLUSIONE DELLO SPEGNIMENTO\n\. Le console moderne in 'Avvio Rapido' non si spengono mai davvero, succhiando energia dalla presa H24 per restare connesse.", action: "Vai nelle impostazioni e scegli lo 'Spegnimento Completo'. Aspettare 10 secondi in più per l'accensione eliminerà il Vampire Drain, facendo risparmiare alla tua famiglia decine di euro all'anno sulla bolletta!" }, 'strat-litio': { tech: "DATI DECRITTATI: IL PARADOSSO DELLA SPINA\n\nCostruire un telefono nuovo genera circa 80 kg di CO2. Ricaricarlo tutti i giorni per un anno intero genera meno di 2 kg.", action: "Evita di far spegnere il telefono allo 0% e attiva la 'Ricarica Ottimizzata' nelle impostazioni. Ridurrai lo stress chimico della batteria: il tuo device durerà 4 o 5 anni invece di 2. Far vivere a lungo l'hardware è la mossa ecologica ed economica più potente in assoluto!" } }, clashQuestions: [ { q: "I SOCIAL NETWORK CONSUMANO ENERGIA, MA CERTAMENTE MENO DI TANTE ALTRE ATTIVITÀ ONLINE, COME INVIARE MAIL, LEGGERE NOTIZIE O NAVIGARE SUI SITI WEB.", ans: false, msg: "Sembrano app leggere, ma a causa di miliardi di utenti connessi simultaneamente, i Social Network (uniti a video streaming e gaming) generano oltre il 70% di tutto il traffico globale dei datacenter.", chart: `
SITI WEB E EMAIL (TESTO)
SOCIAL, VIDEO E GAMING> 70%
` }, { q: "GUARDARE VIDEO PER 30 MINUTI SU YOUTUBE HD CONSUMA MOLTA PIÙ ENERGIA RISPETTO A SCORRERE VELOCEMENTE TIKTOK PER 30 MINUTI.", ans: false, msg: "YouTube scarica solo il video scelto. L'algoritmo di TikTok pre-carica costantemente in background decine di video HD per garantirti zero attese.\nSe fai 'swipe' rapido, forzi i server a consumare energia per contenuti che non hai mai guardato.", chart: `
YOUTUBE HD (SOLO VIDEO SCELTO)~0.4 GB
TIKTOK (PRE-LOAD CONTINUO)~1.2 GB
` }, { q: "FORZARE UN VIDEO YOUTUBE IN 4K DAL CELLULARE FA FATICARE DI PIÙ I SERVER, MA ALMENO VEDI UN'IMMAGINE MOLTO PIÙ DETTAGLIATA.", ans: false, msg: "Richiedere un flusso 4K costringe il datacenter a inviare fino a 8 volte la mole di dati di un normale video HD.\nMa su uno schermo da 6 pollici, il tuo occhio non può notare la differenza con un 1080p. Risultato? Sprecate gigabyte e batteria inutilmente.", chart: `
STREAMING HD (1080p)0.9 GB/h
STREAMING 4K (SPRECO INVISIBILE)7.0 GB/h
` }, { q: "FARE UNA RICERCA TRAMITE INTELLIGENZA ARTIFICIALE (ES. CHATGPT) CONSUMA ESATTAMENTE COME UNA NORMALE RICERCA SU GOOGLE.", ans: false, msg: "Una ricerca web classica estrae solo un link da un indice.\nL'Intelligenza Artificiale, invece, deve \"ragionare\" e generare la risposta parola per parola usando potentissime schede video.\nRisultato? Una ricerca IA consuma circa 10 volte l'energia di una ricerca standard.", chart: `
1 RICERCA WEB CLASSICA (GOOGLE)0.3 Wh
1 RICERCA CON I.A. (ES. CHATGPT)3.0 Wh
` } ], overrideTargets: [ { id: 't-battery', name: 'SMARTPHONE', icon: '🔋', trigger: 'USURA CHIMICA DA RICARICA', action: 'IMPOSTAZIONI > BATTERIA > RICARICA OTTIMIZZATA (O LIMITE 80%)', xp: 50, appLink: 'hardware_battery', reason: "Mantenere la batteria tra il 20% e l'80% non fa risparmiare sulla bolletta, ma dimezza l'usura chimica del litio. Il tuo telefono durerà anni in più prima di doverlo cambiare, salvando all'istante circa 80 kg di CO2!" }, { id: 't-tiktok', name: 'TIKTOK', icon: '', trigger: 'PRE-CARICAMENTO INVISIBILE', action: 'IMPOSTAZIONI > RISPARMIO DATI > ON', xp: 50, appLink: 'https://www.tiktok.com/', reason: "L'algoritmo scarica i 5 video successivi prima ancora che tu li veda. Se scorri via, i server hanno faticato per nulla. Il Risparmio Dati costringe l'app a scaricare solo ciò che guardi." }, { id: 't-ig', name: 'INSTAGRAM', icon: '', trigger: 'AUTOPLAY REELS', action: 'IMPOSTAZIONI E PRIVACY > USO DEI DATI > USA MENO DATI', xp: 50, appLink: 'instagram://app', reason: "Ogni volta che apri l'app, i video partono da soli scaricando decine di Megabyte in pochi secondi. Fermare l'autoplay toglie il pilota automatico: i server si attivano solo quando decidi tu." }, { id: 't-wa', name: 'WHATSAPP', icon: '', trigger: 'DOWNLOAD AUTO IN 4G', action: 'IMPOSTAZIONI > SPAZIO E DATI > SU RETE MOBILE > DESELEZIONA TUTTO', xp: 50, appLink: 'whatsapp://app', reason: "Trasportare dati in 4G costa fino a 5 volte più energia rispetto al Wi-Fi. Bloccando il download per strada, scaricherai i meme la sera usando la fibra ottica, molto più ecologica." }, { id: 't-yt', name: 'YOUTUBE', icon: '', trigger: 'RISOLUZIONE 4K SPRECATA', action: 'IMPOSTAZIONI > PREFERENZE QUALITÀ > RETE MOBILE: RISPARMIO DATI', xp: 50, appLink: 'https://www.youtube.com/', reason: "Su uno schermo da 6 pollici l'occhio non vede la differenza tra HD e 4K. Ma per inviarti il 4K, i server sudano 4 volte di più e i ripetitori bruciano giga inutili." }, { id: 't-twitch', name: 'TWITCH', icon: '', trigger: 'STREAMING PASSIVO', action: 'IMPOSTAZIONI > QUALITÀ > SOLO AUDIO (SE ASCOLTI SOLO)', xp: 50, appLink: 'https://twitch.tv/', reason: "Se metti una live in sottofondo mentre fai altro, stai scaricando gigabyte di video che non guardi. La modalità 'Solo Audio' taglia il consumo del 90%." }, { id: 't-netflix', name: 'NETFLIX', icon: '', trigger: 'ALTA QUALITÀ IN 4G', action: 'IMPOSTAZIONI APP > USO DATI CELLULARE > RISPARMIO DATI', xp: 50, appLink: 'https://netflix.com/', reason: "Scaricare un film in 4G brucia molta più energia che in Wi-Fi. Impostando il limite, i server comprimeranno il video riducendo drasticamente l'impatto sulla rete mobile." }, { id: 't-telegram', name: 'TELEGRAM', icon: '', trigger: 'AUTODOWNLOAD FILE PESANTI', action: 'IMPOSTAZIONI > DATI E ARCHIVIO > AUTODOWNLOAD > DISATTIVA IN 4G', xp: 50, appLink: 'tg://', reason: "Telegram permette l'invio di file enormi fino a 2GB! Se sei in una chat di gruppo, potresti scaricare decine di video pesantissimi in 4G senza neanche accorgertene, esaurendo Giga e batteria." }, { id: 't-roblox', name: 'ROBLOX', icon: '', trigger: 'BATTERY DRAIN DA GRAFICA 3D', action: 'IN GIOCO > SETTINGS > GRAPHICS MODE > MANUAL (ABBASSA IL LIVELLO)', xp: 50, appLink: 'https://roblox.com/', reason: "I mondi 3D ibridi come Roblox spingono la scheda grafica del telefono (GPU) al massimo. Abbassare la grafica salva la batteria, riduce il calore e allunga la vita del dispositivo." }, { id: 't-console', name: 'CONSOLE', icon: '', trigger: 'STANDBY DI RETE H24', action: 'IMPOSTAZIONI > RISPARMIO ENERGIA > SPEGNIMENTO COMPLETO', xp: 80, appLink: 'hardware_joypad', reason: "In 'Avvio Rapido' la console resta accesa di nascosto H24. Alla fine dell'anno, avrà consumato più corrente mentre era 'spenta' rispetto alle ore in cui hai giocato!" }, { id: 't-tv', name: 'SMART TV', icon: '', trigger: 'FAST START E TELEMETRIA', action: 'IMPOSTAZIONI TV > SISTEMA / RETE > DISATTIVA AVVIO RAPIDO', xp: 80, appLink: 'hardware_remote', reason: "Spegnere col telecomando disattiva solo lo schermo. La TV resta connessa per accendersi in 1 secondo o per inviare dati sulle tue abitudini (Telemetria). Stacca la spina virtuale!" } ], init: function() { this.bindEvents(); this.initDiaryEvents(); }, bindEvents: function() { const self = this; document.body.addEventListener('click', () => { if (!audioFX.initialized) audioFX.init(); }, { once: true }); document.getElementById('btn-audio')?.addEventListener('click', (e) => { e.stopPropagation(); audioFX.toggleMute(); audioFX.playClick(); }); const savedGametag = localStorage.getItem('ecoquest_gametag'); const savedMission = localStorage.getItem('ecoquest_mission'); if (savedGametag && document.getElementById('gametag')) { document.getElementById('gametag').value = savedGametag; self.player.gametag = savedGametag; } if (savedMission && document.getElementById('mission-code')) { document.getElementById('mission-code').value = savedMission; self.player.missionCode = savedMission; } if (savedGametag && savedGametag.length >= 3 && savedMission && savedMission.length >= 4) { const btn = document.getElementById('btn-start-game'); if (btn) btn.removeAttribute('disabled'); } const avatars = document.querySelectorAll('.avatar-option'); avatars.forEach(opt => { opt.addEventListener('click', function() { audioFX.playClick(); avatars.forEach(el => el.classList.remove('opt-active')); this.classList.add('opt-active'); self.player.avatar = this.dataset.avatar; checkInput(); }); }); const checkInput = () => { const gametagInput = document.getElementById('gametag'); const missionCodeInput = document.getElementById('mission-code'); const btn = document.getElementById('btn-start-game'); if (!gametagInput || !missionCodeInput || !btn) return; if (gametagInput.value.trim().length >= 3 && missionCodeInput.value.trim().length >= 4) { btn.removeAttribute('disabled'); self.player.gametag = gametagInput.value.trim().toUpperCase(); self.player.missionCode = missionCodeInput.value.trim().toUpperCase(); } else { btn.setAttribute('disabled', 'true'); } }; ['input', 'change', 'keyup'].forEach(evt => { document.getElementById('gametag')?.addEventListener(evt, () => { checkInput(); const val = document.getElementById('gametag').value.trim().toUpperCase(); if(val) localStorage.setItem('ecoquest_gametag', val); }); document.getElementById('mission-code')?.addEventListener(evt, () => { checkInput(); const val = document.getElementById('mission-code').value.trim().toUpperCase(); if(val) localStorage.setItem('ecoquest_mission', val); }); }); const bioBtn = document.getElementById('btn-biometric-scan'); const bioStatus = document.getElementById('biometric-status'); const startBioScan = (e) => { e.preventDefault(); if (self.isPattoSigned) return; audioFX.playClick(); bioStatus.innerText = "VERIFICA IMPRONTA IN CORSO..."; bioStatus.style.color = "var(--yellow-gold)"; bioBtn.style.transform = "scale(0.95)"; self.bioTimer = setTimeout(() => { self.isPattoSigned = true; audioFX.playSuccess(); bioBtn.classList.add('signed'); bioBtn.innerHTML = ''; bioBtn.style.transform = "scale(1)"; bioStatus.innerText = "SIGILLO BIOMETRICO VALIDATO ✔️"; bioStatus.style.color = "var(--lime-green)"; try { localStorage.setItem('ecoquest_signed_' + self.player.gametag, 'true'); } catch(e) {} setTimeout(() => { document.getElementById('patto-signature-box').style.display = 'none'; document.getElementById('patto-actions-view').style.display = 'flex'; }, 3000); self.calculateWattOro(); }, 2000); }; const cancelBioScan = () => { if (self.isPattoSigned) return; if (self.bioTimer) clearTimeout(self.bioTimer); bioBtn.style.transform = "scale(1)"; bioStatus.innerText = "SCANSIONE INTERROTTA. TENERE PREMUTO PER 2 SECONDI."; bioStatus.style.color = "var(--red-neon)"; }; if (bioBtn) { bioBtn.addEventListener('mousedown', startBioScan); bioBtn.addEventListener('mouseup', cancelBioScan); bioBtn.addEventListener('mouseleave', cancelBioScan); bioBtn.addEventListener('touchstart', startBioScan); bioBtn.addEventListener('touchend', cancelBioScan); } document.getElementById('gametag')?.addEventListener('blur', function() { const gt = this.value.trim().toUpperCase(); if (gt.length >= 3) { self.player.gametag = gt; localStorage.setItem('ecoquest_gametag', gt); const getUserUrl = window.location.origin + '/wp-json/ecoquest/v1/user/' + encodeURIComponent(gt); fetch(getUserUrl) .then(res => { if (!res.ok) throw new Error("Utente non trovato"); return res.json(); }) .then(serverData => { self.player.missionCode = serverData.student_profile.mission_code; self.player.avatar = serverData.student_profile.avatar; self.player.xp = serverData.game_metrics.xp_totali; self.isPattoSigned = serverData.game_metrics.patto_signed; self.isFamilyPattoSigned = serverData.game_metrics.family_patto_signed || false; self.player.profileName = serverData.student_profile.agent_title; const missionInput = document.getElementById('mission-code'); if (missionInput && serverData.student_profile.mission_code) { missionInput.value = serverData.student_profile.mission_code; localStorage.setItem('ecoquest_mission', serverData.student_profile.mission_code); } let remoteDiary = serverData.diary_bordo; if (typeof remoteDiary === 'string') { try { remoteDiary = JSON.parse(remoteDiary); } catch(e) {} } if (remoteDiary && remoteDiary.logs) { localStorage.setItem('ecoquest_diary_' + gt, JSON.stringify(remoteDiary)); } if (serverData.student_profile.avatar) { document.querySelectorAll('.avatar-option').forEach(el => { if (el.dataset.avatar === serverData.student_profile.avatar) { document.querySelectorAll('.avatar-option').forEach(o => o.classList.remove('opt-active')); el.classList.add('opt-active'); } }); } const btn = document.getElementById('btn-start-game'); if (btn) btn.removeAttribute('disabled'); self.showCyberPopup(`PROFILO ESISTENTE RICONOSCIUTO DAL CLOUD!\n\nAGENTE: ${gt}\nMISSIONE: ${self.player.missionCode}\nXP RECUPERATI: ${self.player.xp}\n\nClicca sul tasto sottostante per aprire direttamente il tuo Diario di Bordo.`, () => { const diarioModal = document.getElementById('diario-modal'); const loginView = document.getElementById('diario-login-view'); const checkinView = document.getElementById('diario-checkin-view'); const inputGt = document.getElementById('diario-input-gametag'); const welcomeTxt = document.getElementById('diario-welcome-txt'); if(inputGt) inputGt.value = gt; self.currentDiaryGametag = gt; if(loginView) loginView.style.display = 'none'; if(checkinView) checkinView.style.display = 'block'; if(welcomeTxt) welcomeTxt.innerText = `DIARIO DI BORDO AGENTE: ${gt}`; self.renderDiaryLogs(gt); if(diarioModal) diarioModal.style.display = 'flex'; }, null, "[ 📓 VAI AL DIARIO ]"); }) .catch(() => { if(!self.introShown) { self.introShown = true; self.showCyberPopup(`BENVENUTO, ECO-HACKER.\n\nI TUOI DEVICE E LE TUE APP HANNO IMPOSTAZIONI DI FABBRICA ("DEFAULT"), CHE SPESSO SERVONO SOLO A BRUCIARE ENERGIA E DATI.\n\nINSERISCI I TUOI DATI PER INIZIARE L'INDAGINE, TAGLIARE GLI SPRECHI E SBLOCCARE VANTAGGI REALI.`); } }); } }); document.getElementById('btn-start-game')?.addEventListener('click', function(e) { e.preventDefault(); const gt = self.player.gametag; if (!gt) return; const getUserUrl = window.location.origin + '/wp-json/ecoquest/v1/user/' + encodeURIComponent(gt); fetch(getUserUrl) .then(res => { if (!res.ok) throw new Error("Utente non trovato"); return res.json(); }) .then(serverData => { self.player.missionCode = serverData.student_profile.mission_code; self.player.avatar = serverData.student_profile.avatar; self.player.xp = serverData.game_metrics.xp_totali; self.isPattoSigned = serverData.game_metrics.patto_signed; self.isFamilyPattoSigned = serverData.game_metrics.family_patto_signed || false; self.player.profileName = serverData.student_profile.agent_title; localStorage.setItem('ecoquest_gametag', gt); if (serverData.student_profile.mission_code) { localStorage.setItem('ecoquest_mission', serverData.student_profile.mission_code); } if (self.isPattoSigned) { localStorage.setItem('ecoquest_signed_' + gt, 'true'); } if (self.isFamilyPattoSigned) { localStorage.setItem('ecoquest_family_signed_' + gt, 'true'); } let remoteDiary = serverData.diary_bordo; if (typeof remoteDiary === 'string') { try { remoteDiary = JSON.parse(remoteDiary); } catch(e) {} } if (remoteDiary && remoteDiary.logs) { localStorage.setItem('ecoquest_diary_' + gt, JSON.stringify(remoteDiary)); } document.getElementById('main-hud').style.display = 'flex'; document.getElementById('hud-gametag').innerText = gt; document.getElementById('hud-avatar-icon').innerText = self.player.avatar; self.updateXpHud(0); self.showCyberPopup(`BENTORNATO, AGENTE ${gt}!\n\nPROFILO E PROGRESSI RECUPERATI DAL CLOUD.\n\nACCESSO DIRETTO AL DIARIO DI BORDO (CRONACHE ECO-HACKER).`, () => { const diarioModal = document.getElementById('diario-modal'); const loginView = document.getElementById('diario-login-view'); const checkinView = document.getElementById('diario-checkin-view'); const inputGt = document.getElementById('diario-input-gametag'); const welcomeTxt = document.getElementById('diario-welcome-txt'); if(inputGt) inputGt.value = gt; self.currentDiaryGametag = gt; if(loginView) loginView.style.display = 'none'; if(checkinView) checkinView.style.display = 'block'; if(welcomeTxt) welcomeTxt.innerText = `DIARIO DI BORDO AGENTE: ${gt}`; self.renderDiaryLogs(gt); if(diarioModal) diarioModal.style.display = 'flex'; }, null, "[ 📓 VAI AL DIARIO ]"); }) .catch(err => { localStorage.setItem('ecoquest_gametag', gt); localStorage.setItem('ecoquest_mission', self.player.missionCode); self.showCyberPopup(`INIZIO FASE 1: SCANNER LOCALE.\n\nL'OBIETTIVO È REGISTRARE I CONSUMI HARDWARE E STANARE IL 'VAMPIRE DRAIN': L'ENERGIA CHE I TUOI DEVICE SPRECANO IN CASA ANCHE QUANDO CREDI SIANO SPENTI.\n\nSELEZIONA I BERSAGLI E CONFIGURA I PARAMETRI.`, () => { document.getElementById('main-hud').style.display = 'flex'; document.getElementById('hud-gametag').innerText = self.player.gametag; document.getElementById('hud-avatar-icon').innerText = self.player.avatar; self.showStage(1); self.setTarget('pc'); }); }); }); document.getElementById('btnTargetPC')?.addEventListener('click', function() { self.setTarget('pc'); }); document.getElementById('btnTargetTV')?.addEventListener('click', function() { self.setTarget('tv'); }); document.getElementById('btnTargetConsole')?.addEventListener('click', function() { self.setTarget('console'); }); document.getElementById('btnTargetPhone')?.addEventListener('click', function() { self.setTarget('phone'); }); document.getElementById('btnTargetCharger')?.addEventListener('click', function() { self.setTarget('charger'); }); document.getElementById('btnTargetRouter')?.addEventListener('click', function() { self.setTarget('router'); }); document.getElementById('btnCaptureSketch')?.addEventListener('click', function() { self.openProfilerModal(); }); // 1. Dichiara il contatore globale all'inizio (o assicurati che non venga sovrascritto) self.scanCount = self.scanCount || 0; const MAX_SCANS = 6; document.getElementById('btn-confirm-hw')?.addEventListener('click', function() { // 2. Esegue il salvataggio dei dati e l'animazione del tuo script originale self.processHwProfile(); // 3. Incrementa il contatore delle scansioni effettuate self.scanCount++; // 4. Verifica se abbiamo raggiunto il limite di 6 scansioni if (self.scanCount >= MAX_SCANS) { // FASE COMPLETATA: Disattiviamo il sistema const btnCapture = document.getElementById('btnCaptureSketch'); if (btnCapture) { btnCapture.disabled = true; btnCapture.style.pointerEvents = 'none'; btnCapture.style.opacity = '0.4'; btnCapture.style.filter = 'grayscale(100%)'; btnCapture.innerHTML = '✔️ TUTTI I NODI SCANSIONATI'; } // Opzionale: scurisce l'area del mirino per far capire che è inattiva const viewfinderArea = document.querySelector('.viewfinder'); if (viewfinderArea) { viewfinderArea.style.opacity = '0.5'; viewfinderArea.style.pointerEvents = 'none'; } // Mostra il pulsante per procedere al Cloud (Diagnosi) const btnGoCloud = document.getElementById('btn-go-to-diagnosi'); if (btnGoCloud) { btnGoCloud.style.display = 'block'; } } else { // NON ABBIAMO ANCORA FINITO (Meno di 6 scansioni) // Aspettiamo un attimo che l'interfaccia si aggiorni con il box verde, // poi selezioniamo automaticamente il primo target grigio (non ancora fatto) disponibile. setTimeout(() => { // Cerchiamo i bottoni originali usando una classe che sappiamo scomparire quando diventano verdi // Se i bottoni grigi perdono '.btn-target' o '.target-active' quando diventano verdi, usiamo quello const remainingTargets = document.querySelectorAll('.target-selector .btn-target:not(.target-active)'); // Sostituisci ':not(.target-active)' con la logica corretta se necessario // Un approccio più sicuro se i bottoni verdi non sono più pulsanti cliccabili: const clickableTargets = Array.from(document.querySelectorAll('.target-selector button.btn-target')); // Troviamo il primo bottone che non contiene il segno di spunta '✓' (o altra classe che usi per i verdi) const nextTarget = clickableTargets.find(btn => !btn.innerText.includes('✓')); if (nextTarget) { nextTarget.click(); } }, 500); } }); document.getElementById('btn-go-to-diagnosi')?.addEventListener('click', function(e) { e.preventDefault(); self.showCyberPopup("INIZIO FASE 2: PROFILAZIONE CLOUD.\n\nIL CONSUMO FISICO DEI TUOI DISPOSITIVI È SOLO L'INIZIO.\n\nOGNI AZIONE CHE FAI E OGNI VIDEO CHE GUARDI SVEGLIANO ENORMI SERVER LONTANI DA TE, CHE BRUCIANO CORRENTE H24.\n\nDICHIARA LE TUE ABITUDINI SOFTWARE.\n\n⚠️ TIP: CLICCA SUI DIAMANTI PER DECRITTARE DATI SEGRETI E GUADAGNARE +20 XP.", () => { self.showStage(2); }); }); document.getElementById('btn-go-to-minigame')?.addEventListener('click', function(e) { e.preventDefault(); self.calculateCloudGB(); self.showCyberPopup("ATTENZIONE: BLOCCO DI SICUREZZA (DATA CLASH).\n\nPRIMA DI VEDERE I RISULTATI DELLA TUA RICERCA, DEVI DIMOSTRARE DI NON ESSERE UN BOT INFILTRATO.\n\nSMASCHERA LE ILLUSIONI DIGITALI SUI CONSUMI PER BYPASSARE IL FIREWALL.", () => { self.clashCurrentIndex = 0; self.renderClashQuestion(); self.showStage('2bis'); }); }); document.getElementById('btn-generate-diagnosis')?.addEventListener('click', function(e) { e.preventDefault(); self.showCyberPopup("ACCESSO CONSENTITO.\nFASE 3: L'ICEBERG PERSONALE.\n\nLA PUNTA VISIBILE È L'HARDWARE CHE HAI IN CASA E I SUOI CONSUMI NASCOSTI.\nLA MASSA SOMMERSA È L'ENORME ENERGIA RICHIESTA DALLE ANTENNE E DALLE DATACENTER PER INVIARE I DATI.\n\nANALIZZA I TUOI GRAFICI E SCOPRI IL TUO IMPATTO.", () => { self.generateIceberg(); }); }); document.getElementById('btn-play-reality')?.addEventListener('click', function(e) { e.preventDefault(); audioFX.playClick(); document.getElementById('reality-trigger-box').style.display = 'none'; const optionsContainer = document.getElementById('reality-options-container'); optionsContainer.style.display = 'flex'; optionsContainer.scrollIntoView({ behavior: 'smooth', block: 'center' }); self.animateBatteries(self.dailyCharges); }); document.getElementById('btn-go-to-macro')?.addEventListener('click', function(e) { e.preventDefault(); self.showCyberPopup("CREDI CHE I GRANDI MOSTRI SUCCHIA-ENERGIA SIANO SOLO LE FABBRICHE CON LE CIMINIERE O LE METROPOLI ILLUMINATE? SBAGLIATO.\n\nOGGI, IL MONDO 'INVISIBILE' DI INTERNET, DELLE APP E DEI SERVER CONSUMA DA SOLO L'ENERGIA DI 1/3 DI TUTTE LE CASE DEL PIANETA.\n\nI TUOI GIGA PESANO. SCOPRI QUANTO.", () => { self.showStage('3-macro'); setTimeout(() => { document.querySelectorAll('#stage-3-macro .macro-bar').forEach(bar => { const w = bar.getAttribute('data-width'); if(w) bar.style.width = w; }); }, 200); }); }); document.getElementById('btn-go-to-tactics')?.addEventListener('click', function(e) { e.preventDefault(); self.showCyberPopup("FASE 4: ZONA DI OVERRIDE.\n\nORA CHE CONOSCI L'ENORMITÀ DEI CONSUMI GLOBALI DELLA RETE, È IL MOMENTO DI AGIRE.\n\nSTUDIA IL CODICE DELL'ECO-HACKER E RICERCA LE OPPORTUNITÀ DI AZIONE REALI.\n\nPOI SCONFIGGI LE IMPOSTAZIONI DI FABBRICA DELLE TUE APP E CARICA LE PROVE DEGLI HACK.", () => { self.showStage(4); self.renderTacticsGrid(); setTimeout(() => { document.querySelectorAll('#stage-4 .strat-bar').forEach(bar => { const w = bar.getAttribute('data-width'); if(w) bar.style.width = w; }); }, 300); }); }); document.getElementById('modal-file-upload')?.addEventListener('change', function(e) { if(e.target.files && e.target.files[0]) { self.processScreenshotModal(e.target.files[0], this.getAttribute('data-action')); this.value = ''; } }); document.getElementById('btn-go-to-debriefing')?.addEventListener('click', function(e) { e.preventDefault(); self.generateDebriefing(); }); }, openFamilyDealModal: function() { audioFX.playClick(); const modal = document.getElementById('family-deal-modal'); if(this.isFamilyPattoSigned) { document.getElementById('family-patto-status-msg').innerText = "PATTO DI FAMIGLIA GIÀ FIRMATO E BONUS +200 XP ACQUISITO ✔️"; document.getElementById('btn-confirm-family-patto').style.display = 'none'; } modal.style.display = 'flex'; }, closeFamilyDealModal: function() { this.stopFamilyCamera(); document.getElementById('family-deal-modal').style.display = 'none'; }, startFamilyCamera: async function() { audioFX.playClick(); const video = document.getElementById('familyCameraStream'); document.getElementById('family-photo-start-controls').style.display = 'none'; document.getElementById('family-camera-container').style.display = 'block'; if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { try { const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'user' }, audio: false }); video.srcObject = stream; } catch (err) { console.warn('Cam non disponibile:', err); alert("Impossibile accedere alla fotocamera. Verifica i permessi del browser."); document.getElementById('family-photo-start-controls').style.display = 'block'; document.getElementById('family-camera-container').style.display = 'none'; } } else { alert("La fotocamera non è supportata da questo browser."); } }, stopFamilyCamera: function() { const video = document.getElementById('familyCameraStream'); if (video && video.srcObject) { video.srcObject.getTracks().forEach(track => track.stop()); video.srcObject = null; } }, captureFamilyPhoto: function() { audioFX.playSuccess(); const video = document.getElementById('familyCameraStream'); const canvas = document.createElement('canvas'); const width = 480; const height = 360; canvas.width = width; canvas.height = height; const ctx = canvas.getContext('2d'); if(video && video.readyState === 4) { ctx.drawImage(video, 0, 0, width, height); } else { ctx.fillStyle = "#120F24"; ctx.fillRect(0, 0, width, height); } this.familyPhotoBase64 = canvas.toDataURL('image/jpeg'); this.stopFamilyCamera(); document.getElementById('family-camera-container').style.display = 'none'; const previewContainer = document.getElementById('family-photo-preview-container'); const previewImg = document.getElementById('family-photo-preview'); previewImg.src = this.familyPhotoBase64; previewContainer.style.display = 'block'; document.getElementById('family-patto-status-msg').innerText = "SELFIE DI SQUADRA ACQUISITO! PRONTO PER IL SIGILLO."; document.getElementById('btn-confirm-family-patto').removeAttribute('disabled'); }, retakeFamilyPhoto: function() { audioFX.playClick(); this.familyPhotoBase64 = ''; document.getElementById('family-photo-preview-container').style.display = 'none'; document.getElementById('btn-confirm-family-patto').setAttribute('disabled', 'true'); document.getElementById('family-patto-status-msg').innerText = "STATO: PATTO NON ANCORA FIRMATO CON IL SELFIE"; this.startFamilyCamera(); }, confirmFamilyPatto: function() { if(!this.familyPhotoBase64) { alert("Scatta prima il selfie di famiglia per sigillare l'accordo!"); return; } if(this.isFamilyPattoSigned) return; this.isFamilyPattoSigned = true; audioFX.playSuccess(); this.updateXpHud(200); try { localStorage.setItem('ecoquest_family_signed_' + this.player.gametag, 'true'); } catch(e) {} document.getElementById('family-patto-status-msg').innerText = "PATTO FIRMATO E SELFIE SQUADRA SALVATO! +200 XP AGGIUNTI 🌟"; document.getElementById('btn-confirm-family-patto').style.display = 'none'; this.showCyberPopup("🏆 PATTO DI FAMIGLIA SIGILLATO CON SUCCESSO!\n\nSei ufficialmente l'Energy Manager di casa. +200 XP aggiunti al tuo profilo!"); setTimeout(() => { this.closeFamilyDealModal(); }, 2000); }, openPattoModal: function() { audioFX.playClick(); document.getElementById('patto-user-gt').innerText = this.player.gametag || 'AGENTE'; document.getElementById('patto-energiadi-modal').style.display = 'flex'; }, initDiaryEvents: function() { const self = this; document.getElementById('btn-verify-diario-gametag')?.addEventListener('click', () => { audioFX.playClick(); const gtInput = document.getElementById('diario-input-gametag'); if (!gtInput) return; const gt = gtInput.value.trim().toUpperCase(); if (!gt || gt.length { if (!res.ok) throw new Error("Utente non trovato nel cloud"); return res.json(); }) .then(serverData => { self.player.gametag = serverData.student_profile.gametag; self.player.missionCode = serverData.student_profile.mission_code; self.player.avatar = serverData.student_profile.avatar; self.player.xp = serverData.game_metrics.xp_totali; self.isPattoSigned = serverData.game_metrics.patto_signed; self.isFamilyPattoSigned = serverData.game_metrics.family_patto_signed || false; let remoteDiary = serverData.diary_bordo; if (typeof remoteDiary === 'string') { try { remoteDiary = JSON.parse(remoteDiary); } catch(e) {} } if (remoteDiary && remoteDiary.logs) { localStorage.setItem('ecoquest_diary_' + gt, JSON.stringify(remoteDiary)); } if (self.isPattoSigned) { localStorage.setItem('ecoquest_signed_' + gt, 'true'); } if (self.isFamilyPattoSigned) { localStorage.setItem('ecoquest_family_signed_' + gt, 'true'); } proceedToDiaryView(gt); }) .catch(() => { proceedToDiaryView(gt); }); }); function proceedToDiaryView(gt) { self.currentDiaryGametag = gt; self.player.gametag = gt; const loginView = document.getElementById('diario-login-view'); const checkinView = document.getElementById('diario-checkin-view'); const welcomeTxt = document.getElementById('diario-welcome-txt'); if (loginView) loginView.style.display = 'none'; if (checkinView) checkinView.style.display = 'block'; if (welcomeTxt) welcomeTxt.innerText = `CRONACHE ECO-HACKER: ${gt}`; self.renderDiaryLogs(gt); } document.querySelectorAll('.btn-diario-status').forEach(btn => { btn.addEventListener('click', function() { audioFX.playClick(); const status = this.dataset.status; const gt = self.currentDiaryGametag || self.player.gametag; if (!gt) return; try { const storageKey = 'ecoquest_diary_' + gt; let diaryData = JSON.parse(localStorage.getItem(storageKey) || '{"logs":[]}'); const now = new Date(); if (diaryData.logs.length > 0) { const lastLog = new Date(diaryData.logs[diaryData.logs.length - 1].date); const diffHours = (now - lastLog) / (1000 * 60 * 60); if (diffHours STORICO CHECK-IN (CRONACHE ECO-HACKER):

"; diaryData.logs.forEach((l) => { const dStr = new Date(l.date).toLocaleDateString('it-IT', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); let emoji = "🟢"; if(l.status === 'parziale') emoji = "🟡"; if(l.status === 'occasionale') emoji = "🟠"; if(l.status === 'abbandono') emoji = "🔴"; html += `[${dStr}] ${emoji} Stato: ${l.status.toUpperCase()}
`; }); logBox.innerHTML = html; } catch (e) { logBox.innerHTML = "Errore nel caricamento dello storico."; } }, calculateWattOro: function() { const mult = this.isPattoSigned ? 2 : 1; this.wattOro = this.player.xp * mult; const woroVal = document.getElementById('woro-val'); if(woroVal) woroVal.innerText = this.wattOro.toLocaleString(); return this.wattOro; }, updateXpHud: function(amount) { this.player.xp += amount; const el = document.getElementById('xp-val'); el.innerText = this.player.xp; el.style.color = "#fff"; el.style.textShadow = "0 0 10px #fff"; setTimeout(() => { el.style.color = "var(--yellow-gold)"; el.style.textShadow = "none"; }, 500); this.calculateWattOro(); }, claimDiamondXp: function(diamondId, text) { audioFX.playClick(); if(!this.viewedDiamonds.has(diamondId)) { this.viewedDiamonds.add(diamondId); this.updateXpHud(20); const dVal = document.getElementById('diamond-val'); if(dVal) { dVal.innerText = this.viewedDiamonds.size; dVal.style.color = "#00f0ff"; dVal.style.textShadow = "0 0 10px #00f0ff"; setTimeout(() => { dVal.style.color = "#fff"; dVal.style.textShadow = "none"; }, 500); } this.showCyberPopup("💎 INFORMAZIONE DECRITTATA! (+20 XP)\n\n" + text); } else { this.showCyberPopup(text); } }, claimActionOpportunity: function(id) { audioFX.playClick(); const data = this.strategyData[id]; if (!data) return; const cleanActionText = data.action.replace(/✅ AZIONE ECO-HACKER:\s*/g, '').replace(/\n/g, '
'); const keyButtonHtml = `
CLICCA IL LUCCHETTO PER ESTRARRE LA REAL ACTION OPPORTUNITY
`; const actionBoxHtml = `
🔓 REAL ACTION OPPORTUNITY
${cleanActionText}
`; if(!this.viewedDiamonds.has(id)) { this.viewedDiamonds.add(id); this.updateXpHud(20); const dVal = document.getElementById('diamond-val'); if(dVal) { dVal.innerText = this.viewedDiamonds.size; dVal.style.color = "#00f0ff"; dVal.style.textShadow = "0 0 10px var(--cyan-electric)"; setTimeout(() => { dVal.style.color = "#fff"; dVal.style.textShadow = "none"; }, 500); } this.showCyberPopup("💎 INFORMAZIONE DECRITTATA! (+20 XP)\n\n" + data.tech, null, keyButtonHtml); } else { if(this.unlockedActions.has(id)) { this.showCyberPopup(data.tech, null, actionBoxHtml); } else { this.showCyberPopup(data.tech, null, keyButtonHtml); } } }, revealAction: function(id) { audioFX.playSuccess(); const data = this.strategyData[id]; if (!data) return; if(!this.unlockedActions.has(id)) { this.unlockedActions.add(id); this.updateXpHud(50); this.actionKeys++; const kVal = document.getElementById('key-val'); if(kVal) { kVal.innerText = this.actionKeys; kVal.style.color = "var(--yellow-gold)"; kVal.style.textShadow = "0 0 10px var(--yellow-gold)"; setTimeout(() => { kVal.style.color = "#fff"; kVal.style.textShadow = "none"; }, 500); } } const cleanActionText = data.action.replace(/✅ AZIONE ECO-HACKER:\s*/g, '').replace(/\n/g, '
'); const actionBoxHtml = `
🔓 REAL ACTION OPPORTUNITY (+50 XP)
${cleanActionText}
`; this.showCyberPopup("CONOSCENZA ESTRATTA CON SUCCESSO!\n\nEcco la tua opportunità d'azione per salvare energia:", null, actionBoxHtml); }, renderClashQuestion: function() { const qData = this.clashQuestions[this.clashCurrentIndex]; document.getElementById('clash-counter').innerText = `DOMANDA ${this.clashCurrentIndex + 1} / ${this.clashQuestions.length}`; document.getElementById('clash-question').innerText = qData.q; }, showCyberPopup: function(message, callback, chartHTML = null, buttonText = "[ RICEVUTO ]") { if(this.typeWriterInterval) clearInterval(this.typeWriterInterval); const popup = document.getElementById('cyber-popup'); const textContainer = document.getElementById('typewriter-text'); const btn = document.getElementById('btn-accept-mission'); const dynamicContainer = document.getElementById('popup-dynamic-content'); dynamicContainer.innerHTML = ''; btn.innerText = buttonText; popup.style.display = 'flex'; btn.style.display = 'none'; textContainer.innerHTML = ''; let i = 0; audioFX.playTransition(); this.typeWriterInterval = setInterval(() => { if (i '; else { textContainer.innerHTML += char; if (i % 3 === 0) audioFX.playClick(); } i++; } else { clearInterval(this.typeWriterInterval); textContainer.innerHTML += ''; if(chartHTML) { dynamicContainer.innerHTML = chartHTML; setTimeout(() => { const barre = dynamicContainer.querySelectorAll('.hud-bar-fill'); barre.forEach(barra => { barra.style.width = barra.getAttribute('data-width'); }); audioFX.playSuccess(); }, 100); } btn.style.display = 'block'; } }, 15); btn.onclick = () => { audioFX.playClick(); popup.style.display = 'none'; if(callback) callback(); }; }, handleClashAnswer: function(userAnswer) { const self = this; const qData = this.clashQuestions[this.clashCurrentIndex]; let finalMsg = ""; if (userAnswer === qData.ans) { audioFX.playSuccess(); finalMsg = "✔️ BYPASS SUPERATO!\nLa tua analisi è corretta.\n\nDATI DECRITTATI:\n" + qData.msg; } else { audioFX.playError(); finalMsg = "❌ ERRORE DI VALUTAZIONE!\nSei caduto nell'illusione di sistema.\n\nVERITÀ NASCOSTA:\n" + qData.msg; } this.showCyberPopup(finalMsg, function() { self.clashCurrentIndex++; if(self.clashCurrentIndex btn.classList.remove('target-active')); const badge = document.getElementById('targetLabelText'); const iconDisplay = document.getElementById('viewfinder-icon-display'); const targetData = { 'pc': { id: 'btnTargetPC', badge: 'TARGET: PC', icon: '' }, 'tv': { id: 'btnTargetTV', badge: 'TARGET: SMART TV', icon: '' }, 'console': { id: 'btnTargetConsole', badge: 'TARGET: CONSOLE', icon: '' }, 'phone': { id: 'btnTargetPhone', badge: 'TARGET: SMARTPHONE', icon: '' }, 'charger': { id: 'btnTargetCharger', badge: 'TARGET: CARICATORE', icon: '' }, 'router': { id: 'btnTargetRouter', badge: 'TARGET: ROUTER', icon: '' } }; if (targetData[target]) { document.getElementById(targetData[target].id)?.classList.add('target-active'); if (badge) badge.textContent = targetData[target].badge; if (iconDisplay) { iconDisplay.style.transform = 'scale(0.5)'; setTimeout(() => { // ATTENZIONE: Sostituito textContent con innerHTML per renderizzare il tag iconDisplay.innerHTML = targetData[target].icon; iconDisplay.style.transform = 'scale(1)'; }, 150); } } }, showStage: function(stageStr) { // Nascondi tutte le altre fasi document.querySelectorAll('.game-stage').forEach(el => { el.style.display = 'none'; }); this.currentStage = stageStr; const newEl = document.getElementById('stage-' + stageStr); if(newEl) { // Usa block al posto di flex per la Fase 2, che ha layout nativamente a blocco newEl.style.display = stageStr === 2 ? 'block' : 'flex'; // Garantiamo che l'opacità sia forzata a 1 scavalcando eventuali freeze dell'animazione CSS newEl.style.opacity = '1'; newEl.style.transform = 'translateY(0)'; } // Ritorna in cima alla pagina per una corretta visualizzazione window.scrollTo({ top: 0, behavior: 'smooth' }); }, openProfilerModal: function() { audioFX.playClick(); const modal = document.getElementById('profiler-modal'); const fieldsBox = document.getElementById('dynamic-profiler-fields'); let html = ""; const targetIcons = { 'pc': '', 'tv': '', 'console': '', 'phone': '', 'charger': '', 'router': '' }; this.currentTempIcon = targetIcons[this.currentTarget] || '⚡'; if(this.currentTarget === 'pc') { html = `
`; } else if(this.currentTarget === 'console') { html = `
`; } else if(this.currentTarget === 'tv') { html = `
`; } else if(this.currentTarget === 'phone') { html = `
`; } else if(this.currentTarget === 'router') { html = `
`; } else if(this.currentTarget === 'charger') { html = `
`; } fieldsBox.innerHTML = html; const introText = document.getElementById('profiler-intro'); if(this.currentTarget === 'charger') { document.getElementById('profiler-header').style.color = "var(--yellow-gold)"; document.getElementById('profiler-modal').querySelector('.cyber-modal-content').style.borderColor = "var(--yellow-gold)"; introText.innerText = "VAMPIRE DRAIN RILEVATO. IL CARICATORE A VUOTO CONSUMA ENERGIA INUTILMENTE."; introText.style.color = "var(--yellow-gold)"; } else { document.getElementById('profiler-header').style.color = "var(--cyan-electric)"; document.getElementById('profiler-modal').querySelector('.cyber-modal-content').style.borderColor = "var(--cyan-electric)"; introText.innerText = "INSERISCI I DATI REALI PER CALCOLARE L'IMPATTO."; introText.style.color = "#fff"; } modal.style.display = 'flex'; }, processHwProfile: function() { document.getElementById('profiler-modal').style.display = 'none'; let nodeUseful = 0; let nodeWaste = 0; let title = "", sub = "", isMalus = false, xpReward = 30; const annualDailyFactor = 365 / 1000; const annualWeeklyFactor = 52 / 1000; if(this.currentTarget === 'pc' || this.currentTarget === 'console' || this.currentTarget === 'tv') { const rest = document.getElementById('hw-rest')?.value || 'standby'; let hours = 0; if (this.currentTarget === 'pc') { title = "PC DESKTOP / LAPTOP"; sub = "PROFILO HW DINAMICO"; const pcType = document.getElementById('hw-pc-type')?.value || 'desktop_gaming'; const hLight = parseFloat(document.getElementById('hw-hours-light')?.value) || 0; const hHeavy = parseFloat(document.getElementById('hw-hours-heavy')?.value) || 0; hours = hLight + hHeavy; let wLight = 0, wHeavy = 0; switch(pcType) { case 'laptop_base': wLight = 15; wHeavy = 40; break; case 'laptop_gaming': wLight = 30; wHeavy = 120; break; case 'desktop_base': wLight = 60; wHeavy = 100; break; case 'desktop_gaming': wLight = 90; wHeavy = 400; break; } nodeUseful = (wLight * hLight + wHeavy * hHeavy) * annualWeeklyFactor; } else { title = this.currentTarget === 'tv' ? "SMART TV" : "CONSOLE"; sub = "PROFILO HW"; const watts = parseFloat(document.getElementById('hw-watts')?.value) || 100; hours = parseFloat(document.getElementById('hw-hours')?.value) || 0; nodeUseful = watts * hours * annualWeeklyFactor; } if(rest === 'standby') { let standbyW = this.currentTarget === 'tv' ? 3 : (this.currentTarget === 'pc' ? 5 : 12); nodeWaste = standbyW * (168 - hours) * annualWeeklyFactor; isMalus = true; } else if (rest === 'network') { let networkW = this.currentTarget === 'tv' ? 10 : (this.currentTarget === 'pc' ? 10 : 20); nodeWaste = networkW * (168 - hours) * annualWeeklyFactor; isMalus = true; sub = "STANDBY DI RETE ATTIVO"; if (this.currentTarget === 'console') { this.hwCloudBgGB += 520; } else if (this.currentTarget === 'tv') { this.hwCloudBgGB += 104; } else if (this.currentTarget === 'pc') { this.hwCloudBgGB += 260; } } xpReward = 40; } else if(this.currentTarget === 'phone') { const age = document.getElementById('hw-age')?.value || 'used'; const charges = parseFloat(document.getElementById('hw-charges')?.value) || 1; const habit = document.getElementById('hw-habit')?.value || 'precise'; title = "SMARTPHONE"; let capacity = 12; if(age === 'new') capacity = 15; if(age === 'veteran') capacity = 9; nodeUseful = capacity * charges * annualDailyFactor; if(habit === 'night') { nodeWaste = 8 * annualDailyFactor; isMalus = true; sub = "VAMPIRE DRAIN NOTTURNO"; } else if (habit === 'stress') { nodeWaste = (capacity * charges * 0.3) * annualDailyFactor; isMalus = true; sub = "STRESS TERMICO E USURA"; } else { nodeWaste = 0; sub = "CICLI OTTIMIZZATI"; } xpReward = 40; } else if(this.currentTarget === 'router') { const watts = parseFloat(document.getElementById('hw-watts')?.value) || 15; const rest = document.getElementById('hw-rest')?.value || 'h24'; title = "ROUTER WI-FI"; sub = "GATEWAY DOMESTICO"; if(rest === 'h24') { nodeUseful = watts * 16 * annualDailyFactor; nodeWaste = watts * 8 * annualDailyFactor; isMalus = true; sub = "H24 (SPRECO NOTTURNO)"; } else { nodeUseful = watts * 16 * annualDailyFactor; nodeWaste = 0; sub = "TIMER ATTIVO (OTTIMO)"; } xpReward = 50; } else if(this.currentTarget === 'charger') { const watts = parseFloat(document.getElementById('hw-watts')?.value) || 20; const rest = document.getElementById('hw-rest')?.value || 'h24'; title = "CARICATORE A VUOTO"; sub = "VAMPIRE DRAIN E USURA"; nodeUseful = 0; let hoursEmpty = 0; if (rest === 'h24') hoursEmpty = 24; else if (rest === 'notte') hoursEmpty = 8; nodeWaste = 1 * hoursEmpty * annualDailyFactor; isMalus = nodeWaste > 0; xpReward = 50; } nodeUseful = Math.round(nodeUseful * 100) / 100; nodeWaste = Math.round(nodeWaste * 100) / 100; this.localUsefulKwh += nodeUseful; this.localWasteKwh += nodeWaste; this.dossierArchive.push({ type: 'hardware_scan', target: title, status: isMalus ? 'VAMPIRE DRAIN' : 'OK', icon: this.currentTempIcon || '⚡' }); const grid = document.getElementById('dynamic-cards-grid'); const newCard = document.createElement('div'); newCard.className = `holo-card-item acquired ${isMalus ? 'malus' : ''}`; if (isMalus) audioFX.playError(); else audioFX.playSuccess(); newCard.innerHTML = `
${this.currentTempIcon || '⚡'}
${isMalus ? 'VAMPIRE DRAIN / SPRECO' : 'NODE OK'}
${title}
${sub}
UTILE: ${nodeUseful} kWh/y
${isMalus ? `SPRECO: ${nodeWaste} kWh/y` : ''}
⚡ +${xpReward} XP
`; grid.prepend(newCard); this.capturedNodesCount++; this.updateXpHud(xpReward); const nodesVal = document.getElementById('nodes-val'); if(nodesVal) { nodesVal.innerText = this.capturedNodesCount; nodesVal.style.color = "var(--lime-green)"; nodesVal.style.textShadow = "0 0 10px var(--lime-green)"; setTimeout(() => { nodesVal.style.color = "#fff"; nodesVal.style.textShadow = "none"; }, 500); } this.scannedTargets.add(this.currentTarget); const targetBtnMap = { 'pc': 'btnTargetPC', 'tv': 'btnTargetTV', 'console': 'btnTargetConsole', 'phone': 'btnTargetPhone', 'charger': 'btnTargetCharger', 'router': 'btnTargetRouter' }; const currentBtnId = targetBtnMap[this.currentTarget]; if (currentBtnId) { const btn = document.getElementById(currentBtnId); if (btn) { btn.classList.remove('target-active'); btn.classList.add('scanned'); btn.disabled = true; if (!btn.innerText.includes('✔')) { btn.innerText = '✔ ' + btn.innerText; } } } const allTargets = ['pc', 'tv', 'console', 'phone', 'charger', 'router']; const nextTarget = allTargets.find(t => !this.scannedTargets.has(t)); if (nextTarget) { this.setTarget(nextTarget); } else { document.querySelectorAll('.btn-target').forEach(btn => btn.classList.remove('target-active')); const badge = document.getElementById('targetLabelText'); if (badge) badge.textContent = 'TUTTI I TARGET CONFIGURATI ✔'; } document.getElementById('btn-go-to-diagnosi').style.display = 'block'; }, calculateCloudGB: function() { const streamH = parseFloat(document.getElementById('in-stream-h').value) || 0; const stream4kH = parseFloat(document.getElementById('in-stream-4k-h').value) || 0; const extremeH = parseFloat(document.getElementById('in-tiktok-h').value) || 0; const hybridH = parseFloat(document.getElementById('in-ibrido-h').value) || 0; const mediumH = parseFloat(document.getElementById('in-ig-h').value) || 0; const webH = parseFloat(document.getElementById('in-web-h').value) || 0; const msgHours = parseFloat(document.getElementById('in-msg-h')?.value) || 0; const msgType = document.getElementById('in-msg-type')?.value || 'media'; let msgGbPerHour = 0; switch(msgType) { case 'text': msgGbPerHour = 0.01; break; case 'media': msgGbPerHour = 0.15; break; case 'video': msgGbPerHour = 0.80; break; } const msgMB = msgGbPerHour * 1000; let dailyCloudMB = (streamH * 900) + (stream4kH * 7000) + (extremeH * 2500) + (hybridH * 1500) + (mediumH * 500) + (msgHours * msgMB) + (webH * 200); this.cloudActiveGB = Math.round(dailyCloudMB / 1000) * 365; this.cloudBackgroundGB = Math.round(1.5 * 365) + this.hwCloudBgGB; const kwhPerGb = 0.22; this.cloudActiveKwh = Math.round(this.cloudActiveGB * kwhPerGb); this.cloudBackgroundKwh = Math.round(this.cloudBackgroundGB * kwhPerGb); }, animateBatteries: function(targetValue) { const grid = document.getElementById('battery-grid'); const textCounter = document.getElementById('batt-count-text'); grid.innerHTML = ''; let current = 0; const step = 1; const speed = 45; const interval = setInterval(() => { current += step; if (current > targetValue) { current = targetValue; clearInterval(interval); return; } const batt = document.createElement('span'); batt.innerText = '🔋'; batt.style.fontSize = '18px'; batt.style.opacity = '0'; batt.style.transform = 'scale(0)'; batt.style.transition = 'all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275)'; grid.appendChild(batt); setTimeout(() => { batt.style.opacity = '1'; batt.style.transform = 'scale(1)'; }, 10); textCounter.innerText = current; grid.scrollTop = grid.scrollHeight; }, speed); }, generateIceberg: function() { this.showStage(3); const cUseful = Math.round(this.localUsefulKwh); const cWaste = Math.round(this.localWasteKwh); const cCloudActive = this.cloudActiveKwh; const cCloudBg = this.cloudBackgroundKwh; document.getElementById('local-useful-val').innerText = cUseful; document.getElementById('local-waste-val').innerText = cWaste; document.getElementById('cloud-bg-gb-val').innerText = this.cloudBackgroundGB; document.getElementById('cloud-bg-kwh-val').innerText = cCloudBg; document.getElementById('cloud-active-gb-val').innerText = this.cloudActiveGB; document.getElementById('cloud-active-kwh-val').innerText = cCloudActive; const maxVal = Math.max(cUseful + cWaste, cCloudActive + cCloudBg, 10); const pUseful = Math.max(2, Math.round((cUseful / maxVal) * 100)); const pWaste = Math.max(2, Math.round((cWaste / maxVal) * 100)); const pCloudBg = Math.max(5, Math.round((cCloudBg / maxVal) * 100)); const pCloudActive = Math.max(5, Math.round((cCloudActive / maxVal) * 100)); document.getElementById('bar-local-useful').setAttribute('data-width', pUseful + '%'); document.getElementById('bar-local-waste').setAttribute('data-width', pWaste + '%'); document.getElementById('bar-cloud-bg').setAttribute('data-width', pCloudBg + '%'); document.getElementById('bar-cloud-active').setAttribute('data-width', pCloudActive + '%'); const totalGB = this.cloudActiveGB + this.cloudBackgroundGB; const userCO2 = Math.round(totalGB * 0.042); document.getElementById('macro-user-co2').innerText = userCO2 + ' kg CO₂'; const maxCo2 = Math.max(99, userCO2, 10); const avgPct = Math.round((99 / maxCo2) * 100); const userPct = Math.round((userCO2 / maxCo2) * 100); document.getElementById('macro-avg-co2-bar').setAttribute('data-width', avgPct + '%'); document.getElementById('macro-user-co2-bar').setAttribute('data-width', userPct + '%'); document.querySelectorAll('#stage-3 .bar-fill').forEach(bar => { bar.style.width = '0%'; }); const malusAlert = document.getElementById('malus-alert'); const malusAlertText = document.getElementById('malus-alert-text'); if(cWaste > 0) { malusAlert.style.display = 'block'; malusAlertText.innerText = `MALUS LOCALE: STAI PAGANDO INUTILMENTE ~${Math.round(cWaste * 0.3)}€ ALL'ANNO SULLA BOLLETTA PER IL VAMPIRE DRAIN.`; } else { malusAlert.style.display = 'none'; } const dataWh = (cCloudActive + cCloudBg) * 1000; this.dailyCharges = Math.round((dataWh / 365) / 15); document.getElementById('reality-trigger-box').style.display = 'block'; document.getElementById('reality-options-container').style.display = 'none'; setTimeout(() => { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.querySelectorAll('.bar-fill').forEach(bar => { const w = bar.getAttribute('data-width'); if(w) bar.style.width = w; }); observer.unobserve(entry.target); } }); }, { threshold: 0.1 }); document.querySelectorAll('#stage-3 .chart-box').forEach(box => { observer.observe(box); }); }, 150); }, renderTacticsGrid: function() { const grid = document.getElementById('tactics-grid'); grid.innerHTML = ''; this.overrideTargets.forEach(t => { grid.innerHTML += `
${t.icon}
${t.name}
DA HACKERARE
`; }); }, overrideStep: 0, overrideCalcData: {}, tickerInterval: null, // Alfabeto italiano a 21 lettere (1..21) per coerenza totale tra calcolo iniziale e matrice finale italianAlphabet: "ABCDEFGHILMNOPQRSTUVZ", // Matrice delle 13 domande/risposte (corrispondenti alle somme delle cifre 1..13 nell'alfabeto italiano) matrice13Domande: { 1: { lettera: 'A', parola: 'AZZERARE', domanda: "Qual è l'azione di spegnere totalmente un dispositivo anziché lasciarlo in standby?" }, 2: { lettera: 'B', parola: 'BLUETOOTH', domanda: "Quale connessione wireless a corto raggio conviene spegnere quando non usi cuffie o smartwatch per risparmiare batteria?" }, 3: { lettera: 'C', parola: 'CARICATORE', domanda: "Quale accessorio consuma corrente 'fantasma' se lasciato attaccato alla presa a vuoto?" }, 4: { lettera: 'D', parola: 'DATI', domanda: "Cosa trasporta la rete 4G/5G consumando fino a 5 volte più energia rispetto al Wi-Fi?" }, 5: { lettera: 'E', parola: 'ENERGIA', domanda: "Quale risorsa invisibile bruciano H24 i datacenter per mantenere attivi i server?" }, 6: { lettera: 'F', parola: 'FERMA', domanda: "Cosa bisogna fare all'autoplay dei video per bloccare lo spreco automatico di giga?" }, 7: { lettera: 'G', parola: 'GIGA', domanda: "Quale unità di misura del traffico dati schizza alle stelle guardando video in 4K?" }, 8: { lettera: 'H', parola: 'HACKER', domanda: "Come si chiama l'agente speciale che sconfigge le impostazioni di fabbrica (Default)?" }, 9: { lettera: 'I', parola: 'INTERNET', domanda: "Come si chiama la 'Nazione Invisibile' che consuma circa il 10% dell'elettricità mondiale?" }, 10: { lettera: 'L', parola: 'LITIO', domanda: "Quale metallo leggero compone le batterie ricaricabili di smartphone e console?" }, 11: { lettera: 'M', parola: 'MEME', domanda: "Come si chiamano le immagini divertenti virali che, inviate e scaricate a raffica nelle chat, pesano molto più del semplice testo?" }, 12: { lettera: 'N', parola: 'NOTIFICHE', domanda: "Quali avvisi continui risvegliano i server e illuminano lo schermo del telefono in background?" }, 13: { lettera: 'O', parola: 'OFFLINE', domanda: "In quale modalità senza connessione puoi leggere, ascoltare musica già scaricata o giocare risparmiando energia?" } }, // Restituisce la parola chiave tematica e l'indizio (senza svelare il numero di lettere) per annullare A getAppKeywordChallenge: function(appLettersCount) { const challenges = { 6: { word: "SERVER", clue: "Sottrai il numero di lettere del computer centrale che ospita e invia i video online (inizia per S):" }, 7: { word: "STANDBY", clue: "Sottrai il numero di lettere dello stato di 'finto spegnimento' con la lucina rossa accesa (inizia per S):" }, 8: { word: "BATTERIA", clue: "Sottrai il numero di lettere del componente al litio che alimenta lo smartphone (inizia per B):" }, 9: { word: "STREAMING", clue: "Sottrai il numero di lettere della trasmissione video continua in diretta o on-demand via internet (inizia per S):" }, 10: { word: "DATACENTER", clue: "Sottrai il numero di lettere degli enormi capannoni pieni di computer che raffreddano il cloud (inizia per D):" } }; return challenges[appLettersCount] || { word: "SERVER", clue: "Sottrai il numero di lettere del computer centrale che ospita i dati online (inizia per S):" }; }, // Converte una lettera dell'alfabeto italiano (A-Z -> 1-21) o un numero 1-21 parseItalianLetterOrNumber: function(val) { const clean = val.trim().toUpperCase(); if (/^[A-Z]$/.test(clean)) { const idx = this.italianAlphabet.indexOf(clean); if (idx !== -1) return idx + 1; // Gestione eventuali lettere straniere J, K, W, X, Y ricondotte alla posizione standard const fullIdx = clean.charCodeAt(0) - 64; return Math.min(21, fullIdx); } const num = parseInt(clean, 10); if (!isNaN(num) && num >= 1 && num t.id === targetId); if (!target) return; this.currentOverrideTarget = target; this.overrideStep = 1; const appLettersCount = target.name.replace(/[^A-Z]/g, '').length; this.overrideCalcData = { appName: target.name, appLettersDefault: appLettersCount, runningTotal: 0, userInitialVal: 0, appLettersVal: 0, menuStepsVal: 0, friendInitialVal: 0, finalMatrixIndex: 1, lockedSlots: [], unlockedWord: null }; const modal = document.getElementById('override-modal'); document.getElementById('override-title').innerHTML = `TERMINALE OVERRIDE: ${target.name}`; const iconDisplay = document.getElementById('ov-target-icon-display'); if (iconDisplay) iconDisplay.innerHTML = target.icon; document.getElementById('ov-default-label').innerText = `TARGET: ${target.trigger} (${target.action})`; document.getElementById('ov-clue-box').style.display = 'none'; this.buildQuantumSecCoreUI(); this.startQuantumSecCoreTicker(); this.runOverrideStepPrompt(); modal.style.display = 'flex'; }, buildQuantumSecCoreUI: function() { const verifyContainer = document.getElementById('ov-verify-container'); verifyContainer.style.display = 'flex'; verifyContainer.style.flexDirection = 'column'; verifyContainer.style.gap = '10px'; verifyContainer.innerHTML = `
[QUANTUM_DECODER // SEC_CORE: INITIALIZING...]
`; const inputEl = document.getElementById('secret-code-input'); if (inputEl) { inputEl.addEventListener('keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); this.verifyOverrideCode(); } }); } }, startQuantumSecCoreTicker: function() { const tickerEl = document.getElementById('matrix-ticker-display'); if (!tickerEl) return; if (this.tickerInterval) clearInterval(this.tickerInterval); const chars = "0123456789ABCDEFGHILMNOPQRSTUVZ#@&%"; const totalSlots = 9; // 8 passaggi algebrici + 1 slot finale parola chiave const randChunk = (len) => { let s = ""; for (let i = 0; i { const locked = this.overrideCalcData.lockedSlots || []; const unlockedWord = this.overrideCalcData.unlockedWord; let segments = []; for (let idx = 0; idx ${locked[idx]}`); } else if (idx === totalSlots - 1 && unlockedWord) { segments.push(`${unlockedWord}`); } else if (idx === totalSlots - 1) { segments.push(`[${randChunk(4)}]`); } else { segments.push(`${randChunk(4)}`); } } tickerEl.innerHTML = `SEC_CORE // ${segments.join(' - ')}`; }, 75); }, lockNextSecCoreSlot: function(partialValue) { this.overrideCalcData.lockedSlots.push(partialValue); const tickerEl = document.getElementById('matrix-ticker-display'); if (tickerEl) { tickerEl.style.borderColor = "var(--lime-green)"; setTimeout(() => { tickerEl.style.borderColor = "var(--cyan-electric)"; }, 300); } }, runOverrideStepPrompt: function() { const pathText = document.getElementById('ov-path-text'); const inputField = document.getElementById('secret-code-input'); if (inputField) { inputField.value = ''; inputField.focus(); } let promptMessage = ""; switch(this.overrideStep) { case 1: promptMessage = "PASSAGGIO 1/9:\nIn che anno siamo? (Inserisci l'anno attuale, es. 2026):"; if (inputField) inputField.placeholder = "ES. 2026"; break; case 2: promptMessage = "PASSAGGIO 2/9:\nAggiungi l'INIZIALE DEL TUO NOME (alfabeto italiano A=1 ... Z=21, scrivi la lettera o il numero):"; if (inputField) inputField.placeholder = "ES. M (OPPURE 11)"; break; case 3: promptMessage = `PASSAGGIO 3/9:\nAggiungi il numero di lettere del nome della app "${this.overrideCalcData.appName}":`; if (inputField) inputField.placeholder = "CONTA LE LETTERE..."; break; case 4: promptMessage = "PASSAGGIO 4/9:\nAggiungi il numero di passaggi effettuati nei menu per trovare l'impostazione (massimo 5):"; if (inputField) inputField.placeholder = "ES. 3 (MAX 5)"; break; case 5: promptMessage = "PASSAGGIO 5/9:\nSottrai I TUOI ANNI (inserisci la tua età):"; if (inputField) inputField.placeholder = "ES. 13"; break; case 6: promptMessage = "PASSAGGIO 6/9:\nAggiungi l'INIZIALE DEL NOME DEL TUO MIGLIORE AMICO (lettera A-Z o numero 1-21):"; if (inputField) inputField.placeholder = "ES. L (OPPURE 10)"; break; case 7: promptMessage = "PASSAGGIO 7/9:\nSottrai il tuo ANNO DI NASCITA (es. 2013):"; if (inputField) inputField.placeholder = "ES. 2013"; break; case 8: const kwChallenge = this.getAppKeywordChallenge(this.overrideCalcData.appLettersVal); this.overrideCalcData.expectedKeyword = kwChallenge.word; promptMessage = `PASSAGGIO 8/9 (ENIGMA DI CALIBRAZIONE):\n${kwChallenge.clue}`; if (inputField) inputField.placeholder = "NUMERO DI LETTERE (O LA PAROLA)..."; break; case 9: const idx = this.overrideCalcData.finalMatrixIndex; const entry = this.matrice13Domande[idx] || this.matrice13Domande[1]; this.overrideCalcData.parolaCorretta = entry.parola; promptMessage = `CALIBRAZIONE COMPLETATA! Osserva l'ultimo numero rimasto nel SEC_CORE.\n\n1) Somma le cifre che compongono quel numero (se supera 13, sommale ancora) e trova la lettera corrispondente nell'alfabeto italiano (1=A, 2=B... 10=L, 11=M, 12=N, 13=O).\n2) Rispondi all'enigma con la parola chiave che inizia per quella lettera:\n\n"${entry.domanda}"`; if (inputField) inputField.placeholder = "INSERISCI LA PAROLA CHIAVE..."; const btn = document.getElementById('btn-verify-override'); if (btn) btn.innerText = "[ 🔓 SBLOCCA SEC_CORE ]"; break; } pathText.innerHTML = ""; let i = 0; if(this.windowInterval) clearInterval(this.windowInterval); this.windowInterval = setInterval(() => { if (i '; else { pathText.innerHTML += char; if (i % 4 === 0) audioFX.playClick(); } i++; } else { clearInterval(this.windowInterval); } }, 12); }, verifyOverrideCode: function() { const inputField = document.getElementById('secret-code-input'); if (!inputField) return; const rawVal = inputField.value.trim().toUpperCase(); if (!rawVal) { audioFX.playError(); alert("Inserisci un valore prima di confermare!"); return; } const d = this.overrideCalcData; if (this.overrideStep === 1) { const anno = parseInt(rawVal, 10); if (isNaN(anno) || anno 2100) { audioFX.playError(); alert("Inserisci un anno valido (es. 2026)."); return; } audioFX.playClick(); d.runningTotal = anno; this.lockNextSecCoreSlot(d.runningTotal); this.overrideStep = 2; this.runOverrideStepPrompt(); } else if (this.overrideStep === 2) { const valNome = this.parseItalianLetterOrNumber(rawVal); if (!valNome) { audioFX.playError(); alert("Inserisci una lettera (A-Z) oppure un numero da 1 a 21."); return; } audioFX.playClick(); d.userInitialVal = valNome; d.runningTotal += valNome; this.lockNextSecCoreSlot(d.runningTotal); this.overrideStep = 3; this.runOverrideStepPrompt(); } else if (this.overrideStep === 3) { const lettereApp = parseInt(rawVal, 10); if (isNaN(lettereApp) || lettereApp 30) { audioFX.playError(); alert("Inserisci il numero di lettere del nome della app."); return; } if (lettereApp !== d.appLettersDefault) { audioFX.playError(); alert(`Conta bene le lettere di "${d.appName}" (escludendo eventuali spazi)!`); return; } audioFX.playClick(); d.appLettersVal = lettereApp; d.runningTotal += lettereApp; this.lockNextSecCoreSlot(d.runningTotal); this.overrideStep = 4; this.runOverrideStepPrompt(); } else if (this.overrideStep === 4) { const passaggi = parseInt(rawVal, 10); if (isNaN(passaggi) || passaggi 5) { audioFX.playError(); if (typeof this.showCyberPopup === 'function') { this.showCyberPopup( "⚠️ ROTTA NON OTTIMALE RILEVATA!\n\nPer completare l'override servono al massimo 5 passaggi nei menu. Ripercorri la strada più diretta nelle impostazioni dell'app e inserisci un numero uguale o inferiore a 5.", null ); } else { alert("⚠️ Rotta non ottimale! Servono al massimo 5 passaggi nei menu. Riprova con 99) { audioFX.playError(); alert("Inserisci la tua età in anni (es. 13)."); return; } audioFX.playClick(); d.runningTotal -= eta; this.lockNextSecCoreSlot(d.runningTotal); this.overrideStep = 6; this.runOverrideStepPrompt(); } else if (this.overrideStep === 6) { const valAmico = this.parseItalianLetterOrNumber(rawVal); if (!valAmico) { audioFX.playError(); alert("Inserisci la lettera iniziale del tuo migliore amico (A-Z) o un numero 1-21."); return; } audioFX.playClick(); d.friendInitialVal = valAmico; d.runningTotal += valAmico; this.lockNextSecCoreSlot(d.runningTotal); this.overrideStep = 7; this.runOverrideStepPrompt(); } else if (this.overrideStep === 7) { const annoNascita = parseInt(rawVal, 10); if (isNaN(annoNascita) || annoNascita 2022) { audioFX.playError(); alert("Inserisci un anno di nascita valido (es. 2013)."); return; } audioFX.playClick(); d.runningTotal -= annoNascita; this.lockNextSecCoreSlot(d.runningTotal); this.overrideStep = 8; this.runOverrideStepPrompt(); } else if (this.overrideStep === 8) { const expectedWord = d.expectedKeyword || "SERVER"; const expectedLen = expectedWord.length; // Accetta sia il numero esatto di lettere sia la parola stessa convertita nella sua lunghezza let subVal = null; if (rawVal === expectedWord) { subVal = expectedLen; } else { const parsedNum = parseInt(rawVal, 10); if (!isNaN(parsedNum) && parsedNum === expectedLen) { subVal = parsedNum; } } if (subVal === null) { audioFX.playError(); alert(`❌ Valore non corretto! Indovina la parola chiave dall'indizio (inizia per '${expectedWord.charAt(0)}') e inserisci il numero delle sue lettere.`); return; } audioFX.playClick(); d.runningTotal -= subVal; // Evitiamo eventuali residui negativi in casi limite assicurando almeno 1 const finalNum = Math.max(1, d.runningTotal); d.runningTotal = finalNum; this.lockNextSecCoreSlot(finalNum); // Riduzione reale delle cifre del numero finale rimasto fino a rientrare in 1..13 let ridotto = finalNum; while (ridotto > 13) { ridotto = String(ridotto) .split('') .reduce((acc, digit) => acc + parseInt(digit, 10), 0); } d.finalMatrixIndex = ridotto; this.overrideStep = 9; this.runOverrideStepPrompt(); } else if (this.overrideStep === 9) { const parolaAttesa = d.parolaCorretta || "FERMA"; if (rawVal === parolaAttesa) { d.unlockedWord = parolaAttesa; audioFX.playSuccess(); const tickerEl = document.getElementById('matrix-ticker-display'); if (tickerEl) { tickerEl.style.borderColor = "var(--lime-green)"; tickerEl.style.boxShadow = "0 0 18px var(--lime-green)"; } setTimeout(() => { if (this.tickerInterval) clearInterval(this.tickerInterval); this.dossierArchive.push({ type: 'software_hack', target: this.currentOverrideTarget.name, status: `OVERRIDE SEC_CORE (${parolaAttesa})`, imgRaw: 'https://www.energiadi.it/wp-content/uploads/2026/10/Risorsa-1.png' }); document.getElementById('override-modal').style.display = 'none'; this.completeHack(this.currentOverrideTarget, 'override'); }, 1600); } else { audioFX.playError(); alert("❌ Accesso negato dal SEC_CORE! Controlla la somma delle cifre dell'ultimo numero rimasto, verifica la lettera corrispondente nell'alfabeto italiano e riprova."); } } }, completeHack: function(target, actionType) { audioFX.playSuccess(); this.tatticheCompletate++; this.updateXpHud(target.xp); document.getElementById('override-modal').style.display = 'none'; const cardEl = document.getElementById('mini-' + target.id); const statusEl = document.getElementById('status-' + target.id); if(cardEl) cardEl.classList.add('completed'); if(statusEl) statusEl.innerText = 'HACKED'; if ((this.tatticheCompletate + this.ninjaCompletate) >= 1) { document.getElementById('btn-go-to-debriefing').style.display = 'block'; } }, generateDebriefing: function() { const totalHacks = this.tatticheCompletate + this.ninjaCompletate; let pName = "AGENTE OPERATIVO", pDesc = "Hai iniziato il tuo percorso per sconfiggere il Default.", pColor = "#00f0ff"; if (totalHacks >= 9 && this.ninjaCompletate >= 6) { pName = "CYBER GHOST 👻"; pDesc = "Vivi fuori dal Default e la tua impronta di spreco è nulla."; pColor = "#39ff14"; } else if (totalHacks >= 8) { pName = "NET-ECOLOGY MASTER 🏆"; pDesc = "Hai dominato ogni vulnerabilità. Sei un vero leader della decarbonizzazione."; pColor = "#ffd700"; } else if (this.ninjaCompletate >= 4) { pName = "NATIVE NINJA 🥷"; pDesc = "Molte app erano già a prova di spreco. Hai un'ottima immunità."; pColor = "#39ff14"; } else if (this.cloudActiveGB > 400 && totalHacks >= 4) { pName = "CLOUD OPTIMIZER ☁️"; pDesc = "Hai alleggerito drasticamente il carico sulle antenne e sui server."; pColor = "#ff00ff"; } else if (this.localWasteKwh > 20 && totalHacks >= 2) { pName = "VAMPIRE SLAYER 🧛‍♂️"; pDesc = "Hai scovato un forte spreco elettrico silente."; pColor = "#fff"; } else if (totalHacks >= 4) { pName = "CYBER RANGER 🛡️"; pDesc = "Hai difeso la tua rete con astuzia e metodo."; pColor = "#00f0ff"; } else { pName = "ROOKIE HACKER 🛠️"; pDesc = "Hai fatto il tuo primo passo fuori dalla matrice del Default."; pColor = "#00f0ff"; } this.player.profileName = pName; document.getElementById('ap-avatar-icon').innerText = this.player.avatar; document.getElementById('ap-title').innerText = pName; document.getElementById('ap-title').style.color = pColor; document.getElementById('ap-desc').innerText = pDesc; document.getElementById('agent-profile-box').style.borderColor = pColor; document.getElementById('agent-profile-box').style.boxShadow = `0 0 15px ${pColor}80`; const gbSaved = totalHacks * 250; const co2Saved = Math.round(gbSaved * 0.042); const euroRisparmiati = Math.round(this.localWasteKwh * 0.30); const ricariche = totalHacks >= 3 ? '1.5' : '1'; document.getElementById('loot-euro').innerText = euroRisparmiati; document.getElementById('loot-gb').innerText = gbSaved; document.getElementById('loot-co2').innerText = co2Saved; document.getElementById('loot-batt').innerText = ricariche; const initialCO2 = Math.round((this.cloudActiveGB + this.cloudBackgroundGB) * 0.042); const finalCO2 = Math.max(0, initialCO2 - co2Saved); document.getElementById('deb-user-co2-val').innerText = finalCO2 + ' kg CO₂'; const maxFinalCo2 = Math.max(99, finalCO2, 10); const avgDebPct = Math.round((99 / maxFinalCo2) * 100); const userDebPct = Math.round((finalCO2 / maxFinalCo2) * 100); document.getElementById('deb-avg-bar').setAttribute('data-width', avgDebPct + '%'); document.getElementById('deb-user-bar').setAttribute('data-width', userDebPct + '%'); let msg = "> SINCRONIZZAZIONE DATI...\n> RICALCOLO IMPRONTA COMPLETATO.\n\nHAI TAGLIATO IL CORDONE CHE NUTRE LO SPRECO DEI SERVER GLOBALI E LA TUA BOLLETTA.\n\nECCO IL TUO IMPATTO REALE."; if(totalHacks >= 8) { msg += "\n\n🏆 BADGE SBLOCCATO: MASTER! (+100 XP EXTRA)"; this.updateXpHud(100); } this.showCyberPopup(msg, () => { this.showStage(5); setTimeout(() => { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.querySelectorAll('.hud-bar-fill').forEach(bar => { const w = bar.getAttribute('data-width'); if(w) bar.style.width = w; }); observer.unobserve(entry.target); } }); }, { threshold: 0.1 }); const debriefBox = document.getElementById('debrief-chart-box'); if (debriefBox) observer.observe(debriefBox); }, 150); }); }, printDossierMissione: function() { audioFX.playClick(); let printContainer = document.getElementById('print-dossier'); if (!printContainer) { printContainer = document.createElement('div'); printContainer.id = 'print-dossier'; document.body.appendChild(printContainer); } const totalHacks = this.tatticheCompletate + this.ninjaCompletate; const gbSaved = totalHacks * 250; const co2Saved = Math.round(gbSaved * 0.042); const euroRisparmiati = Math.round(this.localWasteKwh * 0.30); const pattoPrintText = this.isPattoSigned ? "FIRMATO CON IMPRONTA BIOMETRICA ✔️ (IMPEGNO 2 MESI)" : "NON FIRMATO"; const familyPrintText = this.isFamilyPattoSigned ? "FIRMATO E SELFIE SQUADRA SCATTATO ✔️ (+200 XP)" : "NON FIRMATO"; let html = `

DOCUMENTO GENERATO DAL SISTEMA ECOQUEST.

`; printContainer.innerHTML = html; setTimeout(() => { window.print(); setTimeout(() => { if(printContainer.parentNode) printContainer.parentNode.removeChild(printContainer); }, 2000); }, 800); }, syncWithWordPress: function() { this.calculateWattOro(); let diaryLogs = { logs: [] }; try { diaryLogs = JSON.parse(localStorage.getItem('ecoquest_diary_' + this.player.gametag) || '{"logs":[]}'); } catch (e) {} const istitutoVal = document.getElementById('input-istituto')?.value.trim() || 'Istituto Non Specificato'; const classeVal = document.getElementById('input-classe')?.value.trim() || 'Classe Non Specificata'; const payload = { ecoquest_audit: { student_profile: { gametag: this.player.gametag || 'Anonymous', mission_code: this.player.missionCode || 'DEFAULT', istituto: istitutoVal, classe: classeVal, anno_scolastico: "2025/2026", avatar: this.player.avatar || '', agent_title: this.player.profileName || '' }, game_metrics: { xp_totali: this.player.xp || 0, watt_oro: this.wattORO || this.wattOro || 0, patto_signed: this.isPattoSigned ? 1 : 0, family_patto_signed: this.isFamilyPattoSigned ? 1 : 0, family_photo: this.familyPhotoBase64 || '', local_kwh_waste: this.localWasteKwh || 0, cloud_active_gb: this.cloudActiveGB || 0, cloud_bg_gb: this.cloudBackgroundGB || 0 }, detailed_responses: { streaming_4k_hours: document.getElementById('in-stream-4k-h')?.value || 0, tiktok_hours: document.getElementById('in-tiktok-h')?.value || 0, gaming_hybrid_hours: document.getElementById('in-ibrido-h')?.value || 0, youtube_hd_hours: document.getElementById('in-stream-h')?.value || 0, web_nav_hours: document.getElementById('in-web-h')?.value || 0, social_scroll_hours: document.getElementById('in-ig-h')?.value || 0, hardware_nodes_scanned: this.dossierArchive || [], tactics_completed_count: this.tatticheCompletate || 0, ninja_completed_count: this.ninjaCompletate || 0 }, diary_bordo: diaryLogs, timestamp: new Date().toISOString() } }; const restUrl = window.location.origin + '/wp-json/ecoquest/v1/sync'; fetch(restUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }) .then(response => response.json()) .then(data => { if (data.success) { audioFX.playSuccess(); alert(`SINCRONIZZAZIONE CLOUD RIUSCITA!\n\nDati salvati sul server delle Energiadi.\n- Gametag: ${this.player.gametag}\n- Istituto: ${istitutoVal}\n- Classe: ${classeVal}`); } else { alert("Errore durante la sincronizzazione con il server."); } }) .catch(error => { console.warn("Errore di rete:", error); alert("Impossibile connettersi al server. Verifica la connessione."); }); } }; if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => app.init()); } else { app.init(); }