Files
Learn_System/frontend/js/phys7_ch1_widgets.js
T
Maxim Dolgolyov 83aad34e8b feat(phys7 ch1): Phase 1 Wave 2 — §3, §4, §5
WIDGETS (+347 строк к phys7_ch1_widgets.js, теперь 749 строк, экспорт p1..p5):

§3 «Методы исследования в физике»:
- 3 карточки (3 метода / отличия / опыт Галилея на Пизанской башне)
- IV-1 СИМ: timeline-список 5 исторических опытов (Архимед→Галилей→Торричелли→Паскаль→Ньютон) с раскрывающимися деталями
- IV-2 КВИЗ: 4 вопроса «опыт vs наблюдение vs гипотеза vs теория»
- IV-3 DnD: 8 ситуаций по 3 корзинам (наблюдение / эксперимент / гипотеза)
- IV-4 ТРН: 5 вопросов закрепления

§4 «Прямые и косвенные измерения» (S=ab, V=abc, rho=m/V):
- 3 карточки (типы измерений / основные формулы / объём картофеля по вытеснению)
- IV-1 СИМ: палитра 6 приборов (линейка/весы/термометр/секундомер/мензурка/динамометр) с единицами
- IV-2 КАЛЬК (главный визуал §4): 4 slider'а a, b, c (см) и m (г) →
  пересчёт S, V, плотности с угадыванием вещества (дерево / алюминий / железо / свинец / золото)
- IV-3 DnD: 8 примеров измерений → прямое / косвенное
- IV-4 ТРН: 5 расчётных задач (площадь, объём кирпича, плотность, скорость, вытеснение)

§5 «Единицы измерения. СИ»:
- 3 карточки (зачем СИ / 7 основных единиц в таблице / приставки от нано до гига)
- IV-1 СИМ: 7 цветных карт основных единиц СИ
- IV-2 КАЛЬК конвертер: число × приставка (Г/М/к/—/с/м/мк/н) × единица (м/г/с/Вт/Гц/Н)
  → результат с автоформатированием (экспоненциальная запись для больших/малых)
- IV-3 DnD: 8 величин → 5 основных единиц СИ
- IV-4 ТРН: 5 задач на перевод (км→м, кг→г, ч→с, мс→с, см²→м²)

Pre-commit, parse-check, KaTeX-аудит (одиночные backslash =0), smoke-test (экспорт=5) пройдены.
2026-05-30 10:47:15 +03:00

750 lines
59 KiB
JavaScript
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.
// Физика 7 · Глава 1 · виджеты §§1–7 (Wave 1: §1, §2).
// Экспорт: window.PHYS7_CH1_WIDGETS = { p1: fn, p2: fn, ... }.
// Каждая функция вставляет в pN-body: 3 теоретические карточки + 4 виджета + кнопку «Прочитал».
(function(){
'use strict';
/* === Общие хелперы (вдохновлено phys9_ch1_widgets.js, но независимо) === */
function renderMath(root){
if(window.renderMathInElement){
try{
window.renderMathInElement(root, {
delimiters: [{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false}],
throwOnError: false
});
}catch(e){}
}
}
function makeCard(kind, title, badge, body){
// kind: 'theory' | 'rule' | 'example'
const colorByKind = { theory:'#0284c7', rule:'#dc2626', example:'#10b981' };
const labelByKind = { theory:'Теория', rule:'Правило', example:'Пример' };
const c = colorByKind[kind] || '#0284c7';
return '<div class="th-card" style="background:#fff;border:1.5px solid #e0f2fe;border-left:5px solid ' + c + ';border-radius:11px;padding:14px 16px;margin-bottom:14px;box-shadow:0 2px 8px rgba(0,0,0,.05)">'
+ '<div style="display:flex;align-items:center;gap:10px;margin-bottom:8px;flex-wrap:wrap">'
+ '<span style="background:' + c + ';color:#fff;padding:3px 10px;border-radius:99px;font-size:.7rem;font-weight:800;text-transform:uppercase;letter-spacing:.05em">' + labelByKind[kind] + '</span>'
+ '<span style="font-size:.72rem;font-weight:700;color:#64748b;letter-spacing:.04em">' + (badge||'') + '</span>'
+ '<span style="font-family:Unbounded,sans-serif;font-weight:800;font-size:.96rem;color:#0f172a;flex:1;min-width:0">' + title + '</span>'
+ '</div>'
+ '<div style="font-size:.94rem;line-height:1.6;color:#0f172a">' + body + '</div>'
+ '</div>';
}
function wgWrap(id, badge, title, hint, body){
return '<div class="wg" id="' + id + '" style="background:#fff;border:1.5px solid #e0f2fe;border-radius:12px;padding:14px 16px;margin-bottom:14px;box-shadow:0 2px 8px rgba(0,0,0,.05)">'
+ '<div style="display:flex;align-items:center;gap:10px;margin-bottom:8px;flex-wrap:wrap">'
+ '<span style="background:#4f46e5;color:#fff;padding:3px 10px;border-radius:99px;font-size:.7rem;font-weight:800;letter-spacing:.05em">' + badge + '</span>'
+ '<span style="font-family:Unbounded,sans-serif;font-weight:800;font-size:.92rem;color:#0f172a">' + title + '</span>'
+ '</div>'
+ (hint ? '<div style="font-size:.84rem;color:#64748b;background:#f0f9ff;border-left:3px solid #0284c7;border-radius:6px;padding:8px 12px;margin-bottom:10px;line-height:1.5">' + hint + '</div>' : '')
+ body
+ '</div>';
}
function readButton(pid){
return '<div style="text-align:center;margin-top:18px"><button class="phys7-read-btn" data-pid="' + pid + '" '
+ 'style="background:linear-gradient(135deg,#10b981,#047857);color:#fff;border:none;padding:11px 22px;border-radius:11px;font-weight:700;font-size:.92rem;cursor:pointer;font-family:inherit;display:inline-flex;align-items:center;gap:8px;box-shadow:0 4px 14px rgba(16,185,129,.32);transition:filter .15s">'
+ '<svg viewBox="0 0 24 24" style="width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round"><polyline points="20 6 9 17 4 12"/></svg>'
+ 'Я прочитал § &nbsp;<span style="opacity:.85;font-size:.86rem">+10 XP</span>'
+ '</button></div>';
}
function wireReadBtn(pid){
const btn = document.querySelector('.phys7-read-btn[data-pid="' + pid + '"]');
if(!btn) return;
const KEY = 'physics7_ch1_read_' + pid;
if(localStorage.getItem(KEY) === '1'){
btn.innerHTML = '<svg viewBox="0 0 24 24" style="width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round"><polyline points="20 6 9 17 4 12"/></svg> Прочитано';
btn.disabled = true;
btn.style.background = '#94a3b8';
btn.style.cursor = 'default';
return;
}
btn.addEventListener('click', function(){
if(localStorage.getItem(KEY) === '1') return;
localStorage.setItem(KEY, '1');
if(typeof window.bumpProgress === 'function') window.bumpProgress(pid, 30);
if(typeof window.addXp === 'function') window.addXp(10, 'read-' + pid);
btn.innerHTML = '<svg viewBox="0 0 24 24" style="width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round"><polyline points="20 6 9 17 4 12"/></svg> Прочитано';
btn.disabled = true;
btn.style.background = '#94a3b8';
btn.style.cursor = 'default';
});
}
/* DnD на 4 корзины — общий движок */
function wireDnd(host, items, cats){
const root = document.getElementById(host);
if(!root) return;
const checkBtn = root.querySelector('.dnd-check');
const fb = root.querySelector('.dnd-fb');
let placed = {}; // itemId -> catKey
let armed = null;
// Pool clicks
root.querySelectorAll('.dnd-chip').forEach(chip => {
chip.addEventListener('click', () => {
if(armed === chip){ armed.classList.remove('armed'); armed = null; return; }
if(armed) armed.classList.remove('armed');
armed = chip;
chip.classList.add('armed');
});
});
// Drop boxes
root.querySelectorAll('.drop-box').forEach(box => {
box.addEventListener('click', () => {
if(!armed) return;
const cat = box.dataset.cat;
const id = armed.dataset.id;
placed[id] = cat;
const inner = box.querySelector('.drop-items');
const clone = armed.cloneNode(true);
clone.classList.remove('armed');
clone.classList.add('placed');
clone.addEventListener('click', e => {
e.stopPropagation();
delete placed[id];
clone.remove();
// Возвращаем в пул
armed = null;
const orig = root.querySelector('.dnd-chip[data-id="' + id + '"]:not(.placed)');
if(orig) orig.style.display = '';
});
inner.appendChild(clone);
armed.style.display = 'none';
armed.classList.remove('armed');
armed = null;
});
});
// Check
if(checkBtn) checkBtn.addEventListener('click', () => {
const total = items.length;
let correct = 0;
items.forEach(it => { if(placed[it.id] === it.cat) correct++; });
const pct = Math.round(correct * 100 / total);
fb.style.display = 'block';
if(correct === total){
fb.style.background = '#d1fae5'; fb.style.color = '#065f46'; fb.style.borderLeft = '4px solid #10b981';
fb.innerHTML = '&#10003; Идеально! Все ' + total + ' карточек на своих местах.';
if(typeof window.bumpProgress === 'function') window.bumpProgress(host.split('-')[0].replace('p','p') === host ? host : null, 0);
if(typeof window.addXp === 'function') window.addXp(15, 'dnd-' + host);
} else {
fb.style.background = '#fee2e2'; fb.style.color = '#7f1d1d'; fb.style.borderLeft = '4px solid #dc2626';
fb.innerHTML = '&#10007; Правильно: ' + correct + '/' + total + ' (' + pct + '%). Попробуй ещё раз.';
}
});
}
function dndPool(host, items, cats){
const chips = items.map(it => '<button class="dnd-chip" data-id="' + it.id + '" type="button" style="background:#fff;border:1.5px solid #bae6fd;border-radius:10px;padding:7px 13px;cursor:pointer;font-size:.9rem;font-family:inherit;transition:all .15s">' + it.html + '</button>').join('');
const boxes = cats.map(c => '<div class="drop-box" data-cat="' + c.cat + '" style="background:#fff;border:1.5px dashed #bae6fd;border-radius:10px;padding:10px;min-height:80px"><h5 style="font-family:Unbounded,sans-serif;font-size:.76rem;color:#0c4a6e;margin-bottom:8px;text-transform:uppercase;letter-spacing:.04em">' + c.label + '</h5><div class="drop-items" style="display:flex;flex-wrap:wrap;gap:6px;min-height:32px"></div></div>').join('');
return '<div id="' + host + '" class="dnd-host">'
+ '<div style="font-size:.86rem;color:#475569;margin-bottom:10px">Нажми на карточку, потом на нужный ящик. Чтобы вернуть карточку — кликни по ней в ящике.</div>'
+ '<div class="dnd-pool" style="display:flex;flex-wrap:wrap;gap:8px;margin-bottom:14px;padding:10px;border:1.5px dashed #bae6fd;border-radius:10px;background:#f0f9ff">' + chips + '</div>'
+ '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:10px;margin-bottom:12px">' + boxes + '</div>'
+ '<div style="display:flex;gap:8px"><button class="dnd-check" type="button" style="background:linear-gradient(135deg,#0284c7,#0c4a6e);color:#fff;border:none;padding:9px 18px;border-radius:9px;font-weight:700;font-size:.86rem;cursor:pointer;font-family:inherit">Проверить</button></div>'
+ '<div class="dnd-fb" style="padding:10px 14px;border-radius:9px;font-weight:600;font-size:.88rem;margin-top:8px;display:none;line-height:1.45"></div>'
+ '</div>';
}
/* Quiz одиночного выбора — карточка вопроса */
function quizQuestion(host, idx, q, opts, correctIdx, explain){
const optsHtml = opts.map((o,i) => '<button class="qz-opt" data-i="' + i + '" type="button" style="background:#fff;border:1.5px solid #bae6fd;border-radius:9px;padding:9px 14px;cursor:pointer;font-size:.92rem;font-family:inherit;text-align:left;transition:all .15s;width:100%;margin-bottom:6px">' + o + '</button>').join('');
return '<div class="qz-q" data-host="' + host + '" data-idx="' + idx + '" style="background:#f0f9ff;border:1.5px solid #bae6fd;border-radius:10px;padding:12px 14px;margin-bottom:10px">'
+ '<div style="font-weight:700;margin-bottom:8px;font-size:.94rem">' + (idx+1) + '. ' + q + '</div>'
+ '<div class="qz-opts" data-correct="' + correctIdx + '" data-explain="' + (explain||'').replace(/"/g,'&quot;') + '">' + optsHtml + '</div>'
+ '<div class="qz-fb" style="padding:9px 12px;border-radius:8px;font-size:.86rem;margin-top:6px;display:none;line-height:1.45"></div>'
+ '</div>';
}
function wireQuiz(host, onAllCorrect){
const root = document.getElementById(host);
if(!root) return;
const all = root.querySelectorAll('.qz-q');
const done = new Set();
all.forEach(qDiv => {
const opts = qDiv.querySelectorAll('.qz-opt');
const correct = +qDiv.querySelector('.qz-opts').dataset.correct;
const explain = qDiv.querySelector('.qz-opts').dataset.explain;
const fb = qDiv.querySelector('.qz-fb');
opts.forEach(o => o.addEventListener('click', () => {
if(done.has(qDiv)) return;
const i = +o.dataset.i;
opts.forEach(x => x.disabled = true);
if(i === correct){
o.style.background = '#d1fae5'; o.style.borderColor = '#10b981'; o.style.color = '#065f46';
fb.style.display = 'block'; fb.style.background = '#d1fae5'; fb.style.color = '#065f46'; fb.style.borderLeft = '4px solid #10b981';
fb.innerHTML = '&#10003; Верно!' + (explain ? ' ' + explain : '');
done.add(qDiv);
if(done.size === all.length && typeof onAllCorrect === 'function') onAllCorrect();
} else {
o.style.background = '#fee2e2'; o.style.borderColor = '#dc2626'; o.style.color = '#7f1d1d';
opts[correct].style.background = '#d1fae5'; opts[correct].style.borderColor = '#10b981'; opts[correct].style.color = '#065f46';
fb.style.display = 'block'; fb.style.background = '#fee2e2'; fb.style.color = '#7f1d1d'; fb.style.borderLeft = '4px solid #dc2626';
fb.innerHTML = '&#10007; Неверно. Правильно: «' + opts[correct].textContent + '».' + (explain ? ' ' + explain : '');
done.add(qDiv);
}
// Renable click-через-кнопки запрещён, но повторное прохождение через reset:
}));
});
}
/* ========================================================== */
/* §1 — Физика — наука о природе. Связь с другими науками */
/* ========================================================== */
function add_p1(){
const body = document.getElementById('p1-body');
if(!body) return;
let h = '';
/* 3 теоретические карточки */
h += makeCard('theory', 'Что изучает физика', '§ 1.1',
'Физика — это <b>наука о природе</b>. Она изучает <b>физические явления</b>: '
+ 'падение тел, движение машин, нагрев и охлаждение, свет, звук, электрический ток, магниты. '
+ 'Слово «физика» произошло от греческого <i>фюзис</i> — «природа».');
h += makeCard('rule', 'Связь с другими науками', '§ 1.2',
'<ul style="padding-left:20px;margin:4px 0">'
+ '<li><b>Астрономия</b> — изучает звёзды и планеты, использует физические законы движения.</li>'
+ '<li><b>Химия</b> — превращения веществ; в основе лежит строение атомов (физика).</li>'
+ '<li><b>Биология</b> — живые организмы; физика помогает понять работу сердца, глаза, мышц.</li>'
+ '<li><b>География</b> — погода, ветра, реки — это всё движущиеся вещества и силы.</li>'
+ '<li><b>Техника</b> — машины, компьютеры, мобильная связь — всё построено на физике.</li>'
+ '</ul>');
h += makeCard('example', 'Примеры физических явлений', '§ 1.3',
'<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px;margin-top:4px">'
+ '<div style="background:#f0f9ff;border-left:3px solid #0284c7;padding:8px 10px;border-radius:6px"><b>Радуга</b><br><span style="font-size:.84rem;color:#475569">световое явление</span></div>'
+ '<div style="background:#fef3c7;border-left:3px solid #d97706;padding:8px 10px;border-radius:6px"><b>Гром</b><br><span style="font-size:.84rem;color:#475569">звуковое явление</span></div>'
+ '<div style="background:#fee2e2;border-left:3px solid #dc2626;padding:8px 10px;border-radius:6px"><b>Северное сияние</b><br><span style="font-size:.84rem;color:#475569">электрическое</span></div>'
+ '<div style="background:#ede9fe;border-left:3px solid #7c3aed;padding:8px 10px;border-radius:6px"><b>Падение яблока</b><br><span style="font-size:.84rem;color:#475569">механическое</span></div>'
+ '<div style="background:#d1fae5;border-left:3px solid #10b981;padding:8px 10px;border-radius:6px"><b>Кипение чайника</b><br><span style="font-size:.84rem;color:#475569">тепловое</span></div>'
+ '<div style="background:#cffafe;border-left:3px solid #0891b2;padding:8px 10px;border-radius:6px"><b>Тающий лёд</b><br><span style="font-size:.84rem;color:#475569">фазовое</span></div>'
+ '</div>');
/* IV-1: галерея явлений (визуализатор) */
h += wgWrap('p1-iv1', 'СИМ', 'Явления вокруг нас', 'Наведи курсор на иконку, чтобы увидеть, какую сторону природы изучает физика.',
'<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:10px">'
+ ['Свет','Звук','Тепло','Движение','Электричество','Магнетизм','Жидкости','Газы'].map((nm,i) =>
'<div class="ph-card" style="background:#f0f9ff;border:1.5px solid #bae6fd;border-radius:10px;padding:14px 10px;text-align:center;cursor:default;transition:transform .15s,box-shadow .15s" onmouseover="this.style.transform=\'translateY(-3px)\';this.style.boxShadow=\'0 6px 16px rgba(2,132,199,.18)\'" onmouseout="this.style.transform=\'none\';this.style.boxShadow=\'none\'">'
+ '<div style="font-size:1.8rem;color:#0284c7;font-weight:800;font-family:Unbounded,sans-serif">' + ['☀','♪','♨','→','⚡','⌘','≈','○'][i] + '</div>'
+ '<div style="font-weight:700;font-size:.88rem;margin-top:4px">' + nm + '</div>'
+ '</div>').join('')
+ '</div>');
/* IV-2: квикфайр-понимание */
h += wgWrap('p1-iv2', 'КВИЗ', 'Понятия физики', 'Отметь верное утверждение.',
'<div id="p1-q-host">'
+ quizQuestion('p1-q', 0,
'Что НЕ изучает физика?',
['Падение тел','Образование облаков','Историю Древнего Рима','Электрический ток'],
2, 'История — это гуманитарная наука; физика изучает явления природы.')
+ quizQuestion('p1-q', 1,
'От какого греческого слова произошло название «физика»?',
['Фюзис (природа)','Космос (мир)','Логос (учение)','Софос (мудрость)'],
0, 'Греческое <i>фюзис</i> = «природа», поэтому физика — наука о природе.')
+ quizQuestion('p1-q', 2,
'Какая наука изучает планеты и звёзды и опирается на физику?',
['Биология','Астрономия','География','Химия'],
1, 'Астрономия — наука о небесных телах.')
+ '</div>');
/* IV-3: DnD соответствие наука↔область */
h += wgWrap('p1-iv3', 'DnD', 'Связь наук', 'Соедини науку с её областью изучения.',
dndPool('p1-dnd', [
{ id:'i1', cat:'astro', html:'Звёзды и планеты' },
{ id:'i2', cat:'chem', html:'Кислоты и щёлочи' },
{ id:'i3', cat:'bio', html:'Клетка и ДНК' },
{ id:'i4', cat:'phys', html:'Падение мяча' },
{ id:'i5', cat:'astro', html:'Затмение Солнца' },
{ id:'i6', cat:'chem', html:'Реакция железа с кислородом' },
{ id:'i7', cat:'bio', html:'Работа сердца' },
{ id:'i8', cat:'phys', html:'Электрический ток' }
], [
{ cat:'astro', label:'Астрономия' },
{ cat:'chem', label:'Химия' },
{ cat:'bio', label:'Биология' },
{ cat:'phys', label:'Физика' }
]));
/* IV-4: тренажёр (5 вопросов) */
h += wgWrap('p1-iv4', 'ТРН', 'Тренажёр §1', 'Ответь на 5 вопросов подряд — получишь +10 XP.',
'<div id="p1-tr-host">'
+ quizQuestion('p1-tr', 0, 'Что изучает физика?', ['Только живую природу','Природные явления (свет, звук, тепло, движение, …)','Только звёзды','Только химические реакции'], 1)
+ quizQuestion('p1-tr', 1, 'Какое из явлений — НЕ физическое?', ['Кипение воды','Дыхание человека','Падение мяча','Работа лампочки'], 1, 'Дыхание — биологический процесс.')
+ quizQuestion('p1-tr', 2, 'Электромобиль — пример…', ['Биологического объекта','Технического устройства, основанного на физике','Химического вещества','Астрономического тела'], 1)
+ quizQuestion('p1-tr', 3, 'Какая пара тесно связана?', ['Физика — литература','Физика — техника','Физика — история','Физика — музыка'], 1, 'Без физики нет техники.')
+ quizQuestion('p1-tr', 4, 'Слово «физика» означает…', ['Мудрость','Природу','Знание','Закон'], 1)
+ '</div>');
h += readButton('p1');
body.innerHTML = h;
// Wire interactivity
wireDnd('p1-dnd', [
{ id:'i1', cat:'astro' },{ id:'i2', cat:'chem' },{ id:'i3', cat:'bio' },{ id:'i4', cat:'phys' },
{ id:'i5', cat:'astro' },{ id:'i6', cat:'chem' },{ id:'i7', cat:'bio' },{ id:'i8', cat:'phys' }
], []);
wireQuiz('p1-q-host', () => { if(window.addXp) window.addXp(10, 'quiz-p1'); });
wireQuiz('p1-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p1'); });
wireReadBtn('p1');
renderMath(body);
}
/* ========================================================== */
/* §2 — Физическое тело, физическое явление, физическая величина */
/* ========================================================== */
function add_p2(){
const body = document.getElementById('p2-body');
if(!body) return;
let h = '';
/* 3 теоретические карточки */
h += makeCard('theory', 'Четыре главных понятия', '§ 2.1',
'<table style="width:100%;border-collapse:collapse;margin-top:4px;font-size:.92rem">'
+ '<tr style="background:#e0f2fe"><th style="text-align:left;padding:8px 10px;border-bottom:2px solid #0284c7">Понятие</th><th style="text-align:left;padding:8px 10px;border-bottom:2px solid #0284c7">Что это</th><th style="text-align:left;padding:8px 10px;border-bottom:2px solid #0284c7">Пример</th></tr>'
+ '<tr><td style="padding:6px 10px;border-bottom:1px solid #e0f2fe"><b>Тело</b></td><td style="padding:6px 10px;border-bottom:1px solid #e0f2fe">конкретный объект</td><td style="padding:6px 10px;border-bottom:1px solid #e0f2fe">мяч, книга, дом</td></tr>'
+ '<tr><td style="padding:6px 10px;border-bottom:1px solid #e0f2fe"><b>Вещество</b></td><td style="padding:6px 10px;border-bottom:1px solid #e0f2fe">из чего сделано тело</td><td style="padding:6px 10px;border-bottom:1px solid #e0f2fe">дерево, железо, вода</td></tr>'
+ '<tr><td style="padding:6px 10px;border-bottom:1px solid #e0f2fe"><b>Явление</b></td><td style="padding:6px 10px;border-bottom:1px solid #e0f2fe">изменение в природе</td><td style="padding:6px 10px;border-bottom:1px solid #e0f2fe">падение, кипение, гроза</td></tr>'
+ '<tr><td style="padding:6px 10px"><b>Величина</b></td><td style="padding:6px 10px">то, что можно измерить</td><td style="padding:6px 10px">масса, скорость, температура</td></tr>'
+ '</table>');
h += makeCard('rule', 'Как отличать?', '§ 2.2',
'<b>Тело</b> — отвечает на вопрос «<i>что это</i>?» — конкретный предмет.<br>'
+ '<b>Вещество</b> — отвечает «<i>из чего</i>?» — материал.<br>'
+ '<b>Явление</b> — отвечает «<i>что происходит</i>?» — изменение, процесс.<br>'
+ '<b>Величина</b> — отвечает «<i>сколько</i>? в каких единицах?» — у неё всегда есть <b>число и единица</b>: $m = 5$ кг, $v = 10$ м/с, $t = 20$ °C.');
h += makeCard('example', 'Один и тот же объект — разные роли', '§ 2.3',
'Рассмотрим <b>стакан с водой</b>:<br>'
+ '<ul style="padding-left:20px;margin:4px 0">'
+ '<li><b>Стакан</b> — это <b>тело</b>.</li>'
+ '<li>Он сделан из <b>стекла</b> — это <b>вещество</b>.</li>'
+ '<li>В нём — другое тело: <b>вода</b> (из вещества «вода»).</li>'
+ '<li>Когда вода <b>кипит</b> — это <b>явление</b>.</li>'
+ '<li>Температура $t = 100$ °C — это <b>величина</b> с числом 100 и единицей °C.</li>'
+ '</ul>');
/* IV-1: главный DnD — 12 карточек по 4 корзинам */
h += wgWrap('p2-iv1', 'СИМ', 'Сортировщик: тело / вещество / явление / величина', 'Перетащи 12 карточек в правильные корзины. Это главный визуал §2 — потренируй интуицию.',
dndPool('p2-dnd', [
{ id:'a1', cat:'body', html:'Стол' },
{ id:'a2', cat:'body', html:'Автомобиль' },
{ id:'a3', cat:'body', html:'Капля росы' },
{ id:'b1', cat:'subst', html:'Алюминий' },
{ id:'b2', cat:'subst', html:'Кислород' },
{ id:'b3', cat:'subst', html:'Сахар' },
{ id:'c1', cat:'phen', html:'Молния' },
{ id:'c2', cat:'phen', html:'Замерзание воды' },
{ id:'c3', cat:'phen', html:'Движение поезда' },
{ id:'d1', cat:'val', html:'$m = 5$ кг' },
{ id:'d2', cat:'val', html:'$t = -10$ °C' },
{ id:'d3', cat:'val', html:'$v = 30$ км/ч' }
], [
{ cat:'body', label:'Тело' },
{ cat:'subst', label:'Вещество' },
{ cat:'phen', label:'Явление' },
{ cat:'val', label:'Величина' }
]));
/* IV-2: «найди величину» — выбрать из списка */
h += wgWrap('p2-iv2', 'КВИЗ', 'Найди величину', 'У величины всегда есть число и единица измерения.',
'<div id="p2-q-host">'
+ quizQuestion('p2-q', 0, 'Что из списка — физическая величина?', ['Скорость','Скоростной поезд','Стрелка часов','Кипение'], 0, 'Скорость измеряется (м/с, км/ч) — это величина.')
+ quizQuestion('p2-q', 1, 'А что из этого — явление?', ['Лужа','Испарение воды','Лёд','Холодильник'], 1, 'Испарение — процесс, изменение состояния.')
+ quizQuestion('p2-q', 2, 'Какое слово обозначает вещество?', ['Гвоздь','Сталь','Молоток','Удар'], 1, 'Сталь — материал, из которого сделан гвоздь.')
+ '</div>');
/* IV-3: квикфайр да/нет по 8 утверждениям */
h += wgWrap('p2-iv3', 'ТЕСТ', 'Тело vs величина (быстрые ответы)', 'Прочитай и отметь верное.',
'<div id="p2-tn-host">'
+ quizQuestion('p2-tn', 0, '«Карандаш» — это…', ['Тело','Вещество','Явление','Величина'], 0)
+ quizQuestion('p2-tn', 1, '«Дерево» (из чего сделана линейка) — это…', ['Тело','Вещество','Явление','Величина'], 1)
+ quizQuestion('p2-tn', 2, '«Длина» — это…', ['Тело','Вещество','Явление','Величина'], 3)
+ quizQuestion('p2-tn', 3, '«Замерзание» — это…', ['Тело','Вещество','Явление','Величина'], 2)
+ quizQuestion('p2-tn', 4, '$10$ кг — это…', ['Тело','Вещество','Явление','Значение величины'], 3, 'Число + единица = величина.')
+ '</div>');
/* IV-4: тренажёр — 4 практических вопроса */
h += wgWrap('p2-iv4', 'ТРН', 'Тренажёр §2', 'Закрепи материал — 4 вопроса.',
'<div id="p2-tr-host">'
+ quizQuestion('p2-tr', 0, 'Что НЕ является телом?', ['Воздушный шар','Капля воды','Скорость','Кирпич'], 2, 'Скорость — величина, а не тело.')
+ quizQuestion('p2-tr', 1, 'Стакан с молоком: молоко в стакане — это…', ['Тело','Вещество','Явление','Величина'], 0, 'Молоко в этой ситуации — отдельное тело со своей формой (формой стакана).')
+ quizQuestion('p2-tr', 2, 'Парусник, плывущий в океане. Назови явление.', ['Парусник','Дерево (мачта)','Движение','Длина паруса'], 2)
+ quizQuestion('p2-tr', 3, 'Что нужно для записи величины?', ['Только число','Только единица','Число + единица','Только название'], 2, 'Например: $v = 20$ м/с — число 20 и единица м/с.')
+ '</div>');
h += readButton('p2');
body.innerHTML = h;
wireDnd('p2-dnd', [
{ id:'a1', cat:'body' },{ id:'a2', cat:'body' },{ id:'a3', cat:'body' },
{ id:'b1', cat:'subst' },{ id:'b2', cat:'subst' },{ id:'b3', cat:'subst' },
{ id:'c1', cat:'phen' },{ id:'c2', cat:'phen' },{ id:'c3', cat:'phen' },
{ id:'d1', cat:'val' },{ id:'d2', cat:'val' },{ id:'d3', cat:'val' }
], []);
wireQuiz('p2-q-host', () => { if(window.addXp) window.addXp(10, 'quiz-p2'); });
wireQuiz('p2-tn-host', () => { if(window.addXp) window.addXp(10, 'tn-p2'); });
wireQuiz('p2-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p2'); });
wireReadBtn('p2');
renderMath(body);
}
/* ========================================================== */
/* §3 — Методы исследования в физике */
/* ========================================================== */
function add_p3(){
const body = document.getElementById('p3-body');
if(!body) return;
let h = '';
h += makeCard('theory', 'Как физики изучают природу', '§ 3.1',
'Физика использует <b>три метода познания</b>:'
+ '<ol style="padding-left:20px;margin:6px 0">'
+ '<li><b>Наблюдение</b> — изучение явления <i>без вмешательства</i>. Учёный смотрит, фиксирует, не изменяя условий.</li>'
+ '<li><b>Эксперимент</b> — <i>целенаправленное</i> воссоздание явления в нужных условиях с измерениями.</li>'
+ '<li><b>Теоретическое описание</b> — построение модели, формул, законов; <i>гипотеза</i> сначала, потом — проверка.</li>'
+ '</ol>');
h += makeCard('rule', 'Чем отличаются?', '§ 3.2',
'<b>Наблюдение</b>: смотрим за грозой — не запускаем её сами.<br>'
+ '<b>Эксперимент</b>: бросаем шары разной массы в трубке без воздуха и измеряем время падения.<br>'
+ '<b>Гипотеза</b>: «может быть, тела падают одинаково в вакууме?» — её надо <i>проверить</i> экспериментом.<br>'
+ '<b>Теория</b>: подтверждённая гипотеза становится частью знаний — например, закон всемирного тяготения.');
h += makeCard('example', 'Опыт Галилея с Пизанской башней', '§ 3.3',
'По легенде, в конце XVI века <b>Галилео Галилей</b> поднялся на наклонную Пизанскую башню '
+ 'и одновременно бросил с её вершины два шара разной массы — тяжёлый и лёгкий. '
+ 'Шары упали на землю <b>почти одновременно</b>. Это был <b>эксперимент</b>, '
+ 'опровергнувший представление Аристотеля о том, что тяжёлые тела падают быстрее. '
+ 'Так появилась гипотеза «все тела падают с одним ускорением», позже подтверждённая в опытах с вакуумной трубкой.');
/* IV-1: timeline исторических опытов */
h += wgWrap('p3-iv1', 'СИМ', 'Великие опыты и наблюдения', 'Кликай по этапам — узнавай, чем прославился каждый учёный.',
'<div style="position:relative;padding:8px 0">'
+ ['Архимед / III в. до н. э. — закон рычага. Наблюдение и расчёт.',
'Галилей / 1590-е — падение тел с башни. Эксперимент.',
'Торричелли / 1643 — открыл атмосферное давление. Эксперимент с ртутью.',
'Паскаль / 1648 — закон передачи давления. Эксперимент и теория.',
'Ньютон / 1687 — закон всемирного тяготения. Теория, объединившая всё.'].map((txt, i) => {
const [name, rest] = txt.split(' — ');
return '<details style="background:#f0f9ff;border-left:3px solid #4f46e5;border-radius:6px;margin-bottom:6px;padding:8px 12px"><summary style="font-weight:700;cursor:pointer;font-size:.94rem">' + (i+1) + '. ' + name + '</summary><div style="margin-top:6px;color:#475569;font-size:.88rem;line-height:1.55">' + rest + '</div></details>';
}).join('')
+ '</div>');
/* IV-2: КВИЗ опыт vs наблюдение */
h += wgWrap('p3-iv2', 'КВИЗ', 'Опыт или наблюдение?', 'Выбери, какой метод использован.',
'<div id="p3-q-host">'
+ quizQuestion('p3-q', 0, 'Метеоролог смотрит на облака и записывает их форму.', ['Наблюдение','Эксперимент','Гипотеза','Теория'], 0)
+ quizQuestion('p3-q', 1, 'Ученик помещает шарик в воду и измеряет, насколько поднялся уровень.', ['Наблюдение','Эксперимент','Гипотеза','Теория'], 1)
+ quizQuestion('p3-q', 2, 'Учёный предполагает: «возможно, металл проводит тепло из-за свободных электронов».', ['Наблюдение','Эксперимент','Гипотеза','Теория'], 2)
+ quizQuestion('p3-q', 3, 'Архимед открыл закон рычага и записал его в виде формулы $F_1 l_1 = F_2 l_2$.', ['Наблюдение','Эксперимент','Гипотеза','Теория'], 3, 'Подтверждённое соотношение — это теория (закон).')
+ '</div>');
/* IV-3: DnD «классифицируй» */
h += wgWrap('p3-iv3', 'DnD', 'Классификация ситуаций', 'Распредели 8 ситуаций по трём корзинам.',
dndPool('p3-dnd', [
{ id:'a1', cat:'obs', html:'Смотрим, как тает снег весной' },
{ id:'a2', cat:'obs', html:'Записываем температуру за неделю' },
{ id:'a3', cat:'exp', html:'Нагреваем металл лампой и измеряем удлинение' },
{ id:'a4', cat:'exp', html:'Сравниваем падение перышка в трубке с воздухом и без' },
{ id:'a5', cat:'hyp', html:'Возможно, скорость света — максимальная во Вселенной' },
{ id:'a6', cat:'hyp', html:'Может быть, существуют тёмная материя и тёмная энергия' },
{ id:'a7', cat:'exp', html:'Бросаем мяч с разной высоты и засекаем время полёта' },
{ id:'a8', cat:'obs', html:'Изучаем затмение Луны' }
], [
{ cat:'obs', label:'Наблюдение' },
{ cat:'exp', label:'Эксперимент' },
{ cat:'hyp', label:'Гипотеза' }
]));
/* IV-4: тренажёр */
h += wgWrap('p3-iv4', 'ТРН', 'Тренажёр §3', 'Закрепи материал.',
'<div id="p3-tr-host">'
+ quizQuestion('p3-tr', 0, 'Что НЕ относится к методам познания в физике?', ['Наблюдение','Эксперимент','Угадывание','Теория'], 2, 'Угадывание — это не научный метод.')
+ quizQuestion('p3-tr', 1, 'Главное отличие эксперимента от наблюдения — это…', ['Использование приборов','Активное вмешательство и контроль условий','Запись результатов','Участие учёного'], 1)
+ quizQuestion('p3-tr', 2, 'Гипотеза становится теорией, когда…', ['Её опубликовали','Она проверена опытом','Её одобрил профессор','Её записали в учебник'], 1)
+ quizQuestion('p3-tr', 3, 'Какой учёный знаменит опытами с падающими телами?', ['Архимед','Галилей','Ньютон','Эйнштейн'], 1)
+ quizQuestion('p3-tr', 4, 'Что такое физическая модель?', ['Реальный прибор','Упрощённое представление явления для расчётов','Любая теория','Только формула'], 1, 'Модель опускает несущественные детали ради простоты.')
+ '</div>');
h += readButton('p3');
body.innerHTML = h;
wireDnd('p3-dnd', [
{ id:'a1', cat:'obs' },{ id:'a2', cat:'obs' },{ id:'a3', cat:'exp' },{ id:'a4', cat:'exp' },
{ id:'a5', cat:'hyp' },{ id:'a6', cat:'hyp' },{ id:'a7', cat:'exp' },{ id:'a8', cat:'obs' }
], []);
wireQuiz('p3-q-host', () => { if(window.addXp) window.addXp(10, 'quiz-p3'); });
wireQuiz('p3-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p3'); });
wireReadBtn('p3');
renderMath(body);
}
/* ========================================================== */
/* §4 — Прямые и косвенные измерения */
/* ========================================================== */
function add_p4(){
const body = document.getElementById('p4-body');
if(!body) return;
let h = '';
h += makeCard('theory', 'Два типа измерений', '§ 4.1',
'<b>Прямое измерение</b> — значение читается <i>прямо со шкалы прибора</i>. '
+ 'Длину книги — линейкой, массу — весами, время — секундомером, температуру — термометром.<br><br>'
+ '<b>Косвенное измерение</b> — значение <i>вычисляется по формуле</i> из других величин, '
+ 'измеренных прямо. Например, чтобы найти площадь стола, измеряют длину и ширину линейкой '
+ '(прямые), а площадь $S = a b$ — это уже косвенное измерение.');
h += makeCard('rule', 'Основные формулы косвенных измерений', '§ 4.2',
'<ul style="padding-left:20px;margin:4px 0;line-height:1.85">'
+ '<li><b>Площадь прямоугольника:</b> $S = a \\cdot b$, $[S] = $ м²</li>'
+ '<li><b>Объём прямоугольного параллелепипеда:</b> $V = a \\cdot b \\cdot c$, $[V] = $ м³</li>'
+ '<li><b>Объём через цилиндр:</b> $V = S \\cdot h$ (если известна площадь основания)</li>'
+ '<li><b>Плотность вещества:</b> $\\rho = \\dfrac{m}{V}$, $[\\rho] = $ кг/м³</li>'
+ '<li><b>Скорость:</b> $v = \\dfrac{s}{t}$, $[v] = $ м/с</li>'
+ '</ul>');
h += makeCard('example', 'Объём картофеля', '§ 4.3',
'Картофелина имеет неправильную форму — линейкой её не измерить. Но можно сделать так:'
+ '<ol style="padding-left:20px;margin:6px 0">'
+ '<li>Налить в мензурку воды до отметки $V_1 = 200$ мл (прямое измерение).</li>'
+ '<li>Опустить картофелину; уровень поднялся до $V_2 = 280$ мл (прямое).</li>'
+ '<li>Объём картофелины: $V = V_2 - V_1 = 80$ мл $= 80$ см³ (косвенное).</li>'
+ '</ol>');
/* IV-1: лаборатория приборов */
h += wgWrap('p4-iv1', 'СИМ', 'Лаборатория измерительных приборов', 'Каждый прибор даёт <i>прямое</i> измерение одной величины.',
'<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px">'
+ [
['Линейка','длина','м, см, мм','#0284c7'],
['Весы','масса','кг, г','#7c3aed'],
['Термометр','температура','°C','#dc2626'],
['Секундомер','время','с, мин','#10b981'],
['Мензурка','объём жидкости','мл, л','#0891b2'],
['Динамометр','сила','Н','#d97706']
].map(([nm, v, u, col]) =>
'<div style="background:#f0f9ff;border:1.5px solid ' + col + ';border-radius:10px;padding:12px;text-align:center">'
+ '<div style="font-family:Unbounded,sans-serif;font-weight:800;color:' + col + ';font-size:.96rem">' + nm + '</div>'
+ '<div style="font-size:.84rem;color:#475569;margin-top:4px">' + v + '</div>'
+ '<div style="font-size:.76rem;color:#64748b;margin-top:2px;font-family:JetBrains Mono,monospace">' + u + '</div>'
+ '</div>').join('')
+ '</div>');
/* IV-2: главный калькулятор косвенных измерений */
h += wgWrap('p4-iv2', 'КАЛЬК', 'Калькулятор косвенных измерений', 'Меняй размеры $a, b, c$ и массу $m$ — формулы пересчитываются автоматически.',
'<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px;margin-bottom:12px">'
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid #bae6fd">$a$, см: <b id="p4-a" style="color:#0c4a6e;font-family:JetBrains Mono,monospace">10</b><input type="range" id="p4-a-r" min="1" max="50" step="1" value="10" style="display:block;width:100%;margin-top:6px;accent-color:#0284c7"></label>'
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid #bae6fd">$b$, см: <b id="p4-b" style="color:#0c4a6e;font-family:JetBrains Mono,monospace">5</b><input type="range" id="p4-b-r" min="1" max="50" step="1" value="5" style="display:block;width:100%;margin-top:6px;accent-color:#0284c7"></label>'
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid #bae6fd">$c$, см: <b id="p4-c" style="color:#0c4a6e;font-family:JetBrains Mono,monospace">3</b><input type="range" id="p4-c-r" min="1" max="50" step="1" value="3" style="display:block;width:100%;margin-top:6px;accent-color:#0284c7"></label>'
+ '<label style="display:block;font-size:.86rem;color:#475569;background:#fff;padding:8px 12px;border-radius:8px;border:1px solid #bae6fd">$m$, г: <b id="p4-m" style="color:#0c4a6e;font-family:JetBrains Mono,monospace">405</b><input type="range" id="p4-m-r" min="10" max="5000" step="5" value="405" style="display:block;width:100%;margin-top:6px;accent-color:#0284c7"></label>'
+ '</div>'
+ '<div style="background:#e0f2fe;border-radius:9px;padding:12px 14px;display:flex;flex-direction:column;gap:6px;font-size:.94rem">'
+ '<div>Площадь: $S = a b = $ <b id="p4-S" style="color:#0c4a6e;font-family:JetBrains Mono,monospace">50</b> см²</div>'
+ '<div>Объём: $V = a b c = $ <b id="p4-V" style="color:#0c4a6e;font-family:JetBrains Mono,monospace">150</b> см³</div>'
+ '<div>Плотность: $\\rho = m/V = $ <b id="p4-rho" style="color:#0c4a6e;font-family:JetBrains Mono,monospace">2.7</b> г/см³ <span id="p4-rho-name" style="color:#475569;font-size:.84rem;margin-left:6px">(близко к алюминию)</span></div>'
+ '</div>');
/* IV-3: DnD прямое/косвенное */
h += wgWrap('p4-iv3', 'DnD', 'Прямое или косвенное?', 'Распредели измерения по типу.',
dndPool('p4-dnd', [
{ id:'a1', cat:'dir', html:'Длина книги линейкой' },
{ id:'a2', cat:'ind', html:'Площадь стола из длины × ширины' },
{ id:'a3', cat:'dir', html:'Температура воздуха термометром' },
{ id:'a4', cat:'ind', html:'Скорость велосипедиста (путь / время)' },
{ id:'a5', cat:'dir', html:'Время урока секундомером' },
{ id:'a6', cat:'ind', html:'Объём картофеля через вытеснение воды' },
{ id:'a7', cat:'dir', html:'Масса яблока на весах' },
{ id:'a8', cat:'ind', html:'Плотность металла $\\rho = m/V$' }
], [
{ cat:'dir', label:'Прямое' },
{ cat:'ind', label:'Косвенное' }
]));
/* IV-4: тренажёр расчётных */
h += wgWrap('p4-iv4', 'ТРН', 'Тренажёр §4', '5 расчётных задач.',
'<div id="p4-tr-host">'
+ quizQuestion('p4-tr', 0, 'Прямоугольник: $a = 6$ см, $b = 4$ см. Площадь $S = ?$', ['10 см²','24 см²','12 см²','20 см²'], 1, '$S = 6 \\cdot 4 = 24$ см².')
+ quizQuestion('p4-tr', 1, 'Кирпич: $a = 25$ см, $b = 12$ см, $c = 6{,}5$ см. Объём $V$?', ['1900 см³','1950 см³','2000 см³','2500 см³'], 1, '$V = 25 \\cdot 12 \\cdot 6{,}5 = 1950$ см³.')
+ quizQuestion('p4-tr', 2, 'Тело массой $m = 200$ г занимает объём $V = 25$ см³. Плотность?', ['4 г/см³','6 г/см³','8 г/см³','10 г/см³'], 2, '$\\rho = m/V = 200/25 = 8$ г/см³ (близко к железу).')
+ quizQuestion('p4-tr', 3, 'Путь $s = 60$ м, время $t = 12$ с. Скорость?', ['4 м/с','5 м/с','6 м/с','8 м/с'], 1, '$v = s/t = 60/12 = 5$ м/с.')
+ quizQuestion('p4-tr', 4, 'В мензурку с водой $V_1 = 50$ мл опустили камень — уровень поднялся до $V_2 = 78$ мл. Объём камня?', ['22 мл','28 мл','32 мл','78 мл'], 1, '$V = V_2 - V_1 = 78 - 50 = 28$ мл.')
+ '</div>');
h += readButton('p4');
body.innerHTML = h;
// Wire calc §4 IV-2
const upd = () => {
const a = +document.getElementById('p4-a-r').value;
const b = +document.getElementById('p4-b-r').value;
const c = +document.getElementById('p4-c-r').value;
const m = +document.getElementById('p4-m-r').value;
document.getElementById('p4-a').textContent = a;
document.getElementById('p4-b').textContent = b;
document.getElementById('p4-c').textContent = c;
document.getElementById('p4-m').textContent = m;
const S = a * b;
const V = a * b * c;
const rho = m / V;
document.getElementById('p4-S').textContent = S;
document.getElementById('p4-V').textContent = V;
document.getElementById('p4-rho').textContent = rho.toFixed(2);
// Угадывание вещества по плотности (г/см³)
let name = '';
if(rho < 0.3) name = '(легче пенопласта — нереально!)';
else if(rho < 0.7) name = '(дерево / сосна)';
else if(rho < 1.1) name = '(вода или лёд)';
else if(rho < 3.5) name = '(алюминий / стекло)';
else if(rho < 9) name = '(железо / медь)';
else if(rho < 15) name = '(свинец / ртуть)';
else if(rho < 22) name = '(золото / платина)';
else name = '(плотнее любого металла)';
document.getElementById('p4-rho-name').textContent = name;
};
['p4-a-r','p4-b-r','p4-c-r','p4-m-r'].forEach(id => document.getElementById(id).addEventListener('input', upd));
upd();
wireDnd('p4-dnd', [
{ id:'a1', cat:'dir' },{ id:'a2', cat:'ind' },{ id:'a3', cat:'dir' },{ id:'a4', cat:'ind' },
{ id:'a5', cat:'dir' },{ id:'a6', cat:'ind' },{ id:'a7', cat:'dir' },{ id:'a8', cat:'ind' }
], []);
wireQuiz('p4-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p4'); });
wireReadBtn('p4');
renderMath(body);
}
/* ========================================================== */
/* §5 — Единицы измерения физических величин. СИ */
/* ========================================================== */
function add_p5(){
const body = document.getElementById('p5-body');
if(!body) return;
let h = '';
h += makeCard('theory', 'Зачем СИ?', '§ 5.1',
'Если каждый учёный использует свои единицы — результаты невозможно сравнить. '
+ 'В 1960 году принята <b>Международная система единиц (СИ)</b> — единый стандарт. '
+ 'В СИ — <b>7 основных единиц</b>; все остальные получаются комбинацией основных.');
h += makeCard('rule', '7 основных единиц СИ', '§ 5.2',
'<table style="width:100%;border-collapse:collapse;margin-top:4px;font-size:.92rem">'
+ '<tr style="background:#e0f2fe"><th style="text-align:left;padding:6px 10px;border-bottom:2px solid #0284c7">Величина</th><th style="text-align:left;padding:6px 10px;border-bottom:2px solid #0284c7">Единица</th><th style="text-align:left;padding:6px 10px;border-bottom:2px solid #0284c7">Обозначение</th></tr>'
+ [['Длина','метр','м'],['Масса','килограмм','кг'],['Время','секунда','с'],['Сила тока','ампер','А'],['Температура','кельвин','К'],['Кол-во вещества','моль','моль'],['Сила света','кандела','кд']].map(([v,u,s]) =>
'<tr><td style="padding:5px 10px;border-bottom:1px solid #e0f2fe">' + v + '</td><td style="padding:5px 10px;border-bottom:1px solid #e0f2fe"><b>' + u + '</b></td><td style="padding:5px 10px;border-bottom:1px solid #e0f2fe;font-family:JetBrains Mono,monospace;color:#0c4a6e">' + s + '</td></tr>').join('')
+ '</table>');
h += makeCard('example', 'Кратные и дольные приставки', '§ 5.3',
'<table style="width:100%;border-collapse:collapse;margin-top:4px;font-size:.92rem">'
+ '<tr style="background:#e0f2fe"><th style="text-align:left;padding:6px 10px">Приставка</th><th style="text-align:left;padding:6px 10px">Множитель</th><th style="text-align:left;padding:6px 10px">Пример</th></tr>'
+ [['Г (гига)','$10^9$','1 ГГц = $10^9$ Гц'],['М (мега)','$10^6$','1 МВт = $10^6$ Вт'],['к (кило)','$10^3$','1 кг = 1000 г'],['—','1','1 м'],['м (милли)','$10^{-3}$','1 мс = 0,001 с'],['мк (микро)','$10^{-6}$','1 мкм = $10^{-6}$ м'],['н (нано)','$10^{-9}$','1 нс = $10^{-9}$ с']].map(([pf,k,ex]) =>
'<tr><td style="padding:4px 10px;border-bottom:1px solid #e0f2fe"><b>' + pf + '</b></td><td style="padding:4px 10px;border-bottom:1px solid #e0f2fe">' + k + '</td><td style="padding:4px 10px;border-bottom:1px solid #e0f2fe;font-family:JetBrains Mono,monospace;font-size:.84rem">' + ex + '</td></tr>').join('')
+ '</table>');
/* IV-1: визуал — 7 основных */
h += wgWrap('p5-iv1', 'СИМ', '7 китов СИ', 'Семь основных единиц — фундамент всех физических измерений.',
'<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px">'
+ [['Длина','м','#0284c7'],['Масса','кг','#7c3aed'],['Время','с','#10b981'],['Ток','А','#d97706'],['Темп.','К','#dc2626'],['Вещ-во','моль','#0891b2'],['Свет','кд','#fbbf24']].map(([v, u, col]) =>
'<div style="background:linear-gradient(135deg,' + col + ',' + col + '99);color:#fff;border-radius:11px;padding:14px 10px;text-align:center;box-shadow:0 3px 10px rgba(0,0,0,.12)">'
+ '<div style="font-family:JetBrains Mono,monospace;font-weight:900;font-size:1.6rem">' + u + '</div>'
+ '<div style="font-weight:700;font-size:.84rem;margin-top:4px;opacity:.95">' + v + '</div>'
+ '</div>').join('')
+ '</div>');
/* IV-2: главный конвертер */
h += wgWrap('p5-iv2', 'КАЛЬК', 'Конвертер единиц', 'Выбери приставку и величину — увидь перевод в основную единицу СИ.',
'<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;margin-bottom:12px">'
+ '<label style="display:block;font-size:.84rem;color:#475569;background:#fff;padding:8px 10px;border-radius:8px;border:1px solid #bae6fd">Число: <b id="p5-n" style="color:#0c4a6e;font-family:JetBrains Mono,monospace">5</b><input type="range" id="p5-n-r" min="1" max="999" step="1" value="5" style="display:block;width:100%;margin-top:6px;accent-color:#0284c7"></label>'
+ '<label style="display:block;font-size:.84rem;color:#475569;background:#fff;padding:8px 10px;border-radius:8px;border:1px solid #bae6fd">Приставка:<select id="p5-pf" style="width:100%;margin-top:6px;padding:5px;border-radius:6px;border:1px solid #bae6fd;font-family:inherit"><option value="1e9">Г (гига, $10^9$)</option><option value="1e6">М (мега, $10^6$)</option><option value="1e3" selected>к (кило, $10^3$)</option><option value="1">— (без приставки)</option><option value="1e-2">с (санти, $10^{-2}$)</option><option value="1e-3">м (милли, $10^{-3}$)</option><option value="1e-6">мк (микро, $10^{-6}$)</option><option value="1e-9">н (нано, $10^{-9}$)</option></select></label>'
+ '<label style="display:block;font-size:.84rem;color:#475569;background:#fff;padding:8px 10px;border-radius:8px;border:1px solid #bae6fd">Единица:<select id="p5-u" style="width:100%;margin-top:6px;padding:5px;border-radius:6px;border:1px solid #bae6fd;font-family:inherit"><option value="м" selected>м (метр)</option><option value="г">г (грамм)</option><option value="с">с (секунда)</option><option value="Вт">Вт (ватт)</option><option value="Гц">Гц (герц)</option><option value="Н">Н (ньютон)</option></select></label>'
+ '</div>'
+ '<div style="background:#e0f2fe;border-radius:9px;padding:12px 14px;font-size:.96rem">'
+ '<span id="p5-src" style="font-family:JetBrains Mono,monospace;color:#0c4a6e;font-weight:700">5 км</span>'
+ ' &nbsp; = &nbsp; '
+ '<span id="p5-dst" style="font-family:JetBrains Mono,monospace;color:#0c4a6e;font-weight:700">5000 м</span>'
+ '<div id="p5-explain" style="font-size:.82rem;color:#475569;margin-top:6px"></div>'
+ '</div>');
/* IV-3: DnD — величина ↔ единица СИ */
h += wgWrap('p5-iv3', 'DnD', 'Величина ↔ единица СИ', 'Соедини каждую величину с её основной единицей.',
dndPool('p5-dnd', [
{ id:'a1', cat:'m', html:'Длина' },
{ id:'a2', cat:'kg', html:'Масса' },
{ id:'a3', cat:'s', html:'Время' },
{ id:'a4', cat:'K', html:'Температура' },
{ id:'a5', cat:'A', html:'Сила тока' },
{ id:'a6', cat:'m', html:'Расстояние от Минска до Бреста' },
{ id:'a7', cat:'kg', html:'Масса арбуза' },
{ id:'a8', cat:'s', html:'Длительность урока' }
], [
{ cat:'m', label:'метр (м)' },
{ cat:'kg', label:'килограмм (кг)' },
{ cat:'s', label:'секунда (с)' },
{ cat:'K', label:'кельвин (К)' },
{ cat:'A', label:'ампер (А)' }
]));
/* IV-4: тренажёр на перевод */
h += wgWrap('p5-iv4', 'ТРН', 'Тренажёр §5', '5 задач на перевод единиц.',
'<div id="p5-tr-host">'
+ quizQuestion('p5-tr', 0, '$5$ км $= ?$ м', ['50','500','5 000','50 000'], 2, '$5 \\cdot 1000 = 5\\,000$ м.')
+ quizQuestion('p5-tr', 1, '$0{,}25$ кг $= ?$ г', ['25','100','250','2500'], 2, '$0{,}25 \\cdot 1000 = 250$ г.')
+ quizQuestion('p5-tr', 2, '$2$ ч $= ?$ с', ['120','3 600','7 200','12 000'], 2, '$2 \\cdot 60 \\cdot 60 = 7\\,200$ с.')
+ quizQuestion('p5-tr', 3, '$300$ мс $= ?$ с', ['0,03','0,3','3','30'], 1, '$300 \\cdot 10^{-3} = 0{,}3$ с.')
+ quizQuestion('p5-tr', 4, '$1$ см² $= ?$ м²', ['0,1','0,01','0,001','0,0001'], 3, '$1\\,\\text{см}^2 = (10^{-2}\\,\\text{м})^2 = 10^{-4}\\,\\text{м}^2$.')
+ '</div>');
h += readButton('p5');
body.innerHTML = h;
// Wire converter §5 IV-2
const updConv = () => {
const n = +document.getElementById('p5-n-r').value;
const pf = +document.getElementById('p5-pf').value;
const u = document.getElementById('p5-u').value;
document.getElementById('p5-n').textContent = n;
const prefixLabels = { '1000000000':'Г','1000000':'М','1000':'к','1':'','0.01':'с','0.001':'м','1e-6':'мк','1e-9':'н' };
// Получим символ по value
const sel = document.getElementById('p5-pf');
const pfLabel = (sel.options[sel.selectedIndex].text.match(/^([А-Яа-я—]+)/) || ['',''])[1];
const result = n * pf;
// Format result
let resStr;
if(Math.abs(result) >= 1e6 || (Math.abs(result) > 0 && Math.abs(result) < 0.001)) resStr = result.toExponential(2);
else if(Number.isInteger(result)) resStr = result.toLocaleString('ru-RU');
else resStr = (+result.toPrecision(6)).toLocaleString('ru-RU');
document.getElementById('p5-src').textContent = n + ' ' + pfLabel + u;
document.getElementById('p5-dst').textContent = resStr + ' ' + u;
const explain = pf === 1 ? 'Без приставки.' : ('Множитель ' + (pf >= 1 ? pf.toLocaleString('ru-RU') : pf) + '. Умножаем число на этот множитель.');
document.getElementById('p5-explain').textContent = explain;
};
document.getElementById('p5-n-r').addEventListener('input', updConv);
document.getElementById('p5-pf').addEventListener('change', updConv);
document.getElementById('p5-u').addEventListener('change', updConv);
updConv();
wireDnd('p5-dnd', [
{ id:'a1', cat:'m' },{ id:'a2', cat:'kg' },{ id:'a3', cat:'s' },{ id:'a4', cat:'K' },
{ id:'a5', cat:'A' },{ id:'a6', cat:'m' },{ id:'a7', cat:'kg' },{ id:'a8', cat:'s' }
], []);
wireQuiz('p5-tr-host', () => { if(window.addXp) window.addXp(15, 'tr-p5'); });
wireReadBtn('p5');
renderMath(body);
}
/* Экспорт */
window.PHYS7_CH1_WIDGETS = {
p1: add_p1,
p2: add_p2,
p3: add_p3,
p4: add_p4,
p5: add_p5
// p6, p7, final1 — в Wave 3
};
})();