feat(quantik-game): фаза 4 — квантовые способности + SR-комнаты

Глава-созвездие quantum (L12–L16) и фирменные механики — всё через
безопасную модель спеки, движок и бэкенд НЕ тронуты (engine touch = 0):
- Суперпозиция: два тела ball+ball2, goal.when требует ОБА (зеркальный
  закон). Туннелирование: forbidden-зона wall + fail wall.hit && tunnel<1;
  способность тратит энергию → setParam(tunnel,1). Коллапс/прицел: пунктир-
  plot предсказанной траектории на паузе.
- Энергия — клиентский ресурс (localStorage quantik-energy, QuantikEnergy).
- SR-комната: мини-сессия повторения флешкарт в модалке (НЕ iframe),
  LS.fcStudySession/fcReview; «Знаю/Легко» дают энергию; текст карт
  экранируется, картинки — по regex-вайтлисту.
Все 5 уровней проверены на реальном движке (2★ достижимы; суперпозиция
требует оба тела; туннель-гейт блокирует без заряда). npm test 253/8
baseline; lint:routes 0; цепочка разблокировки проходима.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@
This commit is contained in:
Maxim Dolgolyov
2026-06-14 10:29:35 +03:00
parent 978448d99b
commit 0b1925fd3b
9 changed files with 1071 additions and 24 deletions
+3 -1
View File
@@ -1046,7 +1046,7 @@ window.LS = {
assistantContext, assistantSeen, assistantDismiss, assistantSettings, assistantAsk, assistantFlashcards, assistantFeedback, assistantMemory, assistantMemoryClear, imageGen, imageGenStatus,
adminGetAssistant, adminSaveAssistant, adminTestAssistant, adminReindexTextbooks,
adminSaveProvider, adminDeleteProvider, adminSetActiveProvider, adminAssistantModels,
fcListDecks, fcCreateDeck, fcAddCard,
fcListDecks, fcCreateDeck, fcAddCard, fcStudySession, fcReview,
escapeHtml, esc,
parseDate, fmtRelTime, safeHref,
initPage,
@@ -1297,6 +1297,8 @@ async function adminAssistantModels(params) { const q = new URLSearchParams(para
async function fcListDecks() { return req('GET', '/flashcards/decks'); }
async function fcCreateDeck(d) { return req('POST', '/flashcards/decks', d); }
async function fcAddCard(deckId, d) { return req('POST', `/flashcards/decks/${deckId}/cards`, d); }
async function fcStudySession(deckId){ return req('GET', `/flashcards/decks/${deckId}/study`); }
async function fcReview(cardId, quality) { return req('POST', `/flashcards/cards/${cardId}/review`, { quality }); }
async function deleteFile(id) { return req('DELETE', `/files/${id}`); }
async function getFileAccess(id) { return req('GET', `/files/${id}/access`); }
async function assignFile(id, data) { return req('POST', `/files/${id}/assign`, data); }