diff --git a/frontend/textbooks/geometry_8_ch2.html b/frontend/textbooks/geometry_8_ch2.html index 923f2d2..202e36d 100644 --- a/frontend/textbooks/geometry_8_ch2.html +++ b/frontend/textbooks/geometry_8_ch2.html @@ -373,7 +373,7 @@ function buildParaSelector(){ const g=document.getElementById('psel-grid');g.inn const BUILT=new Set(); const BUILDERS={ - p1:()=>buildP1stub(),p2:()=>buildP2stub(),p3:()=>buildP3stub(),p4:()=>buildP4stub(),p5:()=>buildP5stub(), + p1:()=>buildP1(),p2:()=>buildP2(),p3:()=>buildP3(),p4:()=>buildP4(),p5:()=>buildP5stub(), p6:()=>buildP6stub(),p7:()=>buildP7stub(),p8:()=>buildP8stub(),p9:()=>buildP9stub(),p10:()=>buildP10stub(), p11:()=>buildP11stub(),p12:()=>buildP12stub(),p13:()=>buildP13stub(),p14:()=>buildP14stub(),p15:()=>buildP15stub(), final2:()=>buildFinal2stub(), @@ -482,10 +482,1182 @@ function initSidebarToggle(){ const side=document.getElementById('col-side'),bac function init(){ loadProgress();initTheme();initSidebarToggle();initGlossaryTip();initSearch();buildParaSelector();refreshProgressUI();loadServerReadState();goTo('p1');setTimeout(()=>achievement('start','Начало главы 2!'),600); if(window.LS&&window.LS.xp){window.LS.xp.load().then(function(s){if(s&&s.xp>STATE.xp){STATE.xp=s.xp;STATE.level=calcLevel(STATE.xp);saveProgress();refreshProgressUI();if(STATE.current)buildSidebar(STATE.current);}});} } document.addEventListener('DOMContentLoaded',init); -function buildP1stub(){ document.getElementById('p1-body').innerHTML='

§1 — Волна 1: содержимое появится в следующем обновлении.

'+secNav(null,'p2'); } -function buildP2stub(){ document.getElementById('p2-body').innerHTML='

§2 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p1','p3'); } -function buildP3stub(){ document.getElementById('p3-body').innerHTML='

§3 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p2','p4'); } -function buildP4stub(){ document.getElementById('p4-body').innerHTML='

§4 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p3','p5'); } +/* ============================================================ + HELPER: setupSorter (drag-and-drop chip sorter) + ============================================================ */ +function setupSorter(cfg){ + const placed={}; const pool=document.getElementById(cfg.poolId); const scope=document.querySelector(cfg.scopeSelector); + if(!pool||!scope) return {placed,render:()=>{},reset:()=>{}}; + pool.classList.add('dnd-pool'); if(cfg.columnLayout) pool.classList.add('col'); + let armed=null; + function buildChip(it,isPlaced){ const e=document.createElement('div'); e.className='dnd-chip'+(isPlaced?' placed':''); e.dataset.id=it.id; e.innerHTML=''+it.html+'\xd7'; attach(e,it.id); return e; } + function attach(elm,itId){ let ghost=null,dragging=false,sx=0,sy=0; elm.addEventListener('pointerdown',ev=>{ if(ev.button!==undefined&&ev.button!==0) return; if(ev.target.classList&&ev.target.classList.contains('dnd-x')){ ev.stopPropagation(); if(placed[itId]){delete placed[itId];render();}else if(armed===itId){armed=null;render();} return; } sx=ev.clientX;sy=ev.clientY; const r=elm.getBoundingClientRect(); const ox=ev.clientX-r.left,oy=ev.clientY-r.top; try{elm.setPointerCapture(ev.pointerId);}catch(e){} function onMove(e){ const dx=e.clientX-sx,dy=e.clientY-sy; if(!dragging&&Math.hypot(dx,dy)>8){ dragging=true; ghost=elm.cloneNode(true); ghost.classList.remove('armed'); ghost.style.cssText='position:fixed;z-index:9999;pointer-events:none;opacity:.9;transform:rotate(-2.5deg);box-shadow:0 14px 36px rgba(0,0,0,.32);width:'+r.width+'px;left:'+(e.clientX-ox)+'px;top:'+(e.clientY-oy)+'px'; document.body.appendChild(ghost); elm.classList.add('dragging'); } if(dragging&&ghost){ ghost.style.left=(e.clientX-ox)+'px';ghost.style.top=(e.clientY-oy)+'px'; const under=document.elementsFromPoint(e.clientX,e.clientY); scope.querySelectorAll('.drop-box.over,.dnd-pool.over').forEach(n=>n.classList.remove('over')); const tgt=under.find(n=>n.classList&&(n.classList.contains('drop-box')||n.classList.contains('dnd-pool'))); if(tgt)tgt.classList.add('over'); } } function onUp(e){ elm.removeEventListener('pointermove',onMove);elm.removeEventListener('pointerup',onUp);elm.removeEventListener('pointercancel',onUp);elm.classList.remove('dragging'); if(ghost){ghost.remove();ghost=null;} scope.querySelectorAll('.drop-box.over,.dnd-pool.over').forEach(n=>n.classList.remove('over')); if(dragging){ const under=document.elementsFromPoint(e.clientX,e.clientY); const box=under.find(n=>n.classList&&n.classList.contains('drop-box')); const pl=under.find(n=>n.classList&&n.classList.contains('dnd-pool')); if(box){const di=box.querySelector('[data-cat]');if(di){placed[itId]=di.dataset.cat;armed=null;render();return;}}else if(pl){delete placed[itId];armed=null;render();return;} }else{ if(placed[itId]){delete placed[itId];armed=null;render();}else{armed=(armed===itId)?null:itId;render();} } dragging=false; } elm.addEventListener('pointermove',onMove);elm.addEventListener('pointerup',onUp);elm.addEventListener('pointercancel',onUp); }); } + function attachBoxTaps(){ scope.querySelectorAll('.drop-box').forEach(box=>{ box.addEventListener('click',ev=>{ if(!armed)return; if(ev.target.closest('.dnd-chip'))return; const di=box.querySelector('[data-cat]'); if(di){placed[armed]=di.dataset.cat;armed=null;render();} }); }); } + function render(){ pool.innerHTML=''; cfg.items.forEach(it=>{if(placed[it.id])return;const c=buildChip(it,false);if(armed===it.id)c.classList.add('armed');pool.appendChild(c);}); cfg.cats.forEach(cat=>{const box=scope.querySelector('.drop-items[data-cat="'+cat+'"]');if(!box)return;box.innerHTML='';cfg.items.forEach(it=>{if(placed[it.id]!==cat)return;box.appendChild(buildChip(it,true));});}); if(window.renderMathInElement)try{renderMath(scope);}catch(_){} } + attachBoxTaps(); render(); + return {placed,render,reset(){ for(const k in placed)delete placed[k];armed=null;render(); }}; +} + +/* ============================================================ + §1 — ПЛОЩАДЬ КВАДРАТА + ============================================================ */ +function buildP1(){ + const box = document.getElementById('p1-body'); + let html = ''; + + html += makeCard('theory','Понятие площади','1.1',` +

Площадь — числовая характеристика плоской фигуры, выражающая её размер. Единица площади — единичный квадрат (квадрат со стороной 1).

+

Аксиомы площади:

+ `); + + html += makeCard('rule','Площадь квадрата','1.2',` +

Если квадрат имеет сторону $a$, то его площадь:

+ $$S = a^2$$ +

Доказательство (идея): квадрат разбивается на $a \\times a = a^2$ единичных квадратов. По аксиоме аддитивности $S = a^2$.

+

Именно поэтому в математике «возведение в квадрат» называется так — это площадь квадрата.

`); + + html += makeCard('rule','Единицы измерения площади','1.3',` + + + + + + + + +
ЕдиницаРавна
$1\\,\\text{км}^2$$10^6\\,\\text{м}^2$
$1\\,\\text{м}^2$$10^4\\,\\text{см}^2 = 10^6\\,\\text{мм}^2$
$1\\,\\text{дм}^2$$100\\,\\text{см}^2$
$1\\,\\text{см}^2$$100\\,\\text{мм}^2$
+

При переводе из крупной единицы в мелкую — умножать, из мелкой в крупную — делить.

`); + + html += makeCard('example','Пример','1.4',` +

Сторона квадрата 7 см. Площадь?
$S = 7^2 = 49\\,\\text{см}^2$.

+

Площадь квадрата 36 дм². Найти сторону.
$a = \\sqrt{36} = 6\\,\\text{дм}$.

+

Перевести 2,5 м² в см².
$2{,}5 \\cdot 10^4 = 25000\\,\\text{см}^2$.

`); + + /* --- INTERACTIVE 1: SVG-квадрат с сеткой --- */ + html += `
+
ИНТЕРАКТИВ 1
Квадрат с сеткой
+
Двигай слайдер — квадрат заполняется единичными клетками. Количество клеток = $a^2$ — это и есть площадь!
+
+ +
+
+
+
+
+
`; + + /* --- INTERACTIVE 2: Калькулятор площади --- */ + html += `
+
ИНТЕРАКТИВ 2
Калькулятор площади квадрата
+
Введи сторону — получи площадь; или введи площадь — получи сторону.
+
+
+
Сторона → Площадь
+
+ + +
+
+
+
+
Площадь → Сторона
+
+ + +
+
+
+
+
`; + + /* --- INTERACTIVE 3: Конвертер единиц --- */ + html += `
+
ИНТЕРАКТИВ 3
Конвертер единиц площади
+
Введи число и выбери единицу — получишь перевод во все остальные единицы.
+
+ + + +
+ +
`; + + /* --- INTERACTIVE 4: Тренажёр --- */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр §1
+
Реши задачи на площадь квадрата и конвертацию единиц. Введи ответ и нажми «Проверить».
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* --- INTERACTIVE 5: Босс §1 --- */ + html += `
+
БОСС §1
Итоговые задачи
+
Реши все 4 задачи — каждая верная даёт +5 XP.
+
+
`; + + html += `
+ +
`; + html += secNav(null,'p2'); + box.innerHTML = html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* == INIT: SVG-сетка == */ + (function(){ + const sl=document.getElementById('p1-grid-a-sl'); + const valEl=document.getElementById('p1-grid-a-val'); + const wrap=document.getElementById('p1-grid-svg-wrap'); + const info=document.getElementById('p1-grid-info'); + function draw(){ + const a=+sl.value; + valEl.textContent=a; + const cell=34, pad=14; + const W=a*cell+pad*2, H=a*cell+pad*2; + let s=''; + // fill cells + for(let r=0;r'; + } + // side label bottom + const midX=pad+a*cell/2, botY=pad+a*cell+11; + s+='a='+a+''; + // side label left + const midY=pad+a*cell/2; + s+='a='+a+''; + s+=''; + wrap.innerHTML=s; + info.innerHTML='
a = '+a+'
= '+a+'² = '+(a*a)+'
S = '+(a*a)+' кл.
'; + } + sl.addEventListener('input',draw); + draw(); + })(); + + /* == INIT: Калькулятор == */ + (function(){ + document.getElementById('p1-calc-go-a').addEventListener('click',()=>{ + const a=parseFloat(document.getElementById('p1-calc-a').value); + const out=document.getElementById('p1-calc-out-a'); + if(!isFinite(a)||a<=0){out.innerHTML='Введи положительное число.';return;} + const S=a*a; + out.innerHTML='$S = '+a+'^2 = '+fmt(S)+'$'; + renderMath(out); addXp(1,'p1-calc'); + }); + document.getElementById('p1-calc-go-s').addEventListener('click',()=>{ + const S=parseFloat(document.getElementById('p1-calc-s').value); + const out=document.getElementById('p1-calc-out-s'); + if(!isFinite(S)||S<=0){out.innerHTML='Введи положительное число.';return;} + const a=Math.sqrt(S); + out.innerHTML='$a = \\sqrt{'+fmt(S)+'} = '+fmt(a)+'$'; + renderMath(out); addXp(1,'p1-calc-inv'); + }); + document.getElementById('p1-calc-a').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p1-calc-go-a').click();}); + document.getElementById('p1-calc-s').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p1-calc-go-s').click();}); + })(); + + /* == INIT: Конвертер == */ + (function(){ + const factors={mm2:1,cm2:100,dm2:1e4,m2:1e6,km2:1e12}; + const labels={mm2:'мм²',cm2:'см²',dm2:'дм²',m2:'м²',km2:'км²'}; + document.getElementById('p1-conv-go').addEventListener('click',()=>{ + const v=parseFloat(document.getElementById('p1-conv-val').value); + const unit=document.getElementById('p1-conv-unit').value; + const out=document.getElementById('p1-conv-out'); + if(!isFinite(v)||v<0){out.style.display='none';return;} + const inMm2=v*factors[unit]; + let rows=''; + for(const [u,f] of Object.entries(factors)){ + const res=inMm2/f; + rows+='
'+labels[u]+': '+fmt(res)+(u===unit?' (исходное)':'')+'
'; + } + out.innerHTML=rows; out.style.display='block'; addXp(2,'p1-conv'); + }); + document.getElementById('p1-conv-val').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p1-conv-go').click();}); + })(); + + /* == INIT: Тренажёр == */ + (function(){ + const tasks=[ + {q:'Сторона квадрата 9 см. Найди площадь (в см²).', ans:81, hint:'S = 9² = 81 см².'}, + {q:'Площадь квадрата 64 м². Найди сторону (в м).', ans:8, hint:'a = √64 = 8 м.'}, + {q:'Переведи 3 м² в см². Ответ в см².', ans:30000, hint:'1 м² = 10 000 см², 3·10 000 = 30 000 см².'}, + {q:'Сторона квадрата 12 дм. Найди площадь в дм².', ans:144, hint:'S = 12² = 144 дм².'}, + {q:'Площадь квадрата 225 мм². Найди сторону в мм.', ans:15, hint:'a = √225 = 15 мм.'}, + ]; + let idx=0,score=0; + function show(){ + document.getElementById('p1-tr-i').textContent=idx+1; + document.getElementById('p1-tr-task').innerHTML=tasks[idx].q; + document.getElementById('p1-tr-ans').value=''; + document.getElementById('p1-tr-fb').style.display='none'; + } + document.getElementById('p1-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p1-tr-score').textContent=0;show();}); + document.getElementById('p1-tr-go').addEventListener('click',()=>{ + if(idx>=tasks.length)return; + const ans=+document.getElementById('p1-tr-ans').value; + const fb=document.getElementById('p1-tr-fb'); + if(Math.abs(ans-tasks[idx].ans)<0.01){ + score++;document.getElementById('p1-tr-score').textContent=score; + addXp(3,'p1-tr-'+idx);bumpProgress('p1',5); + if(idxshow(),900);} + else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p1-tr-all');bumpProgress('p1',10);} + } else { + feedback(fb,false,'Неверно. '+tasks[idx].hint); + } + }); + document.getElementById('p1-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p1-tr-go').click();}); + show(); + })(); + + /* == INIT: Босс §1 == */ + (function(){ + const tasks=[ + {q:'Сторона квадрата 13 см. Площадь (в см²)?', ans:169, hint:'13² = 169.'}, + {q:'Площадь квадрата 196 м². Сторона (в м)?', ans:14, hint:'√196 = 14.'}, + {q:'Переведи 50 000 см² в м². Ответ в м².', ans:5, hint:'50 000 / 10 000 = 5 м².'}, + {q:'Периметр квадрата 28 дм. Площадь в дм²?', ans:49, hint:'a = 28/4 = 7; S = 7² = 49.'}, + ]; + const bossBox=document.getElementById('p1-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + +
+ +
`).join(''); + window.p1BossSolved=new Set(); + })(); +} + +/* ============================================================ + §2 — ПЛОЩАДЬ ПРЯМОУГОЛЬНИКА + ============================================================ */ +function buildP2(){ + const box = document.getElementById('p2-body'); + let html = ''; + + html += makeCard('theory','Площадь прямоугольника','2.1',` +

Теорема. Площадь прямоугольника со сторонами $a$ и $b$:

+ $$S = a \\cdot b$$ +

Доказательство: прямоугольник $a \\times b$ разбивается на $a \\cdot b$ единичных квадратов. По аксиоме аддитивности $S = a \\cdot b$.

+

Квадрат — частный случай прямоугольника при $a = b$: $S = a \\cdot a = a^2$.

`); + + html += makeCard('rule','Периметр и площадь','2.2',` +

Прямоугольник со сторонами $a$ и $b$:

+ $$S = a \\cdot b, \\quad P = 2(a + b)$$ +

Связь: зная $P$ и одну сторону, можно найти вторую: $b = \\dfrac{P}{2} - a$.

`); + + html += makeCard('example','Примеры','2.3',` +

Прямоугольник 6 × 4. Площадь?
$S = 6 \\cdot 4 = 24\\,\\text{см}^2$.

+

Площадь прямоугольника 36 м², одна сторона 9 м. Найти вторую.
$b = 36 / 9 = 4\\,\\text{м}$.

+

Периметр 26 см, одна сторона 3 см. Площадь?
$b = 26/2 - 3 = 10\\,\\text{см}$. $S = 3 \\cdot 10 = 30\\,\\text{см}^2$.

`); + + /* --- INTERACTIVE 1: Draggable прямоугольник --- */ + html += `
+
ИНТЕРАКТИВ 1
Прямоугольник: тяни угол
+
Тащи правый нижний угол мышью или пальцем — меняются стороны и площадь. Сетка показывает разбиение на единичные клетки.
+
+
+
`; + + /* --- INTERACTIVE 2: Калькулятор --- */ + html += `
+
ИНТЕРАКТИВ 2
Калькулятор прямоугольника
+
Введи известные величины и нажми кнопку для нахождения неизвестной.
+
+
+
a, b → S и P
+
+ + + +
+
+
+
+
S, a → b
+
+ + + +
+
+
+
+
`; + + /* --- INTERACTIVE 3: DnD — разложить пары (a,b) для S=24 --- */ + html += `
+
ИНТЕРАКТИВ 3
Какие пары дают площадь 24?
+
Разложи пары $(a, b)$ на «Площадь = 24» и «Площадь ≠ 24». Нажми карточку, затем нужный ящик.
+
+
+
S = 24
+
S ≠ 24
+
+
+ +
`; + + /* --- INTERACTIVE 4: Тренажёр --- */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр §2
+
5 задач на площадь и периметр прямоугольника.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* --- INTERACTIVE 5: Босс §2 --- */ + html += `
+
БОСС §2
Итоговые задачи
+
4 задачи — +5 XP каждая.
+
+
`; + + html += `
+ +
`; + html += secNav('p1','p3'); + box.innerHTML = html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* == INIT: Draggable прямоугольник == */ + (function(){ + const W=340, H=300; + const MIN_CELLS=1, MAX_CELLS=9; + const PAD=30, CELL=24; + let cols=6, rows=4; + function draw(){ + const rw=cols*CELL, rh=rows*CELL; + const x0=PAD, y0=PAD; + let s=''; + // grid cells + for(let r=0;r'; + } + // border + s+=''; + // labels + const midX=x0+rw/2, midY=y0+rh/2; + s+='a = '+cols+''; + s+='b = '+rows+''; + // drag handle (bottom-right corner) + const hx=x0+rw, hy=y0+rh; + s+=''; + s+=''; + s+=''; + const svg=document.getElementById('p2-rect-svg'); + const wrap=document.getElementById('p2-rect-svg-wrap'); + wrap.innerHTML=s; + updateInfo(); + const handle=wrap.querySelector('#p2-drag-handle'); + if(handle){ + handle.addEventListener('pointerdown',ev=>{ + function onMove(e){ + const svgEl=wrap.querySelector('#p2-rect-svg'); + if(!svgEl) return; + const rect=svgEl.getBoundingClientRect(); + const sx=W/rect.width, sy=H/rect.height; + const nx=Math.round(Math.max(MIN_CELLS,Math.min(MAX_CELLS,((e.clientX-rect.left)*sx-PAD)/CELL))); + const ny=Math.round(Math.max(MIN_CELLS,Math.min(MAX_CELLS,((e.clientY-rect.top)*sy-PAD)/CELL))); + if(nx!==cols||ny!==rows){cols=nx;rows=ny;draw();} + } + function onUp(){window.removeEventListener('pointermove',onMove);window.removeEventListener('pointerup',onUp);window.removeEventListener('pointercancel',onUp);} + window.addEventListener('pointermove',onMove); + window.addEventListener('pointerup',onUp); + window.addEventListener('pointercancel',onUp); + }); + } + } + function updateInfo(){ + const S=cols*rows, P=2*(cols+rows); + document.getElementById('p2-rect-info').innerHTML=` +
a
${cols}
+
b
${rows}
+
S = a·b
${S}
+
P = 2(a+b)
${P}
`; + } + draw(); + })(); + + /* == INIT: Калькулятор == */ + (function(){ + document.getElementById('p2-calc-go').addEventListener('click',()=>{ + const a=parseFloat(document.getElementById('p2-calc-a').value); + const b=parseFloat(document.getElementById('p2-calc-b').value); + const out=document.getElementById('p2-calc-out'); + if(!isFinite(a)||!isFinite(b)||a<=0||b<=0){out.innerHTML='Введи положительные числа.';return;} + out.innerHTML='$S = '+fmt(a)+'\\cdot'+fmt(b)+' = '+fmt(a*b)+'$
$P = 2('+fmt(a)+'+'+fmt(b)+') = '+fmt(2*(a+b))+'$'; + renderMath(out); addXp(1,'p2-calc'); + }); + document.getElementById('p2-calc-go2').addEventListener('click',()=>{ + const S=parseFloat(document.getElementById('p2-calc-s').value); + const a=parseFloat(document.getElementById('p2-calc-a2').value); + const out=document.getElementById('p2-calc-out2'); + if(!isFinite(S)||!isFinite(a)||S<=0||a<=0){out.innerHTML='Введи положительные числа.';return;} + const b=S/a; + out.innerHTML='$b = S/a = '+fmt(S)+'/'+fmt(a)+' = '+fmt(b)+'$'; + renderMath(out); addXp(1,'p2-calc-inv'); + }); + })(); + + /* == INIT: DnD == */ + (function(){ + const items=[ + {id:'p1x24',html:'1 × 24',ans:'yes'},{id:'p2x12',html:'2 × 12',ans:'yes'}, + {id:'p3x8', html:'3 × 8', ans:'yes'},{id:'p4x6', html:'4 × 6', ans:'yes'}, + {id:'p5x5', html:'5 × 5', ans:'no'},{id:'p3x9', html:'3 × 9', ans:'no'}, + {id:'p6x5', html:'6 × 5', ans:'no'}, + ]; + const sorter2=setupSorter({poolId:'p2-dnd-pool',scopeSelector:'#p2-dnd-wg',items,cats:['yes','no']}); + document.getElementById('p2-dnd-reset').addEventListener('click',()=>{sorter2.reset();document.getElementById('p2-dnd-fb').style.display='none';}); + document.getElementById('p2-dnd-check').addEventListener('click',()=>{ + let ok=0; + items.forEach(it=>{if(sorter2.placed[it.id]===it.ans)ok++;}); + const fb=document.getElementById('p2-dnd-fb'); + if(ok===items.length){feedback(fb,true,'Все верно! +5 XP');addXp(5,'p2-dnd');bumpProgress('p2',15);} + else feedback(fb,false,'Верно: '+ok+' из '+items.length+'. Перемножь числа и проверь: = 24?'); + }); + })(); + + /* == INIT: Тренажёр == */ + (function(){ + const tasks=[ + {q:'Прямоугольник 7 × 5. Площадь?', ans:35, hint:'S = 7·5 = 35.'}, + {q:'Площадь прямоугольника 48 м², одна сторона 6 м. Вторая сторона?', ans:8, hint:'b = 48/6 = 8.'}, + {q:'Периметр прямоугольника 24 см, одна сторона 4 см. Площадь?', ans:32, hint:'b = 24/2 - 4 = 8; S = 4·8 = 32.'}, + {q:'Прямоугольник 11 × 3. Периметр?', ans:28, hint:'P = 2(11+3) = 28.'}, + {q:'Площадь комнаты 5 × 4 м. Количество плиток 50 × 50 см?', ans:80, hint:'S = 20 м² = 200 000 см². Плитка: 50×50=2500 см². 200 000/2500 = 80.'}, + ]; + let idx=0,score=0; + function show(){ + document.getElementById('p2-tr-i').textContent=idx+1; + document.getElementById('p2-tr-task').innerHTML=tasks[idx].q; + document.getElementById('p2-tr-ans').value=''; + document.getElementById('p2-tr-fb').style.display='none'; + } + document.getElementById('p2-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p2-tr-score').textContent=0;show();}); + document.getElementById('p2-tr-go').addEventListener('click',()=>{ + if(idx>=tasks.length)return; + const ans=+document.getElementById('p2-tr-ans').value; + const fb=document.getElementById('p2-tr-fb'); + if(Math.abs(ans-tasks[idx].ans)<0.5){ + score++;document.getElementById('p2-tr-score').textContent=score; + addXp(3,'p2-tr-'+idx);bumpProgress('p2',5); + if(idxshow(),900);} + else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p2-tr-all');bumpProgress('p2',10);} + } else { + feedback(fb,false,'Неверно. '+tasks[idx].hint); + } + }); + document.getElementById('p2-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p2-tr-go').click();}); + show(); + })(); + + /* == INIT: Босс §2 == */ + (function(){ + const tasks=[ + {q:'Прямоугольник 13 × 8. Площадь?', ans:104, hint:'13·8 = 104.'}, + {q:'Площадь участка 360 м², ширина 15 м. Длина?', ans:24, hint:'360/15 = 24.'}, + {q:'Периметр прямоугольника 34 дм, одна сторона 9 дм. Площадь?', ans:72, hint:'b = 34/2 - 9 = 8; S = 9·8 = 72.'}, + {q:'Квадрат и прямоугольник 9 × 4 имеют равные площади. Сторона квадрата?', ans:6, hint:'S = 36, a = √36 = 6.'}, + ]; + const bossBox=document.getElementById('p2-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + +
+ +
`).join(''); + window.p2BossSolved=new Set(); + })(); +} + +/* ============================================================ + §3 — ПЛОЩАДЬ ПАРАЛЛЕЛОГРАММА + ============================================================ */ +function buildP3(){ + const box = document.getElementById('p3-body'); + let html = ''; + + html += makeCard('theory','Площадь параллелограмма','3.1',` +

Высота параллелограмма — перпендикуляр, опущенный из любой точки одной стороны на другую (параллельную) сторону.

+

Теорема. Площадь параллелограмма равна произведению основания на высоту:

+ $$S = a \\cdot h$$ +

где $a$ — основание (любая сторона), $h$ — высота, опущенная на это основание.

`); + + html += makeCard('rule','Доказательство через прямоугольник','3.2',` +

Идея: от параллелограмма отрезаем боковой прямоугольный треугольник и переносим его на другой конец — получается прямоугольник с теми же основанием $a$ и высотой $h$.

+

По аксиоме аддитивности площади параллелограмм и прямоугольник равновелики:

+ $$S_{\\text{пар}} = S_{\\text{прямоуг}} = a \\cdot h$$ +

Ключевое следствие: два параллелограмма с одним основанием и одинаковой высотой имеют равные площади, даже если выглядят по-разному!

`); + + html += makeCard('example','Примеры','3.3',` +

Параллелограмм, основание 8 см, высота 5 см. Площадь?
$S = 8 \\cdot 5 = 40\\,\\text{см}^2$.

+

Площадь 60 м², основание 12 м. Высота?
$h = 60 / 12 = 5\\,\\text{м}$.

`); + + /* --- INTERACTIVE 1: Draggable параллелограмм (сдвигаем верх) --- */ + html += `
+
ИНТЕРАКТИВ 1
Равноплощадные параллелограммы
+
Тащи верхнее основание влево–вправо. Основание $a$ и высота $h$ не меняются — площадь $S = a \\cdot h$ постоянна!
+
+
+
`; + + /* --- INTERACTIVE 2: Анимация доказательства --- */ + html += `
+
ИНТЕРАКТИВ 2
Доказательство: разрезаем и переставляем
+
Нажимай «Далее» чтобы пройти шаги доказательства формулы $S = a \\cdot h$.
+
+
+
+ + +
+
`; + + /* --- INTERACTIVE 3: Калькулятор --- */ + html += `
+
ИНТЕРАКТИВ 3
Калькулятор параллелограмма
+
Задай два из трёх параметров — найди третий.
+
+
+
a, h → S
+
+ + + +
+
+
+
+
S, h → a
+
+ + + +
+
+
+
+
`; + + /* --- INTERACTIVE 4: Тренажёр --- */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр §3
+
5 задач на площадь параллелограмма.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* --- INTERACTIVE 5: Босс §3 --- */ + html += `
+
БОСС §3
Итоговые задачи
+
4 задачи — +5 XP каждая.
+
+
`; + + html += `
+ +
`; + html += secNav('p2','p4'); + box.innerHTML = html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* == INIT: Draggable параллелограмм == */ + (function(){ + const W=380, H=240; + const BASE_X=50, BASE_Y=190, BASE_W=200, HEIGHT_PX=100; + let shiftX=40; + function draw(){ + const bx=BASE_X, by=BASE_Y, bw=BASE_W, h=HEIGHT_PX; + const x1=bx, x2=bx+bw, x3=bx+bw+shiftX, x4=bx+shiftX; + const y1=by, y2=by, y3=by-h, y4=by-h; + const cx=(x1+x2+x3+x4)/4, cy=(y1+y2+y3+y4)/4; + let s=''; + // height line + const hBaseX=x4+(x1-x4)*0; + s+=''; + s+='h'; + // right angle mark + s+=''; + // polygon + s+=''; + // base label + s+='a'; + // S label + s+='S=a·h'; + // drag handle (upper base midpoint) + const hmx=(x4+x3)/2, hmy=(y4+y3)/2; + s+=''; + s+=''; + s+=''; + document.getElementById('p3-pgram-svg-wrap').innerHTML=s; + document.getElementById('p3-pgram-info').innerHTML=` +
Основание a
${BASE_W} px
+
Высота h
${HEIGHT_PX} px
+
Сдвиг
${shiftX}
+
S = a·h
${BASE_W*HEIGHT_PX}
`; + const handle=document.getElementById('p3-drag-upper'); + if(handle){ + handle.addEventListener('pointerdown',ev=>{ + const startX=ev.clientX, startShift=shiftX; + function onMove(e){ + const svgEl=document.getElementById('p3-pgram-svg'); + if(!svgEl) return; + const rect=svgEl.getBoundingClientRect(); + const scale=W/rect.width; + const delta=Math.round((e.clientX-startX)*scale); + shiftX=Math.max(-80,Math.min(180,startShift+delta)); + draw(); + } + function onUp(){window.removeEventListener('pointermove',onMove);window.removeEventListener('pointerup',onUp);window.removeEventListener('pointercancel',onUp);} + window.addEventListener('pointermove',onMove); + window.addEventListener('pointerup',onUp); + window.addEventListener('pointercancel',onUp); + }); + } + } + draw(); + })(); + + /* == INIT: Анимация доказательства == */ + (function(){ + let step=0; + const W=360, H=200; + const bx=40, by=160, bw=200, H2=100, sh=60; + const steps=[ + { + desc:'Исходный параллелограмм ABCD. Основание AB = a, высота h — перпендикуляр от D к AB.', + draw(){ + const x1=bx,x2=bx+bw,x3=bx+bw+sh,x4=bx+sh; + const y1=by,y2=by,y3=by-H2,y4=by-H2; + return '' + +'' + +'a' + +'h' + +'A' + +'B' + +'C' + +'D'; + } + }, + { + desc:'Проводим высоту DE — перпендикуляр из D на AB. Отрезаем правый треугольник BCE.', + draw(){ + const x1=bx,x2=bx+bw,x3=bx+bw+sh,x4=bx+sh; + const y1=by,y2=by,y3=by-H2,y4=by-H2; + return '' + +'' + +'' + +'Оставшийся трапеция' + +'Треугольник'; + } + }, + { + desc:'Переносим выделенный треугольник на левую сторону. Он встаёт точно на место треугольника ADE.', + draw(){ + const x1=bx,x2=bx+bw,x4=bx+sh; + const y1=by,y2=by,y4=by-H2; + return '' + +'' + +'' + +'Получается прямоугольник!'; + } + }, + { + desc:'Получился прямоугольник со сторонами a и h. Его площадь S = a·h. Значит, и у исходного параллелограмма S = a·h!', + draw(){ + const x1=bx; + return '' + +'a = '+bw+' px' + +'h = '+H2+' px' + +'S = a·h'; + } + }, + ]; + function render(){ + const s=steps[step]; + const svgHtml=''+s.draw()+''; + document.getElementById('p3-proof-svg-wrap').innerHTML=svgHtml; + document.getElementById('p3-proof-desc').innerHTML='Шаг '+(step+1)+' / '+steps.length+'. '+s.desc; + document.getElementById('p3-proof-next').textContent=step{ + if(step{step=0;render();}); + render(); + })(); + + /* == INIT: Калькулятор == */ + (function(){ + document.getElementById('p3-calc-go1').addEventListener('click',()=>{ + const a=parseFloat(document.getElementById('p3-calc-a').value); + const h=parseFloat(document.getElementById('p3-calc-h').value); + const out=document.getElementById('p3-calc-out1'); + if(!isFinite(a)||!isFinite(h)||a<=0||h<=0){out.innerHTML='Введи положительные числа.';return;} + out.innerHTML='$S = '+fmt(a)+'\\cdot'+fmt(h)+' = '+fmt(a*h)+'$'; + renderMath(out); addXp(1,'p3-calc'); + }); + document.getElementById('p3-calc-go2').addEventListener('click',()=>{ + const S=parseFloat(document.getElementById('p3-calc-s').value); + const h=parseFloat(document.getElementById('p3-calc-h2').value); + const out=document.getElementById('p3-calc-out2'); + if(!isFinite(S)||!isFinite(h)||S<=0||h<=0){out.innerHTML='Введи положительные числа.';return;} + out.innerHTML='$a = S/h = '+fmt(S)+'/'+fmt(h)+' = '+fmt(S/h)+'$'; + renderMath(out); addXp(1,'p3-calc-inv'); + }); + })(); + + /* == INIT: Тренажёр == */ + (function(){ + const tasks=[ + {q:'Параллелограмм, основание 10 см, высота 7 см. Площадь?', ans:70, hint:'S = 10·7 = 70.'}, + {q:'Площадь параллелограмма 84 м², высота 6 м. Основание?', ans:14, hint:'a = 84/6 = 14.'}, + {q:'Основание параллелограмма 15 дм, площадь 120 дм². Высота?', ans:8, hint:'h = 120/15 = 8.'}, + {q:'Параллелограмм, сторона 9 см, высота к этой стороне 4 см. Площадь?', ans:36, hint:'S = 9·4 = 36.'}, + {q:'Два параллелограмма: у обоих основание 8, высоты 5 и 5. Какую площадь имеет каждый?', ans:40, hint:'S = 8·5 = 40 — равные площади!'}, + ]; + let idx=0,score=0; + function show(){ + document.getElementById('p3-tr-i').textContent=idx+1; + document.getElementById('p3-tr-task').innerHTML=tasks[idx].q; + document.getElementById('p3-tr-ans').value=''; + document.getElementById('p3-tr-fb').style.display='none'; + } + document.getElementById('p3-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p3-tr-score').textContent=0;show();}); + document.getElementById('p3-tr-go').addEventListener('click',()=>{ + if(idx>=tasks.length)return; + const ans=+document.getElementById('p3-tr-ans').value; + const fb=document.getElementById('p3-tr-fb'); + if(Math.abs(ans-tasks[idx].ans)<0.5){ + score++;document.getElementById('p3-tr-score').textContent=score; + addXp(3,'p3-tr-'+idx);bumpProgress('p3',5); + if(idxshow(),900);} + else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p3-tr-all');bumpProgress('p3',10);} + } else { + feedback(fb,false,'Неверно. '+tasks[idx].hint); + } + }); + document.getElementById('p3-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p3-tr-go').click();}); + show(); + })(); + + /* == INIT: Босс §3 == */ + (function(){ + const tasks=[ + {q:'Параллелограмм, основание 16 дм, высота 9 дм. Площадь?', ans:144, hint:'16·9 = 144.'}, + {q:'Площадь параллелограмма 195 м², основание 15 м. Высота?', ans:13, hint:'195/15 = 13.'}, + {q:'Два параллелограмма с основанием 12 имеют площади 96 и 60. Найди сумму их высот.', ans:13, hint:'h1=96/12=8, h2=60/12=5, сумма=13.'}, + {q:'Параллелограмм, боковая сторона 10 см, высота к ней 6 см. Площадь?', ans:60, hint:'S = 10·6 = 60.'}, + ]; + const bossBox=document.getElementById('p3-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + +
+ +
`).join(''); + window.p3BossSolved=new Set(); + })(); +} + +/* ============================================================ + §4 — ПЛОЩАДЬ ТРЕУГОЛЬНИКА + ============================================================ */ +function buildP4(){ + const box = document.getElementById('p4-body'); + let html = ''; + + html += makeCard('theory','Площадь треугольника','4.1',` +

Высота треугольника — перпендикуляр, опущенный из вершины на противоположную сторону (основание) или её продолжение.

+

Теорема. Площадь треугольника равна половине произведения основания на высоту:

+ $$S = \\dfrac{1}{2} \\cdot a \\cdot h$$ +

где $a$ — основание, $h$ — высота к нему.

`); + + html += makeCard('rule','Доказательство','4.2',` +

Идея: из треугольника $ABC$ строим параллелограмм — копируем треугольник и прикладываем к стороне $AB$. Получается параллелограмм $ABDC$ с тем же основанием $a$ и той же высотой $h$.

+

Площадь параллелограмма: $S_{\\text{пар}} = a \\cdot h$.

+

Треугольник — ровно половина параллелограмма (диагональ делит его на два равных треугольника):

+ $$S_{\\triangle} = \\dfrac{1}{2} \\cdot a \\cdot h$$ +

Важное следствие: треугольники с одним основанием и одинаковой высотой (вершина лежит на прямой, параллельной основанию) имеют равные площади.

`); + + html += makeCard('example','Примеры','4.3',` +

Треугольник, основание 12 см, высота 8 см. Площадь?
$S = \\dfrac{1}{2} \\cdot 12 \\cdot 8 = 48\\,\\text{см}^2$.

+

Площадь 30 м², основание 10 м. Высота?
$h = \\dfrac{2S}{a} = \\dfrac{60}{10} = 6\\,\\text{м}$.

+

Площадь 18 дм², высота 6 дм. Основание?
$a = \\dfrac{2S}{h} = \\dfrac{36}{6} = 6\\,\\text{дм}$.

`); + + /* --- INTERACTIVE 1: Draggable вершина C --- */ + html += `
+
ИНТЕРАКТИВ 1
Равноплощадные треугольники
+
Тащи вершину C вдоль прямой. Основание AB фиксировано, высота не меняется — площадь $S = \\frac{1}{2} \\cdot AB \\cdot h$ постоянна!
+
+
+
`; + + /* --- INTERACTIVE 2: Анимация "достраиваем до параллелограмма" --- */ + html += `
+
ИНТЕРАКТИВ 2
Доказательство: достраиваем до параллелограмма
+
Нажимай «Далее» и смотри, как треугольник превращается в половину параллелограмма.
+
+
+
+ + +
+
`; + + /* --- INTERACTIVE 3: Калькулятор --- */ + html += `
+
ИНТЕРАКТИВ 3
Калькулятор треугольника
+
Введи два из трёх параметров — найди третий.
+
+
+
a, h → S
+
+ + + +
+
+
+
+
S, a → h
+
+ + + +
+
+
+
+
S, h → a
+
+ + + +
+
+
+
+
`; + + /* --- INTERACTIVE 4: Тренажёр --- */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр §4
+
5 задач на площадь треугольника.
+
Задача 1 / 5Очки: 0
+
+
+ + + +
+ +
`; + + /* --- INTERACTIVE 5: Босс §4 --- */ + html += `
+
БОСС §4
Итоговые задачи
+
4 задачи — +5 XP каждая.
+
+
`; + + html += `
+ +
`; + html += secNav('p3','p5'); + box.innerHTML = html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box),0); + + /* == INIT: Draggable вершина C == */ + (function(){ + const W=380, H=240; + const Ax=60, Ay=190, Bx=280, By=190; + const BASE=Bx-Ax, H_FIX=100; + let Cx=170; + const Cy=Ay-H_FIX; + function draw(){ + const S=0.5*BASE*H_FIX; + let s=''; + // parallel line (locus of C) + s+=''; + s+='Прямая C'; + // height line + s+=''; + // right angle mark + s+=''; + s+='h'; + // triangle + s+=''; + // AB label + s+='a = AB = '+BASE+''; + // S label — cx and cy both from triangle centroid + const lx=(Ax+Bx+Cx)/3, ly=(Ay+By+Cy)/3; + s+='S = '+S+''; + // vertex labels + s+='A'; + s+='B'; + s+='C'; + // C drag handle + s+=''; + s+=''; + s+=''; + document.getElementById('p4-tri-svg-wrap').innerHTML=s; + document.getElementById('p4-tri-info').innerHTML=` +
Основание a
${BASE}
+
Высота h
${H_FIX}
+
S = ½·a·h
${S}
`; + const handle=document.getElementById('p4-drag-c'); + if(handle){ + handle.addEventListener('pointerdown',ev=>{ + function onMove(e){ + const svgEl=document.getElementById('p4-tri-svg'); + if(!svgEl) return; + const rect=svgEl.getBoundingClientRect(); + const scale=W/rect.width; + const nx=Math.max(10,Math.min(W-10,(e.clientX-rect.left)*scale)); + Cx=Math.round(nx); + draw(); + } + function onUp(){window.removeEventListener('pointermove',onMove);window.removeEventListener('pointerup',onUp);window.removeEventListener('pointercancel',onUp);} + window.addEventListener('pointermove',onMove); + window.addEventListener('pointerup',onUp); + window.addEventListener('pointercancel',onUp); + }); + } + } + draw(); + })(); + + /* == INIT: Анимация доказательства == */ + (function(){ + let step=0; + const W=380, H=230; + const Ax=60,Ay=190,Bx=260,By=190,Cx=160,Cy=90; + // mirror of C relative to midpoint of AB gives D + const Dx=Ax+Bx-Cx, Dy=Ay+By-Cy; + const steps=[ + { + desc:'Исходный треугольник ABC. Основание AB = a, высота h из вершины C.', + draw(){ + return '' + +'' + +'a' + +'h' + +'A' + +'B' + +'C'; + } + }, + { + desc:'Берём копию треугольника ABC и поворачиваем её на 180° вокруг середины AB. Вершина C переходит в точку D.', + draw(){ + return '' + +'' + +'' + +'D' + +'C'; + } + }, + { + desc:'Треугольники ABC и ABD вместе образуют параллелограмм ACBD. Обе его диагонали — это AB и CD.', + draw(){ + return '' + +'' + +'' + +'Параллелограмм'; + } + }, + { + desc:'Параллелограмм = два равных треугольника. S(пар) = a·h. Значит S(△) = ½·a·h!', + draw(){ + return '' + +'' + +'½·a·h' + +'½·a·h'; + } + }, + ]; + function render(){ + const s=steps[step]; + document.getElementById('p4-proof-svg-wrap').innerHTML=''+s.draw()+''; + document.getElementById('p4-proof-desc').innerHTML='Шаг '+(step+1)+' / '+steps.length+'. '+s.desc; + document.getElementById('p4-proof-next').textContent=step{ + if(step{step=0;render();}); + render(); + })(); + + /* == INIT: Калькулятор == */ + (function(){ + document.getElementById('p4-calc-go1').addEventListener('click',()=>{ + const a=parseFloat(document.getElementById('p4-calc-a').value); + const h=parseFloat(document.getElementById('p4-calc-h').value); + const out=document.getElementById('p4-calc-out1'); + if(!isFinite(a)||!isFinite(h)||a<=0||h<=0){out.innerHTML='Введи положительные числа.';return;} + out.innerHTML='$S = \\frac{1}{2}\\cdot'+fmt(a)+'\\cdot'+fmt(h)+' = '+fmt(0.5*a*h)+'$'; + renderMath(out); addXp(1,'p4-calc'); + }); + document.getElementById('p4-calc-go2').addEventListener('click',()=>{ + const S=parseFloat(document.getElementById('p4-calc-s2').value); + const a=parseFloat(document.getElementById('p4-calc-a2').value); + const out=document.getElementById('p4-calc-out2'); + if(!isFinite(S)||!isFinite(a)||S<=0||a<=0){out.innerHTML='Введи положительные числа.';return;} + out.innerHTML='$h = \\frac{2S}{a} = \\frac{2\\cdot'+fmt(S)+'}{'+fmt(a)+'} = '+fmt(2*S/a)+'$'; + renderMath(out); addXp(1,'p4-calc-h'); + }); + document.getElementById('p4-calc-go3').addEventListener('click',()=>{ + const S=parseFloat(document.getElementById('p4-calc-s3').value); + const h=parseFloat(document.getElementById('p4-calc-h3').value); + const out=document.getElementById('p4-calc-out3'); + if(!isFinite(S)||!isFinite(h)||S<=0||h<=0){out.innerHTML='Введи положительные числа.';return;} + out.innerHTML='$a = \\frac{2S}{h} = \\frac{2\\cdot'+fmt(S)+'}{'+fmt(h)+'} = '+fmt(2*S/h)+'$'; + renderMath(out); addXp(1,'p4-calc-a'); + }); + })(); + + /* == INIT: Тренажёр == */ + (function(){ + const tasks=[ + {q:'Треугольник, основание 14 см, высота 6 см. Площадь?', ans:42, hint:'S = ½·14·6 = 42.'}, + {q:'Площадь треугольника 45 м², высота 9 м. Основание?', ans:10, hint:'a = 2·45/9 = 10.'}, + {q:'Площадь треугольника 36 дм², основание 12 дм. Высота?', ans:6, hint:'h = 2·36/12 = 6.'}, + {q:'Прямоугольный треугольник, катеты 8 см и 6 см. Площадь?', ans:24, hint:'S = ½·8·6 = 24.'}, + {q:'Площадь параллелограмма 80 м². Площадь треугольника на том же основании и высоте?', ans:40, hint:'S(△) = S(пар)/2 = 40.'}, + ]; + let idx=0,score=0; + function show(){ + document.getElementById('p4-tr-i').textContent=idx+1; + document.getElementById('p4-tr-task').innerHTML=tasks[idx].q; + document.getElementById('p4-tr-ans').value=''; + document.getElementById('p4-tr-fb').style.display='none'; + } + document.getElementById('p4-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p4-tr-score').textContent=0;show();}); + document.getElementById('p4-tr-go').addEventListener('click',()=>{ + if(idx>=tasks.length)return; + const ans=+document.getElementById('p4-tr-ans').value; + const fb=document.getElementById('p4-tr-fb'); + if(Math.abs(ans-tasks[idx].ans)<0.5){ + score++;document.getElementById('p4-tr-score').textContent=score; + addXp(3,'p4-tr-'+idx);bumpProgress('p4',5); + if(idxshow(),900);} + else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p4-tr-all');bumpProgress('p4',10);} + } else { + feedback(fb,false,'Неверно. '+tasks[idx].hint); + } + }); + document.getElementById('p4-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p4-tr-go').click();}); + show(); + })(); + + /* == INIT: Босс §4 == */ + (function(){ + const tasks=[ + {q:'Треугольник, основание 18 дм, высота 10 дм. Площадь?', ans:90, hint:'½·18·10 = 90.'}, + {q:'Площадь треугольника 56 м², основание 14 м. Высота?', ans:8, hint:'h = 2·56/14 = 8.'}, + {q:'Квадрат со стороной 6 см. Диагональ делит его на 2 треугольника. Площадь каждого?', ans:18, hint:'S(кв) = 36; S(△) = 36/2 = 18.'}, + {q:'Параллелограмм, основание 20 м, высота 7 м. Площадь вписанного треугольника (того же основания и высоты)?', ans:70, hint:'S(пар) = 140; S(△) = 70.'}, + ]; + const bossBox=document.getElementById('p4-boss-tasks'); + bossBox.innerHTML=tasks.map((t,i)=>` +
+
${t.q}
+
+ + +
+ +
`).join(''); + window.p4BossSolved=new Set(); + })(); +} function buildP5stub(){ document.getElementById('p5-body').innerHTML='

§5 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p4','p6'); } function buildP6stub(){ document.getElementById('p6-body').innerHTML='

§6 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p5','p7'); } function buildP7stub(){ document.getElementById('p7-body').innerHTML='

§7 — Волна 1: содержимое появится в следующем обновлении.

'+secNav('p6','p8'); }