5381679c68
Зафиксирована накопленная незакоммиченная работа рабочего дерева, КРОМЕ файлов учебника «Химия 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>
93 lines
3.7 KiB
JavaScript
93 lines
3.7 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'];
|
|
|
|
// hub footer check
|
|
const hub = fs.readFileSync(path.join(dir,'geometry_10_hub.html'),'utf8');
|
|
const footerMatch = hub.match(/<footer[\s\S]*?<\/footer>/);
|
|
console.log('HUB FOOTER:');
|
|
if (footerMatch) console.log(footerMatch[0].slice(0,400)); else console.log(' NOT FOUND');
|
|
|
|
// g3d.js usage
|
|
console.log('\\n3D ENGINE / g3d.js usage:');
|
|
for (const f of files) {
|
|
const txt = fs.readFileSync(path.join(dir, f), 'utf8');
|
|
const has3d = /g3d/i.test(txt);
|
|
const hasProj = /(project|perspective|3d|threejs|three\.)/i.test(txt);
|
|
const hasViewBox = (txt.match(/viewBox/g) || []).length;
|
|
console.log(' ' + f + ' g3d:'+has3d+' proj/3d:'+hasProj+' viewBox count:'+hasViewBox);
|
|
}
|
|
|
|
// Structure: count §, finals, "Я прочитал" buttons
|
|
console.log('\\nSTRUCTURE:');
|
|
for (const f of files) {
|
|
if (f.includes('hub')) continue;
|
|
const txt = fs.readFileSync(path.join(dir, f), 'utf8');
|
|
// sections: pattern in TOC
|
|
const sectionIds = [];
|
|
const re = /id:\s*['"]([^'"]+)['"]\s*,\s*num:\s*['"]([^'"]*)['"]/g;
|
|
let mm;
|
|
while ((mm = re.exec(txt)) !== null) sectionIds.push({id:mm[1], num:mm[2]});
|
|
// theory blocks
|
|
const theoryCount = (txt.match(/theory|teor|Теори/g) || []).length;
|
|
// interactive: int1/int2/int3/int4 or class
|
|
const intCount = (txt.match(/data-int|intCanvas|interactive/g) || []).length;
|
|
// "Я прочитал"
|
|
const yaProch = (txt.match(/Я прочитал/g) || []).length;
|
|
// markRead
|
|
const markRead = (txt.match(/markRead|markAsRead|читал/g) || []).length;
|
|
console.log(' ' + f + ':');
|
|
console.log(' sections in TOC:', sectionIds.map(s=>s.num+':'+s.id).join(' '));
|
|
console.log(' theoryCount mentions:', theoryCount, 'interactive mentions:', intCount, '"Я прочитал":', yaProch);
|
|
}
|
|
|
|
// Look for slider px ranges 40..150, R=120 etc.
|
|
console.log('\\nSLIDER PIXEL CHECK (range/value hints):');
|
|
for (const f of files) {
|
|
if (f.includes('hub')) continue;
|
|
const txt = fs.readFileSync(path.join(dir, f), 'utf8');
|
|
// Find input range with suspicious min/max
|
|
const ranges = [...txt.matchAll(/<input[^>]*type=["']range["'][^>]*>/g)];
|
|
let suspicious = 0;
|
|
for (const r of ranges) {
|
|
const tag = r[0];
|
|
const min = (tag.match(/min=["']?(\d+)/)||[])[1];
|
|
const max = (tag.match(/max=["']?(\d+)/)||[])[1];
|
|
if (min && max) {
|
|
const lo=+min, hi=+max;
|
|
if ((lo>=30 && hi>=120) || (hi-lo>=60 && hi>=100)) {
|
|
suspicious++;
|
|
if (suspicious<=5) {
|
|
const idx = r.index;
|
|
const line = (txt.slice(0,idx).match(/\n/g)||[]).length+1;
|
|
console.log(' ' + f + ' line '+line+': '+tag.slice(0,140));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
console.log(' ' + f + ': total ranges=' + ranges.length + ' suspicious(px-like)=' + suspicious);
|
|
}
|
|
|
|
// Check "px" usage near labels (R = , a =, etc.)
|
|
console.log('\\nLABEL "R=" / "a=" PATTERNS:');
|
|
for (const f of files) {
|
|
if (f.includes('hub')) continue;
|
|
const txt = fs.readFileSync(path.join(dir, f), 'utf8');
|
|
// Find patterns like 'R = ${...}' or text="R = ${r}" where r might be px
|
|
const pat = /['"`][^'"`]*\b(R|a|h|d|l|r|b|c)\s*=\s*\$\{[^}]+\}/g;
|
|
const matches = [];
|
|
let mm;
|
|
while ((mm = pat.exec(txt)) !== null) {
|
|
if (matches.length < 6) {
|
|
const idx = mm.index;
|
|
const line = (txt.slice(0,idx).match(/\n/g)||[]).length+1;
|
|
matches.push({line, snip: mm[0].slice(0,80)});
|
|
}
|
|
}
|
|
if (matches.length) {
|
|
console.log(' ' + f + ':');
|
|
for (const x of matches) console.log(' line '+x.line+': '+x.snip);
|
|
}
|
|
}
|