diff --git a/frontend/textbooks/physics_10_ch2.html b/frontend/textbooks/physics_10_ch2.html
index c9cd5e2..a387ef8 100644
--- a/frontend/textbooks/physics_10_ch2.html
+++ b/frontend/textbooks/physics_10_ch2.html
@@ -2156,35 +2156,653 @@ function build_p14(){
function build_p15(){
const box = document.getElementById('p15-body');
let html = '';
- html += makeCard('theory', "Тепловые двигатели. Цикл Карно", "§15", `
-
Тепловые двигатели. Цикл Карно — этот параграф в разработке (Phase 1+).
- Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 2+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
+
+ /* THEORY 1 — Устройство и принцип теплового двигателя */
+ html += makeCard('theory', "Устройство и принцип теплового двигателя", "§15", `
+ Тепловой двигатель — устройство, преобразующее часть теплоты в механическую работу.
+ Три обязательных элемента:
+
+ Нагреватель — источник теплоты, температура $T_1$.
+ Рабочее тело — газ или пар; циклически расширяется и сжимается.
+ Холодильник — приёмник избыточной теплоты, температура $T_2 < T_1$.
+
+ За один полный цикл рабочее тело:
+
+ получает $Q_1$ от нагревателя;
+ совершает полезную работу $A$;
+ отдаёт $Q_2$ холодильнику.
+
+ По закону сохранения энергии $Q_1 = A + Q_2$, откуда:
+ $$A = Q_1 - Q_2$$
+ Без холодильника двигатель работать не может — без отвода $Q_2$ цикл не замкнётся.
`);
+
+ /* THEORY 2 — КПД и цикл Карно */
+ html += makeCard('rule', "КПД и цикл Карно", "§15", `
+ Коэффициент полезного действия (КПД) теплового двигателя — отношение совершённой работы к полученной теплоте:
+ $$\\eta = \\dfrac{A}{Q_1} = \\dfrac{Q_1 - Q_2}{Q_1} = 1 - \\dfrac{Q_2}{Q_1}$$
+ Всегда $\\eta < 1$ — часть теплоты неизбежно отдаётся холодильнику.
+ Цикл Карно — идеальный обратимый цикл с максимальным КПД. Состоит из 4 этапов:
+
+ Изотермическое расширение при $T_1$ (рабочее тело получает $Q_1$).
+ Адиабатное расширение (охлаждение от $T_1$ до $T_2$).
+ Изотермическое сжатие при $T_2$ (отдаёт $Q_2$).
+ Адиабатное сжатие (нагрев от $T_2$ до $T_1$).
+
+ КПД цикла Карно зависит только от температур :
+ $$\\eta_{Карно} = \\dfrac{T_1 - T_2}{T_1} = 1 - \\dfrac{T_2}{T_1}$$
+ Полезно: увеличить $T_1$ выгоднее, чем равнозначно уменьшить $T_2$ — растёт знаменатель работы и абсолютная разность.
+ `);
+
+ /* THEORY 3 — Реальные двигатели и экология */
+ html += makeCard('example', "Реальные двигатели и экология", "§15", `
+ Теорема Карно: $\\eta_{Карно}$ — максимально возможный КПД для теплового двигателя между $T_1$ и $T_2$. Любой реальный двигатель имеет $\\eta \\le \\eta_{Карно}$.
+ Реальные значения КПД:
+
+ Двигатель КПД
+
+ ДВС бензиновый 25–35%
+ Дизельный 35–45%
+ Паровая турбина (АЭС, ТЭС) 30–40%
+ Газовая турбина (комб. цикл) до 60%
+ Карно при $T_1=800$ К, $T_2=300$ К 62,5%
+
+
+ Второй закон термодинамики (формулировка Кельвина): невозможен процесс, единственным результатом которого было бы превращение теплоты в работу. Невозможен «вечный двигатель 2-го рода» с $\\eta = 100\\%$.
+ Экологические проблемы:
+
+ тепловое загрязнение (нагрев водоёмов, атмосферы);
+ $CO_2$ — парниковый эффект;
+ $NO_x$, $SO_x$ — кислотные дожди;
+ сажа, тяжёлые металлы — загрязнение воздуха.
+
+ Развитие электротранспорта, ВИЭ и АЭС — путь к снижению этих эффектов.
+ `);
+
+ /* INTERACTIVE 1 — Цикл Карно на PV-диаграмме */
+ html += `
+
+
Двигай ползунки $T_1, T_2$. Жёлтым — изотермы, фиолетовым — адиабаты. Заштрихованная область = работа за цикл.
+
+
+
+
+
+
`;
+
+ /* INTERACTIVE 2 — Калькулятор КПД */
+ html += `
+
+
Выбери способ — введи данные — получи КПД в процентах.
+
+ Через $Q_1, Q_2$
+ Через $A, Q_1$
+ Карно: $T_1, T_2$
+
+
+
Найти КПД
+
+
+
`;
+
+ /* INTERACTIVE 3 — Возможен ли двигатель? */
+ html += `
+
+
6 ситуаций. Сравни заявленный КПД с теоремой Карно.
+
Задание 1 / 6 Очки: 0 / 6
+
+
+ Возможен
+ Нарушает 2-й закон
+
+
+
`;
+
+ /* INTERACTIVE 4 — Тренажёр КПД */
+ html += `
+
+
5 задач. Допуск $\\pm 5\\%$. Ответ — число (КПД в %, работа в кДж и т.п.).
+
Задача 1 / 5 Очки: 0 / 5
+
+
+ ответ =
+
+ Проверить
+ Заново
+
+
+
`;
+
html += secNav('p14', 'final2');
html += readButton('p15');
+
box.innerHTML = html;
renderMath(box);
+
+ /* IV1 — Цикл Карно на PV-диаграмме */
+ (function(){
+ const R = 8.314;
+ const NU = 1;
+ const GAMMA = 5/3;
+ const slBox = document.getElementById('p15-iv1-sliders');
+ const svg = document.getElementById('p15-iv1-svg');
+ const info = document.getElementById('p15-iv1-info');
+ const seen = new Set(); let _done = false;
+
+ slBox.innerHTML = ''
+ + '$T_1$ (нагреватель): 600 К '
+ + '$T_2$ (холодильник): 300 К ';
+ renderMath(slBox);
+
+ function render(){
+ const T1 = +document.getElementById('p15-iv1-t1').value;
+ let T2 = +document.getElementById('p15-iv1-t2').value;
+ if(T2 >= T1) T2 = T1 - 20;
+ document.getElementById('p15-iv1-t1L').textContent = T1;
+ document.getElementById('p15-iv1-t2L').textContent = T2;
+
+ // Точки цикла (PV-плоскость): V в л, p в "виртуальных атм" (используем RT/V напрямую)
+ // Внутри: давление p = nu R T / V (Дж/м^3 если V в м^3); для шкалы — отнормируем
+ const V_A = 1, V_B = 3; // л — изотерма T1
+ const V_C = 5; // л — конец адиабаты от B
+ // pV^gamma = const на адиабате BC: p_B * V_B^g = p_C * V_C^g
+ // Также p_C = nu R T2 / V_C (точка C на изотерме T2)
+ // Адиабата: T V^(g-1) = const → T1 * V_B^(g-1) = T2 * V_C^(g-1)
+ // Тогда V_C из физики: V_C = V_B * (T1/T2)^(1/(g-1))
+ const V_C_calc = V_B * Math.pow(T1/T2, 1/(GAMMA-1));
+ const V_C_use = V_C_calc;
+ // Аналогично для DA: T1 * V_A^(g-1) = T2 * V_D^(g-1)
+ const V_D = V_A * Math.pow(T1/T2, 1/(GAMMA-1));
+
+ // Давления (произвольные единицы — RT/V, R=8.314, T в К, V в л → давление в Дж/л = кПа)
+ function pIso(T, V){ return NU * R * T / V; } // кПа
+ const p_A = pIso(T1, V_A);
+ const p_B = pIso(T1, V_B);
+ const p_C = pIso(T2, V_C_use);
+ const p_D = pIso(T2, V_D);
+
+ // Q1 (получено на AB), Q2 (отдано на CD)
+ const Q1 = NU * R * T1 * Math.log(V_B / V_A);
+ const Q2 = NU * R * T2 * Math.log(V_C_use / V_D);
+ const A = Q1 - Q2;
+ const eta = 1 - T2 / T1;
+
+ // SVG: оси V (1..6 л), p (0..max)
+ const W = 480, H = 360, pad = 50;
+ const xmin = 0.5, xmax = 6.2;
+ // верхняя граница p — для красивого масштаба
+ const pmax = Math.max(p_A, p_B, p_C, p_D) * 1.1;
+ const pmin = 0;
+ const ux = (W - 2*pad) / (xmax - xmin);
+ const uy = (H - 2*pad) / (pmax - pmin);
+ const toX = v => pad + (v - xmin) * ux;
+ const toY = p => H - pad - (p - pmin) * uy;
+
+ let g = '';
+ // Сетка
+ g += ' ';
+ g += '';
+ for(let v=1; v<=6; v++){
+ g += ' ';
+ }
+ g += ' ';
+ // Оси
+ g += ' ';
+ g += ' ';
+ g += 'V, л ';
+ g += 'p, кПа ';
+ // Метки оси V
+ for(let v=1; v<=6; v++){
+ g += ''+v+' ';
+ }
+ // Метки оси p (4 деления)
+ for(let i=1;i<=4;i++){
+ const pv = pmax*i/4;
+ g += ''+pv.toFixed(0)+' ';
+ g += ' ';
+ }
+
+ // Построим путь по циклу (для заливки) и отдельно линии цвета
+ function pathIso(T, v1, v2, N){
+ N = N || 60;
+ let d = '';
+ for(let i=0;i<=N;i++){
+ const v = v1 + (v2-v1)*i/N;
+ const p = pIso(T, v);
+ d += (i===0?'M':' L') + toX(v).toFixed(2) + ',' + toY(p).toFixed(2);
+ }
+ return d;
+ }
+ function pathAdi(pStart, vStart, vEnd, N){
+ N = N || 60;
+ const C = pStart * Math.pow(vStart, GAMMA);
+ let d = '';
+ for(let i=0;i<=N;i++){
+ const v = vStart + (vEnd-vStart)*i/N;
+ const p = C / Math.pow(v, GAMMA);
+ d += (i===0?'M':' L') + toX(v).toFixed(2) + ',' + toY(p).toFixed(2);
+ }
+ return d;
+ }
+
+ // Полный замкнутый путь: A→B (изо T1) → C (адиа) → D (изо T2) → A (адиа)
+ const dAB = pathIso(T1, V_A, V_B);
+ const dBC = pathAdi(p_B, V_B, V_C_use);
+ const dCD = pathIso(T2, V_C_use, V_D);
+ const dDA = pathAdi(p_D, V_D, V_A);
+
+ // Заливка площади цикла
+ const fullPath = dAB + ' ' + dBC.replace(/^M/, 'L') + ' ' + dCD.replace(/^M/, 'L') + ' ' + dDA.replace(/^M/, 'L') + ' Z';
+ g += ' ';
+
+ // Линии
+ g += ' '; // изо T1
+ g += ' '; // адиа
+ g += ' '; // изо T2
+ g += ' '; // адиа сжатия
+
+ // Точки A,B,C,D
+ function pt(x,y,lab,col){
+ return ' '
+ + ''+lab+' ';
+ }
+ g += pt(toX(V_A), toY(p_A), 'A', '#ea580c');
+ g += pt(toX(V_B), toY(p_B), 'B', '#ea580c');
+ g += pt(toX(V_C_use), toY(p_C), 'C', '#2563eb');
+ g += pt(toX(V_D), toY(p_D), 'D', '#2563eb');
+
+ // Легенда
+ g += '';
+ g += ' ';
+ g += ' ';
+ g += 'изотерма T₁ ';
+ g += ' ';
+ g += 'изотерма T₂ ';
+ g += ' ';
+ g += 'адиабаты ';
+ g += ' ';
+
+ svg.innerHTML = g;
+
+ // Инфо
+ info.innerHTML = ''
+ + '$T_1 = '+T1+'$ К, $T_2 = '+T2+'$ К
'
+ + '$Q_1 = \\nu RT_1\\ln(V_B/V_A) \\approx '+Q1.toFixed(1)+'$ Дж (получено)
'
+ + '$Q_2 = \\nu RT_2\\ln(V_C/V_D) \\approx '+Q2.toFixed(1)+'$ Дж (отдано)
'
+ + '$A = Q_1 - Q_2 \\approx '+A.toFixed(1)+'$ Дж (работа за цикл)
'
+ + '$\\eta_{Карно} = 1 - T_2/T_1 = '+(eta*100).toFixed(1)+'\\%$
';
+ renderMath(info);
+
+ seen.add(T1+'_'+T2);
+ if(!_done && seen.size >= 4){ _done = true; addXp(10,'p15-iv1'); bumpProgress('p15', 15); }
+ }
+ document.getElementById('p15-iv1-t1').addEventListener('input', render);
+ document.getElementById('p15-iv1-t2').addEventListener('input', render);
+ render();
+ })();
+
+ /* IV2 — Калькулятор КПД */
+ (function(){
+ const tabs = document.getElementById('p15-iv2-tabs');
+ const inpsBox = document.getElementById('p15-iv2-inputs');
+ const out = document.getElementById('p15-iv2-out');
+ const fb = document.getElementById('p15-iv2-fb');
+ const used = new Set(); let _done = false;
+ let mode = 'QQ';
+
+ function field(id, label, val){
+ return ''+label+' ';
+ }
+ function build(){
+ let h = '';
+ if(mode === 'QQ'){
+ h += field('p15-iv2-Q1','$Q_1$, Дж','1000');
+ h += field('p15-iv2-Q2','$Q_2$, Дж','700');
+ } else if(mode === 'AQ'){
+ h += field('p15-iv2-A','$A$, Дж','300');
+ h += field('p15-iv2-Q1','$Q_1$, Дж','1000');
+ } else {
+ h += field('p15-iv2-T1','$T_1$, К','600');
+ h += field('p15-iv2-T2','$T_2$, К','300');
+ }
+ inpsBox.innerHTML = h;
+ renderMath(inpsBox);
+ out.innerHTML = '';
+ fb.style.display = 'none';
+ }
+ function num(id){ const el = document.getElementById(id); return el ? parseFloat((el.value||'').replace(',','.')) : NaN; }
+ function calc(){
+ let res = '', eta = NaN;
+ if(mode === 'QQ'){
+ const Q1 = num('p15-iv2-Q1'), Q2 = num('p15-iv2-Q2');
+ if(![Q1,Q2].every(isFinite) || Q1 <= 0){ feedback(fb,false,'✗ Введи корректные $Q_1 > 0$ и $Q_2$.'); return; }
+ eta = (Q1 - Q2) / Q1;
+ res = '$\\eta = \\dfrac{Q_1 - Q_2}{Q_1} = \\dfrac{'+Q1+' - '+Q2+'}{'+Q1+'} = '+eta.toFixed(4)+'$';
+ } else if(mode === 'AQ'){
+ const A = num('p15-iv2-A'), Q1 = num('p15-iv2-Q1');
+ if(![A,Q1].every(isFinite) || Q1 <= 0){ feedback(fb,false,'✗ Введи $A$ и $Q_1 > 0$.'); return; }
+ eta = A / Q1;
+ res = '$\\eta = \\dfrac{A}{Q_1} = \\dfrac{'+A+'}{'+Q1+'} = '+eta.toFixed(4)+'$';
+ } else {
+ const T1 = num('p15-iv2-T1'), T2 = num('p15-iv2-T2');
+ if(![T1,T2].every(isFinite) || T1 <= 0){ feedback(fb,false,'✗ Введи $T_1 > 0$ и $T_2$.'); return; }
+ if(T2 >= T1){ feedback(fb,false,'✗ Должно быть $T_2 < T_1$.'); return; }
+ eta = 1 - T2/T1;
+ res = '$\\eta_{Карно} = 1 - \\dfrac{T_2}{T_1} = 1 - \\dfrac{'+T2+'}{'+T1+'} = '+eta.toFixed(4)+'$';
+ }
+ out.innerHTML = ''+res+'
'
+ + 'Ответ: $\\eta \\approx '+(eta*100).toFixed(2)+'\\%$
';
+ renderMath(out);
+ feedback(fb, true, '✓ Вычислено.');
+ used.add(mode);
+ if(!_done && used.size === 3){ _done = true; addXp(10,'p15-iv2'); bumpProgress('p15', 15); }
+ }
+ tabs.querySelectorAll('button').forEach(b => {
+ b.addEventListener('click', () => {
+ mode = b.dataset.mode;
+ tabs.querySelectorAll('button').forEach(x => { x.className = 'btn'; });
+ b.className = 'btn primary';
+ build();
+ });
+ });
+ document.getElementById('p15-iv2-go').addEventListener('click', calc);
+ build();
+ })();
+
+ /* IV3 — Возможен ли двигатель? */
+ (function(){
+ const Q = [
+ { q:'Бензиновый ДВС с заявленным $\\eta = 30\\%$.', ans:'ok', why:'30% — типичный КПД ДВС.' },
+ { q:'Двигатель с $\\eta = 99\\%$ при $T_1 = 400$ К, $T_2 = 300$ К. Карно даёт $25\\%$.', ans:'no', why:'$99\\% > \\eta_{Карно} = 25\\%$ — нарушает теорему Карно.' },
+ { q:'Двигатель с $\\eta = 60\\%$ при $T_1 = 1000$ К, $T_2 = 400$ К. Карно даёт ровно $60\\%$.', ans:'ok', why:'$\\eta = \\eta_{Карно}$ — идеальный случай (предел).' },
+ { q:'Двигатель с $\\eta = 100\\%$ (полностью теплота → работа).', ans:'no', why:'Запрещает 2-й закон термодинамики (вечный двигатель 2-го рода).' },
+ { q:'Паровая турбина с $\\eta = 35\\%$ при $T_1 = 600$ К, $T_2 = 320$ К. Карно даёт $\\approx 47\\%$.', ans:'ok', why:'$35\\% < 47\\%$ — реальное значение, всё в порядке.' },
+ { q:'Двигатель с $\\eta = 50\\%$ при $T_1 = 500$ К, $T_2 = 300$ К. Карно даёт $40\\%$.', ans:'no', why:'$50\\% > \\eta_{Карно} = 40\\%$ — превышает предел Карно.' },
+ ];
+ let i = 0, score = 0; let _done = false;
+ const box = document.getElementById('p15-iv3');
+ function show(){
+ const qEl = document.getElementById('p15-iv3-q');
+ const fb = document.getElementById('p15-iv3-fb');
+ if(i >= Q.length){
+ qEl.innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ renderMath(qEl);
+ if(!_done){
+ _done = true;
+ if(score === Q.length){ addXp(15,'p15-iv3'); bumpProgress('p15', 25); }
+ else if(score >= 4){ addXp(8,'p15-iv3'); bumpProgress('p15', 15); }
+ }
+ return;
+ }
+ document.getElementById('p15-iv3-i').textContent = (i+1);
+ document.getElementById('p15-iv3-s').textContent = score;
+ qEl.innerHTML = Q[i].q;
+ renderMath(qEl);
+ fb.style.display = 'none';
+ }
+ box.querySelectorAll('button[data-ans]').forEach(b => {
+ b.addEventListener('click', () => {
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p15-iv3-fb');
+ if(b.dataset.ans === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! '+Q[i].why+' Дальше ▶'); }
+ else feedback(fb, false, '✗ Неверно. '+Q[i].why+' Дальше ▶');
+ document.getElementById('p15-iv3-s').textContent = score;
+ i++;
+ setTimeout(show, 1800);
+ });
+ });
+ show();
+ })();
+
+ /* IV4 — Тренажёр КПД */
+ (function(){
+ const Q = [
+ { q:'Двигатель получил $Q_1 = 1000$ Дж и отдал $Q_2 = 700$ Дж. КПД в %?', ans:30, tol:2, hint:'$\\eta = (1000-700)/1000 = 30\\%$' },
+ { q:'Двигатель Карно работает между $T_1 = 600$ К и $T_2 = 300$ К. КПД в %?', ans:50, tol:2, hint:'$\\eta = 1 - 300/600 = 50\\%$' },
+ { q:'$T_1 = 500$ К, $T_2 = 300$ К. Что выгоднее: нагреть $T_1$ на 100 К (введи $1$) или охладить $T_2$ на 100 К (введи $2$)?', ans:2, tol:0.4, hint:'$T_1 \\to 600$: $\\eta = 0{,}5$. $T_2 \\to 200$: $\\eta \\approx 0{,}6$. Холодильник выгоднее.' },
+ { q:'ДВС бензиновый совершил работу $A = 30$ кДж за цикл при $\\eta = 25\\%$. Сколько $Q_1$ в кДж?', ans:120, tol:6, hint:'$Q_1 = A/\\eta = 30/0{,}25 = 120$ кДж' },
+ { q:'Идеальный Карно: $T_1 = 800$ К, $T_2 = 400$ К. КПД в %?', ans:50, tol:2, hint:'$\\eta = 1 - 400/800 = 50\\%$' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ if(i >= Q.length){
+ document.getElementById('p15-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ if(score === Q.length){ addXp(15, 'p15-iv4'); bumpProgress('p15', 25); }
+ else if(score >= 3){ addXp(8, 'p15-iv4'); bumpProgress('p15', 15); }
+ return;
+ }
+ document.getElementById('p15-iv4-i').textContent = (i+1);
+ document.getElementById('p15-iv4-s').textContent = score;
+ document.getElementById('p15-iv4-q').innerHTML = Q[i].q;
+ document.getElementById('p15-iv4-ans').value = '';
+ renderMath(document.getElementById('p15-iv4-q'));
+ document.getElementById('p15-iv4-fb').style.display = 'none';
+ }
+ function go(){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p15-iv4-fb');
+ const raw = document.getElementById('p15-iv4-ans').value.replace(',', '.');
+ const ans = parseFloat(raw);
+ if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; }
+ if(Math.abs(ans - Q[i].ans) <= Q[i].tol + 0.001){ score++; feedback(fb, true, '✓ Верно! '+Q[i].hint+'. Дальше ▶'); }
+ else feedback(fb, false, '✗ Неверно. Ответ: $'+Q[i].ans+'$. '+Q[i].hint+'. Дальше ▶');
+ document.getElementById('p15-iv4-s').textContent = score;
+ i++;
+ setTimeout(show, 1800);
+ }
+ document.getElementById('p15-iv4-go').addEventListener('click', go);
+ document.getElementById('p15-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
+ document.getElementById('p15-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
wireReadBtn('p15');
}
function build_final2(){
const box = document.getElementById('final2-body');
let html = '';
- html += makeCard('theory', "Финал главы 2", "★", `
- Финал главы 2 — этот параграф в разработке (Phase 1+).
- Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 2+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
- `);
+
+ /* Часть А — Шпаргалка главы (5 mini-карточек) */
+ const SHEET = [
+ { t:'§ 11 · Внутренняя энергия', icon:' ', body:'$U = \\dfrac{i}{2}\\nu RT$. Зависит только от $T$. $i = 3$ (одноат.), $i = 5$ (двухат.).' },
+ { t:'§ 12 · Работа', icon:' ', body:'Изобарно $A = p\\Delta V$. Изотермически $A = \\nu RT\\ln(V_2/V_1)$. Изохорно $A = 0$.' },
+ { t:'§ 13 · Теплота', icon:' ', body:'$Q = cm\\Delta T$, $Q = \\lambda m$, $Q = rm$, $Q = qm$. Уравнение теплового баланса.' },
+ { t:'§ 14 · 1-й закон ТД', icon:' ', body:'$Q = \\Delta U + A_{газ}$. Изотерм.: $Q = A$. Изохорно: $Q = \\Delta U$. Адиабатно: $\\Delta U = -A$.' },
+ { t:'§ 15 · Тепл. двигатели', icon:' ', body:'$\\eta = (Q_1-Q_2)/Q_1$. Карно: $\\eta = 1 - T_2/T_1$ — максимальный КПД.' },
+ ];
+
+ html += `
+
+
+
Ключевые формулы и идеи всех 5 параграфов главы — повтори перед битвой с боссами.
+
+ ${SHEET.map(s => `
`).join('')}
+
+
+
`;
+
+ /* Часть Б — 5 боссов intro */
+ html += `
+
+
+
5 интегрированных задач по §§11–15. За каждого побеждённого босса: +10 XP, +18% к прогрессу . Победишь всех — ачивка «Мастер термодинамики» и +50 XP бонус .
+
Константы: $R = 8{,}3$ Дж/(моль·К), $c_{вода} = 4200$ Дж/(кг·К), $\\lambda_{лёд} = 330$ кДж/кг, $r_{вода} = 2260$ кДж/кг. Допуск $\\pm 5\\%$.
+
+
`;
+
+ html += '
';
+
+ html += `
+
Прогресс по боссам
+
0 / 5 боссов побеждено
+
+
+
Мастер термодинамики
+
Глава 2 пройдена! Все 5 боссов повержены. +50 XP бонус.
+
Дальше: Глава 3
+
+
`;
+
html += secNav('p15', null);
- html += readButton('final2');
+
box.innerHTML = html;
renderMath(box);
- wireReadBtn('final2');
+
+ /* Боссы */
+ const BOSSES = [
+ {
+ n:1, color:'#0ea5e9',
+ title:'Хранитель Внутренней Энергии',
+ tag:'§ 11',
+ q:'$\\nu = 1$ моль одноатомного газа при $T = 400$ К. Найди $U$ в кДж (до сотых).',
+ ans:4.98, tol:0.1,
+ hint:'$U = \\tfrac{3}{2}\\nu RT = 1{,}5 \\cdot 1 \\cdot 8{,}3 \\cdot 400 = 4980$ Дж $\\approx 4{,}98$ кДж.'
+ },
+ {
+ n:2, color:'#10b981',
+ title:'Поршневой Гигант',
+ tag:'§ 12',
+ q:'Изобарно при $p = 2$ атм газ расширили от $5$ до $15$ л. Работа газа в Дж?',
+ ans:2000, tol:60,
+ hint:'$A = p\\Delta V = 2 \\cdot 10^5 \\cdot 10 \\cdot 10^{-3} = 2000$ Дж.'
+ },
+ {
+ n:3, color:'#f59e0b',
+ title:'Кипящий Левиафан',
+ tag:'§ 13',
+ q:'Нагреть $3$ кг воды от $20°$C до $100°$C и испарить. Найди $Q_{общ}$ в МДж (до десятых).',
+ ans:7.8, tol:0.3,
+ hint:'$Q_1 = cm\\Delta T = 4200 \\cdot 3 \\cdot 80 \\approx 1{,}01$ МДж. $Q_2 = rm = 2{,}26 \\cdot 3 = 6{,}78$ МДж. Сумма $\\approx 7{,}8$ МДж.'
+ },
+ {
+ n:4, color:'#7c3aed',
+ title:'Сторож Первого Закона',
+ tag:'§ 14',
+ q:'Газ получил $Q = 800$ Дж и совершил работу $A = 500$ Дж. Найди $\\Delta U$ в Дж.',
+ ans:300, tol:10,
+ hint:'$\\Delta U = Q - A = 800 - 500 = 300$ Дж.'
+ },
+ {
+ n:5, color:'#dc2626',
+ title:'Магистр Термодинамики',
+ tag:'§ 15',
+ q:'Двигатель Карно: $T_1 = 500$ К, $T_2 = 300$ К, $Q_1 = 1000$ Дж за цикл. Найди работу $A$ в Дж.',
+ ans:400, tol:15,
+ hint:'$\\eta = 1 - 300/500 = 0{,}4$. $A = \\eta Q_1 = 0{,}4 \\cdot 1000 = 400$ Дж.'
+ },
+ ];
+
+ const cont = document.getElementById('ch2-bosses-container');
+ const STATE_KEY = 'physics10_ch2_bosses';
+ const BOSS_STATE = (function(){
+ try{ const s = localStorage.getItem(STATE_KEY); if(s){ const p = JSON.parse(s); if(Array.isArray(p) && p.length === BOSSES.length) return p; } }catch(e){}
+ return BOSSES.map(()=>({defeated:false}));
+ })();
+ function saveBosses(){ try{ localStorage.setItem(STATE_KEY, JSON.stringify(BOSS_STATE)); }catch(e){} }
+
+ cont.innerHTML = BOSSES.map((b)=>{
+ return ''
+ +'
'
+ +'
'
+ +'
Босс '+b.n+': '+b.title+'
'
+ +'
'+b.tag+'
'
+ +'
'
+ +'
'+b.q+'
'
+ +'
'
+ +'ответ = '
+ +' '
+ +'Атаковать '
+ +'Подсказка '
+ +'
'
+ +'
'
+ +'
';
+ }).join('');
+ renderMath(cont);
+
+ function refreshOverall(){
+ const won = BOSS_STATE.filter(s => s.defeated).length;
+ const txt = document.getElementById('ch2-boss-overall');
+ const fill = document.getElementById('ch2-boss-overall-fill');
+ if(txt) txt.textContent = won + ' / ' + BOSSES.length + ' боссов побеждено';
+ if(fill) fill.style.width = (won * 100 / BOSSES.length) + '%';
+ if(won >= BOSSES.length){
+ const reward = document.getElementById('ch2-final-reward');
+ if(reward && reward.style.display === 'none'){
+ reward.style.display = 'block';
+ if(!STATE.achievements.has('ch2_done')){
+ achievement('ch2_done','Мастер термодинамики');
+ addXp(50, 'ch2-bonus');
+ bumpProgress('final2', 30);
+ if(window.confetti){ try{ confetti(); }catch(e){} }
+ }
+ }
+ }
+ }
+
+ BOSSES.forEach((b, idx)=>{
+ const card = document.getElementById('boss2-'+b.n+'-card');
+ const goBtn = document.getElementById('boss2-'+b.n+'-go');
+ const hintBtn = document.getElementById('boss2-'+b.n+'-hint');
+ const ansInp = document.getElementById('boss2-'+b.n+'-ans');
+ if(BOSS_STATE[idx].defeated){
+ card.style.background = 'linear-gradient(135deg,var(--sec-acc-soft),var(--pri-soft))';
+ card.classList.add('glow');
+ goBtn.disabled = true; goBtn.style.opacity = .55; goBtn.textContent = '✓ Повержен';
+ ansInp.disabled = true;
+ }
+ goBtn.addEventListener('click', ()=>{
+ if(BOSS_STATE[idx].defeated) return;
+ const fb = document.getElementById('boss2-'+b.n+'-fb');
+ const raw = ansInp.value.replace(',', '.');
+ const val = parseFloat(raw);
+ if(isNaN(val)){ feedback(fb, false, '✗ Введи число.'); return; }
+ const tol = (typeof b.tol === 'number') ? b.tol : Math.max(0.05 * Math.abs(b.ans), 0.05);
+ if(Math.abs(val - b.ans) < tol + 0.001){
+ BOSS_STATE[idx].defeated = true; saveBosses();
+ feedback(fb, true, '✓ Босс '+b.n+' повержен! +10 XP. '+b.hint);
+ addXp(10, 'boss-ch2-'+b.n);
+ bumpProgress('final2', 18);
+ goBtn.disabled = true; goBtn.style.opacity = .55; goBtn.textContent = '✓ Повержен';
+ ansInp.disabled = true;
+ card.style.background = 'linear-gradient(135deg,var(--sec-acc-soft),var(--pri-soft))';
+ card.classList.add('glow','pulse');
+ setTimeout(()=>card.classList.remove('pulse'), 900);
+ refreshOverall();
+ } else {
+ feedback(fb, false, '✗ Промах. Попробуй ещё. Подсказка доступна.');
+ }
+ });
+ hintBtn.addEventListener('click', ()=>{
+ const fb = document.getElementById('boss2-'+b.n+'-fb');
+ fb.className = 'feedback ok';
+ fb.innerHTML = 'Подсказка: '+b.hint;
+ fb.style.display = 'block';
+ fb.style.background = 'var(--warn-bg)';
+ fb.style.color = '#92400e';
+ fb.style.borderLeftColor = 'var(--warn)';
+ renderMath(fb);
+ });
+ ansInp.addEventListener('keydown', e=>{ if(e.key === 'Enter') goBtn.click(); });
+ });
+
+ refreshOverall();
}
/* ===== Search ===== */