JAMB Scores Arenβt Luck. They are a Calculation.
Nigeriaβs Only AI-Native Mastery Engine. Master the syllabus, own your future.
English β’ Physics β’ Chemistry β’ Biology β’ Government β’ Economics β’ Accounting β’ Agric Science β’ Mathematics β’ Literature β’ Commerce
The Problem: The Past Question Trap
Every year, candidates solve thousands of random past questions without deconstructing the syllabus first. This leads to "JAMB Fever." Success shouldn't be a gamble. AnchorLearn treats your score as a surgical calculation.
The Solution: The 80% Mastery Rule
On AnchorLearn, you donβt finish a topic; you Master it.
The engine only grants you "Mastered" status when you hit the 80% threshold in our curriculum assessments.
Your Board of Examiners
βοΈ Justice Aisha Mohammed (Government) Senior Jurist teaching the Mechanics of Power.
π¬ Prof. Adebayo (Physics) Senior Examiner breaking down complex laws into simple principles.
π Prof. O. J. Mahmud (Economics) Policy Visionary mentoring the next generation of CEOs.
Log In to the Engine
TRIAL CODE:TRIAL
Full Access & Licensing
Reach our support desk instantly via Call or WhatsApp:
09048220128
Choose Stream
JAMB
WAEC
Mastery Map
π Syllabus Deep Mastery Guide
0-79% Gearing Up
Cyan: Passed 1x (Surface Mastery)
Purple: Passed 2x (Consolidated)
Gold: Passed 3x (Deep Mastery Engine)
π Final CBT Exam Simulator
Achieve 80% overall subject mastery to unlock the 40-seconds-per-question Exam Engine.
0%
Topic Loading...
Listen to High-Yield Concept Explanations:
ποΈ Audio breakdown for this section is compiling. Proceed with Study Slides below!
Select a layout view option below to anchor understanding:
β‘ FLASHCARDS IN PRODUCTION
Your active recall cards for this section are currently being compiled. Please use the Audio Summaries and Study Slides to anchor your understanding!
`;
input.value = "";
chatArea.scrollTop = chatArea.scrollHeight;
try {
// 2. Call the Function
const response = await askUncleTunde({
message: text,
history: window.app.mentorHistory
});
console.log("Cloud Function Data:", response.data);
if (response.data.status === "LIMIT_REACHED") {
window.app.showModal(`π¨ CREDITS USED
${response.data.message}`);
return;
}
// 3. FIX: Extract message with a fallback
const rawText = response.data.message || "Uncle Tunde is nodding his head, but no words came out. Check backend deployment!";
const tundeText = window.app.math(rawText);
// 4. Show Uncle Tunde's response
chatArea.innerHTML += `
Uncle Tunde: ${tundeText}
`;
chatArea.scrollTop = chatArea.scrollHeight;
// 5. Update history for context
window.app.mentorHistory.push({ role: "user", parts: [{ text: text }] });
window.app.mentorHistory.push({ role: "model", parts: [{ text: rawText }] });
} catch (err) {
console.error("Auth Failure Log:", err);
// This will display the actual error message (e.g., "Invalid Access Code")
window.app.showModal(`π‘ Authentication Failure
${err.message}`);
}
},
view: (id) => { document.querySelectorAll('.screen').forEach(s => s.classList.remove('active')); document.getElementById(id).classList.add('active'); window.scrollTo(0,0); },
generateQuestionGrid: (totalQuestions) => {
const grid = document.getElementById('question-grid');
if (!grid) return;
grid.innerHTML = '';
for (let i = 1; i <= totalQuestions; i++) {
const btn = document.createElement('button');
btn.id = `q-btn-${i}`;
btn.style.cssText = `padding: 10px 5px; font-weight: 800; border-radius: 8px; background: #6c757d; border: 1px solid #444; color: white; cursor: pointer; font-size: 0.95rem; text-align: center; font-family: 'Inter', sans-serif; transition: 0.2s;`;
btn.innerText = i;
btn.onclick = (e) => {
e.preventDefault();
window.app.loadQuestion(i - 1);
};
grid.appendChild(btn);
}
},
shuffleQuestions: (array) => {
let currentIndex = array.length, randomIndex;
while (currentIndex !== 0) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[array[currentIndex]]];
}
return array;
},
// π CENTRALIZED SIMULATOR MATRIX CONTROLLER
startExamSession: (subjectPool, subjectName) => {
console.log("Launching simulation engine for subject:", subjectName);
alert("SUBJECT POOL LENGTH: " + (subjectPool ? subjectPool.length : "UNDEFINED"));
alert("ACTIVE MODULES LENGTH: " + (window.app.activeModules ? window.app.activeModules.length : "UNDEFINED"));
const cleanSubName = subjectName.toLowerCase().replace(/[^a-z]/g, '');
const isEnglish = (cleanSubName === 'useofenglish' || cleanSubName === 'english');
let livePool = [];
if (window.app.activeModules && window.app.activeModules.length > 0) {
window.app.activeModules.forEach(m => {
if (m && m.qs && m.qs.length > 0) {
m.qs.forEach(q => {
let composedQ = {...q};
composedQ.topicName = m.name || "Syllabus Segment Focus";
livePool.push(composedQ);
});
}
});
}
if (livePool.length === 0 && subjectPool && subjectPool.length > 0) {
livePool = [...subjectPool];
}
if (!livePool || livePool.length === 0) {
alert("β οΈ Question repository pool is empty or initializing. Please ensure questions are loaded into your array before launching.");
return;
}
const totalToDraw = isEnglish ? 60 : 40;
const shuffledPool = window.app.shuffleQuestions([...livePool]);
const selectedQuestions = shuffledPool.slice(0, totalToDraw);
const sessionData = {
subject: subjectName,
questions: selectedQuestions,
startTime: Date.now(),
durationSeconds: isEnglish ? 2400 : 1600,
answers: new Array(selectedQuestions.length).fill(null),
visited: new Array(selectedQuestions.length).fill(false)
};
window.app.currentExamQuestions = selectedQuestions;
window.app.currentExamAnswers = new Array(selectedQuestions.length).fill(null);
sessionStorage.setItem('cbt_active_session', JSON.stringify(sessionData));
const titleEl = document.getElementById('exam-title');
if (titleEl) titleEl.innerHTML = `${subjectName.toUpperCase()} CBT Simulator`;
window.app.generateQuestionGrid(selectedQuestions.length);
// View transition and delayed question load to ensure DOM ready
window.app.view('exam-screen');
setTimeout(() => {
window.app.loadQuestion(0);
}, 100);
if (window.app.examInterval) clearInterval(window.app.examInterval);
let remainingTime = sessionData.durationSeconds;
window.app.examRemainingSeconds = remainingTime;
window.app.examInterval = setInterval(() => {
remainingTime--;
window.app.examRemainingSeconds = remainingTime;
const timerEl = document.getElementById('exam-timer');
if (remainingTime <= 0) {
clearInterval(window.app.examInterval);
if (timerEl) timerEl.innerHTML = "00:00";
alert("β° Time is up! Your exam session is being automatically compiled.");
window.app.submitExamSession();
} else {
const mins = Math.floor(remainingTime / 60).toString().padStart(2, '0');
const secs = (remainingTime % 60).toString().padStart(2, '0');
if (timerEl) timerEl.innerHTML = `${mins}:${secs}`;
}
}, 1000);
},
// π― CORE EXAM RENDER ENGINE: Fetches and displays active simulation metrics
loadQuestion: (idx) => {
console.log("Loading question index:", idx); // <--- ADD THIS
window.app.currentExamIdx = idx;
const sessionRaw = sessionStorage.getItem('cbt_active_session');
if (!sessionRaw) return;
sessionData = JSON.parse(sessionRaw);
const question = sessionData.questions[idx];
if (!question) return;
sessionData.visited[idx] = true;
sessionStorage.setItem('cbt_active_session', JSON.stringify(sessionData));
const qTextEl = document.getElementById('question-text');
if (qTextEl) {
let questionStem = question.q || question.question || question["question text"] || '';
qTextEl.innerHTML = `Q${idx + 1}. ${questionStem}`;
}
const optionsContainer = document.getElementById('options-container');
if (optionsContainer) {
optionsContainer.innerHTML = '';
let optionsList = [];
if (question.options && Array.isArray(question.options)) {
optionsList = question.options;
} else if (question.options && typeof question.options === 'object') {
if (question.options.A !== undefined) optionsList.push(question.options.A);
if (question.options.B !== undefined) optionsList.push(question.options.B);
if (question.options.C !== undefined) optionsList.push(question.options.C);
if (question.options.D !== undefined) optionsList.push(question.options.D);
} else {
if (question['Option A'] !== undefined) optionsList.push(question['Option A']);
else if (question.option_a !== undefined) optionsList.push(question.option_a);
if (question['Option B'] !== undefined) optionsList.push(question['Option B']);
else if (question.option_b !== undefined) optionsList.push(question.option_b);
if (question['Option C'] !== undefined) optionsList.push(question['Option C']);
else if (question.option_c !== undefined) optionsList.push(question.option_c);
if (question['Option D'] !== undefined) optionsList.push(question['Option D']);
else if (question.option_d !== undefined) optionsList.push(question.option_d);
}
const savedAnswer = sessionData.answers[idx];
optionsList.forEach((opt, oIdx) => {
const optLetter = String.fromCharCode(65 + oIdx);
const isSelected = savedAnswer === optLetter;
const optBtn = document.createElement('button');
optBtn.style.cssText = `width:100%; padding:15px 20px; text-align:left; border-radius:12px; cursor:pointer; transition:0.2s; font-size:1rem; font-family:'Inter',sans-serif; font-weight:600; display:block; box-sizing:border-box;`;
optBtn.style.border = isSelected ? '2px solid var(--cyan)' : '1px solid rgba(255,255,255,0.1)';
optBtn.style.background = isSelected ? 'rgba(0, 229, 255, 0.15)' : 'rgba(255,255,255,0.04)';
optBtn.style.color = isSelected ? 'var(--cyan)' : 'white';
optBtn.innerHTML = `${optLetter}. ${opt}`;
optBtn.onclick = (e) => {
e.preventDefault();
sessionData.answers[idx] = optLetter;
sessionStorage.setItem('cbt_active_session', JSON.stringify(sessionData));
window.app.loadQuestion(idx);
};
optionsContainer.appendChild(optBtn);
});
}
}
}
},
// π CBT PERFORMANCE COMPILER ENGINE
submitExamSession: () => {
if (window.app.examInterval) clearInterval(window.app.examInterval);
const sessionRaw = sessionStorage.getItem('cbt_active_session');
if (!sessionRaw) {
window.app.view('dashboard-screen');
return;
}
const sessionData = JSON.parse(sessionRaw);
const totalQuestions = sessionData.questions ? sessionData.questions.length : 0;
if (totalQuestions === 0) {
window.app.view('dashboard-screen');
return;
}
let correctCount = 0;
let attemptedCount = 0;
let reviewHTML = "";
sessionData.questions.forEach((q, idx) => {
if (!q) return;
const userAns = sessionData.answers[idx] || "NOT ANSWERED";
// 1. Identify the correct letter index (0, 1, 2, or 3)
let rawAns = q.a !== undefined ? q.a : (q.answer !== undefined ? q.answer : (q.Index !== undefined ? q.Index : (q.index !== undefined ? q.index : '0')));
let correctIdx = parseInt(rawAns);
// 2. Map index to letter
const letters = ['A', 'B', 'C', 'D'];
let correctLetter = letters[correctIdx] || 'A';
// 3. Get the actual option text
const options = q.options || [q['Option A'], q['Option B'], q['Option C'], q['Option D']];
let correctText = options[correctIdx] || "N/A";
// 4. Determine if correct
const isCorrect = userAns === correctLetter;
if (userAns !== "NOT ANSWERED") attemptedCount++;
if (isCorrect) correctCount++;
let questionBody = q.q || q.question || q["question text"] || '';
reviewHTML += `
`;
});
const scorePct = Math.round((correctCount / totalQuestions) * 100);
const targetDuration = sessionData.durationSeconds;
const spentSeconds = targetDuration - (window.app.examRemainingSeconds || 0);
const spentMins = Math.floor(spentSeconds / 60);
const spentSecs = spentSeconds % 60;
let analyticsCoaching = "";
if (scorePct >= 80) {
analyticsCoaching = `π’ EXCELLENT SPEED MATRICULATION! You scored ${scorePct}%. This velocity proves your standard knowledge architecture is fully ready for high-stakes speed thresholds. Keep polishing minor error logs!`;
} else if (scorePct >= 50) {
analyticsCoaching = `π‘ RETRACE REVIEW OPTIMIZATION REQUIRED. You scored ${scorePct}%. You are processing definitions correctly but losing precision under time constraints. Use the topic tags listed below to re-visit specific flashcard blocks inside the Learning Vault.`;
} else {
analyticsCoaching = `π΄ SPEED THRESHOLD CRITICAL WARNING. You scored ${scorePct}%. You spent ${spentMins}m ${spentSecs}s on this session. Conceptual blocks are locking your parameters. Return to your Core Module Mastery Tests until you achieve stable 80% marks before attempting another full simulation engine.`;
}
let reportPane = document.getElementById('exam-report-screen');
if (!reportPane) {
reportPane = document.createElement('div');
reportPane.id = 'exam-report-screen';
reportPane.className = 'screen';
document.getElementById('exam-screen').parentNode.appendChild(reportPane);
}
// This line forces the feedback page to use the subject from your current session
const subjectTitle = sessionData ? sessionData.subject : "EXAM REPORT";
reportPane = document.createElement('div');
reportPane.id = 'exam-report-screen';
reportPane.className = 'screen';
document.getElementById('exam-screen').parentNode.appendChild(reportPane);
}
reportPane.style.cssText = "padding:20px 15px; background:#0a0a0a; min-height:100vh; color:white; overflow-y:auto; box-sizing:border-box; width:100%;";
reportPane.innerHTML = `
`;
window.app.view('exam-report-screen');
},
copyCode: () => {
navigator.clipboard.writeText("TRIAL").then(() => {
const b = document.getElementById('btn-copy-code'); b.innerText = "COPIED!";
setTimeout(() => { b.innerText = "COPY"; }, 2000);
});
},
triggerVault: async (topicCode, idx, title) => {
// π‘οΈ SECURITY INTERCEPT: Block Silver, and restrict Trial tiers to the first topic only
if (window.app.mode === 'silver' || (window.app.mode === 'trial' && idx > 0)) {
window.app.showModal(`π Gold Upgrade Required
Syllabus video overviews, audio concepts, review slides, and active recall flashcards are exclusive to Gold and Platinum scholars.
Please upgrade your membership to unlock the full Learning Vault layout!`);
return;
}
let cleanToken = topicCode.trim();
if (cleanToken.toLowerCase().includes("section")) {
cleanToken = cleanToken.replace(/section/gi, "").trim();
}
const success = await window.vault.fetchVaultData(cleanToken, window.app.sub);
if (success) {
if (window.vault.activeMetadata) {
window.vault.activeMetadata.topicTitle = `Section ${cleanToken}`;
}
window.vault.renderResourceUI(idx);
} else {
window.app.showModal(`π½οΈ Vault Code: ${cleanToken} The cinematic resources for this specific section are currently in production.