5381679c68
Зафиксирована накопленная незакоммиченная работа рабочего дерева, КРОМЕ файлов учебника «Химия 7» (migration 046, chemistry_7_*.html, chem7_svg.js, тест — оставлены незакоммиченными по запросу). Включает: модуль биохимии (ядро BIO, 3D VSEPR, химдвижок, баланс, challenges, пути из БД), System Health Level 1 (вердикт/мониторинг), а также frontend- страницы и lab/textbooks-правки параллельной сессии. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
92 lines
4.3 KiB
Python
92 lines
4.3 KiB
Python
import sys, os
|
|
|
|
src = os.path.join(os.path.dirname(__file__), '../../frontend/js/labs/opticsbench.js')
|
|
|
|
with open(src, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
# PATCH: Insert new glue functions after lensPreset, before _lensUpdateUI
|
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
MARKER = 'function _lensUpdateUI(info) {'
|
|
|
|
idx = content.find(MARKER)
|
|
if idx == -1:
|
|
print('ERROR: _lensUpdateUI not found'); sys.exit(1)
|
|
|
|
NEW_FUNCS = (
|
|
'/* ── Lens animated ray + LM controls (Feature 1 & 3) ── */\n'
|
|
'function lensToggleLM(on) {\n'
|
|
' const sliders = document.getElementById(\'ob-lm-sliders\');\n'
|
|
' const fRow = document.querySelector(\'#ob-ctrl-lens .proj-slider-row\');\n'
|
|
' if (sliders) sliders.style.display = on ? \'\' : \'none\';\n'
|
|
' // hide/show simple f slider\n'
|
|
' const fSlRow = document.getElementById(\'sl-lens-f\');\n'
|
|
' if (fSlRow && fSlRow.parentElement) fSlRow.parentElement.style.display = on ? \'none\' : \'\';\n'
|
|
' if (lensSim) lensSim.setLensMode(!on);\n'
|
|
' if (on && lensSim) {\n'
|
|
' // sync sliders to current LM params\n'
|
|
' const r1 = lensSim._lmR1, r2 = lensSim._lmR2, n = lensSim._lmN;\n'
|
|
' const s1 = document.getElementById(\'sl-lm-r1\'), l1 = document.getElementById(\'lm-r1-val\');\n'
|
|
' const s2 = document.getElementById(\'sl-lm-r2\'), l2 = document.getElementById(\'lm-r2-val\');\n'
|
|
' const sn = document.getElementById(\'sl-lm-n\'), ln = document.getElementById(\'lm-n-val\');\n'
|
|
' if (s1) s1.value = r1; if (l1) l1.textContent = r1.toFixed(0);\n'
|
|
' if (s2) s2.value = r2; if (l2) l2.textContent = r2.toFixed(0);\n'
|
|
' if (sn) sn.value = n; if (ln) ln.textContent = n.toFixed(2);\n'
|
|
' }\n'
|
|
'}\n'
|
|
'\n'
|
|
'function lensLMParam(name, val) {\n'
|
|
' const v = parseFloat(val);\n'
|
|
' const lblMap = { R1: \'lm-r1-val\', R2: \'lm-r2-val\', n: \'lm-n-val\' };\n'
|
|
' const el = document.getElementById(lblMap[name]);\n'
|
|
' if (el) el.textContent = name === \'n\' ? v.toFixed(2) : v.toFixed(0);\n'
|
|
' if (lensSim) {\n'
|
|
' lensSim.setLMParam(name, v);\n'
|
|
' // update f display\n'
|
|
' const fl = document.getElementById(\'lens-f-val\');\n'
|
|
' if (fl) fl.textContent = lensSim.f.toFixed(0);\n'
|
|
' }\n'
|
|
'}\n'
|
|
'\n'
|
|
'/* ── Mirror R-slider + parabolic controls (Feature 2) ── */\n'
|
|
'function mirrorToggleR(on) {\n'
|
|
' const rRow = document.getElementById(\'ob-mirror-R-row\');\n'
|
|
' if (rRow) rRow.style.display = on ? \'\' : \'none\';\n'
|
|
' const pbtn = document.getElementById(\'mirror-parab-btn\');\n'
|
|
' if (pbtn) pbtn.style.display = on ? \'\' : \'none\';\n'
|
|
' if (mirrorSim) mirrorSim._useR = !!on;\n'
|
|
' if (on && mirrorSim) {\n'
|
|
' const sv = document.getElementById(\'sl-mirror-R\');\n'
|
|
' const lv = document.getElementById(\'mirror-R-val\');\n'
|
|
' if (sv) sv.value = mirrorSim._R;\n'
|
|
' if (lv) lv.textContent = mirrorSim._R;\n'
|
|
' mirrorSim.setMirrorR(mirrorSim._R);\n'
|
|
' } else if (mirrorSim) { mirrorSim.draw(); }\n'
|
|
'}\n'
|
|
'\n'
|
|
'function mirrorRParam(val) {\n'
|
|
' const v = parseFloat(val);\n'
|
|
' const el = document.getElementById(\'mirror-R-val\');\n'
|
|
' if (el) el.textContent = v;\n'
|
|
' if (mirrorSim) mirrorSim.setMirrorR(v);\n'
|
|
'}\n'
|
|
'\n'
|
|
'function mirrorToggleParabolic(btn) {\n'
|
|
' if (!mirrorSim) return;\n'
|
|
' mirrorSim._parabolic = !mirrorSim._parabolic;\n'
|
|
' if (btn) btn.textContent = mirrorSim._parabolic ? \'Параболическое\' : \'Сферическое\';\n'
|
|
' if (btn) btn.style.color = mirrorSim._parabolic ? \'#7BF5A4\' : \'#888\';\n'
|
|
' mirrorSim.draw();\n'
|
|
'}\n'
|
|
'\n'
|
|
)
|
|
|
|
new_content = content[:idx] + NEW_FUNCS + content[idx:]
|
|
|
|
with open(src, 'w', encoding='utf-8') as f:
|
|
f.write(new_content)
|
|
|
|
print('OK lines:', new_content.count('\n'))
|