(()=>{'use strict';const num=(v)=>{const n=Number(v);return Number.isFinite(n)?n:null};const fmt=n=>Number.isInteger(n)?String(n):n.toFixed(2).replace(/\.00$/,'');document.querySelectorAll('[data-ef-tool]').forEach(root=>{if(root.dataset.ready)return;root.dataset.ready='1';const form=root.querySelector('form'),out=root.querySelector('output');let timer=null;let cfg;try{cfg=JSON.parse(atob(root.querySelector('[data-tool-config]').textContent.trim()))}catch{return}const values=()=>Object.fromEntries(new FormData(form).entries());form.addEventListener('reset',()=>{if(timer)clearInterval(timer);setTimeout(()=>out.textContent='Enter values to begin.',0)});form.addEventListener('submit',ev=>{ev.preventDefault();const v=values();try{if(cfg.tool_type==='grade_calculator'||cfg.tool_type==='percentage_calculator'){const earned=num(v.earned??v.value),total=num(v.total);if(earned===null||total===null||total<=0)throw Error('Enter valid numbers and a total greater than zero.');const p=earned/total*100;let grade='';if(cfg.tool_type==='grade_calculator'){const scale=Array.isArray(cfg.grade_scale)&&cfg.grade_scale.length?cfg.grade_scale:[{min:90,label:'A'},{min:80,label:'B'},{min:70,label:'C'},{min:60,label:'D'},{min:0,label:'F'}];grade=(scale.sort((a,b)=>Number(b.min)-Number(a.min)).find(x=>p>=Number(x.min))||{}).label||''}out.textContent=`${cfg.result_label}: ${fmt(p)}%${grade?' · '+grade:''}`}
else if(cfg.tool_type==='unit_converter'){const value=num(v.value),from=v.from,to=v.to,units=cfg.units||{};if(value===null||!units[from]||!units[to])throw Error('Select valid units and enter a number.');const base=value*Number(units[from].factor)+Number(units[from].offset||0);const result=(base-Number(units[to].offset||0))/Number(units[to].factor);out.textContent=`${cfg.result_label}: ${fmt(result)} ${units[to].symbol||to}`}
else if(cfg.tool_type==='date_countdown'){const target=new Date(v.target_date+'T00:00:00');if(Number.isNaN(target.getTime()))throw Error('Choose a valid date.');const today=new Date();today.setHours(0,0,0,0);const days=Math.ceil((target-today)/86400000);out.textContent=days===0?'The date is today.':days>0?`${days} day${days===1?'':'s'} remaining.`:`${Math.abs(days)} day${days===-1?'':'s'} ago.`}
else if(cfg.tool_type==='study_timer'){const minutes=num(v.minutes);if(minutes===null||minutes<=0||minutes>240)throw Error('Choose 1 to 240 minutes.');if(timer)clearInterval(timer);let left=Math.round(minutes*60);const draw=()=>{const m=Math.floor(left/60),s=left%60;out.textContent=`Time remaining: ${m}:${String(s).padStart(2,'0')}`;if(left--<=0){clearInterval(timer);out.textContent='Study session complete.'}};draw();timer=setInterval(draw,1000)}}catch(err){out.textContent=err.message||'Check the entered values.'}})})})();
