fix(textbooks): Физика 9 — STATE collision, KaTeX escape, авто-init симуляций

Три бага из жалобы пользователя:

1) phys9_legacy.js упал с 'Identifier STATE has already been declared' —
   const STATE в монолите конфликтовал с const STATE в chapter inline JS.
   Скрипт extract_phys9_legacy.cjs теперь оборачивает извлечённый код в IIFE
   и явно экспортит через window 70 функций (upd*/draw*/init*/start*/lab*/
   check*/toggle*/render*/show*/...) + 7 const-массивов (TASKS_PN, PUZ_PN).

2) В боковой панели формулы рендерились как 'Delta vecr' вместо Δr⃗ —
   мой переход на JSON.stringify в gen_phys9_ch.js добавил лишний слой
   escape backslash. Уменьшил \\ → \ в SIDEBAR_ROWS, TIPS_HTML,
   PARA_SUBS, LR_SUBS (90 строк). Цепочка теперь: source \Delta → string
   \Delta → JSON "\\Delta" → HTML JS \Delta → runtime \Delta →
   KaTeX \Delta ✓.

3) 'не работают симуляции' — функции из legacy.js были доступны, но
   chapter goTo(id) их не вызывал. Добавлен авто-вызов upd<N>(),
   startAnim<N>(), init<N>(), draw<N>() при переключении на параграф,
   и updLab<N>(), drawLab<N>() — для ЛР.
This commit is contained in:
Maxim Dolgolyov
2026-05-30 09:06:20 +03:00
parent c26423b7d4
commit 66bd7ac1f4
8 changed files with 412 additions and 194 deletions
+34 -17
View File
@@ -15,7 +15,6 @@
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/phys.js" defer></script>
<script src="/js/phys9_legacy.js" defer></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Manrope:wght@600;700;800;900&family=Unbounded:wght@700;800;900&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
<style>
:root{
@@ -617,12 +616,12 @@ const TOTAL_PARAS = 7;
const _TB_SLUG = 'physics-9-ch4';
const PARAS = [
{ id:"p31", num:"§ 31", name:"Импульс тела. Импульс системы тел", sub:"$\\\\vec p = m\\\\vec v$" },
{ id:"p32", num:"§ 32", name:"Закон сохранения импульса. Реактивное движение", sub:"$\\\\sum\\\\vec p = \\\\text{const}$" },
{ id:"p33", num:"§ 33", name:"Механическая работа. Мощность", sub:"$A = F\\\\Delta r\\\\cos\\\\alpha$" },
{ id:"p31", num:"§ 31", name:"Импульс тела. Импульс системы тел", sub:"$\\vec p = m\\vec v$" },
{ id:"p32", num:"§ 32", name:"Закон сохранения импульса. Реактивное движение", sub:"$\\sum\\vec p = \\text{const}$" },
{ id:"p33", num:"§ 33", name:"Механическая работа. Мощность", sub:"$A = F\\Delta r\\cos\\alpha$" },
{ id:"p34", num:"§ 34", name:"Потенциальная энергия", sub:"$E_п = mgh$" },
{ id:"p35", num:"§ 35", name:"Кинетическая энергия. Полная энергия системы тел", sub:"$E_к = mv^2/2$" },
{ id:"p36", num:"§ 36", name:"Закон сохранения энергии", sub:"$E_к + E_п = \\\\text{const}$" },
{ id:"p36", num:"§ 36", name:"Закон сохранения энергии", sub:"$E_к + E_п = \\text{const}$" },
{ id:"final4", num:'\u2605', name:'Финал главы', sub:"Итоги · боссы главы 4", final:true }
];
PARAS.forEach(p => { STATE.progress[p.id] = 0; });
@@ -754,26 +753,44 @@ function goTo(id){
window.scrollTo({top:0,behavior:'smooth'});
if((STATE.progress[id]||0)<10) bumpProgress(id, 10);
if(window.renderMathInElement) setTimeout(()=>renderMath(el), 0);
// Auto-init legacy simulations: call upd<N>() / startAnim<N>() / draw<N>() if defined in phys9_legacy.js.
if(id.startsWith('p')){
const n = id.slice(1);
setTimeout(()=>{
['upd','startAnim','init','draw'].forEach(prefix=>{
const fn = window[prefix + n];
if(typeof fn === 'function'){ try{ fn(); }catch(e){ console.warn(prefix + n + ' init:', e.message); } }
});
}, 50);
} else if(id.startsWith('lr')){
const n = id.slice(2);
setTimeout(()=>{
['updLab','drawLab'].forEach(prefix=>{
const fn = window[prefix + n];
if(typeof fn === 'function'){ try{ fn(); }catch(e){} }
});
}, 50);
}
markLastPara(id);
}
const SIDEBARS = {
p31:{title:"Шпаргалка §31",rows:[["$\\\\vec p = m\\\\vec v$","импульс тела"],["Ед.","кг·м/с"],["Сумма","$\\\\vec p_{сист} = \\\\sum \\\\vec p_i$"]]},
p32:{title:"Шпаргалка §32",rows:[["ЗСИ","$\\\\sum\\\\vec p_{до} = \\\\sum\\\\vec p_{после}$"],["Замкн. сист.","без внеш. сил"],["Ракета","$m_р\\\\vec v_р + m_г\\\\vec v_г = 0$"]]},
p33:{title:"Шпаргалка §33",rows:[["$A = F\\\\Delta r\\\\cos\\\\alpha$",""],["Ед.","Дж"],["Мощность","$P = A/\\\\Delta t$, Вт"]]},
p34:{title:"Шпаргалка §34",rows:[["$E_п = mgh$","тяжести"],["$E_п = kx^2/2$","упругости"],["$A = -\\\\Delta E_п$",""]]},
p35:{title:"Шпаргалка §35",rows:[["$E_к = mv^2/2$",""],["Теорема","$A = \\\\Delta E_к$"],["$E = E_к + E_п$","полная"]]},
p36:{title:"Шпаргалка §36",rows:[["ЗСЭ","$E = \\\\text{const}$ в замкн. консервативной сист."],["Превращ.","один вид → другой"],["Трение","диссипация $\\\\to$ тепло"]]},
p31:{title:"Шпаргалка §31",rows:[["$\\vec p = m\\vec v$","импульс тела"],["Ед.","кг·м/с"],["Сумма","$\\vec p_{сист} = \\sum \\vec p_i$"]]},
p32:{title:"Шпаргалка §32",rows:[["ЗСИ","$\\sum\\vec p_{до} = \\sum\\vec p_{после}$"],["Замкн. сист.","без внеш. сил"],["Ракета","$m_р\\vec v_р + m_г\\vec v_г = 0$"]]},
p33:{title:"Шпаргалка §33",rows:[["$A = F\\Delta r\\cos\\alpha$",""],["Ед.","Дж"],["Мощность","$P = A/\\Delta t$, Вт"]]},
p34:{title:"Шпаргалка §34",rows:[["$E_п = mgh$","тяжести"],["$E_п = kx^2/2$","упругости"],["$A = -\\Delta E_п$",""]]},
p35:{title:"Шпаргалка §35",rows:[["$E_к = mv^2/2$",""],["Теорема","$A = \\Delta E_к$"],["$E = E_к + E_п$","полная"]]},
p36:{title:"Шпаргалка §36",rows:[["ЗСЭ","$E = \\text{const}$ в замкн. консервативной сист."],["Превращ.","один вид → другой"],["Трение","диссипация $\\to$ тепло"]]},
final4:{title:"Финал главы 4",rows:[["§§3136","теория главы 4"],["Награда","+50 XP"]]}
};
const TIPS=[
{sec:"p31",html:"Импульс тела: $\\\\vec p = m\\\\vec v$ (кг·м/с). Импульс системы — сумма импульсов всех тел."},
{sec:"p32",html:"ЗСИ: в замкнутой системе $\\\\sum\\\\vec p = \\\\text{const}$. Реактивное движение: $m_р\\\\vec v_р + m_г\\\\vec v_г = 0$."},
{sec:"p33",html:"Работа силы: $A = F \\\\Delta r \\\\cos\\\\alpha$ (Дж). Мощность: $P = A/\\\\Delta t = Fv\\\\cos\\\\alpha$ (Вт)."},
{sec:"p34",html:"Потенц. энергия тяжести: $E_п = mgh$. Упругости: $E_п = kx^2/2$. Работа консерват. силы: $A = -\\\\Delta E_п$."},
{sec:"p35",html:"Кинет. энергия: $E_к = mv^2/2$. Теорема: $A = \\\\Delta E_к$. Полная мех. энергия: $E = E_к + E_п$."},
{sec:"p36",html:"ЗСЭ: в замкнутой консервативной системе $E_к + E_п = \\\\text{const}$. При трении мех. энергия превращается в тепло."},
{sec:"p31",html:"Импульс тела: $\\vec p = m\\vec v$ (кг·м/с). Импульс системы — сумма импульсов всех тел."},
{sec:"p32",html:"ЗСИ: в замкнутой системе $\\sum\\vec p = \\text{const}$. Реактивное движение: $m_р\\vec v_р + m_г\\vec v_г = 0$."},
{sec:"p33",html:"Работа силы: $A = F \\Delta r \\cos\\alpha$ (Дж). Мощность: $P = A/\\Delta t = Fv\\cos\\alpha$ (Вт)."},
{sec:"p34",html:"Потенц. энергия тяжести: $E_п = mgh$. Упругости: $E_п = kx^2/2$. Работа консерват. силы: $A = -\\Delta E_п$."},
{sec:"p35",html:"Кинет. энергия: $E_к = mv^2/2$. Теорема: $A = \\Delta E_к$. Полная мех. энергия: $E = E_к + E_п$."},
{sec:"p36",html:"ЗСЭ: в замкнутой консервативной системе $E_к + E_п = \\text{const}$. При трении мех. энергия превращается в тепло."},
{sec:"final4",html:"Финал главы 4 — интегрированные задачи по §§31–36. В разработке (Phase 4+)."}
];