Files
Learn_System/frontend/textbooks/math_5_ch3.html
T
Maxim Dolgolyov 5a2a1be089 feat(math5): Глава 3 «Обыкновенные дроби» — §1–18 + финал (Sonnet по эталону)
Дроби и доли, основное свойство и сокращение, смешанные числа, сравнение,
сложение/вычитание/умножение/деление дробей, задачи на дроби; геометрия:
параллельные/перпендикулярные прямые, периметр многоугольника, площадь и
площадь треугольника, среднее арифметическое, столбчатые диаграммы,
параллелепипед и объём (2D-изометрия). Inline-SVG визуалы (полоса долей,
сетка умножения, изометрия). Реализовано Sonnet-агентом инкрементально по
образцу math_5_ch1; проверено: грузится без ошибок, §1–18 без заглушек.

Учебник «Математика 5» наполнен ЦЕЛИКОМ (3 главы, 44 §). Тесты math5: 12/12.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 10:34:15 +03:00

1569 lines
147 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>Математика 5 · Глава 3 · Обыкновенные дроби</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Unbounded:wght@700;800;900&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/css/math6.css">
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/math6_svg.js" defer></script>
<script src="/js/math6_anim.js" defer></script>
<script src="/js/math6_engine.js" defer></script>
<style>:root{--pri:#e11d48;--pri2:#be123c;--pri-soft:#ffe4e6;--acc:#f43f5e;--acc2:#e11d48;--acc-soft:#fff1f2}</style>
</head>
<body>
<header class="hdr" data-wm="¾">
<div class="hdr-row">
<div>
<h1>Математика 5 · Глава 3</h1>
<div class="hdr-sub">Обыкновенные дроби: доли · смешанные числа · действия · многоугольники · площадь и объём</div>
</div>
<div class="hdr-side">
<a href="/textbook/math-5" class="hdr-btn" title="Ко всем главам"><svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> К математике 5</a>
<button id="search-btn" class="hdr-btn" title="Поиск (Ctrl+K)"><svg class="ic" viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg> <span>Поиск</span></button>
<button id="sidebar-btn" class="hdr-btn" title="Шпаргалка"><svg class="ic" viewBox="0 0 24 24"><line x1="4" y1="6" x2="20" y2="6"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="18" x2="14" y2="18"/></svg> Шпаргалка</button>
<button id="theme-btn" class="hdr-btn" title="Сменить тему"><svg class="ic" viewBox="0 0 24 24"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg> <span id="theme-lab">Тёмная</span></button>
</div>
</div>
</header>
<main class="main">
<div class="col-main">
<section class="hero" data-wm="¾">
<h2>Обыкновенные дроби</h2>
<p>Дробь показывает <b>часть целого</b>: половина пиццы, четверть часа, две трети пути. В этой главе мы научимся записывать и сокращать дроби, переводить <b>неправильные дроби в смешанные числа</b>, сравнивать дроби, выполнять <b>сложение, вычитание, умножение и деление</b> дробей, а попутно изучим геометрию: <b>параллельные и перпендикулярные прямые</b>, <b>периметр</b> многоугольников, <b>площадь</b> и <b>объём</b> параллелепипеда.</p>
<div class="hero-row">
<button class="btn-primary" onclick="goTo('p1')"><svg class="ic" viewBox="0 0 24 24"><polygon points="6 4 20 12 6 20 6 4" fill="currentColor" stroke="none"/></svg> Начать § 1</button>
<div class="hero-progress"><span class="hp-label">Прогресс по главе</span><div class="hp-bar"><div id="hero-hp-fill" class="hp-fill"></div></div><span id="hero-hp-text" class="hp-text">0%</span></div>
<div id="hero-xp-badge" class="hero-xp-badge" title="Опыт" data-gamified></div>
</div>
</section>
<section class="psel"><div class="psel-title">Параграфы главы</div><div id="psel-grid" class="psel-grid"></div></section>
<div id="sections"></div>
</div>
<aside class="col-side" id="col-side"><div id="sidebar-content"></div></aside>
<div class="col-side-backdrop" id="col-side-backdrop"></div>
</main>
<footer class="foot" id="m6-foot">Интерактивный учебник «Математика 5» · Глава 3 · Обыкновенные дроби · LearnSpace</footer>
<div id="ach-popup" class="ach-popup"><svg class="ic" viewBox="0 0 24 24" style="width:22px;height:22px"><polygon points="12,2 22,20 2,20"/></svg><span id="ach-text">Достижение!</span></div>
<div id="gloss-tip" class="gloss-tip"></div>
<div id="search-modal" class="search-modal" role="dialog" aria-label="Поиск по главе">
<div class="search-box">
<input type="text" id="search-input" class="search-input" placeholder="Поиск: понятие, действие, параграф…" autocomplete="off">
<div id="search-results" class="search-results"></div>
<div class="search-foot"><span><kbd>&#8593;&#8595;</kbd> навигация</span><span><kbd>Enter</kbd> открыть</span><span><kbd>Esc</kbd> закрыть</span></div>
</div>
</div>
<script>
'use strict';
window.M6 = {
slug: 'math-5-ch3', lsPrefix: 'math5_ch3', xpKey: 'math5_xp', wm: '¾',
paras: [
{ id:'p1', num:'§ 1', name:'Дробные числа. Обыкновенные дроби', sub:'Доли целого' },
{ id:'p2', num:'§ 2', name:'Деление и дроби. Основное свойство дроби', sub:'Сокращение дробей' },
{ id:'p3', num:'§ 3', name:'Правильные, неправильные и смешанные числа', sub:'Целая и дробная части' },
{ id:'p4', num:'§ 4', name:'Сравнение дробных чисел', sub:'Какая дробь больше' },
{ id:'p5', num:'§ 5', name:'Сложение и вычитание обыкновенных дробей', sub:'Общий знаменатель' },
{ id:'p6', num:'§ 6', name:'Сложение и вычитание смешанных чисел', sub:'Целые и дроби вместе' },
{ id:'p7', num:'§ 7', name:'Умножение дробных чисел', sub:'Дробь на дробь' },
{ id:'p8', num:'§ 8', name:'Деление дробных чисел', sub:'Умножаем на обратную' },
{ id:'p9', num:'§ 9', name:'Задачи на все действия с дробями', sub:'Комбинируем действия' },
{ id:'p10', num:'§ 10', name:'Задачи на применение дробей', sub:'Часть от числа' },
{ id:'p11', num:'§ 11', name:'Параллельные и перпендикулярные прямые', sub:'∥ и ⟂' },
{ id:'p12', num:'§ 12', name:'Ломаная. Многоугольник. Периметр', sub:'Сумма длин сторон' },
{ id:'p13', num:'§ 13', name:'Площадь. Единицы измерения площади', sub:'Квадратные единицы' },
{ id:'p14', num:'§ 14', name:'Площадь прямоугольного треугольника', sub:'Половина прямоугольника' },
{ id:'p15', num:'§ 15', name:'Среднее арифметическое', sub:'Сумма ÷ количество' },
{ id:'p16', num:'§ 16', name:'Линейные и столбчатые диаграммы', sub:'Читаем данные' },
{ id:'p17', num:'§ 17', name:'Прямоугольный параллелепипед. Куб', sub:'Грани, рёбра, вершины' },
{ id:'p18', num:'§ 18', name:'Объём параллелепипеда', sub:'Считаем единичные кубики' },
{ id:'final', num:'★', name:'Финал главы', sub:'Тест · боссы главы 3', final:true }
],
achLabels: { final_done:'Глава 3 пройдена!' },
finalAch: ['ch3_done', 'Глава 3 «Обыкновенные дроби» пройдена!'],
sidebars: {}, tips: [], glossary: [], searchRows: [], builders: {},
footer: 'Интерактивный учебник «Математика 5» · Глава 3 · Обыкновенные дроби · LearnSpace'
};
/* ==== ХЕЛПЕРЫ ==== */
function _ri(a,b){ return a + Math.floor(Math.random()*(b-a+1)); }
function _pick(a){ return a[_ri(0,a.length-1)]; }
function _kf(x){ return String(x).replace('.','{,}'); }
function _grp(s){ s=String(s); var o='',c=0; for(var i=s.length-1;i>=0;i--){ o=s[i]+o; if(++c%3===0&&i>0)o='\\,'+o; } return o; }
function gcd(a,b){ while(b){var t=b;b=a%b;a=t;} return a; }
/* ==== BUILDERS ==== */
function buildFinal(){
var box=document.getElementById('final-body'); var h='';
h+=makeCard('theory','Финал главы 3','★',
'<p>Пять боссов проверят владение дробями и геометрией. Победи не меньше четырёх — и глава покорена!</p>');
h+='<div class="wg" id="fin"><div class="wg-header"><span class="wg-badge">Боссы</span><div class="wg-title">Сразись с главой 3</div></div>'
+'<div class="hp-boss"><div class="hp-boss-fill" id="fin-hp" style="width:100%"></div></div>'
+'<div class="score-display"><span>Босс <b id="fin-i">1</b> / 5</span><span>Побеждено: <b id="fin-s">0</b> / 5</span></div>'
+'<div id="fin-name" style="font-weight:800;color:#b91c1c;text-align:center;margin-bottom:6px"></div>'
+'<div id="fin-q" class="boss-q"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="fin-a" class="tinp" style="width:160px;text-align:center" placeholder="ответ"><button class="btn primary" id="fin-go">Удар!</button></div>'
+'<div class="feedback" id="fin-fb"></div></div>';
h+=secNav('p18',null)+readBtn('final','Завершить главу 3 (+10 XP)');
box.innerHTML=h; renderMath(box);
(function(){
var bosses=[
function(){ var n=_ri(1,7),d=_ri(n+1,10); return {name:'Страж Долей', q:'Сократи дробь $\\dfrac{'+(n*2)+'}{'+( d*2)+'}$. Введи числитель (знаменатель '+d+').', ans:n}; },
function(){ var a=_ri(1,4),b=_ri(1,4),d=_ri(3,8); return {name:'Лорд Слагаемых', q:'$\\dfrac{'+a+'}{'+d+'} + \\dfrac{'+b+'}{'+d+'}$ — числитель результата (знаменатель '+d+').', ans:a+b}; },
function(){ var a=_ri(2,5),b=_ri(2,5); return {name:'Умножитель Дробей', q:'$\\dfrac{'+a+'}{'+( a+1)+'} \\cdot \\dfrac{'+(a+1)+'}{'+b+'}$ — числитель результата (знаменатель '+b+').', ans:a}; },
function(){ var n=_ri(2,9),k=_ri(2,7); return {name:'Часть от числа', q:'Найди $\\dfrac{'+n+'}{'+k+'}$ от числа '+(n*k)+'.', ans:n*n}; },
function(){ var a=_ri(2,6),b=_ri(2,6),c=_ri(1,4); return {name:'Мастер Площади', q:'Площадь прямоугольника '+a+' × '+b+' = ?', ans:a*b}; }
];
var i=0,score=0,cur=null,done=false;
function show(){
if(i>=5){ done=true; document.getElementById('fin-name').textContent=''; document.getElementById('fin-q').innerHTML=(score>=4?'<b>Победа!</b> Глава 3 пройдена. ':'<b>Бой окончен.</b> ')+'Побеждено боссов: '+score+' / 5.';
document.getElementById('fin-hp').style.width=(score>=4?0:40)+'%';
if(score>=4){ addXp(40,'final'); bumpProgress('final',100); if(window.confetti)try{confetti();}catch(e){} } else { bumpProgress('final',60); }
return; }
cur=bosses[i](); document.getElementById('fin-i').textContent=i+1; document.getElementById('fin-s').textContent=score;
document.getElementById('fin-name').textContent='Босс '+(i+1)+': '+cur.name;
document.getElementById('fin-hp').style.width=(100-i*20)+'%';
document.getElementById('fin-q').innerHTML=cur.q; renderMath(document.getElementById('fin-q'));
document.getElementById('fin-a').value=''; document.getElementById('fin-fb').style.display='none'; }
function go(){ if(done||i>=5)return; var fb=document.getElementById('fin-fb'), v=parseFloat(document.getElementById('fin-a').value.replace(',','.').trim());
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(Math.abs(v-cur.ans)<1e-9){ score++; feedback(fb,true,'✓ Босс повержен! Ответ '+cur.ans+'.'); } else feedback(fb,false,'✗ Босс устоял. Верный ответ: '+cur.ans+'.');
document.getElementById('fin-s').textContent=score; i++; setTimeout(show,1400); }
document.getElementById('fin-go').addEventListener('click',go);
document.getElementById('fin-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 1. ДРОБНЫЕ ЧИСЛА ==== */
function buildP1(){
var box=document.getElementById('p1-body'); var h='';
h+=makeCard('oral','Где это в жизни','1.0',
'<p>Мама режет пирог на $4$ равные части и даёт тебе одну. Ты съел <b>четверть</b> пирога — это дробь $\\dfrac{1}{4}$. Стрелка часов прошла половину круга — это $\\dfrac{1}{2}$. Дроби встречаются везде, где что-то делят на равные части.</p>');
h+=makeCard('theory','Обыкновенная дробь','1.1',
'<p>Если единицу разбить на $n$ равных частей, каждая такая часть называется <b>$\\dfrac{1}{n}$</b> (одна $n$-ая).</p>'
+'<p>$m$ таких долей записывают дробью $\\dfrac{m}{n}$, где $m$ — <b>числитель</b> (сколько взяли), $n$ — <b>знаменатель</b> (на сколько делили).</p>'
+'<div id="p1-fig" style="text-align:center;margin:10px 0">'
+'<svg viewBox="0 0 280 50" width="280" style="max-width:100%">'
+'<rect x="4" y="10" width="272" height="30" rx="4" fill="#ffe4e6" stroke="#e11d48" stroke-width="1.5"/>'
+'<rect x="4" y="10" width="68" height="30" rx="4" fill="#e11d48"/>'
+'<line x1="72" y1="10" x2="72" y2="40" stroke="#e11d48" stroke-width="1.5"/>'
+'<line x1="140" y1="10" x2="140" y2="40" stroke="#e11d48" stroke-width="1.5"/>'
+'<line x1="208" y1="10" x2="208" y2="40" stroke="#e11d48" stroke-width="1.5"/>'
+'<text x="38" y="30" font-size="13" font-weight="700" fill="white" text-anchor="middle">1</text>'
+'<text x="106" y="30" font-size="13" fill="#e11d48" text-anchor="middle">2</text>'
+'<text x="174" y="30" font-size="13" fill="#e11d48" text-anchor="middle">3</text>'
+'<text x="242" y="30" font-size="13" fill="#e11d48" text-anchor="middle">4</text>'
+'<text x="140" y="6" font-size="10" fill="var(--muted)" text-anchor="middle">Закрашена 1 из 4 частей — дробь ¼</text>'
+'</svg></div>');
h+=makeCard('rule','Как читать дробь','1.2',
'<p>$\\dfrac{3}{5}$ — «три пятых». &nbsp; $\\dfrac{7}{8}$ — «семь восьмых». &nbsp; $\\dfrac{1}{2}$ — «одна вторая» (половина). &nbsp; $\\dfrac{1}{4}$ — «одна четвёртая» (четверть).</p>');
h+=makeCard('example','Разбор по шагам','1.3',
'<p>Прямоугольник разделён на $8$ равных частей, $3$ из них закрашены. Запиши дробь.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Знаменатель = на сколько частей разбит: $8$.</li>'
+'<li>Числитель = сколько частей взяли: $3$.</li>'
+'<li>Дробь: $\\dfrac{3}{8}$. Читаем «три восьмых».</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','1.4',
'<p>Древние египтяне использовали только дроби с числителем $1$ — так называемые <b>единичные дроби</b>. Например, вместо $\\dfrac{2}{5}$ они писали $\\dfrac{1}{3}+\\dfrac{1}{15}$. Их таблицы из папируса Ахмеса дошли до нас через $3700$ лет!</p>');
h+='<div class="wg" id="p1-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Запиши дробь по рисунку</div></div>'
+'<div class="wg-help">Полоска разбита на равные части. Введи числитель (закрашенные части).</div>'
+'<div class="score-display"><span>Вопрос <b id="p1-i">1</b> / 6</span><span>Очки: <b id="p1-s">0</b> / 6</span></div>'
+'<div id="p1-fig2" style="text-align:center;margin:8px 0"></div>'
+'<div style="display:flex;gap:6px;justify-content:center;align-items:center;flex-wrap:wrap">'
+'<span style="font-size:1.1rem">Числитель:</span><input type="number" id="p1-a" class="tinp" style="width:80px;text-align:center" min="1"><button class="btn primary" id="p1-go">Проверить</button></div>'
+'<div class="feedback" id="p1-fb"></div></div>';
h+='<div class="wg" id="p1-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Найди дробь от числа</div></div>'
+'<div class="wg-help">Вычисли дробную часть от числа. Ответ целое число.</div>'
+'<div class="score-display"><span>Задача <b id="p1-pi">1</b> / 5</span><span>Очки: <b id="p1-ps">0</b> / 5</span></div>'
+'<div id="p1-pq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p1-pa" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p1-pgo">Проверить</button></div>'
+'<div class="feedback" id="p1-pfb"></div></div>';
h+=secNav(null,'p2')+readBtn('p1');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function stripSVG(n,m){ var W=280,H=40,pw=Math.floor((W-8)/n),s='<svg viewBox="0 0 '+W+' '+H+'" width="280" style="max-width:100%">';
for(var k=0;k<n;k++){ var x=4+k*pw; s+='<rect x="'+x+'" y="6" width="'+(pw-2)+'" height="28" rx="3" fill="'+(k<m?'#e11d48':'#ffe4e6')+'" stroke="#e11d48" stroke-width="1"/>'; }
return s+'</svg>'; }
function gen(){ var n=_ri(3,8), m=_ri(1,n-1); cur={n:n,m:m}; }
function show(){ if(i>=6){ document.getElementById('p1-fig2').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p1-iv1');bumpProgress('p1',30);}else if(score>=3){addXp(8,'p1-iv1');bumpProgress('p1',16);} return; }
gen(); document.getElementById('p1-i').textContent=i+1;
document.getElementById('p1-fig2').innerHTML=stripSVG(cur.n,cur.m)+'<div style="color:var(--muted);font-size:.85rem;margin-top:2px">Знаменатель: '+cur.n+'</div>';
document.getElementById('p1-a').value=''; document.getElementById('p1-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p1-fb'), v=parseInt(document.getElementById('p1-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.m){ score++; feedback(fb,true,'✓ Верно! Дробь $\\dfrac{'+cur.m+'}{'+cur.n+'}$.'); renderMath(fb); } else feedback(fb,false,'✗ Нет. Закрашено '+cur.m+' частей.');
document.getElementById('p1-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p1-go').addEventListener('click',go);
document.getElementById('p1-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var PROB=[
{q:'$\\dfrac{1}{4}$ от $20$',ans:5},{q:'$\\dfrac{1}{3}$ от $18$',ans:6},{q:'$\\dfrac{1}{5}$ от $35$',ans:7},
{q:'$\\dfrac{1}{6}$ от $42$',ans:7},{q:'$\\dfrac{1}{7}$ от $49$',ans:7},{q:'$\\dfrac{1}{8}$ от $64$',ans:8},
{q:'$\\dfrac{1}{2}$ от $30$',ans:15},{q:'$\\dfrac{1}{9}$ от $36$',ans:4}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=PROB.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } } reorder();
function show(){ if(i>=5){ document.getElementById('p1-pq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p1-iv2');bumpProgress('p1',30);}else if(score>=2){addXp(8,'p1-iv2');bumpProgress('p1',16);} return; }
cur=PROB[order[i]]; document.getElementById('p1-pi').textContent=i+1;
document.getElementById('p1-pq').innerHTML=cur.q; renderMath(document.getElementById('p1-pq'));
document.getElementById('p1-pa').value=''; document.getElementById('p1-pfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p1-pfb'), v=parseFloat(document.getElementById('p1-pa').value);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(Math.abs(v-cur.ans)<1e-9){ score++; feedback(fb,true,'✓ Верно! Ответ '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ '+cur.ans+'.');
document.getElementById('p1-ps').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p1-pgo').addEventListener('click',go);
document.getElementById('p1-pa').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 2. ДЕЛЕНИЕ И ДРОБИ. ОСНОВНОЕ СВОЙСТВО ==== */
function buildP2(){
var box=document.getElementById('p2-body'); var h='';
h+=makeCard('oral','Где это в жизни','2.0',
'<p>Поделить $3$ яблока на $4$ детей можно, только если разрезать их на части. Каждый получит $\\dfrac{3}{4}$ яблока. Деление с «некруглым» результатом и рождает дроби: $a \\div b = \\dfrac{a}{b}$.</p>');
h+=makeCard('rule','Деление и дробь','2.1',
'<p>$a : b = \\dfrac{a}{b}$. &nbsp; Числитель — делимое, знаменатель — делитель.</p>'
+'<p>Дробь можно читать как деление: $\\dfrac{12}{4}=12:4=3$.</p>');
h+=makeCard('rule','Основное свойство дроби','2.2',
'<p>Дробь <b>не изменится</b>, если числитель и знаменатель умножить (или разделить) на одно и то же ненулевое число:</p>'
+'<p style="text-align:center">$\\dfrac{a}{b} = \\dfrac{a\\cdot k}{b\\cdot k} = \\dfrac{a:k}{b:k}$.</p>'
+'<p>Нахождение равной дроби с меньшими числами называют <b>сокращением</b>. Для этого делят числитель и знаменатель на их <b>НОД</b>. Дробь, у которой НОД числителя и знаменателя равен $1$, называется <b>несократимой</b>.</p>');
h+=makeCard('example','Разбор по шагам','2.3',
'<p>Сократим $\\dfrac{18}{24}$.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Находим НОД$(18,24)$. Делители $18$: $1,2,3,6,9,18$. Делители $24$: $1,2,3,4,6,8,12,24$. НОД $=6$.</li>'
+'<li>Делим числитель и знаменатель на $6$: $\\dfrac{18:6}{24:6}=\\dfrac{3}{4}$.</li>'
+'<li>Проверяем: НОД$(3,4)=1$ — дробь несократима.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','2.4',
'<p>Горизонтальную черту дроби (vinculum) ввёл арабский математик аль-Хасар в XII веке. В Европе её распространил Фибоначчи в $1202$ году. До этого числитель просто писали рядом с знаменателем без черты, и всё время путались!</p>');
h+='<div class="wg" id="p2-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Сократи дробь</div></div>'
+'<div class="wg-help">Введи числитель сокращённой дроби. Знаменатель подсказан.</div>'
+'<div class="score-display"><span>Дробь <b id="p2-i">1</b> / 6</span><span>Очки: <b id="p2-s">0</b> / 6</span></div>'
+'<div id="p2-q" class="qbox"></div>'
+'<div style="display:flex;gap:6px;justify-content:center;align-items:center;flex-wrap:wrap">'
+'<span>Числитель:</span><input type="number" id="p2-a" class="tinp" style="width:80px;text-align:center"><button class="btn primary" id="p2-go">Проверить</button></div>'
+'<div class="feedback" id="p2-fb"></div></div>';
h+='<div class="wg" id="p2-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Эквивалентные дроби</div></div>'
+'<div class="wg-help">Найди пропущенный числитель в равенстве дробей.</div>'
+'<div class="score-display"><span>Вопрос <b id="p2-ei">1</b> / 5</span><span>Очки: <b id="p2-es">0</b> / 5</span></div>'
+'<div id="p2-eq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p2-ea" class="tinp" style="width:80px;text-align:center"><button class="btn primary" id="p2-ego">Проверить</button></div>'
+'<div class="feedback" id="p2-efb"></div></div>';
h+=secNav('p1','p3')+readBtn('p2');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){
var g=_pick([2,3,4,5,6]), n=_ri(1,5)*g, d=_ri(n/g+1,8)*g;
var rn=n/g, rd=d/g; cur={n:n,d:d,rn:rn,rd:rd}; }
function show(){ if(i>=6){ document.getElementById('p2-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p2-iv1');bumpProgress('p2',30);}else if(score>=3){addXp(8,'p2-iv1');bumpProgress('p2',16);} return; }
gen(); document.getElementById('p2-i').textContent=i+1;
document.getElementById('p2-q').innerHTML='Сократи $\\dfrac{'+cur.n+'}{'+cur.d+'}$ — знаменатель станет $'+cur.rd+'$.'; renderMath(document.getElementById('p2-q'));
document.getElementById('p2-a').value=''; document.getElementById('p2-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p2-fb'), v=parseInt(document.getElementById('p2-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.rn){ score++; feedback(fb,true,'✓ Верно! $\\dfrac{'+cur.n+'}{'+cur.d+'}=\\dfrac{'+cur.rn+'}{'+cur.rd+'}$.'); renderMath(fb); } else feedback(fb,false,'✗ Нет. Числитель: '+cur.rn+'.');
document.getElementById('p2-s').textContent=score; i++; setTimeout(show,1300); }
document.getElementById('p2-go').addEventListener('click',go);
document.getElementById('p2-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function gen(){ var n=_ri(1,5), d=_ri(n+1,7), k=_ri(2,5); cur={n:n,d:d,k:k,ans:n*k,nd:d*k}; }
function show(){ if(i>=5){ document.getElementById('p2-eq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p2-iv2');bumpProgress('p2',30);}else if(score>=2){addXp(8,'p2-iv2');bumpProgress('p2',16);} return; }
gen(); document.getElementById('p2-ei').textContent=i+1;
document.getElementById('p2-eq').innerHTML='$\\dfrac{'+cur.n+'}{'+cur.d+'} = \\dfrac{\\square}{'+cur.nd+'}$'; renderMath(document.getElementById('p2-eq'));
document.getElementById('p2-ea').value=''; document.getElementById('p2-efb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p2-efb'), v=parseInt(document.getElementById('p2-ea').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ '+cur.ans+'.');
document.getElementById('p2-es').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p2-ego').addEventListener('click',go);
document.getElementById('p2-ea').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 3. ПРАВИЛЬНЫЕ, НЕПРАВИЛЬНЫЕ, СМЕШАННЫЕ ==== */
function buildP3(){
var box=document.getElementById('p3-body'); var h='';
h+=makeCard('oral','Где это в жизни','3.0',
'<p>Купить $2\\dfrac{1}{2}$ килограмма яблок или $\\dfrac{5}{2}$ — это одно и то же! Смешанные числа удобны в быту, неправильные дроби — в вычислениях. Уметь переводить одно в другое очень полезно.</p>');
h+=makeCard('rule','Правильные и неправильные дроби','3.1',
'<p>Дробь $\\dfrac{m}{n}$ называют <b>правильной</b>, если $m < n$ (числитель меньше знаменателя): значение меньше $1$.</p>'
+'<p>Если $m \\ge n$ — дробь <b>неправильная</b>: значение $\\ge 1$.</p>');
h+=makeCard('rule','Смешанные числа','3.2',
'<p><b>Смешанное число</b> = целая часть + правильная дробь: $2\\dfrac{3}{5}$ читают «два целых три пятых».</p>'
+'<p>Перевод неправильной дроби в смешанное число: разделить числитель на знаменатель с остатком. Например: $\\dfrac{11}{4}=2\\dfrac{3}{4}$ (так как $11=4\\cdot2+3$).</p>'
+'<p>Обратно: $2\\dfrac{3}{4}=\\dfrac{4\\cdot2+3}{4}=\\dfrac{11}{4}$.</p>'
+'<div id="p3-fig" style="text-align:center;margin:10px 0">'
+'<svg viewBox="0 0 300 52" width="300" style="max-width:100%">'
+'<rect x="2" y="4" width="96" height="44" rx="4" fill="#e11d48"/>'
+'<rect x="102" y="4" width="96" height="44" rx="4" fill="#e11d48"/>'
+'<rect x="202" y="4" width="24" height="44" rx="2" fill="#e11d48"/>'
+'<rect x="226" y="4" width="24" height="44" rx="2" fill="#ffe4e6" stroke="#e11d48"/>'
+'<rect x="250" y="4" width="24" height="44" rx="2" fill="#ffe4e6" stroke="#e11d48"/>'
+'<rect x="274" y="4" width="24" height="44" rx="2" fill="#ffe4e6" stroke="#e11d48"/>'
+'<text x="50" y="32" font-size="13" fill="white" text-anchor="middle" font-weight="700">1</text>'
+'<text x="150" y="32" font-size="13" fill="white" text-anchor="middle" font-weight="700">1</text>'
+'<text x="214" y="32" font-size="11" fill="white" text-anchor="middle">¼</text>'
+'<text x="150" y="50" font-size="9" fill="var(--muted)" text-anchor="middle">2¼ = 9/4</text>'
+'</svg></div>');
h+=makeCard('example','Разбор по шагам','3.3',
'<p>Переведём $\\dfrac{17}{5}$ в смешанное число.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Делим: $17 : 5 = 3$ (ост. $2$), ведь $5\\cdot3=15$, $17-15=2$.</li>'
+'<li>Целая часть $= 3$, дробная часть $= \\dfrac{2}{5}$.</li>'
+'<li>Ответ: $\\dfrac{17}{5} = 3\\dfrac{2}{5}$.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','3.4',
'<p>В разных странах смешанные числа записывают по-разному. В России пишут $2\\dfrac{3}{5}$. В некоторых странах — $2+\\dfrac{3}{5}$ или даже $2\\frac{3}{5}$ без знака плюс. В алгебре смешанные числа почти не используют — предпочитают неправильные дроби, чтобы не путать с умножением.</p>');
h+='<div class="wg" id="p3-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Неправильная дробь → смешанное число</div></div>'
+'<div class="wg-help">Переведи неправильную дробь в смешанное число. Введи целую часть.</div>'
+'<div class="score-display"><span>Дробь <b id="p3-i">1</b> / 6</span><span>Очки: <b id="p3-s">0</b> / 6</span></div>'
+'<div id="p3-q" class="qbox"></div>'
+'<div style="display:flex;gap:6px;justify-content:center;align-items:center;flex-wrap:wrap">'
+'<span>Целая часть:</span><input type="number" id="p3-a" class="tinp" style="width:80px;text-align:center"><button class="btn primary" id="p3-go">Проверить</button></div>'
+'<div class="feedback" id="p3-fb"></div></div>';
h+='<div class="wg" id="p3-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Смешанное → неправильная дробь</div></div>'
+'<div class="wg-help">Переведи смешанное число в неправильную дробь. Введи числитель.</div>'
+'<div class="score-display"><span>Дробь <b id="p3-mi">1</b> / 5</span><span>Очки: <b id="p3-ms">0</b> / 5</span></div>'
+'<div id="p3-mq" class="qbox"></div>'
+'<div style="display:flex;gap:6px;justify-content:center;align-items:center;flex-wrap:wrap">'
+'<span>Числитель:</span><input type="number" id="p3-ma" class="tinp" style="width:80px;text-align:center"><button class="btn primary" id="p3-mgo">Проверить</button></div>'
+'<div class="feedback" id="p3-mfb"></div></div>';
h+=secNav('p2','p4')+readBtn('p3');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){ var d=_ri(2,7), q=_ri(2,5), r=_ri(1,d-1); cur={n:d*q+r,d:d,q:q,r:r}; }
function show(){ if(i>=6){ document.getElementById('p3-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p3-iv1');bumpProgress('p3',30);}else if(score>=3){addXp(8,'p3-iv1');bumpProgress('p3',16);} return; }
gen(); document.getElementById('p3-i').textContent=i+1;
document.getElementById('p3-q').innerHTML='$\\dfrac{'+cur.n+'}{'+cur.d+'}$'; renderMath(document.getElementById('p3-q'));
document.getElementById('p3-a').value=''; document.getElementById('p3-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p3-fb'), v=parseInt(document.getElementById('p3-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.q){ score++; feedback(fb,true,'✓ Верно! $\\dfrac{'+cur.n+'}{'+cur.d+'}='+cur.q+'\\dfrac{'+cur.r+'}{'+cur.d+'}$.'); renderMath(fb); } else feedback(fb,false,'✗ Нет. Целая часть: '+cur.q+'.');
document.getElementById('p3-s').textContent=score; i++; setTimeout(show,1300); }
document.getElementById('p3-go').addEventListener('click',go);
document.getElementById('p3-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function gen(){ var d=_ri(2,7), w=_ri(2,5), r=_ri(1,d-1); cur={w:w,r:r,d:d,ans:d*w+r}; }
function show(){ if(i>=5){ document.getElementById('p3-mq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p3-iv2');bumpProgress('p3',30);}else if(score>=2){addXp(8,'p3-iv2');bumpProgress('p3',16);} return; }
gen(); document.getElementById('p3-mi').textContent=i+1;
document.getElementById('p3-mq').innerHTML='$'+cur.w+'\\dfrac{'+cur.r+'}{'+cur.d+'}$ → знаменатель останется $'+cur.d+'$.'; renderMath(document.getElementById('p3-mq'));
document.getElementById('p3-ma').value=''; document.getElementById('p3-mfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p3-mfb'), v=parseInt(document.getElementById('p3-ma').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Числитель '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Числитель: '+cur.ans+'.');
document.getElementById('p3-ms').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p3-mgo').addEventListener('click',go);
document.getElementById('p3-ma').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 4. СРАВНЕНИЕ ДРОБЕЙ ==== */
function buildP4(){
var box=document.getElementById('p4-body'); var h='';
h+=makeCard('oral','Где это в жизни','4.0',
'<p>Какой кусок пирога больше: $\\dfrac{3}{8}$ или $\\dfrac{2}{5}$? На первый взгляд неочевидно. Научившись сравнивать дроби, ты сможешь выбирать лучшую скидку в магазине, правильно читать рецепты и оценивать доли.</p>');
h+=makeCard('rule','Как сравнивать дроби','4.1',
'<p><b>Одинаковый знаменатель:</b> больше та дробь, у которой больше числитель. $\\dfrac{3}{7} > \\dfrac{2}{7}$.</p>'
+'<p><b>Разные знаменатели:</b> привести к общему знаменателю (НОК), затем сравнить числители.</p>'
+'<p>$\\dfrac{3}{4}$ и $\\dfrac{5}{6}$: НОК$(4,6)=12$. $\\dfrac{3}{4}=\\dfrac{9}{12}$, $\\dfrac{5}{6}=\\dfrac{10}{12}$. Поскольку $9<10$, имеем $\\dfrac{3}{4}<\\dfrac{5}{6}$.</p>');
h+=makeCard('example','Разбор по шагам','4.2',
'<p>Сравним $\\dfrac{5}{6}$ и $\\dfrac{7}{9}$.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>НОК$(6,9)=18$.</li>'
+'<li>$\\dfrac{5}{6}=\\dfrac{15}{18}$, $\\dfrac{7}{9}=\\dfrac{14}{18}$.</li>'
+'<li>$15>14$, значит $\\dfrac{5}{6}>\\dfrac{7}{9}$.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','4.3',
'<p>Есть быстрый способ: <b>«крест-накрест»</b>. Сравниваем $\\dfrac{a}{b}$ и $\\dfrac{c}{d}$: умножаем крест-накрест ($a\\cdot d$ и $b\\cdot c$). Если $a\\cdot d > b\\cdot c$, то первая дробь больше. Это работает, потому что обе части умножены на $b\\cdot d>0$.</p>');
h+='<div class="wg" id="p4-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Поставь знак</div></div>'
+'<div class="wg-help">Сравни дроби: выбери < = ></div>'
+'<div class="score-display"><span>Вопрос <b id="p4-i">1</b> / 6</span><span>Очки: <b id="p4-s">0</b> / 6</span></div>'
+'<div id="p4-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;flex-wrap:wrap"><button class="btn primary" data-cmp="&lt;">&lt;</button><button class="btn primary" data-cmp="=">=</button><button class="btn primary" data-cmp="&gt;">&gt;</button></div>'
+'<div class="feedback" id="p4-fb"></div></div>';
h+='<div class="wg" id="p4-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Числитель при сравнении</div></div>'
+'<div class="wg-help">Приведи к общему знаменателю и введи числитель первой дроби.</div>'
+'<div class="score-display"><span>Вопрос <b id="p4-ci">1</b> / 5</span><span>Очки: <b id="p4-cs">0</b> / 5</span></div>'
+'<div id="p4-cq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p4-ca" class="tinp" style="width:80px;text-align:center"><button class="btn primary" id="p4-cgo">Проверить</button></div>'
+'<div class="feedback" id="p4-cfb"></div></div>';
h+=secNav('p3','p5')+readBtn('p4');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function lcm(a,b){ return a*b/gcd(a,b); }
function gen(){ var d1=_ri(2,8), d2=_ri(2,8), n1=_ri(1,d1-1), n2=_ri(1,d2-1);
var l=lcm(d1,d2), k1=l/d1, k2=l/d2, nn1=n1*k1, nn2=n2*k2;
var cmp=nn1>nn2?'>':(nn1<nn2?'<':'='); cur={n1:n1,d1:d1,n2:n2,d2:d2,cmp:cmp}; }
function show(){ if(i>=6){ document.getElementById('p4-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p4-iv1');bumpProgress('p4',30);}else if(score>=3){addXp(8,'p4-iv1');bumpProgress('p4',16);} return; }
gen(); document.getElementById('p4-i').textContent=i+1;
document.getElementById('p4-q').innerHTML='$\\dfrac{'+cur.n1+'}{'+cur.d1+'} \\;\\square\\; \\dfrac{'+cur.n2+'}{'+cur.d2+'}$'; renderMath(document.getElementById('p4-q'));
document.getElementById('p4-fb').style.display='none'; }
function ans(sym){ if(i>=6)return; var fb=document.getElementById('p4-fb');
if(sym===cur.cmp){ score++; feedback(fb,true,'✓ Верно!'); } else feedback(fb,false,'✗ Нет. Правильный знак: '+cur.cmp+'.');
document.getElementById('p4-s').textContent=score; i++; setTimeout(show,1100); }
document.querySelectorAll('#p4-iv1 [data-cmp]').forEach(function(b){ b.addEventListener('click',function(){ ans(b.getAttribute('data-cmp')); }); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function lcm(a,b){ return a*b/gcd(a,b); }
function gen(){ var d1=_ri(2,6), d2=_ri(2,6); while(d2===d1)d2=_ri(2,6); var n1=_ri(1,d1-1);
var l=lcm(d1,d2); cur={n1:n1,d1:d1,d2:d2,l:l,ans:n1*(l/d1)}; }
function show(){ if(i>=5){ document.getElementById('p4-cq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p4-iv2');bumpProgress('p4',30);}else if(score>=2){addXp(8,'p4-iv2');bumpProgress('p4',16);} return; }
gen(); document.getElementById('p4-ci').textContent=i+1;
document.getElementById('p4-cq').innerHTML='$\\dfrac{'+cur.n1+'}{'+cur.d1+'}=\\dfrac{\\square}{'+cur.l+'}$'; renderMath(document.getElementById('p4-cq'));
document.getElementById('p4-ca').value=''; document.getElementById('p4-cfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p4-cfb'), v=parseInt(document.getElementById('p4-ca').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ '+cur.ans+'.');
document.getElementById('p4-cs').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p4-cgo').addEventListener('click',go);
document.getElementById('p4-ca').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 5. СЛОЖЕНИЕ И ВЫЧИТАНИЕ ДРОБЕЙ ==== */
function buildP5(){
var box=document.getElementById('p5-body'); var h='';
h+=makeCard('oral','Где это в жизни','5.0',
'<p>Ты съел $\\dfrac{1}{4}$ пиццы утром и $\\dfrac{2}{4}$ вечером. Сколько всего? Это сложение дробей с одинаковыми знаменателями. А если утром было $\\dfrac{1}{3}$ и вечером $\\dfrac{1}{4}$? Нужен общий знаменатель.</p>');
h+=makeCard('rule','Одинаковые знаменатели','5.1',
'<p>$\\dfrac{a}{d}\\pm\\dfrac{b}{d}=\\dfrac{a\\pm b}{d}$. &nbsp; Знаменатель <b>не меняется</b>, складываем/вычитаем только числители.</p>');
h+=makeCard('rule','Разные знаменатели','5.2',
'<p>1. Найти НОК знаменателей.<br>'
+'2. Привести каждую дробь к этому знаменателю.<br>'
+'3. Сложить/вычесть числители.</p>'
+'<p>$\\dfrac{1}{4}+\\dfrac{1}{6}$: НОК$(4,6)=12$. $\\dfrac{3}{12}+\\dfrac{2}{12}=\\dfrac{5}{12}$.</p>');
h+=makeCard('example','Разбор по шагам','5.3',
'<p>Вычислим $\\dfrac{3}{4}-\\dfrac{1}{6}$.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>НОК$(4,6)=12$.</li>'
+'<li>$\\dfrac{3}{4}=\\dfrac{9}{12}$, $\\dfrac{1}{6}=\\dfrac{2}{12}$.</li>'
+'<li>$\\dfrac{9}{12}-\\dfrac{2}{12}=\\dfrac{7}{12}$.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','5.4',
'<p>Правило общего знаменателя существует с древности. Индийский математик Брахмагупта описал его ещё в VII веке. Арабы называли числитель «числом» (بسط), а знаменатель — «основанием» (مقام) — эти слова и сейчас используют в арабском.</p>');
h+='<div class="wg" id="p5-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Сложи дроби (одинаковый знаменатель)</div></div>'
+'<div class="wg-help">Введи числитель суммы.</div>'
+'<div class="score-display"><span>Пример <b id="p5-i">1</b> / 6</span><span>Очки: <b id="p5-s">0</b> / 6</span></div>'
+'<div id="p5-q" class="qbox"></div>'
+'<div style="display:flex;gap:6px;justify-content:center;align-items:center;flex-wrap:wrap">'
+'<span>Числитель:</span><input type="number" id="p5-a" class="tinp" style="width:80px;text-align:center"><button class="btn primary" id="p5-go">Проверить</button></div>'
+'<div class="feedback" id="p5-fb"></div></div>';
h+='<div class="wg" id="p5-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Сложение с разными знаменателями</div></div>'
+'<div class="wg-help">Введи числитель результата (после приведения к НОК).</div>'
+'<div class="score-display"><span>Пример <b id="p5-ri">1</b> / 5</span><span>Очки: <b id="p5-rs">0</b> / 5</span></div>'
+'<div id="p5-rq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p5-ra" class="tinp" style="width:80px;text-align:center"><button class="btn primary" id="p5-rgo">Проверить</button></div>'
+'<div class="feedback" id="p5-rfb"></div></div>';
h+=secNav('p4','p6')+readBtn('p5');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){ var d=_ri(3,9), a=_ri(1,d-1), b=_ri(1,d-a); cur={a:a,b:b,d:d,ans:a+b}; }
function show(){ if(i>=6){ document.getElementById('p5-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p5-iv1');bumpProgress('p5',30);}else if(score>=3){addXp(8,'p5-iv1');bumpProgress('p5',16);} return; }
gen(); document.getElementById('p5-i').textContent=i+1;
document.getElementById('p5-q').innerHTML='$\\dfrac{'+cur.a+'}{'+cur.d+'} + \\dfrac{'+cur.b+'}{'+cur.d+'}$ — знаменатель: $'+cur.d+'$.'; renderMath(document.getElementById('p5-q'));
document.getElementById('p5-a').value=''; document.getElementById('p5-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p5-fb'), v=parseInt(document.getElementById('p5-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Числитель '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Числитель '+cur.ans+'.');
document.getElementById('p5-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p5-go').addEventListener('click',go);
document.getElementById('p5-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function lcm(a,b){ return a*b/gcd(a,b); }
function gen(){ var d1=_ri(2,6), d2=_ri(2,6); while(d2===d1)d2=_ri(2,6);
var n1=_ri(1,d1-1), n2=_ri(1,d2-1), l=lcm(d1,d2);
var rn=n1*(l/d1)+n2*(l/d2); cur={n1:n1,d1:d1,n2:n2,d2:d2,l:l,ans:rn}; }
function show(){ if(i>=5){ document.getElementById('p5-rq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p5-iv2');bumpProgress('p5',30);}else if(score>=2){addXp(8,'p5-iv2');bumpProgress('p5',16);} return; }
gen(); document.getElementById('p5-ri').textContent=i+1;
document.getElementById('p5-rq').innerHTML='$\\dfrac{'+cur.n1+'}{'+cur.d1+'} + \\dfrac{'+cur.n2+'}{'+cur.d2+'}$ — знаменатель станет $'+cur.l+'$.'; renderMath(document.getElementById('p5-rq'));
document.getElementById('p5-ra').value=''; document.getElementById('p5-rfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p5-rfb'), v=parseInt(document.getElementById('p5-ra').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Числитель: '+cur.ans+'.');
document.getElementById('p5-rs').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p5-rgo').addEventListener('click',go);
document.getElementById('p5-ra').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 6. СЛОЖЕНИЕ И ВЫЧИТАНИЕ СМЕШАННЫХ ЧИСЕЛ ==== */
function buildP6(){
var box=document.getElementById('p6-body'); var h='';
h+=makeCard('oral','Где это в жизни','6.0',
'<p>Рецепт: $1\\dfrac{1}{2}$ стакана муки и $2\\dfrac{3}{4}$ стакана сахара. Сколько всего сыпучих продуктов? Здесь нужно складывать смешанные числа — это умение пригодится на кухне, в мастерской и в магазине.</p>');
h+=makeCard('rule','Сложение смешанных чисел','6.1',
'<p>Складываем целые части и дробные части отдельно:</p>'
+'<p>$2\\dfrac{1}{4}+1\\dfrac{1}{4}=(2+1)+\\left(\\dfrac{1}{4}+\\dfrac{1}{4}\\right)=3\\dfrac{2}{4}=3\\dfrac{1}{2}$.</p>'
+'<p>Если сумма дробных частей $\\ge 1$ — переводим лишнее в целую часть.</p>');
h+=makeCard('rule','Вычитание смешанных чисел','6.2',
'<p>Вычитаем целые и дробные части отдельно. Если дробная часть уменьшаемого меньше вычитаемой — <b>занимаем</b> единицу из целой части.</p>'
+'<p>$3\\dfrac{1}{6}-1\\dfrac{4}{6}$: дробная часть $\\dfrac{1}{6}<\\dfrac{4}{6}$. Берём $1$ из $3$: получаем $2\\dfrac{7}{6}-1\\dfrac{4}{6}=1\\dfrac{3}{6}=1\\dfrac{1}{2}$.</p>');
h+=makeCard('example','Разбор по шагам','6.3',
'<p>Вычислим $3\\dfrac{2}{5}+1\\dfrac{4}{5}$.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Целые: $3+1=4$.</li>'
+'<li>Дроби: $\\dfrac{2}{5}+\\dfrac{4}{5}=\\dfrac{6}{5}=1\\dfrac{1}{5}$.</li>'
+'<li>Итого: $4+1\\dfrac{1}{5}=5\\dfrac{1}{5}$.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','6.4',
'<p>В старых русских рецептах меры назывались «фунт», «золотник», «лот» — и их записывали смешанными числами. Один фунт равен $409{,}5$ грамма. Перевести рецепт в граммы без знания дробей было невозможно!</p>');
h+='<div class="wg" id="p6-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Сложение смешанных чисел</div></div>'
+'<div class="wg-help">Вычисли сумму. Введи целую часть результата.</div>'
+'<div class="score-display"><span>Пример <b id="p6-i">1</b> / 6</span><span>Очки: <b id="p6-s">0</b> / 6</span></div>'
+'<div id="p6-q" class="qbox"></div>'
+'<div style="display:flex;gap:6px;justify-content:center;align-items:center;flex-wrap:wrap">'
+'<span>Целая часть:</span><input type="number" id="p6-a" class="tinp" style="width:80px;text-align:center"><button class="btn primary" id="p6-go">Проверить</button></div>'
+'<div class="feedback" id="p6-fb"></div></div>';
h+='<div class="wg" id="p6-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Вычитание смешанных чисел</div></div>'
+'<div class="wg-help">Вычисли разность. Введи целую часть результата.</div>'
+'<div class="score-display"><span>Пример <b id="p6-vi">1</b> / 5</span><span>Очки: <b id="p6-vs">0</b> / 5</span></div>'
+'<div id="p6-vq" class="qbox"></div>'
+'<div style="display:flex;gap:6px;justify-content:center;align-items:center;flex-wrap:wrap">'
+'<span>Целая часть:</span><input type="number" id="p6-va" class="tinp" style="width:80px;text-align:center"><button class="btn primary" id="p6-vgo">Проверить</button></div>'
+'<div class="feedback" id="p6-vfb"></div></div>';
h+=secNav('p5','p7')+readBtn('p6');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){ var d=_ri(3,8), w1=_ri(1,4), n1=_ri(1,d-1), w2=_ri(1,3), n2=_ri(1,d-1);
var rn=n1+n2, rw=w1+w2+Math.floor(rn/d); rn=rn%d; cur={w1:w1,n1:n1,w2:w2,n2:n2,d:d,rw:rw,rn:rn}; }
function show(){ if(i>=6){ document.getElementById('p6-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p6-iv1');bumpProgress('p6',30);}else if(score>=3){addXp(8,'p6-iv1');bumpProgress('p6',16);} return; }
gen(); document.getElementById('p6-i').textContent=i+1;
document.getElementById('p6-q').innerHTML='$'+cur.w1+'\\dfrac{'+cur.n1+'}{'+cur.d+'} + '+cur.w2+'\\dfrac{'+cur.n2+'}{'+cur.d+'}$'; renderMath(document.getElementById('p6-q'));
document.getElementById('p6-a').value=''; document.getElementById('p6-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p6-fb'), v=parseInt(document.getElementById('p6-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.rw){ score++; feedback(fb,true,'✓ Верно! Целая часть '+cur.rw+(cur.rn>0?', дробная '+cur.rn+'/'+cur.d:'')+'.'); } else feedback(fb,false,'✗ Нет. Целая часть: '+cur.rw+'.');
document.getElementById('p6-s').textContent=score; i++; setTimeout(show,1300); }
document.getElementById('p6-go').addEventListener('click',go);
document.getElementById('p6-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function gen(){ var d=_ri(4,8), w1=_ri(3,6), n1=_ri(1,d-1), w2=_ri(1,w1-1), n2=_ri(1,d-1);
var v1=w1*d+n1, v2=w2*d+n2, rv=v1-v2, rw=Math.floor(rv/d); cur={w1:w1,n1:n1,w2:w2,n2:n2,d:d,rw:rw}; }
function show(){ if(i>=5){ document.getElementById('p6-vq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p6-iv2');bumpProgress('p6',30);}else if(score>=2){addXp(8,'p6-iv2');bumpProgress('p6',16);} return; }
gen(); document.getElementById('p6-vi').textContent=i+1;
document.getElementById('p6-vq').innerHTML='$'+cur.w1+'\\dfrac{'+cur.n1+'}{'+cur.d+'} - '+cur.w2+'\\dfrac{'+cur.n2+'}{'+cur.d+'}$'; renderMath(document.getElementById('p6-vq'));
document.getElementById('p6-va').value=''; document.getElementById('p6-vfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p6-vfb'), v=parseInt(document.getElementById('p6-va').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.rw){ score++; feedback(fb,true,'✓ Верно! Целая часть '+cur.rw+'.'); } else feedback(fb,false,'✗ Нет. Целая часть: '+cur.rw+'.');
document.getElementById('p6-vs').textContent=score; i++; setTimeout(show,1300); }
document.getElementById('p6-vgo').addEventListener('click',go);
document.getElementById('p6-va').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 7. УМНОЖЕНИЕ ДРОБЕЙ ==== */
function buildP7(){
var box=document.getElementById('p7-body'); var h='';
h+=makeCard('oral','Где это в жизни','7.0',
'<p>Плитка шоколада разбита на $4$ ряда по $6$ кусочков. Ты хочешь $\\dfrac{2}{3}$ плитки. Это $\\dfrac{2}{3}\\cdot 24=16$ кусочков. Умножение дробей встречается в кулинарии, строительстве, финансах.</p>');
h+=makeCard('rule','Умножение дробей','7.1',
'<p>$\\dfrac{a}{b}\\cdot\\dfrac{c}{d}=\\dfrac{a\\cdot c}{b\\cdot d}$. &nbsp; Числители перемножают, знаменатели перемножают.</p>'
+'<p>Перед умножением удобно <b>сокращать крест-накрест</b>: $\\dfrac{3}{4}\\cdot\\dfrac{8}{9}=\\dfrac{3}{9}\\cdot\\dfrac{8}{4}=\\dfrac{1}{3}\\cdot\\dfrac{2}{1}=\\dfrac{2}{3}$.</p>'
+'<div id="p7-fig" style="text-align:center;margin:10px 0">'
+'<svg viewBox="0 0 180 140" width="180" style="max-width:100%">'
+'<rect x="2" y="2" width="176" height="136" rx="4" fill="#fff1f2" stroke="#e11d48" stroke-width="1.5"/>'
+'<line x1="2" y1="68" x2="178" y2="68" stroke="#e11d48" stroke-width="1" stroke-dasharray="4,3"/>'
+'<line x1="88" y1="2" x2="88" y2="138" stroke="#e11d48" stroke-width="1" stroke-dasharray="4,3"/>'
+'<rect x="2" y="2" width="86" height="66" rx="4" fill="#e11d48" opacity="0.6"/>'
+'<text x="90" y="155" font-size="10" fill="var(--muted)" text-anchor="middle">½ × ½ = ¼ закрашено</text>'
+'</svg></div>');
h+=makeCard('example','Разбор по шагам','7.2',
'<p>Вычислим $\\dfrac{4}{9}\\cdot\\dfrac{3}{8}$.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Сокращаем: $4$ и $8$ — делятся на $4$; $3$ и $9$ — делятся на $3$.</li>'
+'<li>$\\dfrac{4:4}{9:3}\\cdot\\dfrac{3:3}{8:4}=\\dfrac{1}{3}\\cdot\\dfrac{1}{2}=\\dfrac{1}{6}$.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','7.4',
'<p>Умножение дроби на дробь «площадным» способом иллюстрирует единичный квадрат: $\\dfrac{a}{b}\\cdot\\dfrac{c}{d}$ — это доля площади квадрата $1\\times1$, занятая прямоугольником $\\dfrac{a}{b}\\times\\dfrac{c}{d}$.</p>');
h+='<div class="wg" id="p7-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Перемножи дроби</div></div>'
+'<div class="wg-help">Введи числитель произведения (до сокращения).</div>'
+'<div class="score-display"><span>Пример <b id="p7-i">1</b> / 6</span><span>Очки: <b id="p7-s">0</b> / 6</span></div>'
+'<div id="p7-q" class="qbox"></div>'
+'<div style="display:flex;gap:6px;justify-content:center;align-items:center;flex-wrap:wrap">'
+'<span>Числитель:</span><input type="number" id="p7-a" class="tinp" style="width:80px;text-align:center"><button class="btn primary" id="p7-go">Проверить</button></div>'
+'<div class="feedback" id="p7-fb"></div></div>';
h+='<div class="wg" id="p7-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Дробь от числа</div></div>'
+'<div class="wg-help">Найди значение. Ответ — целое число.</div>'
+'<div class="score-display"><span>Задача <b id="p7-pi">1</b> / 5</span><span>Очки: <b id="p7-ps">0</b> / 5</span></div>'
+'<div id="p7-pq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p7-pa" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p7-pgo">Проверить</button></div>'
+'<div class="feedback" id="p7-pfb"></div></div>';
h+=secNav('p6','p8')+readBtn('p7');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){ var n1=_ri(1,5), d1=_ri(n1+1,8), n2=_ri(1,5), d2=_ri(n2+1,8); cur={n1:n1,d1:d1,n2:n2,d2:d2,ans:n1*n2}; }
function show(){ if(i>=6){ document.getElementById('p7-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p7-iv1');bumpProgress('p7',30);}else if(score>=3){addXp(8,'p7-iv1');bumpProgress('p7',16);} return; }
gen(); document.getElementById('p7-i').textContent=i+1;
document.getElementById('p7-q').innerHTML='$\\dfrac{'+cur.n1+'}{'+cur.d1+'} \\cdot \\dfrac{'+cur.n2+'}{'+cur.d2+'}$ — знаменатель $'+(cur.d1*cur.d2)+'$.'; renderMath(document.getElementById('p7-q'));
document.getElementById('p7-a').value=''; document.getElementById('p7-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p7-fb'), v=parseInt(document.getElementById('p7-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Числитель '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Числитель: '+cur.ans+'.');
document.getElementById('p7-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p7-go').addEventListener('click',go);
document.getElementById('p7-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var PROB=[
{q:'$\\dfrac{2}{3}$ от $27$',ans:18},{q:'$\\dfrac{3}{4}$ от $20$',ans:15},{q:'$\\dfrac{5}{6}$ от $24$',ans:20},
{q:'$\\dfrac{3}{5}$ от $35$',ans:21},{q:'$\\dfrac{4}{7}$ от $49$',ans:28},{q:'$\\dfrac{2}{5}$ от $30$',ans:12},
{q:'$\\dfrac{7}{8}$ от $40$',ans:35},{q:'$\\dfrac{5}{9}$ от $45$',ans:25}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=PROB.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } } reorder();
function show(){ if(i>=5){ document.getElementById('p7-pq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p7-iv2');bumpProgress('p7',30);}else if(score>=2){addXp(8,'p7-iv2');bumpProgress('p7',16);} return; }
cur=PROB[order[i]]; document.getElementById('p7-pi').textContent=i+1;
document.getElementById('p7-pq').innerHTML=cur.q; renderMath(document.getElementById('p7-pq'));
document.getElementById('p7-pa').value=''; document.getElementById('p7-pfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p7-pfb'), v=parseFloat(document.getElementById('p7-pa').value);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(Math.abs(v-cur.ans)<1e-9){ score++; feedback(fb,true,'✓ Верно! Ответ '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ '+cur.ans+'.');
document.getElementById('p7-ps').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p7-pgo').addEventListener('click',go);
document.getElementById('p7-pa').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 8. ДЕЛЕНИЕ ДРОБЕЙ ==== */
function buildP8(){
var box=document.getElementById('p8-body'); var h='';
h+=makeCard('oral','Где это в жизни','8.0',
'<p>Если $\\dfrac{3}{4}$ метра ткани нужно разрезать на куски по $\\dfrac{1}{8}$ метра, сколько кусков получится? $\\dfrac{3}{4} : \\dfrac{1}{8} = 6$. Деление дробей — это умножение на обратную дробь.</p>');
h+=makeCard('rule','Обратная дробь и деление','8.1',
'<p><b>Обратная дробь</b> к $\\dfrac{a}{b}$ — это $\\dfrac{b}{a}$ (числитель и знаменатель меняются местами). Произведение числа и обратного к нему равно $1$.</p>'
+'<p>$\\dfrac{a}{b} : \\dfrac{c}{d} = \\dfrac{a}{b} \\cdot \\dfrac{d}{c}$. &nbsp; «Делить на дробь = умножать на обратную».</p>');
h+=makeCard('example','Разбор по шагам','8.2',
'<p>Вычислим $\\dfrac{5}{6} : \\dfrac{10}{3}$.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Переворачиваем вторую дробь: $\\dfrac{10}{3}\\to\\dfrac{3}{10}$.</li>'
+'<li>Умножаем: $\\dfrac{5}{6}\\cdot\\dfrac{3}{10}=\\dfrac{15}{60}$.</li>'
+'<li>Сокращаем: $\\dfrac{15:15}{60:15}=\\dfrac{1}{4}$.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','8.3',
'<p>Правило «перевернуть и умножить» хорошо объясняется через единицы измерения. Если на $\\dfrac{3}{4}$ кг у тебя $6$ яблок, то в $1$ кг поместится $6 \\div \\dfrac{3}{4} = 8$ яблок. Деление дробей — это поиск «сколько раз меньшее укладывается в большем».</p>');
h+='<div class="wg" id="p8-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Обратная дробь</div></div>'
+'<div class="wg-help">Введи числитель обратной дроби.</div>'
+'<div class="score-display"><span>Вопрос <b id="p8-i">1</b> / 5</span><span>Очки: <b id="p8-s">0</b> / 5</span></div>'
+'<div id="p8-q" class="qbox"></div>'
+'<div style="display:flex;gap:6px;justify-content:center;align-items:center;flex-wrap:wrap">'
+'<span>Числитель обратной:</span><input type="number" id="p8-a" class="tinp" style="width:80px;text-align:center"><button class="btn primary" id="p8-go">Проверить</button></div>'
+'<div class="feedback" id="p8-fb"></div></div>';
h+='<div class="wg" id="p8-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Раздели дробь</div></div>'
+'<div class="wg-help">Вычисли результат деления. Введи числитель ответа (до сокращения).</div>'
+'<div class="score-display"><span>Пример <b id="p8-di">1</b> / 5</span><span>Очки: <b id="p8-ds">0</b> / 5</span></div>'
+'<div id="p8-dq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p8-da" class="tinp" style="width:80px;text-align:center"><button class="btn primary" id="p8-dgo">Проверить</button></div>'
+'<div class="feedback" id="p8-dfb"></div></div>';
h+=secNav('p7','p9')+readBtn('p8');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){ var n=_ri(1,7), d=_ri(n+1,10); cur={n:n,d:d,ans:d}; }
function show(){ if(i>=5){ document.getElementById('p8-q').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p8-iv1');bumpProgress('p8',30);}else if(score>=2){addXp(8,'p8-iv1');bumpProgress('p8',16);} return; }
gen(); document.getElementById('p8-i').textContent=i+1;
document.getElementById('p8-q').innerHTML='Обратная к $\\dfrac{'+cur.n+'}{'+cur.d+'}$ — знаменатель $'+cur.n+'.$.'; renderMath(document.getElementById('p8-q'));
document.getElementById('p8-a').value=''; document.getElementById('p8-fb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p8-fb'), v=parseInt(document.getElementById('p8-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Обратная $\\dfrac{'+cur.d+'}{'+cur.n+'}$.'); renderMath(fb); } else feedback(fb,false,'✗ Нет. Числитель обратной: '+cur.ans+'.');
document.getElementById('p8-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p8-go').addEventListener('click',go);
document.getElementById('p8-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function gen(){ var n1=_ri(2,6), d1=_ri(n1+1,8), n2=_ri(1,5), d2=_ri(n2+1,8); cur={n1:n1,d1:d1,n2:n2,d2:d2,ans:n1*d2}; }
function show(){ if(i>=5){ document.getElementById('p8-dq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p8-iv2');bumpProgress('p8',30);}else if(score>=2){addXp(8,'p8-iv2');bumpProgress('p8',16);} return; }
gen(); document.getElementById('p8-di').textContent=i+1;
document.getElementById('p8-dq').innerHTML='$\\dfrac{'+cur.n1+'}{'+cur.d1+'} : \\dfrac{'+cur.n2+'}{'+cur.d2+'}$ — знаменатель $'+(cur.d1*cur.n2)+'$.'; renderMath(document.getElementById('p8-dq'));
document.getElementById('p8-da').value=''; document.getElementById('p8-dfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p8-dfb'), v=parseInt(document.getElementById('p8-da').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Числитель '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Числитель: '+cur.ans+'.');
document.getElementById('p8-ds').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p8-dgo').addEventListener('click',go);
document.getElementById('p8-da').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 9. ЗАДАЧИ НА ВСЕ ДЕЙСТВИЯ С ДРОБЯМИ ==== */
function buildP9(){
var box=document.getElementById('p9-body'); var h='';
h+=makeCard('oral','Где это в жизни','9.0',
'<p>Задача из кулинарии: рецепт на $6$ порций требует $\\dfrac{3}{4}$ стакана сахара. Ты хочешь приготовить $4$ порции. Сколько сахара нужно? $\\dfrac{3}{4}\\cdot\\dfrac{4}{6}=\\dfrac{1}{2}$ стакана. Здесь умножение и деление дробей вместе!</p>');
h+=makeCard('rule','Порядок действий','9.1',
'<p>1. Действия в скобках.<br>2. Умножение и деление (слева направо).<br>3. Сложение и вычитание.</p>'
+'<p>При работе со смешанными числами сначала переводим в неправильные дроби, затем выполняем действия.</p>');
h+=makeCard('example','Разбор по шагам','9.2',
'<p>Вычислим $\\dfrac{3}{4} \\cdot 8 - 1\\dfrac{1}{2}$.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>$\\dfrac{3}{4}\\cdot 8 = \\dfrac{24}{4}=6$.</li>'
+'<li>$1\\dfrac{1}{2}=\\dfrac{3}{2}$.</li>'
+'<li>$6-\\dfrac{3}{2}=\\dfrac{12}{2}-\\dfrac{3}{2}=\\dfrac{9}{2}=4\\dfrac{1}{2}$.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','9.3',
'<p>Задачи с дробями встречались уже в папирусе Ахмеса (~1650 до н.э.): «Раздели $7$ хлебов на $10$ человек». Современные задачи о скидках, налогах и рецептах — их прямые потомки!</p>');
h+='<div class="wg" id="p9-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Вычисли выражение</div></div>'
+'<div class="wg-help">Ответ вводи числом (если целое) или числителем при подсказанном знаменателе.</div>'
+'<div class="score-display"><span>Пример <b id="p9-i">1</b> / 6</span><span>Очки: <b id="p9-s">0</b> / 6</span></div>'
+'<div id="p9-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p9-a" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p9-go">Проверить</button></div>'
+'<div class="feedback" id="p9-fb"></div></div>';
h+='<div class="wg" id="p9-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Текстовые задачи</div></div>'
+'<div class="wg-help">Реши задачу. Ответ — целое число.</div>'
+'<div class="score-display"><span>Задача <b id="p9-pi">1</b> / 5</span><span>Очки: <b id="p9-ps">0</b> / 5</span></div>'
+'<div id="p9-pq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p9-pa" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p9-pgo">Проверить</button></div>'
+'<div class="feedback" id="p9-pfb"></div></div>';
h+=secNav('p8','p10')+readBtn('p9');
box.innerHTML=h; renderMath(box);
(function(){
var QS=[
{q:'$\\dfrac{3}{5} \\cdot 10$',ans:6},{q:'$\\dfrac{2}{3} \\cdot 12$',ans:8},{q:'$\\dfrac{5}{4} \\cdot 4$',ans:5},
{q:'$24 \\cdot \\dfrac{1}{6}$',ans:4},{q:'$\\dfrac{7}{2} \\cdot 4$',ans:14},{q:'$15 \\cdot \\dfrac{2}{5}$',ans:6},
{q:'$\\dfrac{9}{3}$',ans:3},{q:'$\\dfrac{4}{1} \\cdot \\dfrac{3}{4}$',ans:3}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=QS.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } } reorder();
function show(){ if(i>=6){ document.getElementById('p9-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p9-iv1');bumpProgress('p9',30);}else if(score>=3){addXp(8,'p9-iv1');bumpProgress('p9',16);} return; }
cur=QS[order[i]]; document.getElementById('p9-i').textContent=i+1;
document.getElementById('p9-q').innerHTML=cur.q; renderMath(document.getElementById('p9-q'));
document.getElementById('p9-a').value=''; document.getElementById('p9-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p9-fb'), v=parseFloat(document.getElementById('p9-a').value);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(Math.abs(v-cur.ans)<1e-9){ score++; feedback(fb,true,'✓ Верно! '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+'.');
document.getElementById('p9-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p9-go').addEventListener('click',go);
document.getElementById('p9-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var TASKS=[
{q:'Поезд прошёл $\\dfrac{2}{5}$ пути за $4$ ч. Весь путь $100$ км. Сколько км уже пройдено?',ans:40},
{q:'В классе $30$ учеников. $\\dfrac{3}{5}$ из них пришли. Сколько пришло?',ans:18},
{q:'Рулон ткани $12$ м. Отрезали $\\dfrac{3}{4}$. Сколько метров отрезали?',ans:9},
{q:'Из $24$ кг яблок $\\dfrac{1}{6}$ — гнилые. Сколько кг хороших яблок?',ans:20},
{q:'Книга из $80$ страниц. Прочитано $\\dfrac{3}{8}$. Сколько страниц осталось?',ans:50}
];
var order=[],i=0,score=0,cur=null;
function reorder(){ order=TASKS.map(function(_,k){return k;}); for(var j=order.length-1;j>0;j--){ var k=_ri(0,j),t=order[j];order[j]=order[k];order[k]=t; } } reorder();
function show(){ if(i>=5){ document.getElementById('p9-pq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p9-iv2');bumpProgress('p9',30);}else if(score>=2){addXp(8,'p9-iv2');bumpProgress('p9',16);} return; }
cur=TASKS[order[i]]; document.getElementById('p9-pi').textContent=i+1;
document.getElementById('p9-pq').innerHTML=cur.q; renderMath(document.getElementById('p9-pq'));
document.getElementById('p9-pa').value=''; document.getElementById('p9-pfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p9-pfb'), v=parseFloat(document.getElementById('p9-pa').value);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(Math.abs(v-cur.ans)<1e-9){ score++; feedback(fb,true,'✓ Верно! Ответ '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+'.');
document.getElementById('p9-ps').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p9-pgo').addEventListener('click',go);
document.getElementById('p9-pa').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 10. ЗАДАЧИ НА ПРИМЕНЕНИЕ ДРОБЕЙ ==== */
function buildP10(){
var box=document.getElementById('p10-body'); var h='';
h+=makeCard('oral','Где это в жизни','10.0',
'<p>«Скидка $\\dfrac{1}{4}$ от цены» или «в классе $\\dfrac{3}{5}$ девочек» — всё это задачи на часть от числа. Иногда нам известна часть, а нужно найти целое: «если $12$ — это $\\dfrac{3}{4}$ от числа, чему равно целое?»</p>');
h+=makeCard('rule','Часть от числа и число по части','10.1',
'<p><b>Найти $\\dfrac{m}{n}$ от числа $a$:</b> $a \\cdot \\dfrac{m}{n}$.</p>'
+'<p><b>Найти число по его части:</b> если $\\dfrac{m}{n}$ от числа равно $b$, то всё число $= b \\cdot \\dfrac{n}{m} = b : \\dfrac{m}{n}$.</p>');
h+=makeCard('example','Разбор по шагам','10.2',
'<p>Задача 1: найти $\\dfrac{3}{5}$ от $40$. &nbsp; $40\\cdot\\dfrac{3}{5}=24$.</p>'
+'<p>Задача 2: $\\dfrac{3}{5}$ числа равно $24$. Найти число. &nbsp; $24 : \\dfrac{3}{5}=24\\cdot\\dfrac{5}{3}=40$.</p>');
h+=makeCard('theory','А знаешь ли ты?','10.3',
'<p>Банковские проценты — это тоже дроби: $10\\%=\\dfrac{10}{100}=\\dfrac{1}{10}$. Когда банк даёт кредит под $15\\%$ годовых, он берёт $\\dfrac{15}{100}$ от суммы долга каждый год. В классе 7 ты изучишь проценты подробнее — и поймёшь, что уже всё умеешь!</p>');
h+='<div class="wg" id="p10-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Найди часть от числа</div></div>'
+'<div class="wg-help">Вычисли дробную часть. Ответ — целое число.</div>'
+'<div class="score-display"><span>Задача <b id="p10-i">1</b> / 6</span><span>Очки: <b id="p10-s">0</b> / 6</span></div>'
+'<div id="p10-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p10-a" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p10-go">Проверить</button></div>'
+'<div class="feedback" id="p10-fb"></div></div>';
h+='<div class="wg" id="p10-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Найди целое по части</div></div>'
+'<div class="wg-help">Найди исходное число. Ответ — целое.</div>'
+'<div class="score-display"><span>Задача <b id="p10-wi">1</b> / 5</span><span>Очки: <b id="p10-ws">0</b> / 5</span></div>'
+'<div id="p10-wq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p10-wa" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p10-wgo">Проверить</button></div>'
+'<div class="feedback" id="p10-wfb"></div></div>';
h+=secNav('p9','p11')+readBtn('p10');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){ var d=_ri(2,8), m=_ri(1,d-1), whole=d*_ri(2,8); cur={m:m,d:d,whole:whole,ans:(whole*m/d)}; }
function show(){ if(i>=6){ document.getElementById('p10-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p10-iv1');bumpProgress('p10',30);}else if(score>=3){addXp(8,'p10-iv1');bumpProgress('p10',16);} return; }
gen(); document.getElementById('p10-i').textContent=i+1;
document.getElementById('p10-q').innerHTML='Найди $\\dfrac{'+cur.m+'}{'+cur.d+'}$ от $'+cur.whole+'$.'; renderMath(document.getElementById('p10-q'));
document.getElementById('p10-a').value=''; document.getElementById('p10-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p10-fb'), v=parseFloat(document.getElementById('p10-a').value);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(Math.abs(v-cur.ans)<1e-9){ score++; feedback(fb,true,'✓ Верно! '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+'.');
document.getElementById('p10-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p10-go').addEventListener('click',go);
document.getElementById('p10-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function gen(){ var d=_ri(2,7), m=_ri(1,d-1), whole=d*_ri(2,9); var part=whole*m/d; cur={m:m,d:d,part:part,ans:whole}; }
function show(){ if(i>=5){ document.getElementById('p10-wq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p10-iv2');bumpProgress('p10',30);}else if(score>=2){addXp(8,'p10-iv2');bumpProgress('p10',16);} return; }
gen(); document.getElementById('p10-wi').textContent=i+1;
document.getElementById('p10-wq').innerHTML='$\\dfrac{'+cur.m+'}{'+cur.d+'}$ числа равно $'+cur.part+'$. Найди число.'; renderMath(document.getElementById('p10-wq'));
document.getElementById('p10-wa').value=''; document.getElementById('p10-wfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p10-wfb'), v=parseFloat(document.getElementById('p10-wa').value);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(Math.abs(v-cur.ans)<1e-9){ score++; feedback(fb,true,'✓ Верно! Целое число: '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+'.');
document.getElementById('p10-ws').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p10-wgo').addEventListener('click',go);
document.getElementById('p10-wa').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 11. ПАРАЛЛЕЛЬНЫЕ И ПЕРПЕНДИКУЛЯРНЫЕ ПРЯМЫЕ ==== */
function buildP11(){
var box=document.getElementById('p11-body'); var h='';
h+=makeCard('oral','Где это в жизни','11.0',
'<p>Рельсы железной дороги никогда не пересекаются — они <b>параллельны</b>. Угол в углу комнаты — <b>прямой</b>, стены перпендикулярны полу. Каждый раз, когда ты видишь ровные линии, включается геометрия!</p>');
h+=makeCard('theory','Параллельные прямые','11.1',
'<p>Две прямые на плоскости называют <b>параллельными</b>, если они не имеют общих точек (не пересекаются). Обозначение: $a \\parallel b$.</p>'
+'<div id="p11-fig" style="text-align:center;margin:10px 0">'
+'<svg viewBox="0 0 300 90" width="300" style="max-width:100%">'
+'<line x1="20" y1="30" x2="280" y2="30" stroke="#e11d48" stroke-width="2.5"/>'
+'<line x1="20" y1="60" x2="280" y2="60" stroke="#e11d48" stroke-width="2.5"/>'
+'<text x="285" y="34" font-size="13" fill="#e11d48" font-weight="700">a</text>'
+'<text x="285" y="64" font-size="13" fill="#e11d48" font-weight="700">b</text>'
+'<text x="150" y="48" font-size="12" fill="var(--muted)" text-anchor="middle">a ∥ b</text>'
+'<line x1="100" y1="70" x2="100" y2="80" stroke="#94a3b8" stroke-width="1.5"/>'
+'<line x1="200" y1="70" x2="200" y2="80" stroke="#94a3b8" stroke-width="1.5"/>'
+'<line x1="100" y1="80" x2="200" y2="80" stroke="#94a3b8" stroke-width="1.5"/>'
+'<text x="150" y="89" font-size="9" fill="var(--muted)" text-anchor="middle">одинаковое расстояние</text>'
+'</svg></div>');
h+=makeCard('theory','Перпендикулярные прямые','11.2',
'<p>Две прямые называют <b>перпендикулярными</b>, если при пересечении они образуют <b>прямой угол</b> ($90°$). Обозначение: $a \\perp b$. Знак прямого угла — квадратик в вершине угла.</p>');
h+=makeCard('example','Разбор по шагам','11.3',
'<p>Начертим прямую, перпендикулярную данной.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Отметим точку $A$ на прямой $a$.</li>'
+'<li>В точке $A$ поставим угольник так, чтобы один катет лежал вдоль $a$.</li>'
+'<li>Проведём прямую $b$ вдоль другого катета — это и есть $a \\perp b$.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','11.4',
'<p>Параллельные прямые дали название целой геометрии: <b>Лобачевский</b> в XIX веке предложил геометрию, где через точку можно провести <b>бесконечно много</b> прямых, параллельных данной. Оказалось, что это описывает искривлённое пространство — именно такое встречается в общей теории относительности!</p>');
h+='<div class="wg" id="p11-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Параллельные или перпендикулярные?</div></div>'
+'<div class="wg-help">Посмотри на рисунок и определи вид прямых.</div>'
+'<div class="score-display"><span>Вопрос <b id="p11-i">1</b> / 6</span><span>Очки: <b id="p11-s">0</b> / 6</span></div>'
+'<div id="p11-fig2" style="text-align:center;margin:8px 0"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;flex-wrap:wrap"><button class="btn primary" data-t="par">Параллельные</button><button class="btn primary" data-t="perp">Перпендикулярные</button></div>'
+'<div class="feedback" id="p11-fb"></div></div>';
h+='<div class="wg" id="p11-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Угол при пересечении</div></div>'
+'<div class="wg-help">Введи величину прямого угла в градусах.</div>'
+'<div class="score-display"><span>Вопрос <b id="p11-ai">1</b> / 4</span><span>Очки: <b id="p11-as">0</b> / 4</span></div>'
+'<div id="p11-aq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p11-aa" class="tinp" style="width:90px;text-align:center"><span>°</span><button class="btn primary" id="p11-ago">Проверить</button></div>'
+'<div class="feedback" id="p11-afb"></div></div>';
h+=secNav('p10','p12')+readBtn('p11');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function makeSVG(t){ var W=240,H=100;
if(t==='par') return '<svg viewBox="0 0 '+W+' '+H+'" width="240" style="max-width:100%"><line x1="20" y1="35" x2="220" y2="35" stroke="#e11d48" stroke-width="2.5"/><line x1="20" y1="65" x2="220" y2="65" stroke="#e11d48" stroke-width="2.5"/><text x="225" y="39" font-size="12" fill="#e11d48" font-weight="700">a</text><text x="225" y="69" font-size="12" fill="#e11d48" font-weight="700">b</text></svg>';
return '<svg viewBox="0 0 '+W+' '+H+'" width="240" style="max-width:100%"><line x1="120" y1="5" x2="120" y2="95" stroke="#e11d48" stroke-width="2.5"/><line x1="20" y1="50" x2="220" y2="50" stroke="#e11d48" stroke-width="2.5"/><rect x="120" y="50" width="10" height="10" fill="none" stroke="#e11d48" stroke-width="1.5"/><text x="126" y="20" font-size="12" fill="#e11d48" font-weight="700">a</text><text x="192" y="45" font-size="12" fill="#e11d48" font-weight="700">b</text></svg>'; }
function gen(){ cur=_pick(['par','perp']); }
function show(){ if(i>=6){ document.getElementById('p11-fig2').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p11-iv1');bumpProgress('p11',30);}else if(score>=3){addXp(8,'p11-iv1');bumpProgress('p11',16);} return; }
gen(); document.getElementById('p11-i').textContent=i+1;
document.getElementById('p11-fig2').innerHTML=makeSVG(cur);
document.getElementById('p11-fb').style.display='none'; }
function ans(t){ if(i>=6)return; var fb=document.getElementById('p11-fb'), names={par:'параллельные',perp:'перпендикулярные'};
if(t===cur){ score++; feedback(fb,true,'✓ Верно — '+names[cur]+'.'); } else feedback(fb,false,'✗ Нет. Это '+names[cur]+'.');
document.getElementById('p11-s').textContent=score; i++; setTimeout(show,1100); }
document.querySelectorAll('#p11-iv1 [data-t]').forEach(function(b){ b.addEventListener('click',function(){ ans(b.getAttribute('data-t')); }); });
show();
})();
(function(){
var QS=[
{q:'Перпендикулярные прямые пересекаются под углом… (°)',ans:90},
{q:'Если $a \\perp b$, угол между ними равен … °.',ans:90},
{q:'Прямой угол — это … °.',ans:90},
{q:'При пересечении перпендикулярных прямых образуется … прямых угла.',ans:4}
];
var i=0,score=0,cur=null;
function show(){ if(i>=4){ document.getElementById('p11-aq').innerHTML='<b>Готово! '+score+' / 4</b>'; if(score>=3){addXp(20,'p11-iv2');bumpProgress('p11',40);}else{addXp(8,'p11-iv2');bumpProgress('p11',16);} return; }
cur=QS[i]; document.getElementById('p11-ai').textContent=i+1;
document.getElementById('p11-aq').innerHTML=cur.q; renderMath(document.getElementById('p11-aq'));
document.getElementById('p11-aa').value=''; document.getElementById('p11-afb').style.display='none'; }
function go(){ if(i>=4)return; var fb=document.getElementById('p11-afb'), v=parseInt(document.getElementById('p11-aa').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+'.');
document.getElementById('p11-as').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p11-ago').addEventListener('click',go);
document.getElementById('p11-aa').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 12. ЛОМАНАЯ. МНОГОУГОЛЬНИК. ПЕРИМЕТР ==== */
function buildP12(){
var box=document.getElementById('p12-body'); var h='';
h+=makeCard('oral','Где это в жизни','12.0',
'<p>Забор вокруг огорода — это периметр прямоугольника. Длина маршрута из точки в точку через несколько улиц — это длина ломаной. Знать периметр нужно строителям, дизайнерам, спортсменам.</p>');
h+=makeCard('theory','Ломаная и многоугольник','12.1',
'<p><b>Ломаная</b> — фигура из последовательных отрезков. Если концы соединены — получается <b>замкнутая ломаная</b> (многоугольник).</p>'
+'<p><b>Многоугольник</b> с $n$ сторонами: $n=3$ — треугольник; $n=4$ — четырёхугольник; $n=5$ — пятиугольник и т.д. Особый случай четырёхугольника: прямоугольник (все углы прямые); квадрат (прямоугольник с равными сторонами).</p>'
+'<div id="p12-fig" style="text-align:center;margin:10px 0">'
+'<svg viewBox="0 0 280 100" width="280" style="max-width:100%">'
+'<polygon points="40,80 80,20 140,80" fill="#ffe4e6" stroke="#e11d48" stroke-width="2"/>'
+'<text x="40" y="90" font-size="10" fill="#e11d48" text-anchor="middle">A</text>'
+'<text x="80" y="15" font-size="10" fill="#e11d48" text-anchor="middle">B</text>'
+'<text x="140" y="90" font-size="10" fill="#e11d48" text-anchor="middle">C</text>'
+'<text x="60" y="52" font-size="9" fill="#e11d48">3</text>'
+'<text x="110" y="52" font-size="9" fill="#e11d48">4</text>'
+'<text x="87" y="88" font-size="9" fill="#e11d48">5</text>'
+'<polygon points="170,80 200,20 240,20 240,80" fill="#fff1f2" stroke="#e11d48" stroke-width="2"/>'
+'<text x="170" y="90" font-size="10" fill="#e11d48" text-anchor="middle">D</text>'
+'<text x="200" y="15" font-size="10" fill="#e11d48" text-anchor="middle">E</text>'
+'<text x="240" y="15" font-size="10" fill="#e11d48" text-anchor="middle">F</text>'
+'<text x="240" y="90" font-size="10" fill="#e11d48" text-anchor="middle">G</text>'
+'</svg></div>');
h+=makeCard('rule','Периметр','12.2',
'<p><b>Периметр</b> многоугольника — сумма длин всех его сторон.</p>'
+'<p>Прямоугольник: $P=2(a+b)$. &nbsp; Квадрат: $P=4a$. &nbsp; Равносторонний треугольник: $P=3a$.</p>');
h+=makeCard('example','Разбор по шагам','12.3',
'<p>Найдём периметр треугольника со сторонами $3{,}5$ см, $4{,}2$ см и $5{,}1$ см.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>$P = a + b + c = 3{,}5 + 4{,}2 + 5{,}1$.</li>'
+'<li>$3{,}5+4{,}2=7{,}7$; $7{,}7+5{,}1=12{,}8$.</li>'
+'<li>Ответ: $P=12{,}8$ см.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','12.4',
'<p>Слово «периметр» от греч. peri («вокруг») + metron («мера»). Именно периметр нужно было знать, чтобы обнести землю забором. В Древнем Египте землемеры-«гарпедонапты» натягивали верёвки вокруг участков и так измеряли периметр!</p>');
h+='<div class="wg" id="p12-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Найди периметр</div></div>'
+'<div class="wg-help">Сложи длины сторон и введи периметр.</div>'
+'<div class="score-display"><span>Задача <b id="p12-i">1</b> / 6</span><span>Очки: <b id="p12-s">0</b> / 6</span></div>'
+'<div id="p12-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p12-a" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p12-go">Проверить</button></div>'
+'<div class="feedback" id="p12-fb"></div></div>';
h+='<div class="wg" id="p12-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Сторона по периметру</div></div>'
+'<div class="wg-help">Найди неизвестную сторону по периметру.</div>'
+'<div class="score-display"><span>Задача <b id="p12-si">1</b> / 5</span><span>Очки: <b id="p12-ss">0</b> / 5</span></div>'
+'<div id="p12-sq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p12-sa" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p12-sgo">Проверить</button></div>'
+'<div class="feedback" id="p12-sfb"></div></div>';
h+=secNav('p11','p13')+readBtn('p12');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){
var t=_ri(0,2);
if(t===0){ var a=_ri(2,12),b=_ri(2,12); cur={q:'Прямоугольник $'+a+' \\times '+b+'$ см. Периметр?',ans:2*(a+b)}; }
else if(t===1){ var a=_ri(2,15); cur={q:'Квадрат со стороной $'+a+'$ см. Периметр?',ans:4*a}; }
else { var a=_ri(2,10),b=_ri(2,10),c=_ri(2,10); cur={q:'Треугольник со сторонами $'+a+'$, $'+b+'$, $'+c+'$ см.',ans:a+b+c}; } }
function show(){ if(i>=6){ document.getElementById('p12-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p12-iv1');bumpProgress('p12',30);}else if(score>=3){addXp(8,'p12-iv1');bumpProgress('p12',16);} return; }
gen(); document.getElementById('p12-i').textContent=i+1;
document.getElementById('p12-q').innerHTML=cur.q; renderMath(document.getElementById('p12-q'));
document.getElementById('p12-a').value=''; document.getElementById('p12-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p12-fb'), v=parseInt(document.getElementById('p12-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Периметр '+cur.ans+' см.'); } else feedback(fb,false,'✗ Нет. Периметр: '+cur.ans+' см.');
document.getElementById('p12-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p12-go').addEventListener('click',go);
document.getElementById('p12-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function gen(){
var t=_ri(0,1);
if(t===0){ var a=_ri(3,12), P=4*a; cur={q:'Квадрат, периметр $'+P+'$ см. Сторона?',ans:a}; }
else { var a=_ri(3,10), b=_ri(3,10), P=2*(a+b); cur={q:'Прямоугольник, периметр $'+P+'$ см, одна сторона $'+a+'$ см. Другая сторона?',ans:b}; } }
function show(){ if(i>=5){ document.getElementById('p12-sq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p12-iv2');bumpProgress('p12',30);}else if(score>=2){addXp(8,'p12-iv2');bumpProgress('p12',16);} return; }
gen(); document.getElementById('p12-si').textContent=i+1;
document.getElementById('p12-sq').innerHTML=cur.q; renderMath(document.getElementById('p12-sq'));
document.getElementById('p12-sa').value=''; document.getElementById('p12-sfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p12-sfb'), v=parseInt(document.getElementById('p12-sa').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! '+cur.ans+' см.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+' см.');
document.getElementById('p12-ss').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p12-sgo').addEventListener('click',go);
document.getElementById('p12-sa').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 13. ПЛОЩАДЬ ==== */
function buildP13(){
var box=document.getElementById('p13-body'); var h='';
h+=makeCard('oral','Где это в жизни','13.0',
'<p>Сколько плитки нужно, чтобы выложить пол? Какой ковёр купить в комнату? Площадь огорода — чтобы знать, сколько семян нужно. Всё это — задачи на площадь.</p>');
h+=makeCard('rule','Площадь. Единицы','13.1',
'<p>Площадь измеряют квадратными единицами: $\\text{мм}^2$, $\\text{см}^2$, $\\text{дм}^2$, $\\text{м}^2$, $\\text{км}^2$, $\\text{га}$.</p>'
+'<p>$1\\text{ м}^2=100\\text{ дм}^2=10\\,000\\text{ см}^2$. &nbsp; $1\\text{ га}=10\\,000\\text{ м}^2$.</p>'
+'<p><b>Прямоугольник:</b> $S=a\\cdot b$. &nbsp; <b>Квадрат:</b> $S=a^2$.</p>'
+'<div id="p13-fig" style="text-align:center;margin:10px 0">'
+'<svg viewBox="0 0 200 140" width="200" style="max-width:100%">'
+'<rect x="10" y="10" width="180" height="120" fill="#fff1f2" stroke="#e11d48" stroke-width="1.5"/>'
+'<line x1="10" y1="40" x2="190" y2="40" stroke="#e11d48" stroke-width="0.8" stroke-dasharray="3,3"/>'
+'<line x1="10" y1="70" x2="190" y2="70" stroke="#e11d48" stroke-width="0.8" stroke-dasharray="3,3"/>'
+'<line x1="10" y1="100" x2="190" y2="100" stroke="#e11d48" stroke-width="0.8" stroke-dasharray="3,3"/>'
+'<line x1="55" y1="10" x2="55" y2="130" stroke="#e11d48" stroke-width="0.8" stroke-dasharray="3,3"/>'
+'<line x1="100" y1="10" x2="100" y2="130" stroke="#e11d48" stroke-width="0.8" stroke-dasharray="3,3"/>'
+'<line x1="145" y1="10" x2="145" y2="130" stroke="#e11d48" stroke-width="0.8" stroke-dasharray="3,3"/>'
+'<text x="100" y="75" font-size="11" fill="#e11d48" text-anchor="middle" font-weight="700">S = 4 × 3 = 12</text>'
+'<text x="100" y="138" font-size="9" fill="var(--muted)" text-anchor="middle">4 клетки × 3 клетки = 12 кл²</text>'
+'</svg></div>');
h+=makeCard('example','Разбор по шагам','13.2',
'<p>Площадь комнаты $5$ м на $4$ м в квадратных дециметрах.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>$S=5\\cdot4=20$ м².</li>'
+'<li>$1$ м² $=100$ дм², значит $20$ м² $=2000$ дм².</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','13.3',
'<p>Слово «гектар» образовано от «гекто» ($100$) + «ар» ($100$ м²). Значит $1$ га $=100\\times100=10\\,000$ м². В России средний огород около $6$ соток, то есть $600$ м² — это $0{,}06$ га. Египетские землемеры тысячелетия назад рассчитывали площади таким же способом!</p>');
h+='<div class="wg" id="p13-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Найди площадь</div></div>'
+'<div class="wg-help">Вычисли площадь фигуры.</div>'
+'<div class="score-display"><span>Задача <b id="p13-i">1</b> / 6</span><span>Очки: <b id="p13-s">0</b> / 6</span></div>'
+'<div id="p13-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p13-a" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p13-go">Проверить</button></div>'
+'<div class="feedback" id="p13-fb"></div></div>';
h+='<div class="wg" id="p13-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Перевод единиц площади</div></div>'
+'<div class="wg-help">Переведи площадь в указанные единицы.</div>'
+'<div class="score-display"><span>Вопрос <b id="p13-ui">1</b> / 5</span><span>Очки: <b id="p13-us">0</b> / 5</span></div>'
+'<div id="p13-uq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p13-ua" class="tinp" style="width:120px;text-align:center"><button class="btn primary" id="p13-ugo">Проверить</button></div>'
+'<div class="feedback" id="p13-ufb"></div></div>';
h+=secNav('p12','p14')+readBtn('p13');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){
var t=_ri(0,2);
if(t===0){ var a=_ri(2,15), b=_ri(2,15); cur={q:'Прямоугольник $'+a+' \\times '+b+'$. Площадь (кл²)?',ans:a*b}; }
else if(t===1){ var a=_ri(2,12); cur={q:'Квадрат со стороной $'+a+'$ см. Площадь (см²)?',ans:a*a}; }
else { var a=_ri(2,10), b=_ri(2,10); cur={q:'Прямоугольник $'+a+'$ м на $'+b+'$ м. Площадь (м²)?',ans:a*b}; } }
function show(){ if(i>=6){ document.getElementById('p13-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p13-iv1');bumpProgress('p13',30);}else if(score>=3){addXp(8,'p13-iv1');bumpProgress('p13',16);} return; }
gen(); document.getElementById('p13-i').textContent=i+1;
document.getElementById('p13-q').innerHTML=cur.q; renderMath(document.getElementById('p13-q'));
document.getElementById('p13-a').value=''; document.getElementById('p13-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p13-fb'), v=parseInt(document.getElementById('p13-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Площадь '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+'.');
document.getElementById('p13-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p13-go').addEventListener('click',go);
document.getElementById('p13-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var QS=[
{q:'$3$ м² = \\square дм²',ans:300},{q:'$5$ м² = \\square дм²',ans:500},
{q:'$200$ дм² = \\square м²',ans:2},{q:'$2$ га = \\square м²',ans:20000},
{q:'$1$ м² = \\square см²',ans:10000}
];
var i=0,score=0,cur=null;
function show(){ if(i>=5){ document.getElementById('p13-uq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p13-iv2');bumpProgress('p13',30);}else if(score>=2){addXp(8,'p13-iv2');bumpProgress('p13',16);} return; }
cur=QS[i]; document.getElementById('p13-ui').textContent=i+1;
document.getElementById('p13-uq').innerHTML='$'+cur.q+'$'; renderMath(document.getElementById('p13-uq'));
document.getElementById('p13-ua').value=''; document.getElementById('p13-ufb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p13-ufb'), v=parseInt(document.getElementById('p13-ua').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+'.');
document.getElementById('p13-us').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p13-ugo').addEventListener('click',go);
document.getElementById('p13-ua').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 14. ПЛОЩАДЬ ПРЯМОУГОЛЬНОГО ТРЕУГОЛЬНИКА ==== */
function buildP14(){
var box=document.getElementById('p14-body'); var h='';
h+=makeCard('oral','Где это в жизни','14.0',
'<p>Чтобы сшить парус-треугольник или купить треугольный кусок стекла — нужна площадь треугольника. Прямоугольный треугольник — самый простой случай: он ровно половина прямоугольника.</p>');
h+=makeCard('rule','Формула площади треугольника','14.1',
'<p>Прямоугольный треугольник с катетами $a$ и $b$:</p>'
+'<p style="text-align:center;font-size:1.1rem">$S_{\\triangle} = \\dfrac{a\\cdot b}{2}$</p>'
+'<p>Для любого треугольника: $S = \\dfrac{1}{2} \\cdot \\text{основание} \\cdot \\text{высота}$.</p>'
+'<div id="p14-fig" style="text-align:center;margin:10px 0">'
+'<svg viewBox="0 0 220 120" width="220" style="max-width:100%">'
+'<rect x="20" y="20" width="120" height="80" fill="#fff1f2" stroke="#e11d48" stroke-width="1" stroke-dasharray="4,3"/>'
+'<polygon points="20,100 140,100 20,20" fill="#e11d48" opacity="0.5"/>'
+'<polygon points="140,100 20,20 140,20" fill="#ffe4e6" stroke="#e11d48" stroke-width="1.5" stroke-dasharray="4,3"/>'
+'<rect x="20" y="90" width="10" height="10" fill="none" stroke="#e11d48" stroke-width="1.5"/>'
+'<text x="80" y="114" font-size="11" fill="#e11d48" text-anchor="middle" font-weight="700">a (основание)</text>'
+'<text x="8" y="62" font-size="11" fill="#e11d48" text-anchor="middle" font-weight="700">b</text>'
+'<text x="160" y="62" font-size="10" fill="var(--muted)" text-anchor="start">S = ab/2</text>'
+'</svg></div>');
h+=makeCard('example','Разбор по шагам','14.2',
'<p>Катеты прямоугольного треугольника $6$ см и $8$ см. Площадь?</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>$S=\\dfrac{6\\cdot8}{2}=\\dfrac{48}{2}=24$ см².</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','14.3',
'<p>Египетский «верёвочный треугольник» $3{-}4{-}5$ — это прямоугольный треугольник ($3^2+4^2=5^2$). Строители тысячи лет назад использовали верёвку с узлами через $3$, $4$ и $5$ единиц, чтобы делать точные прямые углы. Теорему Пифагора — в $7$ классе!</p>');
h+='<div class="wg" id="p14-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Площадь прямоугольного треугольника</div></div>'
+'<div class="wg-help">Введи площадь треугольника.</div>'
+'<div class="score-display"><span>Задача <b id="p14-i">1</b> / 6</span><span>Очки: <b id="p14-s">0</b> / 6</span></div>'
+'<div id="p14-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p14-a" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p14-go">Проверить</button></div>'
+'<div class="feedback" id="p14-fb"></div></div>';
h+='<div class="wg" id="p14-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Катет по площади</div></div>'
+'<div class="wg-help">Один катет и площадь известны. Найди другой катет.</div>'
+'<div class="score-display"><span>Задача <b id="p14-ki">1</b> / 5</span><span>Очки: <b id="p14-ks">0</b> / 5</span></div>'
+'<div id="p14-kq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p14-ka" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p14-kgo">Проверить</button></div>'
+'<div class="feedback" id="p14-kfb"></div></div>';
h+=secNav('p13','p15')+readBtn('p14');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){ var a=_ri(2,12)*2, b=_ri(2,12)*2; cur={a:a,b:b,ans:a*b/2}; }
function show(){ if(i>=6){ document.getElementById('p14-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p14-iv1');bumpProgress('p14',30);}else if(score>=3){addXp(8,'p14-iv1');bumpProgress('p14',16);} return; }
gen(); document.getElementById('p14-i').textContent=i+1;
document.getElementById('p14-q').innerHTML='Катеты $'+cur.a+'$ и $'+cur.b+'$ см. Площадь (см²)?'; renderMath(document.getElementById('p14-q'));
document.getElementById('p14-a').value=''; document.getElementById('p14-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p14-fb'), v=parseInt(document.getElementById('p14-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Площадь '+cur.ans+' см².'); } else feedback(fb,false,'✗ Нет. S='+cur.a+'·'+cur.b+'/2='+cur.ans+'.');
document.getElementById('p14-s').textContent=score; i++; setTimeout(show,1300); }
document.getElementById('p14-go').addEventListener('click',go);
document.getElementById('p14-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function gen(){ var a=_ri(3,12), b=_ri(3,12); var S=a*b; cur={a:a,b:b,S:S,ans:b}; }
function show(){ if(i>=5){ document.getElementById('p14-kq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p14-iv2');bumpProgress('p14',30);}else if(score>=2){addXp(8,'p14-iv2');bumpProgress('p14',16);} return; }
gen(); document.getElementById('p14-ki').textContent=i+1;
document.getElementById('p14-kq').innerHTML='Площадь треугольника $'+cur.S+'$ см², один катет $'+cur.a+'$ см. Другой катет?'; renderMath(document.getElementById('p14-kq'));
document.getElementById('p14-ka').value=''; document.getElementById('p14-kfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p14-kfb'), v=parseInt(document.getElementById('p14-ka').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! '+cur.ans+' см.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+' (S·2÷a='+cur.ans+').');
document.getElementById('p14-ks').textContent=score; i++; setTimeout(show,1300); }
document.getElementById('p14-kgo').addEventListener('click',go);
document.getElementById('p14-ka').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 15. СРЕДНЕЕ АРИФМЕТИЧЕСКОЕ ==== */
function buildP15(){
var box=document.getElementById('p15-body'); var h='';
h+=makeCard('oral','Где это в жизни','15.0',
'<p>Средняя оценка за четверть, средняя температура за неделю, средняя скорость автомобиля — везде нужно среднее арифметическое. Это одна из самых востребованных операций в статистике и в повседневной жизни.</p>');
h+=makeCard('rule','Среднее арифметическое','15.1',
'<p>Среднее арифметическое $n$ чисел — это их <b>сумма, делённая на</b> $n$:</p>'
+'<p style="text-align:center;font-size:1.1rem">$\\bar{a} = \\dfrac{a_1 + a_2 + \\ldots + a_n}{n}$</p>');
h+=makeCard('example','Примеры','15.2',
'<p>Оценки: $4, 5, 3, 5, 4$. Среднее $=\\dfrac{4+5+3+5+4}{5}=\\dfrac{21}{5}=4{,}2$.</p>'
+'<p>Температура за $3$ дня: $12°, 15°, 9°$. Среднее $=\\dfrac{12+15+9}{3}=12°$.</p>');
h+=makeCard('example','Разбор по шагам','15.3',
'<p>Найдём среднее арифметическое чисел $8, 12, 6, 10$.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Сумма: $8+12+6+10=36$.</li>'
+'<li>Количество чисел: $4$.</li>'
+'<li>Среднее: $36:4=9$.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','15.4',
'<p>В статистике среднее обозначают $\\bar{x}$ («икс с чертой»). Когда говорят «средняя зарплата по стране», имеют в виду именно среднее арифметическое. Но оно может быть обманчивым: если один человек зарабатывает миллион, а девять — по тысяче, среднее $=109\\,000$, хотя большинство получают $1000$.</p>');
h+='<div class="wg" id="p15-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Найди среднее</div></div>'
+'<div class="wg-help">Вычисли среднее арифметическое. Ответ — целое число.</div>'
+'<div class="score-display"><span>Задача <b id="p15-i">1</b> / 6</span><span>Очки: <b id="p15-s">0</b> / 6</span></div>'
+'<div id="p15-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p15-a" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p15-go">Проверить</button></div>'
+'<div class="feedback" id="p15-fb"></div></div>';
h+='<div class="wg" id="p15-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Восстанови число</div></div>'
+'<div class="wg-help">Среднее и часть чисел известны. Найди пропущенное число.</div>'
+'<div class="score-display"><span>Задача <b id="p15-ri">1</b> / 5</span><span>Очки: <b id="p15-rs">0</b> / 5</span></div>'
+'<div id="p15-rq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p15-ra" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p15-rgo">Проверить</button></div>'
+'<div class="feedback" id="p15-rfb"></div></div>';
h+=secNav('p14','p16')+readBtn('p15');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){ var n=_ri(3,5); var avg=_ri(3,15); var arr=[]; var sum=0;
for(var k=0;k<n-1;k++){ var x=_ri(avg-4,avg+4); arr.push(x); sum+=x; }
var last=avg*n-sum; arr.push(last); cur={arr:arr,n:n,ans:avg}; }
function show(){ if(i>=6){ document.getElementById('p15-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p15-iv1');bumpProgress('p15',30);}else if(score>=3){addXp(8,'p15-iv1');bumpProgress('p15',16);} return; }
gen(); document.getElementById('p15-i').textContent=i+1;
document.getElementById('p15-q').innerHTML='Среднее чисел $'+cur.arr.join(', ')+'$.'; renderMath(document.getElementById('p15-q'));
document.getElementById('p15-a').value=''; document.getElementById('p15-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p15-fb'), v=parseInt(document.getElementById('p15-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Среднее: '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Среднее: '+cur.ans+'.');
document.getElementById('p15-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p15-go').addEventListener('click',go);
document.getElementById('p15-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function gen(){ var n=3, avg=_ri(5,15); var a=_ri(avg-3,avg+3), b=_ri(avg-3,avg+3); var x=avg*n-a-b; cur={a:a,b:b,avg:avg,n:n,ans:x}; }
function show(){ if(i>=5){ document.getElementById('p15-rq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p15-iv2');bumpProgress('p15',30);}else if(score>=2){addXp(8,'p15-iv2');bumpProgress('p15',16);} return; }
gen(); document.getElementById('p15-ri').textContent=i+1;
document.getElementById('p15-rq').innerHTML='Среднее трёх чисел $'+cur.avg+'$. Два числа: $'+cur.a+'$ и $'+cur.b+'$. Третье?'; renderMath(document.getElementById('p15-rq'));
document.getElementById('p15-ra').value=''; document.getElementById('p15-rfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p15-rfb'), v=parseInt(document.getElementById('p15-ra').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+'.');
document.getElementById('p15-rs').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p15-rgo').addEventListener('click',go);
document.getElementById('p15-ra').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 16. ДИАГРАММЫ ==== */
function buildP16(){
var box=document.getElementById('p16-body'); var h='';
h+=makeCard('oral','Где это в жизни','16.0',
'<p>Графики продаж, диаграммы успеваемости, результаты опросов — диаграммы везде. Умение их читать важно для учёбы, работы и чтения новостей.</p>');
h+=makeCard('theory','Виды диаграмм','16.1',
'<p><b>Столбчатая диаграмма:</b> высота столбика = значение. Удобна для сравнения нескольких величин.</p>'
+'<p><b>Линейная диаграмма (ломаная):</b> точки соединяются линиями. Удобна для показа изменения во времени.</p>'
+'<div id="p16-fig" style="text-align:center;margin:10px 0">'
+'<svg viewBox="0 0 260 120" width="260" style="max-width:100%">'
+'<line x1="30" y1="10" x2="30" y2="95" stroke="#94a3b8" stroke-width="1.5"/>'
+'<line x1="30" y1="95" x2="250" y2="95" stroke="#94a3b8" stroke-width="1.5"/>'
+'<rect x="45" y="45" width="30" height="50" fill="#e11d48" rx="2"/>'
+'<rect x="95" y="25" width="30" height="70" fill="#e11d48" rx="2"/>'
+'<rect x="145" y="60" width="30" height="35" fill="#e11d48" rx="2"/>'
+'<rect x="195" y="35" width="30" height="60" fill="#e11d48" rx="2"/>'
+'<text x="60" y="108" font-size="9" fill="var(--muted)" text-anchor="middle">Пн</text>'
+'<text x="110" y="108" font-size="9" fill="var(--muted)" text-anchor="middle">Вт</text>'
+'<text x="160" y="108" font-size="9" fill="var(--muted)" text-anchor="middle">Ср</text>'
+'<text x="210" y="108" font-size="9" fill="var(--muted)" text-anchor="middle">Чт</text>'
+'<text x="60" y="42" font-size="9" fill="#e11d48" text-anchor="middle">5</text>'
+'<text x="110" y="22" font-size="9" fill="#e11d48" text-anchor="middle">7</text>'
+'<text x="160" y="57" font-size="9" fill="#e11d48" text-anchor="middle">3</text>'
+'<text x="210" y="32" font-size="9" fill="#e11d48" text-anchor="middle">6</text>'
+'</svg></div>');
h+=makeCard('rule','Читаем диаграмму','16.2',
'<p>По диаграмме определяют: максимум/минимум, разность, сумму, среднее значений.</p>');
h+=makeCard('example','Разбор по шагам','16.3',
'<p>На столбчатой диаграмме показано количество задач, решённых за 4 дня: Пн=5, Вт=7, Ср=3, Чт=6.</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Всего: $5+7+3+6=21$.</li>'
+'<li>Среднее: $21:4=5{,}25$.</li>'
+'<li>Максимум во вторник ($7$), минимум в среду ($3$).</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','16.4',
'<p>Первую столбчатую диаграмму нарисовал шотландский инженер <b>Уильям Плейфэр</b> в $1786$ году в «Коммерческом и политическом атласе». Он же изобрёл линейный и круговой графики. До него все данные представляли только таблицами!</p>');
h+='<div class="wg" id="p16-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Читаем диаграмму</div></div>'
+'<div class="wg-help">По диаграмме ответь на вопрос.</div>'
+'<div class="score-display"><span>Вопрос <b id="p16-i">1</b> / 6</span><span>Очки: <b id="p16-s">0</b> / 6</span></div>'
+'<div id="p16-fig2" style="text-align:center;margin:8px 0"></div>'
+'<div id="p16-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p16-a" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p16-go">Проверить</button></div>'
+'<div class="feedback" id="p16-fb"></div></div>';
h+='<div class="wg" id="p16-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Среднее по диаграмме</div></div>'
+'<div class="wg-help">Найди среднее арифметическое значений диаграммы.</div>'
+'<div class="score-display"><span>Задача <b id="p16-ai">1</b> / 4</span><span>Очки: <b id="p16-as">0</b> / 4</span></div>'
+'<div id="p16-af" style="text-align:center;margin:8px 0"></div>'
+'<div id="p16-aq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p16-aa" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p16-ago">Проверить</button></div>'
+'<div class="feedback" id="p16-afb"></div></div>';
h+=secNav('p15','p17')+readBtn('p16');
box.innerHTML=h; renderMath(box);
function barSVG(vals,labels,question){ var W=260,H=130,bw=30,gap=10,x0=30,y0=10,H0=80;
var mx=Math.max.apply(null,vals); var s='<svg viewBox="0 0 '+W+' '+(H+15)+'" width="260" style="max-width:100%">';
s+='<line x1="'+x0+'" y1="'+y0+'" x2="'+x0+'" y2="'+(y0+H0+5)+'" stroke="#94a3b8" stroke-width="1.5"/>';
s+='<line x1="'+x0+'" y1="'+(y0+H0+5)+'" x2="'+(W-10)+'" y2="'+(y0+H0+5)+'" stroke="#94a3b8" stroke-width="1.5"/>';
vals.forEach(function(v,k){ var bh=Math.round(v/mx*H0); var x=x0+10+k*(bw+gap); var y=(y0+H0+5-bh);
s+='<rect x="'+x+'" y="'+y+'" width="'+bw+'" height="'+bh+'" fill="#e11d48" rx="2"/>';
s+='<text x="'+(x+bw/2)+'" y="'+(y-3)+'" font-size="9" fill="#e11d48" text-anchor="middle">'+v+'</text>';
s+='<text x="'+(x+bw/2)+'" y="'+(y0+H0+18)+'" font-size="9" fill="var(--muted)" text-anchor="middle">'+labels[k]+'</text>'; });
return s+'</svg>'; }
(function(){
var i=0,score=0,cur=null;
var DAYS=['Пн','Вт','Ср','Чт','Пт'];
function gen(){ var vals=[]; for(var k=0;k<4;k++) vals.push(_ri(2,10));
var t=_ri(0,2), ans, q;
if(t===0){ ans=Math.max.apply(null,vals); q='Максимальное значение?'; }
else if(t===1){ ans=Math.min.apply(null,vals); q='Минимальное значение?'; }
else { ans=vals.reduce(function(a,b){return a+b;},0); q='Сумма всех значений?'; }
cur={vals:vals,ans:ans,q:q}; }
function show(){ if(i>=6){ document.getElementById('p16-fig2').innerHTML='<b>Готово! '+score+' / 6</b>'; document.getElementById('p16-q').innerHTML=''; if(score>=5){addXp(15,'p16-iv1');bumpProgress('p16',30);}else if(score>=3){addXp(8,'p16-iv1');bumpProgress('p16',16);} return; }
gen(); document.getElementById('p16-i').textContent=i+1;
document.getElementById('p16-fig2').innerHTML=barSVG(cur.vals,DAYS.slice(0,4),'');
document.getElementById('p16-q').innerHTML=cur.q;
document.getElementById('p16-a').value=''; document.getElementById('p16-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p16-fb'), v=parseInt(document.getElementById('p16-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+'.');
document.getElementById('p16-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p16-go').addEventListener('click',go);
document.getElementById('p16-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
var DAYS=['Пн','Вт','Ср','Чт'];
function gen(){ var n=4, avg=_ri(3,8); var vals=[]; var sum=0;
for(var k=0;k<n-1;k++){ var x=_ri(avg-2,avg+2); vals.push(x); sum+=x; } vals.push(avg*n-sum);
cur={vals:vals,ans:avg}; }
function show(){ if(i>=4){ document.getElementById('p16-af').innerHTML='<b>Готово! '+score+' / 4</b>'; document.getElementById('p16-aq').innerHTML=''; if(score>=3){addXp(20,'p16-iv2');bumpProgress('p16',40);}else{addXp(8,'p16-iv2');bumpProgress('p16',16);} return; }
gen(); document.getElementById('p16-ai').textContent=i+1;
document.getElementById('p16-af').innerHTML=barSVG(cur.vals,DAYS,'');
document.getElementById('p16-aq').innerHTML='Среднее арифметическое значений диаграммы?';
document.getElementById('p16-aa').value=''; document.getElementById('p16-afb').style.display='none'; }
function go(){ if(i>=4)return; var fb=document.getElementById('p16-afb'), v=parseInt(document.getElementById('p16-aa').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Среднее: '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Среднее: '+cur.ans+'.');
document.getElementById('p16-as').textContent=score; i++; setTimeout(show,1300); }
document.getElementById('p16-ago').addEventListener('click',go);
document.getElementById('p16-aa').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 17. ПАРАЛЛЕЛЕПИПЕД И КУБ ==== */
function buildP17(){
var box=document.getElementById('p17-body'); var h='';
h+=makeCard('oral','Где это в жизни','17.0',
'<p>Коробка из-под сока, кирпич, комната — всё это прямоугольные параллелепипеды. Грани, рёбра, вершины — основные понятия пространственной геометрии, которые тебе пригодятся в дальнейшем.</p>');
h+=makeCard('theory','Прямоугольный параллелепипед','17.1',
'<p><b>Прямоугольный параллелепипед</b> — тело, у которого все $6$ граней — прямоугольники. У него $8$ вершин, $12$ рёбер, $6$ граней.</p>'
+'<p>Три измерения: <b>длина</b> $a$, <b>ширина</b> $b$, <b>высота</b> $c$.</p>'
+'<p><b>Куб</b> — особый параллелепипед: все рёбра равны ($a=b=c$), все грани — квадраты.</p>'
+'<div id="p17-fig" style="text-align:center;margin:10px 0">'
+'<svg viewBox="0 0 200 150" width="200" style="max-width:100%">'
+'<!-- Изометрический параллелепипед -->'
+'<!-- Нижняя грань -->'
+'<polygon points="50,110 130,110 160,80 80,80" fill="#fff1f2" stroke="#e11d48" stroke-width="1.5"/>'
+'<!-- Левая грань -->'
+'<polygon points="50,110 50,40 80,10 80,80" fill="#ffe4e6" stroke="#e11d48" stroke-width="1.5"/>'
+'<!-- Верхняя грань -->'
+'<polygon points="50,40 130,40 160,10 80,10" fill="#fecdd3" stroke="#e11d48" stroke-width="1.5"/>'
+'<!-- Правая грань -->'
+'<polygon points="130,110 160,80 160,10 130,40" fill="#fda4af" stroke="#e11d48" stroke-width="1.5"/>'
+'<!-- Метки рёбер -->'
+'<text x="90" y="125" font-size="10" fill="#e11d48" text-anchor="middle" font-weight="700">a</text>'
+'<text x="38" y="78" font-size="10" fill="#e11d48" text-anchor="middle" font-weight="700">c</text>'
+'<text x="155" y="50" font-size="10" fill="#e11d48" text-anchor="middle" font-weight="700">b</text>'
+'</svg></div>');
h+=makeCard('rule','Грани, рёбра, вершины','17.2',
'<p>Параллелепипед: $6$ граней, $12$ рёбер, $8$ вершин. Рёбра трёх видов по $4$ каждого: длиной $a$, $b$, $c$.</p>');
h+=makeCard('example','Разбор по шагам','17.3',
'<p>Параллелепипед $3\\times4\\times5$. Сколько рёбер каждой длины?</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>Длина $3$ — $4$ ребра.</li>'
+'<li>Длина $4$ — $4$ ребра.</li>'
+'<li>Длина $5$ — $4$ ребра. Итого: $12$ рёбер.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','17.4',
'<p>Термин «параллелепипед» от греч. parallelos («параллельный») + epipedon («поверхность»). Это «тело с параллельными гранями». В кристаллографии форма кристаллов описывается именно параллелепипедами — в том числе соль NaCl кристаллизуется в форме куба!</p>');
h+='<div class="wg" id="p17-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Рёбра, грани, вершины</div></div>'
+'<div class="wg-help">Ответь на вопрос о параллелепипеде.</div>'
+'<div class="score-display"><span>Вопрос <b id="p17-i">1</b> / 5</span><span>Очки: <b id="p17-s">0</b> / 5</span></div>'
+'<div id="p17-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p17-a" class="tinp" style="width:90px;text-align:center"><button class="btn primary" id="p17-go">Проверить</button></div>'
+'<div class="feedback" id="p17-fb"></div></div>';
h+='<div class="wg" id="p17-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Сумма всех рёбер куба</div></div>'
+'<div class="wg-help">Введи сумму длин всех рёбер куба со стороной a.</div>'
+'<div class="score-display"><span>Задача <b id="p17-ri">1</b> / 5</span><span>Очки: <b id="p17-rs">0</b> / 5</span></div>'
+'<div id="p17-rq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p17-ra" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p17-rgo">Проверить</button></div>'
+'<div class="feedback" id="p17-rfb"></div></div>';
h+=secNav('p16','p18')+readBtn('p17');
box.innerHTML=h; renderMath(box);
(function(){
var QS=[
{q:'Сколько граней у прямоугольного параллелепипеда?',ans:6},
{q:'Сколько рёбер у прямоугольного параллелепипеда?',ans:12},
{q:'Сколько вершин у прямоугольного параллелепипеда?',ans:8},
{q:'Сколько граней у куба?',ans:6},
{q:'Сколько рёбер у куба?',ans:12}
];
var i=0,score=0,cur=null;
function show(){ if(i>=5){ document.getElementById('p17-q').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p17-iv1');bumpProgress('p17',30);}else if(score>=2){addXp(8,'p17-iv1');bumpProgress('p17',16);} return; }
cur=QS[i]; document.getElementById('p17-i').textContent=i+1;
document.getElementById('p17-q').innerHTML=cur.q;
document.getElementById('p17-a').value=''; document.getElementById('p17-fb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p17-fb'), v=parseInt(document.getElementById('p17-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+'.');
document.getElementById('p17-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p17-go').addEventListener('click',go);
document.getElementById('p17-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function gen(){ var a=_ri(2,10); cur={a:a,ans:12*a}; }
function show(){ if(i>=5){ document.getElementById('p17-rq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p17-iv2');bumpProgress('p17',30);}else if(score>=2){addXp(8,'p17-iv2');bumpProgress('p17',16);} return; }
gen(); document.getElementById('p17-ri').textContent=i+1;
document.getElementById('p17-rq').innerHTML='Куб со стороной $'+cur.a+'$ см. Сумма всех рёбер?'; renderMath(document.getElementById('p17-rq'));
document.getElementById('p17-ra').value=''; document.getElementById('p17-rfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p17-rfb'), v=parseInt(document.getElementById('p17-ra').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! $12\\cdot'+cur.a+'='+cur.ans+'$ см.'); renderMath(fb); } else feedback(fb,false,'✗ Нет. $12\\cdot'+cur.a+'='+cur.ans+'$.');
document.getElementById('p17-rs').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p17-rgo').addEventListener('click',go);
document.getElementById('p17-ra').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== § 18. ОБЪЁМ ПАРАЛЛЕЛЕПИПЕДА ==== */
function buildP18(){
var box=document.getElementById('p18-body'); var h='';
h+=makeCard('oral','Где это в жизни','18.0',
'<p>Сколько воды войдёт в аквариум? Сколько коробок уместится в ящик? Какой объём холодильника? Всё это задачи на объём прямоугольного параллелепипеда.</p>');
h+=makeCard('rule','Формула объёма','18.1',
'<p>Объём прямоугольного параллелепипеда:</p>'
+'<p style="text-align:center;font-size:1.1rem">$V = a \\cdot b \\cdot c$</p>'
+'<p>Единицы: $\\text{мм}^3$, $\\text{см}^3$, $\\text{дм}^3$, $\\text{м}^3$. Особое название: $1$ л $= 1$ дм³ $= 1000$ см³.</p>'
+'<p>Куб со стороной $a$: $V=a^3$.</p>'
+'<div id="p18-fig" style="text-align:center;margin:10px 0">'
+'<svg viewBox="0 0 210 150" width="210" style="max-width:100%">'
+'<!-- Изометрия коробки 3x2x2 из кубиков -->'
+'<!-- Нижний слой кубиков, рисуем сетку: 3 вдоль a, 2 вдоль b -->'
+'<g stroke="#e11d48" stroke-width="1" fill="#fff1f2">'
+'<polygon points="20,110 60,110 70,98 30,98"/>'
+'<polygon points="60,110 100,110 110,98 70,98"/>'
+'<polygon points="100,110 140,110 150,98 110,98"/>'
+'<polygon points="60,110 100,110 110,98 70,98"/>'
+'</g>'
+'<g stroke="#e11d48" stroke-width="1" fill="#ffe4e6">'
+'<polygon points="20,110 20,78 30,66 30,98"/>'
+'<polygon points="20,78 20,46 30,34 30,66"/>'
+'</g>'
+'<g stroke="#e11d48" stroke-width="1" fill="#fecdd3">'
+'<polygon points="20,46 60,46 70,34 30,34"/>'
+'<polygon points="60,46 100,46 110,34 70,34"/>'
+'<polygon points="100,46 140,46 150,34 110,34"/>'
+'</g>'
+'<g stroke="#e11d48" stroke-width="1" fill="#fda4af">'
+'<polygon points="140,110 140,78 150,66 150,98"/>'
+'<polygon points="140,78 140,46 150,34 150,66"/>'
+'</g>'
+'<text x="80" y="125" font-size="10" fill="#e11d48" text-anchor="middle" font-weight="700">a=3</text>'
+'<text x="8" y="80" font-size="10" fill="#e11d48" text-anchor="middle" font-weight="700">c=2</text>'
+'<text x="158" y="72" font-size="10" fill="#e11d48" font-weight="700">b=2</text>'
+'<text x="80" y="20" font-size="10" fill="var(--muted)" text-anchor="middle">V = 3·2·2 = 12</text>'
+'</svg></div>');
h+=makeCard('example','Разбор по шагам','18.2',
'<p>Аквариум $40$ см × $20$ см × $25$ см. Объём в литрах?</p>'
+'<ol style="padding-left:22px;line-height:2">'
+'<li>$V=40\\cdot20\\cdot25=20\\,000$ см³.</li>'
+'<li>$1$ л $=1000$ см³, поэтому $V=20\\,000:1000=20$ л.</li>'
+'</ol>');
h+=makeCard('theory','А знаешь ли ты?','18.3',
'<p>Один кубический дециметр равен одному литру — это не случайность, а осознанное решение создателей метрической системы в $1795$ году. Они хотели, чтобы $1$ л воды весил ровно $1$ кг (при $4°$C). Задумка удалась: $1$ л воды весит $1000$ г = $1$ кг!</p>');
h+='<div class="wg" id="p18-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Найди объём</div></div>'
+'<div class="wg-help">Вычисли объём параллелепипеда.</div>'
+'<div class="score-display"><span>Задача <b id="p18-i">1</b> / 6</span><span>Очки: <b id="p18-s">0</b> / 6</span></div>'
+'<div id="p18-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p18-a" class="tinp" style="width:110px;text-align:center"><button class="btn primary" id="p18-go">Проверить</button></div>'
+'<div class="feedback" id="p18-fb"></div></div>';
h+='<div class="wg" id="p18-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Ребро по объёму</div></div>'
+'<div class="wg-help">Найди неизвестное ребро по объёму.</div>'
+'<div class="score-display"><span>Задача <b id="p18-ei">1</b> / 5</span><span>Очки: <b id="p18-es">0</b> / 5</span></div>'
+'<div id="p18-eq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="number" id="p18-ea" class="tinp" style="width:100px;text-align:center"><button class="btn primary" id="p18-ego">Проверить</button></div>'
+'<div class="feedback" id="p18-efb"></div></div>';
h+=secNav('p17','final')+readBtn('p18');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){ var t=_ri(0,1);
if(t===0){ var a=_ri(2,8),b=_ri(2,8),c=_ri(2,8); cur={q:'Параллелепипед $'+a+'\\times'+b+'\\times'+c+'$. Объём?',ans:a*b*c}; }
else { var a=_ri(2,8); cur={q:'Куб со стороной $'+a+'$ см. Объём (см³)?',ans:a*a*a}; } }
function show(){ if(i>=6){ document.getElementById('p18-q').innerHTML='<b>Готово! '+score+' / 6</b>'; if(score>=5){addXp(15,'p18-iv1');bumpProgress('p18',30);}else if(score>=3){addXp(8,'p18-iv1');bumpProgress('p18',16);} return; }
gen(); document.getElementById('p18-i').textContent=i+1;
document.getElementById('p18-q').innerHTML=cur.q; renderMath(document.getElementById('p18-q'));
document.getElementById('p18-a').value=''; document.getElementById('p18-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p18-fb'), v=parseInt(document.getElementById('p18-a').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Объём '+cur.ans+'.'); } else feedback(fb,false,'✗ Нет. Ответ: '+cur.ans+'.');
document.getElementById('p18-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p18-go').addEventListener('click',go);
document.getElementById('p18-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
(function(){
var i=0,score=0,cur=null;
function gen(){ var a=_ri(2,8), b=_ri(2,8), c=_ri(2,8); cur={a:a,b:b,c:c,V:a*b*c,ans:c}; }
function show(){ if(i>=5){ document.getElementById('p18-eq').innerHTML='<b>Готово! '+score+' / 5</b>'; if(score>=4){addXp(15,'p18-iv2');bumpProgress('p18',30);}else if(score>=2){addXp(8,'p18-iv2');bumpProgress('p18',16);} return; }
gen(); document.getElementById('p18-ei').textContent=i+1;
document.getElementById('p18-eq').innerHTML='Объём $'+cur.V+'$ см³, основание $'+cur.a+'\\times'+cur.b+'$ см². Высота?'; renderMath(document.getElementById('p18-eq'));
document.getElementById('p18-ea').value=''; document.getElementById('p18-efb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p18-efb'), v=parseInt(document.getElementById('p18-ea').value,10);
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(v===cur.ans){ score++; feedback(fb,true,'✓ Верно! Высота '+cur.ans+' см.'); } else feedback(fb,false,'✗ Нет. Высота: '+cur.ans+' ('+cur.V+'/'+cur.a+'/'+cur.b+'='+cur.ans+').');
document.getElementById('p18-es').textContent=score; i++; setTimeout(show,1300); }
document.getElementById('p18-ego').addEventListener('click',go);
document.getElementById('p18-ea').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); });
show();
})();
}
/* ==== ДАННЫЕ ==== */
var SIDEBARS={
final:{title:'Финал главы 3',rows:[['5 боссов','дроби и геометрия'],['Победа','4 из 5'],['Награда','+40 XP, ачивка']]}
};
var TIPS=[];
var GLOSSARY=[];
var BUILDERS={p1:buildP1,p2:buildP2,p3:buildP3,p4:buildP4,p5:buildP5,p6:buildP6,p7:buildP7,p8:buildP8,p9:buildP9,p10:buildP10,p11:buildP11,p12:buildP12,p13:buildP13,p14:buildP14,p15:buildP15,p16:buildP16,p17:buildP17,p18:buildP18,final:buildFinal};
Object.assign(window.M6,{sidebars:SIDEBARS,tips:TIPS,glossary:GLOSSARY,builders:BUILDERS});
</script>
</body>
</html>