diff --git a/frontend/textbooks/physics_10_ch2.html b/frontend/textbooks/physics_10_ch2.html
index 9588403..c9cd5e2 100644
--- a/frontend/textbooks/physics_10_ch2.html
+++ b/frontend/textbooks/physics_10_ch2.html
@@ -1334,34 +1334,822 @@ function build_p12(){
function build_p13(){
const box = document.getElementById('p13-body');
let html = '';
- html += makeCard('theory', "Количество теплоты", "§13", `
-
Количество теплоты — этот параграф в разработке (Phase 1+).
- Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 2+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
+
+ /* THEORY 1 — Количество теплоты и удельная теплоёмкость */
+ html += makeCard('theory', "Количество теплоты и удельная теплоёмкость", "§13", `
+ Количество теплоты $Q$ — энергия, передаваемая телу при теплообмене (без совершения работы). Единица — джоуль (Дж).
+ Для нагревания или охлаждения (без фазового перехода):
+ $$Q = c\\,m\\,\\Delta T$$
+
+ $c$ — удельная теплоёмкость , Дж/(кг·К);
+ $m$ — масса тела, кг;
+ $\\Delta T = T_{кон} - T_{нач}$ — разность температур (К или °C, числовое значение совпадает).
+
+ Удельная теплоёмкость — это $Q$, нужное, чтобы нагреть 1 кг вещества на 1 К. Характеристика вещества:
+
+ Вещество $c$, Дж/(кг·К)
+
+ Вода 4200
+ Воздух 1000
+ Алюминий 920
+ Железо 460
+ Медь 390
+
+
+ Вода имеет аномально большую $c$: поэтому моря медленно нагреваются и медленно остывают — именно так формируется морской климат.
`);
+
+ /* THEORY 2 — Фазовые переходы */
+ html += makeCard('rule', "Фазовые переходы: плавление и парообразование", "§13", `
+ Плавление и кристаллизация (температура не меняется):
+ $$Q = \\lambda\\,m$$
+
+ $\\lambda$ — удельная теплота плавления , Дж/кг;
+ лёд: $\\lambda = 3{,}3 \\cdot 10^5$ Дж/кг ($= 330$ кДж/кг);
+ при плавлении $Q > 0$ (поглощается), при кристаллизации $Q < 0$ (выделяется).
+
+ Парообразование и конденсация :
+ $$Q = r\\,m$$
+
+ $r$ — удельная теплота парообразования , Дж/кг;
+ вода: $r = 2{,}26 \\cdot 10^6$ Дж/кг ($= 2260$ кДж/кг).
+
+ Важно: $r > \\lambda$ — испарение требует значительно больше энергии, чем плавление. Поэтому ожог паром гораздо опаснее ожога кипятком.
+ `);
+
+ /* THEORY 3 — Сгорание топлива и тепловой баланс */
+ html += makeCard('example', "Сгорание топлива. Уравнение теплового баланса", "§13", `
+ Сгорание топлива :
+ $$Q = q\\,m$$
+
+ $q$ — удельная теплота сгорания , Дж/кг;
+ бензин: $q = 4{,}4 \\cdot 10^7$ Дж/кг;
+ уголь: $q \\approx 2{,}9 \\cdot 10^7$ Дж/кг;
+ дрова сухие: $q \\approx 1{,}3 \\cdot 10^7$ Дж/кг.
+
+ Уравнение теплового баланса для изолированной системы (нет теплообмена с окружением):
+ $$\\sum Q_i = 0$$
+ Теплота, отданная горячими телами, равна теплоте, полученной холодными:
+ $$Q_{отд} = Q_{пол}$$
+ Пример. В калориметр наливают холодную воду и опускают горячий кусок металла. Установится общая температура $T$, при которой
+ $$c_1 m_1 (T - T_1) = c_2 m_2 (T_2 - T)$$
+ отсюда:
+ $$T = \\dfrac{c_1 m_1 T_1 + c_2 m_2 T_2}{c_1 m_1 + c_2 m_2}$$
+ `);
+
+ /* INTERACTIVE 1 — Универсальный калькулятор Q */
+ html += `
+
+
Выбери тип процесса — введи параметры — получи формулу и значение в Дж и кДж.
+
+ Нагревание $Q = cm\\Delta T$
+ Плавление $Q = \\lambda m$
+ Испарение $Q = rm$
+ Сгорание $Q = qm$
+
+
+
Вычислить $Q$
+
+
+
`;
+
+ /* INTERACTIVE 2 — График нагревания и плавления льда */
+ html += `
+
+
Меняй массу — четыре сегмента ломаной: нагрев льда, плавление, нагрев воды, испарение.
+
+ Масса $m$: 1.0 кг
+
+
+ Лёд
+ Плавление
+ Вода
+ Испарение
+
+
+
+
+
+
`;
+
+ /* INTERACTIVE 3 — DnD сортер */
+ html += `
+
+
6 явлений — 4 типа процессов.
+
+
+
+
+
+
Парообразование/конденсация
+
+
+
Проверить Сначала
+
+
`;
+
+ /* INTERACTIVE 4 — Тренажёр теплоты */
+ html += `
+
+
6 задач. $c_{воды} = 4200$, $\\lambda_{льда} = 3{,}3 \\cdot 10^5$, $r_{воды} = 2{,}26 \\cdot 10^6$, $q_{бенз} = 4{,}4 \\cdot 10^7$ (СИ). Допуск $\\pm 5\\%$.
+
Задача 1 / 6 Очки: 0 / 6
+
+
+ ответ =
+
+ Проверить
+ Заново
+
+
+
`;
+
html += secNav('p12', 'p14');
html += readButton('p13');
+
box.innerHTML = html;
renderMath(box);
+
+ /* IV1 — Универсальный калькулятор Q */
+ (function(){
+ const tabs = document.getElementById('p13-iv1-tabs');
+ const inpsBox = document.getElementById('p13-iv1-inputs');
+ const out = document.getElementById('p13-iv1-out');
+ const fb = document.getElementById('p13-iv1-fb');
+ const used = new Set(); let _done = false;
+ let mode = 'heat';
+ const C_MAP = { water:4200, air:1000, alum:920, iron:460, copper:390 };
+ const C_LBL = { water:'Вода', air:'Воздух', alum:'Алюминий', iron:'Железо', copper:'Медь' };
+ const L_MAP = { ice:330000, lead:25000, iron:270000 };
+ const L_LBL = { ice:'Лёд (330 кДж/кг)', lead:'Свинец (25 кДж/кг)', iron:'Железо (270 кДж/кг)' };
+ const R_MAP = { water:2260000, eth:360000, alc:850000 };
+ const R_LBL = { water:'Вода (2260 кДж/кг)', eth:'Эфир (360 кДж/кг)', alc:'Спирт (850 кДж/кг)' };
+ const Q_MAP = { gas:4.4e7, coal:2.9e7, wood:1.3e7 };
+ const Q_LBL = { gas:'Бензин (44 МДж/кг)', coal:'Уголь (29 МДж/кг)', wood:'Дрова (13 МДж/кг)' };
+
+ function selectHTML(id, map, lblMap){
+ let h = '';
+ Object.keys(map).forEach(k => { h += ''+lblMap[k]+' '; });
+ h += ' ';
+ return h;
+ }
+ function field(id, label, val){
+ return ''+label+' ';
+ }
+ function pickField(id, label, mapHtml){
+ return ''+label+mapHtml+' ';
+ }
+ function build(){
+ let h = '';
+ if(mode === 'heat'){
+ h += pickField('p13-iv1-sub','Вещество',selectHTML('p13-iv1-c', C_MAP, C_LBL));
+ h += field('p13-iv1-m','$m$, кг','1');
+ h += field('p13-iv1-dt','$\\Delta T$, К','50');
+ } else if(mode === 'melt'){
+ h += pickField('p13-iv1-sub','Вещество',selectHTML('p13-iv1-lam', L_MAP, L_LBL));
+ h += field('p13-iv1-m','$m$, кг','1');
+ } else if(mode === 'evap'){
+ h += pickField('p13-iv1-sub','Вещество',selectHTML('p13-iv1-r', R_MAP, R_LBL));
+ h += field('p13-iv1-m','$m$, кг','1');
+ } else {
+ h += pickField('p13-iv1-sub','Топливо',selectHTML('p13-iv1-q', Q_MAP, Q_LBL));
+ h += field('p13-iv1-m','$m$, кг','1');
+ }
+ 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 fmtJ(v){ const k = v/1000, M = v/1e6; if(Math.abs(v) >= 1e6) return v.toExponential(2)+' Дж ($\\approx '+M.toFixed(2)+'$ МДж)'; if(Math.abs(v) >= 1000) return v.toFixed(0)+' Дж ($= '+k.toFixed(1)+'$ кДж)'; return v.toFixed(1)+' Дж'; }
+ function calc(){
+ let Q = 0, res = '';
+ const m = num('p13-iv1-m');
+ if(!isFinite(m) || m <= 0){ feedback(fb,false,'✗ Масса должна быть положительной.'); return; }
+ if(mode === 'heat'){
+ const sel = document.getElementById('p13-iv1-c').value;
+ const c = C_MAP[sel];
+ const dT = num('p13-iv1-dt');
+ if(!isFinite(dT)){ feedback(fb,false,'✗ Введи $\\Delta T$.'); return; }
+ Q = c * m * dT;
+ res = '$Q = c\\,m\\,\\Delta T = '+c+' \\cdot '+m+' \\cdot '+dT+' = '+Q.toFixed(0)+'$ Дж';
+ } else if(mode === 'melt'){
+ const sel = document.getElementById('p13-iv1-lam').value;
+ const lam = L_MAP[sel];
+ Q = lam * m;
+ res = '$Q = \\lambda\\,m = '+lam.toExponential(2)+' \\cdot '+m+' = '+Q.toFixed(0)+'$ Дж';
+ } else if(mode === 'evap'){
+ const sel = document.getElementById('p13-iv1-r').value;
+ const r = R_MAP[sel];
+ Q = r * m;
+ res = '$Q = r\\,m = '+r.toExponential(2)+' \\cdot '+m+' = '+Q.toFixed(0)+'$ Дж';
+ } else {
+ const sel = document.getElementById('p13-iv1-q').value;
+ const q = Q_MAP[sel];
+ Q = q * m;
+ res = '$Q = q\\,m = '+q.toExponential(2)+' \\cdot '+m+' = '+Q.toFixed(0)+'$ Дж';
+ }
+ out.innerHTML = ''+res+'
'
+ + 'Ответ: '+fmtJ(Q)+'
';
+ renderMath(out);
+ feedback(fb, true, '✓ Вычислено.');
+ used.add(mode);
+ if(!_done && used.size === 4){ _done = true; addXp(10,'p13-iv1'); bumpProgress('p13', 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('p13-iv1-go').addEventListener('click', calc);
+ build();
+ })();
+
+ /* IV2 — График нагревания льда */
+ (function(){
+ const svg = document.getElementById('p13-iv2-svg');
+ const mIn = document.getElementById('p13-iv2-m');
+ const mL = document.getElementById('p13-iv2-mL');
+ const info = document.getElementById('p13-iv2-info');
+ const seen = new Set(); let _done = false;
+ const C_ICE = 2100, C_WATER = 4200, LAMBDA = 330000, R_VAP = 2260000;
+
+ function render(){
+ const m = +mIn.value;
+ mL.textContent = m.toFixed(1);
+ // Q-сегменты в Дж
+ const Q1 = C_ICE * m * 20; // -20 → 0
+ const Q2 = LAMBDA * m; // плавление
+ const Q3 = C_WATER * m * 100; // 0 → 100
+ const Q4 = R_VAP * m; // испарение
+ // в кДж для оси X
+ const q1 = Q1/1000, q2 = Q2/1000, q3 = Q3/1000, q4 = Q4/1000;
+ const Qtotal_kJ = q1 + q2 + q3 + q4;
+ // оси: X 0..6000 кДж × Y -20..120 °C
+ const W=420, H=280, pad=44;
+ // расширяем X-предел чтобы Q4 поместилось
+ const xMax = Math.ceil((Qtotal_kJ + 200) / 500) * 500;
+ // axes2D рисует целые тики; используем напрямую координатную сетку
+ // Зайдём в систему: вычислим toX/toY вручную
+ const xmin = 0, xmax = xMax, ymin = -20, ymax = 120;
+ const ux = (W - 2*pad) / (xmax - xmin);
+ const uy = (H - 2*pad) / (ymax - ymin);
+ const toX = v => pad + (v - xmin) * ux;
+ const toY = v => H - pad - (v - ymin) * uy;
+ let g = '';
+ g += ' ';
+ // сетка X
+ g += '';
+ const xStep = xMax / 10;
+ for(let xv = 0; xv <= xMax; xv += xStep){
+ g += ' ';
+ }
+ for(let yv = -20; yv <= 120; yv += 20){
+ g += ' ';
+ }
+ g += ' ';
+ // оси (Y=0 линия)
+ g += ' ';
+ g += ' ';
+ // подписи осей
+ g += 'Q, кДж ';
+ g += 'T, °C ';
+ // тики X
+ g += '';
+ for(let xv = 0; xv <= xMax; xv += xStep){
+ g += ''+Math.round(xv)+' ';
+ }
+ for(let yv = -20; yv <= 120; yv += 20){
+ g += ''+yv+' ';
+ }
+ g += ' ';
+
+ // Сегменты ломаной
+ let xCur = 0;
+ // 1) лёд -20 → 0 (голубой)
+ g += ' ';
+ xCur += q1;
+ // 2) плавление 0 → 0 (синий пунктир)
+ g += ' ';
+ xCur += q2;
+ // 3) вода 0 → 100 (оранжевый)
+ g += ' ';
+ xCur += q3;
+ // 4) испарение 100 → 100 (красный пунктир)
+ g += ' ';
+ xCur += q4;
+ // точки переходов
+ let xMark = 0;
+ const marks = [
+ {x:xMark, y:-20, color:'#0ea5e9'},
+ {x:(xMark+=q1), y:0, color:'#2563eb'},
+ {x:(xMark+=q2), y:0, color:'#ea580c'},
+ {x:(xMark+=q3), y:100, color:'#dc2626'},
+ {x:(xMark+=q4), y:100, color:'#7c2d12'},
+ ];
+ marks.forEach(p => { g += ' '; });
+
+ svg.innerHTML = g;
+
+ const totalMJ = Qtotal_kJ/1000;
+ info.innerHTML = 'Масса: $m = '+m.toFixed(1)+'$ кг.
'
+ + '$Q_1 = c_{льда}\\,m\\,\\Delta T = 2100 \\cdot '+m.toFixed(1)+' \\cdot 20 = '+Q1.toFixed(0)+'$ Дж $\\approx '+q1.toFixed(0)+'$ кДж
'
+ + '$Q_2 = \\lambda\\,m = '+LAMBDA+' \\cdot '+m.toFixed(1)+' = '+Q2.toFixed(0)+'$ Дж $\\approx '+q2.toFixed(0)+'$ кДж
'
+ + '$Q_3 = c_{воды}\\,m \\cdot 100 = 4200 \\cdot '+m.toFixed(1)+' \\cdot 100 = '+Q3.toFixed(0)+'$ Дж $\\approx '+q3.toFixed(0)+'$ кДж
'
+ + '$Q_4 = r\\,m = '+R_VAP+' \\cdot '+m.toFixed(1)+' = '+Q4.toFixed(0)+'$ Дж $\\approx '+q4.toFixed(0)+'$ кДж
'
+ + 'Итого: $Q_{общ} = Q_1+Q_2+Q_3+Q_4 \\approx '+totalMJ.toFixed(2)+'$ МДж
';
+ renderMath(info);
+
+ seen.add(Math.round(m*10));
+ if(!_done && seen.size >= 4){ _done = true; addXp(10,'p13-iv2'); bumpProgress('p13', 15); }
+ }
+ mIn.addEventListener('input', render);
+ render();
+ })();
+
+ /* IV3 — DnD сортер: тип процесса */
+ (function(){
+ const items = [
+ { id:'b1', cat:'heat', html:'Нагрев кастрюли с водой на плите' },
+ { id:'b2', cat:'melt', html:'Тает лёд в стакане чая' },
+ { id:'b3', cat:'evap', html:'Кипит чайник на огне' },
+ { id:'b4', cat:'burn', html:'Сжигание бензина в двигателе' },
+ { id:'b5', cat:'heat', html:'Чашка кофе постепенно остывает' },
+ { id:'b6', cat:'melt', html:'Замерзает вода в формочке' },
+ ];
+ const sorter = setupSorter({
+ poolId:'p13-iv3-pool',
+ scopeSelector:'#p13-iv3',
+ items: items,
+ cats:['heat','melt','evap','burn'],
+ columnLayout:false,
+ });
+ document.getElementById('p13-iv3-check').addEventListener('click', () => {
+ const fb = document.getElementById('p13-iv3-fb');
+ const placedCount = items.filter(it => sorter.placed[it.id]).length;
+ const correct = items.filter(it => sorter.placed[it.id] === it.cat).length;
+ if(placedCount < items.length){ feedback(fb, false, '✗ Размести все 6 явлений.'); return; }
+ if(correct === items.length){ feedback(fb, true, '✓ Все 6 верно! +10 XP'); addXp(10,'p13-iv3'); bumpProgress('p13', 15); }
+ else feedback(fb, false, '✗ Правильно ' + correct + ' из 6. Попробуй ещё.');
+ });
+ document.getElementById('p13-iv3-reset').addEventListener('click', () => { sorter.reset(); document.getElementById('p13-iv3-fb').style.display = 'none'; });
+ })();
+
+ /* IV4 — Тренажёр теплоты */
+ (function(){
+ const Q = [
+ { q:'Нагреть 2 кг воды от 20°C до 80°C. $Q$ в кДж?', ans:504, tol:10, hint:'$Q = c m \\Delta T = 4200 \\cdot 2 \\cdot 60 = 504000$ Дж = 504 кДж' },
+ { q:'Растопить 0{,}5 кг льда при 0°C. $Q$ в кДж?', ans:165, tol:5, hint:'$Q = \\lambda m = 330000 \\cdot 0{,}5 = 165$ кДж' },
+ { q:'Испарить 1 кг воды при 100°C. $Q$ в кДж?', ans:2260, tol:50, hint:'$Q = r m = 2{,}26 \\cdot 10^6 \\cdot 1 = 2260$ кДж' },
+ { q:'Сжечь 0{,}5 кг бензина ($q = 4{,}4 \\cdot 10^7$ Дж/кг). $Q$ в МДж?', ans:22, tol:1, hint:'$Q = q m = 4{,}4 \\cdot 10^7 \\cdot 0{,}5 = 2{,}2 \\cdot 10^7$ Дж = 22 МДж' },
+ { q:'В калориметр налили 100 г воды при 20°C и опустили 200 г меди при 100°C ($c_{Cu} = 390$). Конечная $T$ в °C?', ans:33, tol:1.5, hint:'$4200 \\cdot 0{,}1 \\cdot (T-20) = 390 \\cdot 0{,}2 \\cdot (100-T)$ → $T \\approx 32{,}5$°C' },
+ { q:'Нагреть 1 кг алюминия ($c = 920$) от 20°C до 100°C. $Q$ в кДж?', ans:73.6, tol:2, hint:'$Q = 920 \\cdot 1 \\cdot 80 = 73600$ Дж = 73{,}6 кДж' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ if(i >= Q.length){
+ document.getElementById('p13-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ if(score === Q.length){ addXp(15, 'p13-iv4'); bumpProgress('p13', 25); }
+ else if(score >= 4){ addXp(8, 'p13-iv4'); bumpProgress('p13', 15); }
+ return;
+ }
+ document.getElementById('p13-iv4-i').textContent = (i+1);
+ document.getElementById('p13-iv4-s').textContent = score;
+ document.getElementById('p13-iv4-q').innerHTML = Q[i].q;
+ document.getElementById('p13-iv4-ans').value = '';
+ renderMath(document.getElementById('p13-iv4-q'));
+ document.getElementById('p13-iv4-fb').style.display = 'none';
+ }
+ function go(){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p13-iv4-fb');
+ const raw = document.getElementById('p13-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('p13-iv4-s').textContent = score;
+ i++;
+ setTimeout(show, 1800);
+ }
+ document.getElementById('p13-iv4-go').addEventListener('click', go);
+ document.getElementById('p13-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
+ document.getElementById('p13-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
wireReadBtn('p13');
}
function build_p14(){
const box = document.getElementById('p14-body');
let html = '';
- html += makeCard('theory', "Первый закон термодинамики", "§14", `
- Первый закон термодинамики — этот параграф в разработке (Phase 1+).
- Здесь появятся: теория, формулы, разобранные примеры и 3–4 интерактива в стиле «алгебры 11» — таблицы, симуляции, ползунки, drag-and-drop и автопроверяемые тренажёры.
-
- Phase 0: создан скелет учебника. Phase 2+: наполнение этого § содержанием по учебнику «Физика 10» (Беларусь, 2019).
-
+
+ /* THEORY 1 — Формулировка первого закона ТД */
+ html += makeCard('theory', "Формулировка первого закона термодинамики", "§14", `
+ Первый закон термодинамики — закон сохранения энергии для термодинамической системы:
+ $$\\Delta U = Q + A_{внеш}$$
+
+ $\\Delta U$ — изменение внутренней энергии системы;
+ $Q$ — количество теплоты, переданное системе ($Q > 0$, если получено);
+ $A_{внеш}$ — работа внешних сил над системой.
+
+ Через работу газа (учитывая $A_{внеш} = -A_{газ}$):
+ $$Q = \\Delta U + A_{газ}$$
+ Словами: теплота, полученная газом, расходуется на изменение его внутренней энергии и на совершение работы газом.
+ Правила знаков:
+
+ Величина $> 0$ $< 0$
+
+ $Q$ газ получает газ отдаёт
+ $A_{газ}$ расширение сжатие
+ $\\Delta U$ $T$ растёт $T$ падает
+
+
`);
+
+ /* THEORY 2 — Применение к изопроцессам */
+ html += makeCard('rule', "Применение к изопроцессам", "§14", `
+ Первый закон $Q = \\Delta U + A_{газ}$ принимает простой вид для каждого изопроцесса.
+ 1) Изотермический ($T = \\text{const}$, для идеального газа $\\Delta U = 0$):
+ $$Q = A_{газ}$$
+ Вся подведённая теплота превращается в работу газа.
+ 2) Изохорный ($V = \\text{const}$, $A_{газ} = 0$):
+ $$Q = \\Delta U = \\dfrac{3}{2}\\,\\nu R\\,\\Delta T$$
+ Вся теплота идёт на увеличение внутренней энергии.
+ 3) Изобарный ($p = \\text{const}$):
+ $$Q = \\Delta U + p\\,\\Delta V$$
+ Часть теплоты — на $\\Delta U$, часть — на работу.
+ 4) Адиабатный ($Q = 0$, нет теплообмена):
+ $$\\Delta U = -A_{газ}$$
+ Работа совершается за счёт внутренней энергии: расширение → охлаждение, сжатие → нагрев.
+ `);
+
+ /* THEORY 3 — Адиабатный процесс и примеры */
+ html += makeCard('example', "Адиабатный процесс и примеры", "§14", `
+ Адиабатный процесс — без теплообмена ($Q = 0$). Реализуется:
+
+ в теплоизолированных сосудах;
+ при быстрых процессах — теплообмен не успевает произойти.
+
+ Примеры:
+
+ Дизельный двигатель. Быстрое сжатие воздуха разогревает его до $\\sim 700°$C — этого достаточно для самовоспламенения солярки (без свечи зажигания).
+ Образование облаков. Тёплый влажный воздух поднимается, адиабатно расширяется, охлаждается — водяной пар конденсируется в капли.
+ Холодильник. Рабочее тело расширяется через дроссель — охлаждается; затем сжимается компрессором — нагревается.
+ Велонасос. При быстром сжатии воздух заметно нагревается — это адиабатный процесс.
+
+ Уравнение Пуассона для адиабаты: $pV^{\\gamma} = \\text{const}$, где $\\gamma = c_p/c_v$ — показатель адиабаты. Для одноатомного газа $\\gamma = 5/3$, для двухатомного $\\gamma = 7/5$.
+ `);
+
+ /* INTERACTIVE 1 — Первый закон в действии (бар-чарт по 4 процессам) */
+ html += ``;
+
+ /* INTERACTIVE 2 — Калькулятор первого закона */
+ html += `
+
+
Введи две величины — получи третью по формуле $Q = \\Delta U + A_{газ}$.
+
+ Найти $\\Delta U$
+ Найти $Q$
+ Найти $A_{газ}$
+
+
+
Вычислить
+
+
+
`;
+
+ /* INTERACTIVE 3 — Что неизменно? (квикфайр) */
+ html += `
+
+
6 ситуаций. Выбери постоянную величину.
+
Задание 1 / 6 Очки: 0 / 6
+
+
+ $T = \\text{const}$
+ $V = \\text{const}$
+ $p = \\text{const}$
+ $Q = 0$
+
+
+
`;
+
+ /* INTERACTIVE 4 — Тренажёр первого закона */
+ html += `
+
+
5 задач. $R = 8{,}3$ Дж/(моль·К). Допуск $\\pm 5\\%$.
+
Задача 1 / 5 Очки: 0 / 5
+
+
+ ответ =
+
+ Проверить
+ Заново
+
+
+
`;
+
html += secNav('p13', 'p15');
html += readButton('p14');
+
box.innerHTML = html;
renderMath(box);
+
+ /* IV1 — Первый закон в действии: бар-чарт */
+ (function(){
+ const R = 8.314;
+ const slBox = document.getElementById('p14-iv1-sliders');
+ const svg = document.getElementById('p14-iv1-svg');
+ const info = document.getElementById('p14-iv1-info');
+ const COL = { iso:'#ea580c', hor:'#10b981', bar:'#2563eb', adi:'#7c3aed' };
+ const seen = new Set(); let _done = false;
+
+ function getMode(){ const r = document.querySelector('input[name="p14-iv1-proc"]:checked'); return r ? r.value : 'iso'; }
+
+ function buildSliders(){
+ const m = getMode();
+ let h = '';
+ if(m === 'iso'){
+ h += '$T$: 300 К ';
+ h += 'Отношение $V_2/V_1$: 2.0 ';
+ } else if(m === 'hor'){
+ h += '$\\Delta T$: +50 К ';
+ } else if(m === 'bar'){
+ h += '$\\Delta T$: +50 К ';
+ } else {
+ h += '$A_{газ}$: +400 Дж ';
+ }
+ slBox.innerHTML = h;
+ renderMath(slBox);
+ slBox.querySelectorAll('input[type=range]').forEach(i => i.addEventListener('input', render));
+ }
+
+ function drawBars(Q, dU, A, mode){
+ const W=420, H=240, pad=44;
+ const innerW = W - 2*pad, innerH = H - 2*pad;
+ const maxAbs = Math.max(Math.abs(Q), Math.abs(dU), Math.abs(A), 100);
+ const ySc = innerH / (2 * maxAbs * 1.15);
+ const y0 = H/2; // ось 0
+ const barW = innerW / 4;
+ const labels = ['Q', 'ΔU', 'A_{газ}'];
+ const vals = [Q, dU, A];
+ const cols = [COL[mode], '#0ea5e9', '#f59e0b'];
+ let g = '';
+ // фон
+ g += ' ';
+ // ось 0
+ g += ' ';
+ g += '0 ';
+ // подсказки уровней
+ for(const lv of [-maxAbs, -maxAbs/2, maxAbs/2, maxAbs]){
+ const y = y0 - lv * ySc;
+ if(y > pad && y < H - pad){
+ g += ' ';
+ g += ''+lv.toFixed(0)+' ';
+ }
+ }
+ // бары
+ vals.forEach((v, i) => {
+ const cx = pad + innerW * (i+0.5) / 3;
+ const bx = cx - barW/2;
+ const h = Math.abs(v) * ySc;
+ const by = v >= 0 ? y0 - h : y0;
+ g += ' ';
+ g += ''+labels[i]+' ';
+ const labY = v >= 0 ? by - 6 : by + h + 14;
+ g += ''+v.toFixed(0)+' Дж ';
+ });
+ svg.innerHTML = g;
+ }
+
+ function render(){
+ const m = getMode();
+ let Q = 0, dU = 0, A = 0, descr = '', formula = '';
+ const NU = 1;
+ if(m === 'iso'){
+ const T = +document.getElementById('p14-iv1-t').value;
+ const r = +document.getElementById('p14-iv1-r').value;
+ document.getElementById('p14-iv1-tL').textContent = T;
+ document.getElementById('p14-iv1-rL').textContent = r.toFixed(1);
+ dU = 0;
+ A = NU * R * T * Math.log(r);
+ Q = A;
+ descr = 'Изотермический процесс: $T = \\text{const}$, $\\Delta U = 0$.';
+ formula = '$Q = A_{газ} = \\nu RT\\ln(V_2/V_1) = '+A.toFixed(0)+'$ Дж';
+ } else if(m === 'hor'){
+ const dT = +document.getElementById('p14-iv1-dt').value;
+ document.getElementById('p14-iv1-dtL').textContent = (dT >= 0 ? '+' : '') + dT;
+ A = 0;
+ dU = 1.5 * NU * R * dT;
+ Q = dU;
+ descr = 'Изохорный процесс: $V = \\text{const}$, $A_{газ} = 0$.';
+ formula = '$Q = \\Delta U = \\tfrac{3}{2}\\nu R \\Delta T = '+dU.toFixed(0)+'$ Дж';
+ } else if(m === 'bar'){
+ const dT = +document.getElementById('p14-iv1-dt').value;
+ document.getElementById('p14-iv1-dtL').textContent = (dT >= 0 ? '+' : '') + dT;
+ dU = 1.5 * NU * R * dT;
+ A = NU * R * dT; // p ΔV = νR ΔT
+ Q = dU + A;
+ descr = 'Изобарный процесс: $p = \\text{const}$. Часть теплоты — на $\\Delta U$, часть — на работу.';
+ formula = '$Q = \\Delta U + p\\Delta V = '+dU.toFixed(0)+' + '+A.toFixed(0)+' = '+Q.toFixed(0)+'$ Дж';
+ } else {
+ const av = +document.getElementById('p14-iv1-a').value;
+ document.getElementById('p14-iv1-aL').textContent = (av >= 0 ? '+' : '') + av;
+ Q = 0;
+ A = av;
+ dU = -A;
+ descr = 'Адиабатный процесс: $Q = 0$, $\\Delta U = -A_{газ}$.';
+ formula = '$\\Delta U = -A_{газ} = '+dU.toFixed(0)+'$ Дж'+(A > 0 ? ' (расширение → охлаждение)' : (A < 0 ? ' (сжатие → нагрев)' : ''));
+ }
+ drawBars(Q, dU, A, m);
+ info.innerHTML = ''+descr+'
'
+ + ''+formula+'
'
+ + 'Проверка $Q = \\Delta U + A_{газ}$: '+Q.toFixed(0)+' = '+dU.toFixed(0)+' + '+A.toFixed(0)+' ✓
';
+ renderMath(info);
+ seen.add(m);
+ if(!_done && seen.size === 4){ _done = true; addXp(10,'p14-iv1'); bumpProgress('p14', 15); }
+ }
+ document.querySelectorAll('input[name="p14-iv1-proc"]').forEach(r => r.addEventListener('change', () => { buildSliders(); render(); }));
+ buildSliders();
+ render();
+ })();
+
+ /* IV2 — Калькулятор первого закона */
+ (function(){
+ const tabs = document.getElementById('p14-iv2-tabs');
+ const inpsBox = document.getElementById('p14-iv2-inputs');
+ const out = document.getElementById('p14-iv2-out');
+ const fb = document.getElementById('p14-iv2-fb');
+ const used = new Set(); let _done = false;
+ let mode = 'dU';
+
+ function field(id, label, val){
+ return ''+label+' ';
+ }
+ function build(){
+ let h = '';
+ if(mode === 'dU'){
+ h += field('p14-iv2-Q','$Q$, Дж','500');
+ h += field('p14-iv2-A','$A_{газ}$, Дж','300');
+ } else if(mode === 'Q'){
+ h += field('p14-iv2-dU','$\\Delta U$, Дж','400');
+ h += field('p14-iv2-A','$A_{газ}$, Дж','300');
+ } else {
+ h += field('p14-iv2-Q','$Q$, Дж','500');
+ h += field('p14-iv2-dU','$\\Delta U$, Дж','200');
+ }
+ 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 = '', val = 0;
+ if(mode === 'dU'){
+ const Q = num('p14-iv2-Q'), A = num('p14-iv2-A');
+ if(![Q,A].every(isFinite)){ feedback(fb,false,'✗ Введи оба числа.'); return; }
+ val = Q - A;
+ res = '$\\Delta U = Q - A_{газ} = '+Q+' - ('+A+') = '+val.toFixed(0)+'$ Дж';
+ } else if(mode === 'Q'){
+ const dU = num('p14-iv2-dU'), A = num('p14-iv2-A');
+ if(![dU,A].every(isFinite)){ feedback(fb,false,'✗ Введи оба числа.'); return; }
+ val = dU + A;
+ res = '$Q = \\Delta U + A_{газ} = '+dU+' + ('+A+') = '+val.toFixed(0)+'$ Дж';
+ } else {
+ const Q = num('p14-iv2-Q'), dU = num('p14-iv2-dU');
+ if(![Q,dU].every(isFinite)){ feedback(fb,false,'✗ Введи оба числа.'); return; }
+ val = Q - dU;
+ res = '$A_{газ} = Q - \\Delta U = '+Q+' - ('+dU+') = '+val.toFixed(0)+'$ Дж';
+ }
+ const labels = { dU:'\\Delta U', Q:'Q', A:'A_{газ}' };
+ out.innerHTML = ''+res+'
'
+ + 'Ответ: $'+labels[mode]+' = '+val.toFixed(0)+'$ Дж
';
+ renderMath(out);
+ feedback(fb, true, '✓ Вычислено.');
+ used.add(mode);
+ if(!_done && used.size === 3){ _done = true; addXp(10,'p14-iv2'); bumpProgress('p14', 15); }
+ }
+ tabs.querySelectorAll('button').forEach(b => {
+ b.addEventListener('click', () => {
+ mode = b.dataset.find;
+ tabs.querySelectorAll('button').forEach(x => { x.className = 'btn'; });
+ b.className = 'btn primary';
+ build();
+ });
+ });
+ document.getElementById('p14-iv2-go').addEventListener('click', calc);
+ build();
+ })();
+
+ /* IV3 — Что неизменно? */
+ (function(){
+ const Q = [
+ { q:'Изотермический процесс — что постоянно?', ans:'T' },
+ { q:'Изохорный процесс — что постоянно?', ans:'V' },
+ { q:'Изобарный процесс — что постоянно?', ans:'p' },
+ { q:'Адиабатный процесс — какая величина равна нулю?', ans:'Q' },
+ { q:'Вода кипит при $T = 100°$C — какой параметр постоянен?', ans:'T' },
+ { q:'Газ в герметичном баллоне греют. Что неизменно?', ans:'V' },
+ ];
+ let i = 0, score = 0; let _done = false;
+ const box = document.getElementById('p14-iv3');
+ function show(){
+ const qEl = document.getElementById('p14-iv3-q');
+ const fb = document.getElementById('p14-iv3-fb');
+ if(i >= Q.length){
+ qEl.innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ renderMath(qEl);
+ if(!_done){
+ _done = true;
+ if(score === Q.length){ addXp(15,'p14-iv3'); bumpProgress('p14', 25); }
+ else if(score >= 4){ addXp(8,'p14-iv3'); bumpProgress('p14', 15); }
+ }
+ return;
+ }
+ document.getElementById('p14-iv3-i').textContent = (i+1);
+ document.getElementById('p14-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('p14-iv3-fb');
+ const ans = b.dataset.ans;
+ if(ans === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! Дальше ▶'); }
+ else {
+ const labels = {T:'$T = \\text{const}$', V:'$V = \\text{const}$', p:'$p = \\text{const}$', Q:'$Q = 0$'};
+ feedback(fb, false, '✗ Неверно. Правильно: '+labels[Q[i].ans]+'. Дальше ▶');
+ }
+ document.getElementById('p14-iv3-s').textContent = score;
+ i++;
+ setTimeout(show, 1500);
+ });
+ });
+ show();
+ })();
+
+ /* IV4 — Тренажёр первого закона */
+ (function(){
+ const Q = [
+ { q:'Газ получил $Q = 500$ Дж тепла и совершил работу $A_{газ} = 300$ Дж. Найди $\\Delta U$ в Дж.', ans:200, tol:5, hint:'$\\Delta U = Q - A = 500 - 300 = 200$' },
+ { q:'Изохорно нагрели 1 моль газа на $\\Delta T = 50$ К. $\\Delta U$ в Дж?', ans:622, tol:30, hint:'$\\Delta U = \\tfrac{3}{2}\\nu R\\Delta T = 1{,}5 \\cdot 1 \\cdot 8{,}3 \\cdot 50 \\approx 622$' },
+ { q:'Изотермически 1 моль газа при $T = 300$ К расширили вдвое ($V_2 = 2V_1$). $Q$ в Дж?', ans:1726, tol:50, hint:'$Q = A = \\nu RT\\ln 2 = 8{,}3 \\cdot 300 \\cdot 0{,}693 \\approx 1726$' },
+ { q:'В адиабатном процессе газ совершил $A_{газ} = 400$ Дж. $\\Delta U$ в Дж (со знаком)?', ans:-400, tol:5, hint:'$Q = 0 \\Rightarrow \\Delta U = -A = -400$' },
+ { q:'Газ изобарно расширился, при этом $\\Delta U = 600$ Дж, $A_{газ} = 400$ Дж. $Q$ в Дж?', ans:1000, tol:20, hint:'$Q = \\Delta U + A = 600 + 400 = 1000$' },
+ ];
+ let i = 0, score = 0;
+ function show(){
+ if(i >= Q.length){
+ document.getElementById('p14-iv4-q').innerHTML = 'Готово! Результат: ' + score + ' / ' + Q.length;
+ if(score === Q.length){ addXp(15, 'p14-iv4'); bumpProgress('p14', 25); }
+ else if(score >= 3){ addXp(8, 'p14-iv4'); bumpProgress('p14', 15); }
+ return;
+ }
+ document.getElementById('p14-iv4-i').textContent = (i+1);
+ document.getElementById('p14-iv4-s').textContent = score;
+ document.getElementById('p14-iv4-q').innerHTML = Q[i].q;
+ document.getElementById('p14-iv4-ans').value = '';
+ renderMath(document.getElementById('p14-iv4-q'));
+ document.getElementById('p14-iv4-fb').style.display = 'none';
+ }
+ function go(){
+ if(i >= Q.length) return;
+ const fb = document.getElementById('p14-iv4-fb');
+ const raw = document.getElementById('p14-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('p14-iv4-s').textContent = score;
+ i++;
+ setTimeout(show, 1800);
+ }
+ document.getElementById('p14-iv4-go').addEventListener('click', go);
+ document.getElementById('p14-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); });
+ document.getElementById('p14-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); });
+ show();
+ })();
+
wireReadBtn('p14');
}