${plus?(en?'Training Plus':'تدريب بلس'):(en?'Practice by idea':'تدرب حسب الأفكار')}${who?`${esc(who)}`:''}
${st.user?``:''}`;
const f=document.createElement('iframe');f.title=plus?(en?'Training Plus':'تدريب بلس'):(en?'Practice by idea':'تدرب حسب الأفكار');f.onload=()=>{try{const w=f.contentWindow;if(w&&w.penShow){w.penShow(false);w.penShow=()=>{};}}catch(e){}};f.srcdoc=TRN.html;ov.appendChild(f);
ov.hidden=false;ov.style.display='flex';if(window.mrPen)mrPen(true);window.scrollTo(0,0);document.body.style.overflow='hidden';document.getElementById('trainBack').onclick=closeTraining;{const to=document.getElementById('trainOut');if(to)to.onclick=()=>document.getElementById('outBtn').onclick();}
}catch(e){console.error(e);alert((lang==='en'?'Could not open the training: ':'تعذر فتح التدريب: ')+(e&&e.message||e));}
}
function closeTraining(){const ov=document.getElementById('trainOv');if(!ov||ov.hidden)return;ov.hidden=true;ov.style.display='none';ov.innerHTML='';if(window.mrPen)mrPen(true);document.body.style.overflow='';TRN.me=null;}
document.addEventListener('keydown',e=>{if(e.key==='Escape')closeTraining();});
// ================= حسابات منصة الاختبارات فقط (لا تظهر في منصة الأستاذ محمد رجب) =================
const ACC={list:null,msg:'',err:false,show:{}};
const genPw=()=>String(Math.floor(100000+Math.random()*900000));
async function loadAccounts(){try{ACC.list=await window.RG.exList();}catch(e){ACC.list=[];ACC.msg=accErr(e);ACC.err=true;}if(st.screen==='accounts')renderAccounts();}
function accErr(e){const en=lang==='en',c=e&&e.code||'';
if(c==='exists'||c==='auth/email-already-in-use')return en?'This code is already used (on the platform or here).':'هذا الكود مستخدم بالفعل (في منصة الأستاذ محمد رجب أو هنا).';
if(c==='auth/weak-password')return en?'The password must be at least 6 characters.':'كلمة المرور 6 خانات على الأقل.';
if(c==='permission-denied')return en?'Firestore refused: publish the updated rules (examStudents).':'قاعدة البيانات رفضت: انشر القواعد المحدّثة (فيها examStudents).';
return (en?'Something went wrong: ':'حدث خطأ: ')+(c||e&&e.message||e);}
function renderAccounts(){
const en=lang==='en'; bclock.hidden=true; st.screen='accounts'; updChrome();
if(ACC.list===null){ACC.list=undefined;loadAccounts();}
const L=ACC.list;
app.innerHTML=`
${en?'Accounts added here can sign in to the practice tests and the idea training only. They do not appear on Mr. Mohamed Ragab’s platform. Students added on the platform can already sign in here.':'الحسابات اللي تضيفها هنا تدخل منصة الاختبارات والتدريب حسب الأفكار فقط، ولا تظهر في منصة الأستاذ محمد رجب. أما الطلاب المضافون من منصة الأستاذ محمد رجب فيدخلون هنا تلقائيًا.'}
`;
document.getElementById('accBack').onclick=()=>{ACC.msg='';renderStart();window.scrollTo(0,0)};
document.getElementById('aGen').onclick=()=>{document.getElementById('aPass').value=genPw();};
document.getElementById('accF').onsubmit=async e=>{
e.preventDefault();
const name=document.getElementById('aName').value.trim(),code=document.getElementById('aCode').value.trim().toLowerCase(),pass=document.getElementById('aPass').value.trim();
const bad=m=>{ACC.msg=m;ACC.err=true;renderAccounts();document.getElementById('aName').value=name;document.getElementById('aCode').value=code;document.getElementById('aPass').value=pass;};
if(name.length<2)return bad(en?'Enter the student’s name.':'اكتب اسم الطالب.');
if(!/^[a-z0-9_.-]{2,30}$/.test(code))return bad(en?'The code uses English letters or digits only, without spaces.':'الكود أرقام أو حروف إنجليزية فقط بدون مسافات.');
if(code==='1411')return bad(accErr({code:'exists'}));
if(pass.length<6)return bad(accErr({code:'auth/weak-password'}));
const b=document.getElementById('aAdd');b.disabled=true;b.textContent=en?'Adding…':'جارٍ الإضافة…';
try{await window.RG.exAdd({code,name,pass});ACC.msg=(en?'Account added: ':'تمت إضافة الحساب: ')+code+' / '+pass;ACC.err=false;ACC.list=undefined;await loadAccounts();}
catch(er){console.error(er);bad(accErr(er));}
};
app.querySelectorAll('[data-showpw]').forEach(b=>b.onclick=()=>{const c=b.dataset.showpw;ACC.show[c]=!ACC.show[c];renderAccounts();});
app.querySelectorAll('[data-delacc]').forEach(b=>b.onclick=async()=>{const c=b.dataset.delacc;const a=(ACC.list||[]).find(x=>x.code===c);if(!a)return;
if(!confirm((en?'Delete the account ':'حذف الحساب ')+c+(en?'? Its saved results stay.':'؟ النتائج المحفوظة لن تُحذف.')))return;
b.disabled=true;try{await window.RG.exDel(c,a.password||'');ACC.msg=(en?'Deleted: ':'تم حذف: ')+c;ACC.err=false;ACC.list=undefined;await loadAccounts();}catch(er){ACC.msg=accErr(er);ACC.err=true;renderAccounts();}});
}
const HUB_ON=!/(exams|extra)\.html/.test(location.pathname);
function renderHub(){
const en=lang==='en',T=t(),par=st.user&&st.user.role==='parent';bclock.hidden=true;st.screen='start';updChrome();
const C=(id,ico,col,ti,tE,sub,sE,href)=>`<${href?'a href="'+href+'"':'button type="button"'} class="hub-card" id="${id}" style="--hc:${col}">${ico}${en?tE:ti}${en?sE:sub}${href?'a':'button'}>`;
const kids=st.user&&st.user.role!=='admin'&&st.user.kids&&st.user.kids.length>1?`
${T.chooseKid}
${st.user.kids.map(k=>``).join('')}
`:'';
app.innerHTML=`
${T.levels[st.level].name}
${en?'Choose how you want to practise today.':'اختر طريقة التدريب التي تريدها اليوم.'}
${T.by}
${kids}${progBanner()}
${C('hubMain','📘','#2b3a68','تجميعات','Compilations','النماذج التجريبية وتجميعات 27 والتجميعات الجديدة','Practice models, Compilations 27 and the new compilations')}
${C('hubXP','✚','#2f9e6b','تجميعات اكسترا وبلس','Compilations Extra & Plus','نماذج كتب موهبة كما هي واختبارات إضافية على أفكارها','The model-book tests as printed plus extra tests on their ideas','exams.html')}
${C('hubTrain','⚡','#7b4bb7',par?'تدرب حسب الأفكار · المتابعة':'تدرب حسب الأفكار','Practice by idea','تعلّم الحل السريع لكل فكرة وتدرّب عليها','Learn the quick solution for each idea and practise it')}
${C('hubTP','⚡','#c0782a',par?'تدريب بلس · المتابعة':'تدريب بلس','Training Plus','أسئلة الكتب نفسها مقسّمة حسب الأفكار','The book questions themselves, sorted by idea')}
${``}
`;
document.getElementById('yes').onclick=finish;
document.getElementById('no').onclick=()=>document.getElementById('modal').innerHTML='';
}
function finish(){
clearProg();
clearInterval(timer);bclock.hidden=true;st.screen='res';st.filter='all';
const right=st.list.filter(id=>st.ans[id]===Q[id].ans).length;
done[st.model]=Math.round(right/st.list.length*100);
const blankN=st.list.filter(id=>st.ans[id]===undefined).length;st.det={model:st.model,right,wrong:st.list.length-right-blankN,blank:blankN,used:st.total-Math.max(0,st.left)};try{localStorage.setItem(st.doneKey,JSON.stringify(done))}catch(e){}
st.sync=null;
if(st.user&&st.user.role!=='admin'&&st.kid&&window.RG&&window.RG.saveResult){
const A=I18N.ar,m=modelOf(st.model),n=st.list.length;
const answers=st.list.map((id,i)=>{const q=Q[id],a=q.ar,p=st.ans[id];return {n:i+1,skill:a.skill,q:a.q,html:!!q.html,pass:a.pass||'',fig:a.fig||'',figOpts:!!q.figOpts,opts:q.order.map(k=>a.o[k]),pick:p===undefined?-1:p,ans:q.ans,flag:!!st.flag[id],e:a.e};});
st.sync={state:'saving',resId:null,ansState:null,answers,data:{studentCode:String(st.kid.code),studentName:nameEditable()?st.name:(st.kid.name||''),nameEdited:nameEditable(),byCode:String(st.user.code),role:st.user.role,level:st.level,model:st.model,hasAnswers:true,lang:lang||'ar',
modelName:A.models[MODELS.filter(x=>x.p===m.p).indexOf(m)],partName:A.parts[m.p],levelName:A.levels[st.level].short,
percent:done[st.model],right,wrong:n-right-blankN,blank:blankN,total:n,usedSec:st.det.used,totalSec:st.total,timestamp:Date.now()}};
syncResult();
}
renderRes();window.scrollTo(0,0);
}
function syncResult(){
const sy=st.sync;if(!sy)return;sy.state='saving';drawSync();
const data=JSON.parse(JSON.stringify(sy.data));
const ans=JSON.parse(JSON.stringify({studentCode:sy.data.studentCode,byCode:sy.data.byCode,timestamp:sy.data.timestamp,answers:sy.answers}));
window.RG.saveResult(data,ans).then(r=>{sy.resId=r.id;sy.state=r.state;drawSync();}).catch(e=>{console.error('examResults save failed',e,data);sy.err=(e&&(e.code||e.message))||'unknown';sy.state='fail';drawSync();});
}
function syncAnswers(){
const sy=st.sync;if(!sy||!sy.resId)return;sy.state='saving';drawSync();
const data=JSON.parse(JSON.stringify({resultId:sy.resId,studentCode:sy.data.studentCode,byCode:sy.data.byCode,timestamp:sy.data.timestamp,answers:sy.answers}));
Promise.resolve().then(()=>window.RG.saveAnswers(sy.resId,data)).then(()=>{sy.state='ok';drawSync();}).catch(e=>{console.error('examAnswers save failed',e);sy.err=(e&&(e.code||e.message))||'unknown';sy.state='partial';drawSync();});
}
function drawSync(){
const el=document.getElementById('syncNote');if(!el||!st.sync)return;const T=t(),s=st.sync.state;
el.className='sync '+s;el.hidden=false;
el.innerHTML=s==='saving'?`${T.syncing}`:s==='ok'?`✓ ${st.kid&&st.kid.examOnly?(lang==='en'?'Your result and answers are saved to your account.':'تم حفظ النتيجة وإجاباتك في حسابك.'):T.synced}`:`${s==='partial'?T.syncPartial:T.syncFail}${s==='fail'?` ${lang==='en'?'Your result is kept on this device and will be sent automatically when the connection returns.':'النتيجة محفوظة على هذا الجهاز وستُرسل تلقائياً عند عودة الاتصال.'}`:''} ${esc(String(st.sync.err||''))} · ${esc(st.sync.data.byCode)} → ${esc(st.sync.data.studentCode)}`;
const b=document.getElementById('syncRetry');if(b)b.onclick=syncResult;
}
function renderRes(){
const T=t(); updChrome();
const Ls=st.list, n=Ls.length;
const right=Ls.filter(id=>st.ans[id]===Q[id].ans).length;
const blank=Ls.filter(id=>st.ans[id]===undefined).length;
const pct=Math.round(right/n*100);
const used=st.total-Math.max(0,st.left);
const C=2*Math.PI*70, off=C*(1-pct/100);
const verdict=T.verdicts[pct>=85?0:pct>=70?1:pct>=50?2:3];
const weak=[...new Set(Ls.filter(id=>st.ans[id]!==Q[id].ans).map(id=>L(Q[id]).skill))];
const OR=ORDERS[st.level];const nextN=OR[OR.indexOf(st.model)+1];const nextM=nextN?modelOf(nextN):null;
const list=Ls.filter(id=>st.filter==='all'||(st.filter==='wrong'&&st.ans[id]!==Q[id].ans)||(st.filter==='flag'&&st.flag[id]));
app.innerHTML=`