diff --git a/frontend/js/flagships/phys9_flag_F13_foucault.js b/frontend/js/flagships/phys9_flag_F13_foucault.js new file mode 100644 index 0000000..03a296e --- /dev/null +++ b/frontend/js/flagships/phys9_flag_F13_foucault.js @@ -0,0 +1,163 @@ +// F13. Маятник Фуко (§36 в ch4) — вращение Земли и розетка. +(function(){ +'use strict'; +const B = () => window.PHYS9_FLAG_BASE; +const C = () => window.PHYS9_COLORS || {}; + +function init(secId){ + if (!B()) return false; + const body = '' + + '
' + + '' + + '' + + '
' + + '' + + '
' + + '' + + '' + + '' + + '
' + + '
' + + '
Текущая широтаМинск (52°)
' + + '
Период оборота плоскости30.4 ч
' + + '
Реальное время0 ч
' + + '
Поворот плоскости
' + + '
' + + '
'; + + const card = B().makeCard(secId, + 'F13. Маятник Фуко', + 'Маятник в Париже (1851) доказал вращение Земли. Период оборота плоскости: $T = 24/\\sin\\varphi$ часов. На полюсе — 24 ч, на экваторе — никогда.', + body); + if (!card) return false; + + const cv = document.getElementById('F13-cv'); + const ctx = cv.getContext('2d'); + const W = cv.width, H = cv.height; + const cx = W/2, cy = H/2; + const R = 130; + + let st = { phase: 0, planeAngle: 0, t: 0, running: false, trail: [] }; + + function update(){ + const lat = +document.getElementById('F13-l').value; + const speed = +document.getElementById('F13-s').value; + document.getElementById('F13-lv').textContent = lat; + document.getElementById('F13-sv').textContent = speed; + let loc; + if (lat >= 89) loc = 'Северный полюс (90°)'; + else if (lat >= 70) loc = 'Заполярье (70-89°)'; + else if (lat >= 55) loc = 'Москва (55°)'; + else if (lat >= 50) loc = 'Минск (52°)'; + else if (lat >= 40) loc = 'Рим (42°)'; + else if (lat >= 20) loc = 'Каир (30°)'; + else if (lat >= 5) loc = 'тропики'; + else loc = 'экватор (0°)'; + document.getElementById('F13-loc').textContent = loc; + const sinL = Math.sin(lat * Math.PI/180); + const T = sinL > 0.001 ? 24 / sinL : Infinity; + document.getElementById('F13-T').textContent = isFinite(T) ? T.toFixed(1) + ' ч' : '∞ (нет поворота)'; + } + + function reset(){ + st = { phase: 0, planeAngle: 0, t: 0, running: false, trail: [] }; + document.getElementById('F13-go').textContent = 'Запустить'; + draw(); + } + + function tick(dt){ + if (!st.running) { draw(); return; } + const lat = +document.getElementById('F13-l').value; + const speed = +document.getElementById('F13-s').value; + const sinL = Math.sin(lat * Math.PI/180); + const realDt = dt * speed; /* условное реальное время в секундах */ + st.t += realDt; + /* колебание маятника: период ~6 с реального времени */ + st.phase += dt * 2 * Math.PI * 0.5; /* псевдо-период для красоты */ + /* поворот плоскости: ω = 2π/(24·3600/sinL) рад/с */ + const omega = sinL * 2 * Math.PI / (24*3600); + st.planeAngle += omega * realDt; + /* trail — текущее положение маятника */ + const r = R * Math.cos(st.phase); + const px = cx + r * Math.cos(st.planeAngle); + const py = cy + r * Math.sin(st.planeAngle); + st.trail.push({ x: px, y: py }); + if (st.trail.length > 5000) st.trail.shift(); + document.getElementById('F13-t').textContent = (st.t/3600).toFixed(2) + ' ч'; + document.getElementById('F13-rot').textContent = ((st.planeAngle * 180/Math.PI) % 360).toFixed(1) + '°'; + draw(); + } + + function draw(){ + const col = C(); + ctx.fillStyle = col.bg || '#fafafa'; + ctx.fillRect(0, 0, W, H); + /* пол */ + ctx.fillStyle = col.bgSubtle || '#f8fafc'; + ctx.beginPath(); ctx.arc(cx, cy, R + 30, 0, Math.PI*2); ctx.fill(); + ctx.strokeStyle = col.axis || '#1e293b'; + ctx.lineWidth = 2; + ctx.stroke(); + /* радиальные направления (страны света) */ + ctx.font = '12px Inter,sans-serif'; + ctx.fillStyle = col.textMuted || '#64748b'; + ctx.textAlign = 'center'; + ctx.fillText('С', cx, cy - R - 15); + ctx.fillText('Ю', cx, cy + R + 25); + ctx.fillText('З', cx - R - 18, cy + 4); + ctx.fillText('В', cx + R + 18, cy + 4); + /* следы маятника */ + if (st.trail.length > 1){ + ctx.strokeStyle = col.velocity || '#0891b2'; + ctx.lineWidth = 1.2; + ctx.globalAlpha = 0.5; + ctx.beginPath(); + ctx.moveTo(st.trail[0].x, st.trail[0].y); + for (let i = 1; i < st.trail.length; i++) ctx.lineTo(st.trail[i].x, st.trail[i].y); + ctx.stroke(); + ctx.globalAlpha = 1; + } + /* центральная точка крепления */ + ctx.fillStyle = col.axis || '#1e293b'; + ctx.beginPath(); ctx.arc(cx, cy, 5, 0, Math.PI*2); ctx.fill(); + /* плоскость колебаний — линия */ + ctx.strokeStyle = col.acceleration || '#ea580c'; + ctx.lineWidth = 1.5; + ctx.setLineDash([6, 4]); + ctx.beginPath(); + ctx.moveTo(cx - R * Math.cos(st.planeAngle), cy - R * Math.sin(st.planeAngle)); + ctx.lineTo(cx + R * Math.cos(st.planeAngle), cy + R * Math.sin(st.planeAngle)); + ctx.stroke(); + ctx.setLineDash([]); + /* маятник — груз */ + const r = R * Math.cos(st.phase); + const px = cx + r * Math.cos(st.planeAngle); + const py = cy + r * Math.sin(st.planeAngle); + ctx.fillStyle = col.forceGravity || '#2563eb'; + ctx.beginPath(); ctx.arc(px, py, 10, 0, Math.PI*2); ctx.fill(); + ctx.strokeStyle = col.bodyAccent || '#1e293b'; + ctx.lineWidth = 1.5; + ctx.stroke(); + ctx.textAlign = 'left'; + } + + document.getElementById('F13-go').addEventListener('click', () => { + st.running = !st.running; + document.getElementById('F13-go').textContent = st.running ? 'Пауза' : 'Запустить'; + }); + document.getElementById('F13-reset').addEventListener('click', reset); + document.getElementById('F13-clear').addEventListener('click', () => { st.trail = []; draw(); }); + ['F13-l','F13-s'].forEach(id => document.getElementById(id).addEventListener('input', update)); + + update(); + draw(); + B().startLoop('F13', cv, tick); + return true; +} + +if (window.PHYS9_FLAG_BASE) window.PHYS9_FLAG_BASE.register('F13', { init: init, cleanup: function(){} }); +else document.addEventListener('DOMContentLoaded', ()=>{ + if (window.PHYS9_FLAG_BASE) window.PHYS9_FLAG_BASE.register('F13', { init: init, cleanup: function(){} }); +}); + +})(); diff --git a/frontend/js/flagships/phys9_flag_F14_resonance.js b/frontend/js/flagships/phys9_flag_F14_resonance.js new file mode 100644 index 0000000..7672449 --- /dev/null +++ b/frontend/js/flagships/phys9_flag_F14_resonance.js @@ -0,0 +1,209 @@ +// F14. Резонанс (§36 в ch4) — пружина + внешняя сила. +(function(){ +'use strict'; +const B = () => window.PHYS9_FLAG_BASE; +const C = () => window.PHYS9_COLORS || {}; + +function init(secId){ + if (!B()) return false; + const body = '' + + '
' + + '' + + '' + + '' + + '' + + '
' + + '' + + '
' + + '' + + '' + + '' + + '
' + + '
' + + '
$\\nu_{собств}$1.01 Гц
' + + '
$\\nu_{внешн}$1.00 Гц
' + + '
Амплитуда0 м
' + + '
Состояние
' + + '
' + + '
'; + + const card = B().makeCard(secId, + 'F14. Резонанс пружинного маятника', + 'Слева: пружина с грузом + внешняя сила. Справа: график амплитуды от частоты — резонансный пик при $\\nu_{вн} = \\nu_{собств}$.', + body); + if (!card) return false; + + const cv = document.getElementById('F14-cv'); + const ctx = cv.getContext('2d'); + const W = cv.width, H = cv.height; + const cx = W * 0.25; + + let st = { x: 0, v: 0, t: 0, running: false, ampHistory: [] }; + + function nuOwn(){ + const m = +document.getElementById('F14-m').value; + const k = +document.getElementById('F14-k').value; + return Math.sqrt(k/m) / (2*Math.PI); + } + + function update(){ + document.getElementById('F14-mv').textContent = (+document.getElementById('F14-m').value).toFixed(1); + document.getElementById('F14-kv').textContent = +document.getElementById('F14-k').value; + document.getElementById('F14-fv').textContent = (+document.getElementById('F14-f').value).toFixed(2); + document.getElementById('F14-gv').textContent = (+document.getElementById('F14-g').value).toFixed(2); + document.getElementById('F14-nu0').textContent = nuOwn().toFixed(2) + ' Гц'; + document.getElementById('F14-nuext').textContent = (+document.getElementById('F14-f').value).toFixed(2) + ' Гц'; + } + + function reset(){ + st = { x: 0, v: 0, t: 0, running: false, ampHistory: [] }; + document.getElementById('F14-go').textContent = 'Запустить'; + draw(); + } + + function tick(dt){ + if (!st.running) { draw(); return; } + const m = +document.getElementById('F14-m').value; + const k = +document.getElementById('F14-k').value; + const omega_ext = 2*Math.PI*(+document.getElementById('F14-f').value); + const gamma = +document.getElementById('F14-g').value; + const F0 = 5; + /* m·x'' = -kx - γ·v + F0·cos(ωt) */ + const N = 8; + const ddt = dt / N; + for (let i = 0; i < N; i++){ + const F = F0 * Math.cos(omega_ext * st.t); + const a = (-k*st.x - gamma*st.v + F) / m; + st.v += a * ddt; + st.x += st.v * ddt; + st.t += ddt; + } + /* записываем амплитуду */ + st.ampHistory.push({ t: st.t, x: st.x }); + if (st.ampHistory.length > 800) st.ampHistory.shift(); + /* текущая амплитуда — максимум за последние 2 с */ + let amp = 0; + for (const h of st.ampHistory){ + if (st.t - h.t < 5) amp = Math.max(amp, Math.abs(h.x)); + } + document.getElementById('F14-A').textContent = amp.toFixed(3) + ' м'; + /* классификация */ + const nu0 = nuOwn(); + const nuExt = +document.getElementById('F14-f').value; + const mode = document.getElementById('F14-mode'); + const fb = document.getElementById('F14-fb'); + if (Math.abs(nu0 - nuExt) / nu0 < 0.08){ + mode.textContent = 'РЕЗОНАНС!'; + mode.style.color = 'var(--fail,#dc2626)'; + fb.className = 'flag-feedback fail show'; + fb.innerHTML = '⚠ РЕЗОНАНС! Амплитуда нарастает. Так разрушаются мосты — рота не должна маршировать через них в ногу.'; + } else if (Math.abs(nu0 - nuExt) / nu0 < 0.25){ + mode.textContent = 'близко к резонансу'; + mode.style.color = 'var(--warn,#f59e0b)'; + fb.className = 'flag-feedback warn show'; + fb.innerHTML = 'Близко к резонансу — амплитуда заметно больше внешней силы.'; + } else { + mode.textContent = 'вынужденные колебания'; + mode.style.color = 'var(--ok,#10b981)'; + fb.className = 'flag-feedback'; + } + draw(); + } + + function draw(){ + const col = C(); + ctx.fillStyle = col.bg || '#fafafa'; + ctx.fillRect(0, 0, W, H); + /* левая половина — пружина с грузом */ + /* потолок */ + ctx.fillStyle = col.surface || '#a16207'; + ctx.fillRect(cx - 60, 30, 120, 14); + /* пружина */ + const massY = 160 + st.x * 400; + ctx.strokeStyle = col.forceSpring || '#d97706'; + ctx.lineWidth = 2.5; + ctx.beginPath(); + ctx.moveTo(cx, 44); + for (let i = 0; i < 14; i++){ + const t = i / 14; + const y = 44 + t * (massY - 44); + const x = cx + Math.sin(t * 14 * Math.PI) * 12; + ctx.lineTo(x, y); + } + ctx.lineTo(cx, massY); + ctx.stroke(); + /* груз */ + ctx.fillStyle = col.forceGravity || '#2563eb'; + ctx.fillRect(cx - 25, massY, 50, 30); + ctx.strokeStyle = col.bodyAccent || '#1e293b'; + ctx.strokeRect(cx - 25, massY, 50, 30); + /* нулевая линия */ + ctx.strokeStyle = col.grid || '#e5e7eb'; + ctx.setLineDash([4, 4]); + ctx.beginPath(); + ctx.moveTo(cx - 60, 160); ctx.lineTo(cx + 60, 160); + ctx.stroke(); + ctx.setLineDash([]); + /* стрелка внешней силы */ + const F_now = 5 * Math.cos(2*Math.PI*(+document.getElementById('F14-f').value) * st.t); + if (st.running){ + B().arrow(ctx, cx + 35, massY + 15, cx + 35 + F_now*8, massY + 15, col.acceleration || '#ea580c', 2); + } + /* правая половина — график x(t) */ + const gx = W/2 + 20, gy = 40, gw = W/2 - 40, gh = H - 90; + ctx.fillStyle = col.bgSubtle || '#f8fafc'; + ctx.fillRect(gx, gy, gw, gh); + ctx.strokeStyle = col.axis || '#1e293b'; + ctx.lineWidth = 1.5; + ctx.strokeRect(gx, gy, gw, gh); + /* центральная ось */ + ctx.strokeStyle = col.grid || '#e5e7eb'; + ctx.beginPath(); ctx.moveTo(gx, gy + gh/2); ctx.lineTo(gx + gw, gy + gh/2); ctx.stroke(); + /* линия x(t) */ + if (st.ampHistory.length > 1){ + const tMin = Math.max(0, st.t - 20); + const tMax = st.t; + let maxAbsX = 0.1; + for (const h of st.ampHistory) if (h.t >= tMin) maxAbsX = Math.max(maxAbsX, Math.abs(h.x)); + ctx.strokeStyle = col.velocity || '#0891b2'; + ctx.lineWidth = 2; + ctx.beginPath(); + let first = true; + for (const h of st.ampHistory){ + if (h.t < tMin) continue; + const px = gx + ((h.t - tMin)/(tMax - tMin)) * gw; + const py = gy + gh/2 - (h.x / maxAbsX) * (gh/2 - 5); + if (first){ ctx.moveTo(px, py); first = false; } else ctx.lineTo(px, py); + } + ctx.stroke(); + } + ctx.fillStyle = col.textMuted || '#64748b'; + ctx.font = '11px Inter,sans-serif'; + ctx.fillText('x(t) — последние 20 с', gx + 6, gy + 14); + ctx.fillText('t →', gx + gw - 24, gy + gh - 4); + } + + document.getElementById('F14-go').addEventListener('click', () => { + st.running = !st.running; + document.getElementById('F14-go').textContent = st.running ? 'Пауза' : 'Запустить'; + }); + document.getElementById('F14-reset').addEventListener('click', reset); + document.getElementById('F14-tune').addEventListener('click', () => { + document.getElementById('F14-f').value = nuOwn().toFixed(2); + update(); + reset(); + }); + ['F14-m','F14-k','F14-f','F14-g'].forEach(id => document.getElementById(id).addEventListener('input', update)); + + update(); + reset(); + B().startLoop('F14', cv, tick); + return true; +} + +if (window.PHYS9_FLAG_BASE) window.PHYS9_FLAG_BASE.register('F14', { init: init, cleanup: function(){} }); +else document.addEventListener('DOMContentLoaded', ()=>{ + if (window.PHYS9_FLAG_BASE) window.PHYS9_FLAG_BASE.register('F14', { init: init, cleanup: function(){} }); +}); + +})(); diff --git a/frontend/js/flagships/phys9_flag_F6_road.js b/frontend/js/flagships/phys9_flag_F6_road.js new file mode 100644 index 0000000..602a102 --- /dev/null +++ b/frontend/js/flagships/phys9_flag_F6_road.js @@ -0,0 +1,167 @@ +// F6. Симулятор скоростной дороги (§20 в ch2) — μ и тормозной путь. +(function(){ +'use strict'; +const B = () => window.PHYS9_FLAG_BASE; +const C = () => window.PHYS9_COLORS || {}; + +const SURFACES = { + asphalt_dry: { mu: 0.7, name: 'асфальт сухой', col: '#1e293b' }, + asphalt_wet: { mu: 0.4, name: 'асфальт мокрый', col: '#475569' }, + gravel: { mu: 0.55, name: 'гравий', col: '#92400e' }, + snow: { mu: 0.2, name: 'снег', col: '#cbd5e1' }, + ice: { mu: 0.08, name: 'лёд', col: '#bfdbfe' } +}; + +function init(secId){ + if (!B()) return false; + let surfBtns = ''; + for (const id in SURFACES){ + const s = SURFACES[id]; + surfBtns += ''; + } + const body = '' + + '
'+surfBtns+'
' + + '
' + + '' + + '
' + + '' + + '
' + + '' + + '' + + '
' + + '
' + + '
Покрытиесухой асфальт
' + + '
μ0.7
' + + '
Тормозной путь20.4 м
' + + '
Время торможения2.43 с
' + + '
' + + '
'; + + const card = B().makeCard(secId, + 'F6. Симулятор скоростной дороги', + 'Выбери покрытие и скорость. При торможении: $s = v^2/(2\\mu g)$. На льду путь в 8 раз длиннее!', + body); + if (!card) return false; + + const cv = document.getElementById('F6-cv'); + const ctx = cv.getContext('2d'); + const W = cv.width, H = cv.height; + let surf = 'asphalt_dry'; + let st = { x: 50, v: 0, vTarget: 60/3.6, mode: 'cruise' }; + + function update(){ + const v_kmh = +document.getElementById('F6-v').value; + document.getElementById('F6-vv').textContent = v_kmh; + st.vTarget = v_kmh / 3.6; + const mu = SURFACES[surf].mu; + const v = st.vTarget; + const sStop = v*v / (2 * mu * 9.8); + const tStop = v / (mu * 9.8); + document.getElementById('F6-surf').textContent = SURFACES[surf].name; + document.getElementById('F6-mu').textContent = mu; + document.getElementById('F6-stop').textContent = sStop.toFixed(1) + ' м'; + document.getElementById('F6-tstop').textContent = tStop.toFixed(2) + ' с'; + } + + function reset(){ + st = { x: 50, v: st.vTarget, mode: 'cruise' }; + document.getElementById('F6-fb').className = 'flag-feedback'; + draw(); + } + + function tick(dt){ + const mu = SURFACES[surf].mu; + if (st.mode === 'cruise'){ + st.v = st.vTarget; + st.x += st.v * dt * 5; /* 5 px = 1 м */ + if (st.x > W + 50) st.x = -20; + } else if (st.mode === 'brake'){ + st.v -= mu * 9.8 * dt; + if (st.v < 0){ st.v = 0; st.mode = 'stopped'; } + st.x += st.v * dt * 5; + } + draw(); + } + + function draw(){ + const col = C(); + ctx.fillStyle = col.bg || '#fafafa'; + ctx.fillRect(0, 0, W, H); + /* небо */ + ctx.fillStyle = col.gas || '#dbeafe'; + ctx.fillRect(0, 0, W, 80); + /* дорога */ + const s = SURFACES[surf]; + ctx.fillStyle = s.col; + ctx.fillRect(0, 80, W, 80); + /* разметка */ + ctx.strokeStyle = '#fff'; + ctx.lineWidth = 3; + ctx.setLineDash([24, 16]); + ctx.beginPath(); + ctx.moveTo(0, 120); ctx.lineTo(W, 120); + ctx.stroke(); + ctx.setLineDash([]); + /* шкала метров */ + ctx.fillStyle = col.text || '#0f172a'; + ctx.font = '11px Inter,sans-serif'; + for (let m = 0; m <= 140; m += 10){ + const px = 50 + m*5; + if (px > W) break; + ctx.fillRect(px-1, 160, 2, 6); + if (m % 20 === 0) ctx.fillText(m + ' м', px - 8, 178); + } + /* трава */ + ctx.fillStyle = '#16a34a'; + ctx.fillRect(0, 180, W, H - 180); + /* машина */ + ctx.fillStyle = col.fail || '#dc2626'; + ctx.fillRect(st.x - 25, 95, 50, 22); + ctx.fillRect(st.x - 18, 88, 36, 9); + ctx.fillStyle = '#0f172a'; + ctx.fillRect(st.x - 16, 117, 8, 8); + ctx.fillRect(st.x + 8, 117, 8, 8); + /* подпись */ + ctx.fillStyle = col.text || '#0f172a'; + ctx.font = 'bold 13px Inter,sans-serif'; + ctx.fillText((st.v*3.6).toFixed(0) + ' км/ч', st.x - 22, 78); + /* shadow */ + ctx.fillStyle = 'rgba(0,0,0,0.3)'; + ctx.fillRect(st.x - 25, 130, 50, 4); + } + + card.querySelectorAll('[data-surf]').forEach(btn => { + btn.addEventListener('click', () => { + surf = btn.dataset.surf; + card.querySelectorAll('[data-surf]').forEach(b => b.classList.remove('primary')); + btn.classList.add('primary'); + update(); + reset(); + }); + }); + document.getElementById('F6-v').addEventListener('input', () => { update(); if(st.mode==='cruise') st.v = st.vTarget; }); + document.getElementById('F6-brake').addEventListener('click', () => { + if (st.mode === 'cruise'){ + st.mode = 'brake'; + const fb = document.getElementById('F6-fb'); + const mu = SURFACES[surf].mu; + const v = st.v; + const sStop = v*v / (2 * mu * 9.8); + fb.className = 'flag-feedback warn show'; + fb.innerHTML = 'Торможение на ' + SURFACES[surf].name + ' с ' + (v*3.6).toFixed(0) + ' км/ч — потребуется ' + sStop.toFixed(1) + ' м.'; + } + }); + document.getElementById('F6-reset').addEventListener('click', reset); + + update(); + reset(); + B().startLoop('F6', cv, tick); + return true; +} + +if (window.PHYS9_FLAG_BASE) window.PHYS9_FLAG_BASE.register('F6', { init: init, cleanup: function(){} }); +else document.addEventListener('DOMContentLoaded', ()=>{ + if (window.PHYS9_FLAG_BASE) window.PHYS9_FLAG_BASE.register('F6', { init: init, cleanup: function(){} }); +}); + +})(); diff --git a/frontend/textbooks/physics_9_ch2.html b/frontend/textbooks/physics_9_ch2.html index 5d38daa..ca123cd 100644 --- a/frontend/textbooks/physics_9_ch2.html +++ b/frontend/textbooks/physics_9_ch2.html @@ -790,7 +790,7 @@ function _injectTasks(id){ var body = document.getElementById(id + '-body'); if(!body || body.querySelector('.legacy-tasks')) return; body.insertAdjacentHTML('beforeend', _makeTaskBlock(id)); - setTimeout(function(){ try { if(window.renderTask) window.renderTask(id); if(window.renderNav) window.renderNav(id); } catch(e){} try { if(window.PHYS9_FINALS_INIT && /^final\d+$/.test(id)) window.PHYS9_FINALS_INIT(id); } catch(e){ console.warn("phys9 final init:", e.message); } try { if(window.PHYS9_CH2_WIDGETS && window.PHYS9_CH2_WIDGETS[id]) window.PHYS9_CH2_WIDGETS[id](); } catch(e){ console.warn('phys9 widget init:', e.message); } try { if(window.PHYS9_FLAG_BASE){ if(id==='p17') window.PHYS9_FLAG_BASE.mount('F4','p17'); else if(id==='p22') window.PHYS9_FLAG_BASE.mount('F5','p22'); else if(id==='p24') window.PHYS9_FLAG_BASE.mount('F7','p24'); } } catch(e){ console.warn('phys9 flag init:', e.message); } }, 60); + setTimeout(function(){ try { if(window.renderTask) window.renderTask(id); if(window.renderNav) window.renderNav(id); } catch(e){} try { if(window.PHYS9_FINALS_INIT && /^final\d+$/.test(id)) window.PHYS9_FINALS_INIT(id); } catch(e){ console.warn("phys9 final init:", e.message); } try { if(window.PHYS9_CH2_WIDGETS && window.PHYS9_CH2_WIDGETS[id]) window.PHYS9_CH2_WIDGETS[id](); } catch(e){ console.warn('phys9 widget init:', e.message); } try { if(window.PHYS9_FLAG_BASE){ if(id==='p17') window.PHYS9_FLAG_BASE.mount('F4','p17'); else if(id==='p22') window.PHYS9_FLAG_BASE.mount('F5','p22'); else if(id==='p24') window.PHYS9_FLAG_BASE.mount('F7','p24'); else if(id==='p20') window.PHYS9_FLAG_BASE.mount('F6','p20'); } } catch(e){ console.warn('phys9 flag init:', e.message); } }, 60); } var _origEnsureBuilt = ensureBuilt; ensureBuilt = function(id){ _origEnsureBuilt(id); _injectTasks(id); }; diff --git a/frontend/textbooks/physics_9_ch4.html b/frontend/textbooks/physics_9_ch4.html index 14e12a7..62e5fe9 100644 --- a/frontend/textbooks/physics_9_ch4.html +++ b/frontend/textbooks/physics_9_ch4.html @@ -774,7 +774,7 @@ function _injectTasks(id){ var body = document.getElementById(id + '-body'); if(!body || body.querySelector('.legacy-tasks')) return; body.insertAdjacentHTML('beforeend', _makeTaskBlock(id)); - setTimeout(function(){ try { if(window.renderTask) window.renderTask(id); if(window.renderNav) window.renderNav(id); } catch(e){} try { if(window.PHYS9_FINALS_INIT && /^final\d+$/.test(id)) window.PHYS9_FINALS_INIT(id); } catch(e){ console.warn("phys9 final init:", e.message); } try { if(window.PHYS9_CH4_WIDGETS && window.PHYS9_CH4_WIDGETS[id]) window.PHYS9_CH4_WIDGETS[id](); } catch(e){ console.warn('phys9 widget init:', e.message); } try { if(window.PHYS9_FLAG_BASE){ if(id==='p35') window.PHYS9_FLAG_BASE.mount('F12','p35'); else if(id==='p32') window.PHYS9_FLAG_BASE.mount('F11','p32'); else if(id==='final4') window.PHYS9_FLAG_BASE.mount('F19','final4'); } } catch(e){ console.warn('phys9 flag init:', e.message); } }, 60); + setTimeout(function(){ try { if(window.renderTask) window.renderTask(id); if(window.renderNav) window.renderNav(id); } catch(e){} try { if(window.PHYS9_FINALS_INIT && /^final\d+$/.test(id)) window.PHYS9_FINALS_INIT(id); } catch(e){ console.warn("phys9 final init:", e.message); } try { if(window.PHYS9_CH4_WIDGETS && window.PHYS9_CH4_WIDGETS[id]) window.PHYS9_CH4_WIDGETS[id](); } catch(e){ console.warn('phys9 widget init:', e.message); } try { if(window.PHYS9_FLAG_BASE){ if(id==='p35') window.PHYS9_FLAG_BASE.mount('F12','p35'); else if(id==='p32') window.PHYS9_FLAG_BASE.mount('F11','p32'); else if(id==='final4') window.PHYS9_FLAG_BASE.mount('F19','final4'); else if(id==='p36'){ window.PHYS9_FLAG_BASE.mount('F13','p36'); window.PHYS9_FLAG_BASE.mount('F14','p36'); } } } catch(e){ console.warn('phys9 flag init:', e.message); } }, 60); } var _origEnsureBuilt = ensureBuilt; ensureBuilt = function(id){ _origEnsureBuilt(id); _injectTasks(id); };