Commit Graph

59 Commits

Author SHA1 Message Date
Maxim Dolgolyov 28db2de74f feat(labs): Фаза0 — эконом-режим FX + выбор симуляции из списка в редакторе
План улучшения симуляций — plans/simulations-improvement/README.md.
- LabFX: reduced-motion/эконом-режим (prefers-reduced-motion + тумблер
  localStorage labfx-economy). Тряска отключается, частицы ×0.25 — доступность
  и экономия на слабых устройствах сразу для всех ~50 симуляций. Кнопка-тумблер
  в lab.html рядом со звуком.
- lesson-editor: блок «Симуляция» — выпадающий список из /api/lab/sims
  (сгруппирован по предметам) вместо сырого ввода simId; неизвестный id не
  теряется, помечается «(не найдена)». Закрывает хрупкую вставку в урок.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 10:33:50 +03:00
Maxim Dolgolyov 5b103ab606 refactor(lab): превью симуляций вынесены в общий lab-previews.js (единый источник)
~45 SVG-превью (P_*) и хелперы _grid/_axes/_svg вынесены из lab-glue.js в
общий /js/lab-previews.js: window.LabPreviews (карта id→SVG, 40 симуляций) +
window.__LabP (по имени, lab-glue берёт алиасы оттуда). SIMS не тронут.
lab.html подключает lab-previews.js перед lab-glue.js. Теперь дашборд берёт
настоящие превью симуляций из того же источника → «Лаборатория дня» крутит
весь каталог, а не 6 захардкоженных. Дублирование 6 превью устранено.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 09:34:29 +03:00
Maxim Dolgolyov fc1139f51d feat(lab-content-engine): phase 3 - ленивая загрузка кода симуляций
Старт /lab грузит только каркас (~530KB) вместо ~2.9MB + three.js(~600KB):
- _loader.js — LabLoader.ensure(id): грузит файлы симуляции по манифесту +
  three.js при необходимости; кеш по URL; САМОВОССТАНОВЛЕНИЕ (если open-функция
  не определена после загрузки — грузит все ленивые файлы -> корректность
  гарантирована независимо от точности манифеста)
- _sim_deps.js — сгенерированный манифест SIM_DEPS{id:{open,files,three}} +
  LAB_LAZY_FILES; three:true только для crystal/orbitals/stereo/periodic
- _register-all.js — open-обёртка: LabLoader.ensure(id).then(rawOpen)
- lab-init.js openSim — обработка Promise от open() (lucide после init)
- lab.html — убраны 45 ленивых <script> + three.js из eager; каркас: registry,
  loader, sim_deps, fx-движки, общие визуалы, graph.js (GRID для 15 сим)

Проверка: vm-harness (per-sim load, three only 3D, кеш, self-heal) ALL PASS;
инвариант owner-in-files для всех 40; нет утечки ленивых в eager; node --check OK.
В БРАУЗЕРЕ НЕ ПРОВЕРЕНО.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 15:02:29 +03:00
Maxim Dolgolyov 3f99d1b62f feat(lab-content-engine): phase 2 - вынос тел симуляций в labs-bodies.html
- 40 тел симуляций (~4420 строк) вынесены из lab.html в frontend/labs-bodies.html
- lab.html: 4880 -> 484 строк; тела заменены на #sim-bodies-host + синхронная
  инъекция (XHR sync во время парсинга -> тела присутствуют до DOMContentLoaded,
  сохраняя обработчики geometry.js и порядок инициализации)
- ctrl-бары и theory-panel ОСТАЮТСЯ в lab.html (в topbar)
- partial раздаётся существующим static middleware (frontendDir)

Гарантии: реконструкция before+region+after == оригинал побайтово;
id-мультимножество (newLab без host + partial) == оригинал; 40 sim-body div;
node --check glue/init OK. В БРАУЗЕРЕ НЕ ПРОВЕРЕНО (нужна ручная проверка).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 14:23:10 +03:00
Maxim Dolgolyov 81d4c15442 feat(opticsbench): учебное построение характеристических лучей
Для «Предмет» + «Характ. лучи» (один предмет, одна линза):
- подписи лучей 1/2/3 у предмета
- точка изображения = пересечение финальных отрезков лучей 1 и 2
- стрелка-изображение (основание на оси → вершина в точке изображения)
- мнимое изображение: пунктирные продления расходящихся лучей назад к
  мнимой точке (слева от линзы); подпись «изображение»/«мнимое изобр.»
- проверено численно: предмет за 2F → реальное справа, внутри F → мнимое слева
- bump opticsbench.js?v=10

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:33:46 +03:00
Maxim Dolgolyov 6a3d1e04d0 feat(opticsbench): режим лучей предмета — характеристические vs пучок
- источник «Предмет»: тумблер «Характ. лучи» (по умолчанию) / «Пучок»
- характеристические: 3 луча от вершины (параллельный→F', через центр,
  через F→параллельно) + осевой от основания — как в учебнике; проверено
  численно (F'=lensX+f, центр прямо, через F выход параллелен)
- пучок: прежний физичный веер + ползунок «Лучей» (густота) и «Раствор»
- setSource: rayMode как строковый ключ; bump opticsbench.js?v=9

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:28:15 +03:00
Maxim Dolgolyov a97896d293 fix(opticsbench): источник — вертикальное положение + фикс плавающего FX
- источник можно двигать по вертикали: слайдер «Положение ↕» (для любого
  типа) + вертикальное перетаскивание; эмиссия/отрисовка/хит-тест через _sy()
- фикс бага: FX-вспышка рисовалась на ay−source.h даже для точечного
  источника (h оставалась 70) → «звезда» улетала вверх; теперь FX привязан
  к реальной точке источника (поднятая вершина только у стрелки-предмета)
- object «Высота» → «Размер стрелки» (чтобы не путать с вертик. положением)
- bump opticsbench.js?v=8

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:21:30 +03:00
Maxim Dolgolyov bb58141c76 fix(opticsbench): полный конструктор (Фаза 4) на feature-ветке + чип «Источник»
Ветка feature/lab-content-engine отделилась до Фазы 4 оптики, из-за чего
кнопки «+ Граница/+ Пластина» были без логики. Принёс полную Фазу 4
opticsbench.js с master (граница сред со Снеллиусом/ПВО, пластина, источники
луч/лазер, отсечение апертурой, F/2F, числовые слайдеры) и заново наложил
фикс выбора источника: постоянный чип «Источник» + выбор по умолчанию.
bump opticsbench.js?v=7

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:08:12 +03:00
Maxim Dolgolyov 0888a707cc fix(lab-content-engine): phase 0 - устранены 3 блокера ревью
- подключён _registry.js в lab.html (был отсутствует -> LabRegistry был undefined)
- регистрация 3 пилотов в _pilots.js (graph/quadratic/pendulum), подключён последним
- loadTheory (lab-glue.js) адаптирован: реестр в приоритете, иначе THEORY

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:04:39 +03:00
Maxim Dolgolyov dfce94fbf7 fix(opticsbench): постоянный чип «Источник» + восстановлены кнопки Граница/Пластина
- выбор источника теперь всегда доступен: чип «Источник» в списке схемы
  (раньше — только кликом по точке на холсте); источник выбран по умолчанию
- восстановлены потерянные кнопки палитры «+ Граница» / «+ Пластина»
- bump opticsbench.js?v=6

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:00:42 +03:00
Maxim Dolgolyov 1c7d8e9d95 feat(opticsbench): конструктор Фаза 3 — изображение на экране + экспорт PNG
- _drawScreenHits: светящиеся пятна (additive) в точках попадания лучей на
  экран, по длине волны — видно формирование изображения и спектр
- benchExportPng + кнопка «Снимок PNG»; подсказка про λ/белый свет
- bump opticsbench.js?v=4

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:40:37 +03:00
Maxim Dolgolyov 353a6cb8a9 feat(opticsbench): конструктор Фаза 2 — призма со Снеллиусом и дисперсией
- _prismInteract: тонкопризменное отклонение δ=(n−1)·A к основанию +
  хроматическая дисперсия n(λ) через _nAtWavelength
- белый свет: пучки по OB_SPECTRAL, каждый луч красится по длине волны
  (до призмы совпадают, после — расходятся в спектр); управление общим λ-баром
- _obRedraw для freebuild переключён на benchSim (был freeSim)
- сферические зеркала уже из Фазы 1; проверено численно (фиолет>красный)
- bump opticsbench.js?v=3

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:38:40 +03:00
Maxim Dolgolyov 832efc0907 feat(opticsbench): конструктор оптических систем — Фаза 1 (общий трассировщик)
Режим «Цепочка линз» → «Конструктор» на базе нового класса BenchSim:
- общий 2D-трассировщик: линза, зеркало (плоск./вогн./выпукл.), диафрагма,
  экран; источники предмет/точка/параллель; лимит отражений
- фокус линзы в x+f и терминация зеркала проверены численно
- динамический инспектор: палитра элементов, список схемы, свойства
  выбранного, удаление; слайдеры перерисовывают только холст (не ломают drag)
- pointer-слушатели на canvas (capture, dispose), выбор/перетаскивание
- пресеты: микроскоп/телескоп/проектор/зеркальная; сохранение состояния
  в снимок (_obGetState/_obApplyState); bump opticsbench.js?v=2
- призма — пока грубый placeholder (Снеллиус/дисперсия в Фазе 2)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 12:35:41 +03:00
Maxim Dolgolyov d63f6eec67 fix(stereo3d): ревью метода следов — центрирование следа, фикс скрытия сечения
- _traceLine: p0 = основание перпендикуляра из начала координат (след
  рисуется у фигуры, а не у далёкого пересечения с осью)
- фикс: после сброса/смены фигуры в пошаговом режиме step мог стать 0 →
  сечение скрыто и шаги не рисуются; нормализация step≥1 в _drawSection3P
- подпись шага обновляется сразу после 3-го клика (в step-режиме)
- bump stereo.js?v=10

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:54:32 +03:00
Maxim Dolgolyov 3801d0cfa8 feat(stereo3d): Фаза 6 — построение сечения «по следам» (метод следов)
Путь (b): надёжный полигон (есть) + аналитический след и вспом. точки.
- _traceLine(): след = π ∩ плоскость основания y=0 (проверено численно)
- _auxiliaryPoints(): продление сторон сечения до следа (dist=0 на следе)
- _hasBase()/_sameFace(): топология тел с основанием
- настоящий пошаговый _drawSection3PStep: 6 подписанных шагов, финал скрыт
  до шага 5 (showFull); подписи в #sect3p-hint через _stepCaption
- scope: куб, параллелепипед, призма, пирамида, усеч. пирамида, тетраэдр
- bump stereo.js?v=9

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:49:16 +03:00
Maxim Dolgolyov ccfb6116c0 feat(stereo3d): Фаза 5 — deep-link фигур из учебников + клавиатурная a11y
- openSim('stereo:<figure>') и /lab?stereofig=<figure> открывают нужное тело
  (без изменения общего hash-роутера)
- клавиатура на canvas: стрелки=орбита, +/-=зум, R/Home=сброс
- aria-live на readout; bump stereo.js?v=8
- дробление файла на модули отложено по решению пользователя (в бэклоге)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:34:51 +03:00
Maxim Dolgolyov b46c761373 feat(stereo3d): Фаза 4 — визуал (подписи осей, свечение вершин, контраст рёбер)
- подписи осей X/Y/Z цветами AxesHelper
- мягкое additive-свечение вершин (без текстур), вершины поверх рёбер
- рёбра контрастнее (opacity 0.9, renderOrder над полупрозрачным телом)
- bump stereo.js?v=7

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:32:21 +03:00
Maxim Dolgolyov dbb6a6fa11 feat(stereo3d): Фаза 3 — readout-панель, точки на гранях, подписи вершин сечения
- live-readout overlay: тип сечения, площадь, периметр, последнее измерение
  (через info().readout; _notify добавлен в section/measure-пути)
- _raycastFace(): в режиме точек клик по грани ставит точку на поверхности
- подписи вершин сечения буквами K,L,M… (наклонное/произвольное/3-точки, ≤12 вершин)
- bump stereo.js?v=6

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:29:25 +03:00
Maxim Dolgolyov c802fe552a feat(stereo3d): Фаза 2 — точные сечения кривых, унификация пикинга, HiDPI-метки
- _sliceCurvedByNormal(): аналитическое сечение шара (окружность) и
  цилиндра/конуса/усеч.конуса (гладкая кривая через точное y(θ)); старый
  сэмплинг оставлен fallback'ом для почти вертикальных плоскостей
- _edgePickNDC(): корректный пикинг ребра по всей длине (было — по середине)
- _makeTextSprite: DPR-aware, аспект по тексту, обводка, анизотропия
- тип сечения кривых = окружность/эллипс; вершинные маркеры cap ≤12 точек
- bump stereo.js?v=5

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:19:40 +03:00
Maxim Dolgolyov 7c598d6430 feat(stereo3d): Фаза 1 — камера и навигация (инерция, pan, пресеты, скриншот)
- инерция орбиты с затуханием; панорамирование (ПКМ/СКМ/Shift+ЛКМ, 2 пальца)
- орбита вокруг сдвигаемого таргета (_panOffset)
- overlay-тулбар: сброс вида + пресеты ракурса (Изо/Спереди/Сбоку/Сверху)
- тумблер авто-вращения с реальным засыпанием loop, fullscreen, снимок PNG
- a11y-атрибуты на кнопках; bump stereo.js?v=4

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:13:04 +03:00
Maxim Dolgolyov 8af85961b5 perf(stereo3d): Фаза 0 — render-on-demand, остановка фонового рендера, dispose
- lab-init: _pauseAllSims() паузит активный rAF-сим при переключении (раньше стерео рендерило невидимый canvas вечно)
- stereo: render-on-demand через _invalidate()/_needsRender, loop засыпает и просыпается по взаимодействию
- pointer/touch-слушатели перенесены с window на canvas (pointer-capture), трекаются и снимаются в dispose()
- обработка webglcontextlost/restored + метод dispose()
- _clearGroup стал рекурсивным (устранена утечка вложенных групп), a11y-атрибуты на canvas
- bump stereo.js?v=3

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:05:35 +03:00
Maxim Dolgolyov af46290ca3 feat(labs): новая симуляция «Гонка с задачами» — кинематика 1D с геймификацией
race.js (1357 строк):
- 8 сценариев: встречи (поезд+машина, 2 лодки), догон (мотоциклист, поезда), кто первый (авто vs поезд, 3 спортсмена), свободное падение vs парашют, обгон с разгоном
- Иконки movers inline SVG: car, train, bike, moto, runner, ball, boat
- Аналитический поиск точки встречи: линейный + квадратный + численный (если задержка)
- Стробоскоп положений каждые 0.5-1 с
- Canvas-графики x(t) и v(t) с маркером встречи (красная точка + бейдж)
- Проверка ответа с tolerance ±5%, verdict зелёный/красный
- Слайдеры x₀/v₀/a для каждого мовера + кнопка 'Сброс к сценарию'
- Stats bar 5 ячеек: Время, t_встречи, x_встречи, Лидер, Расстояние между

UI (lab.html):
- Sticky quick-bar: Старт/Пауза/Сброс
- Карточка вопроса вверху + answer-bar внизу с input + verdict
- Collapsible-секции (race-acc): Параметры мовера 1, 2, 3, Настройки

Интеграция:
- lab-init.js: 'sim-race' в ALL_SIM_BODIES + роутинг _openRace
- admin/sims.js: запись в ADMIN_SIMS (cat: Физика, title: 'Гонка с задачами')
- lab-glue.js: P_RACE preset с SVG-превью (дорожка + кривые x(t))
- lab.css: ~200 строк стилей .race-* по паттерну elec/geo/dyn-acc
2026-05-26 19:49:08 +03:00
Maxim Dolgolyov 218baef4ad refactor(labs): полная переработка симуляции Электролиз
electrolysis.js (556 → 1072 строк):
- База электролитов с 3 до 6: NaCl/CuSO4/H2SO4 + KI/ZnSO4/AgNO3
- Стеклянный сосуд с бликами, волнующаяся поверхность раствора (sin-анимация)
- Ионы со стробоскопным шлейфом (4 точки) и радиальным свечением
- Пузырьки: растут при подъёме + pop-эффект на поверхности (LabFX)
- Осадок: градиент по металлу (Cu медь / Zn серый / Ag серебро) + метка
- Электроды с bevel и polarity badge (− / +)
- Внешняя цепь: батарея + провода + анимированные жёлтые электроны
- Закон Фарадея: панель с живой подстановкой U/I/t/Q/m/V в формулу
- Графики m(t)/V(t): мини-холст 200×75 с двумя трендами
- info() добавлены Q (Кл) и n_электронов

lab.html (sim-electrolysis):
- Панель 220 → 280px, класс elec-panel-modern
- elec-quick-bar: Старт/Сброс всегда видны
- 4 collapsible-секции elec-acc: Электролит / Скорость / Отображение / Уравнения
- Stats bar 4 → 6: добавлены Q и e⁻

lab.css: стили .elec-panel-modern, .elec-quick-bar, .elec-acc по паттерну geo-acc/dyn-acc
2026-05-26 19:31:00 +03:00
Maxim Dolgolyov 2db3abcf64 fix(labs): убрать горизонтальный скролл в панели Планиметрии
Причина: .geo-tool-btn имел white-space:nowrap, длинные подписи ('Подобие (гомотетия)', 'Параллельность', 'Средняя линия') вылезали за пределы 1fr-ячейки 2-колоночного грида.

Фикс:
- white-space:normal + word-break:break-word + line-height 1.15 в .geo-panel-modern → текст переносится в 2 строки
- overflow-x:hidden на саму панель — гарантия что горизонтальный скролл не появится
- min-width:0 на грид и его ячейки — иначе текст не сжимался
- 'Подобие (гомотетия)' → 'Подобие' (полное название осталось в title)
2026-05-26 19:04:01 +03:00
Maxim Dolgolyov 1528d4e46e refactor(labs): переработка панели управления Планиметрии
Было: 13 секций подряд (включая дублирующийся заголовок 'Построения'), 35 кнопок одним сплошным длинным списком, ширина 210px, шрифт .73rem — приходилось много скроллить, инструменты сложно находить.

Стало:
- Ширина 210px → 260px
- Sticky quick-bar сверху с 4 самыми частыми: Выбор / Точка / Отрезок / Круг (фиолетовая подсветка, всегда видна)
- Все остальные инструменты — в 7 collapsible-секциях <details>:
  - Линии (Прямая, Луч)
  - Фигуры (Треугольник, Четырёхугольник, Многоугольник, Параллелограмм, n-угольник + control)
  - Построения (Середина, Пересечение, ⊥ биссектриса, ∠ биссектриса, ∥ прямая, ⊥ прямая, Основание, Касательные, Диагонали, Описанная, Вписанная) — теперь без дублирующегося заголовка
  - Треугольник (Высота, Медиана, Центроид, Ортоцентр, Средняя линия, Фалес)
  - Преобразования (Симметрия, Перенос, Подобие + k-control)
  - Измерения и ГМТ (Длина, Угол, Площадь, ГМТ, Т. на отрезке, Т. на круге)
  - Метки (Штрихи, Дуги, Параллельность)
- Шрифт .73rem → .78rem
- Параметры/Объектов/Очистить/Задачник остались внизу без сворачивания
2026-05-26 18:55:49 +03:00
Maxim Dolgolyov 970276915c fix(opticsbench): призма теперь даёт радугу — фикс геометрии + белый свет по умолчанию
Причины 'один луч, работает неправильно':
1. tangDir = efVec/efLen давал тангенциальное направление, при котором преломлённый луч внутри призмы уходил вниз в основание (sFace > 1), а не в выходную правую грань → внешнего луча не было
2. По умолчанию был включён моно-режим — пользователь видел один луч без дисперсии

Исправлено:
- tangDir = 90° по часовой от efNorm (efNorm.y, -efNorm.x) — теперь падающий луч при стандартных углах попадает в выходную грань правильно
- При первом входе в режим призмы window._obWhiteLight = true → 6 спектральных лучей сразу видны (расхождение цветов)
- Добавлена кнопка 'Белый / Моно' в панель призмы для переключения
2026-05-26 18:45:06 +03:00
Maxim Dolgolyov 46d80c0bdf refactor(labs): переработка панели управления Динамики
- Расширена с 248px до 300px
- Mode selector: 5 в ряд → 2 ряда (Песочница/Классика, I/II/III законы) с понятными названиями + tooltips
- Sandbox-панель: секции Мир/Отображение/Время/Пресеты обёрнуты в <details> (collapsible) с акцентом-стрелкой
- 21 пресет сгруппирован по 5 категориям: Базовые/Столкновения/Пружины и осцилляторы/Маятники и блоки/Горки и стопки
- Шрифты увеличены с .65-.72rem до .78-.82rem (mode buttons, tool grid, checkboxes, presets, подсказки)
- Newton-панель: сцены A/B/C, классические Атвуд/Наклон/Качение — кнопки крупнее
- Topbar ctrl-dynamics: .65rem → .78rem для всех инструментов и сцен
- Подсказки (help boxes) перерисованы с большим контрастом и шрифтом
- Новый CSS-блок .dyn-panel-modern с детализированным acc-styling
2026-05-26 18:25:57 +03:00
Maxim Dolgolyov 7a323f8fe0 feat(labs): универсальные инструменты для физических симуляций (Раунд 2)
ФУНДАМЕНТ — frontend/js/labs/_phys_visuals.js (новый файл, 871 строк):
- LSPhysFX.FORCE_COLORS: стандарт 10 цветов (mg красный, N циан, F_тр оранжевый,
  T фиолетовый, F_упр зелёный, F_сопр серый, F_прил жёлтый, импульс, v, a)
- drawVector / drawForceArrow / drawSpring / drawRope / drawSurface
- drawCoordSystem / drawScale / drawClock / drawAngleArc / drawPivot
- drawEnergyBars (KE/PE/W_тр/E_упр стеком с авто-масштабированием)
- LSTimeControl class (pause/play/0.1×-5×/scrubber для одного DOF)
- LSMotionTrail class (gradient line с alpha fade)
- LSBuildTimeControlUI helper для DOM-UI бара

ГРАФИКИ — frontend/js/labs/_graph_panel.js (новый файл, 415 строк):
- LSGraphPanel: 3 stacked time-series плота, авто-scale, freeze/export PNG
- LSGraphPanelUI: overlay-виджет 320×248 в углу canvas, body-selector,
  кнопки Сброс/Стоп/PNG download

FBD (свободные силовые диаграммы) интегрированы в:
- projectile.js: mg + drag + wind + elastic (bounce)
- pendulum.js: mg + T (math), mg + F_упр (spring vert/horiz)
- collision.js: стрелки скорости каждого шара + flash импульса
- newton.js: все сцены законов I-III + новые Атвуд/наклон/скатывание
- forcesandbox.js: gravity/N/friction/spring/applied на каждом теле

ENERGY BARS интегрированы в 5 сим с расчётами:
- projectile: ΔE_drag = F_d·v·dt (cumulative)
- pendulum: для math/spring/double/physical с учётом γ-затухания
- collision: KE loss при каждом столкновении
- newton: все 8 сцен включая Атвуд + наклон + скатывание (с моментом инерции)
- forcesandbox: + E_упр от пружин

GRAPHS PANEL — в 5 сим:
- pendulum: θ/ω/E (режим-aware)
- collision: |v₁|, |v₂|, v_цм
- newton: x/v/a (зависит от закона)
- forcesandbox: x/|v|/|a| выбранного тела
- hydrostatics: depth/vy/submergedFrac (только Архимед)

TIME CONTROL + MOTION TRAILS в 5 сим:
- pendulum (полный scrubber для math), collision, newton, forcesandbox (speed+pause)
- projectile (layered speed+pause, свой trail сохранён)
- LSMotionTrail на bob/балах/блоках с alpha gradient

Заменено рисование пружин на LSPhysFX.drawSpring везде.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 14:37:48 +03:00
Maxim Dolgolyov e46548d06b feat(labs): механика V2 — 4 ключевые симы школьной физики расширены
pendulum V2 (472 → 1651 строк):
- Математический (default, сохранён)
- Двойной маятник (Lagrangian RK4, ghost-копия для демо хаоса)
- Связанные маятники (биения, чарт θ₁/θ₂)
- Пружинный (вертикальный/горизонтальный, T=2π√(m/k))
- Физический (4 формы: стержень/обруч/диск/прямоугольник, с моментом инерции)
- Маятник Фуко (Кориолис, slider широты, период прецессии)
- Резонанс (внешняя F₀·cos(ω_d·t), резонансная кривая A(ω))
- Фазовый портрет (универсальный toggle для всех режимов)

collision V2 (~1000 → 2416 строк):
- 1D (default, сохранён)
- 2D под углом (импульс по осям, slider e, до/после стат)
- Multi-ball (N=2-10, стены с отскоками, перемешать)
- Бильярдный стол (6 луз, кий с прицелом, треугольник шаров, реалистичное трение)
- Реф.фрейм ЦМ (universal toggle)

newton V2 (1693 → 2585 строк):
- 4-й закон-таб «Классические задачи»
- Машина Атвуда (a=(m₂-m₁)g/(m₁+m₂), идеальный/массивный блок)
- Тело на наклонной плоскости (FBD, статика/скольжение, slider α/μ/F_app)
- Скатывание шара/цилиндра/обруча (момент инерции, гонка, наглядно почему обруч медленнее)

projectile V2 (1900 → 2400 строк):
- Парашют: F_d = ½C_d·ρ·A·v² с терминальной скоростью v_t = √(2mg/(C_d·ρ·A))
- C_d selector: парашют/куб/сфера/полусфера/диск; раскрытие парашюта на заданной высоте
- Горка-катапульта: v_0 = √(2gL(sinα-μcosα)) автомат
- 10 планет: Земля/Луна/Марс/Юпитер/Меркурий/Венера/Сатурн/Уран/Нептун/Плутон
  с реальными g + плотностью атмосферы (для drag)
- Сравнительный режим: 3 планеты одновременно с разными цветами

Все 4 симы — additive, существующая функциональность сохранена.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 14:14:42 +03:00
Maxim Dolgolyov 7ffed45974 feat(labs): максимальное улучшение периодической таблицы — 5 волн
ВОЛНА A — Расширенная база данных:
- Новый файл _periodic_data.js (~70 KB): PERIODIC_EXT_DATA + ISOTOPES + SPECTRA
- 30 элементов полностью (H..Au): радиусы, ионизация, теплоёмкость, теплопроводность,
  кристалл, распространённость, биология, токсичность, пламя, применения, история,
  этимология, минералы, типичные реакции
- 9 элементов с минимумом (Sc, Ti, V, As, Se, Kr, Hg, Pb, I)
- 60 изотопов в 20 элементах (включая ¹³¹I, ¹³⁷Cs, ⁶⁰Co, ⁹⁰Sr, ¹⁴C, ³H, U-235/238)
- 43 эмиссионных линий для 8 элементов (H, He, Li, Na, K, Ne, Ar, Hg)

ВОЛНА B — Визуальные режимы:
- Heatmap по 9 свойствам (En, mass, density, melt, boil, discovered + расширенные)
  с jet-colormap, lin/log toggle, легендой, анимацией 400ms
- 3D-таблица через Three.js: bar / wave / stack modes, orbit camera, raycaster hover
- Морф между формами таблицы: standard / long (32-col, f-block inline) / short (8-col)
  с staggered fade-in 800ms
- Тренды стрелками: радиус / ЭО / ИЕ / металличность с градиентными arrows

ВОЛНА C — Карточка элемента 2.0 (11 табов):
- Обзор (hero 96px символ + Z + категория-бейдж + quick stats)
- Свойства (17-row таблица расширенных параметров)
- Электроника (Bohr + статичная конфигурация)
- Изотопы (список + bar chart + weighted average mass)
- История (timeline + этимология)
- Применения (15 SVG иконок-сфер + текст)
- Биология (badge: macro/micro/trace/toxic/inert/radioactive)
- Минералы (формулы)
- Спектр (rainbow 380-780nm + линии эмиссии)
- Пламя (цвет + название)
- Реакции (типовые уравнения по типу элемента)
- Hero header с цветом типа; smooth fade transitions между табами

ВОЛНА D — Интерактивные режимы:
- Бинарные соединения: drag 2 элемента → формула (NaCl, Fe₂O₃) + тип связи (ΔЭО)
- Сравнить до 4 элементов: side-by-side + min/max highlight + chart
- Ряд активности металлов: 28 элементов от Li до Au, разделитель H
- Таблица Менделеева 1869: 63 элемента + 4 предсказанных (Ga, Sc, Ge, Tc)
  с popup «предсказано vs реально»
- Таймлайн открытий 1660-2024 с slider и auto-play

ВОЛНА G — Электронные конфигурации углубление:
- Orbital filling diagram: квадратики с электронами по Хунду/Паули, glow на валентном
- Aufbau diagram с slider Z 1-118 и анимированным указателем порядка заполнения
- Квантовые числа (n, l, m_l, m_s) — hover на электрон → tooltip
- Возбуждение электронов: click на электрон в Bohr → выбор уровня → анимация
  перехода с фотоном (цвет ∝ длине волны через ΔE = 13.6 eV × ...)

periodic.js: 750 → 3239 строк. Все 5 волн ADDITIVE — старая база сохранена.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 13:45:35 +03:00
Maxim Dolgolyov ea2526dc73 feat(labs): 4 школьные хим. симы + визуальная прокачка лаборатории
4 НОВЫЕ СИМЫ (школьная программа 8-11 классов):

Органика (organic.js, 1545 строк):
- Конструктор молекул: drag атомов C/H/O/N/Cl/S, валентности, click-pair bonds
- Авто-определение класса: алкан/алкен/алкин/спирт/альдегид/кислота/эфир/амин/аромат
- IUPAC-имена для C1-C10
- Гомологические ряды: 7 рядов с slider количества углеродов, M, T_кип, T_пл
- 6 качественных реакций: Br₂ вода, KMnO₄, Ag₂O/NH₃ (серебряное зеркало), Cu(OH)₂, FeCl₃, I₂

Периодическая таблица (periodic.js, 118 элементов):
- Стандартный вид 18×9 + лантаноиды/актиноиды
- Карточка элемента: Z, M, конфигурация, степени окисления, ЭО, ρ, T_пл/T_кип
- Боровская модель электронных оболочек (анимированная)
- Подсветка: 11 типов / s/p/d/f-блоки / без подсветки
- Графики свойств по периоду/группе (ЭО, M, плотность, T_пл/T_кип)
- Поиск по символу/имени/Z/массе

Качественный анализ (qualanalysis.js, 24 иона):
- 15 катионов: Na/K/NH₄/Mg/Ca/Ba/Al/Fe²⁺/Fe³⁺/Cu/Ag/Pb/Zn/H/OH
- 10 анионов: Cl/Br/I/SO₄/SO₃/CO₃/NO₃/PO₄/S²/CH₃COO
- 9 реактивов + пламя
- 2 режима: «определи ион» и «неизвестное вещество» с логом наблюдений
- Анимация капли, осадка с цветом, газовых пузырей, пламени

Растворы (solutions.js, 4 режима):
- Калькулятор: m_в, m_р-ра, ρ, T → ω, ν, C_М, C_Н с понятной логикой пересчёта
- Разбавление с before/after визуализацией
- Смешивание двух растворов с правилом рычага
- Кривые растворимости 8 веществ + задача перекристаллизации
- 15 пресетов веществ (NaCl, NaOH, H₂SO₄, CuSO₄·5H₂O, глюкоза, сахароза, ...)

ВИЗУАЛЬНАЯ ПРОКАЧКА (_chem_visuals.js, helper file):

12 функций школьной лабораторной графики:
- drawErlenmeyer / drawBeaker / drawBurette / drawTube — proper SVG-paths со шкалой
- drawSpiritLamp — стеклянный резервуар + фитиль + анимированное пламя
- animateGasBubbles / animatePrecipitateFall — анимация продуктов
- drawProductLabel — fade-in/out стрелка ↑/↓ с подписью
- drawEduTooltip — bubble с пояснением реакции
- drawDeskBackground / drawVesselShadow — лабораторный фон
- drawPHStrip — pH-индикаторная полоса с маркером

Прокачено 6 chem-сим: chemsandbox, flask, titration, electrolysis, ionexchange, redox
Каждая получила: фон парты, тени под колбами, анимированные стрелки продуктов,
educational tooltips из поля 'why' реакции. Спиртовка с пламенем в flask.
pH-полоса в titration.

Каталог теперь: 39 симуляций (было 35 + 4 новых).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 13:08:35 +03:00
Maxim Dolgolyov add17b1bb4 feat(labs): opticsbench round 2 — wave optics + interference + visual depth
Новый режим «Волны» (DiffractionSim, ~400 строк):
- Опыт Юнга: I = I₀·cos²(πd·sinθ/λ), полосы Δy = λL/d, концентрические волновые фронты
- Однощелевая дифракция: (sin α/α)², центральный максимум 2λ/a, минимумы
- Дифракционная решётка: (sin Nψ/N sin ψ)², главные порядки 0,±1,±2,±3, white-light спектр

Новый режим «Интерференция» (InterferenceSim):
- Кольца Ньютона: top-down + cross-section, r_n = √(nλR) тёмные / √((n+½)λR) светлые
- Тонкоплёночная интерференция: integrate I=cos²(π·OPD/λ) по спектру → цвет плёнки
  пресеты: мыльная плёнка / масло на воде / антибликовое покрытие
- Поляризация: P1+P2, закон Малюса I=I₀·cos²θ, анимированные E-векторы, гашение при 90°
  + связь с Брюстером из refraction mode

Визуальные эффекты (5 toggle'ов в <details>):
- «Волновые фронты»: перпендикулярные tick-marks вдоль лучей, λ_screen∝1/n в среде
- «Туман»: LabFX smoke partikles по всему canvas — лучи видны через дым
- «Lens flare»: 6-spike starburst + ghost-reflections + chromatic ring (additive composite)
- «Конструкция Гюйгенса»: расходящиеся wavelets на границе для refraction/reflection
- «Каустики»: 20-ray trace через линзу с aberration-shifted f_eff → настоящая caustic curve
- localStorage persist + zero cost when off

THEORY entry расширен 3 секциями (Юнг + однощель + решётка).

Каталог теперь: 7 вкладок в оптической скамье (lens / mirror / refraction / freebuild / prism / waves / interf).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 12:33:10 +03:00
Maxim Dolgolyov 2a8011d68e feat(labs): opticsbench round 1 — instruments + aberrations + dispersion + chain
9 готовых пресетов приборов (OB_PRESETS):
- Лупа, Микроскоп, Телескопы Кеплера/Галилея, Камера, Перископ, Проектор
- Световод (TIR), Согнутая ложка в воде
- HUD с подписью на 5 сек при загрузке + chime/whoosh sounds

ThinLensSim — стрелка-объект + анимация 3 главных лучей:
- Slider высоты объекта h_o, расчёт h_i и Г с учётом знака
- Real (cyan) vs Virtual (pink, dashed) image
- Кнопка «Построить лучи» → tween (easeOutCubic) по 500мс каждый
- Финальный chime при сходимости

ThinLensSim — формула lensmaker (R₁, R₂, n):
- Toggle «Подробный / Простой» переключает между f-слайдером и R₁/R₂/n
- Вычисление f и диоптрий D=1000/f
- Силуэт линзы динамически меняется (биконвекс/мениск/...)

MirrorSim — переменная кривизна R:
- Slider R: -250..+250 (signed, convex/concave/flat)
- Toggle «Параболическое / Сферическое» → 5-ray aberration fan
- На спherической краевые лучи разъезжаются; на параболе — точечный фокус

FreeBuildSim — multi-lens chain (новый класс):
- Каскадный расчёт изображений: image_n становится object_(n+1)
- F_sys = f1·f2 / (f1+f2-d), общее Г = Г1·Г2·...
- 3 ray tracing через всю цепочку
- 3 пресета: микроскоп / телескоп / relay
- Новая вкладка «Цепочка линз»

ThinLensSim — сферическая и хроматическая аберрации:
- Toggle «Сферическая»: 5 параллельных лучей с f_eff(h) = f - h²/(2f), spread видно
- Toggle «Хроматическая»: 3 bundle R/G/B с f×{1.02,1.0,0.98}, focal spread метки

Wavelength slider 380–780 нм:
- wavelengthToRGB() — sRGB-приближение CIE
- Цвет лучей применён во всех 3 модулях (lens/mirror/refraction)
- Toggle «Белый свет» — 3 RGB bundle с физически корректным n(λ) сдвигом
- n(λ) = 1.55 - 0.0002*(λ-550) — линейная дисперсионная модель

PrismSim — призма (новый класс):
- Равносторонняя стеклянная призма, draggable + rotatable
- Double-Snell на двух гранях, n(λ) → веер радуги при белом свете
- Новая вкладка «Призма»

Спектрометр-панель:
- 280×80 панель с rainbow gradient 380–780 nm
- Маркер текущей длины волны + точки выхода после призмы
- Авто-показ в режиме призмы

Все добавления additive — ни один из существующих 4 режимов не сломан.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 12:16:39 +03:00
Maxim Dolgolyov 6afe928c0d feat(labs): visual polish wave — LabFX foundation + 33 sims juiced up
ФУНДАМЕНТ (4 новых файла):
- _fx_core.js: LabFX namespace, glow.drawGlow, glow.pulse, haptic, shake
- _fx_particles.js: пул 1500 объектов, 6 shapes (dot/spark/ring/smoke/splash/dust)
- _fx_motion.js: tween + 12 easings + critically-damped spring
- _fx_sound.js: 9 procedural synth-звуков (click/tick/whoosh/chime/fizz/spark/bounce/pour/drone), Web Audio API
- Sound toggle в шапке lab.html с localStorage-persist

UX МИКРО (CSS + JS):
- Button states: hover scale+brightness, active scale-down, disabled grayscale
- Slider polish: custom thumb с тенью, filled-track gradient, hover/active
- Focus rings через :focus-visible
- Tooltip system .tt-host data-tt= с 400ms hover, fade-in
- Marching ants для selection
- Loading skeleton с shimmer
- Empty state .sim-empty-* паттерн
- Toast: progress bar внизу, icons по типу
- Cursor states utility classes
- View Transitions API для smooth sim-switch, fallback на CSS fade

PHASE 2 — визуальные эффекты для 33 симуляций:

Physics motion: projectile (launch whoosh + landing splash/shake/haptic + target chime), pendulum (max-extension tick + bob glow), collision (bounce + sparks + shake), angrybirds (whoosh/bounce/fizz/chime + confetti), newton (rocket flame trail + scene transitions), forcesandbox (spring glow + impact sparks)

Physics fields: emfield (field-lines glow + particle trail + lightning при high field + Gauss-drag haptic + rod motion sparks), circuit (energized-wire glow ∝ current + LED bloom + short-circuit shake/spark + heat shimmer smoke + place/erase/switch sounds), opticsbench (beam glow на всех режимах + caustics dust у фокуса + TIR/Brewster one-shot sounds)

Thermo+waves: waves (mode-switch whoosh + Mach-cone particles + spectrum harmonic chime + waveform glow), hydrostatics (pour sound + splash при погружении + valve click), isoprocess (PV-trail dust), heatengine (drone цикла + hot/cold reservoir smoke/dust + phase-change ticks), radioactive (Geiger tick throttle + decay sparks + half-life chime + α/β/γ glow)

Chemistry: chemsandbox (pour splash + fizz bubbles/dust/spark по типу реакции + shake при горении), equilibrium/electrolysis/reactions/titration/flask/ionexchange/redox (pour/fizz/spark/chime по событиям, частицы при ключевых моментах), stoichiometry (fizz bubbles + recipe-change click)

Math+geom: geometry (tool-click + object-create tick + locus glow + challenge confetti via LabFX + haptic), triangle (vertex-drop tick + special-point glow), stereo (figure-change whoosh + cross-section chime, no particles — Three.js), trigcircle (drag-haptic + pitch∝angle tick + sin/cos glow), graph/graphtransform/quadratic (slider-tick throttled + curve glow + discriminant-cross chime), probability (bounce + finish-chime burst), normaldist (pulsing shade + bell glow)

Bio+misc: celldivision (phase-change whoosh + prophase dust + anaphase poles spark + cytokinesis chime), photosynthesis (photon tick + ATP chime + glucose sparkle), bohratom (electron-jump chime ∝ levels + photon spark), orbitals/crystal (mode-change whoosh — Three.js, sound only), logic (gate-place + wire-connect + LED bloom + HIGH wire flowing dots + preset chime), gas/brownian/diffusion/states (preset whoosh, throttled tick по событиям)

Все LabFX вызовы обёрнуты в if (window.LabFX) guard — graceful degradation если фундамент не загружен. 47 JS файлов прошли syntax check.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 13:58:49 +03:00
Maxim Dolgolyov 8b3159b529 feat(labs): wave 3 — 5 new sims + optics merger
Оптическая скамья (opticsbench) — merger thinlens + mirror + refraction
- 4 режима: «Свободная сборка» / «Линза» / «Зеркало» / «Преломление»
- Все 3 движка слиты в OpticsBenchSim (1583 строк)
- Backward compat: #thinlens / #mirrors / #refraction → #opticsbench
- Удалены: thinlens.js, mirror.js, refraction.js

Радиоактивный распад (radioactive) — новая сима
- Monte-Carlo распад: λ·dt вероятность на тик, частицы меняют цвет, эмитируются α/β/γ
- Real-time N(t) график с теоретической кривой N₀·exp(-λt)
- 7 изотопов: ¹⁴C, ¹³¹I, ¹³⁷Cs, ²²⁶Ra, ⁴⁰K, ²³⁸U-chain, ²³⁵U-chain
- Цепочки распадов (U-238: 14 шагов сокращены до 5 ключевых)
- Dating mode для C-14: t = ln(N₀/N)/λ
- HUD: периодов прошло, % распалось, активность в Бк

Тепловые двигатели (heatengine) — новая сима
- 4 цикла: Карно / Отто / Дизель / Брайтон
- PV-диаграмма с замкнутым циклом, заполненной площадью работы
- Аналитически точные изотермы (PV=nRT) и адиабаты (PV^γ=const)
- Анимированный поршень с резервуарами (красный T_h / синий T_c)
- Частицы газа, скорость ∝ √T
- Hover-tooltips с формулами для каждого сегмента

Логические схемы (logic) — новая сима для информатики
- Drag-drop конструктор: 12 типов компонентов (INPUT/CLOCK/OUTPUT/AND/OR/NOT/XOR/NAND/NOR/XNOR/BUF/wire)
- Топологическая сортировка для propagation, цветовая подсветка HIGH/LOW
- Авто-генерация булевого выражения (∧ ∨ ¬ ⊕)
- Авто-таблица истинности (до 2^6 = 64 строк)
- 6 пресетов: полусумматор, полный сумматор, RS-триггер, D-триггер, декодер 2-в-4, мультиплексор 2-в-1

Стехиометрия (stoichiometry) — новая сима
- 10 реакций: Zn+HCl, H₂+O₂, CH₄+O₂, N₂+H₂ (Габер), Al+CuSO₄, Mg+O₂, CaCO₃→, HCl+NaOH, KMnO₄→, C₂H₅OH+O₂
- Sliders с переключением m/n/V (для газов V=n·22.4 при н.у.)
- Анимация частиц при реакции, подсветка лимитирующего реагента
- Пошаговый расчёт m→n→n_product→m_product с KaTeX
- HUD: лимит, избытки, теоретический выход

Каталог: 33 → 35 сим (5 новых − 3 удалённых merger)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 13:25:16 +03:00
Maxim Dolgolyov 8f30a8cef6 feat(labs): wave 2 — depth features across 6 sims
Электрические цепи (circuit):
- Индуктивность L как новый компонент (1–1000 мГн, шорт в DC, jωL в AC)
- RLC preset для демонстрации резонанса
- Осциллограф: U(t)/I(t) для выбранного компонента, 100 sample, dual-axis
- Heatmap мощности: радиальный градиент halo от blue→red пропорционально P=UI

Стереометрия 3D (stereo):
- Сечение через 3 произвольные точки: pick на гранях/рёбрах/вершинах
- Плоскость + полигон пересечения с авто-определением типа (3–6-угольник) и площадью
- Step-by-step режим: визуализация P1→линия→P2→линия→P3→плоскость→сечение
- Поддержка всех solids (включая cylinder/cone через sampling fallback)

Планиметрия (geometry):
- Задачник framework: CHALLENGES[] с setup/check функциями
- 5 стартовых задач: серединный перпендикуляр, биссектриса, описанная окружность, ГМТ, касательная
- Авто-checker: толерантности ±0.5° для углов, ±1–5% для расстояний
- UI: collapsible панель с статус-иконками, конфетти + «Молодец!» на success

Электромагнитные поля (emfield):
- Preset «Тороид»: 16+16 проводов в концентрических кольцах
- Поверхность Гаусса: draggable круг, считает Φ = q_enc/ε₀, подсвечивает охваченные заряды
- Motional EMF: draggable rod, arrow-keys управление, считает ε = ∫(v×B)·dl

Химическая песочница (chemsandbox):
- Live-overlay с уравнением реакции: молекулярное / полное ионное / сокращённое ионное
- Coverage: 49/49 молекулярных, 34/49 ионных, 36/49 сокращённых
- Auto-hide через 5 сек, fade-in animation, цветовая кодировка типов

Волны и звук (waves):
- Doppler: source+observer drag, expanding wavefronts, f_obs формула, Mach cone при v>c
- Beats: f1+f2, sum waveform с envelope, индикация f_beat=|f1-f2|
- Spectrum (DFT): N=256 samples pure JS, bar-chart с пиками и labels, «Добавить гармонику»

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 12:48:14 +03:00
Maxim Dolgolyov 7f75c96acd feat(labs): planimetry locus + emfield merger + projectile graphs + UI cleanup
Геометрия (планиметрия):
- Живые измерения как объекты: длина / угол / площадь — auto-recompute, draggable chips
- Инструмент ГМТ: sweep мовера через параметр, рисует кривую места точек
- Новые типы точек: on_segment (скользит по отрезку, _t), on_circle (по окружности, _theta)
- Toolbar: «Длина», «Угол», «Площадь», «ГМТ», «На отрезке», «На окружности»

Электромагнитные поля (emfield):
- Merge magnetic.js + coulomb.js в один EMFieldSim с 3 режимами (E / B / комбинированное)
- Унифицированный pipeline: colormap, field lines, vectors, equipotentials, flux loop, test particle
- Combined-режим: полная сила Лоренца F=q(E+v×B)
- Backward compat: #coulomb и #magnetic хеши и ?sim= параметры редиректят в emfield
- Удалены: magnetic.js, coulomb.js. Добавлен: emfield.js

Бросок тела (projectile):
- Режим целей: 3 окна, hit-детекция, HUD «Цели: N/M / Попыток: K»
- Графики x(t), y(t), vx(t), vy(t) — 2×2 Canvas 2D, real-time
- Двойной бросок: одновременно 2 траектории для сравнения (cyan vs gold)

UI fixes (по результатам аудита):
- Заменены emoji/unicode на inline SVG .ic: switch ⌇, spring 〜 (5 мест), download ⬇ (2), camera 📷
- Убраны декоративные символы ☉ ○ из geometry tool labels
- Добавлены THEORY entries: geometry, hydrostatics (раньше показывали fallback)
- Стандартизирована ширина panel для sim-proj и sim-coll (240px)
- waves перенесён в физический блок SIMS catalog (был после биологии)
- Очищен дефолтный sim-topbar-title (был «График функции»)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 12:09:44 +03:00
Maxim Dolgolyov 6792a4a5c7 refactor(lab): phase 3 — token purification across lab.html / lab.css / lab-glue.js
Replaced ~100 hardcoded brand colors with var() tokens across 3 files.
Kept: tinted-alpha colors (rgba(155,93,229,.x)), canvas fillStyle (vars
don't resolve there), curated SVG card-preview palettes (P_GRAPH, P_MAGNETIC,
etc.), physics-convention colors (#EF476F for positive charges, #4CC9F0 for
negative), slightly-different decorative shades (#EF476F ≠ #F15BB5).

lab.css: #9B5DE5→var(--violet), #06D6E0→var(--cyan), #F15BB5/nscene→var(--pink),
  #0F172A (filter.active)→var(--text), fn-color defaults, trig btn defaults.
lab.html: stat bars, slider labels, info-fn-dot, toggle-dot, panel badges,
  section-specific color coding (violet=wave1/param1, cyan=wave2/param2).
lab-glue.js: toggleTheory() JS style assignments, template-literal HTML headings.

Before: ~265 hardcodes   After: ~60 (canvas+curated+rgba+physics-convention)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 22:51:28 +03:00
Maxim Dolgolyov 92b5c39860 refactor(lab): phase 2 — extract inline glue script to /js/labs/lab-glue.js
lab.html 4324L → 3499L (-825L). 824 lines of glue code moved.

Position preserved: lab-glue.js loads after lab-init.js, before

newton.js / forcesandbox.js / etc. — same execution order as inline.

node --check passes. /lab returns 200. /js/labs/lab-glue.js returns 200.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 22:36:26 +03:00
Maxim Dolgolyov 46e6d82010 refactor(lab): phase 1 — extract inline style block to /css/lab.css
lab.html 5180L → 4324L (-856L). All CSS moved to frontend/css/lab.css

(855L). Added <link> tag after ls.css for proper cascade.

Visual rendering unchanged — pure file move.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 22:35:07 +03:00
Maxim Dolgolyov d5f77bb648 refactor: extract lab.html sim initializers to lab-init.js
lab.html: 9273 → 5180 lines (-44%)
frontend/js/labs/lab-init.js: new file, 4098 lines

All 34 _open*() functions + sim instance vars + openSim/closeSim/
_addTouchSupport/_simShow + THEORY data extracted to lab-init.js.
Shared globals (FN_COLORS, ALL_SIM_BODIES, ALL_CTRL_BARS, sim vars)
converted from const/let to var for cross-script accessibility.
Three vars in lab.html made global: _disabledSimIds, _theoryOpen, _embedMode.
Load order preserved: lab-init.js added before main <script> block.
2026-05-08 13:41:38 +03:00
Maxim Dolgolyov 26ba289019 a11y: WCAG AA contrast + ARIA roles + focus management across all pages
- css/ls.css: --text-3 #8898AA → #56687A (5.1:1 contrast), min-height 44px on .btn-primary/.btn-ghost/.sb-link, new .icon-btn utility (44×44px)
- js/api.js: lsConfirm — role=dialog, aria-modal, aria-labelledby, Tab focus trap, restore focus on close; lsToast — aria-live=polite on container, role=alert on errors; live quiz — role=dialog, role=radiogroup, role=radio, aria-checked, keyboard support
- test-run.html: q-opt divs — role=radio/checkbox, aria-checked, tabindex, keyboard enter/space; confirm modal — role=dialog, aria-modal; btn-flag — aria-pressed; dots — aria-label, aria-current; touch targets 44px
- board.html: btn-del-ann — aria-label; reaction buttons — aria-label, aria-pressed
- All 18 HTML files: replace hardcoded color:#8898AA with color:var(--text-3)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 11:42:38 +03:00
Maxim Dolgolyov d2bf3aba47 fix: цвет текста кнопок-действий в панели стереометрии 2026-04-14 14:19:28 +03:00
Maxim Dolgolyov e4f7c167eb refactor: переработана панель стереометрии — иконки, toggle-ряды, stepper для n 2026-04-14 14:14:37 +03:00
Maxim Dolgolyov d822b705c4 feat: удаление последнего измерения и очистка всех измерений 2026-04-14 14:05:40 +03:00
Maxim Dolgolyov fff22f7331 feat: засечки рёбер, производные точки 3D, длины рёбер в стереометрии 2026-04-14 13:59:32 +03:00
Maxim Dolgolyov 481a9aeb02 feat: стереометрия — усечённая пирамида, правильные многогранники, скрещивающиеся прямые
- Добавлены фигуры: усечённая пирамида, октаэдр, икосаэдр, додекаэдр
- Формулы V, S, r_вп, R_оп для всех новых фигур
- Инструмент '∠ скрещ. прям.' — угол и расстояние между скрещивающимися прямыми (4 клика)
- Для икосаэдра/додекаэдра — THREE.IcosahedronGeometry/DodecahedronGeometry с извлечением рёбер
- Вписанная/описанная сфера поддерживает октаэдр, икосаэдр, додекаэдр
- Параметр n добавлен для пирамиды

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 11:59:42 +03:00
Maxim Dolgolyov 84dac03e53 fix: баги штрихов/дуг планиметрии + переработка инструментов треугольника; фаза 10.1 (теорема Фалеса)
- arcmark: рисуется всегда (не только при showAngles=true)
- altitude/median: 1 клик на вершину треугольника (авто-определение)
- centroid/orthocenter: 1 клик внутри/на треугольник
- thales: 3 клика O, A, B → A'B' параллельно AB, коэф. k

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 11:24:43 +03:00
Maxim Dolgolyov bdb81ba9c8 feat: планиметрия фазы 8.3–10.2 — метки параллельности, средняя линия, параллелограмм, диагонали, подобие; geometry в онлайн-уроке
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 11:15:46 +03:00
Maxim Dolgolyov 2191e53529 feat: Фазы 7–8 планиметрии — элементы треугольника + метки
Фаза 7:
- altitude: высота (клик на сторону → клик вершина → foot + отрезок + прямой угол)
- median: медиана (3 клика A,B,C → midpoint + отрезок)
- centroid: 3 клика → 3 медианы + точка G (centroid constr)
- orthocenter: 3 клика → 3 высоты + точка H (orthocenter constr + altitude_foot constr)
- gOrthocenter() math function
- Прямые углы для altitude_foot в _drawAngleMeasures
- Исправлен баг onHintChange: передавался boolean вместо numeric phase

Фаза 8:
- tick tool: метки равных сторон на отрезках и сторонах полигонов (1–3 штриха)
- arcmark tool: метки равных углов на вершинах полигонов (1–3 дуги)
- _drawTickMark(), sideMarks[], angleMarks[] на полигонах
- Новая секция «Метки» в панели инструментов

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 11:08:16 +03:00