# Phase 0: Спека v1 + рантайм (формульные сцены) **Status:** ⬜ Not Started **Parent plan:** [PLAN.md](./PLAN.md) **Domain:** frontend ## Objective Заложить ядро: формат JSON-спеки v1, безопасный движок выражений, рантайм `SimEngine`, адаптер регистрации в `LabRegistry`. После фазы рукописная спека «брошенное тело» играет в /lab. ## Tasks - [ ] Задокументировать формат спеки v1 в шапке нового файла + в CONTEXT.md (params, objects, viewport, controls). - [ ] `frontend/js/labs/_sim_expr.js` — безопасный движок выражений: токенайзер → AST → `evaluate(ast, env)`. Whitelist математики (см. CONTEXT.md). Парсер расширяет логику `y=f(x)` из `graph.js` (посмотреть и переиспользовать, не дублировать). ⛔ без `eval`/`Function`. `compile(src) -> {fn(env), error}`. - [ ] `frontend/js/labs/_sim_engine.js` — `window.SimEngine.mount(host, spec)`: - создаёт canvas (мир→экран трансформация по `viewport`) + оверлей-слой для подписей (KaTeX через существующий путь рендера формул); - объекты: point|segment|vector|circle|rect|polyline|path|label (числовые свойства = число или строка-выражение, компилируются один раз); - игровой цикл `requestAnimationFrame`: пересчёт `t`, перевычисление привязок, перерисовка; - контролы: слайдеры-параметры (из `params[]`), кнопки play/pause/reset; API инстанса `{ play, pause, reset, setParam, destroy }`. - [ ] `frontend/js/labs/_sim_adapter.js` — `registerSpecSim(spec)` строит манифест LabRegistry (`open(ctx)` → `SimEngine.mount`, `stop/destroy`, `preview` из спеки) и регистрирует. - [ ] Фикстура-демо: рукописная спека «projectile» (угол/скорость слайдеры, точка x=v·cosθ·t, y=v·sinθ·t−5t²) — зарегистрировать как `customdemo` для проверки в /lab (за временным флагом/разделом, не светить ученикам). - [ ] Подключить новые файлы в /lab (lazy через существующий `_loader`/`_sim_deps` или прямыми тегами — выбрать минимально-инвазивно, не ломая старт). ## Files to Modify/Create - `frontend/js/labs/_sim_expr.js` — движок выражений (new) - `frontend/js/labs/_sim_engine.js` — рантайм (new) - `frontend/js/labs/_sim_adapter.js` — адаптер LabRegistry (new) - `frontend/js/labs/_sim_demo.js` — демо-спека-фикстура (new, временная) - `frontend/lab.html` или `_sim_deps.js` — подключение файлов (минимальная правка) ## Acceptance Criteria - В /lab открывается демо-симуляция, слайдеры меняют движение, play/pause/reset работают. - Движок выражений не использует eval/Function; некорректная формула не роняет рантайм (показывает ошибку/0). - Существующие ~40 симуляций и старт /lab не сломаны. ## Notes - Подписи с LaTeX — переиспользовать существующий рендер формул (KaTeX), не тянуть новый. - Мир-координаты с осью Y вверх (математические), трансформация в экранные внутри движка. - Производительность: компилировать выражения один раз при mount, в цикле только evaluate. ## Review Checklist - [ ] Все задачи выполнены - [ ] Нет eval/new Function в движке выражений - [ ] Нет эмодзи (только SVG .ic) - [ ] Старт /lab и существующие симуляции не регрессировали - [ ] Код в стиле проекта (vanilla, IIFE-модули labs/) ## Handoff to Next Phase