diff --git a/frontend/textbooks/algebra_8_ch2.html b/frontend/textbooks/algebra_8_ch2.html
index 7113dae..0fbf1f0 100644
--- a/frontend/textbooks/algebra_8_ch2.html
+++ b/frontend/textbooks/algebra_8_ch2.html
@@ -1037,12 +1037,14 @@ function buildP10(){
`);
/* INT 2 — Шаговый разлагатель */
- html += widget('Пошаговый разлагатель','INTERACT 2','Введите $a$, $b$, $c$ — система разложит трёхчлен по шагам.',`
+ html += widget('Пошаговый разлагатель','INTERACT 2','Введите $a$, $b$, $c$ и нажимайте «Дальше» — каждый шаг отдельно.',`
-
+
+
+
`);
@@ -1121,24 +1123,51 @@ function buildP10(){
refresh();
})();
- /* INIT 2 */
+ /* INIT 2 — пошаговый */
(function(){
- document.getElementById('p10s-go').addEventListener('click', ()=>{
- const a = +document.getElementById('p10s-a').value;
- const b = +document.getElementById('p10s-b').value;
- const c = +document.getElementById('p10s-c').value;
- const stage = document.getElementById('p10s-stage');
- if(!a){ stage.innerHTML = '$a$ не может быть нулём.
'; return; }
+ const stage = document.getElementById('p10s-stage');
+ const goBtn = document.getElementById('p10s-go');
+ const nextBtn = document.getElementById('p10s-next');
+ const resetBtn = document.getElementById('p10s-reset');
+ let steps = [], idx = 0, awarded = false;
+ function build(a, b, c){
const D = b*b - 4*a*c;
- let html = 'Шаг 1: $D = ' + (b*b) + ' - ' + (4*a*c) + ' = ' + D + '$
';
- if(D < 0){ html += 'Шаг 2: $D < 0$ → трёхчлен не раскладывается на множители с действительными коэффициентами.
'; }
- else {
+ const arr = [];
+ arr.push('Шаг 1. Исходный трёхчлен: $' + a + 'x^2 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 'x ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + '$');
+ arr.push('Шаг 2. $D = b^2 - 4ac = ' + (b*b) + ' - ' + (4*a*c) + ' = ' + D + '$');
+ if(D < 0){
+ arr.push('Шаг 3. $D < 0$ — на множители первой степени с действительными коэффициентами не раскладывается.');
+ } else {
const x1 = (-b - Math.sqrt(D))/(2*a), x2 = (-b + Math.sqrt(D))/(2*a);
- html += 'Шаг 2: $x_1 = ' + fmt(x1) + ',\\ x_2 = ' + fmt(x2) + '$
';
- html += 'Шаг 3: $' + a + 'x^2 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 'x ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + ' = ' + (a === 1 ? '' : a) + '(x ' + (x1 >= 0 ? '- ' + fmt(x1) : '+ ' + fmt(-x1)) + ')(x ' + (x2 >= 0 ? '- ' + fmt(x2) : '+ ' + fmt(-x2)) + ')$
';
+ arr.push('Шаг 3. Корни: $x_1 = ' + fmt(x1) + ',\\ x_2 = ' + fmt(x2) + '$');
+ arr.push('Шаг 4. Подставляем в формулу $a(x-x_1)(x-x_2)$:');
+ arr.push('Ответ: $' + (a === 1 ? '' : a) + '(x ' + (x1 >= 0 ? '- ' + fmt(x1) : '+ ' + fmt(-x1)) + ')(x ' + (x2 >= 0 ? '- ' + fmt(x2) : '+ ' + fmt(-x2)) + ')$');
}
- stage.innerHTML = html; renderMath(stage);
- achievement('p10_steps'); bumpProgress('p10', 14);
+ return arr;
+ }
+ function render(){
+ stage.innerHTML = steps.slice(0, idx + 1)
+ .map(s => `${s}
`)
+ .join('');
+ renderMath(stage);
+ if(idx >= steps.length - 1){
+ nextBtn.disabled = true; nextBtn.textContent = 'Готово';
+ if(!awarded){ awarded = true; achievement('p10_steps'); bumpProgress('p10', 14); confetti(); }
+ } else {
+ nextBtn.disabled = false; nextBtn.textContent = 'Дальше (' + (idx + 1) + '/' + steps.length + ')';
+ }
+ }
+ goBtn.addEventListener('click', ()=>{
+ const a = +document.getElementById('p10s-a').value, b = +document.getElementById('p10s-b').value, c = +document.getElementById('p10s-c').value;
+ if(!a){ stage.innerHTML = '$a$ не может быть нулём.
'; renderMath(stage); return; }
+ steps = build(a, b, c); idx = 0; awarded = false;
+ goBtn.style.display = 'none'; nextBtn.style.display = ''; resetBtn.style.display = '';
+ render();
+ });
+ nextBtn.addEventListener('click', ()=>{ if(idx < steps.length - 1){ idx++; render(); } });
+ resetBtn.addEventListener('click', ()=>{
+ idx = 0; steps = []; awarded = false; stage.innerHTML = '';
+ goBtn.style.display = ''; nextBtn.style.display = 'none'; resetBtn.style.display = 'none';
});
})();
@@ -1568,12 +1597,14 @@ function buildP12(){
3) $\\dfrac{x}{x-2} - \\dfrac{2}{x+2} = 1$. ОДЗ: $x \\neq \\pm 2$. Умножим на $(x-2)(x+2)$: $x(x+2) - 2(x-2) = (x-2)(x+2) \\Rightarrow x^2 + 2x - 2x + 4 = x^2 - 4 \\Rightarrow 4 = -4$ — противоречие, корней нет.
`);
/* INT 1 — Биквадратное пошагово */
- html += widget('Решатель биквадратного','INTERACT 1','Введите $a$, $b$, $c$ — система применит замену $t=x^2$ и доведёт до конца.',`
+ html += widget('Решатель биквадратного','INTERACT 1','Введите $a$, $b$, $c$ и нажимайте «Дальше» — шаги замены и решения.',`
-
+
+
+
`);
@@ -1626,33 +1657,59 @@ function buildP12(){
box.innerHTML = html;
if(window.renderMathInElement) setTimeout(()=>renderMath(box), 0);
- /* INIT 1 — Биквадратное */
+ /* INIT 1 — Биквадратное пошагово */
(function(){
- document.getElementById('p12b-go').addEventListener('click', ()=>{
- const a = +document.getElementById('p12b-a').value;
- const b = +document.getElementById('p12b-b').value;
- const c = +document.getElementById('p12b-c').value;
- const out = document.getElementById('p12b-out');
- if(!a){ out.innerHTML = '$a \\neq 0$'; renderMath(out); return; }
- let html = 'Дано: $' + a + 'x^4 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 'x^2 ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + ' = 0$
';
- html += 'Замена $t = x^2,\\ t \\geq 0$: $' + a + 't^2 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 't ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + ' = 0$
';
+ const out = document.getElementById('p12b-out');
+ const goBtn = document.getElementById('p12b-go');
+ const nextBtn = document.getElementById('p12b-next');
+ const resetBtn = document.getElementById('p12b-reset');
+ let steps = [], idx = 0, awarded = false;
+ function build(a, b, c){
+ const arr = [];
+ arr.push('Дано: $' + a + 'x^4 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 'x^2 ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + ' = 0$');
+ arr.push('Замена. Пусть $t = x^2,\\ t \\geq 0$. Получаем $' + a + 't^2 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 't ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + ' = 0$');
const D = b*b - 4*a*c;
- html += 'D = ' + (b*b) + ' − ' + (4*a*c) + ' = ' + D + '
';
- if(D < 0){ html += '$D < 0$ → нет $t$, значит нет $x$.
'; }
- else {
+ arr.push('Дискриминант. $D = ' + (b*b) + ' - ' + (4*a*c) + ' = ' + D + '$');
+ if(D < 0){
+ arr.push('Анализ. $D < 0 \\Rightarrow$ нет $t$, значит нет $x$.');
+ arr.push('Ответ: корней нет.');
+ } else {
const t1 = (-b - Math.sqrt(D))/(2*a), t2 = (-b + Math.sqrt(D))/(2*a);
- html += '$t_1 = ' + fmt(t1) + ',\\ t_2 = ' + fmt(t2) + '$
';
+ arr.push('Корни вспомогательного. $t_1 = ' + fmt(t1) + ',\\ t_2 = ' + fmt(t2) + '$');
const roots = [];
[t1, t2].forEach((t, k)=>{
- if(t > 0){ const r = Math.sqrt(t); roots.push(r, -r); html += '$t_' + (k+1) + ' = ' + fmt(t) + ' > 0 \\Rightarrow x = \\pm' + fmt(r) + '$
'; }
- else if(t === 0){ roots.push(0); html += '$t_' + (k+1) + ' = 0 \\Rightarrow x = 0$
'; }
- else html += '$t_' + (k+1) + ' = ' + fmt(t) + ' < 0$ — не подходит
';
+ if(t > 0){ const r = Math.sqrt(t); roots.push(r, -r); arr.push('Возврат. $t_' + (k+1) + ' = ' + fmt(t) + ' > 0 \\Rightarrow x = \\pm\\sqrt{' + fmt(t) + '} = \\pm' + fmt(r) + '$'); }
+ else if(t === 0){ roots.push(0); arr.push('Возврат. $t_' + (k+1) + ' = 0 \\Rightarrow x = 0$'); }
+ else arr.push('Возврат. $t_' + (k+1) + ' = ' + fmt(t) + ' < 0$ — не подходит, ведь $t \\geq 0$.');
});
const u = [...new Set(roots)].sort((a,b)=>a-b);
- html += 'Ответ: ' + (u.length ? '$\\{' + u.map(fmt).join(';\\ ') + '\\}$' : 'корней нет') + '
';
+ arr.push('Ответ: ' + (u.length ? '$\\{' + u.map(fmt).join(';\\ ') + '\\}$' : 'корней нет'));
}
- out.innerHTML = html; renderMath(out);
- achievement('p12_bi'); bumpProgress('p12', 14);
+ return arr;
+ }
+ function render(){
+ out.innerHTML = steps.slice(0, idx + 1)
+ .map(s => `${s}
`)
+ .join('');
+ renderMath(out);
+ if(idx >= steps.length - 1){
+ nextBtn.disabled = true; nextBtn.textContent = 'Готово';
+ if(!awarded){ awarded = true; achievement('p12_bi'); bumpProgress('p12', 14); confetti(); }
+ } else {
+ nextBtn.disabled = false; nextBtn.textContent = 'Дальше (' + (idx + 1) + '/' + steps.length + ')';
+ }
+ }
+ goBtn.addEventListener('click', ()=>{
+ const a = +document.getElementById('p12b-a').value, b = +document.getElementById('p12b-b').value, c = +document.getElementById('p12b-c').value;
+ if(!a){ out.innerHTML = '$a \\neq 0$'; renderMath(out); return; }
+ steps = build(a, b, c); idx = 0; awarded = false;
+ goBtn.style.display = 'none'; nextBtn.style.display = ''; resetBtn.style.display = '';
+ render();
+ });
+ nextBtn.addEventListener('click', ()=>{ if(idx < steps.length - 1){ idx++; render(); } });
+ resetBtn.addEventListener('click', ()=>{
+ idx = 0; steps = []; awarded = false; out.innerHTML = '';
+ goBtn.style.display = ''; nextBtn.style.display = 'none'; resetBtn.style.display = 'none';
});
})();
@@ -2585,12 +2642,14 @@ function buildP8(){
`);
/* INTERACTIVE 5: пошаговый */
- html += widget('Пошаговый решатель','INTERACT 5','Введите $a$, $b$, $c$ — система разложит решение по шагам.',`
+ html += widget('Пошаговый решатель','INTERACT 5','Введите $a$, $b$, $c$ и нажимайте «Дальше» — каждый шаг появляется отдельно.',`
-
+
+
+
`);
@@ -2755,8 +2814,9 @@ function buildP8(){
const txt = 'x^2 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 'x ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + ' = 0';
document.getElementById('p8t-task').innerHTML = '$' + txt + '$';
document.getElementById('p8t-i').textContent = i;
- document.getElementById('p8t-d-hint').textContent = 'Подскажу: $D = b^2 - 4ac$';
+ document.getElementById('p8t-d-hint').innerHTML = 'Подскажу: $D = b^2 - 4ac$';
renderMath(document.getElementById('p8t-task'));
+ renderMath(document.getElementById('p8t-d-hint'));
document.getElementById('p8t-fb').style.display = 'none';
}
function answer(n){
@@ -2775,25 +2835,66 @@ function buildP8(){
document.getElementById('p8t-0').addEventListener('click', ()=>answer(0));
})();
- /* INIT INTERACTIVE 5 */
+ /* INIT INTERACTIVE 5 — пошаговый по одному шагу */
(function initSteps(){
- document.getElementById('p8s-go').addEventListener('click', ()=>{
+ const stage = document.getElementById('p8s-stage');
+ const goBtn = document.getElementById('p8s-go');
+ const nextBtn = document.getElementById('p8s-next');
+ const resetBtn = document.getElementById('p8s-reset');
+ let steps = [], idx = 0, awarded = false;
+ function buildSteps(a, b, c){
+ const D = b*b - 4*a*c;
+ const arr = [];
+ arr.push('Шаг 1. Выпишем коэффициенты: $a = ' + a + ',\\ b = ' + b + ',\\ c = ' + c + '$');
+ arr.push('Шаг 2. $D = b^2 - 4ac = (' + b + ')^2 - 4 \\cdot (' + a + ') \\cdot (' + c + ') = ' + (b*b) + ' - ' + (4*a*c) + ' = ' + D + '$');
+ arr.push('Шаг 3. ' + (D > 0 ? '$D > 0 \\Rightarrow$ два корня' : D === 0 ? '$D = 0 \\Rightarrow$ один корень' : '$D < 0 \\Rightarrow$ корней нет'));
+ if(D >= 0){
+ arr.push('Шаг 4. $\\sqrt{D} = \\sqrt{' + D + '} = ' + fmt(Math.sqrt(D)) + '$');
+ if(D > 0){
+ const r1 = (-b - Math.sqrt(D))/(2*a), r2 = (-b + Math.sqrt(D))/(2*a);
+ arr.push('Шаг 5. $x_{1,2} = \\dfrac{-b \\pm \\sqrt{D}}{2a} = \\dfrac{' + (-b) + ' \\pm ' + fmt(Math.sqrt(D)) + '}{' + (2*a) + '}$');
+ arr.push('Шаг 6. $x_1 = ' + fmt(r1) + ',\\ x_2 = ' + fmt(r2) + '$');
+ } else {
+ arr.push('Шаг 5. $x = \\dfrac{-b}{2a} = \\dfrac{' + (-b) + '}{' + (2*a) + '} = ' + fmt(-b/(2*a)) + '$');
+ }
+ }
+ arr.push('Ответ: ' + (D > 0 ? 'два корня' : D === 0 ? 'один корень' : 'корней нет'));
+ return arr;
+ }
+ function render(){
+ const html = steps.slice(0, idx + 1)
+ .map((s, k)=>`${s}
`)
+ .join('');
+ stage.innerHTML = html;
+ renderMath(stage);
+ if(idx >= steps.length - 1){
+ nextBtn.disabled = true;
+ nextBtn.textContent = 'Готово';
+ if(!awarded){ awarded = true; achievement('p8_steps'); bumpProgress('p8', 14); confetti(); }
+ } else {
+ nextBtn.disabled = false;
+ nextBtn.textContent = 'Дальше (' + (idx + 1) + '/' + steps.length + ')';
+ }
+ }
+ goBtn.addEventListener('click', ()=>{
const a = +document.getElementById('p8s-a').value;
const b = +document.getElementById('p8s-b').value;
const c = +document.getElementById('p8s-c').value;
- const stage = document.getElementById('p8s-stage');
- if(!a){ stage.innerHTML = '$a$ не может быть нулём.
'; return; }
- const D = b*b - 4*a*c;
- let html = 'Шаг 1: $a = ' + a + ',\\ b = ' + b + ',\\ c = ' + c + '$
';
- html += 'Шаг 2: $D = b^2 - 4ac = ' + b + '^2 - 4 \\cdot ' + a + ' \\cdot ' + c + ' = ' + (b*b) + ' - ' + (4*a*c) + ' = ' + D + '$
';
- html += 'Шаг 3: ' + (D > 0 ? '$D > 0$ → два корня' : D === 0 ? '$D = 0$ → один корень' : '$D < 0$ → корней нет') + '
';
- if(D >= 0){
- html += 'Шаг 4: $\\sqrt{D} = ' + fmt(Math.sqrt(D)) + '$
';
- if(D > 0){ const r1 = (-b - Math.sqrt(D))/(2*a), r2 = (-b + Math.sqrt(D))/(2*a); html += 'Шаг 5: $x_1 = \\dfrac{' + (-b) + ' - ' + fmt(Math.sqrt(D)) + '}{' + (2*a) + '} = ' + fmt(r1) + ',\\ x_2 = ' + fmt(r2) + '$
'; }
- else html += 'Шаг 5: $x = \\dfrac{' + (-b) + '}{' + (2*a) + '} = ' + fmt(-b/(2*a)) + '$
';
- }
- stage.innerHTML = html; renderMath(stage);
- achievement('p8_steps'); bumpProgress('p8', 12);
+ if(!a){ stage.innerHTML = '$a$ не может быть нулём.
'; renderMath(stage); return; }
+ steps = buildSteps(a, b, c);
+ idx = 0; awarded = false;
+ goBtn.style.display = 'none';
+ nextBtn.style.display = ''; resetBtn.style.display = '';
+ nextBtn.disabled = false;
+ render();
+ });
+ nextBtn.addEventListener('click', ()=>{
+ if(idx < steps.length - 1){ idx++; render(); }
+ });
+ resetBtn.addEventListener('click', ()=>{
+ idx = 0; steps = []; awarded = false;
+ stage.innerHTML = '';
+ goBtn.style.display = ''; nextBtn.style.display = 'none'; resetBtn.style.display = 'none';
});
})();