/* chem8_intro_widgets.js — виджеты вводного раздела «Химия 8».
* Монтируются движком chem8_engine.js: window.CHEM8_WIDGETS[id] / window.FLAG_MOUNTS[id].
* Используют window.Chem8 (chem8_svg.js): molarMass, elementCounts, arOf, fmt,
* moleTriangle, equationBalancer.
*/
(function (W) {
'use strict';
function C() { return W.Chem8 || {}; }
function $(id) { return document.getElementById(id); }
function rr(v, d) { var p = Math.pow(10, d == null ? 3 : d); return (Math.round(v * p) / p).toString().replace('.', ','); }
/* §1 — карта элементов */
var EL = {
H: [1, 'Водород'], He: [2, 'Гелий'], Li: [3, 'Литий'], Be: [4, 'Бериллий'], B: [5, 'Бор'], C: [6, 'Углерод'],
N: [7, 'Азот'], O: [8, 'Кислород'], F: [9, 'Фтор'], Ne: [10, 'Неон'], Na: [11, 'Натрий'], Mg: [12, 'Магний'],
Al: [13, 'Алюминий'], Si: [14, 'Кремний'], P: [15, 'Фосфор'], S: [16, 'Сера'], Cl: [17, 'Хлор'], Ar: [18, 'Аргон'],
K: [19, 'Калий'], Ca: [20, 'Кальций'], Fe: [26, 'Железо'], Cu: [29, 'Медь'], Zn: [30, 'Цинк'], Ag: [47, 'Серебро'], Ba: [56, 'Барий']
};
function mount_p1() {
var grid = $('p1-el'), info = $('p1-elinfo'); if (!grid || grid._built) return; grid._built = 1;
Object.keys(EL).forEach(function (s) {
var ar = C().arOf ? C().arOf(s) : '';
var c = document.createElement('div'); c.className = 'el-cell';
c.innerHTML = '' + EL[s][0] + '' + s + '' + ar + '';
c.addEventListener('click', function () {
grid.querySelectorAll('.el-cell').forEach(function (x) { x.classList.remove('on'); }); c.classList.add('on');
info.innerHTML = '' + EL[s][1] + ' (' + s + ') · порядковый номер Z = ' + EL[s][0] + ' · A_r = ' + ar;
});
grid.appendChild(c);
});
}
/* §2 — калькулятор Mr */
function mount_p2() {
var inp = $('p2-mr-in'), out = $('p2-mr-out'), go = $('p2-mr-go'); if (!inp || inp._built) return; inp._built = 1;
function calc() {
var f = inp.value.trim(), cnt = C().elementCounts ? C().elementCounts(f) : null, mr = C().molarMass ? C().molarMass(f) : NaN;
if (!cnt || isNaN(mr)) { out.className = 'out bad'; out.textContent = 'Не удалось разобрать формулу. Проверьте символы элементов.'; return; }
out.className = 'out ok';
out.innerHTML = 'M_r(' + f + ') = ' + C().fmt(mr) + '
' +
Object.keys(cnt).map(function (e) { return e + ': A_r=' + (C().arOf ? C().arOf(e) : '?') + ' × ' + cnt[e]; }).join(' | ') +
'
Σ = ' + Object.keys(cnt).map(function (e) { return (C().arOf ? C().arOf(e) : '?') + '·' + cnt[e]; }).join(' + ') + ' = ' + C().fmt(mr) + '';
}
go.addEventListener('click', calc);
inp.addEventListener('keydown', function (e) { if (e.key === 'Enter') calc(); });
document.querySelectorAll('.p2-ex').forEach(function (b) { b.addEventListener('click', function () { inp.value = b.dataset.f; calc(); }); });
calc();
}
/* §3 — порция вещества */
function mount_p3() {
var sub = $('p3-sub'), rng = $('p3-n'), nv = $('p3-nv'), out = $('p3-out'); if (!sub || sub._built) return; sub._built = 1;
var M = { H2O: 18, O2: 32, CO2: 44, NaCl: 58.5 };
function upd() {
var n = parseFloat(rng.value), s = sub.value, m = n * M[s], N = n * 6.02;
nv.textContent = n.toFixed(1).replace('.', ',');
out.innerHTML = 'n = ' + n.toFixed(1).replace('.', ',') + ' моль
m = n·M = ' + n.toFixed(1).replace('.', ',') + ' · ' + String(M[s]).replace('.', ',') + ' = ' + rr(m, 1) + ' г
N = n·N_A = ' + rr(N, 2) + '·10²³ частиц';
}
sub.addEventListener('change', upd); rng.addEventListener('input', upd); upd();
}
/* §4 — счётчик частиц */
function mount_p4() {
var rng = $('p4-n'), nv = $('p4-nv'), out = $('p4-out'); if (!rng || rng._built) return; rng._built = 1;
function upd() { var n = parseFloat(rng.value), N = n * 6.02; nv.textContent = n.toFixed(2).replace('.', ',');
out.innerHTML = 'N = n · N_A = ' + n.toFixed(2).replace('.', ',') + ' · 6,02·10²³ = ' + rr(N, 2) + '·10²³ частиц'; }
rng.addEventListener('input', upd); upd();
}
/* §5 — M + объём газа */
function mount_p5() {
var inp = $('p5-in'), out = $('p5-out'), go = $('p5-go'); if (!inp || inp._built) return; inp._built = 1;
function calc() {
var f = inp.value.trim(), mr = C().molarMass ? C().molarMass(f) : NaN;
if (isNaN(mr)) { out.className = 'out bad'; out.textContent = 'Не удалось разобрать формулу.'; return; }
out.className = 'out ok';
out.innerHTML = 'M(' + f + ') = ' + C().fmt(mr) + ' г/моль
1 моль газа при н.у. → 22,4 л
Плотность газа ≈ M/22,4 = ' + rr(mr / 22.4) + ' г/л';
}
go.addEventListener('click', calc); inp.addEventListener('keydown', function (e) { if (e.key === 'Enter') calc(); }); calc();
}
/* §6 / ПР1 — треугольник n–m–M (флагман) */
function mount_triangle(mountId, subId) {
var mount = $(mountId), sub = $(subId); if (!mount || mount._built || !C().moleTriangle) return; mount._built = 1;
var api = C().moleTriangle(mount, {});
if (sub) sub.addEventListener('change', function () {
var f = sub.value; if (!f) return; var m = C().molarMass(f);
if (!isNaN(m) && api && api.set) api.set('M', m);
});
}
function mount_p6() { mount_triangle('p6-mount', 'p6-sub'); }
function mount_pr1() { mount_triangle('pr1-mount', 'pr1-sub'); }
/* §7 — универсальный калькулятор газа (флагман) */
function mount_p7() {
var sub = $('p7-sub'), key = $('p7-key'), val = $('p7-val'), go = $('p7-go'), out = $('p7-out'); if (!sub || sub._built) return; sub._built = 1;
var Vm = 22.4, NA = 6.02;
function calc() {
var f = sub.value, M = C().molarMass(f), k = key.value, x = parseFloat((val.value || '').replace(',', '.'));
if (isNaN(x)) { out.className = 'out bad'; out.textContent = 'Введите число.'; return; }
var n; if (k === 'n') n = x; else if (k === 'm') n = x / M; else if (k === 'V') n = x / Vm; else n = x / NA;
var m = n * M, V = n * Vm, N = n * NA;
out.className = 'out ok';
out.innerHTML = 'M(' + f + ')=' + M + ' г/моль
n = ' + rr(n) + ' моль
m = ' + rr(m) + ' г
V(н.у.) = ' + rr(V) + ' л
N = ' + rr(N) + '·10²³ частиц';
}
go.addEventListener('click', calc); val.addEventListener('keydown', function (e) { if (e.key === 'Enter') calc(); }); calc();
}
/* §8 — балансировщик (флагман) */
function mount_p8() {
var pick = $('p8-pick'), mount = $('p8-mount'); if (!pick || pick._built || !C().equationBalancer) return; pick._built = 1;
function build() { var parts = pick.value.split('|'); C().equationBalancer(mount, { skeleton: parts[0], solution: parts[1].split(',').map(Number) }); }
pick.addEventListener('change', build); build();
}
/* §9 — пошаговый решатель (флагман) */
var ST = [
{ eq: '2H₂ + O₂ → 2H₂O', given: 'Дано: m(H₂) = 4 г. Найти m(H₂O).',
steps: ['M(H₂)=2 г/моль, M(H₂O)=18 г/моль.', 'n(H₂) = m/M = 4/2 = 2 моль.', 'По уравнению n(H₂):n(H₂O) = 2:2 = 1:1 → n(H₂O)=2 моль.', 'm(H₂O) = n·M = 2·18 = 36 г. Ответ: 36 г.'] },
{ eq: 'CaCO₃ → CaO + CO₂↑', given: 'Дано: m(CaCO₃) = 100 г. Найти V(CO₂) при н.у.',
steps: ['M(CaCO₃)=100 г/моль.', 'n(CaCO₃) = 100/100 = 1 моль.', 'n(CaCO₃):n(CO₂) = 1:1 → n(CO₂)=1 моль.', 'V(CO₂) = n·Vm = 1·22,4 = 22,4 л. Ответ: 22,4 л.'] },
{ eq: 'Zn + 2HCl → ZnCl₂ + H₂↑', given: 'Дано: n(Zn) = 0,5 моль. Найти V(H₂) при н.у.',
steps: ['n(Zn):n(H₂) = 1:1 → n(H₂)=0,5 моль.', 'V(H₂) = n·Vm = 0,5·22,4 = 11,2 л. Ответ: 11,2 л.'] }
];
function mount_p9() {
var pick = $('p9-pick'), out = $('p9-out'), bStep = $('p9-step'), bAll = $('p9-all'); if (!pick || pick._built) return; pick._built = 1;
ST.forEach(function (p, i) { var o = document.createElement('option'); o.value = i; o.textContent = p.eq; pick.appendChild(o); });
var cur = 0, shown = 0;
function render() {
var p = ST[cur];
var html = '' + p.eq + '
' + p.given + '