Grade 12 ဘာသာရပ်များ
မေးခွန်းဟောင်းများ
🎁 ဘာသာရပ်များကို အစမ်းသုံးရန်
Daily Quiz (Free)
နေ့စဉ် မေးခွန်းသစ် ၃ ခုကို ကျပန်းဖြေဆိုနိုင်ပါသည်။
မြန်မာစာ ➔
အင်္ဂလိပ်စာ ➔
သင်္ချာ ➔
ရူပဗေဒ ➔
ဓာတုဗေဒ ➔
ဇီဝဗေဒ ➔
ဘောဂဗေဒ ➔
💡
Daily Motivation
"ရင်းနှီးမြုပ်နှံမှုတွေထဲမှာအကောင်းဆုံးက ပညာရေးမှာရင်းနှီးမြုပ်နှံခြင်းပါပဲ""
⏳ ခန့်မှန်းခြေ စာမေးပွဲဖြေဆိုရန် ကျန်ရှိချိန်
Daily Study Tracker
Scholar
ကျား
မ
ဝယ်ယူပြီးသော ဘာသာရပ်များ
ဘာသာရပ်ဝယ်ယူရန် ဆက်သွယ်ရန်
⚙️
မေးခွန်းဖြေဆိုမှု ပုံစံ
မေးခွန်းများကို အစဉ်လိုက်ဖြေဆိုမည်လား၊ ကျပန်း (Random) ဖြေဆိုမည်လား ရွေးချယ်ပါ။
အစဉ်လိုက်
ကျပန်း
🎨 Theme Shop
သင့်အကြိုက်ဆုံး အရောင်ကို ရွေးချယ်ပါ
နောက်သို့
📊 My Statistics
📈 Summary
🏆 Best
📜 Old
🏅 Rank
ဆွဲယူနေသည်...
0%
စုစုပေါင်း အဖြေမှန်နှုန်း
0 မေးခွန်းပေါင်း
0 မှန်သောအဖြေ
📜 မေးခွန်းဟောင်းများအကောင်းဆုံးရမှတ်များ
ဘာသာရပ်ရွေးချယ်ပါ
စုစုပေါင်း
မြန်မာစာ
အင်္ဂလိပ်စာ
သင်္ချာ
ရူပဗေဒ
ဓာတုဗေဒ
ဇီဝဗေဒ
ဘောဂဗေဒ
🏅အဆင့်သတ်မှတ်ခြင်း (Fair Rank System)
① မေးခွန်းအရေအတွက် (40%) — များများဖြေထားရင် ပိုကောင်းသည်
② အဖြေမှန်နှုန်း (40%) — မှန်နှုန်းမြင့်ရင် ပိုကောင်းသည်
③ အချိန်မြန်မှု (20%) — တစ်ပုဒ်ချင်းအချိန်နည်းရင် ပိုကောင်းသည်
⚠️ Daily Quiz ဖြေဆိုထားသူများ Rank ထဲမပါပါ
ဆွဲယူနေသည်...
ဒေတာမရှိသေးပါ
နောက်သို့
Flashcard
🔄 ပုံမှန်
1 / 1
⬅️ ရှေ့သို့
နောက်သို့ ➡️
ထွက်မည်
ရမှတ်: 0
နောက်တစ်ပုဒ်သို့ ➔
00:00
⏱ အချိန်မှတ်မည်
🔄 ပြန်စမည်
ထွက်မည်
အဖြေနှင့် တွက်နည်း
⬅️ မေးခွန်းသို့ ပြန်သွားရန်
နောက်တစ်ပုဒ်သို့ ➡️
`;
}
const ADMIN_ID = 8432363664;
const specialUsers = [5593040432,1709037573,5186599374];
const STATS_GAS_URL = "https://script.google.com/macros/s/AKfycbyh46zQCfBKHgi194FYaZAhgTV0CYMqItdooK9VF6lKaSAe-cvUCAZdpZg0yknY0iV7/exec";
// --- School Exclusive Themes (ဈေးမရောင်းဘဲ အထူးပေးသုံး) ---
const exclusiveThemeUsers = {
'mmpn': [8432363664, 987654321, 5593040432], // ဒီကျောင်းသား Telegram ID များ
'joker':[8432363664,5593040432],
'itachi':[8432363664,5593040432],
'heaven':[8432363664,5593040432],
'infinity':[8432363664,5593040432]
};
// --- Sub-Chapter Configuration ---
// အခန်းခွဲများကို မိမိစိတ်ကြိုက် ဤနေရာတွင် ပြင်ဆင်/ထပ်ထည့်နိုင်ပါသည်။
const subChapterConfig = {
'phy': {
'Chapter 1': ['1.1', '1.2','1.3'],
'Chapter 2': ['2.1', '2.2'],
'Chapter 3': ['3.1','3.2','3.3','3.4','3.5','3.6'],
'Chapter 4': ['4.1','4.2','4.3','4.4','4.5'],
'Chapter 5': ['5.1', '5.2','5.3'],
'Chapter 6': ['6.1','6.2','6.3','6.4','6.5'],
'Chapter 7': ['7.1','7.2','7.3','7.4','7.5','7.6','7.7','7.8'],
'Chapter 8': ['8.1','8.2','8.3','8.4'],
'Chapter 9': ['9.1','9.2','9.3','9.4','9.5'],
'Chapter 10': ['10.1','10.2','10.3','10.4','10.5'],
'Chapter 11': ['11.1','11.2','11.3','11.4','11.5','11.6','11.7'],
'Chapter 12': ['12.1', '12.2','12.3'],
'Chapter 13': ['13.1','13.2','13.3','13.4']
},
'chem': {
'Chapter 1': ['1.1', '1.2','1.3','1.4','1.5'],
'Chapter 2': ['2.1', '2.2','2.3'],
'Chapter 3': ['3.1','3.2','3.3'],
'Chapter 4': ['4.1', '4.2','4.3'],
'Chapter 5': ['5.1','5.2','5.3','5.4','5.5'],
'Chapter 6': ['6.1', '6.2','6.3'],
'Chapter 7': ['7.1','7.2','7.3','7.4'],
'Chapter 8': ['8.1','8.2','8.3']
},
'bio': {
'Chapter 1': ['1.1', '1.2'],
'Chapter 2': ['2.1', '2.2','2.3','2.4'],
'Chapter 3': ['3.1','3.2','3.3','3.4','3.5','3.6','3.7','3.8'],
'Chapter 4': ['4.1', '4.2'],
'Chapter 5': ['5.1','5.2','5.3','5.4','5.5'],
'Chapter 6': ['6.1', '6.2','6.3','6.4']
},
'eco': {
'Chapter 1': [],
'Chapter 2': [],
'Chapter 3': [],
'Chapter 4': [],
'Chapter 5': [],
'Chapter 7': [],
'Chapter 8': []
}
};
// ─── Quiz File Parser ───
// ─── Quiz File Parser ───
function parseQuizFile(fileName) {
if (!fileName) return { subject: 'unknown', chapter: 'unknown', type: 'unknown', isOld: false };
let name = String(fileName);
let isOld = false;
if (name.startsWith('old_')) {
isOld = true;
name = name.substring(4);
}
if (name.startsWith('daily_')) {
return { subject: name.replace('daily_', ''), chapter: 'Daily Quiz', type: 'Daily', isOld: false };
}
const parts = name.split('_');
if (parts.length < 2) return { subject: name, chapter: 'General', type: 'Quiz', isOld: isOld };
const subject = parts[0];
if (parts.length >= 4 && parts[1] === 'Chapter') {
let chapterEnd = 3;
if (/^\d+\.\d+$/.test(parts[3])) chapterEnd = 4;
const chapter = parts.slice(1, chapterEnd).join('_').replace(/_/g, ' ');
const type = parts.slice(chapterEnd).join('_').replace(/_/g, ' ') || 'Mixed';
return { subject, chapter, type, isOld };
}
if (parts.length >= 3 && parts[1].startsWith('unit')) {
const chapter = parts[1];
const type = parts.slice(2).join('_').replace(/_/g, ' ') || 'Mixed';
return { subject, chapter, type, isOld };
}
if (subject === 'mm') {
const chapIdx = parts.findIndex(p => p.includes('အခန်း'));
if (chapIdx !== -1 && chapIdx + 1 < parts.length) {
const chapter = `${parts[chapIdx]} ${parts[chapIdx + 1]}`;
const type = parts.slice(chapIdx + 2).join('_').replace(/_/g, ' ') || parts[parts.length - 1];
return { subject, chapter, type, isOld };
}
if (parts.length >= 3) {
return { subject, chapter: parts.slice(1, -1).join('_').replace(/_/g, ' '), type: parts[parts.length - 1], isOld };
}
}
return { subject, chapter: parts.slice(1, -1).join('_').replace(/_/g, ' ') || 'General', type: parts[parts.length - 1] || 'Quiz', isOld };
}
function isMyanmarIndividualQuiz(fileName) {
if (!fileName || typeof fileName !== 'string') return false;
// 🆕 Catch both current (mm_) and old (old_mm_) Myanmar quizzes
const isMm = fileName.startsWith('mm_') || fileName.startsWith('old_mm_');
if (!isMm) return false;
// ✅ Allow combined "all" quizzes (e.g. mm_စကားပြေ_all_မှား_မှန်)
if (fileName.includes('_all_')) return false;
// ✅ Allow ရေသည် (no sub-chapters)
if (fileName.includes('_ရေသည်_')) return false;
// ❌ Everything else is individual chapter/title → skip from rank/stats
return true;
}
// ─── Submit Score ───
// ─── Local Stats Helpers ───
function getLocalStats() {
try {
return JSON.parse(localStorage.getItem('local_quiz_stats')) || { history: [], bestScores: {} };
} catch (e) {
return { history: [], bestScores: {} };
}
}
function saveLocalStats(stats) {
localStorage.setItem('local_quiz_stats', JSON.stringify(stats));
}
function formatTime(seconds) {
const m = Math.floor(seconds / 60).toString().padStart(2, '0');
const s = (seconds % 60).toString().padStart(2, '0');
return `${m}:${s}`;
}
// Detect sub-chapter files like phy_Chapter_1_1.1_MCQ
function isSubChapter(quizFile) {
return /_\d+\.\d+_/.test(quizFile);
}
// Clean up Myanmar "_all_" filenames for stats display
// mm_စကားပြေ_all_မှား_မှန် → "စကားပြေ မှားမှန်"
// mm_အပြော_all_အမှန်ရွေး → "အပြော အမှန်ရွေး"
function getStatDisplayName(key, item) {
const cleanKey = key.replace(/^old_/, '');
if (cleanKey.includes('_all_') && item.subject === 'mm') {
const parts = cleanKey.split('_');
if (parts.length >= 4 && parts[0] === 'mm') {
const category = parts[1]; // e.g. အပြော, စကားပြေ, ကဗျာ, အရေး
const typeParts = parts.slice(3); // everything after "all"
const typeClean = typeParts.join(''); // မှား + မှန် = မှားမှန်
return `${category} ${typeClean}`;
}
}
// 🆕 Handle ရေသည် quizzes: mm_ရေသည်_မှား_မှန် → "ရေသည် မှား မှန်"
if (item.subject === 'mm' && cleanKey.includes('_ရေသည်_')) {
const parts = cleanKey.split('_');
if (parts.length >= 3) {
return parts.slice(1).join(' ');
}
}
return item.chapter || '';
}
async function submitScore(timeTaken = 0) {
// 🚫 Do NOT save Daily Quiz data to statistics
if (currentQuizFile && currentQuizFile.startsWith('daily_')) {
console.log("Daily Quiz data not saved to sheet.");
resetTimer();
return;
}
// 🚫 Do NOT save Myanmar individual chapter/title quizzes
if (isMyanmarIndividualQuiz(currentQuizFile)) {
console.log("Stats not saved: Myanmar individual chapter/title quiz");
resetTimer();
return;
}
if (!currentQuizFile || !currentQuestions || currentQuestions.length === 0) {
console.warn("submitScore skipped: no quiz data");
return;
}
const isRandom = localStorage.getItem('randomQuizSetting') !== 'false';
if (!isRandom) {
console.log("Stats not saved: Random mode is OFF");
resetTimer();
return;
}
if (!isTimerRunning) {
console.log("Stats not saved: Timer not running or was stopped");
resetTimer();
return;
}
const userId = tg.initDataUnsafe?.user?.id?.toString() || 'unknown';
const userName = tg.initDataUnsafe?.user?.first_name || 'unknown';
const meta = parseQuizFile(currentQuizFile);
const isSubChapter = /_\d+\.\d+_/.test(currentQuizFile);
let finalScore = score || 0;
let finalTotal = currentQuestions.length || 0;
const isMathShow = currentQuestions[0] && currentQuestions[0].type === 'math_show';
if (isMathShow) {
finalScore = 0;
finalTotal = 0;
}
// Local stats
const localStats = getLocalStats();
const previousBest = localStats.bestScores[currentQuizFile];
const isNewBest = !previousBest || finalScore > previousBest.score;
const now = new Date().toISOString();
localStats.history.unshift({
quizFile: currentQuizFile,
subject: meta.subject,
chapter: meta.chapter,
type: meta.type,
score: finalScore,
total: finalTotal,
timeTaken: timeTaken,
date: now,
isOld: meta.isOld
});
if (localStats.history.length > 100) localStats.history = localStats.history.slice(0, 100);
if (isNewBest) {
localStats.bestScores[currentQuizFile] = {
score: finalScore,
total: finalTotal,
timeTaken: timeTaken,
date: now,
subject: meta.subject,
chapter: meta.chapter,
type: meta.type,
isOld: meta.isOld
};
}
saveLocalStats(localStats);
// Only send to Google Sheet if new best AND not sub-chapter
if (!isNewBest || isSubChapter) {
console.log("Score not sent to sheet: not a new best or is sub-chapter");
resetTimer();
return;
}
const params = new URLSearchParams({
action: 'saveScore',
userId: userId,
userName: userName,
quizFile: currentQuizFile,
subject: meta.subject,
chapter: meta.chapter,
type: meta.type,
score: String(finalScore),
total: String(finalTotal),
isOld: meta.isOld ? 'true' : 'false',
timeTaken: String(timeTaken)
});
const url = `${STATS_GAS_URL}?${params.toString()}`;
console.log("Submitting to GAS:", url);
try {
const res = await fetch(url);
const text = await res.text();
console.log("GAS Response:", text);
const data = JSON.parse(text);
if (data.status === 'ok') {
if (data.action === 'replaced') {
console.log(`🏆 Record replaced: ${data.oldScore} → ${data.newScore}`);
} else if (data.action === 'inserted') {
console.log(`✅ New score saved at row ${data.row}`);
} else if (data.action === 'skipped') {
console.log(`⏭️ Score skipped (not better than ${data.bestScore})`);
}
} else {
console.error("GAS Error:", data.message);
}
} catch (e) {
console.error("SaveScore failed:", e);
}
resetTimer();
}
function renderBestScores(bestScoresObj, containerId, filterOld) {
const container = document.getElementById(containerId);
container.innerHTML = '';
let keys = Object.keys(bestScoresObj);
// Filter Old vs New
keys = keys.filter(key => {
const item = bestScoresObj[key];
const isOld = item.isOld || key.startsWith('old_');
const isDaily = key.startsWith('daily_');
if (filterOld) return isOld;
return !isOld && !isDaily;
});
// Hide sub-chapters and Myanmar individual title/chapter quizzes
keys = keys.filter(key => !isSubChapter(key) && !isMyanmarIndividualQuiz(key));
if (keys.length === 0) {
container.innerHTML = '
ဒေတာမရှိသေးပါ
';
return;
}
const bySubject = {};
keys.forEach(key => {
const b = bestScoresObj[key];
const sub = b.subject || 'unknown';
if (!bySubject[sub]) bySubject[sub] = [];
bySubject[sub].push({ key, ...b });
});
Object.keys(bySubject).forEach(sub => {
const header = document.createElement('div');
header.className = 'stat-subject-header';
header.innerText = getSubjectName(sub);
container.appendChild(header);
bySubject[sub].forEach(b => {
const div = document.createElement('div');
div.style.cssText = 'background: var(--card-bg); padding: 12px 15px; border-radius: 12px; margin-bottom: 8px; border-left: 4px solid #F59E0B;';
const timeStr = b.timeTaken ? formatTime(b.timeTaken) : '-';
const percent = b.total > 0 ? Math.round((b.score / b.total) * 100) : 0;
const dateStr = b.date ? new Date(b.date).toLocaleDateString() : '';
// 🆕 Use clean display name for Myanmar "_all_" quizzes
const displayName = getStatDisplayName(b.key, b);
const cleanKey = b.key.replace(/^old_/, '');
const isMyanmarAll = cleanKey.includes('_all_') && b.subject === 'mm';
const isMyanmarYadaya = b.subject === 'mm' && cleanKey.includes('_ရေသည်_');
div.innerHTML = `
${displayName}
${b.score}/${b.total} (${percent}%)
${(isMyanmarAll || isMyanmarYadaya) ? '' : `
${b.type || ''}
`}
⏱ ${timeStr}
${dateStr}
`;
container.appendChild(div);
});
});
}
// ─── Load Statistics ───
async function loadUserStats() {
const userId = tg.initDataUnsafe?.user?.id?.toString() || 'unknown';
// 1. Show loading first (no stale local data shown yet)
document.getElementById('stats-loading').style.display = 'block';
document.getElementById('stats-loading').innerText = 'ဆွဲယူနေသည်...';
document.getElementById('stats-loading').style.color = 'var(--text-muted)';
document.getElementById('stats-tab-summary').style.display = 'none';
document.getElementById('stats-tab-best').style.display = 'none';
document.getElementById('stats-tab-old').style.display = 'none';
let bestScoresToRender = {};
// 2. Try server first for the latest official data
if (userId !== 'unknown') {
const url = `${STATS_GAS_URL}?action=getStats&userId=${userId}`;
try {
const res = await fetch(url);
const text = await res.text();
let data;
try { data = JSON.parse(text); } catch(e) { throw e; }
if (data.status === 'ok' && data.bestScores && data.bestScores.length > 0) {
data.bestScores.forEach(b => { bestScoresToRender[b.quizFile] = b; });
}
} catch (e) {
console.error("Server stats fetch failed:", e);
}
}
// 3. Merge with local data so unsynced high scores aren't lost
const localStats = getLocalStats();
const localBest = localStats.bestScores || {};
Object.keys(localBest).forEach(key => {
const localItem = localBest[key];
const serverItem = bestScoresToRender[key];
if (!serverItem || (localItem.score || 0) > (serverItem.score || 0)) {
bestScoresToRender[key] = localItem;
}
});
// 4. Render final merged data
renderSummary(bestScoresToRender);
renderBestScores(bestScoresToRender, 'stat-best-scores', false);
renderBestScores(bestScoresToRender, 'stat-old-scores', true);
document.getElementById('stats-loading').style.display = 'none';
switchStatsTab('summary');
}
function renderSummary(bestScoresObj) {
bestScoresObj = bestScoresObj || {};
const container = document.getElementById('stat-subjects');
container.innerHTML = '';
const keys = Object.keys(bestScoresObj).filter(key => {
const item = bestScoresObj[key];
const isOld = item.isOld || key.startsWith('old_');
const isDaily = key.startsWith('daily_');
return !isOld && !isDaily && !isSubChapter(key) && !isMyanmarIndividualQuiz(key);
});
// Overall card elements
const overallAccEl = document.getElementById('stat-overall-acc');
const card = overallAccEl.closest('.stat-card');
if (keys.length === 0) {
overallAccEl.innerText = '0%';
document.getElementById('stat-total-q').innerText = '0';
document.getElementById('stat-total-c').innerText = '0';
let timeDiv = document.getElementById('stat-total-time');
if (timeDiv) timeDiv.innerText = '⏱ 00:00';
container.innerHTML = '
ဒေတာမရှိသေးပါ
';
return;
}
// Group & sum by subject
const bySubject = {};
let overallScore = 0, overallTotal = 0, overallTime = 0;
keys.forEach(key => {
const b = bestScoresObj[key];
const sub = b.subject || 'unknown';
if (!bySubject[sub]) bySubject[sub] = { score: 0, total: 0, time: 0, count: 0 };
bySubject[sub].score += (b.score || 0);
bySubject[sub].total += (b.total || 0);
bySubject[sub].time += (b.timeTaken || 0);
bySubject[sub].count += 1;
overallScore += (b.score || 0);
overallTotal += (b.total || 0);
overallTime += (b.timeTaken || 0);
});
// Update overall card
const overallAcc = overallTotal > 0 ? Math.round((overallScore / overallTotal) * 100) : 0;
overallAccEl.innerText = overallAcc + '%';
document.getElementById('stat-total-q').innerText = overallTotal;
document.getElementById('stat-total-c').innerText = overallScore;
let timeDiv = document.getElementById('stat-total-time');
if (!timeDiv) {
timeDiv = document.createElement('div');
timeDiv.id = 'stat-total-time';
timeDiv.style.cssText = 'margin-top:10px;padding-top:10px;border-top:1px solid rgba(255,255,255,0.1);font-family:monospace;color:var(--text-muted);font-size:0.85rem;text-align:center;';
card.appendChild(timeDiv);
}
timeDiv.innerText = '⏱ စုစုပေါင်းအချိန်: ' + formatTime(overallTime);
// Render per-subject rows
Object.keys(bySubject).forEach(sub => {
const s = bySubject[sub];
const acc = s.total > 0 ? Math.round((s.score / s.total) * 100) : 0;
const timeStr = formatTime(s.time);
const div = document.createElement('div');
div.style.cssText = 'background:var(--card-bg);padding:12px 15px;border-radius:12px;margin-bottom:8px;border-left:4px solid var(--accent);display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px;';
div.innerHTML = `
${getSubjectName(sub)}
⏱ ${timeStr} · ${s.count} ခု
${acc}%
${s.score}/${s.total}
`;
container.appendChild(div);
});
}
function showStatsScreen() {
showScreen('stats');
document.getElementById('stats-loading').style.display = 'block';
document.getElementById('stats-loading').innerText = 'ဆွဲယူနေသည်...';
document.getElementById('stats-loading').style.color = 'var(--text-muted)';
document.getElementById('stats-tab-summary').style.display = 'none';
document.getElementById('stats-tab-best').style.display = 'none';
document.getElementById('stats-tab-old').style.display = 'none';
document.getElementById('stats-tab-leaderboard').style.display = 'none';
// Reset all tabs to inactive first
['summary', 'best', 'old', 'leaderboard'].forEach(t => {
const btn = document.getElementById('tab-' + t);
if (btn) btn.classList.remove('stats-tab-active');
});
// Set summary as active by default
const summaryBtn = document.getElementById('tab-summary');
if (summaryBtn) summaryBtn.classList.add('stats-tab-active');
loadUserStats();
}
function getSubjectName(id) {
const map = { mm: 'မြန်မာစာ', en: 'အင်္ဂလိပ်စာ', math: 'သင်္ချာ', phy: 'ရူပဗေဒ', chem: 'ဓာတုဗေဒ', bio: 'ဇီဝဗေဒ', eco: 'ဘောဂဗေဒ', unknown: 'အခြား' };
return map[id] || id;
}
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
function toggleArticle(id) {
const content = document.getElementById(id);
const arrow = document.getElementById('arrow-' + id);
if (content.classList.contains('open')) {
content.classList.remove('open');
arrow.classList.remove('open');
} else {
// Close all other articles first (only one open at a time)
document.querySelectorAll('.article-content').forEach(el => el.classList.remove('open'));
document.querySelectorAll('.article-arrow').forEach(el => el.classList.remove('open'));
content.classList.add('open');
arrow.classList.add('open');
}
}
// ===== ARTICLES SYSTEM (JSON Based) =====
let articlesIndex = [];
async function loadArticlesIndex() {
const container = document.getElementById('articles-list');
container.innerHTML = '
ဆွဲယူနေသည်...
';
try {
const res = await fetch('./articles/index.json');
if (!res.ok) throw new Error();
articlesIndex = await res.json();
renderArticlesList();
} catch (e) {
container.innerHTML = '
ဆောင်းပါးများ မရရှိသေးပါ
';
}
}
function renderArticlesList() {
const container = document.getElementById('articles-list');
container.innerHTML = '';
if (!articlesIndex || articlesIndex.length === 0) {
container.innerHTML = '
ဆောင်းပါးများ မရှိသေးပါ
';
return;
}
articlesIndex.forEach(article => {
const div = document.createElement('div');
div.style.cssText = 'background: var(--card-bg); border-radius: 14px; margin-bottom: 12px; border: 1px solid #334155; overflow: hidden; cursor: pointer; transition: transform 0.1s ease;';
div.innerHTML = `
${article.title}
${article.date ? `
${article.date}
` : ''}
➔
`;
div.onmousedown = () => div.style.transform = 'scale(0.98)';
div.onmouseup = () => div.style.transform = 'scale(1)';
div.onmouseleave = () => div.style.transform = 'scale(1)';
div.onclick = () => openArticleDetail(article.id);
container.appendChild(div);
});
}
async function openArticleDetail(articleId) {
try {
const res = await fetch(`./articles/${articleId}.json`);
if (!res.ok) throw new Error();
const article = await res.json();
document.getElementById('article-detail-title').innerText = article.title;
document.getElementById('article-detail-date').innerText = article.date || '';
const bodyDiv = document.getElementById('article-detail-body');
bodyDiv.innerHTML = '';
// Helper to render each block
const renderBlock = (block) => {
// Case 1: Plain text paragraph
if (typeof block === 'string') {
const p = document.createElement('p');
p.style.margin = '0 0 14px 0';
p.style.lineHeight = '1.8';
p.style.color = 'var(--white)';
p.innerText = block;
return p;
}
// Case 2: Image object
if (typeof block === 'object' && block.type === 'image') {
const wrapper = document.createElement('div');
wrapper.style.cssText = 'margin: 16px 0; text-align: center;';
const img = document.createElement('img');
img.src = block.src;
img.alt = block.caption || 'Image';
img.style.cssText = 'width: 100%; max-width: 100%; border-radius: 12px; display: block; border: 1px solid #334155;';
wrapper.appendChild(img);
// Optional caption
if (block.caption) {
const cap = document.createElement('div');
cap.style.cssText = 'margin-top: 8px; font-size: 0.8rem; color: var(--text-muted); font-style: italic;';
cap.innerText = block.caption;
wrapper.appendChild(cap);
}
return wrapper;
}
// Case 3: Raw HTML fallback (for advanced use)
if (typeof block === 'object' && block.type === 'html') {
const div = document.createElement('div');
div.style.margin = '0 0 14px 0';
div.innerHTML = block.value;
return div;
}
return document.createElement('span');
};
// Support both old array format and new mixed format
if (Array.isArray(article.content)) {
article.content.forEach(block => {
bodyDiv.appendChild(renderBlock(block));
});
} else if (typeof article.content === 'string') {
// Legacy single-string HTML support
bodyDiv.innerHTML = article.content;
}
showScreen('article-detail');
} catch (e) {
tg.showAlert("ဆောင်းပါး ဖွင့်ရာတွင် အမှားတစ်ခု ဖြစ်သွားပါသည်။");
}
}
const tg = window.Telegram.WebApp;
tg.ready(); tg.expand();
let paidUsers = {};
let userBought = {}; // const အစား let ပြောင်းပေးရမည်
const userId = tg.initDataUnsafe?.user?.id?.toString() || "Guest";
function loadFromCache() {
try {
const cached = localStorage.getItem('cached_paid_users');
if (cached) {
paidUsers = JSON.parse(cached);
userBought = paidUsers[userId] || {};
renderSubjects();
initOldSubjects();
return true; // Cache ရှိတယ်
}
} catch (e) {
console.error("Cache error:", e);
}
return false; // Cache မရှိဘူး
}
async function fetchPaidUsers() {
const sheetURL = "https://script.google.com/macros/s/AKfycbyFdqz2eAR7gr8ZKyMph-9sxYzXJ48fjfC42GNhsWug9YO0p6U-X6I3Rx8WJ4dtSMXQ/exec";
try {
const response = await fetch(sheetURL + "?action=getUsers");
const newData = await response.json();
if (newData.success === false) {
console.error("GAS Error:", newData.message);
return;
}
const cachedStr = localStorage.getItem('cached_paid_users');
const newStr = JSON.stringify(newData);
// ဒေတာ တကယ်ပြောင်းမှ ပြန်သိမ်းပြီး Re-render လုပ်မယ်
if (cachedStr !== newStr) {
localStorage.setItem('cached_paid_users', newStr);
paidUsers = newData;
userBought = paidUsers[userId] || {};
renderSubjects();
initOldSubjects();
console.log("✅ Data synced from server");
}
} catch (e) {
console.error("❌ Background sync failed:", e);
// Fail ရင် Cache ကို အရင်အတိုင်းထားခဲ့မယ် (User ကို မကြောက်စရာလိုဘူး)
}
}
const subjects = [
{ id: 'mm', name: 'မြန်မာစာ' },
{ id: 'en', name: 'အင်္ဂလိပ်စာ' },
{ id: 'math', name: 'သင်္ချာ', chapters: 11 }, // သင်္ချာကို ပြန်ထည့်ထားသည်
{ id: 'phy', name: 'ရူပဗေဒ', chapters: 13 },
{ id: 'chem', name: 'ဓာတုဗေဒ', chapters: 8 },
{ id: 'bio', name: 'ဇီဝဗေဒ', chapters: 6 },
{ id: 'eco', name: 'ဘောဂဗေဒ', chapters: 8 }
];
let currentSubject = null;
let currentQuestions = [];
let currentIdx = 0;
let flashIdx = 0;
let flashCards = [];
let isAnswered = false;
let currentQuizFile = '';
// မူလရှိနေသော const userId နှင့် const userBought နေရာများကို အပေါ်သို့ ရွှေ့လိုက်ပါပြီ။
// --- Old Questions Navigation Logic ---
// Grammar ခေါင်းစဉ်များကို နှစ်အလိုက်မခွဲတော့ဘဲ တစ်ခုတည်းအဖြစ် ပေါင်းထားပါသည်
const oldENGrammarTopics = [
{ title: "Direct Indirect", id: "din" },
{ title: "Both And", id: "botha" },
{ title: "Too to", id: "toot" },
{ title: "Omission of Relative Pronoun", id: "omispro" },
{ title: "Relative Pronoun & Adverbs", id: "relativepro" },
{ title: "Active Voice To Passive Voice", id: "passive" },
{ title: "Linking Word", id: "linkinw" },
{ title: "Second Conditional", id: "seccon" },
{ title: "Third Conditional", id: "thirdcon" },
{ title: "No matter", id: "nomat" },
{ title: "Not only but also", id: "notonly" },
{ title: "It is/ It was", id: "itisitwas" },
{ title: "So as to", id: "soas" },
{ title: "Introductory phases", id: "introduct" },
{ title: "Owning to", id: "owning" },
{ title: "Tenses", id: "tense" },
{ title: "Without Ving", id: "without" },
{ title: "Enough to", id: "enough" },
{ title: "Although", id: "although" },
{ title: "Even Though", id: "even" },
{ title: "Either or", id: "eitheror" },
{ title: "Neither nor", id: "neither" },
{ title: "Before", id: "before" },
{ title: "After", id: "after" },
{ title: "So that such that", id: "sothat" },
{ title: "As soon as / No sooner", id: "assoon" },
{ title: "Nouns in apposition", id: "nounin" },
{ title: "As if / As though", id: "asif" },
{ title: "The more the less", id: "the more" },
{ title: "Such that / In order to", id: "inorder" },
{ title: "Participal phrases", id: "participal" }
// လိုအပ်သလို ထပ်ဖြည့်နိုင်ပါသည်
];
// မေးခွန်းဟောင်းအတွက် သီးသန့် Button ဖန်တီးပေးသည့် Function
function createOldBtn(txt, parent, act) {
const b = document.createElement('button');
b.className = 'btn old-btn'; // ⬅️ uses the purple theme
b.innerText = txt;
b.onclick = act;
parent.appendChild(b);
}
let isOldQuestionFlow = false;
function setOldQuestionContext(active) {
isOldQuestionFlow = active;
}
function updateOldQuestionBadges() {
// Remove any existing badges first
document.querySelectorAll('.old-question-badge').forEach(el => el.remove());
if (!isOldQuestionFlow) return;
// Quiz screen
const quizScreen = document.getElementById('quiz-screen');
if (quizScreen && quizScreen.classList.contains('active-screen')) {
const badge = document.createElement('div');
badge.className = 'old-question-badge';
badge.innerText = '📜 မေးခွန်းဟောင်း';
badge.style.cssText = 'position:absolute; top:5px; right:10px; background:linear-gradient(135deg,#A855F7,#7C3AED); color:#fff; padding:3px 10px; border-radius:10px; font-size:0.7rem; font-weight:700; z-index:40; border:1px solid rgba(255,255,255,0.2); pointer-events:none;';
quizScreen.appendChild(badge);
}
// Flashcard screen
const flashScreen = document.getElementById('flashcard-screen');
if (flashScreen && flashScreen.classList.contains('active-screen')) {
const wrap = document.createElement('div');
wrap.className = 'old-question-badge';
wrap.style.cssText = 'text-align:center; margin-bottom:8px;';
wrap.innerHTML = '
📜 မေးခွန်းဟောင်း ';
const firstDiv = flashScreen.querySelector('div');
if (firstDiv) flashScreen.insertBefore(wrap, firstDiv);
else flashScreen.prepend(wrap);
}
// Math solution screen
const mathScreen = document.getElementById('math-solution-screen');
if (mathScreen && mathScreen.classList.contains('active-screen')) {
const badge = document.createElement('div');
badge.className = 'old-question-badge';
badge.innerText = '📜 မေးခွန်းဟောင်း';
badge.style.cssText = 'position:absolute; top:10px; right:10px; background:linear-gradient(135deg,#A855F7,#7C3AED); color:#fff; padding:3px 10px; border-radius:10px; font-size:0.7rem; font-weight:700; z-index:40; border:1px solid rgba(255,255,255,0.2); pointer-events:none;';
mathScreen.appendChild(badge);
}
}
function initOldSubjects() {
const list = document.getElementById('old-subject-list');
if (!list) return;
list.innerHTML = '';
subjects.forEach(sub => {
const currentUserId = tg.initDataUnsafe?.user?.id?.toString() || "0";
const isSpecial = specialUsers.map(String).includes(currentUserId);
let isPaid = checkAccess(sub.id);
if (isSpecial && (['mm', 'en', 'phy', 'chem', 'math'].includes(sub.id) || sub.id === 'bio' || sub.id === 'eco')) {
isPaid = true;
}
const card = document.createElement('div');
card.className = `subject-card ${isPaid ? '' : 'locked'} ${isSpecial && isPaid ? 'premium-card' : ''}`;
card.innerHTML = `
${sub.name} ${isPaid ? '' : '🔒'} ➔ `;
card.onclick = () => {
if (isPaid) {
currentSubject = sub;
isAnswered = false;
setOldQuestionContext(true);
showScreen('old-menu'); // ⬅️ Go to separate screen
showOldMenu(sub);
} else {
tg.showAlert("ဒီဘာသာရပ်ကို ဝယ်ယူထားခြင်း မရှိသေးပါ။ Unlock လုပ်ရန် ဆက်သွယ်ပါ။");
}
};
list.appendChild(card);
});
}
function backToOldSubjects() {
setOldQuestionContext(false);
showScreen('home');
switchHomeTab('old');
}
function showOldMenu(sub) {
document.getElementById('old-menu-title').innerHTML =
`
📜 မေးခွန်းဟောင်း
` +
`
${sub.name}
`;
const list = document.getElementById('old-menu-content');
list.innerHTML = '';
document.getElementById('old-menu-back-btn').onclick = backToOldSubjects;
// ... rest of the function stays exactly the same
if (sub.id === 'en') {
['Initial Letter', 'MCQ', 'Grammar'].forEach(type => {
createOldBtn(type, list, () => {
if (type === 'Grammar') showOldENGrammarOptions();
else showOldENUnits(type);
});
});
} else if (sub.id === 'mm') {
['မှား/မှန်', 'ကွက်လပ်ဖြည့်', 'အမှန်ရွေး'].forEach(m => {
createOldBtn(m, list, () => showOldMMQuizOptions(m));
});
} else {
for (let i = 1; i <= sub.chapters; i++) {
if (sub.id === 'eco' && i === 6) continue;
createOldBtn(`Chapter ${i}`, list, () => showOldGeneralActivities(sub.id, `Chapter ${i}`));
}
}
}
function showOldENUnits(typeName) {
const list = document.getElementById('old-menu-content');
list.innerHTML = '';
document.getElementById('old-menu-title').innerText = typeName;
document.getElementById('old-menu-back-btn').onclick = () => showOldMenu(currentSubject);
for (let i = 1; i <= 12; i++) {
createOldBtn(`Unit ${i}`, list, () => {
initQuiz(`old_en_unit${i}_${typeName.toLowerCase().replace(' ', '_')}`);
document.getElementById('quiz-back-btn').onclick = () => {
showScreen('old-menu');
showOldENUnits(typeName);
};
});
}
}
function showOldENGrammarOptions() {
const list = document.getElementById('old-menu-content');
list.innerHTML = '';
document.getElementById('old-menu-title').innerText = "Grammar";
document.getElementById('old-menu-back-btn').onclick = () => showOldMenu(currentSubject);
oldENGrammarTopics.forEach(topic => {
createOldBtn(topic.title, list, () => {
initFlashcards(`old_${topic.id}`, topic.title);
const flashExitBtn = document.querySelector('#flashcard-screen .back-btn');
flashExitBtn.onclick = () => {
showScreen('old-menu');
showOldENGrammarOptions();
};
});
});
}
function showOldMMQuizOptions(typeName) {
const list = document.getElementById('old-menu-content');
list.innerHTML = '';
document.getElementById('old-menu-title').innerText = typeName;
document.getElementById('old-menu-back-btn').onclick = () => showOldMenu(currentSubject);
['အပြော', 'စကားပြေ', 'ကဗျာ', 'ရေသည်', 'အရေး'].forEach(cat => {
createOldBtn(cat, list, () => {
if (cat === 'အပြော' || cat === 'အရေး') {
showOldMMChapters(typeName, cat);
} else if (cat === 'ရေသည်') {
const fileName = `old_mm_ရေသည်_${typeName}`.replace(/\//g, "_").replace(/ /g, "_");
initQuiz(fileName);
document.getElementById('quiz-back-btn').onclick = () => {
showScreen('old-menu');
showOldMMQuizOptions(typeName);
};
} else {
initQuiz(`old_mm_${cat}_${typeName}`.replace(/\//g, "_").replace(/ /g, "_"));
document.getElementById('quiz-back-btn').onclick = () => {
showScreen('old-menu');
showOldMMQuizOptions(typeName);
};
}
});
});
}
function showOldMMChapters(typeName, cat) {
const list = document.getElementById('old-menu-content');
list.innerHTML = '';
document.getElementById('old-menu-title').innerText = `${cat} (${typeName})`;
document.getElementById('old-menu-back-btn').onclick = () => showOldMMQuizOptions(typeName);
['အခန်း ၁', 'အခန်း ၂', 'အခန်း ၃'].forEach(chapter => {
createOldBtn(chapter, list, () => {
const fileName = `old_mm_${cat}_${chapter}_${typeName}`.replace(/\//g, "_").replace(/ /g, "_");
initQuiz(fileName);
document.getElementById('quiz-back-btn').onclick = () => {
showScreen('old-menu');
showOldMMChapters(typeName, cat);
};
});
});
}
function showOldGeneralActivities(subId, partName) {
const list = document.getElementById('old-menu-content');
list.innerHTML = '';
document.getElementById('old-menu-title').innerText = partName;
document.getElementById('old-menu-back-btn').onclick = () => showOldMenu(currentSubject);
if (subId === 'math') {
let marksArray = ['1_Mark', '2_Marks', '3_Marks'];
if (partName === 'Chapter 2') marksArray = ['3_Marks'];
if (partName === 'Chapter 7') marksArray = ['1_Mark', '2_Marks'];
marksArray.forEach(mark => {
createOldBtn(mark.replace('_', ' '), list, () => {
const fileName = `old_math_${partName}_${mark}`.replace(/ /g, "_");
initQuiz(fileName);
document.getElementById('quiz-back-btn').onclick = () => {
showScreen('old-menu');
showOldGeneralActivities(subId, partName);
};
});
});
} else {
let types = ['True_False', 'Fill_Blank', 'MCQ'];
types.forEach(type => {
createOldBtn(type.replace('_', ' '), list, () => {
const fileName = `old_${subId}_${partName}_${type}`.replace(/ /g, "_");
initQuiz(fileName);
document.getElementById('quiz-back-btn').onclick = () => {
showScreen('old-menu');
showOldGeneralActivities(subId, partName);
};
});
});
}
}
function checkAccess(subId) {
// ၁။ ဒီနေ့ ရက်စွဲကို အချိန် (Time) မပါဘဲ ယူမည်
const today = new Date();
today.setHours(0, 0, 0, 0);
// ၂။ ရက်စွဲ စစ်ဆေးမည့် အတွင်းပိုင်း Function
function isValid(expiryStr) {
if (!expiryStr) return false;
// စာသားကို Date Object အဖြစ် ပြောင်းမည်
const expiryDate = new Date(expiryStr);
// အကယ်၍ ရက်စွဲ မဟုတ်ခဲ့လျှင် (ဥပမာ- စာသားအမှား ဖြစ်နေလျှင်) False ပြန်မည်
if (isNaN(expiryDate.getTime())) return false;
expiryDate.setHours(0, 0, 0, 0);
// Expire Date က ဒီနေ့ထက် ကြီးရင် (သို့) ညီရင် True (ပွင့်မည်)
return expiryDate >= today;
}
// ၃။ 'all' သို့မဟုတ် သက်ဆိုင်ရာ 'subId' ကို စစ်ဆေးခြင်း
if (isValid(userBought['all'])) return true;
if (isValid(userBought[subId])) return true;
return false;
}
// သော့ဖွင့်ပေးသည့် Function
function unlockCard(div, sub) {
div.classList.remove('locked');
const lockSpan = div.querySelector('.lock-icon');
if (lockSpan) lockSpan.remove(); // သော့ပုံလေးကို ဖြုတ်လိုက်မည်
div.onclick = () => openSubjectMenu(sub);
}
function renderSubjects() {
const list = document.getElementById('subject-list');
list.innerHTML = '';
// specialUsers ကို အပေါ်မှာ Global ထားခဲ့ပြီးဖြစ်လို့ ဒီမှာ ထပ်ကြေညာစရာမလိုပါ
const currentUserId = tg.initDataUnsafe?.user?.id?.toString() || "0";
const isSpecial = specialUsers.map(String).includes(currentUserId);
subjects.forEach(sub => {
let isPaid = checkAccess(sub.id);
// Special User ဆိုလျှင် ၆ ဘာသာ ပွင့်ပေးမည်
if (isSpecial) {
const fiveSubjects = ['mm', 'en', 'math', 'phy', 'chem'];
if (fiveSubjects.includes(sub.id) || sub.id === 'bio' || sub.id === 'eco') {
isPaid = true;
}
}
const div = document.createElement('div');
div.className = `subject-card ${isPaid ? '' : 'locked'} ${isSpecial && isPaid ? 'premium-card' : ''}`;
div.innerHTML = `
${sub.name} ${isPaid ? '' : '🔒'} ➔ `;
div.onclick = () => {
setOldQuestionContext(false); // ⬅️ ADD THIS LINE
isPaid ? openSubjectMenu(sub) : tg.showAlert("ဘာသာရပ်၀ယ်ယူထားသူများသာ အသုံးပြုနိုင်ပါသည်။");
};
list.appendChild(div);
});
}
function openSubjectMenu(sub) {
setOldQuestionContext(false);
const currentUserId = tg.initDataUnsafe?.user?.id?.toString() || "0";
const isSpecial = specialUsers.map(String).includes(currentUserId);
// ပုံမှန်ဝယ်ထားသူလား (သို့မဟုတ်) Special User ဖြစ်ပြီး ၆ ဘာသာထဲက တစ်ခုလား စစ်ဆေးခြင်း
const isPaidInCode = checkAccess(sub.id);
const isSpecialSubject = isSpecial && (['mm', 'en', 'math', 'phy', 'chem'].includes(sub.id) || sub.id === 'bio' || sub.id === 'eco');
const canAccess = isPaidInCode || isSpecialSubject;
if (!canAccess) {
tg.showAlert("တစ်ဘာသာလုံးကိုလေ့ကျင့်ဖို့ ဒီဘာသာရပ်ကိုဝယ်ယူလိုက်ပါ");
showScreen('home');
return;
}
currentSubject = sub;
showScreen('menu');
document.getElementById('menu-title').innerText = sub.name;
const content = document.getElementById('menu-content');
content.innerHTML = '';
if (sub.id === 'en') {
['Initial Letter', 'MCQ', 'Grammar', 'Poem'].forEach(type => {
createBtn(type, content, () => {
if (type === 'Initial Letter' || type === 'MCQ') showENUnits(type);
else if (type === 'Grammar') showENGrammarOptions();
else if (type === 'Poem') showENPoemOptions();
});
});
} else if (sub.id === 'mm') {
['မှား/မှန်', 'ကွက်လပ်ဖြည့်', 'အမှန်ရွေး', 'ခက်ဆစ်', 'အလင်္ကာ'].forEach(m => {
createBtn(m, content, () => {
if (['မှား/မှန်', 'ကွက်လပ်ဖြည့်', 'အမှန်ရွေး'].includes(m)) showMMQuizOptions(m);
else showMMFlashcardOptions(m);
});
});
} else if (sub.id === 'phy' || sub.id === 'chem') {
for(let i=1; i<=sub.chapters; i++) {
createBtn(`Chapter ${i}`, content, () => showSubChaptersMenu(sub.id, `Chapter ${i}`));
}
} else {
for(let i=1; i<=sub.chapters; i++) {
if (sub.id === 'eco' && i === 6) continue;
if (sub.id === 'math') {
createBtn(`Chapter ${i}`, content, () => showGeneralActivities(sub.id, `Chapter ${i}`));
} else {
createBtn(`Chapter ${i}`, content, () => showSubChaptersMenu(sub.id, `Chapter ${i}`));
}
}
}
}
function showENUnits(typeName) {
showScreen('activity');
document.getElementById('activity-title').innerText = typeName;
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-back-btn').onclick = () => openSubjectMenu(currentSubject);
for (let i = 1; i <= 12; i++) {
createBtn(`Unit ${i}`, content, () => {
initQuiz(`en_unit${i}_${typeName.toLowerCase().replace(' ', '_')}`);
document.getElementById('quiz-back-btn').onclick = () => showENUnits(typeName);
});
}
}
function showENGrammarOptions() {
showScreen('activity');
document.getElementById('activity-title').innerText = "Grammar";
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-back-btn').onclick = () => openSubjectMenu(currentSubject);
// လူကြီးမင်း ပေးထားသော Grammar ခေါင်းစဉ်အသစ်များအားလုံး၏ စာရင်း
const grammarTopics = [
{ title: "Past Simple", id: "past_simple" },
{ title: "Present Simple", id: "present_simple" },
{ title: "Present Continuous", id: "present_continuous" },
{ title: "Past Continuous", id: "past_continuous" },
{ title: "Present Perfect", id: "present_perfect" },
{ title: "Present Perfect Continuous", id: "present_perfect_continuous" },
{ title: "Future Simple", id: "future_simple" },
{ title: "Going To/Will Be", id: "going_to" },
{ title: "Future Continuous", id: "future_continuous" },
{ title: "Used To", id: "used_to" },
{ title: "Modal Auxiliaries", id: "modal_auxiliaries" },
{ title: "Nouns In Apposition", id: "nouns_in_apposition" },
{ title: "Not + Any = No", id: "not_any_no" },
{ title: "Active Voice To Passive Voice", id: "active_passive_voice" },
{ title: "Passive Voice To Active Voice", id: "passive_active_voice" },
{ title: "Impersonal Passive", id: "impersonal_passive" },
// Conditional ၄ မျိုး ခွဲခြားထားခြင်း
{ title: "Zero Conditional", id: "zero_conditional" },
{ title: "First Conditional", id: "first_conditional" },
{ title: "Second Conditional", id: "second_conditional" },
{ title: "Third Conditional", id: "third_conditional" },
{ title: "Subordinating Conjunction", id: "subordinating_conjunction" },
{ title: "Clauses Of Contact", id: "clauses_of_contact" },
{ title: "As If / As Though", id: "as_if_as_though" },
{ title: "Preposition and Conjunction for Purposes", id: "preposition_conjunction_purpose" },
{ title: "Verbs of Cause and Effect", id: "verbs_cause_effect" },
{ title: "Linking Words to Show Cause and Effect", id: "linking_words_cause_effect" },
{ title: "As soon as To No sooner", id: "as_soon_as_no_sooner" },
{ title: "No sooner To As soon as", id: "no_sooner_as_soon_as" },
{ title: "Both ... and", id: "both_and" },
{ title: "Not only ... But also", id: "not_only_but_also" },
{ title: "Neither ... nor", id: "neither_nor" },
{ title: "Either ... or", id: "either_or" },
{ title: "So and Neither", id: "so_and_neither" },
{ title: "So that", id: "so_that" },
{ title: "Such that", id: "such_that" },
{ title: "Too ... to / Enough to", id: "too_to_enough_to" },
{ title: "Before + V-ing", id: "before_ving" },
{ title: "After + V-ing", id: "after_ving" },
{ title: "Without + V-ing", id: "without_ving" },
{ title: "By + V-ing", id: "by_ving" },
{ title: "Introductory Phrases", id: "introductory_phrases" },
{ title: "Participle Phrases", id: "participle_phrases" },
{ title: "Gerund and Infinitive with 'to'", id: "gerund_infinitive" },
{ title: "Verbs followed by a noun group", id: "verbs_followed_by_noun_group" },
{ title: "Joining Sentences Using Relative Pronouns", id: "joining_relative_pronouns" },
{ title: "Omission Of Relative Pronouns", id: "omission_relative_pronouns" },
{ title: "It is / It was", id: "it_is_it_was" },
{ title: "Double Negative Structure", id: "double_negative_structure" },
{ title: "No Matter", id: "no_matter" },
{ title: "Omission of Verbs", id: "omission_of_verbs" },
{ title: "The more / The less", id: "the_more_the_less" },
{ title: "As ... As", id: "as_as" },
{ title: "Not as ... as", id: "not_as_as" },
{ title: "Inversion (Full Verb Before Subject)", id: "inversion_full_verb" },
{ title: "As and Like", id: "as_and_like" }
];
// ခလုတ်များ အလိုအလျောက် တည်ဆောက်ပြီး openFlashcard သို့ ချိတ်ဆက်ပေးခြင်း
grammarTopics.forEach(topic => {
createBtn(topic.title, content, () => showGrammarMenu(topic.id, topic.title));
});
}
function showGrammarMenu(topicId, topicTitle) {
showScreen('activity');
document.getElementById('activity-title').innerText = topicTitle;
const content = document.getElementById('activity-content');
content.innerHTML = '';
// နောက်သို့ = Grammar ခေါင်းစဉ်ရွေးစရာကို ပြန်သွား
document.getElementById('activity-back-btn').onclick = () => showENGrammarOptions();
// Grammar Note ခလုတ်
createBtn("📖 Grammar Note", content, () => {
loadGrammarNote(topicId, topicTitle);
});
// လေ့ကျင့်ရန် ခလုတ်
createBtn("✏️ လေ့ကျင့်ရန်", content, () => {
initFlashcards(topicId, topicTitle);
// Flashcard ထွက်ရင် Grammar Menu ကို ပြန်သွား
const flashExitBtn = document.querySelector('#flashcard-screen .back-btn');
flashExitBtn.onclick = () => {
showScreen('activity');
showGrammarMenu(topicId, topicTitle);
};
});
}
async function loadGrammarNote(topicId, topicTitle) {
try {
const res = await fetch(`./notes/grammar_${topicId}.json`);
if (!res.ok) throw new Error();
const noteData = await res.json();
showScreen('grammar-note');
document.getElementById('grammar-note-title').innerText = topicTitle + " - Grammar Note";
document.getElementById('grammar-note-content').innerHTML = noteData.content;
document.getElementById('grammar-note-screen').scrollTop = 0;
if (window.MathJax) MathJax.typesetPromise();
} catch (e) {
tg.showAlert("Grammar Note ဖိုင်မတွေ့သေးပါ - " + topicId);
}
}
function showENPoemOptions() {
showScreen('activity');
document.getElementById('activity-title').innerHTML = "Poems";
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-back-btn').onclick = () => {
const userId = tg.initDataUnsafe?.user?.id || 0;
const isSpecial = specialUsers.includes(userId);
// ပြင်ဆင်ချက်: subId အစား currentSubject.id ကို အသုံးပြုထားပါသည်
const currentId = currentSubject.id;
const isSpecialSubject = isSpecial && (['mm', 'en', 'math', 'phy', 'chem'].includes(currentId) || currentId === 'bio' || currentId === 'eco');
// checkAccess ကိုလည်း currentId ဖြင့်သာ စစ်ဆေးပါမည်
if (checkAccess(currentId) || isSpecialSubject) {
openSubjectMenu(currentSubject);
} else {
openTrialMenu();
}
};
// ကဗျာ (၄) ပုဒ်၏ စာသားအပြည့်အစုံ
const poemsData = {
"The Library": `
It looks like any building
When you pass it on the street,
Made of stone and glass and marble,
Made of iron and concrete.
But once inside you can ride
A camel or a train,
Visit Rome, Siam, or Nome,
Feel a hurricane,
Meet a king, learn to sing,
How to bake a pie,
Go to sea, plant a tree,
Find how airplanes fly,
Train a horse, and of course
Have all the dogs you’d like,
See the moon, a sandy dune,
Or catch a whopping pike.
Everything that books can bring
You’ll find inside these walls.
A world is there for you to share
When adventure calls.
You cannot tell its magic
By the way the building looks,
But there’s wonderment within it,
The wonderment of books.
by Barbara A. Huff
`,
"The Quiet Life": `
Happy the man, whose wish and care
A few paternal acres bound,
Content to breathe his native air,
In his own ground.
Whose herds with milk, whose fields with bread,
Whose flocks supply him with attire,
Whose trees in summer yield him shade,
In winter fire.
Blest, who can unconcernedly find
Hours, days, and years slide soft away,
In health of body, peace of mind,
Quiet by day,
Sound sleep by night; study and ease,
Together mixed; sweet recreation;
And innocence, which most does please,
With meditation.
Thus let me live, unseen, unknown;
Thus unlamented let me die;
Steal from the world, and not a stone
Tell where I lie.
by Alexander Pope
`,
"The Road Not Taken": `
Two roads diverged in a yellow wood,
And sorry I could not travel both
And be one traveler, long I stood
And looked down one as far as I could
To where it bent in the undergrowth;
Then took the other, as just as fair,
And having perhaps the better claim,
Because it was grassy and wanted wear;
Though as for that the passing there
Had worn them really about the same,
And both that morning equally lay
In leaves no step had trodden black.
Oh, I kept the first for another day!
Yet knowing how way leads on to way,
I doubted if I should ever come back.
I shall be telling this with a sigh
Somewhere ages and ages hence:
Two roads diverged in a wood, and I—
I took the one less traveled by,
And that has made all the difference.
by Robert Frost
`,
"Windy Nights": `
Whenever the moon and stars are set,
Whenever the wind is high,
All night long in the dark and wet,
A man goes riding by.
Late in the night when the fires are out,
Why does he gallop and gallop about?
Whenever the trees are crying aloud,
And ships are tossed at sea,
By, on the highway, low and loud,
By at the gallop goes he.
By at the gallop he goes, and then
By he comes back at the gallop again.
by Robert Louis Stevenson
`
};
// ကဗျာခေါင်းစဉ်များဖြင့် ခလုတ်များ ဖန်တီးခြင်း
["The Library", "The Quiet Life", "The Road Not Taken", "Windy Nights"].forEach(p => createBtn(p, content, () => {
showScreen('poem');
document.getElementById('poem-title').innerText = p;
// poemsData ထဲမှ ကဗျာစာသားများကို ယူ၍ ပြသခြင်း
document.getElementById('poem-body').innerHTML = poemsData[p] || "
ကဗျာစာသား မရှိသေးပါ။
";
}));
}
// စကားပြေနှင့် ကဗျာ ခေါင်းစဉ် (၈) မျိုးစီကို Array အဖြစ် ကြိုတင်သတ်မှတ်ထားခြင်း
const proseTitles = ['ညောင်ရမ်းကြီးသမီး', 'သစ္စာနှင့်ပညာ', 'ခေတ်', 'မလုပ်မစား', 'စာဘူးတောင်း', 'ဦးဖေမောင်တင်', 'အဖြူနှင့်အနက်', 'စိတ်ဓာတ်ရင့်ကျက်တည်ငြိမ်ခြင်း'];
const poetryTitles = ['ပေါ်နွေလလျှင်', 'ငါ့ကိုလွယ်အမယ်ကြီးနှင့်', 'ဩဝါဒထူးပျို့', 'ပေါင်းရှစ်ယောက်ကောက်စိုက်သူ', 'အညာမင်္ဂလာဆောင်', 'ကမ္ဗောဇသို့', 'လက်ဖက်ရည်ကြမ်းဝိုင်း', 'ပဒေသာလက်ရာ'];
function showMMQuizOptions(typeName) {
showScreen('activity');
document.getElementById('activity-title').innerText = typeName;
const content = document.getElementById('activity-content');
content.innerHTML = '';
// Back button နှိပ်ပါက Subject Menu သို့ ပြန်သွားရန်
document.getElementById('activity-back-btn').onclick = () => openSubjectMenu(currentSubject);
['အပြော', 'စကားပြေ' , 'ကဗျာ' , 'ရေသည်', 'အရေး',].forEach(cat => {
createBtn(cat, content, () => {
if (cat === 'စကားပြေ') {
// စကားပြေကို ရွေးချယ်ပါက စကားပြေ ခေါင်းစဉ် ၈ မျိုး ထပ်ပြရန်
showSubMenu(typeName, cat, proseTitles);
} else if (cat === 'ကဗျာ') {
// ကဗျာကို ရွေးချယ်ပါက ကဗျာ ခေါင်းစဉ် ၈ မျိုး ထပ်ပြရန်
showSubMenu(typeName, cat, poetryTitles);
} else if (cat === 'ရေသည်') {
const fileName = `mm_ရေသည်_${typeName}`.replace(/\//g, "_").replace(/ /g, "_");
initQuiz(fileName); // ✅ initFlashcards ကို initQuiz အစားထိုး
document.getElementById('quiz-back-btn').onclick = () => { showScreen('activity'); showMMQuizOptions(typeName); };
} else {
// အပြော နှင့် အရေး အတွက် မူလအတိုင်း ဆက်သွားရန်
{ showMMChapters(typeName, cat) };
document.getElementById('quiz-back-btn').onclick = () => showMMQuizOptions(typeName);
}
});
});
}
// အပြော နှင့် အရေး အတွက် အခန်းခွဲများကို ပြသမည့် Function အသစ်
function showMMChapters(typeName, cat) {
showScreen('activity');
document.getElementById('activity-title').innerText = `${cat} (${typeName})`;
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-back-btn').onclick = () => showMMQuizOptions(typeName);
// 🆕 GREEN "All" button (e.g. "အပြောအကုန်လေ့ကျင့်မည်")
const allBtn = document.createElement('button');
allBtn.className = 'btn';
allBtn.innerText = `${cat}အကုန်လေ့ကျင့်မည်`;
allBtn.style.background = '#00FF80';
allBtn.style.color = '#000000';
allBtn.style.border = 'none';
allBtn.style.boxShadow = '0 4px 15px rgba(0, 213, 255, 0.3)';
allBtn.style.marginBottom = '5px';
allBtn.style.fontWeight = 'bold';
allBtn.style.gridColumn = '1 / -1';
allBtn.onclick = () => {
const fileName = `mm_${cat}_all_${typeName}`.replace(/\//g, "_").replace(/ /g, "_");
initQuiz(fileName);
document.getElementById('quiz-back-btn').onclick = () => showMMChapters(typeName, cat);
};
content.appendChild(allBtn);
['အခန်း ၁', 'အခန်း ၂', 'အခန်း ၃'].forEach(chapter => {
createBtn(chapter, content, () => {
const fileName = `mm_${cat}_${chapter}_${typeName}`.replace(/\//g, "_").replace(/ /g, "_");
initQuiz(fileName);
document.getElementById('quiz-back-btn').onclick = () => showMMChapters(typeName, cat);
});
});
}
// ခေါင်းစဉ်ခွဲ (Sub Menu) များကို ပြသပေးမည့် Function အသစ်
function showSubMenu(typeName, cat, titles) {
showScreen('activity');
document.getElementById('activity-title').innerText = cat;
const content = document.getElementById('activity-content');
content.innerHTML = '';
// ခေါင်းစဉ်ခွဲများမှ Back button နှိပ်ပါက မူလ ရွေးချယ်သည့်နေရာသို့ ပြန်သွားရန်
document.getElementById('activity-back-btn').onclick = () => showMMQuizOptions(typeName);
// 🆕 GREEN "All" button (e.g. "စကားပြေအကုန်လေ့ကျင့်မည်")
const allBtn = document.createElement('button');
allBtn.className = 'btn';
allBtn.innerText = `${cat}အကုန်လေ့ကျင့်မည်`;
allBtn.style.background = '#00FF80';
allBtn.style.color = '#000000';
allBtn.style.border = 'none';
allBtn.style.boxShadow = '0 4px 15px rgba(0, 213, 255, 0.3)';
allBtn.style.marginBottom = '5px';
allBtn.style.fontWeight = 'bold';
allBtn.style.gridColumn = '1 / -1';
allBtn.onclick = () => {
const fileName = `mm_${cat}_all_${typeName}`.replace(/\//g, "_").replace(/ /g, "_");
initQuiz(fileName);
document.getElementById('quiz-back-btn').onclick = () => {
showScreen('activity');
showSubMenu(typeName, cat, titles);
};
};
content.appendChild(allBtn);
titles.forEach(title => {
createBtn(title, content, () => {
const fileName = `mm_${cat}_${title}_${typeName}`.replace(/\//g, "_").replace(/ /g, "_");
initQuiz(fileName);
document.getElementById('quiz-back-btn').onclick = () => {
showScreen('activity');
showSubMenu(typeName, cat, titles);
};
});
});
}
function showMMFlashcardOptions(typeName) {
showScreen('activity');
document.getElementById('activity-title').innerText = typeName;
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-back-btn').onclick = () => openSubjectMenu(currentSubject);
if (typeName === "အလင်္ကာ") {
// အလင်္ကာအတွက် သီးသန့်ခွဲထားသော ခလုတ် (၅) ခု
createBtn("ဥပမာအလင်္ကာ", content, () => initFlashcards("mm_ဥပမာအလင်္ကာ"));
createBtn("ရူပကအလင်္ကာ", content, () => initFlashcards("mm_ရူပကအလင်္ကာ"));
createBtn("ဝင်္ကဝုတ္တိအလင်္ကာ", content, () => initFlashcards("mm_ဝင်္ကဝုတ္တိအလင်္ကာ"));
createBtn("အတိယဝုတ္တိအလင်္ကာ", content, () => initFlashcards("mm_အတိသယဝုတ္တိအလင်္ကာ"));
createBtn("မြည်သံစွဲအလင်္ကာ", content, () => initFlashcards("mm_မြည်သံစွဲအလင်္ကာ"));
} else {
// ကျန်တဲ့ စကားပြေ၊ ကဗျာ၊ ရေသည် များအတွက် မူလအတိုင်း
createBtn("စကားပြေ", content, () => showMMSubTopics(typeName, "စကားပြေ"));
createBtn("ကဗျာ", content, () => showMMSubTopics(typeName, "ကဗျာ"));
createBtn("ရေသည်", content, () => initFlashcards("mm_ရေသည်_ခက်ဆစ်"));
}
}
function showMMSubTopics(typeName, category) {
showScreen('activity');
const content = document.getElementById('activity-content');
content.innerHTML = `
${category} (${typeName}) `;
document.getElementById('activity-back-btn').onclick = () => showMMFlashcardOptions(typeName);
let topics = [];
if (category === "စကားပြေ") {
topics = ["ညောင်ရမ်းကြီးသမီး", "သစ္စာနှင့်ပညာ", "ခေတ်", "မလုပ်မစား", "စာဘူးတောင်း", "ဦးဖေမောင်တင်", "အဖြူနှင့်အနက်", "စိတ်ဓာတ်ရင့်ကျက်တည်ငြိမ်ခြင်း"];
} else if (category === "ကဗျာ") {
topics = ["ပေါ်နွေလလျှင်", "ငါ့ကိုလွယ်အမယ်ကြီးနှင့်", "ဩဝါဒထူးပျို့", "ပေါင်းရှစ်ယောက် ကောက်စိုက်သူ", "အညာမင်္ဂလာဆောင်", "ကမ္ဗောဇသို့", "လက်ဖက်ရည်ကြမ်းဝိုင်း", "ပဒေသာလက်ရာ"];
}
topics.forEach(t => {
createBtn(t, content, () => {
const fName = `${currentSubject.id}_${category}_${typeName}_${t}`.replace(/ /g, "_");
initFlashcards(fName);
});
});
}
// --- Sub-Chapters ပြသမည့် Menu အသစ် ---
function showSubChaptersMenu(subId, chapterName) {
showScreen('activity');
document.getElementById('activity-title').innerText = chapterName;
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-back-btn').onclick = () => {
const userId = tg.initDataUnsafe?.user?.id || 0;
const isSpecial = specialUsers.includes(userId);
const isSpecialSubject = isSpecial && (['mm', 'en', 'math', 'phy', 'chem'].includes(subId) || subId === 'bio' || subId === 'eco');
if (checkAccess(subId) || isSpecialSubject) {
openSubjectMenu(currentSubject);
} else {
openTrialMenu();
}
};
// 1) Quiz types
['True_False', 'Fill_Blank', 'MCQ'].forEach(type => {
createBtn(type.replace('_', ' '), content, () => {
showQuizSubChapters(subId, chapterName, type);
});
});
// 2) Definition (Physics & Economy only)
if (subId === 'phy' || subId === 'eco') {
createBtn("Definition", content, () => {
loadDefinitions(subId, chapterName);
});
}
// 3) Formula (Physics all chapters, Economy only ch 1,2,3,7)
if (subId === 'phy') {
createBtn("Formula", content, () => {
loadFormulas(subId, chapterName);
});
}
// 4) Key terms (Chemistry only)
if (subId === 'chem') {
createBtn("Key terms", content, () => {
loadKeyTerms(subId, chapterName);
});
}
}
function isFormulaChapter(chapterName) {
const num = parseInt(chapterName.replace(/\D/g, ''));
return [1, 2, 3, 7].includes(num);
}
function showQuizSubChapters(subId, chapterName, quizType) {
showScreen('activity');
document.getElementById('activity-title').innerText = `${chapterName} - ${quizType.replace('_', ' ')}`;
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-back-btn').onclick = () => showSubChaptersMenu(subId, chapterName);
const fullBtn = document.createElement('button');
fullBtn.className = 'btn';
fullBtn.innerText = "တစ်ခန်းလုံးလေ့ကျင့်ရန်";
fullBtn.style.gridColumn = "1 / -1";
fullBtn.style.background = "#00FF80";
fullBtn.style.color = "#000000";
fullBtn.style.border = "none";
fullBtn.style.boxShadow = "0 4px 15px rgba(0, 213, 255, 0.3)";
fullBtn.style.marginBottom = "5px";
fullBtn.style.fontWeight = "bold";
fullBtn.onclick = () => {
const fileName = `${subId}_${chapterName}_${quizType}`.replace(/ /g, "_");
initQuiz(fileName);
document.getElementById('quiz-back-btn').onclick = () => showQuizSubChapters(subId, chapterName, quizType);
};
content.appendChild(fullBtn);
const subChapters = (subChapterConfig[subId] && subChapterConfig[subId][chapterName]) || [];
subChapters.forEach(subChap => {
createBtn(subChap, content, () => {
const activityPartName = `${chapterName}_${subChap}`;
const fileName = `${subId}_${activityPartName}_${quizType}`.replace(/ /g, "_");
initQuiz(fileName);
document.getElementById('quiz-back-btn').onclick = () => showQuizSubChapters(subId, chapterName, quizType);
});
});
}
async function loadDefinitions(subId, chapterName) {
try {
const fileName = `${subId}_${chapterName}_definition`.replace(/ /g, "_");
const res = await fetch(`./quizzes/${fileName}.json`);
if (!res.ok) throw new Error();
const data = await res.json();
showScreen('activity');
document.getElementById('activity-title').innerText = `${chapterName} - Definitions`;
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-back-btn').onclick = () => showSubChaptersMenu(subId, chapterName);
data.forEach((item, index) => {
createBtn(item.title, content, () => {
showDefinitionDetail(subId, chapterName, data, index);
});
});
} catch (e) {
tg.showAlert("Definition file not found for " + chapterName);
}
}
function showDefinitionDetail(subId, chapterName, data, index) {
showScreen('activity');
document.getElementById('activity-title').innerText = data[index].title;
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-back-btn').onclick = () => loadDefinitions(subId, chapterName);
const div = document.createElement('div');
div.style.cssText = 'grid-column: 1 / -1; background: var(--detail-bg); padding: 25px; border-radius: 16px; border: 1px solid var(--detail-border); line-height: 1.8; color: var(--detail-text); white-space: pre-wrap; font-size: 1.05rem; text-align: center; box-sizing: border-box; width: 100%;';
div.innerText = data[index].content;
content.appendChild(div);
}
async function loadKeyTerms(subId, chapterName) {
try {
const fileName = `${subId}_${chapterName}_definition`.replace(/ /g, "_");
const res = await fetch(`./quizzes/${fileName}.json`);
if (!res.ok) throw new Error();
const data = await res.json();
showScreen('activity');
document.getElementById('activity-title').innerText = `${chapterName} - Key Terms`;
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-back-btn').onclick = () => showSubChaptersMenu(subId, chapterName);
data.forEach((item, index) => {
createBtn(item.title, content, () => {
showKeyTermDetail(subId, chapterName, data, index);
});
});
} catch (e) {
tg.showAlert("Key terms file not found for " + chapterName);
}
}
function showKeyTermDetail(subId, chapterName, data, index) {
showScreen('activity');
document.getElementById('activity-title').innerText = data[index].title;
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-back-btn').onclick = () => loadKeyTerms(subId, chapterName);
const div = document.createElement('div');
div.style.cssText = 'grid-column: 1 / -1; background: var(--detail-bg); padding: 25px; border-radius: 16px; border: 1px solid var(--detail-border); line-height: 1.8; color: var(--detail-text); white-space: pre-wrap; font-size: 1.05rem; text-align: center; box-sizing: border-box; width: 100%;';
div.innerText = data[index].content;
content.appendChild(div);
}
function wrapLatex(formula) {
formula = formula.trim();
// Already wrapped? Leave it alone
if (formula.startsWith('\\(') && formula.endsWith('\\)')) return formula;
if (formula.startsWith('$') && formula.endsWith('$')) return formula;
if (formula.startsWith('\\[') && formula.endsWith('\\]')) return formula;
if (formula.startsWith('$$') && formula.endsWith('$$')) return formula;
// Otherwise wrap with inline math delimiters
return `\\(${formula}\\)`;
}
async function loadFormulas(subId, chapterName) {
try {
const fileName = `${subId}_${chapterName}_formula`.replace(/ /g, "_");
const res = await fetch(`./quizzes/${fileName}.json`);
if (!res.ok) throw new Error();
const data = await res.json();
showScreen('activity');
document.getElementById('activity-title').innerText = `${chapterName} - Formulas`;
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-back-btn').onclick = () => showSubChaptersMenu(subId, chapterName);
data.forEach(item => {
const card = document.createElement('div');
card.style.cssText = `
grid-column: 1 / -1;
background: var(--detail-bg);
padding: 20px;
border-radius: 16px;
margin-bottom: 12px;
border: 1px solid var(--detail-border);
width: 100%;
box-sizing: border-box;
`;
card.innerHTML = `
${wrapLatex(item.name)}
${item.content}
`;
content.appendChild(card);
});
if (window.MathJax && MathJax.typesetPromise) {
await MathJax.typesetPromise([content]);
}
} catch (e) {
tg.showAlert("Formula file not found for " + chapterName);
}
}
function showPhyChemActivities(subId, partName, parentChapter = null) {
showScreen('activity');
// အခန်းခွဲ (e.g., Chapter 1_1.1) ဖြစ်နေလျှင် 1.1 ကိုသာ ခေါင်းစဉ်တပ်ရန်
let displayTitle = partName.includes('_') ? partName.split('_')[1] : partName;
document.getElementById('activity-title').innerText = displayTitle;
const content = document.getElementById('activity-content');
content.innerHTML = '';
// နောက်သို့နှိပ်လျှင် သက်ဆိုင်ရာ SubChapter Menu သို့ ပြန်သွားရန်
document.getElementById('activity-back-btn').onclick = () => {
if (parentChapter) {
showSubChaptersMenu(subId, parentChapter);
} else {
openSubjectMenu(currentSubject);
}
};
['True_False', 'Fill_Blank', 'MCQ'].forEach(type => {
createBtn(type.replace('_', ' '), content, () => {
initQuiz(`${subId}_${partName}_${type}`.replace(/ /g, "_"));
// Quiz ကနေ ပြန်ထွက်လျှင် လက်ရှိ menu သို့ ပြန်လာရန်
document.getElementById('quiz-back-btn').onclick = () => showPhyChemActivities(subId, partName, parentChapter);
});
});
}
// --- Trial System Functions ---
function openTrialMenu() {
setOldQuestionContext(false);
showScreen('activity');
document.getElementById('activity-title').innerText = "Free Trial (စမ်းသုံးရန်)";
const content = document.getElementById('activity-content');
content.innerHTML = '';
// ပင်မစာမျက်နှာသို့ ပြန်သွားရန်
document.getElementById('activity-back-btn').onclick = () => showScreen('home');
subjects.forEach(sub => {
createBtn(`${sub.name} (Trial)`, content, () => {
currentSubject = sub;
if (sub.id === 'mm') {
showMyanmarTrialParts();
} else if (sub.id === 'en') {
showENPoemOptions();
// Back Button ကို Trial Menu သို့ ပြန်လှည့်
document.getElementById('activity-back-btn').onclick = () => openTrialMenu();
} else {
if (sub.id === 'math') {
showGeneralActivities(sub.id, 'Chapter 1');
} else {
showSubChaptersMenu(sub.id, 'Chapter 1');
}
// back btn onclick ကို ဒီမှာ ထပ်မရေးတော့ပါ။ အတွင်းမှ function က အလိုအလျောက် Trial ကို ပြန်ပို့ပေးပါမည်။
}
});
});
}
function showMyanmarTrialParts() {
const content = document.getElementById('activity-content');
content.innerHTML = '';
document.getElementById('activity-title').innerText = "မြန်မာစာ ခက်ဆစ် (Trial)";
document.getElementById('activity-back-btn').onclick = () => openTrialMenu();
const mmTrialItems = [
{ name: "စကားပြေ (ညောင်ရမ်းကြီးသမီး)", file: "mm_စကားပြေ_ခက်ဆစ်_ညောင်ရမ်းကြီးသမီး" },
{ name: "စကားပြေ (သစ္စာနှင့်ပညာ)", file: "mm_စကားပြေ_ခက်ဆစ်_သစ္စာနှင့်ပညာ" },
{ name: "စကားပြေ (ခေတ်)", file: "mm_စကားပြေ_ခက်ဆစ်_ခေတ်" },
{ name: "ကဗျာ (ပေါ်နွေလလျှင်)", file: "mm_ကဗျာ_ခက်ဆစ်_ပေါ်နွေလလျှင်" },
{ name: "ကဗျာ (ငါ့ကိုလွယ်အမယ်ကြီးနှင့်)", file: "mm_ကဗျာ_ခက်ဆစ်_ငါ့ကိုလွယ်အမယ်ကြီးနှင့်" },
{ name: "ကဗျာ (ဩဝါဒထူးပျို့)", file: "mm_ကဗျာ_ခက်ဆစ်_ဩဝါဒထူးပျို့" },
{ name: "ရေသည်ပြဇာတ် (ခက်ဆစ်)", file: "mm_ရေသည်ပြဇာတ်_ခက်ဆစ်_ရေသည်" }
];
mmTrialItems.forEach(item => {
createBtn(item.name, content, () => {
initFlashcards(item.file);
// Flashcard ထဲက ထွက်ရင် မြန်မာစာ Trial menu ကို ပြန်လာရန်
const flashExitBtn = document.querySelector('#flashcard-screen .back-btn');
flashExitBtn.onclick = () => {
showScreen('activity');
showMyanmarTrialParts();
};
});
});
}
// --- Flashcard Engine ---
let currentFlashMark = ""; // ခေါင်းစဉ်မှတ်ရန် variable အသစ်
async function initFlashcards(fileName, markTitle = "Flashcard") {
currentFlashMark = markTitle; // လက်ရှိနှိပ်လိုက်တဲ့ Mark နာမည်ကို သိမ်းမယ်
try {
const res = await fetch(`./quizzes/${fileName}.json`);
if(!res.ok) throw new Error();
flashCards = await res.json();
flashIdx = 0;
showScreen('flashcard');
updateFlashUI();
} catch (e) { tg.showAlert("ဖိုင်မတွေ့သေးပါ- " + fileName); }
}
function updateFlashUI() {
const card = document.getElementById('flash-card');
card.classList.remove('is-flipped');
// ခေါင်းစဉ်ကို ပြောင်းလဲပေးခြင်း
document.getElementById('flash-title').innerText = currentFlashMark;
// innerText ကို innerHTML သို့ ပြောင်းလဲခြင်း (Messy ဖြစ်တာကို ရှင်းဖို့)
document.getElementById('flash-front-content').innerHTML = flashCards[flashIdx].q;
document.getElementById('flash-back-content').innerHTML = flashCards[flashIdx].a;
document.getElementById('flash-count').innerText = `${flashIdx + 1} / ${flashCards.length}`;
if (window.MathJax) MathJax.typesetPromise();
}
function flipCard() {
document.getElementById('flash-card').classList.toggle('is-flipped');
}
function nextFlash() {
if (flashIdx < flashCards.length - 1) { flashIdx++; updateFlashUI(); }
}
function prevFlash() {
if (flashIdx > 0) { flashIdx--; updateFlashUI(); }
}
function showGeneralActivities(subId, partName, parentChapter = null) {
showScreen('activity');
// အခန်းခွဲ ဖြစ်နေလျှင် ဖြတ်ထုတ်ပြသရန်
let displayTitle = partName.includes('_') ? partName.split('_')[1] : partName;
document.getElementById('activity-title').innerText = displayTitle;
const content = document.getElementById('activity-content');
content.innerHTML = '';
// နောက်သို့နှိပ်လျှင် သက်ဆိုင်ရာ နေရာများသို့ ပြန်သွားရန်
document.getElementById('activity-back-btn').onclick = () => {
if (parentChapter) {
showSubChaptersMenu(subId, parentChapter);
} else {
const userId = tg.initDataUnsafe?.user?.id || 0;
const isSpecial = specialUsers.includes(userId);
const isSpecialSubject = isSpecial && (['mm', 'en', 'math', 'phy', 'chem'].includes(subId) || subId === 'bio' || subId === 'eco');
if (checkAccess(subId) || isSpecialSubject) {
openSubjectMenu(currentSubject);
} else {
openTrialMenu();
}
}
};
if(subId === 'math') {
let mathMarks = ['1_Mark', '2_Marks', '3_Marks'];
if (partName === 'Chapter 2') {
mathMarks = ['3_Marks'];
}
mathMarks.forEach(mark => {
createBtn(mark.replace('_', ' '), content, () => {
const fileName = `math_${partName}_${mark}`.replace(/ /g, "_");
initQuiz(fileName);
document.getElementById('quiz-back-btn').onclick = () => showGeneralActivities(subId, partName, parentChapter);
});
});
} else {
let types = ['True_False', 'Fill_Blank', 'MCQ'];
types.forEach(type => {
createBtn(type.replace('_', ' '), content, () => {
const fileName = `${subId}_${partName}_${type}`.replace(/ /g, "_");
if (type === 'Definition') {
initFlashcards(fileName, "Definition");
const flashExitBtn = document.querySelector('#flashcard-screen .back-btn');
flashExitBtn.onclick = () => { showScreen('activity'); showGeneralActivities(subId, partName, parentChapter); };
} else {
initQuiz(fileName);
document.getElementById('quiz-back-btn').onclick = () => showGeneralActivities(subId, partName, parentChapter);
}
});
});
}
}
// --- Quiz Engine ---
async function initQuiz(fileName) {
currentQuizFile = fileName;
try {
const res = await fetch(`./quizzes/${fileName}.json`);
if(!res.ok) throw new Error();
let data = await res.json();
// Local Storage မှ Setting ကို ဆွဲယူစစ်ဆေးခြင်း (Default အနေဖြင့် ကျပန်းကိုသာ ထားမည်)
const isRandom = localStorage.getItem('randomQuizSetting') !== 'false';
// အသုံးပြုသူ ရွေးချယ်မှုပေါ် မူတည်၍ Random လုပ်/မလုပ် ဆုံးဖြတ်ခြင်း
if (isRandom) {
currentQuestions = shuffleArray(data);
} else {
currentQuestions = [...data]; // မူရင်း အစဉ်လိုက်အတိုင်းထားမည်
}
currentIdx = 0;
showScreen('quiz');
loadQuestion();
} catch (e) { tg.showAlert("မေးခွန်းဖိုင်မတွေ့သေးပါ- " + fileName); }
}
function loadQuestion() {
isAnswered = false;
const nextBtn = document.getElementById('next-btn');
// Always show next button so users can skip for speedrunning
nextBtn.style.display = 'block';
nextBtn.className = 'btn';
nextBtn.innerText = 'နောက်တစ်ပုဒ်သို့ ➔'; // Reset to default class first
const isMath2Or3Mark = currentQuizFile && (currentQuizFile.includes('2_Marks') || currentQuizFile.includes('3_Marks'));
const scoreDisplay = document.getElementById('score-display');
if (isMath2Or3Mark) {
scoreDisplay.style.display = 'none';
} else {
scoreDisplay.style.display = 'inline-block';
}
const timerWrapper = document.getElementById('timer-wrapper');
if (isMath2Or3Mark) {
timerWrapper.style.display = 'none';
if (isTimerRunning) resetTimer();
} else {
timerWrapper.style.display = 'flex';
}
const q = currentQuestions[currentIdx];
// Progress နှင့် မေးခွန်းပြသခြင်း
document.getElementById('quiz-progress').innerHTML = `${currentIdx + 1} / ${currentQuestions.length}`;
document.getElementById('question-box').innerHTML = q.q;
const optDiv = document.getElementById('quiz-options');
optDiv.innerHTML = '';
// သင်္ချာမေးခွန်းအတွက် ကြိုတင်သတ်မှတ်ချက်
if (currentSubject.id === 'math' && (q.type === undefined || q.type === 'math_show')) {
q.type = 'math_show';
}
// --- ၁။ သင်္ချာမေးခွန်းဖြစ်မဖြစ် စစ်ဆေးခြင်း ---
if (q.type === 'math_show') {
const showBtn = document.createElement('button');
showBtn.className = 'btn';
showBtn.innerText = "အဖြေကြည့်ရန်";
showBtn.onclick = function() {
// Screen အသစ်ကို ပြောင်းမည်
showScreen('math-solution');
document.getElementById('math-solution-content').innerHTML = q.c;
if (window.MathJax) MathJax.typesetPromise();
// အပေါ်ဆုံးသို့ scroll လုပ်ရန်
document.getElementById('math-solution-screen').scrollTop = 0;
window.scrollTo(0, 0);
// နောက်သို့ (မေးခွန်း ပြန်ကြည့်ရန်)
document.getElementById('math-prev-btn').onclick = () => {
showScreen('quiz');
};
// ရှေ့သို့ (နောက်တစ်ပုဒ် သွားရန်)
const mathNextBtn = document.getElementById('math-next-btn');
if (currentIdx < currentQuestions.length - 1) {
mathNextBtn.style.display = 'block';
mathNextBtn.onclick = () => {
currentIdx++;
showScreen('quiz');
loadQuestion();
};
} else {
mathNextBtn.style.display = 'block';
mathNextBtn.innerText = 'ပြီးဆုံးပါပြီ ✅';
mathNextBtn.onclick = () => {
tg.showAlert("ဂုဏ်ယူပါသည်။ မေးခွန်းများအားလုံး ဖြေဆိုပြီးပါပြီ 🎉");
submitScore(); // ⬅️ Log view-only completion
document.getElementById('quiz-back-btn').click();
};
}
// ထွက်မည် (Menu သို့ ပြန်သွားရန်)
document.getElementById('math-exit-btn').onclick = () => {
document.getElementById('quiz-back-btn').click();
};
};
optDiv.appendChild(showBtn);
}
// --- ၂။ အခြားပုံမှန် မေးခွန်းများ (MCQ, True/False) ---
else if (q.type === 'mcq' || q.type === 'tf') {
let opts = [];
let correctIdx = 0;
if (q.type === 'tf') {
opts = ["မှန် (TRUE)", "မှား (FALSE)"];
correctIdx = (q.c === true || q.c === "true" || q.c === 0 || q.c === "မှန်") ? 0 : 1;
} else {
let originalCorrectAnswer = String(q.a[q.c]).trim();
opts = [...q.a];
// ရွေးချယ်စရာများကို မွှေနှောက်ခြင်း
for (let i = opts.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[opts[i], opts[j]] = [opts[j], opts[i]];
}
correctIdx = opts.map(opt => String(opt).trim()).indexOf(originalCorrectAnswer);
if (correctIdx === -1) {
console.error("အဖြေမှန်စာသားကို ရှာမတွေ့ပါ");
opts = [...q.a];
correctIdx = q.c;
}
}
opts.forEach((a, i) => {
const btn = document.createElement('button');
btn.className = 'btn option-btn';
btn.innerHTML = a;
btn.onclick = () => {
if(isAnswered) return;
isAnswered = true;
const options = document.querySelectorAll('.option-btn');
// အဖြေမှန်/မှား စစ်ဆေးခြင်း
if (i === correctIdx) {
options[i].classList.add('correct-answer');
// မှန်ရင် ရမှတ်တိုးမည်
if (typeof score !== 'undefined') {
score++;
document.getElementById('score-display').innerText = `ရမှတ်: ${score}`;
}
} else {
options.forEach((b, idx) => {
if(idx === correctIdx) b.classList.add('correct-answer');
else if(idx === i) b.classList.add('wrong-answer');
});
}
// ခလုတ်အားလုံးကို ပိတ်မည်
options.forEach(b => b.disabled = true);
// Next Button ကို Display ပေးပြီး ပုံစံပြောင်းမည်
const nextBtnStyled = document.getElementById('next-btn');
nextBtnStyled.style.display = 'block';
nextBtnStyled.className = 'next-btn-styled';
nextBtnStyled.innerText = 'နောက်တစ်ပုဒ်သို့ ⮕';
};
optDiv.appendChild(btn);
});
}
// --- ၃။ ကွက်လပ်ဖြည့် ---
else if (q.type === 'blank') {
const input = document.createElement('input');
input.className = 'quiz-input';
input.placeholder = "အဖြေရိုက်ထည့်ပါ...";
const sBtn = document.createElement('button');
sBtn.className = 'btn';
sBtn.style.width = '100%';
sBtn.innerText = "အဖြေစစ်မည်";
sBtn.onclick = () => {
if(isAnswered) return;
isAnswered = true;
if(input.value.trim().toLowerCase() === q.c.toString().toLowerCase()) {
tg.showAlert("မှန်ကန်ပါသည်။ ✅");
// မှန်ရင် ရမှတ်တိုးမည်
if (typeof score !== 'undefined') {
score++;
document.getElementById('score-display').innerText = `ရမှတ်: ${score}`;
}
} else {
tg.showAlert("အဖြေမှန်မှာ: " + q.c + "\nအခြားသောအဖြေမှန်များလည်းရှိနိုင်ပါသည်");
}
const nextBtnStyled = document.getElementById('next-btn');
nextBtnStyled.style.display = 'block';
nextBtnStyled.className = 'next-btn-styled';
nextBtnStyled.innerText = 'နောက်တစ်ပုဒ်သို့ ⮕';
};
optDiv.append(input, sBtn);
}
if (window.MathJax) MathJax.typesetPromise();
}
function selectOption(index) {
const q = currentQuestions[currentQuestionIndex];
const options = document.querySelectorAll('.option-btn');
// အကုန်လုံးကို အရင်ပိတ်လိုက်ပါ (ထပ်နှိပ်လို့မရအောင်)
options.forEach(btn => btn.disabled = true);
// အဖြေမှန်ကို အစိမ်းရောင်ပြပါ
options[q.answer].classList.add('correct-answer');
if (index == q.answer) {
options[index].classList.add('correct-answer');
score++;
document.getElementById('score-display').innerText = `ရမှတ်: ${score}`;
}
// ရွေးလိုက်တဲ့အဖြေက မှားနေရင် အနီရောင်ပြပါ
if (index !== q.answer) {
options[index].classList.add('wrong-answer');
}
// ကျန်တဲ့ အဖြေမှားတွေကိုပါ အနီရောင်ပြရန်
options.forEach((btn, i) => {
if (i !== q.answer) {
btn.classList.add('wrong-answer');
}
});
// "နောက်တစ်ပုဒ်သို့" ခလုတ်ကို ပြသခြင်း
const nextBtn = document.getElementById('next-btn');
if (nextBtn) {
nextBtn.style.display = 'block';
nextBtn.className = 'next-btn'; // CSS class ချိတ်ခြင်း
nextBtn.innerText = 'နောက်တစ်ပုဒ်သို့ ⮕';
}
}
function nextQuestion() {
if (currentIdx < currentQuestions.length - 1) {
currentIdx++;
loadQuestion();
} else {
tg.showAlert("ဂုဏ်ယူပါသည်။ မေးခွန်းများအားလုံး ဖြေဆိုပြီးပါပြီ 🎉");
const finalTime = quizSeconds; // Capture time before stopping
submitScore(finalTime); // ⬅️ Send result to statistics sheet (only if random+timer active) // ⬅️ Send result to statistics sheet
// နောက်ထပ်နှိပ်စရာ မေးခွန်းမရှိတော့တဲ့အတွက် "နောက်တစ်ပုဒ်သို့" ခလုတ်ကို ဖျောက်ထားလိုက်ပါမည်
document.getElementById('next-btn').style.display = 'none';
// --- ⏱ Timer ကို ရပ်တန့်မည့် Code ---
if (isTimerRunning) {
clearInterval(quizTimerInterval);
isTimerRunning = false;
// ခလုတ်စာသားကို ပြောင်းပြီး ထပ်နှိပ်လို့မရအောင် ပိတ်ထားပါမည်
const startBtn = document.getElementById('timer-start-btn');
startBtn.innerText = "⏹ ပြီးဆုံးပါပြီ";
startBtn.disabled = true;
startBtn.style.opacity = "0.5"; // ပိတ်ထားကြောင်း သိသာစေရန် မှိန်ထားမည်
}
}
}
// --- UI Utils ---
function updateAvatar(save = false) {
const isFemale = document.getElementById('gender-switch').checked;
document.getElementById('hair').style.display = isFemale ? 'block' : 'none';
if(save) localStorage.setItem('userGender', isFemale ? 'female' : 'male');
}
function createBtn(txt, parent, act) {
const b = document.createElement('button'); b.className = 'btn'; b.innerText = txt; b.onclick = act; parent.appendChild(b);
}
function showScreen(id) {
if (id !== 'quiz') {
resetTimer();
}
document.querySelectorAll('.screen').forEach(s => s.classList.remove('active-screen'));
document.getElementById(id + '-screen').classList.add('active-screen');
// Refresh old-question badge whenever screen changes
updateOldQuestionBadges();
}
function changeTab(id, el) {
showScreen(id);
document.querySelectorAll('.nav-item').forEach(i => i.classList.remove('nav-active'));
el.classList.add('nav-active');
if(id === 'home') {
setOldQuestionContext(false);
renderSubjects();
backToOldSubjects();
switchHomeTab('current');
}
if(id === 'profile') renderProfileData();
if(id === 'articles') loadArticlesIndex();
}
function switchHomeTab(tab) {
const currentSection = document.getElementById('home-current-section');
const oldSection = document.getElementById('home-old-section');
const currentBtn = document.getElementById('home-tab-current');
const oldBtn = document.getElementById('home-tab-old');
if(tab === 'current') {
currentSection.style.display = 'block';
oldSection.style.display = 'none';
currentBtn.style.opacity = '1';
currentBtn.style.background = 'var(--accent)';
currentBtn.style.color = '#000';
oldBtn.style.opacity = '0.6';
oldBtn.style.background = '#1E293B';
oldBtn.style.color = 'var(--white)';
} else {
currentSection.style.display = 'none';
oldSection.style.display = 'block';
oldBtn.style.opacity = '1';
oldBtn.style.background = 'var(--accent)';
oldBtn.style.color = '#000';
currentBtn.style.opacity = '0.6';
currentBtn.style.background = '#1E293B';
currentBtn.style.color = 'var(--white)';
}
}
// Special Users ID များစာရင်း (ဒီမှာ ID ထည့်ရုံနဲ့ Premium ဖြစ်ပြီး ၆ ဘာသာပွင့်ပါမယ်)
function renderProfileData() {
const userId = tg.initDataUnsafe?.user?.id || 0;
const userName = tg.initDataUnsafe?.user?.first_name || "Scholar";
const isSpecial = specialUsers.includes(userId);
// Local Storage ကနေ Streak ကို ယူမယ်
let currentStreak = parseInt(localStorage.getItem('streak_count')) || updateStreak();
// UI Elements များကို သတ်မှတ်ခြင်း
document.getElementById('user-name').innerText = userName;
// --- 📋 ID ကို နှိပ်လိုက်လျှင် Copy ကူးမည့် စနစ် ---
const idTextElement = document.getElementById('user-id-text');
idTextElement.innerHTML = `ID: ${userId}
📋 `;
idTextElement.style.cursor = "pointer"; // နှိပ်လို့ရကြောင်း လက်ညှိုးပုံပေါ်စေရန်
idTextElement.onclick = () => {
// Clipboard သို့ Copy ကူးခြင်း
navigator.clipboard.writeText(userId.toString()).then(() => {
tg.showAlert("သင့် ID (" + userId + ") ကို Copy ကူးပြီးပါပြီ ✅");
}).catch(err => {
console.error('Copy failed', err);
});
};
// Premium ဖြစ်ပါက Body ကို class ထည့်ပြီး အရောင်ပြောင်းရန်
if (isSpecial) {
document.body.classList.add('premium-bg');
} else {
document.body.classList.remove('premium-bg');
}
// ဝယ်ယူထားသည့် ဘာသာရပ်ကွက် (Bought Badges) ပြသခြင်း
const container = document.getElementById('bought-items-container');
container.innerHTML = '';
const bought = subjects.filter(s => {
const isPaidInCode = checkAccess(s.id);
const isSpecialSubject = isSpecial && (['mm', 'en', 'math', 'phy', 'chem'].includes(s.id) || s.id === 'bio' || s.id === 'eco');
return isPaidInCode || isSpecialSubject;
});
if(bought.length > 0) {
bought.forEach(s => {
const span = document.createElement('span');
span.className = 'bought-badge';
if (isSpecial) span.style.border = "1px solid #F59E0B";
span.innerText = s.name;
container.appendChild(span);
});
}
// Streak Mini Badge ကို Profile Avatar ဘေးတွင် ထည့်ခြင်း
let streakBadge = document.getElementById('streak-mini-badge');
if (!streakBadge) {
streakBadge = document.createElement('div');
streakBadge.id = 'streak-mini-badge';
streakBadge.className = 'streak-mini-badge';
const avatar = document.getElementById('profile-avatar');
avatar.parentElement.style.position = 'relative';
avatar.parentElement.appendChild(streakBadge);
}
streakBadge.innerHTML = `🔥 ${currentStreak} Day${currentStreak > 1 ? 's' : ''}`;
// Dynamic Area ထဲကို UI တွေ ထည့်မယ်
const dynamicArea = document.getElementById('dynamic-content-area');
dynamicArea.innerHTML = `
📊 My Statistics
🎨 Theme Shop
📢 Join Telegram Channel
`;
}
// --- Init ---
if(localStorage.getItem('userGender') === 'female') {
document.getElementById('gender-switch').checked = true;
updateAvatar();
}
renderSubjects();
// ၂။ Checkbox အားလုံးကို Save လုပ်ခြင်း
function saveGoals() {
const goals = {};
for(let i=1; i<=7; i++) {
goals[`goal${i}`] = document.getElementById(`goal${i}`).checked;
}
// ယနေ့ ရက်စွဲကိုပါ သိမ်းမည်
const data = {
date: new Date().toLocaleDateString(),
values: goals
};
localStorage.setItem('dailyStudyData', JSON.stringify(data));
}
function loadGoals() {
const today = new Date().toLocaleDateString();
let savedData = JSON.parse(localStorage.getItem('dailyStudyData'));
// ၁။ နေ့ရက်အသစ်ရောက်မရောက် စစ်ဆေးပြီး Reset ချခြင်း
if (!savedData || savedData.date !== today) {
// Data အသစ်တည်ဆောက်ပြီး Checkbox အားလုံးကို အလွတ် (false) ထားမည်
savedData = {
date: today,
values: {
goal1: false, goal2: false, goal3: false,
goal4: false, goal5: false, goal6: false, goal7: false,goal8: false,goal9: false
}
};
localStorage.setItem('dailyStudyData', JSON.stringify(savedData));
}
// ၂။ Checkbox အခြေအနေများကို UI တွင် ပြန်လည်ပြသခြင်း
for (let i = 1; i <= 9; i++) {
const checkbox = document.getElementById(`goal${i}`);
// values ရှိမရှိ စစ်ပြီးမှ သုံးပါ
if (checkbox && savedData && savedData.values) {
checkbox.checked = savedData.values[`goal${i}`] || false;
}
}
// ၃။ Motivation Quote ပြောင်းလဲခြင်း (၁၅ ခုအနက်မှ တစ်ရက်တစ်ခု)
const quotes = [
"အောင်မြင်မှုဆီသို့ သွားရာလမ်းသည် ကြိုးစားအားထုတ်မှုဖြင့် စတင်သည်။",
"မနက်ဖြန်အတွက် အကောင်းဆုံး ပြင်ဆင်မှုက ဒီနေ့မှာ အကောင်းဆုံး ကြိုးစားခြင်းပဲ။",
"အခက်အခဲဆိုတာ ကျော်ဖြတ်ဖို့အတွက်ပဲ ဖြစ်ပါတယ်။",
"မရပ်မနား ကြိုးစားနေသရွေ့ မင်းဟာ အရှုံးမပေးသေးပါဘူး။",
"ပညာဆိုတာ မင်းဘယ်သူ့ဆီကမှ ခိုးယူလို့မရတဲ့ ရတနာတစ်ခုပဲ။",
"မင်းရဲ့ အနာဂတ်ဟာ မင်းဒီနေ့လုပ်ဆောင်တဲ့ အရာတွေအပေါ်မှာပဲ မူတည်တယ်။",
"ရှုံးနိမ့်ခြင်းဆိုတာ အောင်မြင်မှုအတွက် သင်ခန်းစာတစ်ခု ရလိုက်တာပါပဲ။",
"အိပ်မက်တွေကို အကောင်အထည်ဖော်ဖို့ အကောင်းဆုံးအချိန်ဟာ အခုအချိန်ပဲ။",
"မဖြစ်နိုင်ဘူးဆိုတာ ဇွဲမရှိတဲ့သူတွေ ပြောတဲ့ စကားလုံးသက်သက်ပါ။",
"သေးငယ်တဲ့ ခြေလှမ်းတွေကနေ ကြီးမားတဲ့ အောင်မြင်မှုတွေ ဖြစ်လာတတ်တယ်။",
"ကိုယ့်ကိုယ်ကိုယ် ယုံကြည်မှုရှိခြင်းဟာ အောင်မြင်မှုရဲ့ ပထမဆုံး လျှို့ဝှက်ချက်ပဲ။",
"ပန်းတိုင်ကို ရောက်ဖို့ ဖြတ်လမ်းမရှိဘူး၊ ကြိုးစားမှုပဲ ရှိတယ်။",
"အကောင်းဆုံးဖြစ်အောင် လုပ်ပါ၊ ကျန်တာကို ကံကြမ္မာအပေါ် ပုံချမထားပါနဲ့။",
"သူများထက် ပိုသိချင်ရင် သူများထက် ပိုကြိုးစားရမယ်။",
"ရင်းနှီးမြုပ်နှံမှုတွေထဲမှာအကောင်းဆုံးက ပညာရေးမှာရင်းနှီးမြုပ်နှံခြင်းပါပဲ"
];
const d = new Date();
const dayOfYear = Math.floor((d - new Date(d.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);
const quoteIdx = dayOfYear % quotes.length;
document.getElementById('daily-quote').innerText = `"${quotes[quoteIdx]}"`;
}
// ၁။ Exam Date သတ်မှတ်ရန် (ဥပမာ - ၂၀၂၇ မတ်လ ၁ ရက်)
function updateCountdown() {
const examDate = new Date("March 9, 2027 09:00:00").getTime();
// စာမေးပွဲရက် သတ်မှတ်ချက်
const now = new Date().getTime();
const diff = examDate - now;
if (diff <= 0) {
document.getElementById('exam-countdown').innerHTML = "စာမေးပွဲရက်သို့ ရောက်ရှိပါပြီ";
return;
}
const d = Math.floor(diff / (1000 * 60 * 60 * 24));
const h = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const m = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const s = Math.floor((diff % (1000 * 60)) / 1000);
document.getElementById('exam-countdown').innerHTML = `
${d}
Days
${h}
Hrs
${m}
Mins
${s}
Secs
`;
}
setInterval(updateCountdown, 1000);
function resetGoals() {
for(let i=1; i<=7; i++) {
if(document.getElementById(`goal${i}`)) document.getElementById(`goal${i}`).checked = false;
}
saveGoals();
}
// --- Theme CSS Loader ---
const loadedThemeCSS = new Set(); // ဘယ် file တွေ load ပြီးလဲ သိမ်းထားမယ်
function loadThemeCSS(themeId) {
// default ဆိုရင် file မလိုဘူး (index.html ထဲမှာပဲ base ရှိတယ်)
if (themeId === 'default') return;
const fileName = `theme-${themeId}.css`;
// ရှေ့က load ထားရင် ပြန်မလုပ်ဘူး
if (loadedThemeCSS.has(fileName)) return;
// HTML head ထဲမှာ CSS link အသစ် ထည့်မယ်
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = `./${fileName}`; // 📁 index.html နဲ့ တူညီတဲ့ folder ထဲမှာ theme-xxx.css ရှိရမယ်
link.type = 'text/css';
// load ပြီးရင် Set ထဲထည့်
link.onload = () => {
loadedThemeCSS.add(fileName);
console.log(`Theme CSS loaded: ${fileName}`);
};
// load မရရင် console မှာ error ပြမယ်
link.onerror = () => {
console.error(`Failed to load theme CSS: ${fileName}`);
};
document.head.appendChild(link);
}
window.onload = () => {
loadGoals();
updateCountdown();
updateStreak();
loadFromCache(); // ① Cache ရှိရင် ချက်ချင်း သော့ပွင့်ပြမယ် (စောင့်စရာမလို)
fetchPaidUsers();
// Theme Init
const savedTheme = localStorage.getItem('activeTheme') || 'default';
// 🆕 savedTheme မဟုတ်ဘူးဆိုရင် file load မယ်
if (savedTheme !== 'default') {
loadThemeCSS(savedTheme);
}
document.body.setAttribute('data-theme', savedTheme);
const savedRandomSetting = localStorage.getItem('randomQuizSetting') !== 'false';
const randomSwitch = document.getElementById('random-switch');
if (randomSwitch) {
randomSwitch.checked = savedRandomSetting;
}
};
// နေ့စဉ် Quote ပြောင်းလဲရန် Logic
function displayDailyQuote() {
const today = new Date();
// နေ့၊ လ၊ ခုနှစ်ကို ပေါင်းပြီး နံပါတ်တစ်ခုထုတ်ယူခြင်း (ဥပမာ - ၂၆၅၂၀၂၆)
const daySeed = today.getDate() + (today.getMonth() + 1) * 100 + today.getFullYear();
// နေ့ရက်အပေါ် မူတည်ပြီး array ထဲက quote တစ်ခုကို ပုံသေရွေးချယ်ခြင်း
const quoteIdx = daySeed % quotes.length;
document.getElementById('daily-quote').innerText = `"${quotes[quoteIdx]}"`;
}
function updateStreak() {
const todayDate = new Date().toISOString().split('T')[0];
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const yesterdayDate = yesterday.toISOString().split('T')[0];
let lastLogin = localStorage.getItem('last_login_date');
let streak = parseInt(localStorage.getItem('streak_count')) || 0;
if (!lastLogin) {
// ပထမဆုံးအကြိမ် App သုံးသူဖြစ်လျှင်
streak = 1;
} else if (lastLogin === todayDate) {
// ဒီနေ့ ဝင်ပြီးသားဖြစ်လျှင် (ဘာမှမလုပ်ဘူး၊ လက်ရှိ streak အတိုင်းပဲ)
if (streak === 0) streak = 1;
} else if (lastLogin === yesterdayDate) {
// မနေ့က ဝင်ခဲ့လျှင် Streak ၁ တိုးမယ်
streak += 1;
} else {
// တစ်ရက်ထက်ကျော်ပြီး ပျက်ကွက်သွားလျှင် ၁ ကနေ ပြန်စမယ်
streak = 1;
}
localStorage.setItem('last_login_date', todayDate);
localStorage.setItem('streak_count', streak.toString());
return streak;
}
// ၁။ Daily Quiz အတွက် မေးခွန်းများ စုစည်းထားမည့် နေရာ
// သင့်ရဲ့ မူရင်း JSON ပုံစံအတိုင်း (q, type, a, c) အတိအကျ သုံးထားပါတယ်
const dailyQuizDB = {
'mm': [
{ q: "မြန်မာစာ မေးခွန်း ၁", type: "mcq", a: ["က", "ခ", "ဂ", "ဃ"], c: 0 },
{ q: "မြန်မာစာ မေးခွန်း ၂", type: "mcq", a: ["က", "ခ", "ဂ", "ဃ"], c: 1 },
{ q: "မြန်မာစာ မေးခွန်း ၃", type: "mcq", a: ["က", "ခ", "ဂ", "ဃ"], c: 2 },
{ q: "မြန်မာစာ မေးခွန်း ၄", type: "mcq", a: ["က", "ခ", "ဂ", "ဃ"], c: 3 }
],
'en': [], 'eco': [], 'phy': [], 'chem': [], 'bio': []
};
// နေ့စဉ် ရက်စွဲအလိုက် ကျပန်းနံပါတ်ထုတ်ပေးမည့် စနစ်
function getDailySeed() {
const today = new Date();
return today.getFullYear() * 10000 + (today.getMonth() + 1) * 100 + today.getDate();
}
function seededRandom(seed) {
const x = Math.sin(seed) * 10000;
return x - Math.floor(x);
}
// သက်ဆိုင်ရာ ဘာသာရပ်အလိုက် JSON ဖိုင်နာမည်များ စုစည်းပေးမည့် Function
function getFileNamesForSubject(subId) {
let fileNames = [];
if (subId === 'phy' || subId === 'chem' || subId === 'bio' || subId === 'eco') {
// Physics, Chem, Bio, Eco အတွက် (ဥပမာ- phy_Chapter_1_MCQ မှ 13 အထိ)
const sub = subjects.find(s => s.id === subId);
const maxChap = sub ? sub.chapters : 10;
for (let i = 1; i <= maxChap; i++) {
fileNames.push(`${subId}_Chapter_${i}_MCQ`);
}
}
else if (subId === 'math') {
// သင်္ချာအတွက် (ဥပမာ- math_Chapter_1_1_Mark မှ 11 ထိ)
for (let i = 1; i <= 11; i++) {
fileNames.push(`math_Chapter_${i}_1_Mark`);
}
}
else if (subId === 'en') {
// English အတွက် (ဥပမာ- en_unit1_mcq)
for (let i = 1; i <= 12; i++) {
fileNames.push(`en_unit${i}_mcq`);
}
}
else if (subId === 'mm') {
// မြန်မာစာအတွက်က ဖိုင်နာမည် ကွဲပြားလွန်းသဖြင့် အမှန်ရွေးဖိုင်များကို သီးသန့်ထည့်ပေးရမည်
fileNames = [
"mm_အပြော_အမှန်ရွေး",
"mm_စကားပြေ_အမှန်ရွေး",
"mm_ကဗျာ_အမှန်ရွေး",
"mm_အဖတ်_အမှန်ရွေး"
// လိုအပ်လျှင် မြန်မာစာ ဖိုင်နာမည်များကို ဤနေရာတွင် ထပ်တိုးပါ
];
}
return fileNames;
}
async function startDailyQuiz(subId) {
currentQuizFile = 'daily_' + subId;
const backBtn = document.getElementById('quiz-back-btn');
backBtn.innerText = "ခဏစောင့်ပါ...";
backBtn.disabled = true;
// အရေးကြီးသော ပြင်ဆင်ချက်: currentSubject ကို မှန်ကန်စွာ သတ်မှတ်ပေးခြင်း
// ဒါက App ဖွင့်ဖွင့်ချင်းမှာ currentSubject null ဖြစ်နေတဲ့ ပြဿနာကို ရှင်းပေးပါလိမ့်မယ်။
const selectedSub = subjects.find(s => s.id === subId);
if (selectedSub) {
currentSubject = selectedSub;
} else {
// အကယ်၍ ရှာမတွေ့ပါက ပုံသေတစ်ခု ထည့်ထားပေးပါမည် (Error ကာကွယ်ရန်)
currentSubject = { id: subId, name: subId };
}
const filesToFetch = getFileNamesForSubject(subId);
let allQuestionsPool = [];
try {
let fetchPromises = filesToFetch.map(fileName => {
return fetch(`./quizzes/${fileName}.json`)
.then(res => res.ok ? res.json() : [])
.catch(() => []);
});
const chaptersData = await Promise.all(fetchPromises);
chaptersData.forEach((chapterQuestions) => {
if (Array.isArray(chapterQuestions)) {
const validQuestions = chapterQuestions.filter(item => {
return item.q && item.a && Array.isArray(item.a);
}).map(item => {
if (!item.type) {
item.type = 'mcq';
}
return item;
});
allQuestionsPool = allQuestionsPool.concat(validQuestions);
}
});
if(allQuestionsPool.length < 3) {
tg.showAlert("မေးခွန်းဖိုင်များ မတွေ့ပါ သို့မဟုတ် မပြည့်စုံပါ။");
backBtn.innerText = "ထွက်မည်";
backBtn.disabled = false;
return;
}
let seed = getDailySeed();
let shuffled = [...allQuestionsPool];
for (let i = shuffled.length - 1; i > 0; i--) {
const r = seededRandom(seed + i);
const j = Math.floor(r * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
currentQuestions = shuffled.slice(0, 3);
currentIdx = 0;
backBtn.innerText = "ထွက်မည်";
backBtn.disabled = false;
backBtn.onclick = () => showScreen('daily');
showScreen('quiz');
loadQuestion();
} catch (error) {
tg.showAlert("Error: " + error.message);
backBtn.innerText = "ထွက်မည်";
backBtn.disabled = false;
}
}
function updateRandomizeSetting() {
const isRandom = document.getElementById('random-switch').checked;
localStorage.setItem('randomQuizSetting', isRandom ? 'true' : 'false');
}
// Flashcard မူလဒေတာကို သိမ်းထားရန်
let originalFlashCards = [];
let isFlashcardShuffled = false;
// မူလ initFlashcards function ကို အောက်ပါအတိုင်း အစားထိုးပါ
async function initFlashcards(fileName, markTitle = "Flashcard") {
currentFlashMark = markTitle;
try {
const res = await fetch(`./quizzes/${fileName}.json`);
if(!res.ok) throw new Error();
const data = await res.json();
originalFlashCards = [...data]; // မူလအစီအစဉ်ကို သိမ်းထားမယ်
// ယခင်က Shuffle ဖွင့်ထားခဲ့ရင် ဆက်ဖွင့်ထားပေးမယ်
if (isFlashcardShuffled) {
flashCards = shuffleArray([...originalFlashCards]);
} else {
flashCards = [...originalFlashCards];
}
flashIdx = 0;
showScreen('flashcard');
updateFlashUI();
} catch (e) {
tg.showAlert("ဖိုင်မတွေ့သေးပါ- " + fileName);
}
}
// ခလုတ်နှိပ်လိုက်ရင် အလုပ်လုပ်မည့် Function
function toggleFlashcardShuffle() {
const btn = document.getElementById('shuffle-toggle-btn');
isFlashcardShuffled = !isFlashcardShuffled; // အခြေအနေကို ပြောင်းမယ်
if (isFlashcardShuffled) {
btn.classList.add('shuffle-active');
btn.innerText = "🔀 မွှေနှောက်";
// မွှေနှောက်လိုက်မယ်
flashCards = shuffleArray([...originalFlashCards]);
} else {
btn.classList.remove('shuffle-active');
btn.innerText = "🔄 ပုံမှန်";
// မူလအစီအစဉ်အတိုင်း ပြန်ထားမယ်
flashCards = [...originalFlashCards];
}
// Index ပြန်စပြီး UI Update လုပ်မယ်
flashIdx = 0;
updateFlashUI();
}
// --- Timer Variables ---
let quizTimerInterval = null;
let quizSeconds = 0;
let isTimerRunning = false;
let score = 0; // 🎯 ရမှတ်သိမ်းဆည်းရန် Variable အသစ်
// Timer အဖွင့်/အပိတ် လုပ်မည့် Function
function toggleTimer() {
if (isTimerRunning) {
// အချိန် ခဏရပ်မည်
clearInterval(quizTimerInterval);
isTimerRunning = false;
document.getElementById('timer-start-btn').innerText = "▶ ဆက်မှတ်မည်";
} else {
// အချိန် စမှတ်မည်
isTimerRunning = true;
document.getElementById('timer-display').style.display = 'inline';
document.getElementById('timer-reset-btn').style.display = 'inline';
document.getElementById('timer-start-btn').innerText = "⏸ ခဏရပ်မည်";
quizTimerInterval = setInterval(() => {
quizSeconds++;
const m = Math.floor(quizSeconds / 60).toString().padStart(2, '0');
const s = (quizSeconds % 60).toString().padStart(2, '0');
document.getElementById('timer-display').innerText = `${m}:${s}`;
}, 1000);
}
}
// ပြန်စသည့်အခါ ရမှတ်ကိုပါ ၀ ပြန်ဖြစ်စေရန် resetTimer() ကို ပြင်ဆင်ခြင်း
function resetTimer() {
clearInterval(quizTimerInterval);
isTimerRunning = false;
quizSeconds = 0;
document.getElementById('timer-display').innerText = "00:00";
document.getElementById('timer-display').style.display = 'none';
document.getElementById('timer-reset-btn').style.display = 'none';
const startBtn = document.getElementById('timer-start-btn');
startBtn.innerText = "⏱ အချိန်မှတ်မည်";
startBtn.removeAttribute('disabled');
startBtn.disabled = false;
startBtn.style.opacity = "1";
startBtn.style.cursor = "pointer";
startBtn.style.pointerEvents = "auto";
// 🎯 ရမှတ်ကို ၀ ပြန်ပြောင်းပြီး Screen ပေါ်မှာ ပြန်ပြင်ပေးရန်
score = 0;
document.getElementById('score-display').innerText = "ရမှတ်: 0";
}
// --- Theme Shop System ---
const themes = [
{ id: 'default', name: 'Ocean Dark Theme', price: 0, color: '#00D5FF', preview: 'linear-gradient(135deg, #0B0F19, #162235)' },
{ id: 'joker', name: 'Jocker Theme', price: -1, color: '#BF00FF', preview: 'linear-gradient(135deg, #0F0718, #1E1035)' , lockedText: 'Locked'},
{ id: 'heaven', name: 'Heaven Theme', price: -1, color: '#FFFFFF', preview: 'linear-gradient(135deg, FFFFFF, #CCCCCC)' , lockedText: 'Locked'},
{ id: 'itachi', name: 'Itachi Theme', price: -1, color: '#DC2626', preview: 'linear-gradient(135deg, #140303, #351010)' , lockedText: 'Locked'},
{ id: 'infinity', name: 'Void Theme', price: -1, color: '#000000', preview: 'linear-gradient(135deg, #FFFFFF, #7D7D7D)' , lockedText: 'Locked'}
];
// --- { id: 'mmpn', name: 'MMPN', price: -1, color: '#F59E0B', preview: 'linear-gradient(135deg, #1a1000, #3d2800)', exclusive: true, schoolName: "MMPN students onnly" } ---
function checkThemeAccess(themeId) {
if (themeId === 'default') return true;
// 🆕 ၁။ Hardcoded List (VIP, School, Special) ထဲမှာ ရှိရင် အရင်ခွင့်ပြု
// ဒါက theme ဘယ်လိုအမျိုးအစားဖြစ်ဖြစ် စစ်ပေးမယ်
if (checkExclusiveAccess(themeId)) return true;
// ၂။ Google Sheet (Paid) မှ ဝယ်ထားရင် ခွင့်ပြု
return checkAccess('theme_' + themeId);
}
function checkExclusiveAccess(themeId) {
// ၁။ Hardcoded List ထဲမှာလား စစ်မယ်
const uid = tg.initDataUnsafe?.user?.id?.toString();
const allowed = exclusiveThemeUsers[themeId] || [];
if (allowed.map(String).includes(uid)) return true;
// ၂။ Google Sheet ကနေ ယူထားတဲ့ Theme List ထဲမှာလား စစ်မယ်
if (window.userThemes && window.userThemes.includes(themeId)) return true;
return false;
}
function setTheme(themeId) {
// 🆕 CSS file load မယ် (ရှေ့က load ထားရင် auto skip လုပ်မယ်)
loadThemeCSS(themeId);
// 🆕 Default theme သို့ ပြန်သွားရင် ရှေ့က load ထားသော theme CSS files အားလုံး ဖယ်ရှားမယ်
if (themeId === 'default') {
document.querySelectorAll('link[rel="stylesheet"][href^="./theme-"]').forEach(link => {
link.remove();
const fileName = link.getAttribute('href').replace('./', '');
loadedThemeCSS.delete(fileName);
});
}
document.body.setAttribute('data-theme', themeId);
localStorage.setItem('activeTheme', themeId);
tg.showAlert(themes.find(t => t.id === themeId).name + " theme သုံးပါပြီ ✅");
// Theme Shop ကို refresh
if (document.getElementById('theme-shop-screen').classList.contains('active-screen')) {
openThemeShop();
}
}
document.body.setAttribute('data-theme', themeId);
function openThemeShop() {
showScreen('theme-shop');
const list = document.getElementById('theme-list');
list.innerHTML = '';
// Make sure body has the current theme attribute
const currentTheme = localStorage.getItem('activeTheme') || 'default';
document.body.setAttribute('data-theme', currentTheme);
themes.forEach(t => {
const isOwned = checkThemeAccess(t.id);
const isActive = currentTheme === t.id;
const div = document.createElement('div');
div.className = 'theme-shop-card';
div.style.cssText = `border: 2px solid ${t.color}; border-radius: 16px; padding: 15px; margin-bottom: 12px; display: flex; align-items: center; justify-content: space-between;`;
let btnHtml = '';
if (isActive) {
btnHtml = `
✓ သုံးနေသည် `;
} else if (isOwned) {
btnHtml = `
သုံးမည် `;
} else {
// 🏫 Exclusive Theme (School)
if (t.exclusive) {
btnHtml = `
🏫 ${t.schoolName} `;
}
// 🔒 ဝယ်လို့မရတဲ့ Theme (VIP, Event, etc...)
else if (t.lockedText) {
btnHtml = `
${t.lockedText} `;
}
// 💰 ဝယ်လို့ရတဲ့ Theme (အခမဲ့မဟုတ်၊ ဝယ်မည်ခလုတ်ပဲထားမယ်)
else if (t.price > 0) {
btnHtml = `
ဝယ်မည် `;
}
}
div.innerHTML = `
${t.name}
${isActive
? '✓ သုံးနေသည်'
: (isOwned
? 'သုံးရန်'
: (t.price === 0
? 'Free'
: (t.price > 0
? 'Premium'
: (t.lockedText || 'Locked'))))}
${btnHtml}
`;
list.appendChild(div);
});
}
function buyThemePrompt(themeId) {
const t = themes.find(x => x.id === themeId);
tg.showAlert("🎨 " + t.name + " ဝယ်ယူရန် @minaphayarkot ကို ဆက်သွယ်ပါ။\n\nသင့် ID: " + userId + "\n(Theme: " + themeId + ")");
}
function switchStatsTab(tabName) {
['summary', 'best', 'old', 'leaderboard'].forEach(t => {
const el = document.getElementById('stats-tab-' + t);
if (el) el.style.display = 'none';
const btn = document.getElementById('tab-' + t);
if (btn) {
btn.classList.remove('stats-tab-active');
btn.classList.add('stats-tab-inactive');
}
});
const activeTab = document.getElementById('stats-tab-' + tabName);
const activeBtn = document.getElementById('tab-' + tabName);
if (activeTab) activeTab.style.display = 'block';
if (activeBtn) {
activeBtn.classList.remove('stats-tab-inactive');
activeBtn.classList.add('stats-tab-active');
}
if (tabName === 'leaderboard') {
loadLeaderboard();
}
}
function calculateRankScore(totalScore, totalPossible, totalTime) {
if (totalPossible === 0) return { composite: -1, acc: 0, avgTime: 999, volume: 0 };
const accuracy = totalScore / totalPossible;
const avgTimePerQ = totalTime / totalPossible;
// Volume: logarithmic curve (0 → 1). 10 Qs ≈ 0.39, 50 ≈ 0.63, 100 ≈ 0.74, 200 ≈ 0.85, 500+ = 1.0
const volumeScore = Math.min(Math.log(totalPossible + 1) / Math.log(501), 1);
// Speed: optimal ~20s/q, linear penalty, zero at 120s/q
const timeScore = Math.max(0, Math.min(1, 1 - ((avgTimePerQ - 20) / 100)));
// Composite: 40% accuracy + 40% volume + 20% speed
const composite = (accuracy * 0.40) + (volumeScore * 0.40) + (timeScore * 0.20);
return {
composite: composite,
acc: accuracy,
avgTime: avgTimePerQ,
volume: totalPossible,
volumeScore: volumeScore,
timeScore: timeScore
};
}
function sortLeaderboard(entries) {
return entries.sort((a, b) => {
const ra = a.rankData, rb = b.rankData;
// 1) Composite score (higher is better)
if (rb.composite !== ra.composite) return rb.composite - ra.composite;
// 2) Tie-break: accuracy
if (rb.acc !== ra.acc) return rb.acc - ra.acc;
// 3) Tie-break: total questions answered (more is better)
if (rb.volume !== ra.volume) return rb.volume - ra.volume;
// 4) Tie-break: average time per question (less is better)
return ra.avgTime - rb.avgTime;
});
}
async function loadLeaderboard() {
const subject = document.getElementById('leaderboard-subject').value;
const listDiv = document.getElementById('leaderboard-list');
const loadingDiv = document.getElementById('leaderboard-loading');
const emptyDiv = document.getElementById('leaderboard-empty');
if (listDiv) listDiv.innerHTML = '';
if (loadingDiv) loadingDiv.style.display = 'block';
if (emptyDiv) emptyDiv.style.display = 'none';
try {
const url = `${STATS_GAS_URL}?action=getLeaderboard&subject=${encodeURIComponent(subject)}`;
const res = await fetch(url);
const text = await res.text();
let data;
try { data = JSON.parse(text); } catch(e) {
console.error("Bad response:", text);
throw new Error("Server returned invalid data");
}
if (data.status !== 'ok') {
if (loadingDiv) loadingDiv.style.display = 'none';
if (emptyDiv) { emptyDiv.style.display = 'block'; emptyDiv.innerText = 'Error: ' + (data.message || 'Unknown'); emptyDiv.style.color = 'var(--text-muted)'; }
return;
}
if (!data.rows || data.rows.length === 0) {
if (loadingDiv) loadingDiv.style.display = 'none';
if (emptyDiv) { emptyDiv.style.display = 'block'; emptyDiv.innerText = 'ဒေတာမရှိသေးပါ'; emptyDiv.style.color = 'var(--text-muted)'; }
return;
}
const userMap = {};
const currentUserId = tg.initDataUnsafe?.user?.id?.toString() || 'unknown';
const filteredRows = data.rows.filter(row => {
const qf = row.quizFile || '';
// Exclude Daily Quiz
if (qf.startsWith('daily_')) return false;
// 🆕 Exclude Myanmar individual chapter/title quizzes
if (isMyanmarIndividualQuiz(qf)) return false;
return true;
});
filteredRows.forEach(row => {
const uid = row.userId || 'unknown';
const uname = row.userName || 'Anonymous';
if (!userMap[uid]) {
userMap[uid] = { userId: uid, userName: uname, totalScore: 0, totalPossible: 0, totalTime: 0, quizCount: 0 };
}
userMap[uid].totalScore += parseInt(row.score || 0);
userMap[uid].totalPossible += parseInt(row.total || 0);
userMap[uid].totalTime += parseInt(row.timeTaken || 0);
userMap[uid].quizCount += 1;
});
let entries = Object.values(userMap)
.map(u => ({ ...u, rankData: calculateRankScore(u.totalScore, u.totalPossible, u.totalTime) }))
.filter(e => e.totalPossible > 0);
if (entries.length === 0) {
if (loadingDiv) loadingDiv.style.display = 'none';
if (emptyDiv) { emptyDiv.style.display = 'block'; emptyDiv.innerText = 'ဒေတာမရှိသေးပါ'; emptyDiv.style.color = 'var(--text-muted)'; }
return;
}
entries = sortLeaderboard(entries);
if (loadingDiv) loadingDiv.style.display = 'none';
renderLeaderboard(entries, currentUserId, subject);
} catch (e) {
console.error("Leaderboard error:", e);
if (loadingDiv) loadingDiv.style.display = 'none';
if (emptyDiv) { emptyDiv.style.display = 'block'; emptyDiv.innerText = 'ဆွဲယူမှားနေပါသည်'; emptyDiv.style.color = 'var(--text-muted)'; }
}
}
function renderLeaderboard(entries, currentUserId, subject) {
const listDiv = document.getElementById('leaderboard-list');
listDiv.innerHTML = '';
const medals = ['🥇', '🥈', '🥉'];
const TOP_N = 10;
let myRank = -1;
const myEntryIndex = entries.findIndex(e => e.userId === currentUserId);
if (myEntryIndex !== -1) myRank = myEntryIndex + 1;
const topEntries = entries.slice(0, TOP_N);
topEntries.forEach((entry, index) => {
const rank = index + 1;
const isMe = entry.userId === currentUserId;
const acc = Math.round(entry.rankData.acc * 100);
const totalTimeStr = formatTime(entry.totalTime); // ⬅️ Total time instead of avg
const div = document.createElement('div');
div.className = `leaderboard-item ${isMe ? 'is-me' : ''}`;
const rankClass = rank <= 3 ? `rank-${rank}` : 'rank-other';
const medal = rank <= 3 ? medals[rank - 1] : '';
const nameInitial = (entry.userName || 'A').charAt(0).toUpperCase();
let displayName = entry.userName || 'Anonymous';
if (displayName.length > 15) displayName = displayName.substring(0, 14) + '…';
if (isMe) displayName += ' (You)';
div.innerHTML = `
${rank}
${nameInitial}
${displayName}
${entry.totalPossible} Qs · ${acc}% correct · ⏱ ${totalTimeStr}
${acc}%
${entry.quizCount} quizzes
${medal}
`;
listDiv.appendChild(div);
});
// Current user outside Top 10
if (myRank > TOP_N && currentUserId !== 'unknown') {
const me = entries[myEntryIndex];
const acc = Math.round(me.rankData.acc * 100);
const totalTimeStr = formatTime(me.totalTime); // ⬅️ Total time instead of avg
const nameInitial = (me.userName || 'A').charAt(0).toUpperCase();
let displayName = me.userName || 'Anonymous';
if (displayName.length > 15) displayName = displayName.substring(0, 14) + '…';
displayName += ' (You)';
const div = document.createElement('div');
div.className = 'leaderboard-item is-me';
div.style.marginTop = '20px';
div.style.borderTop = '2px dashed var(--accent)';
div.style.paddingTop = '15px';
div.innerHTML = `
${myRank}
${nameInitial}
${displayName}
${me.totalPossible} Qs · ${acc}% correct · ⏱ ${totalTimeStr}
${acc}%
${me.quizCount} quizzes
`;
listDiv.appendChild(div);
}
// No data state
if (myRank === -1 && currentUserId !== 'unknown') {
const div = document.createElement('div');
div.className = 'leaderboard-item is-me';
div.style.marginTop = '20px';
div.style.opacity = '0.7';
div.innerHTML = `
-
?
You (No data)
ဒီဘာသာရပ်အတွက် မေးခွန်းမဖြေဆိုရသေးပါ (Daily Quiz မပါ)
`;
listDiv.appendChild(div);
}
}
function copyTelegram() {
const username = "@minaphayarkot";
tg.showPopup({
title: 'ဆက်သွယ်ရန် ( Telegram Account )',
message: username,
buttons: [
{id: 'copy', type: 'default', text: '📋 Copy'},
{type: 'cancel'}
]
}, function(btnId) {
if (btnId === 'copy') {
navigator.clipboard.writeText(username).then(function() {
tg.showAlert('ကူးယူပြီးပါပြီ ✅');
}).catch(function() {
tg.showAlert('ကူးယူ၍မရပါ။ လက်နဲ့မှတ်ယူပါ: ' + username);
});
}
});
}
function openChannel() {
tg.openTelegramLink('https://t.me/REED_education');
}