diff --git a/frontend/textbooks/algebra_8.html b/frontend/textbooks/algebra_8.html index 2a2bd6d..bca69d6 100644 --- a/frontend/textbooks/algebra_8.html +++ b/frontend/textbooks/algebra_8.html @@ -466,6 +466,45 @@ input,select,textarea{font-family:inherit} @keyframes simpPop{0%{transform:scale(1)}50%{transform:scale(1.1)}100%{transform:scale(1)}} @keyframes simpShake{0%,100%{transform:translateX(0)}25%{transform:translateX(-6px)}75%{transform:translateX(6px)}} +/* ═══════════════════════════════════════════════ + BOSS BATTLES — CSS + ═══════════════════════════════════════════════ */ +.boss-card{margin:30px 0 14px;padding:22px;background:linear-gradient(135deg,var(--card),var(--sec-acc-soft,var(--pri-soft)));border:2.5px solid var(--sec-acc,var(--pri));border-radius:18px;box-shadow:0 8px 32px rgba(0,0,0,.08);position:relative;overflow:hidden} +.boss-card::before{content:'';position:absolute;top:0;left:0;right:0;height:4px;background:linear-gradient(90deg,var(--sec-acc,var(--pri)),var(--acc));border-radius:18px 18px 0 0} +.boss-header{display:flex;align-items:center;gap:14px;flex-wrap:wrap} +.boss-header svg{color:var(--sec-acc,var(--pri))} +.boss-tag{font-family:'Unbounded',sans-serif;font-size:.7rem;font-weight:800;text-transform:uppercase;letter-spacing:.1em;color:var(--sec-acc-d,var(--pri2))} +.boss-title{font-family:'Unbounded',sans-serif;font-size:1.3rem;font-weight:900;color:var(--text)} +.boss-header .btn{margin-left:auto} +.boss-arena{margin-top:18px;padding:18px;background:var(--card);border-radius:13px;border:1px solid var(--border)} +.boss-progress{display:flex;align-items:center;gap:12px;margin-bottom:18px} +.boss-progress-bar{flex:1;height:10px;background:rgba(0,0,0,.08);border-radius:6px;overflow:hidden} +.boss-progress-fill{height:100%;background:linear-gradient(90deg,var(--sec-acc,var(--pri)),var(--acc));border-radius:6px;width:0%;transition:width .4s} +.boss-progress-text{font-size:.85rem;font-weight:700;color:var(--muted);min-width:80px;text-align:right} +.boss-task{font-size:1.15rem;font-weight:600;color:var(--text);margin:18px 0;padding:18px;background:linear-gradient(135deg,var(--pri-soft),var(--acc-soft));border-radius:12px;text-align:center;min-height:80px;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:8px} +.boss-controls{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin-bottom:10px} +.boss-controls .btn{font-size:.95rem;padding:10px 18px;min-width:90px} +.boss-controls .b-act{background:var(--card);border:1.5px solid var(--border);font-weight:600} +.boss-controls .b-act:hover{border-color:var(--sec-acc,var(--pri));background:var(--sec-acc-soft,var(--pri-soft))} +.boss-controls .b-act.correct{background:var(--ok);color:#fff;border-color:var(--ok)} +.boss-controls .b-act.wrong{background:var(--fail);color:#fff;border-color:var(--fail);animation:simpShake .4s ease} +.boss-aux{margin-top:8px;display:flex;gap:8px;justify-content:center} +.boss-feedback{margin-top:10px} +.boss-inp{padding:9px 14px;border-radius:9px;background:var(--card);border:1.5px solid var(--border);font-size:1rem;color:var(--text);font-family:'JetBrains Mono',monospace;width:160px;text-align:center;outline:none} +.boss-inp:focus{border-color:var(--sec-acc,var(--pri));background:var(--sec-acc-soft,var(--pri-soft))} +.boss-result{padding:30px;text-align:center;animation:boxIn .5s cubic-bezier(.34,1.56,.64,1)} +@keyframes boxIn{from{opacity:0;transform:scale(.85) translateY(12px)}to{opacity:1;transform:none}} +.boss-medal{width:100px;height:100px;margin:0 auto 14px;border-radius:50%;display:flex;align-items:center;justify-content:center;animation:medalSpin .9s ease} +.boss-medal.gold{background:linear-gradient(135deg,#fbbf24,#f59e0b);box-shadow:0 0 0 6px rgba(245,158,11,.2)} +.boss-medal.silver{background:linear-gradient(135deg,#cbd5e1,#94a3b8);box-shadow:0 0 0 6px rgba(148,163,184,.2)} +.boss-medal.bronze{background:linear-gradient(135deg,#fb923c,#ea580c);box-shadow:0 0 0 6px rgba(234,88,12,.2)} +.boss-medal svg{width:50px;height:50px;color:#fff;stroke-width:2.5} +.boss-result-title{font-family:'Unbounded',sans-serif;font-size:1.5rem;font-weight:900;color:var(--sec-acc-d,var(--pri2));margin-bottom:8px} +.boss-result-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin:18px 0;font-size:.95rem} +.boss-result-stat-num{font-size:1.6rem;font-weight:900;color:var(--sec-acc,var(--pri))} +.boss-result-stat-lab{font-size:.75rem;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;margin-top:2px} +@keyframes medalSpin{0%{transform:rotateY(0) scale(0.5)}50%{transform:rotateY(180deg) scale(1.1)}100%{transform:rotateY(360deg) scale(1)}} + /* Геометрическое доказательство §3 */ .geo-canvas-wrap{background:var(--card);border:1px solid var(--border);border-radius:11px;padding:8px;margin-top:14px} .geo-cell{filter:drop-shadow(0 1px 1px rgba(0,0,0,.12))} @@ -942,6 +981,7 @@ const STATE = { streak: 0, maxStreak: 0, dailyChallenge: { date: null, completed: false, taskIdx: 0 }, + bossResults: {}, // secId → { passed, score, total, perfect } }; /* Словарь имён достижений — используется и для отображения, и для retroactive-фикса старых записей */ @@ -993,6 +1033,8 @@ function loadProgress(){ if(sk){ const o = JSON.parse(sk); STATE.streak = o.streak||0; STATE.maxStreak = o.max||0; } const dc = localStorage.getItem('algebra8_ch1_daily'); if(dc){ Object.assign(STATE.dailyChallenge, JSON.parse(dc)); } + const br = localStorage.getItem('algebra8_ch1_bossResults'); + if(br){ Object.assign(STATE.bossResults, JSON.parse(br)); } }catch(e){} } function saveProgress(){ @@ -1003,6 +1045,7 @@ function saveProgress(){ localStorage.setItem('algebra8_ch1_xp', String(STATE.xp)); localStorage.setItem('algebra8_ch1_streak', JSON.stringify({streak:STATE.streak, max:STATE.maxStreak})); localStorage.setItem('algebra8_ch1_daily', JSON.stringify(STATE.dailyChallenge)); + localStorage.setItem('algebra8_ch1_bossResults', JSON.stringify(STATE.bossResults)); }catch(e){} } function bumpProgress(key, delta){ @@ -1815,6 +1858,8 @@ function buildP1(){ `)} + ${bossWidget('p1')} + ${secNav(null, 'p2')} `; renderMath(body); @@ -2357,6 +2402,8 @@ function buildP2(){ `)} + ${bossWidget('p2')} + ${secNav('p1', 'p3')} `; renderMath(body); @@ -2768,6 +2815,8 @@ function buildP3(){ `)} + ${bossWidget('p3')} + ${secNav('p2', 'p4')} `; renderMath(body); @@ -3321,6 +3370,8 @@ function buildP4(){ `)} + ${bossWidget('p4')} + ${secNav('p3', 'p5')} `; renderMath(body); @@ -3754,6 +3805,8 @@ function buildP5(){ `)} + ${bossWidget('p5')} + ${secNav('p4', 'p6')} `; renderMath(body); @@ -4134,6 +4187,8 @@ function buildP6(){ `)} + ${bossWidget('p6')} + ${secNav('p5', 'final')} `; renderMath(body); @@ -4596,6 +4651,8 @@ function buildFinal(){ + ${bossWidget('final')} + ${secNav('p6', null)} `; renderMath(body); @@ -4818,6 +4875,475 @@ function finalSummary(){ const sqBest = isFinite(STATE.squaresBest) ? STATE.squaresBest : '—'; alert(`Сводка по Главе 1:\n\nОбщий прогресс: ${total}%\nДостижений: ${ach}\nЛучшая «Таблица квадратов»: ${sqBest} очк.\n\nПродолжайте! Откройте Главу 2 «Квадратные уравнения» — там корни заработают на полную.`); } + +/* ════════════════════════════════════════════════════════ + BOSS BATTLES ENGINE + ════════════════════════════════════════════════════════ */ + +/* ── Task sets ── */ +const BOSS_TASKS = { + p1: [ + { type:'input', q:'Найди $\\sqrt{121}$', a:'11', hint:'$11^2 = 121$', explanation:'$\\sqrt{121} = 11$, так как $11^2 = 121$.' }, + { type:'select', q:'Сравни $\\sqrt{50}$ и $7$', a:0, opts:['$\\sqrt{50} > 7$','$\\sqrt{50} < 7$','$\\sqrt{50} = 7$'], hint:'$7^2 = 49$, $50 > 49$', explanation:'$7^2 = 49 < 50$, значит $\\sqrt{50} > 7$.' }, + { type:'yesno', q:'Существует ли $\\sqrt{-9}$ среди действительных чисел?', a:false, hint:'Под корнем отрицательное', explanation:'Арифметический квадратный корень определён только для $a \\geq 0$.' }, + { type:'input', q:'Чему равно $(\\sqrt{5})^2$?', a:'5', hint:'$(\\sqrt{a})^2 = a$', explanation:'По определению: $(\\sqrt{a})^2 = a$ при $a \\geq 0$.' }, + { type:'select', q:'$\\sqrt{a^2}$ при $a = -7$ равно?', a:1, opts:['$-7$','$7$','$49$','$14$'], hint:'$\\sqrt{a^2} = |a|$', explanation:'$\\sqrt{(-7)^2} = \\sqrt{49} = 7 = |-7|$.' }, + { type:'input', q:'Найди $\\sqrt{0{,}81}$', a:'0.9', hint:'$0.9^2 = 0.81$', explanation:'$\\sqrt{0{,}81} = 0{,}9$, так как $0{,}9^2 = 0{,}81$.' }, + { type:'select', q:'Сколько квадратных корней из $100$?', a:2, opts:['$0$','$1$','$2$','Бесконечно'], hint:'Есть 10 и −10', explanation:'$10^2 = 100$ и $(-10)^2 = 100$. Два корня: $10$ и $-10$.' }, + ], + p2: [ + { type:'select', q:'К какому множеству принадлежит $\\dfrac{1}{3}$?', a:2, opts:['$\\mathbb{N}$','$\\mathbb{Z}$','$\\mathbb{Q}$','$\\mathbb{I}$ (иррац.)'], hint:'Это дробь', explanation:'$1/3$ — рациональное число ($\\mathbb{Q}$), так как это обыкновенная дробь.' }, + { type:'select', q:'$\\sqrt{7}$ — это число...', a:1, opts:['Рациональное','Иррациональное','Натуральное','Целое'], hint:'Нельзя записать в виде дроби', explanation:'$\\sqrt{7}$ — иррациональное, его нельзя представить в виде $m/n$.' }, + { type:'select', q:'Какое число иррационально?', a:1, opts:['$\\sqrt{16}$','$\\sqrt{7}$','$2/3$','$0{,}5$'], hint:'$\\sqrt{16} = 4$ — рациональное', explanation:'$\\sqrt{16} = 4$ — рациональное, $\\sqrt{7}$ — иррациональное.' }, + { type:'yesno', q:'Равны ли $0{,}(3)$ и $\\dfrac{1}{3}$?', a:true, hint:'$1/3 = 0.333...$', explanation:'$0{,}(3) = 0{,}333\\ldots = 1/3$. Да, равны.' }, + { type:'yesno', q:'Верно ли утверждение $\\mathbb{N} \\subset \\mathbb{R}$?', a:true, hint:'Натуральные входят в действительные', explanation:'$\\mathbb{N} \\subset \\mathbb{Z} \\subset \\mathbb{Q} \\subset \\mathbb{R}$. Да, верно.' }, + { type:'input', q:'Между какими целыми числами находится $\\sqrt{51}$? Введи наименьшее:', a:'7', hint:'$7^2=49$, $8^2=64$', explanation:'$7^2 = 49 < 51 < 64 = 8^2$, значит $7 < \\sqrt{51} < 8$.' }, + ], + p3: [ + { type:'select', q:'$\\sqrt{9 \\cdot 25} = ?$', a:0, opts:['$15$','$12$','$18$','$30$'], hint:'$\\sqrt{ab} = \\sqrt{a}\\cdot\\sqrt{b}$', explanation:'$\\sqrt{9 \\cdot 25} = \\sqrt{9}\\cdot\\sqrt{25} = 3\\cdot5 = 15$.' }, + { type:'select', q:'$\\sqrt{a} \\cdot \\sqrt{b}$ равно...', a:1, opts:['$\\sqrt{a+b}$','$\\sqrt{ab}$','$\\sqrt{a}+\\sqrt{b}$','$a \\cdot b$'], hint:'Свойство корня произведения', explanation:'По свойству: $\\sqrt{a}\\cdot\\sqrt{b} = \\sqrt{ab}$ при $a,b\\geq 0$.' }, + { type:'input', q:'$\\sqrt{64/16} = ?$', a:'2', hint:'$\\sqrt{a/b} = \\sqrt{a}/\\sqrt{b}$', explanation:'$\\sqrt{64/16} = \\sqrt{4} = 2$.' }, + { type:'yesno', q:'Верно ли: $\\sqrt{a^2} = a$ — всегда?', a:false, hint:'Попробуй $a = -3$', explanation:'Нет: $\\sqrt{a^2} = |a|$. При $a = -3$: $\\sqrt{9} = 3 \\neq -3$.' }, + { type:'input', q:'$\\sqrt{100} \\cdot \\sqrt{4} = ?$', a:'20', hint:'$\\sqrt{100}=10$, $\\sqrt{4}=2$', explanation:'$\\sqrt{100}\\cdot\\sqrt{4} = 10\\cdot2 = 20$.' }, + { type:'input', q:'$\\dfrac{\\sqrt{81}}{\\sqrt{9}} = ?$', a:'3', hint:'$\\sqrt{81/9} = \\sqrt{9}$', explanation:'$\\sqrt{81}/\\sqrt{9} = 9/3 = 3$.' }, + { type:'select', q:'Упрости $\\sqrt{36a^2}$ при $a \\geq 0$', a:0, opts:['$6a$','$36a$','$6a^2$','$\\sqrt{36}\\cdot a$'], hint:'$\\sqrt{36}=6$, $\\sqrt{a^2}=a$ при $a\\geq0$', explanation:'$\\sqrt{36a^2} = \\sqrt{36}\\cdot\\sqrt{a^2} = 6\\cdot a = 6a$.' }, + ], + p4: [ + { type:'input', q:'Вынеси из-под корня: $\\sqrt{72}$ — введи коэффициент (множитель вне корня):', a:'6', hint:'$72 = 36\\cdot2$', explanation:'$\\sqrt{72} = \\sqrt{36\\cdot2} = 6\\sqrt{2}$. Коэффициент равен 6.' }, + { type:'input', q:'Внеси под корень: $5\\sqrt{3} = \\sqrt{?}$. Введи подкоренное число:', a:'75', hint:'$5\\sqrt{3}=\\sqrt{25\\cdot3}$', explanation:'$5\\sqrt{3} = \\sqrt{5^2\\cdot3} = \\sqrt{75}$.' }, + { type:'select', q:'Освободи от иррациональности: $\\dfrac{1}{\\sqrt{3}} = ?$', a:1, opts:['$\\sqrt{3}$','$\\dfrac{\\sqrt{3}}{3}$','$\\dfrac{1}{3}$','$\\dfrac{3}{\\sqrt{3}}$'], hint:'Умножь числитель и знаменатель на $\\sqrt{3}$', explanation:'$\\dfrac{1}{\\sqrt{3}} = \\dfrac{\\sqrt{3}}{\\sqrt{3}\\cdot\\sqrt{3}} = \\dfrac{\\sqrt{3}}{3}$.' }, + { type:'select', q:'Что больше: $3\\sqrt{2}$ или $2\\sqrt{3}$?', a:0, opts:['$3\\sqrt{2} > 2\\sqrt{3}$','$3\\sqrt{2} < 2\\sqrt{3}$','Они равны'], hint:'$(3\\sqrt{2})^2 = 18$, $(2\\sqrt{3})^2 = 12$', explanation:'$(3\\sqrt{2})^2 = 18 > 12 = (2\\sqrt{3})^2$, значит $3\\sqrt{2} > 2\\sqrt{3}$.' }, + { type:'input', q:'Упрости $\\sqrt{200}$ — введи коэффициент вне корня:', a:'10', hint:'$200 = 100\\cdot2$', explanation:'$\\sqrt{200} = \\sqrt{100\\cdot2} = 10\\sqrt{2}$. Коэффициент 10.' }, + { type:'input', q:'$(\\sqrt{7} + \\sqrt{7})^2 = ?$', a:'28', hint:'$\\sqrt{7}+\\sqrt{7} = 2\\sqrt{7}$', explanation:'$\\sqrt{7}+\\sqrt{7} = 2\\sqrt{7}$; $(2\\sqrt{7})^2 = 4\\cdot7 = 28$.' }, + ], + p5: [ + { type:'select', q:'Запиши промежуток для $x > 5$', a:0, opts:['$(5; +\\infty)$','$[5; +\\infty)$','$(-\\infty; 5)$','$[5; +\\infty]$'], hint:'Строгое неравенство — открытая скобка', explanation:'$x > 5$ — строгое, значит 5 не включён: $(5; +\\infty)$.' }, + { type:'select', q:'$(2; 6) \\cap [4; 10] = ?$', a:0, opts:['$[4; 6)$','$(2; 10]$','$(4; 6)$','$(4; 10]$'], hint:'Пересечение берёт максимальную левую и минимальную правую', explanation:'Пересечение: $\\max(2,4)=4$ (включён у второго) и $\\min(6,10)=6$ (не включён у первого): $[4; 6)$.' }, + { type:'yesno', q:'Принадлежит ли $3$ промежутку $(2; 5]$?', a:true, hint:'$2 < 3 \\leq 5$?', explanation:'$2 < 3 \\leq 5$ — да, $3 \\in (2; 5]$.' }, + { type:'select', q:'$(-\\infty; 0) \\cup (0; +\\infty)$ — это...', a:1, opts:['$\\mathbb{R}$','$\\mathbb{R} \\setminus \\{0\\}$','$\\varnothing$','$\\{0\\}$'], hint:'Вся прямая без нуля', explanation:'Объединение двух лучей без точки 0: $\\mathbb{R} \\setminus \\{0\\}$.' }, + { type:'select', q:'$[1; 4) \\cup [4; 8] = ?$', a:0, opts:['$[1; 8]$','$[1; 8)$','$(1; 8]$','$[1;4)\\cup[4;8]$'], hint:'Промежутки смыкаются в точке 4', explanation:'$[1;4)\\cup[4;8] = [1;8]$ — непрерывный отрезок.' }, + { type:'input', q:'Сколько целых чисел в $[-3; 4]$? Введи число:', a:'8', hint:'Считай: $-3, -2, -1, 0, 1, 2, 3, 4$', explanation:'Целые: $-3,-2,-1,0,1,2,3,4$ — всего 8.' }, + ], + p6: [ + { type:'select', q:'Решение системы $\\begin{cases}x>2\\\\x\\leq5\\end{cases}$ = ?', a:1, opts:['$(2;5)$','$(2;5]$','$[2;5]$','$(-\\infty;5]$'], hint:'x > 2 — открытая слева, x ≤ 5 — закрытая справа', explanation:'$x>2$ и $x\\leq5$: пересечение $(2;5]$.' }, + { type:'select', q:'Решение совокупности $\\left[\\begin{array}{l}x\\leq1\\\\x>4\\end{array}\\right.$ = ?', a:1, opts:['$(1;4]$','$(-\\infty;1]\\cup(4;+\\infty)$','$[1;4]$','$(1;4)$'], hint:'Совокупность — объединение', explanation:'Совокупность: $x\\leq1$ ИЛИ $x>4$ = $(-\\infty;1]\\cup(4;+\\infty)$.' }, + { type:'select', q:'$-2 < 3x + 1 \\leq 7$. Решение = ?', a:0, opts:['$(-1;2]$','$(-1;2)$','$[-1;2]$','$(-2;7]$'], hint:'Вычти 1, затем раздели на 3', explanation:'$-3 < 3x \\leq 6$; $-1 < x \\leq 2$; ответ: $(-1; 2]$.' }, + { type:'input', q:'Сколько целых решений у системы $\\begin{cases}x\\geq0\\\\x<4\\end{cases}$? Введи число:', a:'4', hint:'$0, 1, 2, 3$', explanation:'Целые числа: $0, 1, 2, 3$ — четыре решения.' }, + { type:'yesno', q:'Имеет ли решение система $\\begin{cases}x\\geq5\\\\x\\leq3\\end{cases}$?', a:false, hint:'$x$ не может быть ≥5 и ≤3 одновременно', explanation:'Нет такого $x$. Система несовместна: $\\varnothing$.' }, + { type:'select', q:'Решение $\\{x^2 > 0\\}$ для $x \\in \\mathbb{R}$ = ?', a:1, opts:['$\\mathbb{R}$','$\\mathbb{R}\\setminus\\{0\\}$','$(0;+\\infty)$','$\\varnothing$'], hint:'$x^2 > 0$ при $x \\neq 0$', explanation:'$x^2 = 0$ только при $x = 0$, иначе $x^2 > 0$. Ответ: $\\mathbb{R}\\setminus\\{0\\}$.' }, + ], + final: [ + { type:'input', q:'$\\sqrt{15^2 + 8^2} = ?$ (теорема Пифагора)', a:'17', hint:'$15^2=225$, $8^2=64$, $225+64=289$', explanation:'$\\sqrt{225+64} = \\sqrt{289} = 17$.' }, + { type:'input', q:'Упрости $\\sqrt{75} - \\sqrt{12}$ — введи коэффициент при $\\sqrt{3}$:', a:'3', hint:'$\\sqrt{75}=5\\sqrt{3}$, $\\sqrt{12}=2\\sqrt{3}$', explanation:'$5\\sqrt{3} - 2\\sqrt{3} = 3\\sqrt{3}$. Коэффициент 3.' }, + { type:'select', q:'Реши $x^2 = 49$. Сколько корней?', a:2, opts:['$0$','$1$','$2$'], hint:'$x = \\pm 7$', explanation:'$x^2 = 49$ имеет два решения: $x = 7$ и $x = -7$.' }, + { type:'select', q:'Область определения $\\sqrt{x-3}+\\sqrt{7-x}$ = ?', a:0, opts:['$[3;7]$','$(3;7)$','$\\mathbb{R}$','$\\varnothing$'], hint:'Нужно $x-3\\geq0$ и $7-x\\geq0$', explanation:'$x\\geq3$ и $x\\leq7$ одновременно: $[3;7]$.' }, + { type:'select', q:'$\\sqrt{10 - 2\\sqrt{21}} = ?$', a:0, opts:['$\\sqrt{7}-\\sqrt{3}$','$\\sqrt{5}-\\sqrt{2}$','$\\sqrt{7}+\\sqrt{3}$','$\\sqrt{10}-1$'], hint:'$10-2\\sqrt{21} = 7-2\\sqrt{21}+3 = (\\sqrt{7}-\\sqrt{3})^2$', explanation:'$(\\sqrt{7}-\\sqrt{3})^2 = 7-2\\sqrt{21}+3 = 10-2\\sqrt{21}$. Ответ: $\\sqrt{7}-\\sqrt{3}$.' }, + { type:'select', q:'Реши $0{,}5 \\leq \\dfrac{x}{3} < 2$', a:0, opts:['$[1{,}5; 6)$','$(1{,}5; 6]$','$[1{,}5; 6]$','$(1{,}5; 6)$'], hint:'Умножь все части на 3', explanation:'$1{,}5 \\leq x < 6$: промежуток $[1{,}5; 6)$.' }, + { type:'input', q:'$\\sqrt{0{,}04 \\cdot 49} = ?$', a:'1.4', hint:'$\\sqrt{0.04}=0.2$, $\\sqrt{49}=7$', explanation:'$\\sqrt{0{,}04\\cdot49} = \\sqrt{0{,}04}\\cdot\\sqrt{49} = 0{,}2\\cdot7 = 1{,}4$.' }, + ], +}; + +/* ── Per-section metadata ── */ +const BOSS_META = { + p1: { tag:'БОСС §1', title:'Знаток корней', ach:'boss_p1', achP:'boss_p1_perfect', sec:'p1' }, + p2: { tag:'БОСС §2', title:'Эксперт по числам', ach:'boss_p2', achP:'boss_p2_perfect', sec:'p2' }, + p3: { tag:'БОСС §3', title:'Свойства корней', ach:'boss_p3', achP:'boss_p3_perfect', sec:'p3' }, + p4: { tag:'БОСС §4', title:'Преобразования', ach:'boss_p4', achP:'boss_p4_perfect', sec:'p4' }, + p5: { tag:'БОСС §5', title:'Числовые промежутки', ach:'boss_p5', achP:'boss_p5_perfect', sec:'p5' }, + p6: { tag:'БОСС §6', title:'Системы неравенств', ach:'boss_p6', achP:'boss_p6_perfect', sec:'p6' }, + final: { tag:'ФИНАЛЬНЫЙ БОСС', title:'Глава 1', ach:'boss_final', achP:'boss_final_perfect', sec:'final' }, +}; + +/* ── Runtime state ── */ +const BOSS_STATE = { + current: null, // secId + idx: 0, // текущая задача + correct: 0, + hintsUsed: 0, + errors: 0, + t0: 0, + secondTry: false, + hintShown: false, +}; + +// Boss results are persisted in STATE.bossResults (initialized in STATE declaration) + +/* ── HTML generator (called inside builders) ── */ +function bossWidget(secId){ + const meta = BOSS_META[secId]; + const tasks = BOSS_TASKS[secId]; + const tot = tasks.length; + return `