Files
Learn_System/backend/scripts/review_geom10.js
T
Maxim Dolgolyov 5381679c68 chore: консолидация незакоммиченной работы (биохимия + System Health + lab/textbooks)
Зафиксирована накопленная незакоммиченная работа рабочего дерева, КРОМЕ файлов
учебника «Химия 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>
2026-05-30 18:12:55 +03:00

86 lines
4.1 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const dir = path.join(__dirname, '..', '..', 'frontend', 'textbooks');
const files = ['geometry_10_hub.html','geometry_10_r1.html','geometry_10_r2.html','geometry_10_r3.html','geometry_10_r4.html'];
const cmds = ['dfrac','sqrt','sin','cos','tan','angle','vec','triangle','Rightarrow','cdot','ne','le','ge','pi','alpha','beta','gamma','delta','varphi','circ','perp','parallel','frac','tfrac','overline','left','right','begin','end','boxed','cot','arcsin','arccos','arctan','log','ln','lim','sum','int','infty','Delta','theta','lambda','mu','rho','sigma','tau','omega','Omega','phi','psi','xi','zeta','eta','epsilon','varepsilon','Pi','Sigma','approx','equiv','pm','mp','times','div','leq','geq','neq','sim','cong','subset','supset','cup','cap','forall','exists','overrightarrow','overleftarrow','widehat','widetilde','mathbf','mathrm','mathbb','mathcal','quad','qquad','hline','cline','displaystyle','textstyle','scriptstyle','underline','operatorname','land','lor','lnot','mapsto','Leftrightarrow','Leftarrow','leftarrow','rightarrow','uparrow','downarrow','prime','colon'];
for (const f of files) {
const fp = path.join(dir, f);
if (!fs.existsSync(fp)) { console.log('MISSING', f); continue; }
const txt = fs.readFileSync(fp, 'utf8');
const scriptRe = /<script(?![^>]*\bsrc=)[^>]*>([\s\S]*?)<\/script>/g;
let m;
let totalKatexErrs = 0;
const errSamples = [];
let scriptBlocks = 0;
let combinedJs = '';
while ((m = scriptRe.exec(txt)) !== null) {
scriptBlocks++;
const body = m[1];
combinedJs += body + ';\n';
const cmdRe = /(^|[^\\])\\([a-zA-Z]+)/g;
let cm;
while ((cm = cmdRe.exec(body)) !== null) {
const cmd = cm[2];
if (cmds.includes(cmd)) {
totalKatexErrs++;
const idxAbs = m.index + cm.index + cm[1].length;
const before = txt.slice(0, idxAbs);
const line = (before.match(/\n/g) || []).length + 1;
if (errSamples.length < 10) errSamples.push({line, cmd, ctx: body.slice(Math.max(0,cm.index-30), cm.index+50).replace(/\n/g,' ')});
}
}
}
// <option> raw KaTeX
const optRe = /<option[^>]*>([\s\S]*?)<\/option>/g;
let om;
let optionRaw = 0;
const optionSamples = [];
while ((om = optRe.exec(txt)) !== null) {
const content = om[1];
if (/\$[^\$]+\$/.test(content) || /\\(dfrac|sqrt|frac|angle|vec|sin|cos|alpha|beta|pi|circ|triangle|Rightarrow)/.test(content)) {
optionRaw++;
const before = txt.slice(0, om.index);
const line = (before.match(/\n/g) || []).length + 1;
if (optionSamples.length < 8) optionSamples.push({line, content: content.slice(0,90)});
}
}
// Emoji
const emojiRe = /[\u{1F300}-\u{1FAFF}\u{1F000}-\u{1F02F}\u{2700}-\u{27BF}\u{2600}-\u{26FF}]/gu;
let em;
let emoji = 0;
const emojiSamples = [];
while ((em = emojiRe.exec(txt)) !== null) {
emoji++;
const before = txt.slice(0, em.index);
const line = (before.match(/\n/g) || []).length + 1;
if (emojiSamples.length < 10) emojiSamples.push({line, ch: em[0], cp: em[0].codePointAt(0).toString(16), ctx: txt.slice(Math.max(0,em.index-25), em.index+25).replace(/\n/g,' ')});
}
let authors = [];
if (f.includes('hub')) {
for (const a of ['Латотин','Чеботаревский','Горбунова','Шлыков']) {
if (txt.includes(a)) authors.push(a);
}
}
let parseErr = null;
try { new Function(combinedJs); } catch(e) { parseErr = e.message.slice(0,200); }
console.log('=== ' + f + ' ===');
console.log(' size:', txt.length, 'scripts:', scriptBlocks);
console.log(' KaTeX single-backslash errors:', totalKatexErrs);
for (const s of errSamples) console.log(' line ' + s.line + ' \\' + s.cmd + ' ctx: ' + s.ctx);
console.log(' <option> raw KaTeX:', optionRaw);
for (const s of optionSamples) console.log(' line ' + s.line + ': ' + s.content);
console.log(' Emoji symbols:', emoji);
for (const s of emojiSamples) console.log(' line ' + s.line + ' U+' + s.cp + ' ctx: ' + s.ctx);
if (authors.length) console.log(' Authors in hub:', authors.join(', '));
console.log(' JS parse:', parseErr ? 'ERROR: ' + parseErr : 'OK');
}