'use strict'; /* ────────────────────────────────────────────────────────────────── Variants view — picks a variant, renders its tasks via TaskCard (interactive answer input + check + auto-logged attempts). ────────────────────────────────────────────────────────────────── */ (async function () { await EP.boot(); const examKey = EP.examKey; const initialVariantFromQuery = (() => { const m = location.search.match(/[?&]v=(\d+)/); return m ? Number(m[1]) : null; })(); let variants = []; let currentN = null; const tasksCache = new Map(); /* ── Variants list ──────────────────────────────────────────── */ try { const r = await EP.api.listVariants(examKey); variants = r.variants || []; } catch (e) { showError(`Не удалось загрузить варианты: ${e.message || e}`); return; } if (!variants.length) { showError('Варианты не найдены'); return; } /* ── DOM ────────────────────────────────────────────────────── */ const main = document.getElementById('ep-main'); const pickerBtn = document.getElementById('vp-btn'); const pickerLabel = document.getElementById('vp-label'); const pickerOver = document.getElementById('vp-overlay'); const pickerGrid = document.getElementById('vp-grid'); /* ── Picker overlay ─────────────────────────────────────────── */ function buildGrid() { pickerGrid.innerHTML = variants.map(v => { let cls = ''; // Prefer solved-based highlight; fall back to viewed-sol when nothing solved yet. if (v.total > 0 && v.solved === v.total) cls = ' done'; else if (v.solved > 0) cls = ' partial'; else if (v.viewed_sol > 0) cls = ' partial'; const active = v.n === currentN ? ' active' : ''; const title = `${v.label} · решено ${v.solved}/${v.total}` + (v.viewed_sol ? ` · решений открыто ${v.viewed_sol}` : ''); return ``; }).join(''); pickerGrid.querySelectorAll('button[data-n]').forEach(b => { b.onclick = () => { selectVariant(Number(b.dataset.n)); closePicker(); }; }); } function openPicker() { buildGrid(); pickerOver.classList.add('visible'); pickerBtn.classList.add('open'); document.addEventListener('keydown', onEsc); } function closePicker() { pickerOver.classList.remove('visible'); pickerBtn.classList.remove('open'); document.removeEventListener('keydown', onEsc); } function onEsc(e) { if (e.key === 'Escape') closePicker(); } function onOverlayClick(e) { if (e.target === pickerOver) closePicker(); } pickerBtn.onclick = () => { pickerOver.classList.contains('visible') ? closePicker() : openPicker(); }; pickerOver.onclick = onOverlayClick; document.getElementById('vp-close').onclick = closePicker; /* ── Variant rendering ──────────────────────────────────────── */ async function selectVariant(n) { currentN = n; pickerLabel.textContent = `Вариант ${n}`; try { localStorage.setItem(`exam_prep_${examKey}_last_variant`, String(n)); } catch {} if (!tasksCache.has(n)) { main.innerHTML = `

Загрузка варианта ${n}…

`; if (window.lucide) lucide.createIcons(); try { const r = await EP.api.getVariant(examKey, n); tasksCache.set(n, r.tasks || []); } catch (e) { showError(`Не удалось загрузить вариант ${n}: ${e.message || e}`); return; } } renderVariant(n, tasksCache.get(n)); window.scrollTo({ top: 0, behavior: 'smooth' }); } function renderVariant(n, tasks) { main.innerHTML = `
Вариант ${n}${tasks.length} заданий
`; const variantMeta = variants.find(v => v.n === n); const solvedTracked = new Set(); // tasks already solved this session const viewedTracked = new Set(); // tasks where solution opened this session tasks.forEach(task => { EP.TaskCard.render(main, task, { mode: 'variant', autoCheck: true, showSolution: true, onAttempt: ({ taskId, isCorrect, solutionViewed }) => { // Optimistic update of picker counters (best-effort; backend is source of truth) if (!variantMeta) return; if (isCorrect === 1 && !solvedTracked.has(taskId)) { solvedTracked.add(taskId); variantMeta.solved = Math.min(variantMeta.solved + 1, variantMeta.total); } if (solutionViewed && !viewedTracked.has(taskId)) { viewedTracked.add(taskId); variantMeta.viewed_sol = Math.min(variantMeta.viewed_sol + 1, variantMeta.total); } }, }); }); } function showError(msg) { document.getElementById('ep-main').innerHTML = `

${escapeHtml(msg)}

`; if (window.lucide) lucide.createIcons(); } function escapeHtml(s) { return String(s || '').replace(/[&<>"']/g, c => ({ '&':'&', '<':'<', '>':'>', '"':'"', "'":''' }[c])); } /* ── Pick initial variant ───────────────────────────────────── */ let initial = variants[0].n; if (initialVariantFromQuery && variants.some(v => v.n === initialVariantFromQuery)) { initial = initialVariantFromQuery; } else { try { const last = Number(localStorage.getItem(`exam_prep_${examKey}_last_variant`)); if (last && variants.some(v => v.n === last)) initial = last; } catch {} } selectVariant(initial); })();