'use strict'; /* admin → sims (simulations) section */ (function () { 'use strict'; let inited = false; // Full list of available (non-null id) sims mirrored from /lab const ADMIN_SIMS = [ { id: 'graph', cat: 'Математика', title: 'График функции' }, { id: 'graphtransform', cat: 'Математика', title: 'Трансформации графиков' }, { id: 'geometry', cat: 'Математика', title: 'Планиметрия' }, { id: 'triangle', cat: 'Математика', title: 'Геометрия треугольника' }, { id: 'quadratic', cat: 'Математика', title: 'Корни квадратного уравнения' }, { id: 'stereo', cat: 'Математика', title: 'Стереометрия 3D' }, { id: 'probability', cat: 'Математика', title: 'Теория вероятностей' }, { id: 'trigcircle', cat: 'Математика', title: 'Тригонометрическая окружность' }, { id: 'normaldist', cat: 'Математика', title: 'Нормальное распределение' }, { id: 'projectile', cat: 'Физика', title: 'Бросок тела' }, { id: 'pendulum', cat: 'Физика', title: 'Маятник' }, { id: 'collision', cat: 'Физика', title: 'Столкновение шаров' }, { id: 'emfield', cat: 'Физика', title: 'Электромагнитные поля' }, { id: 'circuit', cat: 'Физика', title: 'Электрические цепи' }, { id: 'hydrostatics', cat: 'Физика', title: 'Гидростатика' }, { id: 'dynamics', cat: 'Физика', title: 'Динамика' }, { id: 'opticsbench', cat: 'Физика', title: 'Оптическая скамья' }, { id: 'isoprocess', cat: 'Физика', title: 'Изопроцессы' }, { id: 'waves', cat: 'Физика', title: 'Волны и звук' }, { id: 'heatengine', cat: 'Физика', title: 'Тепловые двигатели' }, { id: 'radioactive', cat: 'Физика', title: 'Радиоактивный распад' }, { id: 'race', cat: 'Физика', title: 'Гонка с задачами' }, { id: 'logic', cat: 'Физика', title: 'Логические схемы' }, { id: 'molphys', cat: 'Химия', title: 'Молекулярная физика' }, { id: 'chemistry', cat: 'Химия', title: 'Химические реакции' }, { id: 'equilibrium', cat: 'Химия', title: 'Химическое равновесие' }, { id: 'electrolysis', cat: 'Химия', title: 'Электролиз' }, { id: 'bohratom', cat: 'Химия', title: 'Атом Бора' }, { id: 'orbitals', cat: 'Химия', title: 'Молекулярные орбитали' }, { id: 'titration', cat: 'Химия', title: 'pH и кривая титрования' }, { id: 'chemsandbox', cat: 'Химия', title: 'Химическая песочница' }, { id: 'stoichiometry', cat: 'Химия', title: 'Стехиометрия' }, { id: 'crystal', cat: 'Химия', title: 'Кристаллическая решётка' }, { id: 'qualanalysis', cat: 'Химия', title: 'Качественный анализ' }, { id: 'periodic', cat: 'Химия', title: 'Периодическая таблица' }, { id: 'organic', cat: 'Химия', title: 'Органическая химия' }, { id: 'solutions', cat: 'Химия', title: 'Растворы' }, { id: 'celldivision', cat: 'Биология', title: 'Деление клетки' }, { id: 'photosynthesis', cat: 'Биология', title: 'Фотосинтез и дыхание' }, { id: 'angrybirds', cat: 'Игры', title: 'Angry Birds Physics' }, ]; let _simsSettings = { module_disabled: false, disabled_ids: [] }; async function load() { try { const data = await LS.api('/api/settings/sims'); _simsSettings = data; _render(); } catch(e) { LS.toast('Ошибка загрузки настроек: ' + e.message, 'error'); } } function _render() { // master toggle const masterChk = document.getElementById('sims-master-chk'); if (masterChk) masterChk.checked = !_simsSettings.module_disabled; // per-sim cards const grid = document.getElementById('sims-grid'); const dis = new Set(_simsSettings.disabled_ids || []); // group by category const byCat = {}; ADMIN_SIMS.forEach(s => { (byCat[s.cat] = byCat[s.cat] || []).push(s); }); let html = ''; Object.entries(byCat).forEach(([cat, sims]) => { html += `
${esc(cat)}
`; sims.forEach(s => { const enabled = !dis.has(s.id); html += `
${esc(s.title)}
${esc(s.id)}
`; }); }); grid.innerHTML = html; if (window.lucide) lucide.createIcons(); } async function simsMasterToggle(checked) { try { await LS.api('/api/settings/sims', { method: 'PUT', body: JSON.stringify({ module_disabled: !checked }) }); _simsSettings.module_disabled = !checked; LS.toast(checked ? 'Модуль симуляций включён' : 'Модуль симуляций отключён', checked ? 'success' : 'warning'); } catch(e) { LS.toast('Ошибка: ' + e.message, 'error'); } } async function simToggleOne(simId, enabled) { const dis = new Set(_simsSettings.disabled_ids || []); if (enabled) dis.delete(simId); else dis.add(simId); const disabled_ids = [...dis]; try { await LS.api('/api/settings/sims', { method: 'PUT', body: JSON.stringify({ disabled_ids }) }); _simsSettings.disabled_ids = disabled_ids; const card = document.getElementById('simcard-' + simId); if (card) card.classList.toggle('enabled', enabled); LS.toast(enabled ? `«${simId}» включена` : `«${simId}» отключена`, enabled ? 'success' : 'warning'); } catch(e) { LS.toast('Ошибка: ' + e.message, 'error'); } } window.simsMasterToggle = simsMasterToggle; window.simToggleOne = simToggleOne; window.AdminSections = window.AdminSections || {}; window.AdminSections.sims = { init: async () => { if (inited) return; inited = true; await load(); }, reload: load, }; })();