feat(algebra-8 ch3): Wave 4 — финал, 7 боссов, практика

§ Финал главы 3:
- BOSS ARENA: 7 боссов (5–7 заданий каждый, иконки <>, ±, [], ∩, ∪, 1/x, ★):
  · §13 Хранитель сравнения — свойства, транзитивность, смена знака
  · §14 Алхимик границ — оценки x+y, x-y, xy
  · §15 Архитектор промежутков — линейные неравенства, запись
  · §16 Дирижёр пересечений — системы и совокупности
  · §17 Мастер параболы — квадратные, D, корни
  · §18 Властелин ОДЗ — дробно-рац., выколотые точки
  · ★ Чемпион неравенств (финал) — 7 заданий из всей главы
- Универсальный движок select / yesno / input, HP-бар, состояние в localStorage
- Сертификат «Чемпион неравенств» при всех 7 победах

Увлекательная математика (3 факта):
- Почему меняется знак при умножении на отрицательное
- Кто придумал знаки $<$ и $>$ (Хэрриот, 1631)
- Неравенство Коши (a+b)/2 ≥ √(ab)

Финальная практика — генератор 5 типов задач (линейные, оценка,
системы, квадратные, ОДЗ). Серия из 5 = достижение.

algebra_8.html: добавлена ссылка «Глава 3 →» в шапке.
This commit is contained in:
Maxim Dolgolyov
2026-05-27 16:24:12 +03:00
parent b540c1b3a0
commit c2ef4f4898
2 changed files with 285 additions and 1 deletions
+4
View File
@@ -760,6 +760,10 @@ input,select,textarea{font-family:inherit}
<svg id="sound-on-ic" class="ic" viewBox="0 0 24 24"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14"/><path d="M15.54 8.46a5 5 0 0 1 0 7.07"/></svg>
<svg id="sound-off-ic" class="ic" viewBox="0 0 24 24" style="display:none"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><line x1="23" y1="9" x2="17" y2="15"/><line x1="17" y1="9" x2="23" y2="15"/></svg>
</button>
<a href="/textbook/algebra-8-ch3" class="hdr-btn" title="Глава 3 — Неравенства">
Глава 3
<svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
</a>
<a href="/textbook/algebra-8-ch2" class="hdr-btn" title="Глава 2 — Квадратные уравнения">
Глава 2
<svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
+281 -1
View File
@@ -2283,7 +2283,287 @@ function buildP18(){
document.getElementById('p18d-reset').addEventListener('click', ()=>{ sorter.reset(); document.getElementById('p18d-fb').style.display='none'; });
})();
}
function buildFinal3stub(){ document.getElementById('final3-body').innerHTML = `<div class="card"><div class="card-body"><p style="text-align:center;padding:20px"><b>Финал главы</b><br><br>Будет в Wave 4 — 7 боссов, увлекательная математика, практика.</p></div></div>${secNav('p18',null)}`; }
function buildFinal3stub(){ buildFinal3(); }
function buildFinal3(){
const box = document.getElementById('final3-body');
let html = '';
html += `<div class="card"><div class="card-header"><div class="card-icon theory">${ICONS.theory}</div><div class="card-title">Поздравляем!</div></div><div class="card-body">
<p>Вы прошли 6 параграфов главы «Неравенства с одной переменной». В финале вас ждут <b>7 боссов</b> — по одному на каждый параграф и один общий. Победите всех — получите титул «Чемпион неравенств».</p>
</div></div>`;
html += widget('Боссы главы 3','BOSS ARENA','Каждый босс — 5 заданий. Победите всех 7, чтобы открыть финальный титул.',`
<div id="boss-grid" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px"></div>
<div id="boss-arena" style="margin-top:14px;display:none">
<div id="boss-head" style="display:flex;align-items:center;gap:14px;padding:14px;background:linear-gradient(135deg,#1f2937,#0f172a);border-radius:10px;color:#fff;margin-bottom:10px">
<div id="boss-emoji" style="font-size:2.4rem;line-height:1">★</div>
<div style="flex:1">
<div id="boss-name" style="font-family:'Unbounded',sans-serif;font-weight:800;font-size:1.05rem"></div>
<div id="boss-subname" style="font-size:.85rem;opacity:.75"></div>
<div class="hp-bar" style="margin-top:6px;background:rgba(255,255,255,.15);height:8px;border-radius:4px;overflow:hidden"><div id="boss-hp" style="height:100%;background:linear-gradient(90deg,#10b981,#fbbf24,#ef4444);width:100%;transition:width .5s"></div></div>
</div>
<button class="btn" id="boss-quit" style="background:rgba(255,255,255,.15);color:#fff;border-color:transparent">Выйти</button>
</div>
<div id="boss-task" style="padding:16px;background:var(--card);border:1.5px solid var(--sec-acc);border-radius:10px;min-height:120px"></div>
<div id="boss-opts" style="display:flex;flex-direction:column;gap:6px;margin-top:10px"></div>
<div id="boss-fb" class="feedback" style="display:none;margin-top:10px"></div>
</div>`);
html += widget('Увлекательная математика','BONUS','3 факта про неравенства.',`
<details class="spoiler" style="margin-bottom:8px"><summary>Почему меняется знак при умножении на отрицательное?</summary>
<div class="spoiler-body">Геометрически: умножение на $-1$ — это отражение числовой прямой относительно нуля. То, что было правее (больше), теперь оказалось левее (меньше). Поэтому «больше» становится «меньше».</div>
</details>
<details class="spoiler" style="margin-bottom:8px"><summary>Кто придумал знаки $<$ и $>$?</summary>
<div class="spoiler-body">Английский математик Томас Хэрриот в 1631 году предложил эти знаки. Левый конец — узкий, правый — широкий: с маленькой стороны меньшее, с широкой — большее. Знак <i>точка слева, точка справа</i> наглядно показывает направление сравнения.</div>
</details>
<details class="spoiler"><summary>Неравенство Коши</summary>
<div class="spoiler-body">Знаменитое неравенство: $\\dfrac{a + b}{2} \\geq \\sqrt{ab}$ для $a, b \\geq 0$ — среднее арифметическое не меньше среднего геометрического. Равенство — когда $a = b$. Это краеугольный камень многих доказательств в высшей математике.</div>
</details>`);
html += widget('Финальная практика','PRACTICE','Случайные задачи из всей главы.',`
<div class="score-display"><span>Решено: <b id="prac-i">0</b></span><span>Правильно: <b id="prac-score">0</b></span><span>Серия: <b id="prac-streak">0</b></span></div>
<div id="prac-task" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.05rem;line-height:1.6;margin-bottom:10px"></div>
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:center;justify-content:center">
<input type="text" id="prac-inp" placeholder="ответ" class="tinp" style="width:200px">
<button class="btn primary" id="prac-go">Ответ</button>
<button class="btn" id="prac-next">Следующая</button>
</div>
<div class="feedback" id="prac-fb" style="display:none;margin-top:10px"></div>`);
html += `<div class="card"><div class="card-header"><div class="card-icon home">${ICONS.home}</div><div class="card-title">Сертификат прохождения</div></div><div class="card-body">
<p>Как вы оцените своё знание неравенств?</p>
<div id="cert-state" style="margin-top:10px;font-size:.9rem;color:var(--muted)"></div>
</div></div>`;
html += secNav('p18', null);
box.innerHTML = html;
if(window.renderMathInElement) setTimeout(()=>renderMath(box), 0);
/* BOSSES */
const BOSSES = [
{ id:'b1', name:'Хранитель сравнения', sub:'§ 13 · свойства неравенств', icon:'<>', hp:5, tasks:[
{ t:'select', q:'Что больше: $-7$ или $-3$?', opts:['$-3$','$-7$','равны','зависит'], ok:0 },
{ t:'yesno', q:'При умножении на $-2$ знак неравенства меняется.', ok:true },
{ t:'input', q:'Дано $a > b$. Найдите $c$ такое, что $a + c$ и $b + c$ остаются в том же порядке. (введите любое число, например 5)', ans:[5] },
{ t:'select', q:'$a > b$, $b > c$. Тогда:', opts:['$a > c$','$a < c$','$a = c$','зависит'], ok:0 },
{ t:'yesno', q:'Из $a > b > 0$ следует $a^2 > b^2$.', ok:true },
]},
{ id:'b2', name:'Алхимик границ', sub:'§ 14 · оценка значений', icon:'±', hp:5, tasks:[
{ t:'input', q:'$1 \\leq x \\leq 3$, $2 \\leq y \\leq 5$. Найдите верхнюю границу $x + y$.', ans:[8] },
{ t:'input', q:'Те же границы. Найдите нижнюю границу $x - y$.', ans:[-4] },
{ t:'input', q:'Те же границы (все $>0$). Найдите верхнюю границу $xy$.', ans:[15] },
{ t:'yesno', q:'Можно сложить $a > b$ и $c < d$, чтобы получить $a + c > b + d$.', ok:false },
{ t:'select', q:'Если $0 < a < b$ и $0 < c < d$, то:', opts:['$ac < bd$','$ac > bd$','$ac = bd$','неизвестно'], ok:0 },
]},
{ id:'b3', name:'Архитектор промежутков', sub:'§ 15 · линейные', icon:'[]', hp:5, tasks:[
{ t:'select', q:'Решение $2x - 4 > 0$:', opts:['$(2;\\,+\\infty)$','$[2;\\,+\\infty)$','$(-\\infty;\\,2)$','$\\{2\\}$'], ok:0 },
{ t:'select', q:'Решение $-3x \\geq 9$:', opts:['$(-\\infty;\\,-3]$','$[-3;\\,+\\infty)$','$(-\\infty;\\,3]$','$[3;\\,+\\infty)$'], ok:0 },
{ t:'yesno', q:'Промежуток $[2;\\,5)$ включает точку $5$.', ok:false },
{ t:'select', q:'Запись $x > 4$ соответствует:', opts:['$(4;\\,+\\infty)$','$[4;\\,+\\infty)$','$(-\\infty;\\,4)$','$(-\\infty;\\,4]$'], ok:0 },
{ t:'input', q:'Корень неравенства $5x = 25$ (граница). Чему равен $x$?', ans:[5] },
]},
{ id:'b4', name:'Дирижёр пересечений', sub:'§ 16 · системы', icon:'∩', hp:5, tasks:[
{ t:'select', q:'$\\begin{cases} x > 2 \\\\ x \\leq 5 \\end{cases}$:', opts:['$(2;\\,5]$','$[2;\\,5)$','$(2;\\,5)$','$\\emptyset$'], ok:0 },
{ t:'yesno', q:'Система $\\begin{cases} x > 5 \\\\ x < 3 \\end{cases}$ имеет решение.', ok:false },
{ t:'select', q:'Совокупность $\\left[\\begin{array}{l} x < 0 \\\\ x \\geq 4 \\end{array}\\right.$:', opts:['$(-\\infty;\\,0) \\cup [4;\\,+\\infty)$','$[0;\\,4)$','$\\emptyset$','$\\mathbb{R}$'], ok:0 },
{ t:'yesno', q:'Система использует логическое «И», совокупность — «ИЛИ».', ok:true },
{ t:'select', q:'Пересечение $[1;\\,5]$ и $[3;\\,8]$:', opts:['$[3;\\,5]$','$[1;\\,8]$','$\\emptyset$','$[1;\\,3]$'], ok:0 },
]},
{ id:'b5', name:'Мастер параболы', sub:'§ 17 · квадратные', icon:'', hp:5, tasks:[
{ t:'select', q:'Решение $x^2 - 4 > 0$:', opts:['$(-\\infty;\\,-2) \\cup (2;\\,+\\infty)$','$(-2;\\,2)$','$[-2;\\,2]$','$\\emptyset$'], ok:0 },
{ t:'select', q:'$x^2 + 1 > 0$:', opts:['$\\mathbb{R}$','$\\emptyset$','$x \\neq 0$','$x > 0$'], ok:0 },
{ t:'yesno', q:'При $D < 0$ и $a > 0$ выражение $ax^2 + bx + c$ всегда положительно.', ok:true },
{ t:'select', q:'$x^2 - 5x + 6 \\leq 0$ имеет решение:', opts:['$[2;\\,3]$','$(2;\\,3)$','$(-\\infty;\\,2) \\cup (3;\\,+\\infty)$','$\\emptyset$'], ok:0 },
{ t:'input', q:'Сколько решений у $x^2 + 9 < 0$ (количество, 0 если нет)?', ans:[0] },
]},
{ id:'b6', name:'Властелин ОДЗ', sub:'§ 18 · дробно-рац.', icon:'1/x', hp:5, tasks:[
{ t:'input', q:'Запрещённая точка для $\\dfrac{1}{x - 5}$:', ans:[5] },
{ t:'select', q:'$\\dfrac{x - 1}{x + 2} > 0$:', opts:['$(-\\infty;\\,-2) \\cup (1;\\,+\\infty)$','$(-2;\\,1)$','$[-2;\\,1]$','$\\emptyset$'], ok:0 },
{ t:'yesno', q:'Точка, где знаменатель равен нулю, ВСЕГДА выколотая.', ok:true },
{ t:'select', q:'$\\dfrac{x + 3}{x - 4} \\leq 0$:', opts:['$[-3;\\,4)$','$(-3;\\,4)$','$[-3;\\,4]$','$\\emptyset$'], ok:0 },
{ t:'yesno', q:'$\\dfrac{1}{x} > 0$ верно при любом $x \\neq 0$.', ok:false },
]},
{ id:'b7', name:'Чемпион неравенств', sub:'Финал · вся глава', icon:'★', hp:7, tasks:[
{ t:'input', q:'$4x + 3 > 11$. Граничное значение $x$:', ans:[2] },
{ t:'select', q:'Знак $a > b$ после умножения на $-5$:', opts:['Меняется','Не меняется','Зависит','Исчезает'], ok:0 },
{ t:'select', q:'$1 \\leq x \\leq 4$, $2 \\leq y \\leq 6$. Верхняя граница $xy$:', opts:['$24$','$8$','$12$','$10$'], ok:0 },
{ t:'select', q:'$\\begin{cases} x \\geq 0 \\\\ x \\leq 10 \\end{cases}$:', opts:['$[0;\\,10]$','$(0;\\,10)$','$\\mathbb{R}$','$\\emptyset$'], ok:0 },
{ t:'select', q:'$x^2 - 9 < 0$:', opts:['$(-3;\\,3)$','$[-3;\\,3]$','$(-\\infty;\\,-3) \\cup (3;\\,+\\infty)$','$\\emptyset$'], ok:0 },
{ t:'input', q:'Запрещённая точка для $\\dfrac{x + 1}{x - 7}$:', ans:[7] },
{ t:'yesno', q:'Метод интервалов работает только для квадратных неравенств.', ok:false },
]},
];
const BOSS_STATE = (function(){
try { return JSON.parse(localStorage.getItem('algebra8_ch3_bosses') || '{}'); } catch(e){ return {}; }
})();
function saveBosses(){ try{ localStorage.setItem('algebra8_ch3_bosses', JSON.stringify(BOSS_STATE)); }catch(e){} }
function renderBossGrid(){
const g = document.getElementById('boss-grid');
g.innerHTML = '';
BOSSES.forEach(b=>{
const won = BOSS_STATE[b.id];
const c = document.createElement('div');
c.style.cssText = 'background:' + (won ? 'linear-gradient(135deg,var(--ok-bg),#d1fae5)' : 'var(--card)') + ';border:1.5px solid ' + (won ? 'var(--ok)' : 'var(--border)') + ';border-radius:10px;padding:10px 12px;cursor:pointer;text-align:center;transition:transform .15s,box-shadow .15s';
c.innerHTML = '<div style="font-size:1.5rem;line-height:1;margin-bottom:4px;font-family:JetBrains Mono,monospace">' + b.icon + '</div><div style="font-family:Unbounded,sans-serif;font-size:.78rem;font-weight:800;color:var(--sec-acc-d)">' + b.name + '</div><div style="font-size:.7rem;color:var(--muted);margin-top:2px">' + b.sub + '</div>' + (won ? '<div style="color:var(--ok);font-weight:700;font-size:.8rem;margin-top:4px">&#10003; Побеждён</div>' : '<div style="margin-top:4px"><button class="btn small" style="font-size:.72rem">В бой</button></div>');
c.addEventListener('click', ()=>startBoss(b.id));
c.addEventListener('mouseover', ()=>{ c.style.transform='translateY(-2px)'; c.style.boxShadow='var(--sh2)'; });
c.addEventListener('mouseout', ()=>{ c.style.transform=''; c.style.boxShadow=''; });
g.appendChild(c);
});
if(window.renderMathInElement) renderMath(g);
}
let currentBoss = null, taskIdx = 0, hpLeft = 0;
function startBoss(id){
const b = BOSSES.find(x => x.id === id);
if(!b) return;
currentBoss = b; taskIdx = 0; hpLeft = b.hp;
document.getElementById('boss-arena').style.display = 'block';
document.getElementById('boss-name').textContent = b.name;
document.getElementById('boss-subname').textContent = b.sub;
document.getElementById('boss-emoji').textContent = b.icon;
showTask();
}
function showTask(){
const t = currentBoss.tasks[taskIdx];
if(!t){ winBoss(); return; }
document.getElementById('boss-hp').style.width = (hpLeft / currentBoss.hp * 100) + '%';
const tEl = document.getElementById('boss-task');
tEl.innerHTML = '<div style="font-size:.75rem;color:var(--muted);margin-bottom:6px">Задание ' + (taskIdx + 1) + ' / ' + currentBoss.tasks.length + '</div><div style="font-size:1.05rem">' + t.q + '</div>';
renderMath(tEl);
const opts = document.getElementById('boss-opts'); opts.innerHTML = '';
document.getElementById('boss-fb').style.display = 'none';
if(t.t === 'select'){
t.opts.forEach((o, k)=>{
const b = document.createElement('button');
b.className = 'btn'; b.innerHTML = o; b.style.cssText = 'text-align:left';
b.addEventListener('click', ()=>checkAnswer(k === t.ok, b));
opts.appendChild(b);
});
renderMath(opts);
} else if(t.t === 'yesno'){
['Да','Нет'].forEach((lab, k)=>{
const b = document.createElement('button');
b.className = 'btn'; b.textContent = lab;
b.addEventListener('click', ()=>checkAnswer((k === 0) === t.ok, b));
opts.appendChild(b);
});
} else if(t.t === 'input'){
const wrap = document.createElement('div');
wrap.style.cssText = 'display:flex;gap:8px;align-items:center';
const inp = document.createElement('input');
inp.type = 'text'; inp.placeholder = 'ваш ответ'; inp.className = 'tinp'; inp.style.flex = '1';
const go = document.createElement('button'); go.className = 'btn primary'; go.textContent = 'Ответ';
go.addEventListener('click', ()=>{
const u = parseFloat(inp.value.replace(',','.'));
const ok = t.ans.some(a => Math.abs(u - a) < 1e-6);
checkAnswer(ok, go);
});
inp.addEventListener('keyup', e=>{ if(e.key === 'Enter') go.click(); });
wrap.appendChild(inp); wrap.appendChild(go); opts.appendChild(wrap);
}
}
function checkAnswer(ok, btn){
const fb = document.getElementById('boss-fb'); fb.style.display = 'block';
if(ok){
if(btn) btn.classList.add('ok');
feedback(fb, true, '&#10003; Точное попадание!');
taskIdx++;
setTimeout(showTask, 700);
} else {
if(btn) btn.classList.add('fail');
feedback(fb, false, '&#10007; Промах! Попробуйте ещё.');
}
}
function winBoss(){
BOSS_STATE[currentBoss.id] = 1; saveBosses();
achievement('boss_' + currentBoss.id, 'Победил: ' + currentBoss.name);
bumpProgress('final3', 14); confetti();
document.getElementById('boss-task').innerHTML = '<div style="text-align:center;padding:20px"><div style="font-size:3rem;font-family:JetBrains Mono,monospace">' + currentBoss.icon + '</div><h3 style="color:var(--ok);margin:10px 0">Победа!</h3><p>Босс <b>«' + currentBoss.name + '»</b> повержен.</p></div>';
document.getElementById('boss-opts').innerHTML = '<button class="btn primary" id="boss-back">К списку боссов</button>';
document.getElementById('boss-fb').style.display = 'none';
document.getElementById('boss-back').addEventListener('click', closeBoss);
renderBossGrid();
if(BOSSES.every(b => BOSS_STATE[b.id])){
setTimeout(()=>{ achievement('all_bosses', 'Чемпион неравенств!'); confetti(); refreshCert(); }, 800);
}
}
function closeBoss(){ document.getElementById('boss-arena').style.display = 'none'; currentBoss = null; }
document.getElementById('boss-quit').addEventListener('click', closeBoss);
renderBossGrid();
/* PRACTICE */
(function(){
let cur = null, total = 0, score = 0, streak = 0;
function gen(){
const t = Math.floor(Math.random()*5);
if(t === 0){
// линейное
const a = (Math.random()<0.5?-1:1)*(1+Math.floor(Math.random()*4));
const b = -5+Math.floor(Math.random()*11);
const c = -5+Math.floor(Math.random()*11);
const v = (c - b) / a;
const flip = a < 0;
return { q:'Решите $' + a + 'x ' + (b>=0?'+ '+b:'- '+Math.abs(b)) + ' > ' + c + '$. Введите граничное значение $x$.', ans:[v] };
}
if(t === 1){
// оценка
const a = 1+Math.floor(Math.random()*3), b = a+1+Math.floor(Math.random()*3);
const c = 1+Math.floor(Math.random()*3), d = c+1+Math.floor(Math.random()*3);
return { q:'Дано: $' + a + ' \\leq x \\leq ' + b + '$, $' + c + ' \\leq y \\leq ' + d + '$. Верхняя граница $x + y$:', ans:[b + d] };
}
if(t === 2){
// система
const a = -5+Math.floor(Math.random()*5), b = a+2+Math.floor(Math.random()*5);
return { q:'$\\begin{cases} x > ' + a + ' \\\\ x \\leq ' + b + ' \\end{cases}$. Введите верхнюю границу.', ans:[b] };
}
if(t === 3){
// квадратное
const r = 1+Math.floor(Math.random()*5);
return { q:'Сколько корней у $x^2 - ' + (r*r) + ' = 0$?', ans:[2] };
}
// дробное
const r = (Math.random()<0.5?-1:1)*(1+Math.floor(Math.random()*8));
return { q:'Запрещённая точка для $\\dfrac{1}{x - ' + r + '}$:', ans:[r] };
}
function show(){
cur = gen();
document.getElementById('prac-task').innerHTML = cur.q;
renderMath(document.getElementById('prac-task'));
document.getElementById('prac-inp').value = '';
document.getElementById('prac-fb').style.display = 'none';
}
document.getElementById('prac-go').addEventListener('click', ()=>{
const fb = document.getElementById('prac-fb'); fb.style.display = 'block';
const u = parseFloat(document.getElementById('prac-inp').value.replace(',','.'));
const ok = cur.ans.some(a => Math.abs(u - a) < 1e-6);
total++;
if(ok){ score++; streak++; feedback(fb, true, '&#10003;'); if(streak === 5){ achievement('prac_streak', 'Серия из 5!'); confetti(); } }
else { streak = 0; feedback(fb, false, 'Правильно: ' + cur.ans.join(', ')); }
document.getElementById('prac-i').textContent = total;
document.getElementById('prac-score').textContent = score;
document.getElementById('prac-streak').textContent = streak;
if(total >= 5) bumpProgress('final3', 4);
});
document.getElementById('prac-next').addEventListener('click', show);
document.getElementById('prac-inp').addEventListener('keyup', e=>{ if(e.key === 'Enter') document.getElementById('prac-go').click(); });
show();
})();
function refreshCert(){
const won = BOSSES.filter(b => BOSS_STATE[b.id]).length;
const cs = document.getElementById('cert-state');
if(!cs) return;
if(won === BOSSES.length){
cs.innerHTML = '<div style="padding:18px;background:linear-gradient(135deg,#fef3c7,#ede9fe);border:2px solid #8b5cf6;border-radius:12px;text-align:center"><div style="font-family:Unbounded,sans-serif;font-size:1.2rem;font-weight:900;color:#6d28d9">ЧЕМПИОН НЕРАВЕНСТВ</div><div style="font-size:.9rem;color:#5b21b6;margin-top:4px">Все 7 боссов главы 3 повержены &mdash; вы освоили §§ 1318.</div></div>';
} else {
cs.innerHTML = 'Побеждено боссов: <b>' + won + ' / ' + BOSSES.length + '</b>. Победите всех, чтобы получить титул.';
}
}
refreshCert();
}
</script>
<script>