| //Complete Fitness App-Redesigned class FitnessApp{constructor(){this.currentView='home';this.currentCategory=null;this.currentWorkout=null;this.workoutTimer=null;this.workoutStartTime=null;this.workoutSeconds=0;this.currentExerciseIndex=0;this.currentSeries=0;this.navigationHistory=[];this.calendar30DayCache=null;this.calendar30DaySaveDebounce=null;this.activeFileReader=null;this.restInterval=null;this.activeTimeouts=new Set();this.activeVideoHandlers=null;const urlParams=new URLSearchParams(window.location.search);const isPWA=window.matchMedia('(display-mode:standalone)').matches||window.navigator.standalone===true||urlParams.get('source')==='pwa';const isLocalDev=window.location.hostname==='localhost'||window.location.hostname==='127.0.0.1';this.VIDEO_BASE_URL='videos/';this.AUDIO_BASE_URL='songs/';this.VIDEO_BASE_URL_FALLBACK='https://huggingface.co/datasets/RaiSantos/k30/resolve/main/';this.AUDIO_BASE_URL_FALLBACK='https://huggingface.co/datasets/RaiSantos/k30/resolve/main/';this.HF_DOWNLOAD_PARAM='';this.userProfile=this.loadUserProfile();this.userData=this.loadUserData();this.progress=this.loadProgress();this.weightData=this.loadWeightData();this.personalPlan=null;this.soundEnabled=localStorage.getItem('soundEnabled')!=='false';this.audioContext=new(window.AudioContext||window.webkitAudioContext)();this.sounds={backgroundYoga:this.createAudioWithFallback('background_yoga.mp3'),startYoga:this.createAudioWithFallback('start_yoga.mp3'),countdown:this.createAudioWithFallback('td_countdown.mp3'),motivational:this.createAudioWithFallback('td_di_2.ogg')};this.setupAudio();this.init()}createAudioWithFallback(filename){const audio=new Audio(this.AUDIO_BASE_URL+filename);audio.addEventListener('error',()=>{if(audio.src.includes(this.AUDIO_BASE_URL)){audio.src=this.AUDIO_BASE_URL_FALLBACK+filename}},{once:true});return audio}setupAudio(){this.sounds.backgroundYoga.loop=true;this.sounds.backgroundYoga.volume=0.3;this.audioLoaded=false}ensureAudioLoaded(){if(this.audioLoaded)return;Object.values(this.sounds).forEach(sound=>{sound.load()});this.audioLoaded=true}playCuteSound(type){if(!this.soundEnabled)return;try{const ctx=this.audioContext;const oscillator=ctx.createOscillator();const gainNode=ctx.createGain();oscillator.connect(gainNode);gainNode.connect(ctx.destination);switch(type){case 'tap':oscillator.frequency.setValueAtTime(800,ctx.currentTime);oscillator.frequency.exponentialRampToValueAtTime(400,ctx.currentTime+0.1);gainNode.gain.setValueAtTime(0.3,ctx.currentTime);gainNode.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.1);oscillator.type='sine';oscillator.start(ctx.currentTime);oscillator.stop(ctx.currentTime+0.1);break;case 'success':oscillator.frequency.setValueAtTime(523.25,ctx.currentTime);oscillator.frequency.setValueAtTime(659.25,ctx.currentTime+0.1);oscillator.frequency.setValueAtTime(783.99,ctx.currentTime+0.2);oscillator.frequency.setValueAtTime(1046.50,ctx.currentTime+0.3);gainNode.gain.setValueAtTime(0.35,ctx.currentTime);gainNode.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.6);oscillator.type='sine';oscillator.start(ctx.currentTime);oscillator.stop(ctx.currentTime+0.6);break;case 'complete':const osc1=ctx.createOscillator();const osc2=ctx.createOscillator();const osc3=ctx.createOscillator();const gain1=ctx.createGain();const gain2=ctx.createGain();const gain3=ctx.createGain();osc1.connect(gain1);osc2.connect(gain2);osc3.connect(gain3);gain1.connect(ctx.destination);gain2.connect(ctx.destination);gain3.connect(ctx.destination);osc1.frequency.setValueAtTime(523.25,ctx.currentTime);osc2.frequency.setValueAtTime(659.25,ctx.currentTime);osc3.frequency.setValueAtTime(783.99,ctx.currentTime);gain1.gain.setValueAtTime(0.25,ctx.currentTime);gain2.gain.setValueAtTime(0.25,ctx.currentTime);gain3.gain.setValueAtTime(0.25,ctx.currentTime);gain1.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.8);gain2.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.8);gain3.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.8);osc1.start(ctx.currentTime);osc2.start(ctx.currentTime);osc3.start(ctx.currentTime);osc1.stop(ctx.currentTime+0.8);osc2.stop(ctx.currentTime+0.8);osc3.stop(ctx.currentTime+0.8);break;case 'click':oscillator.frequency.setValueAtTime(600,ctx.currentTime);gainNode.gain.setValueAtTime(0.2,ctx.currentTime);gainNode.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.05);oscillator.type='sine';oscillator.start(ctx.currentTime);oscillator.stop(ctx.currentTime+0.05);break;case 'countdown':oscillator.frequency.setValueAtTime(440,ctx.currentTime);gainNode.gain.setValueAtTime(0.25,ctx.currentTime);gainNode.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.08);oscillator.type='square';oscillator.start(ctx.currentTime);oscillator.stop(ctx.currentTime+0.08);break;case 'rest':oscillator.frequency.setValueAtTime(329.63,ctx.currentTime);oscillator.frequency.setValueAtTime(392.00,ctx.currentTime+0.15);gainNode.gain.setValueAtTime(0.3,ctx.currentTime);gainNode.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.4);oscillator.type='sine';oscillator.start(ctx.currentTime);oscillator.stop(ctx.currentTime+0.4);break;case 'halfway':oscillator.frequency.setValueAtTime(523.25,ctx.currentTime);oscillator.frequency.setValueAtTime(659.25,ctx.currentTime+0.12);gainNode.gain.setValueAtTime(0.3,ctx.currentTime);gainNode.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.3);oscillator.type='triangle';oscillator.start(ctx.currentTime);oscillator.stop(ctx.currentTime+0.3);break;case 'warning':oscillator.frequency.setValueAtTime(800,ctx.currentTime);oscillator.frequency.setValueAtTime(600,ctx.currentTime+0.1);oscillator.frequency.setValueAtTime(800,ctx.currentTime+0.2);gainNode.gain.setValueAtTime(0.25,ctx.currentTime);gainNode.gain.exponentialRampToValueAtTime(0.01,ctx.currentTime+0.3);oscillator.type='sawtooth';oscillator.start(ctx.currentTime);oscillator.stop(ctx.currentTime+0.3);break}}catch(e){}}playSound(soundName){if(!this.soundEnabled)return;this.ensureAudioLoaded();const sound=this.sounds[soundName];if(sound){sound.currentTime=0;sound.play().catch(e=>{if(e.name!=='NotAllowedError'){}})}}stopSound(soundName){const sound=this.sounds[soundName];if(sound){sound.pause();sound.currentTime=0}}toggleSound(){this.soundEnabled=!this.soundEnabled;localStorage.setItem('soundEnabled',this.soundEnabled);const icon=document.getElementById('soundIcon');icon.textContent=this.soundEnabled?'🔊':'🔇';if(!this.soundEnabled){this.stopSound('backgroundYoga')}this.playCuteSound('click')}init(){if(!this.userProfile||!this.userProfile.name){this.showProfileSetup();return}if(this.userProfile&&this.weightData){let needsSave=false;if(this.userProfile.weight&&!this.weightData.current){this.weightData.current=this.userProfile.weight;this.weightData.initial=this.userProfile.weight;needsSave=true}else if(this.weightData.current&&this.userProfile.weight!==this.weightData.current){this.userProfile.weight=this.weightData.current;this.saveUserProfile()}if(this.userProfile.goalWeight&&!this.weightData.goal){this.weightData.goal=this.userProfile.goalWeight;needsSave=true}else if(this.weightData.goal&&this.userProfile.goalWeight!==this.weightData.goal){this.userProfile.goalWeight=this.weightData.goal;this.saveUserProfile()}if(needsSave){this.saveWeightData()}}const isFirstTime=!localStorage.getItem('appVisited');if(isFirstTime){this.showWelcome()}else{this.hideWelcome()}this.generatePersonalPlan();this.setupEventListeners();this.resetDailyCalories();this.updateAllStats();this.loadAchievements();this.setupPWA();window.addEventListener('beforeunload',()=>{this.cleanupTimers()})}cleanupTimers(){if(this.workoutTimer){clearInterval(this.workoutTimer);this.workoutTimer=null}if(this.restInterval){clearInterval(this.restInterval);this.restInterval=null}if(this.activeFileReader){this.activeFileReader.abort();this.activeFileReader.onload=null;this.activeFileReader.onerror=null;this.activeFileReader=null}this.clearAllTimeouts();if(this.activeVideoHandlers){const{video,loadHandler,errorHandler}=this.activeVideoHandlers;if(video){video.removeEventListener('loadeddata',loadHandler);video.onerror=null}this.activeVideoHandlers=null}}safeSetTimeout(callback,delay){const id=window.setTimeout(()=>{callback();this.activeTimeouts.delete(id)},delay);this.activeTimeouts.add(id);return id}clearAllTimeouts(){this.activeTimeouts.forEach(id=>clearTimeout(id));this.activeTimeouts.clear()}sanitizeHTML(str){if(!str)return '';const temp=document.createElement('div');temp.textContent=str;return temp.innerHTML}sanitizeNumber(value,min,max,defaultValue=0){const num=parseFloat(value);if(isNaN(num)||!Number.isFinite(num))return defaultValue;return Math.max(min,Math.min(max,num))}sanitizeString(str,maxLength=100){if(!str||typeof str!=='string')return '';return this.sanitizeHTML(str.trim().slice(0,maxLength))}sanitizeAttribute(str){if(!str)return '';return String(str).replace(/"/g,'"').replace(/'/g,''').replace(/</g,'<').replace(/>/g,'>').replace(/\}sanitizeURL(url){if(!url)return '';const dangerous=/^(javascript|data|vbscript):/i;if(dangerous.test(url)){console.warn('🔒 Blocked dangerous URL protocol:',url);return ''}return url}loadUserProfile(){if(this.userProfileCache!==undefined){return this.userProfileCache}try{const data=localStorage.getItem('userProfile');if(!data){this.userProfileCache=null;return null}const profile=JSON.parse(data);this.userProfileCache=profile;if(profile){profile.name=this.sanitizeString(profile.name,50);profile.weight=this.sanitizeNumber(profile.weight,30,300,65);profile.height=this.sanitizeNumber(profile.height,100,250,165);profile.age=this.sanitizeNumber(profile.age,10,120,25);profile.goalWeight=this.sanitizeNumber(profile.goalWeight,30,300,60)}return profile}catch(e){console.error('Error loading profile:',e);this.userProfileCache=null;return null}}saveUserProfile(){this.userProfileCache=this.userProfile;try{const profileData=JSON.stringify(this.userProfile);if(profileData.length>500000){console.error('Profile data too large');alert('Dados do perfil muito grandes. Por favor,reduza o tamanho da foto.');return false}localStorage.setItem('userProfile',profileData);return true}catch(e){if(e.name==='QuotaExceededError'){console.error('localStorage quota exceeded');alert('Espaço de armazenamento cheio. Por favor,limpe alguns dados.')}else{console.error('Error saving profile:',e)}return false}}showProfileSetup(){const setupHTML=`<div class="profile-setup-screen" id="profileSetup"><div class="profile-setup-content"><h1 class="setup-title">🎯 Vamos Criar Seu Perfil</h1><p class="setup-subtitle">Para criar um plano personalizado perfeito para você!</p><form class="profile-form" id="profileForm"><!--Photo--><div class="form-group photo-upload"><label>📸 Foto de Perfil</label><div class="photo-selector"><input type="file" id="photoUpload" accept="image calculateScientificParameters(profile){const fcMax=220-profile.age;const fcRestEstimated={'sedentary':75,'light':70,'moderate':65,'active':60,'extreme':55}[profile.activityLevel]||70;const zones={recovery:{min:Math.round(fcRestEstimated+(fcMax-fcRestEstimated)*0.50),max:Math.round(fcRestEstimated+(fcMax-fcRestEstimated)*0.60),name:'Recuperação',color:'#4ECDC4'},fatBurn:{min:Math.round(fcRestEstimated+(fcMax-fcRestEstimated)*0.60),max:Math.round(fcRestEstimated+(fcMax-fcRestEstimated)*0.70),name:'Queima Gordura',color:'#FFB347'},cardio:{min:Math.round(fcRestEstimated+(fcMax-fcRestEstimated)*0.70),max:Math.round(fcRestEstimated+(fcMax-fcRestEstimated)*0.80),name:'Cardio',color:'#FF6B6B'},hiit:{min:Math.round(fcRestEstimated+(fcMax-fcRestEstimated)*0.80),max:Math.round(fcRestEstimated+(fcMax-fcRestEstimated)*0.90),name:'HIIT',color:'#FF4444'}};const weeklyVolumeMinutes={'lose-weight':250,'lose-weight-fast':300,'maintain':150,'gain-muscle':180,'tone':200,'health':150}[profile.goal]||200;const weeklyIntensity=[{week:1,load:0.65,volume:1.0,name:'Adaptação'},{week:2,load:0.75,volume:1.1,name:'Construção'},{week:3,load:0.85,volume:1.2,name:'Intensificação'},{week:4,load:0.70,volume:0.8,name:'Recuperação'},{week:5,load:0.90,volume:1.0,name:'Pico'}];const focusDistribution=this.calculateFocusDistribution(profile);let dailyDeficit=0;if(profile.goal.includes('lose-weight')){const weightToLose=profile.weight-profile.goalWeight;const daysToGoal=30;dailyDeficit=Math.round((weightToLose*7700)/daysToGoal);dailyDeficit=Math.min(1000,Math.max(300,dailyDeficit))}return{fcMax,fcRest:fcRestEstimated,zones,weeklyVolumeMinutes,weeklyIntensity,focusDistribution,dailyDeficit,bmi:profile.bmi,age:profile.age,goal:profile.goal,activityLevel:profile.activityLevel}}calculateFocusDistribution(profile){const distributions={'lose-weight':{cardio:0.35,core:0.25,legs:0.20,fullbody:0.15,recovery:0.05},'lose-weight-fast':{cardio:0.40,core:0.25,legs:0.20,fullbody:0.10,recovery:0.05},'tone':{resistance:0.40,core:0.25,cardio:0.20,flexibility:0.10,recovery:0.05},'gain-muscle':{resistance:0.50,compound:0.25,isolation:0.15,cardio:0.05,recovery:0.05},'maintain':{cardio:0.30,resistance:0.30,flexibility:0.20,balance:0.15,recovery:0.05},'health':{cardio:0.30,mobility:0.25,balance:0.20,strength:0.20,recovery:0.05}};return distributions[profile.goal]||distributions['lose-weight']}generatePeriodizedPlan(profile,scientificParams){const plan=[];const{weeklyIntensity,focusDistribution,zones,dailyDeficit}=scientificParams;for(let day=1;day<=30;day++){const weekNumber=Math.ceil(day/7);const dayOfWeek=((day-1)%7)+1;const intensity=weeklyIntensity[Math.min(weekNumber-1,4)];const dayPlan=this.generateDayPlan(day,dayOfWeek,weekNumber,intensity,profile,scientificParams);plan.push(dayPlan)}return plan}generateDayPlan(day,dayOfWeek,weekNumber,intensity,profile,scientificParams){if(dayOfWeek===7&&day!==30){return{day,weekNumber,focus:'Recuperação Ativa',icon:'🧘♀️',category:'yoga',type:'recovery',intensity:'baixa',intensityPercent:null,sets:2,reps:'10-15',description:'Yoga,alongamento e recuperação muscular',scientificReason:'🔬 Recuperação ativa promove remoção de lactato e reparo muscular',targetZone:'recovery',expectedCalories:50,duration:15}}const dayType=this.selectDayType(day,dayOfWeek,profile,scientificParams.focusDistribution);const sets=this.calculateSets(intensity.load,dayType);const reps=this.calculateReps(dayType,intensity.load);const expectedCalories=this.calculateExpectedCalories(dayType,sets,reps,profile.weight);const duration=this.calculateDuration(dayType,sets);return{day,focus:dayType.name,icon:dayType.icon,category:dayType.category,secondCategory:dayType.secondCategory,doubleWorkout:dayType.doubleWorkout,type:dayType.type,intensity:intensity.name.toLowerCase(),intensityPercent:Math.round(intensity.load*100),sets,reps,description:dayType.description,scientificReason:dayType.scientificReason,targetZone:dayType.targetZone,expectedCalories,duration,weekNumber,progressiveOverload:{week:weekNumber,loadPercent:intensity.load,volumeMultiplier:intensity.volume}}}selectDayType(day,dayOfWeek,profile,focusDistribution){const goal=profile.goal;if(goal.includes('lose-weight')){const types=[{day:[1,8,15,22,29],name:'HIIT+Core',icon:'🔥',category:'cardio',secondCategory:'abs',doubleWorkout:true,type:'hiit',targetZone:'hiit',description:'Cardio intenso+abdômen',scientificReason:'🔬 HIIT eleva EPOC(consumo de O2 pós-exercício)em até 24h'},{day:[2,9,16,23],name:'Pernas+Glúteos',icon:'🦵',category:'legs',secondCategory:'glutes',doubleWorkout:true,type:'strength',targetZone:'cardio',description:'Treino de membros inferiores',scientificReason:'🔬 Pernas são 40%da massa muscular-maior gasto calórico'},{day:[3,10,17,24],name:'Cardio Moderado',icon:'❤️',category:'cardio',type:'cardio',targetZone:'fatBurn',description:'Zona de queima de gordura',scientificReason:'🔬 60-70%FCmax otimiza oxidação lipídica'},{day:[4,11,18,25],name:'Core+Cintura',icon:'⏳',category:'abs',secondCategory:'waist',doubleWorkout:true,type:'core',targetZone:'cardio',description:'Abdômen e oblíquos',scientificReason:'🔬 Core forte melhora postura e reduz circunferência abdominal'},{day:[5,12,19,26],name:'Corpo Completo',icon:'✨',category:'fullbody',type:'metabolic',targetZone:'cardio',description:'Treino metabólico',scientificReason:'🔬 Exercícios compostos maximizam gasto energético total'},{day:[6,13,20,27],name:'Cardio+Braços',icon:'💪',category:'cardio',secondCategory:'arms',doubleWorkout:true,type:'mixed',targetZone:'cardio',description:'Cardio+membros superiores',scientificReason:'🔬 Variação de estímulos previne adaptação metabólica'},{day:[30],name:'Desafio Final',icon:'🏆',category:'fullbody',type:'challenge',targetZone:'hiit',description:'Teste de evolução completo',scientificReason:'🔬 Avaliação de performance demonstra adaptações neuromusculares'}];return types.find(t=>t.day.includes(day))||types[0]}if(goal==='gain-muscle'){const types=[{day:[1,8,15,22,29],name:'Pernas+Glúteos',icon:'🦵',category:'legs',secondCategory:'glutes',doubleWorkout:true,type:'hypertrophy',targetZone:'cardio',description:'Hipertrofia de inferiores',scientificReason:'🔬 Leg day estimula GH e testosterona sistêmica'},{day:[2,9,16,23],name:'Peito+Tríceps',icon:'💪',category:'fullbody',secondCategory:'arms',doubleWorkout:true,type:'push',targetZone:'fatBurn',description:'Push-empurrar',scientificReason:'🔬 Exercícios push ativam cadeia anterior'},{day:[3,10,17,24],name:'Costas+Bíceps',icon:'💪',category:'back',secondCategory:'arms',doubleWorkout:true,type:'pull',targetZone:'fatBurn',description:'Pull-puxar',scientificReason:'🔬 Exercícios pull corrigem desequilíbrios posturais'},{day:[4,11,18,25],name:'Ombros+Core',icon:'🔥',category:'fullbody',secondCategory:'abs',doubleWorkout:true,type:'functional',targetZone:'cardio',description:'Ombros e estabilização',scientificReason:'🔬 Core forte aumenta transferência de força'},{day:[5,12,19,26],name:'Pernas Intensas',icon:'🦵',category:'legs',type:'strength',targetZone:'cardio',description:'Força de pernas',scientificReason:'🔬 Sobrecarga progressiva estimula hipertrofia miofibrilar'},{day:[6,13,20,27],name:'Corpo Todo',icon:'✨',category:'fullbody',type:'compound',targetZone:'fatBurn',description:'Compostos multiarticulares',scientificReason:'🔬 Exercícios compostos recrutam múltiplas fibras simultâneamente'},{day:[30],name:'Teste de Força',icon:'🏆',category:'fullbody',type:'maxtest',targetZone:'cardio',description:'Teste de força máxima',scientificReason:'🔬 Avaliação 1RM mede ganhos de força neural'}];return types.find(t=>t.day.includes(day))||types[0]}if(goal==='tone'){const types=[{day:[1,8,15,22,29],name:'Core+Cardio',icon:'🔥',category:'abs',secondCategory:'cardio',doubleWorkout:true,type:'toning',targetZone:'cardio',description:'Definição de core',scientificReason:'🔬 Alta repetição+baixa carga define sem hipertrofiar'},{day:[2,9,16,23],name:'Pernas+Glúteos',icon:'🦵',category:'legs',secondCategory:'glutes',doubleWorkout:true,type:'sculpt',targetZone:'cardio',description:'Esculpir inferiores',scientificReason:'🔬 12-15 reps otimizam definição muscular'},{day:[3,10,17,24],name:'Braços+Ombros',icon:'💪',category:'arms',secondCategory:'fullbody',doubleWorkout:true,type:'toning',targetZone:'fatBurn',description:'Tonificar superiores',scientificReason:'🔬 Trabalho de resistência local reduz%gordura segmentar'},{day:[4,11,18,25],name:'Corpo Todo',icon:'✨',category:'fullbody',type:'circuit',targetZone:'cardio',description:'Circuito metabólico',scientificReason:'🔬 Circuitos mantêm FC elevada-queima+tonificação'},{day:[5,12,19,26],name:'Core+Cintura',icon:'⏳',category:'abs',secondCategory:'waist',doubleWorkout:true,type:'core',targetZone:'cardio',description:'Cintura definida',scientificReason:'🔬 Oblíquos definem silhueta da cintura'},{day:[6,13,20,27],name:'Yoga+Pilates',icon:'🧘♀️',category:'yoga',secondCategory:'back',doubleWorkout:true,type:'flexibility',targetZone:'recovery',description:'Alongar e fortalecer',scientificReason:'🔬 Flexibilidade aumenta amplitude-melhor ativação muscular'},{day:[30],name:'Treino Completo',icon:'🏆',category:'fullbody',type:'complete',targetZone:'cardio',description:'Sessão completa final',scientificReason:'🔬 Integração de todos os componentes treinados'}];return types.find(t=>t.day.includes(day))||types[0]}const typesHealth=[{day:[1,8,15,22,29],name:'Cardio Saúde',icon:'❤️',category:'cardio',type:'health',targetZone:'fatBurn',description:'Saúde cardiovascular',scientificReason:'🔬 150 min/semana cardio reduz risco cardiovascular em 30%'},{day:[2,9,16,23],name:'Força Funcional',icon:'💪',category:'fullbody',type:'functional',targetZone:'fatBurn',description:'Movimentos funcionais',scientificReason:'🔬 Treino funcional melhora ADLs(atividades diárias)'},{day:[3,10,17,24],name:'Equilíbrio',icon:'🧘♀️',category:'yoga',type:'balance',targetZone:'recovery',description:'Propriocepção e equilíbrio',scientificReason:'🔬 Treino de equilíbrio reduz quedas em 23%'},{day:[4,11,18,25],name:'Mobilidade',icon:'🤸♀️',category:'back',type:'mobility',targetZone:'recovery',description:'Amplitude de movimento',scientificReason:'🔬 Mobilidade previne lesões e dores crônicas'},{day:[5,12,19,26],name:'Caminhada Ativa',icon:'🚶♀️',category:'cardio',type:'walk',targetZone:'fatBurn',description:'Baixo impacto',scientificReason:'🔬 Caminhada 30min/dia reduz mortalidade em 20%'},{day:[6,13,20,27],name:'Yoga Suave',icon:'🧘♀️',category:'yoga',type:'gentle',targetZone:'recovery',description:'Relaxamento e flexibilidade',scientificReason:'🔬 Yoga reduz cortisol e melhora qualidade de vida'},{day:[30],name:'Avaliação Saúde',icon:'🏥',category:'fullbody',type:'assessment',targetZone:'fatBurn',description:'Teste de aptidão',scientificReason:'🔬 Testes funcionais avaliam saúde geral'}];return typesHealth.find(t=>t.day.includes(day))||typesHealth[0]}calculateSets(loadPercent,dayType){const baseSets={'hypertrophy':4,'strength':5,'toning':3,'cardio':3,'hiit':4,'recovery':2}[dayType.type]||3;if(loadPercent>=0.85)return baseSets+1;if(loadPercent<=0.70)return baseSets-1;return baseSets}calculateReps(dayType,loadPercent){const baseReps={'hypertrophy':'8-12','strength':'4-6','toning':'12-15','cardio':'30s','hiit':'20s on/10s off','recovery':'30-45s','metabolic':'15-20'}[dayType.type]||'10-12';return baseReps}calculateExpectedCalories(dayType,sets,reps,weight){const caloriesPerSetMin={'hiit':25,'strength':15,'cardio':20,'toning':12,'recovery':5,'metabolic':22}[dayType.type]||15;const weightFactor=weight/65;const totalSets=dayType.doubleWorkout?sets*2*5:sets*5;return Math.round(caloriesPerSetMin*totalSets*weightFactor)}calculateDuration(dayType,sets){const minutesPerSet=2;const totalSets=dayType.doubleWorkout?sets*2*5:sets*5;return Math.round(totalSets*minutesPerSet)}generate30DayCalendar(){const calendarContainer=document.getElementById('calendar30Days');if(!calendarContainer)return;calendarContainer.innerHTML='';const calendar30Day=this.loadCalendar30Day();const userProfile=this.userProfile;if(!userProfile){this.showProfilePrompt();return}const scientificParams=this.calculateScientificParameters(userProfile);const workoutPlan=this.generatePeriodizedPlan(userProfile,scientificParams);this.scientificParams=scientificParams;this.currentWorkoutPlan=workoutPlan;const planHeaderHTML=`<div class="scientific-plan-header"><div class="plan-title"><h3>🧬 Seu Plano Científico Personalizado</h3><p>Baseado em seu perfil e objetivo:<strong>${this.getGoalName(userProfile.goal)}</strong></p></div><div class="scientific-metrics"><div class="metric-card"><div class="metric-icon">💓</div><div class="metric-content"><div class="metric-label">FCmax</div><div class="metric-value">${scientificParams.fcMax}bpm</div></div></div><div class="metric-card"><div class="metric-icon">🎯</div><div class="metric-content"><div class="metric-label">Zona Alvo</div><div class="metric-value">${scientificParams.zones.cardio.min}-${scientificParams.zones.cardio.max}bpm</div></div></div><div class="metric-card"><div class="metric-icon">📈</div><div class="metric-content"><div class="metric-label">Volume/Semana</div><div class="metric-value">${scientificParams.weeklyVolumeMinutes}min</div></div></div>${scientificParams.dailyDeficit>0?`<div class="metric-card"><div class="metric-icon">🔥</div><div class="metric-content"><div class="metric-label">Déficit Diário</div><div class="metric-value">${scientificParams.dailyDeficit}kcal</div></div></div>`:''}</div></div>`;calendarContainer.insertAdjacentHTML('beforebegin',planHeaderHTML);const fragment=document.createDocumentFragment();const completedDays=Object.keys(calendar30Day).length;for(let i=0;i<workoutPlan.length;i++){const dayPlan=workoutPlan[i];const dayCard=document.createElement('div');dayCard.className='day-card';dayCard.classList.add(`intensity-${dayPlan.intensity}`);if(calendar30Day[dayPlan.day]){dayCard.classList.add('completed')}if(completedDays===0&&dayPlan.day===1){dayCard.classList.add('today')}else if(completedDays>0&&!calendar30Day[dayPlan.day]&&dayPlan.day===completedDays+1){dayCard.classList.add('today')}const intensityBadge=dayPlan.intensityPercent?`<div class="intensity-badge">${dayPlan.intensityPercent}%</div>`:'';dayCard.innerHTML=`<div class="day-icon">${dayPlan.icon}</div><div class="day-number">Dia ${dayPlan.day}</div><div class="day-focus">${dayPlan.focus}</div>${intensityBadge}<div class="day-week-badge">Semana ${dayPlan.weekNumber}</div>`;dayCard.dataset.dayIndex=i;dayCard.addEventListener('click',()=>{this.showScientificDayDetail(dayPlan,scientificParams)},{passive:true});fragment.appendChild(dayCard)}calendarContainer.appendChild(fragment)}getGoalName(goal){const names={'lose-weight':'Perder Peso','lose-weight-fast':'Perder Peso Rápido','maintain':'Manter Peso','gain-muscle':'Ganhar Massa Muscular','tone':'Tonificar','health':'Saúde Geral'};return names[goal]||goal}showScientificDayDetail(dayPlan,scientificParams){const modal=document.createElement('div');modal.className='day-detail-modal scientific-modal';const selectedExercises=this.selectIntelligentExercises(dayPlan);const scientificExplanation=`<div class="scientific-explanation"><div class="explanation-header"><span class="explanation-icon">🔬</span><h4>Base Científica</h4></div><p>${dayPlan.scientificReason}</p><div class="target-zone"><strong>Zona Alvo:</strong><span class="zone-badge" style="background:${scientificParams.zones[dayPlan.targetZone].color}">${scientificParams.zones[dayPlan.targetZone].name}(${scientificParams.zones[dayPlan.targetZone].min}-${scientificParams.zones[dayPlan.targetZone].max}bpm)</span></div></div>`;const progressionInfo=`<div class="progression-info"><h4>📈 Periodização</h4><div class="progression-details"><div class="prog-item"><span class="prog-label">Semana:</span><span class="prog-value">${dayPlan.weekNumber}-${dayPlan.intensity}</span></div><div class="prog-item"><span class="prog-label">Carga:</span><span class="prog-value">${dayPlan.intensityPercent}%da máxima</span></div><div class="prog-item"><span class="prog-label">Volume:</span><span class="prog-value">${dayPlan.sets}séries × ${dayPlan.reps}</span></div></div></div>`;let exercisesHTML='';if(dayPlan.doubleWorkout&&dayPlan.secondCategory){exercisesHTML='<div class="double-workout-badge">⚡ TREINO DUPLO-Máxima Eficiência</div>';exercisesHTML+='<h4 style="color:#FF6B6B;margin-top:16px;">🔥 Treino 1-'+this.getCategoryName(dayPlan.category)+'</h4>'}selectedExercises.slice(0,5).forEach(ex=>{exercisesHTML+=`<div class="day-exercise-item enhanced"><div class="day-exercise-emoji">${ex.emoji}</div><div class="day-exercise-info"><div class="day-exercise-name">${ex.name}</div><div class="day-exercise-details">${dayPlan.sets}× ${dayPlan.reps}|~${Math.round(ex.calories*dayPlan.sets)}kcal</div></div></div>`});if(dayPlan.doubleWorkout&&dayPlan.secondCategory){exercisesHTML+='<h4 style="color:#4ECDC4;margin-top:16px;">💪 Treino 2-'+this.getCategoryName(dayPlan.secondCategory)+'</h4>';selectedExercises.slice(5,10).forEach(ex=>{exercisesHTML+=`<div class="day-exercise-item enhanced"><div class="day-exercise-emoji">${ex.emoji}</div><div class="day-exercise-info"><div class="day-exercise-name">${ex.name}</div><div class="day-exercise-details">${dayPlan.sets}× ${dayPlan.reps}|~${Math.round(ex.calories*dayPlan.sets)}kcal</div></div></div>`})}modal.innerHTML=`<div class="day-detail-content scientific-content"><button class="modal-close-btn" id="closeScientificModal">×</button><div class="day-detail-header scientific-header"><div class="day-icon-large">${dayPlan.icon}</div><div class="day-detail-title">Dia ${dayPlan.day}-${dayPlan.focus}</div><div class="day-detail-subtitle">${dayPlan.description}</div><div class="day-stats"><span>⏱️ ${dayPlan.duration}min</span><span>🔥 ~${dayPlan.expectedCalories}kcal</span><span>💪 ${selectedExercises.length}exercícios</span></div></div>${scientificExplanation}${progressionInfo}<div class="exercises-section"><h4>💪 Exercícios do Dia</h4><div class="day-exercises-list">${exercisesHTML}</div></div><div class="day-actions"><button class="btn-day-action btn-day-close" id="closeDayDetailBtn">Fechar</button><button class="btn-day-action btn-day-start" id="startDayWorkoutBtn">Começar Treino 🚀</button></div></div>`;document.body.appendChild(modal);modal.querySelector('#closeScientificModal').addEventListener('click',()=>{modal.remove();this.playCuteSound('tap')});modal.querySelector('#closeDayDetailBtn').addEventListener('click',()=>{modal.remove();this.playCuteSound('tap')});modal.querySelector('#startDayWorkoutBtn').addEventListener('click',()=>{modal.remove();this.startWorkout(selectedExercises);this.currentDayPlan=dayPlan;this.playCuteSound('success')});modal.addEventListener('click',(e)=>{if(e.target===modal){modal.remove();this.playCuteSound('tap')}});this.playCuteSound('tap')}selectIntelligentExercises(dayPlan){const exercises1=this.getExercisesByCategory(dayPlan.category);let selected=exercises1.slice(0,5);if(dayPlan.doubleWorkout&&dayPlan.secondCategory){const exercises2=this.getExercisesByCategory(dayPlan.secondCategory);selected=[...selected,...exercises2.slice(0,5)]}return selected}getCategoryName(category){const names={'abs':'Abdômen','legs':'Pernas','glutes':'Glúteos','arms':'Braços','back':'Costas','cardio':'Cardio','fullbody':'Corpo Todo','yoga':'Yoga','waist':'Cintura','face':'Face','massage':'Massagem'};return names[category]||category}showProfilePrompt(){alert('Por favor,complete seu perfil primeiro para gerar um plano personalizado!');this.navigateTo('progress')}showDayDetail(dayPlan){const modal=document.createElement('div');modal.className='day-detail-modal';const exercises1=this.getExercisesByCategory(dayPlan.category);let selectedExercises=exercises1.slice(0,5);let exercisesHTML='';let doubleWorkoutInfo='';if(dayPlan.doubleWorkout&&dayPlan.secondCategory){doubleWorkoutInfo='<div style="background:linear-gradient(135deg,#FF6B6B,#FF8E53);padding:12px;border-radius:12px;margin-bottom:16px;color:white;text-align:center;font-weight:600;font-size:14px;">⚡ DIA INTENSO:2 TREINOS PARA ACELERAR RESULTADOS!</div>';exercisesHTML+='<div style="margin-bottom:20px;"><h4 style="color:#FF6B6B;margin-bottom:12px;">🔥 Treino 1</h4>';selectedExercises.forEach(ex=>{exercisesHTML+=`<div class="day-exercise-item"><div class="day-exercise-emoji">${ex.emoji}</div><div class="day-exercise-info"><div class="day-exercise-name">${ex.name}</div><div class="day-exercise-details">${ex.sets}séries × ${ex.reps}</div></div></div>`});exercisesHTML+='</div>';const exercises2=this.getExercisesByCategory(dayPlan.secondCategory);const selectedExercises2=exercises2.slice(0,5);exercisesHTML+='<div><h4 style="color:#4ECDC4;margin-bottom:12px;">💪 Treino 2</h4>';selectedExercises2.forEach(ex=>{exercisesHTML+=`<div class="day-exercise-item"><div class="day-exercise-emoji">${ex.emoji}</div><div class="day-exercise-info"><div class="day-exercise-name">${ex.name}</div><div class="day-exercise-details">${ex.sets}séries × ${ex.reps}</div></div></div>`});exercisesHTML+='</div>';selectedExercises=[...selectedExercises,...selectedExercises2]}else{selectedExercises.forEach(ex=>{exercisesHTML+=`<div class="day-exercise-item"><div class="day-exercise-emoji">${ex.emoji}</div><div class="day-exercise-info"><div class="day-exercise-name">${ex.name}</div><div class="day-exercise-details">${ex.sets}séries × ${ex.reps}</div></div></div>`})}const totalCalories=selectedExercises.reduce((sum,ex)=>sum+(ex.calories*ex.sets),0);const estimatedTime=selectedExercises.length*2;modal.innerHTML=`<div class="day-detail-content"><div class="day-detail-header"><div class="day-detail-title">Dia ${dayPlan.day}</div><div class="day-detail-focus">${dayPlan.icon}${dayPlan.focus}</div><div style="display:flex;gap:16px;justify-content:center;margin-top:12px;font-size:13px;color:#666;"><span>⏱️ ~${estimatedTime}min</span><span>🔥 ~${totalCalories}kcal</span><span>💪 ${selectedExercises.length}exercícios</span></div></div>${doubleWorkoutInfo}<div class="day-exercises-list">${exercisesHTML}</div><div class="day-actions"><button class="btn-day-action btn-day-close" id="closeDayDetail">Fechar</button><button class="btn-day-action btn-day-start" id="startDayWorkout">Começar Treino ✨</button></div></div>`;document.body.appendChild(modal);modal.querySelector('#closeDayDetail').addEventListener('click',()=>{modal.remove();this.playCuteSound('tap')});modal.querySelector('#startDayWorkout').addEventListener('click',()=>{modal.remove();this.startWorkout(selectedExercises);this.playCuteSound('success');this.currentDayPlan=dayPlan});modal.addEventListener('click',(e)=>{if(e.target===modal){modal.remove();this.playCuteSound('tap')}});this.playCuteSound('tap')}markDayComplete(dayNumber){const calendar30Day=this.loadCalendar30Day();calendar30Day[dayNumber]=new Date().toISOString();this.saveCalendar30Day(calendar30Day);if(this.currentView==='calendar'){this.generate30DayCalendar()}const daysCompleted=Object.keys(calendar30Day).length;if(daysCompleted===30){this.showToast('🎉 Parabéns!Você completou os 30 dias!🎊','success',5000);this.sendNotification('🎉 30 Dias Completos!','Você é incrível!Completou todo o desafio!')}else{this.showToast(`✨ Dia ${dayNumber}concluído!${30-daysCompleted}dias restantes!`,'success')}}goBack(){if(this.navigationHistory.length>0){const previousView=this.navigationHistory.pop();this.navigateTo(previousView,false)}else{this.navigateTo('home',false)}}showCategoryExercises(category){this.currentCategory=category;const exercises=this.getExercisesByCategory(category);const categoryNames={personalized:'Treino Personalizado',abs:'Abdômen',face:'Massagem Facial',waist:'Cintura',legs:'Pernas',glutes:'Glúteos',back:'Postura e Mobilidade',arms:'Braços',cardio:'Cardio',fullbody:'Corpo Todo',yoga:'Yoga',massage:'Massagem Corporal'};document.getElementById('categoryTitle').textContent=categoryNames[category];const container=document.getElementById('exercisesList');container.innerHTML='';if(category==='personalized'){const sections={'🔥 Abdômen e Core':exercises.filter(ex=>['Prancha com Elevação de Perna','Prancha com Balanço Lateral','Prancha Lateral com Rotação','Elevações Alternadas de Perna','Tesoura(Scissor Kicks)'].includes(ex.name)),'🦵 Pernas e Glúteos':exercises.filter(ex=>['Agachamento com Rotação'].includes(ex.name)),'💪 Costas e Mobilidade':exercises.filter(ex=>['Flexão e Extensão do Tronco','Exercício de Escápula','Alongamento Dinâmico Lateral','Alongamento de Lado(Sentado)','Torção de Torso(Sentado)'].includes(ex.name)),'🏋️ Ombros e Mobilidade':exercises.filter(ex=>['Alongamento de Ombro','Circundução com Garrafa','Alcance Cruzado nas Costas','Alongamento de Peitoral','Alongamento de Tríceps'].includes(ex.name)),'😊 Facial':exercises.filter(ex=>['Exercício para Queixo Duplo','Rosto Esculpido','Rosto Afinado','Linhas de Sorriso'].includes(ex.name))};const fragment=document.createDocumentFragment();Object.entries(sections).forEach(([sectionName,sectionExercises])=>{if(sectionExercises.length>0){const sectionHeader=document.createElement('div');sectionHeader.className='section-header';sectionHeader.innerHTML=`<h3>${sectionName}</h3>`;fragment.appendChild(sectionHeader);sectionExercises.forEach((exercise)=>{const card=document.createElement('div');card.className='exercise-card';if(this.wasCompletedIn24h(exercise.name)){card.classList.add('completed-24h')}card.innerHTML=`<div class="exercise-emoji">${exercise.emoji}</div><div class="exercise-info"><div class="exercise-name">${exercise.name}</div><div class="exercise-details">${exercise.sets}× ${exercise.reps}</div></div><div class="exercise-arrow">→</div>`;card.addEventListener('click',()=>{this.startWorkout(sectionExercises,sectionExercises.indexOf(exercise))});fragment.appendChild(card)})}});container.appendChild(fragment);this.navigateTo('exercisesList');return}const fragment=document.createDocumentFragment();exercises.forEach((exercise,index)=>{const card=document.createElement('div');card.className='exercise-card';if(this.wasCompletedIn24h(exercise.name)){card.classList.add('completed-24h')}card.innerHTML=`<div class="exercise-emoji">${exercise.emoji}</div><div class="exercise-info"><div class="exercise-name">${exercise.name}</div><div class="exercise-details">${exercise.sets}× ${exercise.reps}</div></div><div class="exercise-arrow">→</div>`;card.addEventListener('click',()=>{const exerciseIndex=exercises.indexOf(exercise);this.startWorkout(exercises,exerciseIndex)});fragment.appendChild(card)});container.appendChild(fragment);this.navigateTo('exercisesList')}startWorkout(exercises,startIndex=0){this.currentWorkout=exercises.map(ex=>{if(ex.videoFile){return{...ex,video:this.VIDEO_BASE_URL+ex.videoFile,isLocalVideo:true}}else if(ex.youtubeId){return{...ex,youtubeId:ex.youtubeId}}return ex});this.currentExerciseIndex=startIndex;this.currentSeries=0;this.workoutStartTime=Date.now();this.playSound('startYoga');setTimeout(()=>{this.playSound('backgroundYoga')},2000);this.navigateTo('workoutSession');this.displayCurrentExercise();this.startWorkoutTimer()}displayCurrentExercise(){const exercise=this.currentWorkout[this.currentExerciseIndex];document.getElementById('currentExerciseName').textContent=exercise.name;document.getElementById('exerciseCount').textContent=`Exercício ${this.currentExerciseIndex+1}de ${this.currentWorkout.length}`;const demoVideo=document.getElementById('demoVideo');const demoIcon=document.getElementById('demoIcon');const exerciseDemo=document.getElementById('exerciseDemo');if(demoVideo){demoVideo.onended=null;demoVideo.ontimeupdate=null}if(exercise.youtubeId){const youtubeContainer=exerciseDemo.querySelector('.demo-placeholder');youtubeContainer.innerHTML='';const iframe=document.createElement('iframe');iframe.id='youtube-player';iframe.width='100%';iframe.height='100%';iframe.style.borderRadius='var(--radius-lg)';iframe.style.maxHeight='60vh';iframe.src=`https://www.youtube.com/embed/${exercise.youtubeId}?autoplay=1&mute=1&loop=1&playlist=${exercise.youtubeId}&modestbranding=1&rel=0&showinfo=0&controls=1&playsinline=1`;iframe.allow='accelerometer;autoplay;clipboard-write;encrypted-media;gyroscope;picture-in-picture';iframe.allowFullscreen=true;youtubeContainer.appendChild(iframe);this.playCuteSound('tap')}else if(exercise.video){const skip4SecondsExercises=['Prancha com Balanço Lateral','Prancha com Elevação de Perna','Tesoura(Scissor Kicks)','Elevação Alternada de Pernas'];const startTime=skip4SecondsExercises.includes(exercise.name)?4:3;demoVideo.setAttribute('playsinline','');demoVideo.setAttribute('muted','');demoVideo.muted=true;const videoSource=demoVideo.querySelector('source');let videoUrl=exercise.video;videoSource.src=videoUrl;videoSource.type='video/mp4';demoVideo.load();const handleVideoError=()=>{console.warn('⚠️ Vídeo local falhou,tentando CDN...');if(exercise.video.startsWith('videos/')){const videoFileName=exercise.video.replace('videos/','');const cdnUrl=this.VIDEO_BASE_URL_FALLBACK+videoFileName;videoSource.src=cdnUrl;demoVideo.load();demoVideo.addEventListener('canplaythrough',()=>{demoVideo.currentTime=startTime;demoVideo.play().catch(err=>{console.error('❌ CDN também falhou:',err);demoVideo.style.display='none';demoIcon.style.display='block'})},{once:true})}else{console.error('❌ Vídeo externo falhou');demoVideo.style.display='none';demoIcon.style.display='block'}};demoVideo.onerror=handleVideoError;videoSource.onerror=handleVideoError;demoVideo.addEventListener('loadeddata',()=>{demoVideo.currentTime=startTime;demoVideo.style.display='block';demoIcon.style.display='none';const playPromise=demoVideo.play();if(playPromise!==undefined){playPromise.catch(err=>{console.warn('⚠️ Autoplay bloqueado(normal em mobile):',err.message);const playButton=document.getElementById('videoPlayButton');if(playButton){playButton.style.display='block';const playHandler=()=>{demoVideo.currentTime=startTime;demoVideo.play().then(()=>{playButton.style.display='none';this.playCuteSound('tap')}).catch(err2=>{console.error('❌ Erro ao tocar vídeo:',err2)})};playButton.addEventListener('click',playHandler,{once:true});demoVideo.addEventListener('click',playHandler,{once:true})}})}},{once:true});demoVideo.dataset.startTime=startTime;demoVideo.onended=()=>{const skipTime=parseInt(demoVideo.dataset.startTime)||3;demoVideo.currentTime=skipTime;demoVideo.play().catch(()=>{})};let lastLoopCheck=0;demoVideo.ontimeupdate=()=>{const now=Date.now();if(now-lastLoopCheck<100)return;lastLoopCheck=now;const skipTime=parseInt(demoVideo.dataset.startTime)||3;if(demoVideo.currentTime>=demoVideo.duration-0.5){demoVideo.currentTime=skipTime}}}else{demoVideo.style.display='none';demoIcon.style.display='block';demoIcon.textContent=exercise.emoji||'💪'}document.getElementById('repsInfo').textContent=`${exercise.sets}séries × ${exercise.reps}`;document.getElementById('restInfo').textContent=`Descanso:${exercise.rest||30}s entre séries`;this.updateSeriesTracker(exercise.sets);const progress=((this.currentExerciseIndex+(this.currentSeries/exercise.sets))/this.currentWorkout.length)*100;document.getElementById('workoutProgressBar').style.width=`${progress}%`;this.preloadNextVideo()}preloadNextVideo(){const nextIndex=this.currentExerciseIndex+1;if(nextIndex<this.currentWorkout.length){const nextExercise=this.currentWorkout[nextIndex];if(nextExercise.video){const link=document.createElement('link');link.rel='preload';link.as='video';link.href=nextExercise.video;document.head.appendChild(link)}}}updateSeriesTracker(totalSeries){const tracker=document.getElementById('seriesTracker');const fragment=document.createDocumentFragment();for(let i=0;i<totalSeries;i++){const dot=document.createElement('div');dot.className='series-dot';if(i<this.currentSeries){dot.classList.add('completed')}fragment.appendChild(dot)}tracker.innerHTML='';tracker.appendChild(fragment)}startWorkoutTimer(){if(this.workoutTimer){clearInterval(this.workoutTimer);this.workoutTimer=null}this.workoutSeconds=0;this.workoutTimer=setInterval(()=>{this.workoutSeconds++;const mins=Math.floor(this.workoutSeconds/60);const secs=this.workoutSeconds%60;const timerEl=document.getElementById('workoutTimer');if(timerEl){timerEl.textContent=`${String(mins).padStart(2,'0')}:${String(secs).padStart(2,'0')}`}},1000)}completeCurrentExercise(){const exercise=this.currentWorkout[this.currentExerciseIndex];this.currentSeries++;this.playCuteSound('success');if(this.currentSeries>=exercise.sets){this.currentExerciseIndex++;this.currentSeries=0;if(this.currentExerciseIndex>=this.currentWorkout.length){this.completeWorkout()}else{this.displayCurrentExercise();this.playCuteSound('tap')}}else{this.updateSeriesTracker(exercise.sets);this.showRestPeriod(exercise.rest||30)}}showRestPeriod(seconds){const btn=document.getElementById('completeExercise');const skipBtn=document.getElementById('skipExercise');const originalText=btn.textContent;const originalSkipText=skipBtn.textContent;let remaining=seconds;btn.textContent=`Descansando... ${remaining}s`;btn.disabled=true;skipBtn.textContent='Pular Descanso ⏭️';skipBtn.style.display='block';if(remaining>5){this.playCuteSound('tap')}if(this.restInterval){clearInterval(this.restInterval);this.restInterval=null}this.restInterval=setInterval(()=>{remaining--;btn.textContent=`Descansando... ${remaining}s`;if(remaining===10){this.playCuteSound('tap')}else if(remaining===5){this.playCuteSound('tap')}else if(remaining<=3&&remaining>0){this.playSound('countdown')}else if(remaining===0){this.playCuteSound('success')}if(remaining<=0){clearInterval(this.restInterval);btn.textContent=originalText;btn.disabled=false;skipBtn.textContent=originalSkipText;this.restInterval=null}},1000);this.currentRestInterval=this.restInterval;this.isResting=true;const skipRestHandler=()=>{if(this.isResting){clearInterval(this.currentRestInterval);btn.textContent=originalText;btn.disabled=false;skipBtn.textContent=originalSkipText;this.isResting=false;this.playCuteSound('tap')}};if(this.skipRestHandler){skipBtn.removeEventListener('click',this.skipRestHandler)}this.skipRestHandler=skipRestHandler;skipBtn.addEventListener('click',skipRestHandler)}skipExercise(){if(this.isResting){return}this.currentExerciseIndex++;this.currentSeries=0;if(this.skipRestHandler){const skipBtn=document.getElementById('skipExercise');if(skipBtn){skipBtn.removeEventListener('click',this.skipRestHandler)}this.skipRestHandler=null}if(this.currentExerciseIndex>=this.currentWorkout.length){this.completeWorkout()}else{this.displayCurrentExercise();this.playCuteSound('tap')}}completeWorkout(){if(this.isCompletingWorkout){return}this.isCompletingWorkout=true;clearInterval(this.workoutTimer);this.workoutTimer=null;const durationInSeconds=this.workoutSeconds||Math.floor((Date.now()-this.workoutStartTime)/1000);const duration=Math.max(1,Math.floor(durationInSeconds/60));const calories=this.calculateCalories(duration,this.currentWorkout);if(this.currentDayPlan){this.markDayComplete(this.currentDayPlan.day);this.currentDayPlan=null}this.progress.workoutsCompleted=(this.progress.workoutsCompleted||0)+1;this.progress.totalMinutes=(this.progress.totalMinutes||0)+duration;this.progress.totalCalories=(this.progress.totalCalories||0)+calories;this.progress.lastWorkout=new Date().toISOString();if(!this.progress.longestWorkout||duration>this.progress.longestWorkout){this.progress.longestWorkout=duration}if(!this.progress.workoutHistory){this.progress.workoutHistory=[]}this.progress.workoutHistory.push({date:new Date().toISOString(),duration:duration,calories:calories,category:this.currentCategory});if(!this.progress.completedExercises){this.progress.completedExercises=[]}this.currentWorkout.forEach(exercise=>{this.progress.completedExercises.push({name:exercise.name,completedAt:new Date().toISOString(),category:this.currentCategory})});if(this.progress.completedExercises.length>50){this.progress.completedExercises=this.progress.completedExercises.slice(-50)}this.updateStreak();this.saveProgress();this.updateAllStats();this.stopSound('backgroundYoga');this.playCuteSound('complete');this.playSound('motivational');this.sendNotification('🎉 Treino Concluído!',`Você queimou ${calories}kcal em ${duration}minutos!Continue assim!💪`);document.getElementById('summaryTime').textContent=`${duration}min`;document.getElementById('summaryCalories').textContent=`${calories}kcal`;document.getElementById('summaryExercises').textContent=`${this.currentWorkout.length}exercícios`;let detailsHTML='<strong>📊 Detalhes do Treino:</strong><br><br>';this.currentWorkout.forEach((exercise,index)=>{const exerciseCalories=Math.round(this.getExerciseCaloriesPerMinute(exercise.name)*(duration/this.currentWorkout.length)*(exercise.sets/3));detailsHTML+=`<div style="margin-bottom:8px;"><strong>${index+1}. ${exercise.name}</strong><br><span style="font-size:0.85rem;">${exercise.sets}séries × ${exercise.reps}repetições<br>~${exerciseCalories}kcal queimadas</span></div>`});document.getElementById('workoutDetails').innerHTML=detailsHTML;document.getElementById('completionModal').classList.add('active');this.checkAchievements();this.updateWeightBasedOnCalories();this.updateUI();this.updateDetailedStats();this.isCompletingWorkout=false}endWorkout(completed=false){clearInterval(this.workoutTimer);this.workoutSeconds=0;this.stopSound('backgroundYoga');this.stopSound('startYoga');if(this.currentCategory){this.goBack()}else{this.navigateTo('home')}}getExerciseCaloriesPerMinute(exerciseName){const name=exerciseName.toLowerCase();let caloriesPerMinute=8;if(name.includes('scissor')||name.includes('tesoura')){caloriesPerMinute=12}else if(name.includes('prancha')||name.includes('plank')){caloriesPerMinute=10}else if(name.includes('elevação')||name.includes('leg lift')){caloriesPerMinute=9}else if(name.includes('face')||name.includes('rosto')||name.includes('papada')||name.includes('chin')||name.includes('linha')||name.includes('esculpida')||name.includes('afinada')){caloriesPerMinute=3}else if(name.includes('agachamento')||name.includes('squat')||name.includes('rotação')){caloriesPerMinute=11}else if(name.includes('flexão')||name.includes('push')||name.includes('extensão')){caloriesPerMinute=10}else if(name.includes('ponte')||name.includes('bridge')){caloriesPerMinute=9}else if(name.includes('burpee')||name.includes('jump')){caloriesPerMinute=14}else if(name.includes('polichinelo')||name.includes('jack')){caloriesPerMinute=13}else if(name.includes('alongamento')||name.includes('stretch')){caloriesPerMinute=6}else if(name.includes('torção')||name.includes('twist')){caloriesPerMinute=7}else if(name.includes('yoga')){caloriesPerMinute=5}else if(name.includes('massagem')||name.includes('massage')){caloriesPerMinute=2}return caloriesPerMinute}calculateCalories(minutes,workoutExercises=null){if(!workoutExercises||workoutExercises.length===0){return Math.round(minutes*8)}const userWeight=this.userProfile?.weight||65;let totalCalories=0;const minutesPerExercise=minutes/workoutExercises.length;workoutExercises.forEach(exercise=>{const met=this.getExerciseMET(exercise.name);const timeInHours=minutesPerExercise/60;const caloriesFromMET=met*userWeight*timeInHours;const sets=exercise.sets||3;let reps=15;if(typeof exercise.reps==='number'){reps=exercise.reps}else if(typeof exercise.reps==='string'){const repsMatch=exercise.reps.match(/\d+/);if(repsMatch){reps=parseInt(repsMatch[0])}}const intensityFactor=(sets*reps)/45;const caloriesForThisExercise=caloriesFromMET*intensityFactor;totalCalories+=caloriesForThisExercise});return Math.round(totalCalories)}getExerciseMET(exerciseName){const metValues={'prancha com balanço lateral':8.5,'prancha com elevação de perna':9.0,'tesoura':8.0,'elevação alternada de pernas':7.5,'prancha lateral com rotação':8.5,'face esculpida':2.0,'face afinada':2.0,'redução de linhas':2.0,'redução de papada':2.5,'alongamento lateral dinâmico':3.5,'torção do tronco sentado':4.0,'flexão lateral em pé':3.5,'agachamento com rotação':9.0,'flexão e extensão do tronco':5.5,'prancha':8.0,'abdominal':8.0,'bicicleta':8.0,'mountain climber':8.0,'russian twist':7.0,'scissor':8.0,'agachamento':8.0,'afundo':8.0,'ponte':6.0,'leg lift':7.0,'elevação':7.5,'squat':8.0,'lunge':8.0,'glúteo':7.0,'ponte glúteos':6.0,'chute':7.0,'donkey kick':7.0,'flexão':8.0,'tríceps':7.0,'prancha lateral':8.0,'push-up':8.0,'burpee':12.0,'jumping jack':8.0,'pular':10.0,'corrida':10.0,'polichinelo':8.0,'yoga':3.0,'alongamento':2.5,'respiração':2.0,'torção':4.0,'twist':4.0,'massagem':2.0,'postura':2.5,'face':2.0,'facial':2.0,'papada':2.5,'chin':2.5,'linha':2.0,'esculpida':2.0,'afinada':2.0};const lowerName=exerciseName.toLowerCase();if(metValues[lowerName]){return metValues[lowerName]}for(const[key,met]of Object.entries(metValues)){if(lowerName.includes(key)){return met}}return 6.0}updateWeightBasedOnCalories(){if(!this.userProfile||!this.weightData||!this.weightData.history||this.weightData.history.length===0)return;const today=new Date().toDateString();const lastWeightEntry=this.weightData.history[this.weightData.history.length-1];const lastWeightDate=new Date(lastWeightEntry.date).toDateString();if(lastWeightDate===today)return;const caloriesIn=this.progress.dailyCaloriesConsumed||this.userProfile.targetCalories;const caloriesBurned=this.progress.totalCalories||0;const tdee=this.userProfile.tdee||2000;const dailyDeficit=(tdee+caloriesBurned)-caloriesIn;const weightChange=dailyDeficit/7700;const safeWeightChange=Math.max(-0.15,Math.min(0.15,weightChange));const currentWeight=lastWeightEntry.weight;const newWeight=Math.max(30,currentWeight-safeWeightChange);this.weightData.history.push({date:new Date().toISOString(),weight:parseFloat(newWeight.toFixed(1)),auto:true});this.weightData.current=newWeight;this.userProfile.weight=newWeight;this.saveWeightData();this.saveUserProfile();this.progress.dailyCaloriesConsumed=this.userProfile.targetCalories;this.saveProgress()}addCaloriesConsumed(calories){if(!this.progress.dailyCaloriesConsumed){this.progress.dailyCaloriesConsumed=0}this.progress.dailyCaloriesConsumed+=calories;this.saveProgress();this.updateUI()}resetDailyCalories(){const today=new Date().toDateString();const lastReset=this.progress.lastCalorieReset||'';if(lastReset!==today){this.progress.dailyCaloriesConsumed=0;this.progress.lastCalorieReset=today;this.saveProgress()}}updateStreak(){const today=new Date().toDateString();const lastWorkout=this.progress.lastWorkout?new Date(this.progress.lastWorkout).toDateString():null;if(!lastWorkout){this.progress.streak=1}else{const yesterday=new Date();yesterday.setDate(yesterday.getDate()-1);if(lastWorkout===today){return}else if(lastWorkout===yesterday.toDateString()){this.progress.streak=(this.progress.streak||0)+1}else{this.progress.streak=1}}if(!this.progress.longestStreak||this.progress.streak>this.progress.longestStreak){this.progress.longestStreak=this.progress.streak}}toggleWater(index){const glasses=document.querySelectorAll('.glass');const glass=glasses[index];if(glass.classList.contains('filled')){for(let i=index;i<glasses.length;i++){glasses[i].classList.remove('filled')}}else{for(let i=0;i<=index;i++){glasses[i].classList.add('filled')}this.playCuteSound('tap')}const filled=document.querySelectorAll('.glass.filled').length;document.getElementById('waterCount').textContent=filled;if(filled===8){this.playCuteSound('success')}const today=new Date().toISOString().split('T')[0];if(!this.progress.water)this.progress.water={};this.progress.water[today]=Array(filled).fill(1);this.saveProgress();this.updateDetailedStats()}startWellnessSession(type){const sessions=this.getWellnessSessions();const session=sessions[type];if(session){this.startWorkout(session.exercises,0)}}updateAllStats(){if(this.weightData&&this.userProfile){if(this.weightData.current&&this.weightData.current!==this.userProfile.weight){this.userProfile.weight=this.weightData.current;this.saveUserProfile()}if(this.weightData.goal&&this.weightData.goal!==this.userProfile.goalWeight){this.userProfile.goalWeight=this.weightData.goal;this.saveUserProfile()}}this.updateUI();this.updateWeightDisplay();this.updateDetailedStats()}updateUI(){const hour=new Date().getHours();let greeting='Olá';if(hour<12)greeting='Bom dia';else if(hour<18)greeting='Boa tarde';else greeting='Boa noite';const name=this.userProfile?this.userProfile.name.split(' ')[0]:'Guerreira';const greetingEl=document.getElementById('greeting');if(greetingEl)greetingEl.textContent=`${greeting},${name}!`;if(this.userProfile&&this.userProfile.photo){const avatar=document.querySelector('.avatar');if(avatar){avatar.style.backgroundImage=`url(${this.userProfile.photo})`;avatar.style.backgroundSize='cover';avatar.style.backgroundPosition='center';avatar.textContent=''}}this.updatePlanSummary();const streakEl=document.getElementById('streakDays');if(streakEl)streakEl.textContent=this.progress.streak||0;const todayProgress=this.calculateTodayProgress();const progressValueEl=document.getElementById('progressValue');const progressFillEl=document.getElementById('progressFill');if(progressValueEl)progressValueEl.textContent=todayProgress;if(progressFillEl)progressFillEl.style.setProperty('--progress',todayProgress);const caloriesBurnedEl=document.getElementById('caloriesBurned');const minutesActiveEl=document.getElementById('minutesActive');const workoutsCompletedEl=document.getElementById('workoutsCompleted');if(caloriesBurnedEl)caloriesBurnedEl.textContent=this.progress.totalCalories||0;if(minutesActiveEl)minutesActiveEl.textContent=this.progress.totalMinutes||0;if(workoutsCompletedEl)workoutsCompletedEl.textContent=this.progress.workoutsCompleted||0;const totalWorkoutsEl=document.getElementById('totalWorkouts');const totalMinutesEl=document.getElementById('totalMinutes');const totalCaloriesEl=document.getElementById('totalCalories');const daysActiveEl=document.getElementById('daysActive');if(totalWorkoutsEl)totalWorkoutsEl.textContent=this.progress.workoutsCompleted||0;if(totalMinutesEl)totalMinutesEl.textContent=this.progress.totalMinutes||0;if(totalCaloriesEl)totalCaloriesEl.textContent=this.progress.totalCalories||0;if(daysActiveEl)daysActiveEl.textContent=this.progress.daysActive||0;const waterToday=this.getWaterToday();document.querySelectorAll('.glass').forEach((glass,index)=>{if(index<waterToday){glass.classList.add('filled')}else{glass.classList.remove('filled')}});document.getElementById('waterCount').textContent=waterToday}calculateTodayProgress(){const workouts=this.progress.todayWorkouts||0;const water=this.getWaterToday();const workoutProgress=Math.min((workouts/2)*100,50);const waterProgress=Math.min((water/8)*100,50);return Math.round(workoutProgress+waterProgress)}getWaterToday(){const today=new Date().toISOString().split('T')[0];const waterData=this.progress.water?.[today];if(Array.isArray(waterData)){return waterData.length}return 0}loadAchievements(){this.achievements=[{id:'first-workout',name:'Primeiro Passo',emoji:'👟',unlocked:(this.progress.workoutsCompleted||0)>=1},{id:'five-workouts',name:'5 Treinos',emoji:'💪',unlocked:(this.progress.workoutsCompleted||0)>=5},{id:'week-streak',name:'1 Semana',emoji:'🔥',unlocked:(this.progress.streak||0)>=7},{id:'ten-workouts',name:'10 Treinos',emoji:'🏋️',unlocked:(this.progress.workoutsCompleted||0)>=10},{id:'water-master',name:'Hidratada',emoji:'💧',unlocked:this.checkWaterStreak(5)},{id:'month-streak',name:'1 Mês',emoji:'🏆',unlocked:(this.progress.streak||0)>=30},{id:'twenty-workouts',name:'20 Treinos',emoji:'💯',unlocked:(this.progress.workoutsCompleted||0)>=20},{id:'fifty-workouts',name:'50 Treinos',emoji:'⭐',unlocked:(this.progress.workoutsCompleted||0)>=50},{id:'weight-loss',name:'Peso Perdido',emoji:'📉',unlocked:this.checkWeightLoss()},{id:'hundred-workouts',name:'100 Treinos',emoji:'🎯',unlocked:(this.progress.workoutsCompleted||0)>=100},{id:'yoga-master',name:'Mestre Yoga',emoji:'🧘♀️',unlocked:this.checkYogaWorkouts()},{id:'dedication',name:'Dedicação',emoji:'🌟',unlocked:(this.progress.daysActive||0)>=30}];const container=document.getElementById('achievementsGrid');if(container){const fragment=document.createDocumentFragment();this.achievements.forEach(achievement=>{const card=document.createElement('div');card.className=`achievement-card ${achievement.unlocked?'':'locked'}`;card.innerHTML=`<div class="achievement-icon">${achievement.unlocked?achievement.emoji:'🔒'}</div><div class="achievement-name">${achievement.name}</div>`;fragment.appendChild(card)});container.innerHTML='';container.appendChild(fragment)}}checkWeightLoss(){if(this.weightData.initial&&this.weightData.current){return this.weightData.initial>this.weightData.current}return false}checkYogaWorkouts(){if(!this.progress.workoutHistory)return false;const yogaWorkouts=this.progress.workoutHistory.filter(w=>w.category==='yoga');return yogaWorkouts.length>=5}checkAchievements(){this.loadAchievements()}checkWaterStreak(days){if(!this.progress.water)return false;let streak=0;const today=new Date();for(let i=0;i<30;i++){const date=new Date(today);date.setDate(date.getDate()-i);const dateStr=date.toDateString();if(this.progress.water[dateStr]>=8){streak++;if(streak>=days)return true}else{break}}return false}requestNotificationPermission(){if('Notification' in window&&Notification.permission!=='granted'){Notification.requestPermission().then(permission=>{if(permission==='granted'){new Notification('Notificações Ativadas!🔔',{body:'Você receberá lembretes motivacionais!',icon:'/icons/icon.svg'})}})}}playSound(){if(this.userData.soundEnabled!==false){const context=new(window.AudioContext||window.webkitAudioContext)();const oscillator=context.createOscillator();const gainNode=context.createGain();oscillator.connect(gainNode);gainNode.connect(context.destination);oscillator.frequency.value=800;oscillator.type='sine';gainNode.gain.setValueAtTime(0.3,context.currentTime);gainNode.gain.exponentialRampToValueAtTime(0.01,context.currentTime+0.1);oscillator.start(context.currentTime);oscillator.stop(context.currentTime+0.1)}}loadUserData(){try{const data=localStorage.getItem('userData');if(!data)return{};const parsed=JSON.parse(data);if(typeof parsed!=='object'||parsed===null){console.warn('⚠️ Invalid userData structure,resetting');return{}}return parsed}catch(e){console.error('⚠️ Failed to load userData,resetting:',e);localStorage.removeItem('userData');return{}}}loadProgress(){try{if(window.PerformanceUtils){const data=window.PerformanceUtils.safeLocalStorageGet('userProgress',null,true);if(!data){return this.getDefaultProgress()}if(typeof data!=='object'||data===null){console.warn('Invalid progress data,resetting');return this.getDefaultProgress()}return{...this.getDefaultProgress(),...data}}else{const dataString=localStorage.getItem('userProgress');if(!dataString){return this.getDefaultProgress()}const parsed=JSON.parse(dataString);if(typeof parsed!=='object'||parsed===null){console.warn('Invalid progress data,resetting');return this.getDefaultProgress()}return{...this.getDefaultProgress(),...parsed}}}catch(e){console.error('Error loading progress:',e);return this.getDefaultProgress()}}getDefaultProgress(){return{workoutsCompleted:0,totalMinutes:0,totalCalories:0,streak:0,daysActive:0,water:{},workoutHistory:[],todayWorkouts:0,todayMinutes:0,todayCalories:0,longestStreak:0,longestWorkout:0,memberSince:null}}saveProgress(){if(!this.saveProgressDebounced){if(window.PerformanceUtils){this.saveProgressDebounced=window.PerformanceUtils.debounce(()=>{this._doSaveProgress()},300)}else{this.saveProgressDebounced=this._doSaveProgress.bind(this)}}this.saveProgressDebounced()}_doSaveProgress(){try{if(window.PerformanceUtils){const shouldCompress=JSON.stringify(this.progress).length>50000;window.PerformanceUtils.safeLocalStorageSet('userProgress',this.progress,shouldCompress)}else{localStorage.setItem('userProgress',JSON.stringify(this.progress))}}catch(e){console.error('Failed to save progress:',e);if(e.name==='QuotaExceededError'){this.compressProgress()}}}compressProgress(){if(this.progress.workoutHistory&&this.progress.workoutHistory.length>30){this.progress.workoutHistory=this.progress.workoutHistory.slice(-30)}if(this.progress.water){const thirtyDaysAgo=new Date();thirtyDaysAgo.setDate(thirtyDaysAgo.getDate()-30);const recentWater={};Object.keys(this.progress.water).forEach(key=>{const date=new Date(key);if(date>=thirtyDaysAgo){recentWater[key]=this.progress.water[key]}});this.progress.water=recentWater}try{localStorage.setItem('userProgress',JSON.stringify(this.progress))}catch(e){console.error('Still failed after compression:',e)}}loadWeightData(){try{const data=localStorage.getItem('weightData');if(!data){return this.getDefaultWeightData()}const parsed=JSON.parse(data);if(typeof parsed!=='object'||parsed===null){console.warn('⚠️ Invalid weight data structure');return this.getDefaultWeightData()}if(!parsed.history||!Array.isArray(parsed.history)){console.warn('⚠️ Missing or invalid weight history field');localStorage.removeItem('weightData');return this.getDefaultWeightData()}return{...this.getDefaultWeightData(),...parsed}}catch(e){console.error('⚠️ Corrupted weight data,resetting:',e);localStorage.removeItem('weightData');return this.getDefaultWeightData()}}getDefaultWeightData(){return{current:null,initial:null,goal:null,history:[]}}saveWeightData(){if(!this.saveWeightDebounced){if(window.PerformanceUtils){this.saveWeightDebounced=window.PerformanceUtils.debounce(()=>{try{window.PerformanceUtils.safeLocalStorageSet('weightData',this.weightData)}catch(e){console.error('Failed to save weight data:',e)}},300)}else{this.saveWeightDebounced=()=>{try{localStorage.setItem('weightData',JSON.stringify(this.weightData))}catch(e){console.error('Failed to save weight data:',e)}}}}this.saveWeightDebounced()}showWeightModal(){const modal=document.getElementById('weightModal');const weightInput=document.getElementById('weightInput');const goalInput=document.getElementById('goalWeightInput');weightInput.value=this.weightData.current||'';goalInput.value=this.weightData.goal||'';modal.classList.add('active');this.playCuteSound('tap')}closeWeightModal(){const modal=document.getElementById('weightModal');modal.classList.remove('active');this.playCuteSound('tap')}saveWeight(){const weightInput=document.getElementById('weightInput');const goalInput=document.getElementById('goalWeightInput');if(!weightInput||!goalInput){console.error('Weight inputs not found');return}const newWeight=this.sanitizeNumber(weightInput.value,30,300,null);const newGoal=this.sanitizeNumber(goalInput.value,30,300,null);if(newWeight===null||newWeight<30||newWeight>300){alert('Por favor,insira um peso válido entre 30 e 300 kg');return}if(newGoal===null||newGoal<30||newGoal>300){alert('Por favor,insira uma meta válida entre 30 e 300 kg');return}if(this.userProfile){this.userProfile.weight=newWeight;this.userProfile.goalWeight=newGoal;this.saveUserProfile()}if(this.weightData.initial===null){this.weightData.initial=newWeight;if(!this.progress.memberSince){this.progress.memberSince=new Date().toISOString()}}this.weightData.current=newWeight;this.weightData.goal=newGoal;const today=new Date().toISOString().split('T')[0];const existingIndex=this.weightData.history.findIndex(entry=>entry.date===today);if(existingIndex>=0){this.weightData.history[existingIndex].weight=newWeight}else{this.weightData.history.push({date:today,weight:newWeight})}if(this.weightData.history.length>30){this.weightData.history=this.weightData.history.slice(-30)}this.saveWeightData();this.saveProgress();this.updateAllStats();this.closeWeightModal();this.playCuteSound('success')}updateWeightDisplay(){const currentWeightEl=document.getElementById('currentWeight');const initialWeightEl=document.getElementById('initialWeight');const goalWeightEl=document.getElementById('goalWeight');const weightLostEl=document.getElementById('weightLost');const weightProgressFill=document.getElementById('weightProgressFill');const weightChartMini=document.getElementById('weightChartMini');if(currentWeightEl){if(this.weightData.current){currentWeightEl.textContent=`${this.weightData.current}kg`}else{currentWeightEl.textContent='--'}}if(initialWeightEl){if(this.weightData.initial){initialWeightEl.textContent=`${this.weightData.initial}kg`}else{initialWeightEl.textContent='--'}}if(goalWeightEl){if(this.weightData.goal){goalWeightEl.textContent=`${this.weightData.goal}kg`}else{goalWeightEl.textContent='--'}}if(weightLostEl){if(this.weightData.initial&&this.weightData.current){const lost=this.weightData.initial-this.weightData.current;weightLostEl.textContent=`${lost.toFixed(1)}kg`}else{weightLostEl.textContent='0 kg'}}if(weightProgressFill){if(this.weightData.initial&&this.weightData.current&&this.weightData.goal){const totalToLose=this.weightData.initial-this.weightData.goal;const lost=this.weightData.initial-this.weightData.current;const percentage=Math.min(100,(lost/totalToLose)*100);weightProgressFill.style.width=`${Math.max(0,percentage)}%`}else{weightProgressFill.style.width='0%'}}if(weightChartMini&&this.weightData.history&&this.weightData.history.length>0){const maxWeight=Math.max(...this.weightData.history.map(e=>e.weight));const minWeight=Math.min(...this.weightData.history.map(e=>e.weight));const range=maxWeight-minWeight||1;weightChartMini.innerHTML=this.weightData.history.slice(-10).map(entry=>{const height=((entry.weight-minWeight)/range)*80+20;return `<div class="weight-chart-bar" style="height:${height}px" title="${entry.date}:${entry.weight}kg"></div>`}).join('')}}wasCompletedIn24h(exerciseName){if(!this.progress.completedExercises){return false}const now=new Date();const twentyFourHoursAgo=new Date(now.getTime()-(24*60*60*1000));this.progress.completedExercises=this.progress.completedExercises.filter(ex=>{const completedDate=new Date(ex.completedAt);return completedDate>twentyFourHoursAgo});return this.progress.completedExercises.some(ex=>{const completedDate=new Date(ex.completedAt);return ex.name===exerciseName&&completedDate>twentyFourHoursAgo})}renderWeeklyActivity(){const container=document.getElementById('weeklyActivityGrid');if(!container)return;container.innerHTML='';const today=new Date();const weekDays=['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'];const fragment=document.createDocumentFragment();for(let i=6;i>=0;i--){const date=new Date(today);date.setDate(date.getDate()-i);const dayName=weekDays[date.getDay()];const dayNumber=date.getDate();const isToday=date.toDateString()===today.toDateString();const workoutsCount=this.progress.workoutHistory?this.progress.workoutHistory.filter(w=>{const workoutDate=new Date(w.date);return workoutDate.toDateString()===date.toDateString()}).length:0;const dayElement=document.createElement('div');dayElement.className='weekly-day';if(workoutsCount>0){dayElement.classList.add('active')}if(isToday){dayElement.classList.add('today')}dayElement.innerHTML=`<div class="weekly-day-name">${dayName}</div><div class="weekly-day-number">${dayNumber}</div><div class="weekly-day-workouts">${workoutsCount>0?`${workoutsCount}treino${workoutsCount>1?'s':''}`:'-'}</div>`;fragment.appendChild(dayElement)}container.appendChild(fragment)}updateDetailedStats(){this.renderWeeklyActivity();document.getElementById('totalWorkouts').textContent=this.progress.workoutsCompleted||0;document.getElementById('totalMinutes').textContent=this.progress.totalMinutes||0;document.getElementById('totalCaloriesDetail').textContent=this.progress.totalCalories||0;const uniqueDays=new Set();if(this.progress.workoutHistory){this.progress.workoutHistory.forEach(w=>{const date=new Date(w.date).toDateString();uniqueDays.add(date)})}this.progress.daysActive=uniqueDays.size;document.getElementById('daysActiveDetail').textContent=this.progress.daysActive||0;document.getElementById('currentStreak').textContent=this.progress.streak||0;if(this.userProfile){const bmi=this.userProfile.bmi||this.calculateBMI(this.userProfile.weight,this.userProfile.height);let bmiCategory='';let bmiColor='';if(bmi<18.5){bmiCategory='Abaixo do Peso';bmiColor='#FFA726'}else if(bmi<25){bmiCategory='Peso Normal';bmiColor='#4CAF50'}else if(bmi<30){bmiCategory='Sobrepeso';bmiColor='#FF9800'}else{bmiCategory='Obesidade';bmiColor='#F44336'}let bmiCard=document.getElementById('bmiCard');if(!bmiCard){const statsGrid=document.querySelector('.stats-grid');if(statsGrid){bmiCard=document.createElement('div');bmiCard.id='bmiCard';bmiCard.className='stat-detail-card';statsGrid.insertBefore(bmiCard,statsGrid.firstChild)}}if(bmiCard){bmiCard.innerHTML=`<div class="stat-detail-icon">⚖️</div><div class="stat-detail-content"><div class="stat-detail-number" style="color:${bmiColor};">${bmi}</div><div class="stat-detail-label">IMC(Índice de Massa Corporal)</div><div class="stat-detail-sublabel" style="color:${bmiColor};">${bmiCategory}</div></div>`}let avgCalCard=document.getElementById('avgCaloriesCard');if(!avgCalCard){const statsGrid=document.querySelector('.stats-grid');if(statsGrid){avgCalCard=document.createElement('div');avgCalCard.id='avgCaloriesCard';avgCalCard.className='stat-detail-card';statsGrid.appendChild(avgCalCard)}}if(avgCalCard){const avgCal=this.progress.workoutsCompleted>0?Math.round(this.progress.totalCalories/this.progress.workoutsCompleted):0;avgCalCard.innerHTML=`<div class="stat-detail-icon">🔥</div><div class="stat-detail-content"><div class="stat-detail-number">${avgCal}</div><div class="stat-detail-label">Calorias Médias</div><div class="stat-detail-sublabel">por treino</div></div>`}}const thisWeek=this.getThisWeekWorkouts();document.getElementById('thisWeekWorkouts').textContent=thisWeek;const avgMinutes=this.progress.workoutsCompleted>0?Math.round(this.progress.totalMinutes/this.progress.workoutsCompleted):0;const avgCalories=this.progress.workoutsCompleted>0?Math.round(this.progress.totalCalories/this.progress.workoutsCompleted):0;document.getElementById('avgMinutes').textContent=avgMinutes;document.getElementById('avgCalories').textContent=avgCalories;const totalWaterGlasses=Object.values(this.progress.water||{}).reduce((sum,day)=>{return sum+(Array.isArray(day)?day.length:0)},0);const waterStreak=this.getWaterStreak();document.getElementById('totalWaterGlasses').textContent=totalWaterGlasses;document.getElementById('waterStreak').textContent=waterStreak;if(!this.achievements){this.loadAchievements()}const unlockedAchievements=this.achievements.filter(a=>a.unlocked).length;document.getElementById('achievementsUnlocked').textContent=unlockedAchievements;document.getElementById('totalAchievements').textContent=this.achievements.length;document.getElementById('longestStreak').textContent=`${this.progress.longestStreak||0}dias`;document.getElementById('longestWorkout').textContent=`${this.progress.longestWorkout||0}min`;const favoriteCategory=this.getFavoriteCategory();document.getElementById('favoriteCategory').textContent=favoriteCategory;if(this.progress.memberSince){const date=new Date(this.progress.memberSince);const formatted=date.toLocaleDateString('pt-BR');document.getElementById('memberSince').textContent=formatted}else{document.getElementById('memberSince').textContent='--'}this.renderWeeklyChart()}getThisWeekWorkouts(){if(!this.progress.workoutHistory)return 0;const oneWeekAgo=new Date();oneWeekAgo.setDate(oneWeekAgo.getDate()-7);return this.progress.workoutHistory.filter(workout=>{const workoutDate=new Date(workout.date);return workoutDate>=oneWeekAgo}).length}getWaterStreak(){if(!this.progress.water)return 0;let streak=0;const today=new Date();for(let i=0;i<365;i++){const date=new Date(today);date.setDate(date.getDate()-i);const dateKey=date.toISOString().split('T')[0];if(this.progress.water[dateKey]&&this.progress.water[dateKey].length>=8){streak++}else{break}}return streak}getFavoriteCategory(){if(!this.progress.workoutHistory||this.progress.workoutHistory.length===0){return '--'}const categoryCount={};this.progress.workoutHistory.forEach(workout=>{categoryCount[workout.category]=(categoryCount[workout.category]||0)+1});const favorite=Object.keys(categoryCount).reduce((a,b)=>categoryCount[a]>categoryCount[b]?a:b);const categoryNames={abs:'Abdômen',legs:'Pernas',glutes:'Glúteos',arms:'Braços',waist:'Cintura',back:'Costas',cardio:'Cardio',fullbody:'Corpo Todo',yoga:'Yoga',massage:'Massagem'};return categoryNames[favorite]||favorite}renderWeeklyChart(){const chartContainer=document.getElementById('weeklyChart');if(!chartContainer)return;const days=['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'];const today=new Date();const weekData=[];for(let i=6;i>=0;i--){const date=new Date(today);date.setDate(date.getDate()-i);const dayIndex=date.getDay();const dateKey=date.toISOString().split('T')[0];const workoutsOnDay=this.progress.workoutHistory?this.progress.workoutHistory.filter(w=>w.date.startsWith(dateKey)).length:0;weekData.push({label:days[dayIndex],value:workoutsOnDay})}const maxValue=Math.max(...weekData.map(d=>d.value),1);chartContainer.innerHTML=weekData.map(day=>{const heightPercent=(day.value/maxValue)*100;return `<div class="chart-day"><div class="chart-bar" style="height:${heightPercent}%"></div><div class="chart-label">${day.label}</div></div>`}).join('')}getExercisesByCategory(category){const exercises={personalized:[{name:'Prancha com Elevação de Perna',emoji:'🔥',videoFile:'Prancha com elevação de perna.mp4',sets:3,reps:'12 cada',rest:30,calories:12},{name:'Prancha com Balanço Lateral',emoji:'⚖️',videoFile:'Prancha com balanço lateral.mp4',sets:3,reps:'30s',rest:30,calories:11},{name:'Prancha Lateral com Rotação',emoji:'🔄',videoFile:'prancha lateral com rotação.mp4',sets:3,reps:'10 cada',rest:30,calories:13},{name:'Elevações Alternadas de Perna',emoji:'✂️',videoFile:'Alternating Leg Lifts.mp4',sets:3,reps:'20',rest:30,calories:10},{name:'Tesoura(Scissor Kicks)',emoji:'✂️',videoFile:'Scissor Kicks.mp4',sets:3,reps:'30s',rest:30,calories:11},{name:'Agachamento com Rotação',emoji:'🏋️♀️',videoFile:'agachamento rotação.mp4',sets:3,reps:'15',rest:35,calories:14},{name:'Flexão e Extensão do Tronco',emoji:'💪',videoFile:'flexao,extensão e hiperextenxao do tronco com baco estendido.mp4',sets:3,reps:'12',rest:30,calories:10},{name:'Exercício de Escápula',emoji:'🦋',videoFile:'Scapular winging exercise ou Elbow fly stretch.mp4',sets:3,reps:'15',rest:30,calories:9},{name:'Alongamento Dinâmico Lateral',emoji:'↔️',videoFile:'Dynamic Side Stretch].mp4',sets:2,reps:'10 cada',rest:25,calories:8},{name:'Alongamento de Lado(Sentado)',emoji:'🧘',videoFile:'Side Bend Stretch.mp4',sets:2,reps:'30s cada',rest:25,calories:6},{name:'Torção de Torso(Sentado)',emoji:'🔄',videoFile:'Seated Torso Twist.mp4',sets:3,reps:'15 cada',rest:25,calories:8},{name:'Alongamento de Ombro',emoji:'💆♀️',videoFile:'MobilidadeAlongamento de Ombro com Apoio(Garrafa ou Outro Objeto.mp4',sets:2,reps:'30s cada',rest:20,calories:7},{name:'Circundução com Garrafa',emoji:'🔄',videoFile:'Circundução órbita com a garrafa ao redor da nuca com reverso.mp4',sets:3,reps:'12',rest:30,calories:9},{name:'Alcance Cruzado nas Costas',emoji:'🤝',videoFile:'Alcance cruzado por trás das costas(pegada alternada).mp4',sets:2,reps:'10 cada',rest:25,calories:7},{name:'Alongamento de Peitoral',emoji:'💪',videoFile:'Alongamento de Peitoral com Mãos Entrelaçadas Atrás do Corpo.mp4',sets:2,reps:'30s',rest:20,calories:6},{name:'Alongamento de Tríceps',emoji:'💪',videoFile:'Overhead triceps stretch.mp4',sets:2,reps:'30s cada',rest:20,calories:6},{name:'Exercício para Queixo Duplo',emoji:'😊',videoFile:'Double chin.mp4',sets:2,reps:'15',rest:20,calories:4},{name:'Rosto Esculpido',emoji:'✨',videoFile:'Sculpted face.mp4',sets:2,reps:'12',rest:20,calories:4},{name:'Rosto Afinado',emoji:'😌',videoFile:'Slim face.mp4',sets:2,reps:'12',rest:20,calories:4},{name:'Linhas de Sorriso',emoji:'😄',videoFile:'Smile lines.mp4',sets:2,reps:'15',rest:20,calories:3}],abs:[{name:'Abdominal Águia em Pé',emoji:'🔥',youtubeId:'MkMB8Hdq2qU',sets:3,reps:'40s',rest:30,calories:11},{name:'Ponte com Elevação de Perna',emoji:'🌉',youtubeId:'JxnGOaye88w',sets:3,reps:'34s',rest:30,calories:9},{name:'Prancha Reversa',emoji:'🧘♀️',youtubeId:'mX_SX6I2DSI',sets:3,reps:'37s',rest:30,calories:10},{name:'Prancha Ajoelhado',emoji:'🧘♀️',youtubeId:'xNBL63AhZcc',sets:3,reps:'34s',rest:30,calories:9},{name:'Chutes Tesoura',emoji:'✂️',youtubeId:'9i0J_I4ASow',sets:3,reps:'12',rest:30,calories:6},{name:'Prancha com Mergulho de Quadril',emoji:'🧘♀️',youtubeId:'h1_Y3GBUd0M',sets:3,reps:'23s',rest:30,calories:6},{name:'Abdominal Oblíquo',emoji:'🔥',youtubeId:'Z9WtuN50f9s',sets:3,reps:'24s',rest:30,calories:6},{name:'Abdominal Estrela',emoji:'🔥',youtubeId:'HBB5tf2vndA',sets:3,reps:'28s',rest:30,calories:7},{name:'Abdominal Bicicleta Elevado',emoji:'🔥',youtubeId:'1xEZ1So_D-A',sets:3,reps:'12',rest:30,calories:5},{name:'Prancha Homem-Aranha',emoji:'🧘♀️',youtubeId:'G8-vocJfWEM',sets:3,reps:'12',rest:30,calories:6},{name:'Prancha com Rotação',emoji:'🧘♀️',youtubeId:'fu6-teFilJk',sets:3,reps:'24s',rest:30,calories:6},{name:'Abdominal Cruzado',emoji:'🔥',youtubeId:'LATqsI5q0hc',sets:3,reps:'24s',rest:30,calories:6}],face:[{name:'Rosto de Peixe Sorridente',emoji:'😊',youtubeId:'mLYm4ItAuro',sets:2,reps:'10',rest:20,calories:3},{name:'Firmador de Bochechas',emoji:'✨',youtubeId:'83Xu_F92j60',sets:2,reps:'12',rest:20,calories:3},{name:'Linha do Maxilar',emoji:'😄',youtubeId:'R2cqpjvaB3E',sets:2,reps:'10',rest:20,calories:2}],waist:[{name:'Meio Barco com Torção',emoji:'🔄',youtubeId:'PSZgJiFIrHQ',sets:3,reps:'31s',rest:30,calories:7},{name:'Inclinação Lateral Sentado',emoji:'⏳',youtubeId:'jKcHh78Y_JE',sets:3,reps:'12',rest:30,calories:5},{name:'Torção de Coluna Sentado',emoji:'🔄',youtubeId:'4YlCtaTdtgA',sets:3,reps:'26s',rest:30,calories:6},{name:'Torção de Tronco',emoji:'🔄',youtubeId:'HMKbmG1L7vc',sets:3,reps:'12',rest:30,calories:4},{name:'Inclinação Lateral em Pé',emoji:'⏳',youtubeId:'RfuiraEgKcY',sets:3,reps:'24s',rest:30,calories:6},{name:'V-Ups Oblíquo',emoji:'⏳',youtubeId:'iFaZ095MMGg',sets:3,reps:'25s',rest:30,calories:6},{name:'Torção Oblíqua Reclinada',emoji:'🔄',youtubeId:'XKW5jru5pGo',sets:3,reps:'25s',rest:30,calories:6},{name:'V-Up Oblíquo',emoji:'⏳',youtubeId:'dZGajX67rdQ',sets:3,reps:'29s',rest:30,calories:7}],back:[{name:'Puxada de Costas',emoji:'💆♀️',youtubeId:'GvyCtKvmaVE',sets:3,reps:'12',rest:30,calories:4},{name:'Remada Curvado',emoji:'💆♀️',youtubeId:'t2DUqP_13x8',sets:3,reps:'25s',rest:30,calories:5},{name:'Remada Alta',emoji:'💆♀️',youtubeId:'8ywEQiJuBNg',sets:3,reps:'28s',rest:30,calories:6},{name:'Alongamento de Peito',emoji:'💆♀️',youtubeId:'JoxGFxbgJ2Y',sets:3,reps:'12',rest:30,calories:4},{name:'Remada Deltóide Posterior',emoji:'💆♀️',youtubeId:'65gMtswVB1c',sets:3,reps:'30s',rest:30,calories:6},{name:'Remada Alternada',emoji:'💆♀️',youtubeId:'KvoHxslZun0',sets:3,reps:'23s',rest:30,calories:5},{name:'Elevação Lateral',emoji:'💆♀️',youtubeId:'6L19uhg2otQ',sets:3,reps:'23s',rest:30,calories:5},{name:'Puxada de Rombóide',emoji:'💆♀️',youtubeId:'DEyDbzSudEU',sets:3,reps:'26s',rest:30,calories:5},{name:'Super-Homem',emoji:'🦸♀️',youtubeId:'pGeaBXLwDtw',sets:3,reps:'12',rest:30,calories:4},{name:'Nadador e Super-Homem',emoji:'💆♀️',youtubeId:'XydDDn_Rngw',sets:3,reps:'25s',rest:30,calories:5}],legs:[{name:'Agachamento Sumo na Parede',emoji:'🏋️♀️',youtubeId:'oR90gl2vj7c',sets:3,reps:'40s',rest:30,calories:13},{name:'Afundo Baixo Crescente',emoji:'🦵',youtubeId:'93kUVEAqiv8',sets:3,reps:'43s',rest:30,calories:14},{name:'Afundo com Torção',emoji:'🔄',youtubeId:'E-_LxciEon4',sets:3,reps:'41s',rest:30,calories:14},{name:'Afundo com Braço Elevado',emoji:'🦵',youtubeId:'VQwrouNIlXw',sets:3,reps:'36s',rest:30,calories:12},{name:'Afundo Baixo',emoji:'🦵',youtubeId:'dXREtCBZnV4',sets:3,reps:'36s',rest:30,calories:12},{name:'Barco com Pernas Alternadas',emoji:'🦵',youtubeId:'ii245b_MNxI',sets:3,reps:'35s',rest:30,calories:12},{name:'Alongamento Posterior de Pernas',emoji:'🦵',youtubeId:'tShKvg4h12k',sets:3,reps:'32s',rest:30,calories:11},{name:'Alongamento Ajoelhado',emoji:'🦵',youtubeId:'lWi7rZWJ2cY',sets:3,reps:'30s',rest:30,calories:10},{name:'Afundo do Corredor',emoji:'🦵',youtubeId:'6ikwduxu0JU',sets:3,reps:'32s',rest:30,calories:11},{name:'Abertura de Pernas',emoji:'🦵',youtubeId:'aZRDySUyC1I',sets:3,reps:'12',rest:30,calories:6},{name:'Agachamento com Saltos',emoji:'🏋️♀️',youtubeId:'tcgvAxhEhvQ',sets:3,reps:'12',rest:30,calories:7},{name:'Joelho ao Peito em Pé',emoji:'🦵',youtubeId:'uC7dzhqN47M',sets:3,reps:'26s',rest:30,calories:9}],glutes:[{name:'Postura da Borboleta',emoji:'🦋',youtubeId:'seRyFNh7boQ',sets:3,reps:'33s',rest:30,calories:10},{name:'Alongamento Borboleta',emoji:'🦋',youtubeId:'QehQaZvvquA',sets:3,reps:'24s',rest:30,calories:7},{name:'Ponte de Glúteo',emoji:'🌉',youtubeId:'6gGzYaD9Cb4',sets:3,reps:'24s',rest:30,calories:7},{name:'Ponte Borboleta',emoji:'🌉',youtubeId:'sJC_fMOVZVw',sets:3,reps:'24s',rest:30,calories:7},{name:'Coice de Glúteo',emoji:'🍑',youtubeId:'3ao9J4vvEXA',sets:3,reps:'26s',rest:30,calories:8},{name:'Chute de Burro',emoji:'🦵',youtubeId:'pd3KyzQS5nc',sets:3,reps:'24s',rest:30,calories:7},{name:'Coice de Tríceps',emoji:'🍑',youtubeId:'zfnWQVmDspU',sets:3,reps:'24s',rest:30,calories:7},{name:'Hidrante com Pulso',emoji:'🔥',youtubeId:'uILAw7D7fxE',sets:3,reps:'12',rest:30,calories:7},{name:'Chute com Pulso',emoji:'🦵',youtubeId:'QaTh15GsgHk',sets:3,reps:'25s',rest:30,calories:7},{name:'Coice de Glúteo com Pulso',emoji:'🍑',youtubeId:'Lxdu7Nlp6KE',sets:3,reps:'26s',rest:30,calories:8},{name:'Alongamento de Glúteo',emoji:'🍑',youtubeId:'vSKSU8KDc38',sets:3,reps:'12',rest:30,calories:6},{name:'Coice de Glúteo na Parede',emoji:'🍑',youtubeId:'qzqDHSDTc0U',sets:3,reps:'23s',rest:30,calories:7}],arms:[{name:'Flexão Isométrica',emoji:'💪',youtubeId:'16-WWEQNiK0',sets:3,reps:'34s',rest:30,calories:8},{name:'Flexão com Remada',emoji:'💪',youtubeId:'DpsHmYX3Ifg',sets:3,reps:'25s',rest:30,calories:6},{name:'Extensão de Tríceps Sentado',emoji:'💪',youtubeId:'-9Uup5bhPBI',sets:3,reps:'12',rest:30,calories:5},{name:'Extensão de Tríceps Deitado',emoji:'💪',youtubeId:'FyBXas1QUWo',sets:3,reps:'24s',rest:30,calories:5},{name:'Rosca Bíceps Alternada',emoji:'💪',youtubeId:'sQbtGNsAcl4',sets:3,reps:'26s',rest:30,calories:6},{name:'Rosca Bíceps Aberta',emoji:'💪',youtubeId:'pB4Iic8p6Ag',sets:3,reps:'26s',rest:30,calories:6},{name:'Extensão de Tríceps',emoji:'💪',youtubeId:'a1Uanj_vaYA',sets:3,reps:'26s',rest:30,calories:6},{name:'Remada Renegada',emoji:'💪',youtubeId:'m0KEk-Y4iII',sets:3,reps:'12',rest:30,calories:5},{name:'Rosca para Press',emoji:'💪',youtubeId:'9C5EtvkK6k4',sets:3,reps:'29s',rest:30,calories:7},{name:'Círculos com os Braços',emoji:'💪',youtubeId:'wZVO6ZnARIE',sets:3,reps:'12',rest:30,calories:5},{name:'Flexões Desalinhadas',emoji:'💪',youtubeId:'32yYCbAQo5A',sets:3,reps:'12',rest:30,calories:5},{name:'Balanço de Braços Lateral',emoji:'💪',youtubeId:'tLEkdDgTDbM',sets:3,reps:'12',rest:30,calories:5}],cardio:[{name:'Saltos Estrela',emoji:'⭐',youtubeId:'VVEO_J1tIXU',sets:3,reps:'12',rest:20,calories:6},{name:'Alpinista Cruzado',emoji:'⛰️',youtubeId:'tIEkB8S42j8',sets:3,reps:'12',rest:20,calories:8},{name:'Burpees em X',emoji:'💥',youtubeId:'uD5BUL79CvY',sets:3,reps:'28s',rest:20,calories:11},{name:'Alpinista Lento',emoji:'⛰️',youtubeId:'24gpL7t4iPY',sets:3,reps:'12',rest:20,calories:9},{name:'Corrida na Parede',emoji:'🤸♀️',youtubeId:'Vvuj9R-w6a4',sets:3,reps:'12',rest:20,calories:6},{name:'Corte de Lenha',emoji:'🤸♀️',youtubeId:'Ax_94gEavYo',sets:3,reps:'12',rest:20,calories:8},{name:'Polichinelos Laterais',emoji:'🤸♀️',youtubeId:'p75NmUtH9so',sets:3,reps:'12',rest:20,calories:8},{name:'Rotação de Tronco',emoji:'🤸♀️',youtubeId:'YBgjuQMviCE',sets:3,reps:'12',rest:20,calories:8},{name:'Salto do Patinador',emoji:'⛸️',youtubeId:'5gtLC5BgN7Q',sets:3,reps:'12',rest:20,calories:9},{name:'Burpees Modificados',emoji:'💥',youtubeId:'8PbnMQISmZQ',sets:3,reps:'23s',rest:20,calories:9},{name:'Saltos no Lugar',emoji:'🤸♀️',youtubeId:'ImamH6J566s',sets:3,reps:'12',rest:20,calories:6},{name:'Salto Lateral',emoji:'🤸♀️',youtubeId:'nYmUEJIBj3c',sets:3,reps:'12',rest:20,calories:7},{name:'Burpees',emoji:'💥',youtubeId:'818SkLAPyKY',sets:3,reps:'12',rest:20,calories:9},{name:'Alpinista',emoji:'⛰️',youtubeId:'wQq3ybaLZeA',sets:3,reps:'12',rest:20,calories:9},{name:'Polichinelos',emoji:'🤸♀️',youtubeId:'2W4ZNSwoW_4',sets:3,reps:'12',rest:20,calories:8}],fullbody:[{name:'Burpees',emoji:'💥',youtubeId:'818SkLAPyKY',sets:3,reps:'10',rest:40,calories:15},{name:'Agachamento Sumo na Parede',emoji:'🏋️♀️',youtubeId:'oR90gl2vj7c',sets:3,reps:'40s',rest:30,calories:13},{name:'Flexão Isométrica',emoji:'💪',youtubeId:'16-WWEQNiK0',sets:3,reps:'34s',rest:30,calories:8},{name:'Prancha Reversa',emoji:'🧘♀️',youtubeId:'mX_SX6I2DSI',sets:3,reps:'37s',rest:30,calories:10},{name:'Alpinista',emoji:'⛰️',youtubeId:'wQq3ybaLZeA',sets:3,reps:'30s',rest:30,calories:13},{name:'Polichinelos',emoji:'🤸♀️',youtubeId:'2W4ZNSwoW_4',sets:3,reps:'30',rest:20,calories:12},{name:'Afundo Baixo Crescente',emoji:'🦵',youtubeId:'93kUVEAqiv8',sets:3,reps:'43s',rest:30,calories:14},{name:'Burpees em X',emoji:'💥',youtubeId:'uD5BUL79CvY',sets:3,reps:'28s',rest:20,calories:11},{name:'Abdominal Águia em Pé',emoji:'🔥',youtubeId:'MkMB8Hdq2qU',sets:3,reps:'40s',rest:30,calories:11},{name:'Salto do Patinador',emoji:'⛸️',youtubeId:'5gtLC5BgN7Q',sets:3,reps:'12',rest:20,calories:9},{name:'Ponte com Elevação de Perna',emoji:'🌉',youtubeId:'JxnGOaye88w',sets:3,reps:'34s',rest:30,calories:9}],yoga:[{name:'Postura da Meia Lua',emoji:'🌙',youtubeId:'TznRHywkPwU',sets:2,reps:'36s',rest:15,calories:5},{name:'Guerreiro III',emoji:'⚔️',youtubeId:'ySy_k5R3lHg',sets:2,reps:'35s',rest:15,calories:5},{name:'Guerreiro Reverso',emoji:'⚔️',youtubeId:'8LmWu5XnEWc',sets:2,reps:'52s',rest:15,calories:7},{name:'Guerreiro II',emoji:'⚔️',youtubeId:'YSjBJDkA6zg',sets:2,reps:'40s',rest:15,calories:5},{name:'Guerreiro Humilde',emoji:'⚔️',youtubeId:'a6ANkE4emF8',sets:2,reps:'51s',rest:15,calories:7},{name:'Triângulo com Torção',emoji:'🔄',youtubeId:'Tbz3FVAjVtI',sets:2,reps:'38s',rest:15,calories:5},{name:'Postura da Esfinge',emoji:'🧘♀️',youtubeId:'7a_WhOoegHE',sets:2,reps:'31s',rest:15,calories:4},{name:'Postura do Bebê Feliz',emoji:'👶',youtubeId:'z-BjiGQZe4s',sets:2,reps:'32s',rest:15,calories:4},{name:'Passeio do Cachorro',emoji:'🐕',youtubeId:'PCgS48SiR2k',sets:2,reps:'32s',rest:15,calories:4},{name:'Postura da Guirlanda',emoji:'🧘♀️',youtubeId:'_xJPi7yuelw',sets:2,reps:'35s',rest:15,calories:5},{name:'Cadeira com Torção',emoji:'🔄',youtubeId:'pQOK2-E-5sM',sets:2,reps:'35s',rest:15,calories:5},{name:'Postura da Deusa',emoji:'🧘♀️',youtubeId:'AhX3PujoRgo',sets:2,reps:'36s',rest:15,calories:5},{name:'Cachorro Olhando para Cima',emoji:'🐕',youtubeId:'OJ9j9D0lNBg',sets:2,reps:'35s',rest:15,calories:5}],massage:[{name:'Rosto de Peixe Sorridente',emoji:'😊',youtubeId:'mLYm4ItAuro',sets:1,reps:'1min',rest:10,calories:3},{name:'Firmador de Bochechas',emoji:'😌',youtubeId:'83Xu_F92j60',sets:1,reps:'1min',rest:10,calories:3},{name:'Linha do Maxilar',emoji:'💫',youtubeId:'R2cqpjvaB3E',sets:1,reps:'1min',rest:10,calories:2}]};return exercises[category]||[]}showToast(message,type='info',duration=3000){const existingToast=document.querySelector('.toast');if(existingToast){existingToast.remove()}const toast=document.createElement('div');toast.className=`toast ${type}`;toast.textContent=message;document.body.appendChild(toast);requestAnimationFrame(()=>{requestAnimationFrame(()=>{toast.classList.add('show')})});setTimeout(()=>{toast.classList.remove('show');setTimeout(()=>{toast.remove()},400)},duration)}getWellnessSessions(){return{'face-massage':{exercises:[{name:'Massagem na Testa',emoji:'💆♀️',sets:1,reps:'30s',rest:10},{name:'Contorno dos Olhos',emoji:'👁️',sets:1,reps:'30s',rest:10},{name:'Bochechas',emoji:'😊',sets:1,reps:'30s',rest:10},{name:'Mandíbula',emoji:'💫',sets:1,reps:'30s',rest:10}]},'body-massage':{exercises:[{name:'Pescoço e Ombros',emoji:'💆♀️',sets:1,reps:'1min',rest:20},{name:'Braços',emoji:'💪',sets:1,reps:'30s cada',rest:10},{name:'Pernas',emoji:'🦵',sets:1,reps:'1min cada',rest:20},{name:'Pés',emoji:'👣',sets:1,reps:'30s cada',rest:10}]},'posture':{exercises:[{name:'Alongamento Cervical',emoji:'🧍♀️',sets:2,reps:'20s',rest:10},{name:'Abertura de Peito',emoji:'💫',sets:2,reps:'30s',rest:10},{name:'Gato-Vaca',emoji:'🐱',sets:2,reps:'10',rest:10},{name:'Postura na Parede',emoji:'🧱',sets:1,reps:'1min',rest:0}]},'stretching':{exercises:[{name:'Alongamento de Pernas',emoji:'🦵',sets:2,reps:'30s cada',rest:10},{name:'Alongamento de Braços',emoji:'💪',sets:2,reps:'20s cada',rest:10},{name:'Torção Espinal',emoji:'🔄',sets:2,reps:'20s cada',rest:10},{name:'Alongamento Total',emoji:'🤸♀️',sets:1,reps:'30s',rest:0}]},'breathing':{exercises:[{name:'Respiração Profunda',emoji:'🌬️',sets:3,reps:'10',rest:20},{name:'Respiração Alternada',emoji:'👃',sets:2,reps:'5 cada',rest:20},{name:'Respiração 4-7-8',emoji:'💫',sets:3,reps:'4',rest:10}]},'meditation':{exercises:[{name:'Meditação Guiada',emoji:'🧘♀️',sets:1,reps:'5min',rest:0},{name:'Visualização',emoji:'✨',sets:1,reps:'3min',rest:0},{name:'Gratidão',emoji:'🙏',sets:1,reps:'2min',rest:0}]}}}}document.addEventListener('DOMContentLoaded',()=>{window.app=new FitnessApp();if('serviceWorker' in navigator){navigator.serviceWorker.register('/sw.js').then(reg=>{reg.update().catch(err=>reg.addEventListener('updatefound',()=>{const newWorker=reg.installing;newWorker.addEventListener('statechange',()=>{if(newWorker.state==='activated'&&!navigator.serviceWorker.controller){}else if(newWorker.state==='activated'){window.app.updateUI()}})});if(window.swUpdateInterval){clearInterval(window.swUpdateInterval)}window.swUpdateInterval=setInterval(()=>{reg.update()},60000);document.addEventListener('visibilitychange',()=>{if(!document.hidden&®){reg.update().catch(err=>}});window.addEventListener('focus',()=>{if(reg){reg.update().catch(err=>}})}).catch(err=>console.error('❌ Service Worker registration failed:',err));navigator.serviceWorker.addEventListener('message',(event)=>{if(event.data&&event.data.type==='SW_UPDATED'){if(event.data.autoRefresh){document.body.style.opacity='0';setTimeout(()=>location.reload(),300)}else if(window.app){window.app.updateUI();window.app.showToast('🎉 App atualizado para a versão '+event.data.version)}}});navigator.serviceWorker.addEventListener('controllerchange',()=>{if(window.app&&typeof window.app.showToast==='function'){window.app.showToast('✨ App atualizado!')}})}});const style=document.createElement('style');style.textContent=` @keyframes fadeOut{from{opacity:1}to{opacity:0}}`;document.head.appendChild(style); |