feat(geom8): Wave 4 Главы 3 — §8-§9 (биссектриса, отношение площадей подобных)

§8 Свойство биссектрисы треугольника: SVG с слайдерами AB/AC/BC,
автоматическое построение точки D на BC через BD/DC=AB/AC, цветовая
подсветка отрезков BD/DC; 5-шаговое доказательство через параллель
CE∥AD, равнобедренный △ACE и теорему Фалеса; калькулятор BD,DC по
сторонам; DnD верна ли пропорция; тренажёр; босс.

§9 Отношение площадей подобных треугольников: SVG двух подобных
треугольников со слайдерами k=0.5..3 и S₂, live S₁=k²·S₂;
5-шаговое доказательство через S=½·a·h и подстановку отношений;
двухрежимный калькулятор (k,S₂→S₁ или S₁,S₂→k=√(S₁/S₂)); DnD
по k²=4 vs k²=9; mini-quiz из 5 вопросов с обобщением на произвольные
подобные фигуры; тренажёр; босс.

File: 3234 → 4095 LOC. Все 9 §§ Главы 3 готовы.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-05-28 15:04:15 +03:00
parent f9f6a04c88
commit 8d4eab659c
+864 -3
View File
@@ -339,7 +339,7 @@ const PARAS=[
function buildParaSelector(){const g=document.getElementById('psel-grid');g.innerHTML='';PARAS.forEach(p=>{const card=document.createElement('div');card.className='psel-card'+(p.final?' final':'');card.dataset.id=p.id;card.dataset.progCard=p.id;card.innerHTML=`<div class="psel-num">${p.num}</div><div class="psel-name">${p.name}</div><div class="psel-prog"><div class="psel-prog-fill"></div></div>`;card.addEventListener('click',()=>goTo(p.id));g.appendChild(card);});}
const BUILT=new Set();
const BUILDERS={p1:()=>buildP1(),p2:()=>buildP2(),p3:()=>buildP3(),p4:()=>buildP4(),p5:()=>buildP5(),p6:()=>buildP6(),p7:()=>buildP7(),p8:()=>buildP8stub(),p9:()=>buildP9stub(),final3:()=>buildFinal3stub()};
const BUILDERS={p1:()=>buildP1(),p2:()=>buildP2(),p3:()=>buildP3(),p4:()=>buildP4(),p5:()=>buildP5(),p6:()=>buildP6(),p7:()=>buildP7(),p8:()=>buildP8(),p9:()=>buildP9(),final3:()=>buildFinal3stub()};
function ensureBuilt(id){if(BUILT.has(id))return;const fn=BUILDERS[id];if(fn){fn();BUILT.add(id);}}
function goTo(id){STATE.current=id;ensureBuilt(id);document.querySelectorAll('.sec').forEach(s=>s.classList.remove('active'));const el=document.getElementById('sec-'+id);if(el)el.classList.add('active');document.querySelectorAll('.psel-card').forEach(c=>c.classList.toggle('active',c.dataset.id===id));buildSidebar(id);window.scrollTo({top:0,behavior:'smooth'});if((STATE.progress[id]||0)<10)bumpProgress(id,10);if(window.renderMathInElement)setTimeout(()=>renderMath(el),0);setTimeout(()=>{try{wrapGlossary(el);}catch(e){}},60);markLastPara(id);}
@@ -3226,8 +3226,869 @@ function buildP7(){
renderMath(bossBox);
})();
}
function buildP8stub(){ document.getElementById('p8-body').innerHTML='<div class="card"><div class="card-body"><p><b>§8 — Волна 1</b>: содержимое появится в следующем обновлении.</p></div></div>'+secNav('p7','p9'); }
function buildP9stub(){ document.getElementById('p9-body').innerHTML='<div class="card"><div class="card-body"><p><b>§9 — Волна 1</b>: содержимое появится в следующем обновлении.</p></div></div>'+secNav('p8','final3'); }
function buildP8(){
const box=document.getElementById('p8-body');
let html='';
/* ---- Theory cards ---- */
html+=makeCard('theory','Свойство биссектрисы треугольника','8.1',`
<p><b>Теорема.</b> Биссектриса угла треугольника делит противоположную сторону на отрезки, пропорциональные двум другим сторонам.</p>
<p style="margin-top:8px">В $\\triangle ABC$, $AD$ — биссектриса $\\angle A$ ($D \\in BC$). Тогда:</p>
$$\\dfrac{BD}{DC} = \\dfrac{AB}{AC} = \\dfrac{c}{b}$$
<p style="margin-top:8px">Здесь $c = AB$, $b = AC$. Биссектриса делит отрезок $BC$ в отношении смежных (прилежащих к нему) сторон.</p>
<div style="display:flex;justify-content:center;margin-top:14px">
<svg viewBox="0 0 300 180" style="max-width:320px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<!-- Triangle: A=(150,18), B=(30,162), C=(270,162) -->
<!-- Bisector of angle A: splits BC in ratio AB:AC -->
<!-- AB = sqrt((150-30)^2+(18-162)^2) = sqrt(14400+20736) = sqrt(35136) ≈ 187.4 -->
<!-- AC = sqrt((150-270)^2+(18-162)^2) = sqrt(14400+20736) ≈ 187.4 (isoceles here) -->
<!-- Let's use asymmetric: A=(120,18), B=(30,162), C=(260,162) -->
<!-- AB = sqrt(90^2+144^2)=sqrt(8100+20736)=sqrt(28836)≈169.8, AC=sqrt(140^2+144^2)=sqrt(19600+20736)=sqrt(40336)≈200.8 -->
<!-- D divides BC: BD/DC = AB/AC = 169.8/200.8 ≈ 0.846 → BD = 230*0.846/1.846 ≈ 105.5, D=(30+105.5,162)=(135.5,162) -->
<polygon points="120,18 30,162 260,162" fill="rgba(192,38,211,.1)" stroke="#c026d3" stroke-width="2"/>
<!-- bisector AD -->
<line x1="120" y1="18" x2="136" y2="162" stroke="#f59e0b" stroke-width="2.5" stroke-dasharray="6,3"/>
<!-- D point -->
<circle cx="136" cy="162" r="4" fill="#f59e0b"/>
<!-- BD in green, DC in blue -->
<line x1="30" y1="162" x2="136" y2="162" stroke="#10b981" stroke-width="3"/>
<line x1="136" y1="162" x2="260" y2="162" stroke="#6366f1" stroke-width="3"/>
<!-- Labels -->
<text x="120" y="12" text-anchor="middle" font-size="11" font-weight="800" fill="#a21caf">A</text>
<text x="18" y="170" font-size="11" font-weight="800" fill="#a21caf">B</text>
<text x="262" y="170" font-size="11" font-weight="800" fill="#a21caf">C</text>
<text x="136" y="175" text-anchor="middle" font-size="10" font-weight="800" fill="#b45309">D</text>
<!-- Side labels -->
<text x="66" y="90" text-anchor="middle" font-size="10" fill="#c026d3" font-style="italic" font-weight="700">c=AB</text>
<text x="198" y="90" text-anchor="middle" font-size="10" fill="#c026d3" font-style="italic" font-weight="700">b=AC</text>
<!-- BD, DC labels -->
<text x="83" y="155" text-anchor="middle" font-size="10" fill="#10b981" font-weight="800">BD</text>
<text x="198" y="155" text-anchor="middle" font-size="10" fill="#6366f1" font-weight="800">DC</text>
<!-- AD label -->
<text x="135" y="85" text-anchor="start" font-size="9" fill="#b45309" font-weight="700">AD — биссектриса</text>
<text x="150" y="12" text-anchor="middle" font-size="9" fill="#c026d3" font-weight="800">BD/DC = AB/AC = c/b</text>
</svg>
</div>`);
html+=makeCard('rule','Доказательство — через параллельную прямую','8.2',`
<p><b>Метод доказательства:</b> через точку $C$ проводим прямую, параллельную биссектрисе $AD$, до пересечения с продолжением стороны $AB$ в точке $E$.</p>
<ol style="margin-left:18px;margin-top:8px;line-height:2">
<li>$CE \\parallel AD$, $AD$ — биссектриса $\\angle A$ → $\\angle 1 = \\angle 2$ (смежно-внутренние при секущей $AB$).</li>
<li>$\\angle 2 = \\angle 3$ (вертикальные углы при пересечении $CE$ и $AB$ ... скорректировано: соответственные углы при параллельных). Значит $\\angle 1 = \\angle 3$, т.е. $\\triangle ACE$ — равнобедренный: $AE = AC = b$.</li>
<li>По теореме Фалеса (прямая $AD \\parallel CE$, секущие $BA$ и $BC$): $\\dfrac{BD}{DC} = \\dfrac{BA}{AE} = \\dfrac{c}{b}$.</li>
</ol>
<p style="margin-top:8px"><b>Итог:</b> $\\dfrac{BD}{DC} = \\dfrac{c}{b} = \\dfrac{AB}{AC}$. <b>Теорема доказана.</b></p>
<div style="display:flex;justify-content:center;margin-top:12px">
<svg viewBox="0 0 300 175" style="max-width:320px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<!-- A=(120,18), B=(30,162), C=(260,162), D=(136,162) -->
<!-- E on extension of BA: CE || AD -->
<!-- E = A + t*(A-B) direction. Since CE||AD, by construction E≈(190,18) as approximate -->
<polygon points="120,18 30,162 260,162" fill="rgba(192,38,211,.08)" stroke="#c026d3" stroke-width="1.5"/>
<!-- bisector AD -->
<line x1="120" y1="18" x2="136" y2="162" stroke="#f59e0b" stroke-width="2" stroke-dasharray="5,3"/>
<!-- CE parallel to AD, from C(260,162) toward E -->
<!-- E roughly at (208,18) for illustration -->
<line x1="260" y1="162" x2="208" y2="18" stroke="#10b981" stroke-width="2" stroke-dasharray="5,3"/>
<!-- extension of AB to E: A=(120,18), B=(30,162); direction (90,144). E=(120+t*90, 18+t*144) where E.x≈208 → t≈0.978 → E≈(208,159)? No, let's just draw E above A -->
<!-- E is on ray from B through A extended beyond A: E=(192,18) approx -->
<line x1="30" y1="162" x2="192" y2="18" stroke="#6366f1" stroke-width="1.5" stroke-dasharray="4,2"/>
<circle cx="192" cy="18" r="4" fill="#6366f1"/>
<circle cx="136" cy="162" r="4" fill="#f59e0b"/>
<circle cx="260" cy="162" r="4" fill="#c026d3"/>
<text x="120" y="13" text-anchor="middle" font-size="10" font-weight="800" fill="#a21caf">A</text>
<text x="20" y="170" font-size="10" font-weight="800" fill="#a21caf">B</text>
<text x="262" y="170" font-size="10" font-weight="800" fill="#a21caf">C</text>
<text x="136" y="175" text-anchor="middle" font-size="9" font-weight="800" fill="#b45309">D</text>
<text x="194" y="13" text-anchor="start" font-size="10" font-weight="800" fill="#4f46e5">E</text>
<text x="160" y="100" font-size="9" fill="#10b981" font-weight="700">CE ∥ AD</text>
<text x="150" y="12" text-anchor="middle" font-size="9" fill="#c026d3" font-weight="700">BD/DC = BA/AE = c/b</text>
</svg>
</div>`);
html+=makeCard('example','Примеры применения','8.3',`
<p><b>Пример 1.</b> В $\\triangle ABC$ биссектриса $\\angle A$ делит $BC$. $AB=6$, $AC=9$, $BC=15$. Найти $BD$ и $DC$.</p>
<p style="margin-top:6px">$\\dfrac{BD}{DC} = \\dfrac{AB}{AC} = \\dfrac{6}{9} = \\dfrac{2}{3}$. Сумма $BD+DC=15$. Тогда $BD = \\dfrac{2}{5} \\cdot 15 = 6$, $DC = 9$.</p>
<p style="margin-top:10px"><b>Пример 2.</b> $AB=8$, $AC=12$, $BD=4$. Найти $DC$.</p>
<p style="margin-top:6px">$\\dfrac{4}{DC} = \\dfrac{8}{12}$ → $DC = \\dfrac{4 \\cdot 12}{8} = 6$.</p>
<p style="margin-top:10px"><b>Пример 3.</b> $BD=5$, $DC=7$. Найти $AB$, если $AC=14$.</p>
<p style="margin-top:6px">$\\dfrac{AB}{AC} = \\dfrac{BD}{DC} = \\dfrac{5}{7}$ → $AB = \\dfrac{5 \\cdot 14}{7} = 10$.</p>`);
/* ---- ИНТЕРАКТИВ 1: SVG с биссектрисой (слайдеры AB, AC) ---- */
html+=`<div class="wg" id="p8-svg-wg">
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Биссектриса $AD$ — живая пропорция</div></div>
<div class="wg-help">Меняй стороны $AB$ и $AC$ — точка $D$ автоматически делит $BC$ в отношении $AB:AC$. Цвета: BD — зелёный, DC — синий.</div>
<div class="sliders">
<label>$AB = c$: <b id="p8-c-val">6</b>
<input type="range" min="2" max="14" value="6" id="p8-c-sl" step="1">
</label>
<label>$AC = b$: <b id="p8-b-val">9</b>
<input type="range" min="2" max="14" value="9" id="p8-b-sl" step="1">
</label>
<label>$BC$: <b id="p8-a-val">12</b>
<input type="range" min="4" max="20" value="12" id="p8-a-sl" step="1">
</label>
</div>
<div id="p8-svg-out" style="display:flex;justify-content:center"></div>
<div id="p8-svg-info" style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft,var(--pri-soft));border-radius:10px;font-size:.92rem;line-height:1.8"></div>
</div>`;
/* ---- ИНТЕРАКТИВ 2: Пошаговое доказательство ---- */
html+=`<div class="wg" id="p8-proof-wg">
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Доказательство — по шагам</div></div>
<div class="wg-help">Нажимай «Далее» для каждого шага. Доказательство через параллельную прямую.</div>
<div id="p8-proof-svg" style="display:flex;justify-content:center;margin-bottom:10px"></div>
<div id="p8-proof-desc" style="padding:10px 14px;background:var(--sec-acc-soft,var(--pri-soft));border-radius:10px;font-size:.95rem;line-height:1.6;margin-bottom:10px;min-height:60px"></div>
<div style="display:flex;gap:8px">
<button class="btn primary" id="p8-proof-next">Далее</button>
<button class="btn" id="p8-proof-reset">Сначала</button>
</div>
</div>`;
/* ---- ИНТЕРАКТИВ 3: Калькулятор биссектрисы ---- */
html+=`<div class="wg">
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Калькулятор: AB, AC, BC → BD и DC</div></div>
<div class="wg-help">Введи три стороны треугольника и получи отрезки $BD$, $DC$, которые образует биссектриса.</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(90px,1fr));gap:8px;margin-bottom:10px">
<div><span style="font-size:.8rem;color:var(--muted);display:block">AB = c</span><input type="number" id="p8-kc" class="tinp" placeholder="напр. 6" style="width:100%"></div>
<div><span style="font-size:.8rem;color:var(--muted);display:block">AC = b</span><input type="number" id="p8-kb" class="tinp" placeholder="напр. 9" style="width:100%"></div>
<div><span style="font-size:.8rem;color:var(--muted);display:block">BC</span><input type="number" id="p8-ka" class="tinp" placeholder="напр. 15" style="width:100%"></div>
<div style="display:flex;align-items:flex-end"><button class="btn primary" id="p8-kcalc" style="width:100%">Вычислить</button></div>
</div>
<div id="p8-kcalc-out" style="display:none;padding:10px 14px;background:var(--sec-acc-soft,var(--pri-soft));border-radius:10px;font-size:.95rem;line-height:1.7"></div>
</div>`;
/* ---- ИНТЕРАКТИВ 4: Тренажёр ---- */
html+=`<div class="wg">
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр §8 — Биссектриса</div></div>
<div class="wg-help">5 задач на нахождение отрезков BD, DC и сторон по свойству биссектрисы.</div>
<div class="score-display"><span>Задача <b id="p8-tr-i">1</b> / 5</span><span>Очки: <b id="p8-tr-score">0</b></span></div>
<div id="p8-tr-task" style="padding:14px;background:var(--sec-acc-soft,var(--pri-soft));border-radius:10px;font-size:1.02rem;margin-bottom:10px"></div>
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">
<input type="number" id="p8-tr-ans" class="tinp" placeholder="Ответ" style="width:130px">
<button class="btn primary" id="p8-tr-go">Проверить</button>
<button class="btn" id="p8-tr-start">Начать</button>
</div>
<div class="feedback" id="p8-tr-fb" style="display:none"></div>
</div>`;
/* ---- ИНТЕРАКТИВ 5: DnD-сортер ---- */
html+=`<div class="wg">
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 5</span><div class="wg-title">Верное деление или нет? — Сортировка</div></div>
<div class="wg-help">Перетащи каждую карточку: если биссектриса с данными $AB$, $AC$ действительно делит $BC$ в указанном отношении — в «Верно», иначе — «Неверно».</div>
<div id="p8-dnd-pool" class="dnd-pool"></div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:10px">
<div class="drop-box" id="p8-drop-yes"><h5>Верно (BD/DC = AB/AC)</h5><div class="drop-items" id="p8-drop-yes-items"></div></div>
<div class="drop-box" id="p8-drop-no"><h5>Неверно</h5><div class="drop-items" id="p8-drop-no-items"></div></div>
</div>
<div class="actions"><button class="btn primary" id="p8-dnd-check">Проверить</button><button class="btn" id="p8-dnd-reset">Сбросить</button></div>
<div class="feedback" id="p8-dnd-fb" style="display:none"></div>
</div>`;
/* ---- ИНТЕРАКТИВ 6: Босс §8 ---- */
html+=`<div class="wg" style="border-color:var(--sec-acc-d,var(--pri2))">
<div class="wg-header"><span class="wg-badge" style="background:var(--sec-acc-d,var(--pri2))">БОСС §8</span><div class="wg-title">Итоговые задачи</div></div>
<div class="wg-help">4 задачи — каждая верная даёт +5 XP.</div>
<div id="p8-boss-tasks"></div>
</div>`;
html+=`<div style="margin-top:18px;display:flex;justify-content:center">
<button class="btn primary" id="p8-read-btn" onclick="addXp(10,'p8-read');bumpProgress('p8',40);this.textContent='Прочитано!';this.disabled=true;">
<svg class="ic" viewBox="0 0 24 24"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>
Я прочитал §8 (+10 XP)
</button>
</div>`;
html+=secNav('p7','p9');
box.innerHTML=html;
if(window.renderMathInElement) setTimeout(()=>renderMath(box),0);
/* == INIT ИНТЕРАКТИВ 1: живой SVG биссектрисы == */
(function(){
const cSl=document.getElementById('p8-c-sl');
const bSl=document.getElementById('p8-b-sl');
const aSl=document.getElementById('p8-a-sl');
const cVal=document.getElementById('p8-c-val');
const bVal=document.getElementById('p8-b-val');
const aVal=document.getElementById('p8-a-val');
const svgOut=document.getElementById('p8-svg-out');
const infoEl=document.getElementById('p8-svg-info');
function draw(){
const c=+cSl.value, b=+bSl.value, a=+aSl.value;
cVal.textContent=c; bVal.textContent=b; aVal.textContent=a;
// Triangle: B=(40,170), C=(40+a*16,170) — scaled horizontally
// A somewhere above — use fixed A position for clear view
// Place B at left, C at right on baseline, A above
const W=400, H=200;
const scale=Math.min(14, Math.floor(320/a));
const Bx=40, By=170;
const Cx=Bx+a*scale, Cy=170;
// A: place using sides c=AB, b=AC
// AB=c, AC=b. Place A using cosine rule for angle B:
// cos B = (c^2 + a^2 - b^2)/(2*c*a)
const cosB=(c*c+a*a-b*b)/(2*c*a);
if(cosB<-0.999||cosB>0.999||!isFinite(cosB)){
svgOut.innerHTML='<div style="color:var(--bad);padding:10px">Нарушено треугольное неравенство. Измени стороны.</div>';
infoEl.innerHTML='Некорректные стороны.';
return;
}
const sinB=Math.sqrt(1-cosB*cosB);
const Ax=Bx+c*scale*cosB;
const Ay=By-c*scale*sinB;
// D divides BC: BD/DC = c/b → BD = a*c/(b+c)
const BD=a*c/(b+c);
const DC=a*b/(b+c);
const Dx=Bx+BD*scale;
const Dy=By;
let s=`<svg viewBox="0 0 ${W} ${H}" style="max-width:${W}px;width:100%;background:#fafafa;border:1px solid var(--border);border-radius:10px">`;
// triangle
s+=`<polygon points="${Ax},${Ay} ${Bx},${By} ${Cx},${Cy}" fill="rgba(192,38,211,.09)" stroke="#c026d3" stroke-width="2"/>`;
// BD segment green
s+=`<line x1="${Bx}" y1="${By}" x2="${Dx}" y2="${Dy}" stroke="#10b981" stroke-width="3.5"/>`;
// DC segment blue
s+=`<line x1="${Dx}" y1="${Dy}" x2="${Cx}" y2="${Cy}" stroke="#6366f1" stroke-width="3.5"/>`;
// bisector AD
s+=`<line x1="${Ax}" y1="${Ay}" x2="${Dx}" y2="${Dy}" stroke="#f59e0b" stroke-width="2.5" stroke-dasharray="6,3"/>`;
// D point
s+=`<circle cx="${Dx}" cy="${Dy}" r="5" fill="#f59e0b"/>`;
// Vertices
s+=`<circle cx="${Ax}" cy="${Ay}" r="4.5" fill="#c026d3"/>`;
s+=`<circle cx="${Bx}" cy="${By}" r="4.5" fill="#c026d3"/>`;
s+=`<circle cx="${Cx}" cy="${Cy}" r="4.5" fill="#c026d3"/>`;
// Labels
const ax=Ax, ay=Ay;
s+=`<text x="${ax}" y="${ay-7}" text-anchor="middle" font-size="12" font-weight="800" fill="#a21caf">A</text>`;
s+=`<text x="${Bx-10}" y="${By+4}" font-size="12" font-weight="800" fill="#a21caf">B</text>`;
s+=`<text x="${Cx+4}" y="${Cy+4}" font-size="12" font-weight="800" fill="#a21caf">C</text>`;
s+=`<text x="${Dx}" y="${Dy+16}" text-anchor="middle" font-size="11" font-weight="800" fill="#b45309">D</text>`;
// Side labels
const mABx=(ax+Bx)/2, mABy=(ay+By)/2;
const mACx=(ax+Cx)/2, mACy=(ay+Cy)/2;
s+=`<text x="${mABx-10}" y="${mABy}" text-anchor="end" font-size="10" fill="#c026d3" font-weight="700">c=${c}</text>`;
s+=`<text x="${mACx+10}" y="${mACy}" font-size="10" fill="#c026d3" font-weight="700">b=${b}</text>`;
// BD DC midpoints
const mBDx=(Bx+Dx)/2, mDCx=(Dx+Cx)/2;
s+=`<text x="${mBDx}" y="${By-7}" text-anchor="middle" font-size="10" fill="#10b981" font-weight="800">BD=${fmt(BD)}</text>`;
s+=`<text x="${mDCx}" y="${Cy-7}" text-anchor="middle" font-size="10" fill="#6366f1" font-weight="800">DC=${fmt(DC)}</text>`;
s+=`<text x="${W/2}" y="14" text-anchor="middle" font-size="10" fill="#c026d3" font-weight="800">BD/DC = ${fmt(BD)}/${fmt(DC)} = ${fmt(c)}/${fmt(b)} = ${fmt(c/b)}</text>`;
s+='</svg>';
svgOut.innerHTML=s;
infoEl.innerHTML=`$AB=c=${c}$, $AC=b=${b}$, $BC=${a}$. Биссектриса $AD$ делит $BC$: $BD=${fmt(BD)}$, $DC=${fmt(DC)}$. $\\dfrac{BD}{DC}=\\dfrac{${c}}{${b}}=${fmt(c/b)}$ — совпадает с $\\dfrac{AB}{AC}$.`;
renderMath(infoEl);
addXp(1,'p8-svg');
}
cSl.addEventListener('input',draw);
bSl.addEventListener('input',draw);
aSl.addEventListener('input',draw);
draw();
})();
/* == INIT ИНТЕРАКТИВ 2: пошаговое доказательство == */
(function(){
const steps=[
{desc:'<b>Шаг 1.</b> Дано: $\\triangle ABC$, $AD$ — биссектриса $\\angle A$ ($D \\in BC$). Нужно доказать: $\\dfrac{BD}{DC} = \\dfrac{AB}{AC}$.',
svg:`<svg viewBox="0 0 280 155" style="max-width:280px;background:#fafafa;border:1px solid var(--border);border-radius:10px"><polygon points="120,18 30,145 250,145" fill="rgba(192,38,211,.09)" stroke="#c026d3" stroke-width="2"/><line x1="120" y1="18" x2="140" y2="145" stroke="#f59e0b" stroke-width="2.5" stroke-dasharray="5,3"/><circle cx="140" cy="145" r="4" fill="#f59e0b"/><text x="120" y="13" text-anchor="middle" font-size="11" font-weight="800" fill="#a21caf">A</text><text x="20" y="152" font-size="11" font-weight="800" fill="#a21caf">B</text><text x="252" y="152" font-size="11" font-weight="800" fill="#a21caf">C</text><text x="140" y="158" text-anchor="middle" font-size="10" font-weight="800" fill="#b45309">D</text><text x="140" y="12" text-anchor="middle" font-size="9" fill="#c026d3" font-weight="700">AD — биссектриса ∠A, D ∈ BC</text></svg>`},
{desc:'<b>Шаг 2.</b> Через вершину $C$ проводим прямую $CE \\parallel AD$ до пересечения с продолжением стороны $AB$ в точке $E$.',
svg:`<svg viewBox="0 0 280 165" style="max-width:280px;background:#fafafa;border:1px solid var(--border);border-radius:10px"><polygon points="110,22 30,150 240,150" fill="rgba(192,38,211,.08)" stroke="#c026d3" stroke-width="1.5"/><line x1="110" y1="22" x2="130" y2="150" stroke="#f59e0b" stroke-width="2" stroke-dasharray="5,3"/><line x1="240" y1="150" x2="190" y2="22" stroke="#10b981" stroke-width="2" stroke-dasharray="6,2"/><line x1="30" y1="150" x2="210" y2="22" stroke="#6366f1" stroke-width="1.5" stroke-dasharray="3,2"/><circle cx="190" cy="22" r="4" fill="#6366f1"/><circle cx="130" cy="150" r="4" fill="#f59e0b"/><text x="110" y="16" text-anchor="middle" font-size="10" font-weight="800" fill="#a21caf">A</text><text x="20" y="158" font-size="10" font-weight="800" fill="#a21caf">B</text><text x="242" y="158" font-size="10" font-weight="800" fill="#a21caf">C</text><text x="130" y="162" text-anchor="middle" font-size="9" font-weight="800" fill="#b45309">D</text><text x="192" y="16" font-size="10" font-weight="800" fill="#4f46e5">E</text><text x="210" y="100" font-size="9" fill="#10b981" font-weight="700">CE ∥ AD</text></svg>`},
{desc:'<b>Шаг 3.</b> Так как $CE \\parallel AD$ и $AD$ — биссектриса: $\\angle 1 = \\angle DAB$ (смежно-внутренние при секущей $AB$), $\\angle 2 = \\angle DAC$ (соответственные при секущей $AC$). Поскольку $\\angle DAB = \\angle DAC$ (биссектриса!), то $\\angle 1 = \\angle 2$. В $\\triangle ACE$: $\\angle AEC = \\angle 1$, $\\angle ACE = \\angle 2$ → $\\angle AEC = \\angle ACE$ → $\\triangle ACE$ равнобедренный, $AE = AC = b$.',
svg:`<svg viewBox="0 0 280 100" style="max-width:280px;background:#fafafa;border:1px solid var(--border);border-radius:10px"><text x="140" y="22" text-anchor="middle" font-size="11" fill="#c026d3" font-weight="700">CE ∥ AD, AD — биссектриса ∠A</text><text x="140" y="42" text-anchor="middle" font-size="11" fill="#10b981" font-weight="700">∠AEC = ∠ACE → △ACE равнобедренный</text><text x="140" y="62" text-anchor="middle" font-size="12" fill="#a21caf" font-weight="800">AE = AC = b</text><text x="140" y="85" text-anchor="middle" font-size="10" fill="#6366f1">Ключевой шаг доказательства</text></svg>`},
{desc:'<b>Шаг 4.</b> По теореме Фалеса (параллельные $AD \\parallel CE$, секущие $BA$ и $BC$):<br>$\\dfrac{BD}{DC} = \\dfrac{BA}{AE}$.',
svg:`<svg viewBox="0 0 280 90" style="max-width:280px;background:#fafafa;border:1px solid var(--border);border-radius:10px"><text x="140" y="24" text-anchor="middle" font-size="11" fill="#4338ca" font-weight="800">Теорема Фалеса: AD ∥ CE</text><text x="140" y="46" text-anchor="middle" font-size="12" fill="#c026d3" font-weight="800">BD/DC = BA/AE</text><text x="140" y="68" text-anchor="middle" font-size="10" fill="#6366f1">секущие BA и BC пересекают параллельные AD и CE</text><text x="140" y="85" text-anchor="middle" font-size="9" fill="#10b981">Теорема Фалеса — §1 этой главы</text></svg>`},
{desc:'<b>Шаг 5.</b> Подставляем $AE = AC = b$ (шаг 3): $\\dfrac{BD}{DC} = \\dfrac{BA}{AE} = \\dfrac{c}{b} = \\dfrac{AB}{AC}$. <b>Теорема доказана.</b>',
svg:`<svg viewBox="0 0 280 80" style="max-width:280px;background:#fafafa;border:1px solid var(--border);border-radius:10px"><text x="140" y="26" text-anchor="middle" font-size="12" fill="#c026d3" font-weight="800">BD/DC = BA/AE = c/b = AB/AC</text><text x="140" y="50" text-anchor="middle" font-size="10" fill="#6366f1">Биссектриса делит BC в отношении AB:AC</text><text x="140" y="70" text-anchor="middle" font-size="14" fill="#10b981" font-weight="900">QED ∎</text></svg>`},
];
let step=0;
const svgEl=document.getElementById('p8-proof-svg');
const descEl=document.getElementById('p8-proof-desc');
function show(){svgEl.innerHTML=steps[step].svg;descEl.innerHTML=steps[step].desc;renderMath(descEl);}
document.getElementById('p8-proof-next').addEventListener('click',()=>{
if(step<steps.length-1){step++;show();addXp(1,'p8-proof-step');}
else{addXp(5,'p8-proof-done');bumpProgress('p8',10);}
});
document.getElementById('p8-proof-reset').addEventListener('click',()=>{step=0;show();});
show();
})();
/* == INIT ИНТЕРАКТИВ 3: калькулятор == */
(function(){
document.getElementById('p8-kcalc').addEventListener('click',()=>{
const c=parseFloat(document.getElementById('p8-kc').value);
const b=parseFloat(document.getElementById('p8-kb').value);
const a=parseFloat(document.getElementById('p8-ka').value);
const out=document.getElementById('p8-kcalc-out');
if([c,b,a].some(v=>!isFinite(v)||v<=0)){
out.style.display='block';out.innerHTML='<span style="color:var(--bad)">Введи все три значения (положительные числа).</span>';return;
}
const BD=a*c/(b+c);
const DC=a*b/(b+c);
out.style.display='block';
out.innerHTML=`$\\dfrac{BD}{DC} = \\dfrac{AB}{AC} = \\dfrac{${fmt(c)}}{${fmt(b)}}$.<br>$BC = ${fmt(a)}$, поэтому:<br>$BD = \\dfrac{c}{b+c} \\cdot BC = \\dfrac{${fmt(c)}}{${fmt(b+c)}} \\cdot ${fmt(a)} = <b>${fmt(BD)}</b>$.<br>$DC = \\dfrac{b}{b+c} \\cdot BC = \\dfrac{${fmt(b)}}{${fmt(b+c)}} \\cdot ${fmt(a)} = <b>${fmt(DC)}</b>$.`;
renderMath(out);
addXp(3,'p8-calc');bumpProgress('p8',5);
});
})();
/* == INIT ИНТЕРАКТИВ 4: тренажёр == */
(function(){
const tasks=[
{q:'$\\triangle ABC$: $AB=6$, $AC=9$, $BC=15$. Биссектриса $\\angle A$ делит $BC$ в точке $D$. Найди $BD$.',ans:6,hint:'BD/DC = AB/AC = 6/9 = 2/3. BD = 2/(2+3)·15 = 6.'},
{q:'$\\triangle ABC$: $AB=8$, $AC=12$, $BD=4$. Биссектриса $\\angle A$ делит $BC$ в точке $D$. Найди $DC$.',ans:6,hint:'BD/DC = AB/AC → 4/DC = 8/12 → DC = 4·12/8 = 6.'},
{q:'Биссектриса $\\angle A$ делит $BC$: $BD=5$, $DC=7$, $AC=14$. Найди $AB$.',ans:10,hint:'AB/AC = BD/DC = 5/7 → AB = 5·14/7 = 10.'},
{q:'$\\triangle ABC$: $AB=10$, $AC=15$, $BC=20$. Найди $DC$ (биссектриса $\\angle A$).',ans:12,hint:'DC = b/(b+c)·BC = 15/25·20 = 12.'},
{q:'Биссектриса $\\angle A$: $AB=4$, $AC=6$, $BD=8$. Найди $BC$.',ans:20,hint:'BD/DC = AB/AC = 4/6 = 2/3 → DC = BD·3/2 = 12. BC = BD+DC = 8+12 = 20.'},
];
let idx=0,score=0;
function show(){
document.getElementById('p8-tr-i').textContent=idx+1;
const t=document.getElementById('p8-tr-task');
t.innerHTML=tasks[idx].q;
renderMath(t);
document.getElementById('p8-tr-ans').value='';
document.getElementById('p8-tr-fb').style.display='none';
}
document.getElementById('p8-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p8-tr-score').textContent=0;show();});
document.getElementById('p8-tr-go').addEventListener('click',()=>{
if(idx>=tasks.length)return;
const ans=+document.getElementById('p8-tr-ans').value;
const fb=document.getElementById('p8-tr-fb');
if(Math.abs(ans-tasks[idx].ans)<0.05){
score++;document.getElementById('p8-tr-score').textContent=score;
addXp(3,'p8-tr-'+idx);bumpProgress('p8',4);
if(idx<tasks.length-1){feedback(fb,true,'Верно! +3 XP');idx++;setTimeout(()=>show(),900);}
else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p8-tr-all');bumpProgress('p8',10);confetti();}
} else {
feedback(fb,false,'Неверно. '+tasks[idx].hint);
}
});
document.getElementById('p8-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p8-tr-go').click();});
show();
})();
/* == INIT ИНТЕРАКТИВ 5: DnD-сортер == */
(function(){
const items=[
{text:'AB=6, AC=9, BD=4, DC=6',yes:true},
{text:'AB=5, AC=8, BD=5, DC=8',yes:true},
{text:'AB=4, AC=6, BD=3, DC=5',yes:false},
{text:'AB=10, AC=15, BD=8, DC=12',yes:true},
{text:'AB=3, AC=7, BD=3, DC=5',yes:false},
];
const pool=document.getElementById('p8-dnd-pool');
const yesBox=document.getElementById('p8-drop-yes-items');
const noBox=document.getElementById('p8-drop-no-items');
let dragging=null;
function makeChip(it,i){
const chip=document.createElement('div');
chip.className='dnd-chip';chip.dataset.idx=i;chip.textContent=it.text;chip.draggable=true;
chip.addEventListener('dragstart',e=>{dragging=chip;chip.classList.add('dragging');e.dataTransfer.effectAllowed='move';});
chip.addEventListener('dragend',()=>{chip.classList.remove('dragging');dragging=null;});
return chip;
}
items.forEach((it,i)=>pool.appendChild(makeChip(it,i)));
[document.getElementById('p8-drop-yes'),document.getElementById('p8-drop-no'),pool].forEach(box=>{
box.addEventListener('dragover',e=>{e.preventDefault();box.classList.add('over');});
box.addEventListener('dragleave',()=>box.classList.remove('over'));
box.addEventListener('drop',e=>{
e.preventDefault();box.classList.remove('over');
if(!dragging)return;
const target=box===document.getElementById('p8-drop-yes')?yesBox:box===document.getElementById('p8-drop-no')?noBox:pool;
target.appendChild(dragging);
});
});
document.getElementById('p8-dnd-check').addEventListener('click',()=>{
const fb=document.getElementById('p8-dnd-fb');
const yChips=[...yesBox.querySelectorAll('.dnd-chip')];
const nChips=[...noBox.querySelectorAll('.dnd-chip')];
if(yChips.length+nChips.length<items.length){feedback(fb,false,'Разложи все карточки.');return;}
let ok=true;
yChips.forEach(c=>{if(!items[+c.dataset.idx].yes)ok=false;});
nChips.forEach(c=>{if(items[+c.dataset.idx].yes)ok=false;});
if(ok){feedback(fb,true,'Верно! +5 XP');addXp(5,'p8-dnd');bumpProgress('p8',8);}
else{feedback(fb,false,'Есть ошибки. Проверь: BD/DC должно равняться AB/AC.');}
});
document.getElementById('p8-dnd-reset').addEventListener('click',()=>{
[...yesBox.children].forEach(c=>pool.appendChild(c));
[...noBox.children].forEach(c=>pool.appendChild(c));
document.getElementById('p8-dnd-fb').style.display='none';
});
})();
/* == INIT: Босс §8 == */
(function(){
const tasks=[
{q:'<svg viewBox="0 0 280 145" style="display:block;max-width:280px;margin:0 auto 8px;background:#fae8ff;border:1px solid #e879f9;border-radius:8px"><polygon points="120,18 30,135 250,135" fill="rgba(192,38,211,.10)" stroke="#c026d3" stroke-width="2"/><line x1="120" y1="18" x2="140" y2="135" stroke="#f59e0b" stroke-width="2.5" stroke-dasharray="5,3"/><line x1="30" y1="135" x2="140" y2="135" stroke="#10b981" stroke-width="3"/><line x1="140" y1="135" x2="250" y2="135" stroke="#6366f1" stroke-width="3"/><circle cx="140" cy="135" r="4" fill="#f59e0b"/><text x="120" y="12" text-anchor="middle" font-size="10" fill="#a21caf" font-weight="800">A</text><text x="20" y="143" font-size="10" fill="#a21caf" font-weight="800">B</text><text x="252" y="143" font-size="10" fill="#a21caf" font-weight="800">C</text><text x="140" y="148" text-anchor="middle" font-size="9" fill="#b45309" font-weight="800">D</text><text x="140" y="10" text-anchor="middle" font-size="8" fill="#c026d3">AB=9, AC=12, BC=21</text></svg>$AB=9$, $AC=12$, $BC=21$. Биссектриса $\\angle A$ делит $BC$ в точке $D$. Найди $BD$.',ans:9,hint:'BD/DC = AB/AC = 9/12 = 3/4. BD = 3/7·21 = 9.'},
{q:'Биссектриса $\\angle A$ делит $BC$: $BD=6$, $DC=10$, $BC=16$. $AB=9$. Найди $AC$.',ans:15,hint:'BD/DC = AB/AC → 6/10 = 9/AC → AC = 9·10/6 = 15.'},
{q:'В $\\triangle ABC$: $AB=7$, $AC=14$, биссектриса $\\angle A$ делит $BC$ на $BD$ и $DC$. Чему равно $BD$, если $BC=12$?',ans:4,hint:'BD = AB/(AB+AC)·BC = 7/21·12 = 4.'},
{q:'Биссектриса $\\angle B$ треугольника $ABC$ делит сторону $AC$ в точке $E$: $AE=6$, $EC=9$. $BC=15$. Найди $AB$.',ans:10,hint:'AE/EC = AB/BC → 6/9 = AB/15 → AB = 6·15/9 = 10.'},
];
const bossBox=document.getElementById('p8-boss-tasks');
bossBox.innerHTML=tasks.map((t,i)=>`
<div style="padding:14px;background:var(--card);border-radius:10px;border:1px solid var(--border);margin-bottom:10px">
<div style="margin-bottom:8px;font-size:.95rem">${t.q}</div>
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:center">
<input type="number" class="tinp" id="p8b-a${i}" placeholder="Ответ" style="width:110px">
<button class="btn primary small" onclick="(function(){
const v=+document.getElementById('p8b-a${i}').value;
const fb=document.getElementById('p8b-fb${i}');
if(Math.abs(v-${t.ans})<0.05){
feedback(fb,true,'Верно! +5 XP');
if(!window.p8BossSolved.has(${i})){ window.p8BossSolved.add(${i}); addXp(5,'p8-boss${i}'); bumpProgress('p8',8); }
} else feedback(fb,false,'Неверно. ${t.hint}');
})()">Проверить</button>
</div>
<div class="feedback" id="p8b-fb${i}" style="display:none;margin-top:8px"></div>
</div>`).join('');
window.p8BossSolved=new Set();
renderMath(bossBox);
})();
}
function buildP9(){
const box=document.getElementById('p9-body');
let html='';
/* ---- Theory cards ---- */
html+=makeCard('theory','Отношение площадей подобных треугольников','9.1',`
<p><b>Теорема.</b> Если $\\triangle ABC \\sim \\triangle A'B'C'$ с коэффициентом подобия $k$, то:</p>
$$\\dfrac{S_{ABC}}{S_{A'B'C'}} = k^2$$
<p style="margin-top:8px">Площади подобных треугольников относятся как <b>квадрат коэффициента подобия</b>. Это означает: при увеличении сторон в $k$ раз площадь вырастает в $k^2$ раз.</p>
<p style="margin-top:8px"><b>Обобщение:</b> отношение площадей любых подобных фигур (многоугольников, кругов) тоже равно $k^2$.</p>
<div style="display:flex;justify-content:center;margin-top:14px">
<svg viewBox="0 0 340 180" style="max-width:360px;background:#fafafa;border:1px solid var(--border);border-radius:10px">
<!-- Large triangle: A=(100,18), B=(20,162), C=(220,162) — S1 -->
<polygon points="100,18 20,162 220,162" fill="rgba(124,58,237,.15)" stroke="#7c3aed" stroke-width="2"/>
<text x="100" y="13" text-anchor="middle" font-size="11" font-weight="800" fill="#6d28d9">A</text>
<text x="10" y="170" font-size="11" font-weight="800" fill="#6d28d9">B</text>
<text x="222" y="170" font-size="11" font-weight="800" fill="#6d28d9">C</text>
<text x="87" y="110" text-anchor="middle" font-size="10" fill="#7c3aed" font-weight="700">S₁</text>
<!-- Small triangle k=2: sides halved: A'=(240,90), B'=(200,162), C'=(300,162) -->
<!-- Original sides: BC=200, AB=~165, AC=~189. k=2 → B'C'=100, A'B'≈82, A'C'≈94 -->
<!-- Place B'=(240,162), C'=(314,162), A'=(270,90)? -->
<!-- Actually let's just use a clearly similar, half-sized triangle -->
<polygon points="270,90 240,162 314,162" fill="rgba(99,102,241,.22)" stroke="#6366f1" stroke-width="1.8"/>
<text x="270" y="85" text-anchor="middle" font-size="10" font-weight="800" fill="#4f46e5">A'</text>
<text x="232" y="170" font-size="10" font-weight="800" fill="#4f46e5">B'</text>
<text x="316" y="170" font-size="10" font-weight="800" fill="#4f46e5">C'</text>
<text x="278" y="140" text-anchor="middle" font-size="9" fill="#6366f1" font-weight="700">S₂</text>
<!-- k label -->
<text x="175" y="12" text-anchor="middle" font-size="10" fill="#f59e0b" font-weight="800">k = 2: S₁/S₂ = k² = 4</text>
<!-- Arrow suggesting scale -->
<text x="235" y="75" font-size="9" fill="#6366f1">k=2</text>
</svg>
</div>`);
html+=makeCard('rule','Доказательство через формулу площади','9.2',`
<p>Пусть $\\triangle ABC \\sim \\triangle A'B'C'$, коэффициент подобия $k$: $AB = k \\cdot A'B'$, $BC = k \\cdot B'C'$ и т.д.</p>
<p style="margin-top:8px">Высоты подобных треугольников тоже относятся как $k$ (высота строится из вершины перпендикулярно к стороне, а все стороны уменьшены в $k$ раз). Обозначим $h$ и $h'$ — высоты к $BC$ и $B'C'$:</p>
$$h = k \\cdot h'$$
<p style="margin-top:8px">Тогда:</p>
$$\\dfrac{S_{ABC}}{S_{A'B'C'}} = \\dfrac{\\tfrac{1}{2} \\cdot BC \\cdot h}{\\tfrac{1}{2} \\cdot B'C' \\cdot h'} = \\dfrac{BC}{B'C'} \\cdot \\dfrac{h}{h'} = k \\cdot k = k^2$$
<p style="margin-top:8px">Обобщение: для любых подобных многоугольников с коэффициентом подобия $k$: $S_1/S_2 = k^2$.</p>`);
html+=makeCard('example','Примеры','9.3',`
<p><b>Пример 1.</b> $\\triangle ABC \\sim \\triangle A'B'C'$, $k=3$, $S_{A'B'C'} = 8$. Найти $S_{ABC}$.</p>
<p style="margin-top:6px">$S_{ABC} = k^2 \\cdot S_{A'B'C'} = 9 \\cdot 8 = 72$.</p>
<p style="margin-top:10px"><b>Пример 2.</b> Стороны двух подобных треугольников — $6$ и $10$. Площадь меньшего — $18$. Найти площадь большего.</p>
<p style="margin-top:6px">$k = 10/6 = 5/3$. $S_2 = k^2 \\cdot S_1 = (5/3)^2 \\cdot 18 = 25/9 \\cdot 18 = 50$.</p>
<p style="margin-top:10px"><b>Пример 3.</b> $S_1 = 48$, $S_2 = 75$. Найти $k = \\sqrt{S_1/S_2}$ ... нет, $k = \\sqrt{S_2/S_1} = \\sqrt{75/48} = \\sqrt{25/16} = 5/4 = 1{,}25$ (если $S_2$ у большего).</p>
<p style="margin-top:6px">$k = \\sqrt{75/48} = \\sqrt{25/16} = 1{,}25$.</p>`);
/* ---- ИНТЕРАКТИВ 1: SVG два треугольника со слайдером k ---- */
html+=`<div class="wg" id="p9-svg-wg">
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Два подобных треугольника: слайдер $k$</div></div>
<div class="wg-help">Меняй $k$ и наблюдай: второй треугольник подобен первому с коэффициентом $k$. Отношение площадей = $k^2$.</div>
<div class="sliders">
<label>Коэффициент $k$: <b id="p9-k-val">2.0</b>
<input type="range" min="10" max="30" value="20" id="p9-k-sl" step="1">
</label>
<label>Площадь $S_2$: <b id="p9-s2-val">12</b>
<input type="range" min="4" max="30" value="12" id="p9-s2-sl" step="1">
</label>
</div>
<div id="p9-svg-out" style="display:flex;justify-content:center"></div>
<div id="p9-svg-info" style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft,var(--pri-soft));border-radius:10px;font-size:.92rem;line-height:1.8"></div>
</div>`;
/* ---- ИНТЕРАКТИВ 2: Пошаговое доказательство ---- */
html+=`<div class="wg" id="p9-proof-wg">
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Доказательство теоремы — по шагам</div></div>
<div class="wg-help">Нажимай «Далее» для каждого шага. Доказательство через формулу площади $S = \\frac{1}{2}ah$.</div>
<div id="p9-proof-svg" style="display:flex;justify-content:center;margin-bottom:10px"></div>
<div id="p9-proof-desc" style="padding:10px 14px;background:var(--sec-acc-soft,var(--pri-soft));border-radius:10px;font-size:.95rem;line-height:1.6;margin-bottom:10px;min-height:60px"></div>
<div style="display:flex;gap:8px">
<button class="btn primary" id="p9-proof-next">Далее</button>
<button class="btn" id="p9-proof-reset">Сначала</button>
</div>
</div>`;
/* ---- ИНТЕРАКТИВ 3: Калькулятор ---- */
html+=`<div class="wg">
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Калькулятор: $k$ и площади</div></div>
<div class="wg-help">Два режима: по $k$ и $S_2$ найти $S_1$; или по двум площадям найти $k$.</div>
<div style="display:flex;gap:14px;flex-wrap:wrap;margin-bottom:10px">
<label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:.88rem"><input type="radio" name="p9-mode" value="0" checked id="p9-m0" style="accent-color:var(--sec-acc,var(--pri))"> По $k$ и $S_2$ → $S_1$</label>
<label style="display:flex;align-items:center;gap:6px;cursor:pointer;font-size:.88rem"><input type="radio" name="p9-mode" value="1" id="p9-m1" style="accent-color:var(--sec-acc,var(--pri))"> По $S_1$, $S_2$ → $k$</label>
</div>
<div id="p9-calc-mode0" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(90px,1fr));gap:8px;margin-bottom:10px">
<div><span style="font-size:.8rem;color:var(--muted);display:block">Коэфф. $k$</span><input type="number" id="p9-ck" class="tinp" placeholder="напр. 3" style="width:100%"></div>
<div><span style="font-size:.8rem;color:var(--muted);display:block">$S_2$ (меньш.)</span><input type="number" id="p9-cs2" class="tinp" placeholder="напр. 8" style="width:100%"></div>
<div style="display:flex;align-items:flex-end"><button class="btn primary" id="p9-ccalc0" style="width:100%">Найти $S_1$</button></div>
</div>
<div id="p9-calc-mode1" style="display:none;grid-template-columns:repeat(auto-fit,minmax(90px,1fr));gap:8px;margin-bottom:10px">
<div><span style="font-size:.8rem;color:var(--muted);display:block">$S_1$ (больш.)</span><input type="number" id="p9-cs1b" class="tinp" placeholder="напр. 72" style="width:100%"></div>
<div><span style="font-size:.8rem;color:var(--muted);display:block">$S_2$ (меньш.)</span><input type="number" id="p9-cs2b" class="tinp" placeholder="напр. 8" style="width:100%"></div>
<div style="display:flex;align-items:flex-end"><button class="btn primary" id="p9-ccalc1" style="width:100%">Найти $k$</button></div>
</div>
<div id="p9-ccalc-out" style="display:none;padding:10px 14px;background:var(--sec-acc-soft,var(--pri-soft));border-radius:10px;font-size:.95rem;line-height:1.7"></div>
</div>`;
/* ---- ИНТЕРАКТИВ 4: Тренажёр ---- */
html+=`<div class="wg">
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр §9 — Площади подобных треугольников</div></div>
<div class="wg-help">5 задач на применение формулы $S_1/S_2 = k^2$.</div>
<div class="score-display"><span>Задача <b id="p9-tr-i">1</b> / 5</span><span>Очки: <b id="p9-tr-score">0</b></span></div>
<div id="p9-tr-task" style="padding:14px;background:var(--sec-acc-soft,var(--pri-soft));border-radius:10px;font-size:1.02rem;margin-bottom:10px"></div>
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">
<input type="number" id="p9-tr-ans" class="tinp" placeholder="Ответ" style="width:130px">
<button class="btn primary" id="p9-tr-go">Проверить</button>
<button class="btn" id="p9-tr-start">Начать</button>
</div>
<div class="feedback" id="p9-tr-fb" style="display:none"></div>
</div>`;
/* ---- ИНТЕРАКТИВ 5: DnD-сортер k → k² ---- */
html+=`<div class="wg">
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 5</span><div class="wg-title">Соотнеси $k$ с отношением площадей $k^2$</div></div>
<div class="wg-help">Перетащи каждую карточку $k$ в колонку с верным $k^2$. Две колонки: «$k^2 = 4$» и «$k^2 = 9$».</div>
<div id="p9-dnd-pool" class="dnd-pool"></div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:10px">
<div class="drop-box" id="p9-drop-4"><h5>$k^2 = 4$</h5><div class="drop-items" id="p9-drop-4-items"></div></div>
<div class="drop-box" id="p9-drop-9"><h5>$k^2 = 9$</h5><div class="drop-items" id="p9-drop-9-items"></div></div>
</div>
<div class="actions"><button class="btn primary" id="p9-dnd-check">Проверить</button><button class="btn" id="p9-dnd-reset">Сбросить</button></div>
<div class="feedback" id="p9-dnd-fb" style="display:none"></div>
</div>`;
/* ---- ИНТЕРАКТИВ 6: Мини-квиз ---- */
html+=`<div class="wg">
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 6</span><div class="wg-title">Мини-квиз: теория §9</div></div>
<div class="wg-help">5 вопросов о площадях подобных фигур. Выбери верный ответ.</div>
<div id="p9-quiz-wrap"></div>
<div class="actions"><button class="btn primary" id="p9-quiz-check">Проверить</button></div>
<div class="feedback" id="p9-quiz-fb" style="display:none"></div>
</div>`;
/* ---- ИНТЕРАКТИВ 7: Босс §9 ---- */
html+=`<div class="wg" style="border-color:var(--sec-acc-d,var(--pri2))">
<div class="wg-header"><span class="wg-badge" style="background:var(--sec-acc-d,var(--pri2))">БОСС §9</span><div class="wg-title">Итоговые задачи</div></div>
<div class="wg-help">4 задачи — каждая верная даёт +5 XP.</div>
<div id="p9-boss-tasks"></div>
</div>`;
html+=`<div style="margin-top:18px;display:flex;justify-content:center">
<button class="btn primary" id="p9-read-btn" onclick="addXp(10,'p9-read');bumpProgress('p9',40);this.textContent='Прочитано!';this.disabled=true;">
<svg class="ic" viewBox="0 0 24 24"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>
Я прочитал §9 (+10 XP)
</button>
</div>`;
html+=secNav('p8','final3');
box.innerHTML=html;
if(window.renderMathInElement) setTimeout(()=>renderMath(box),0);
/* == INIT ИНТЕРАКТИВ 1: SVG два подобных треугольника == */
(function(){
const kSl=document.getElementById('p9-k-sl');
const s2Sl=document.getElementById('p9-s2-sl');
const kVal=document.getElementById('p9-k-val');
const s2Val=document.getElementById('p9-s2-val');
const svgOut=document.getElementById('p9-svg-out');
const infoEl=document.getElementById('p9-svg-info');
function draw(){
const k=+kSl.value/10;
const S2=+s2Sl.value;
const S1=S2*k*k;
kVal.textContent=k.toFixed(1);
s2Val.textContent=S2;
const W=400, H=200;
// Triangle 2 (smaller): fixed base, height from S2 = 1/2 * base * height
// base2 = 120 px (scaled), height2 = 2*S2/base2 — but we use unit scale
// Use a fixed nice triangle shape, scale by k for the bigger one
// Small triangle T2: B2=(240,175), C2=(360,175), A2=(310, 175 - h2)
// base = 120, h2 = 60 px (display). S2 shown as text.
const base2=110;
const h2=60;
const B2x=240, B2y=175;
const C2x=B2x+base2, C2y=175;
const A2x=B2x+base2*0.55, A2y=B2y-h2;
// Large triangle T1 = k * T2, anchored at B1
const base1=base2*k;
const h1=h2*k;
// Place T1 on the left side
const B1x=20, B1y=175;
const C1x=B1x+base1, C1y=175;
const A1x=B1x+base1*0.55, A1y=B1y-h1;
// Safety: check bounds
const maxX=Math.max(C1x, C2x)+10;
const minY=Math.min(A1y, A2y)-14;
let s=`<svg viewBox="0 ${Math.min(0,minY)-5} ${Math.max(W,maxX+10)} ${H}" style="max-width:${W}px;width:100%;background:#fafafa;border:1px solid var(--border);border-radius:10px">`;
// T1 large
s+=`<polygon points="${A1x},${A1y} ${B1x},${B1y} ${C1x},${C1y}" fill="rgba(124,58,237,.16)" stroke="#7c3aed" stroke-width="2.2"/>`;
// Height line T1 (from A1 perpendicular to B1C1)
s+=`<line x1="${A1x}" y1="${A1y}" x2="${A1x}" y2="${B1y}" stroke="#7c3aed" stroke-width="1.2" stroke-dasharray="4,2"/>`;
// right angle marker T1
s+=`<rect x="${A1x}" y="${B1y-12}" width="12" height="12" fill="none" stroke="#7c3aed" stroke-width="1.2"/>`;
s+=`<text x="${A1x}" y="${A1y-6}" text-anchor="middle" font-size="11" font-weight="800" fill="#6d28d9">A</text>`;
s+=`<text x="${B1x-8}" y="${B1y+4}" font-size="11" font-weight="800" fill="#6d28d9">B</text>`;
s+=`<text x="${C1x+4}" y="${C1y+4}" font-size="11" font-weight="800" fill="#6d28d9">C</text>`;
const mBC1x=(B1x+C1x)/2;
s+=`<text x="${mBC1x}" y="${B1y+14}" text-anchor="middle" font-size="10" fill="#7c3aed" font-weight="700">a·k</text>`;
s+=`<text x="${A1x+6}" y="${(A1y+B1y)/2}" font-size="10" fill="#7c3aed" font-weight="700">h·k</text>`;
s+=`<text x="${mBC1x}" y="${A1y+(B1y-A1y)*0.55}" text-anchor="middle" font-size="13" fill="#7c3aed" font-weight="800">S₁=${fmt(S1)}</text>`;
// T2 small
s+=`<polygon points="${A2x},${A2y} ${B2x},${B2y} ${C2x},${C2y}" fill="rgba(99,102,241,.20)" stroke="#6366f1" stroke-width="1.8"/>`;
s+=`<line x1="${A2x}" y1="${A2y}" x2="${A2x}" y2="${B2y}" stroke="#6366f1" stroke-width="1.2" stroke-dasharray="4,2"/>`;
s+=`<rect x="${A2x}" y="${B2y-12}" width="10" height="10" fill="none" stroke="#6366f1" stroke-width="1.2"/>`;
s+=`<text x="${A2x}" y="${A2y-6}" text-anchor="middle" font-size="10" font-weight="800" fill="#4f46e5">A'</text>`;
s+=`<text x="${B2x-10}" y="${B2y+4}" font-size="10" font-weight="800" fill="#4f46e5">B'</text>`;
s+=`<text x="${C2x+4}" y="${C2y+4}" font-size="10" font-weight="800" fill="#4f46e5">C'</text>`;
const mBC2x=(B2x+C2x)/2;
s+=`<text x="${mBC2x}" y="${B2y+14}" text-anchor="middle" font-size="9" fill="#6366f1" font-weight="700">a</text>`;
s+=`<text x="${A2x+5}" y="${(A2y+B2y)/2}" font-size="9" fill="#6366f1" font-weight="700">h</text>`;
s+=`<text x="${mBC2x}" y="${A2y+(B2y-A2y)*0.55}" text-anchor="middle" font-size="11" fill="#6366f1" font-weight="800">S₂=${S2}</text>`;
// top label
s+=`<text x="${W/2}" y="${Math.min(0,minY)+12}" text-anchor="middle" font-size="11" font-weight="800" fill="#7c3aed">k = ${k.toFixed(1)}, S₁/S₂ = k² = ${fmt(k*k)}</text>`;
s+='</svg>';
svgOut.innerHTML=s;
infoEl.innerHTML=`$k=${k.toFixed(1)}$, $S_2=${S2}$. Тогда $S_1 = k^2 \\cdot S_2 = ${k.toFixed(1)}^2 \\cdot ${S2} = ${fmt(k*k)} \\cdot ${S2} = ${fmt(S1)}$. Стороны первого в $${k.toFixed(1)}$ раз больше, площадь — в $${fmt(k*k)}$ раз больше.`;
renderMath(infoEl);
addXp(1,'p9-svg');
}
kSl.addEventListener('input',draw);
s2Sl.addEventListener('input',draw);
draw();
})();
/* == INIT ИНТЕРАКТИВ 2: пошаговое доказательство == */
(function(){
const steps=[
{desc:'<b>Шаг 1.</b> Дано: $\\triangle ABC \\sim \\triangle A\'B\'C\'$, коэффициент подобия $k$. Нужно доказать: $\\dfrac{S_{ABC}}{S_{A\'B\'C\'}} = k^2$.',
svg:`<svg viewBox="0 0 300 155" style="max-width:300px;background:#fafafa;border:1px solid var(--border);border-radius:10px"><polygon points="100,18 20,140 220,140" fill="rgba(124,58,237,.12)" stroke="#7c3aed" stroke-width="2"/><polygon points="240,80 212,140 300,140" fill="rgba(99,102,241,.20)" stroke="#6366f1" stroke-width="1.8"/><text x="100" y="13" text-anchor="middle" font-size="11" font-weight="800" fill="#6d28d9">A</text><text x="10" y="148" font-size="11" font-weight="800" fill="#6d28d9">B</text><text x="222" y="148" font-size="11" font-weight="800" fill="#6d28d9">C</text><text x="240" y="75" text-anchor="middle" font-size="10" font-weight="800" fill="#4f46e5">A\'</text><text x="204" y="148" font-size="10" font-weight="800" fill="#4f46e5">B\'</text><text x="302" y="148" font-size="10" font-weight="800" fill="#4f46e5">C\'</text><text x="150" y="12" text-anchor="middle" font-size="10" fill="#f59e0b" font-weight="800">△ABC △A\'B\'C\', коэфф. k</text></svg>`},
{desc:'<b>Шаг 2.</b> Из подобия: $BC = k \\cdot B\'C\'$ (основание). Проведём высоты $BH \\perp AC$ и $B\'H\' \\perp A\'C\'$. Так как $\\triangle ABH \\sim \\triangle A\'B\'H\'$ (тот же коэффициент $k$), то $BH = k \\cdot B\'H\'$.',
svg:`<svg viewBox="0 0 300 145" style="max-width:300px;background:#fafafa;border:1px solid var(--border);border-radius:10px"><polygon points="100,18 20,135 220,135" fill="rgba(124,58,237,.10)" stroke="#7c3aed" stroke-width="1.5"/><line x1="100" y1="18" x2="100" y2="135" stroke="#7c3aed" stroke-width="2" stroke-dasharray="5,3"/><text x="100" y="13" text-anchor="middle" font-size="10" font-weight="800" fill="#6d28d9">A</text><text x="10" y="143" font-size="10" font-weight="800" fill="#6d28d9">B</text><text x="222" y="143" font-size="10" font-weight="800" fill="#6d28d9">C</text><text x="104" y="70" font-size="9" fill="#7c3aed">h = k·h\'</text><rect x="100" y="127" width="10" height="10" fill="none" stroke="#7c3aed" stroke-width="1.5"/><text x="100" y="143" text-anchor="middle" font-size="9" fill="#7c3aed">H</text><text x="150" y="12" text-anchor="middle" font-size="9" fill="#c026d3" font-weight="700">BC = k·B\'C\', BH = k·B\'H\'</text></svg>`},
{desc:'<b>Шаг 3.</b> Запишем формулу площади для каждого треугольника: $S_{ABC} = \\dfrac{1}{2} \\cdot BC \\cdot h$, $S_{A\'B\'C\'} = \\dfrac{1}{2} \\cdot B\'C\' \\cdot h\'$.',
svg:`<svg viewBox="0 0 300 90" style="max-width:300px;background:#fafafa;border:1px solid var(--border);border-radius:10px"><text x="150" y="22" text-anchor="middle" font-size="12" fill="#7c3aed" font-weight="700">S = ½ · BC · h</text><text x="150" y="44" text-anchor="middle" font-size="12" fill="#6366f1" font-weight="700">S\' = ½ · B\'C\' · h\'</text><text x="150" y="70" text-anchor="middle" font-size="10" fill="#6d28d9">Формула площади треугольника через основание и высоту</text></svg>`},
{desc:'<b>Шаг 4.</b> Составим отношение:<br>$\\dfrac{S_{ABC}}{S_{A\'B\'C\'}} = \\dfrac{\\frac{1}{2} \\cdot BC \\cdot h}{\\frac{1}{2} \\cdot B\'C\' \\cdot h\'} = \\dfrac{BC}{B\'C\'} \\cdot \\dfrac{h}{h\'} = k \\cdot k = k^2$.',
svg:`<svg viewBox="0 0 300 85" style="max-width:300px;background:#fafafa;border:1px solid var(--border);border-radius:10px"><text x="150" y="24" text-anchor="middle" font-size="11" fill="#4338ca" font-weight="800">S₁/S₂ = (BC/B\'C\')·(h/h\') = k·k = k²</text><text x="150" y="50" text-anchor="middle" font-size="10" fill="#6366f1">BC = k·B\'C\' и h = k·h\'</text><text x="150" y="72" text-anchor="middle" font-size="12" fill="#10b981" font-weight="800">S₁/S₂ = k²</text></svg>`},
{desc:'<b>Шаг 5.</b> <b>Обобщение:</b> для любых подобных многоугольников с коэффициентом $k$ разбиваем их на треугольники с тем же коэффициентом подобия. Сумма площадей каждого треугольника второй фигуры умножена на $k^2$. Значит $S_1/S_2 = k^2$ — верно для любых подобных фигур. <b>Теорема доказана.</b>',
svg:`<svg viewBox="0 0 300 80" style="max-width:300px;background:#fafafa;border:1px solid var(--border);border-radius:10px"><text x="150" y="28" text-anchor="middle" font-size="13" fill="#7c3aed" font-weight="800">S₁/S₂ = k² для подобных △</text><text x="150" y="52" text-anchor="middle" font-size="10" fill="#6366f1">Обобщается на любые подобные фигуры</text><text x="150" y="72" text-anchor="middle" font-size="14" fill="#10b981" font-weight="900">QED ∎</text></svg>`},
];
let step=0;
const svgEl=document.getElementById('p9-proof-svg');
const descEl=document.getElementById('p9-proof-desc');
function show(){svgEl.innerHTML=steps[step].svg;descEl.innerHTML=steps[step].desc;renderMath(descEl);}
document.getElementById('p9-proof-next').addEventListener('click',()=>{
if(step<steps.length-1){step++;show();addXp(1,'p9-proof-step');}
else{addXp(5,'p9-proof-done');bumpProgress('p9',10);}
});
document.getElementById('p9-proof-reset').addEventListener('click',()=>{step=0;show();});
show();
})();
/* == INIT ИНТЕРАКТИВ 3: калькулятор == */
(function(){
document.querySelectorAll('input[name="p9-mode"]').forEach(r=>{
r.addEventListener('change',()=>{
const m=+r.value;
document.getElementById('p9-calc-mode0').style.display=m===0?'grid':'none';
document.getElementById('p9-calc-mode1').style.display=m===1?'grid':'none';
document.getElementById('p9-ccalc-out').style.display='none';
});
});
document.getElementById('p9-ccalc0').addEventListener('click',()=>{
const k=parseFloat(document.getElementById('p9-ck').value);
const s2=parseFloat(document.getElementById('p9-cs2').value);
const out=document.getElementById('p9-ccalc-out');
if(!isFinite(k)||k<=0||!isFinite(s2)||s2<=0){
out.style.display='block';out.innerHTML='<span style="color:var(--bad)">Введи $k > 0$ и $S_2 > 0$.</span>';renderMath(out);return;
}
const s1=s2*k*k;
out.style.display='block';
out.innerHTML=`$k = ${fmt(k)}$, $S_2 = ${fmt(s2)}$.<br>$S_1 = k^2 \\cdot S_2 = ${fmt(k)}^2 \\cdot ${fmt(s2)} = ${fmt(k*k)} \\cdot ${fmt(s2)} = <b>${fmt(s1)}</b>$.`;
renderMath(out);addXp(3,'p9-calc0');bumpProgress('p9',5);
});
document.getElementById('p9-ccalc1').addEventListener('click',()=>{
const s1=parseFloat(document.getElementById('p9-cs1b').value);
const s2=parseFloat(document.getElementById('p9-cs2b').value);
const out=document.getElementById('p9-ccalc-out');
if(!isFinite(s1)||s1<=0||!isFinite(s2)||s2<=0){
out.style.display='block';out.innerHTML='<span style="color:var(--bad)">Введи $S_1 > 0$ и $S_2 > 0$.</span>';renderMath(out);return;
}
const k=Math.sqrt(s1/s2);
out.style.display='block';
out.innerHTML=`$S_1 = ${fmt(s1)}$, $S_2 = ${fmt(s2)}$.<br>$k = \\sqrt{S_1/S_2} = \\sqrt{${fmt(s1)}/${fmt(s2)}} = \\sqrt{${fmt(s1/s2)}} = <b>${fmt(k)}</b>$.`;
renderMath(out);addXp(3,'p9-calc1');bumpProgress('p9',5);
});
})();
/* == INIT ИНТЕРАКТИВ 4: тренажёр == */
(function(){
const tasks=[
{q:'$\\triangle ABC \\sim \\triangle A\'B\'C\'$, $k=3$, $S_{A\'B\'C\'}=8$. Найди $S_{ABC}$.',ans:72,hint:'S = k²·S\' = 9·8 = 72.'},
{q:'$\\triangle ABC \\sim \\triangle A\'B\'C\'$, $S_{ABC}=50$, $S_{A\'B\'C\'}=8$. Найди $k$.',ans:2.5,hint:'k = √(S/S\') = √(50/8) = √(6.25) = 2.5.'},
{q:'Стороны двух подобных треугольников — $6$ и $10$. Площадь меньшего — $18$. Найди площадь большего.',ans:50,hint:'k = 10/6 = 5/3. S₁ = (5/3)²·18 = 25/9·18 = 50.'},
{q:'$\\triangle ABC \\sim \\triangle A\'B\'C\'$, $k=4$. На сколько $S_{ABC}$ больше $S_{A\'B\'C\'}$? (Во сколько раз — введи число.)',ans:16,hint:'S₁/S₂ = k² = 16. Площадь больше в 16 раз.'},
{q:'Площади двух подобных треугольников: $S_1=48$, $S_2=75$. Найди $k = \\sqrt{S_2/S_1}$ (большего к меньшему).',ans:1.25,hint:'k = √(75/48) = √(25/16) = 5/4 = 1.25.'},
];
let idx=0,score=0;
function show(){
document.getElementById('p9-tr-i').textContent=idx+1;
const t=document.getElementById('p9-tr-task');
t.innerHTML=tasks[idx].q;
renderMath(t);
document.getElementById('p9-tr-ans').value='';
document.getElementById('p9-tr-fb').style.display='none';
}
document.getElementById('p9-tr-start').addEventListener('click',()=>{idx=0;score=0;document.getElementById('p9-tr-score').textContent=0;show();});
document.getElementById('p9-tr-go').addEventListener('click',()=>{
if(idx>=tasks.length)return;
const ans=+document.getElementById('p9-tr-ans').value;
const fb=document.getElementById('p9-tr-fb');
if(Math.abs(ans-tasks[idx].ans)<0.05){
score++;document.getElementById('p9-tr-score').textContent=score;
addXp(3,'p9-tr-'+idx);bumpProgress('p9',4);
if(idx<tasks.length-1){feedback(fb,true,'Верно! +3 XP');idx++;setTimeout(()=>show(),900);}
else{feedback(fb,true,'Все задачи решены! +5 XP');addXp(5,'p9-tr-all');bumpProgress('p9',10);confetti();}
} else {
feedback(fb,false,'Неверно. '+tasks[idx].hint);
}
});
document.getElementById('p9-tr-ans').addEventListener('keydown',e=>{if(e.key==='Enter')document.getElementById('p9-tr-go').click();});
show();
})();
/* == INIT ИНТЕРАКТИВ 5: DnD-сортер k → k² == */
(function(){
// items: k value → which bucket k²=4 (k=2) or k²=9 (k=3)
const items=[
{text:'k = 2',group:4},
{text:'k = 3',group:9},
{text:'√4 = 2',group:4},
{text:'S₁/S₂ = 4',group:4},
{text:'S₁/S₂ = 9',group:9},
{text:'k = √9 = 3',group:9},
];
const pool=document.getElementById('p9-dnd-pool');
const box4=document.getElementById('p9-drop-4-items');
const box9=document.getElementById('p9-drop-9-items');
let dragging=null;
function makeChip(it,i){
const chip=document.createElement('div');
chip.className='dnd-chip';chip.dataset.idx=i;chip.textContent=it.text;chip.draggable=true;
chip.addEventListener('dragstart',e=>{dragging=chip;chip.classList.add('dragging');e.dataTransfer.effectAllowed='move';});
chip.addEventListener('dragend',()=>{chip.classList.remove('dragging');dragging=null;});
return chip;
}
items.forEach((it,i)=>pool.appendChild(makeChip(it,i)));
[document.getElementById('p9-drop-4'),document.getElementById('p9-drop-9'),pool].forEach(box=>{
box.addEventListener('dragover',e=>{e.preventDefault();box.classList.add('over');});
box.addEventListener('dragleave',()=>box.classList.remove('over'));
box.addEventListener('drop',e=>{
e.preventDefault();box.classList.remove('over');
if(!dragging)return;
const target=box===document.getElementById('p9-drop-4')?box4:box===document.getElementById('p9-drop-9')?box9:pool;
target.appendChild(dragging);
});
});
document.getElementById('p9-dnd-check').addEventListener('click',()=>{
const fb=document.getElementById('p9-dnd-fb');
const chips4=[...box4.querySelectorAll('.dnd-chip')];
const chips9=[...box9.querySelectorAll('.dnd-chip')];
if(chips4.length+chips9.length<items.length){feedback(fb,false,'Разложи все карточки.');return;}
let ok=true;
chips4.forEach(c=>{if(items[+c.dataset.idx].group!==4)ok=false;});
chips9.forEach(c=>{if(items[+c.dataset.idx].group!==9)ok=false;});
if(ok){feedback(fb,true,'Верно! +5 XP');addXp(5,'p9-dnd');bumpProgress('p9',8);}
else{feedback(fb,false,'Есть ошибки. $k=2$ → $k^2=4$; $k=3$ → $k^2=9$.');}
});
document.getElementById('p9-dnd-reset').addEventListener('click',()=>{
[...box4.children].forEach(c=>pool.appendChild(c));
[...box9.children].forEach(c=>pool.appendChild(c));
document.getElementById('p9-dnd-fb').style.display='none';
});
})();
/* == INIT ИНТЕРАКТИВ 6: мини-квиз == */
(function(){
const qs=[
{q:'Если коэффициент подобия треугольников $k=5$, то отношение их площадей равно...',opts:['5','10','25','$\\sqrt{5}$'],ans:2},
{q:'Площади двух подобных треугольников — $9$ и $36$. Чему равен коэффициент подобия?',opts:['4','2','$\\sqrt{3}$','$\\frac{1}{2}$'],ans:1},
{q:'При каком $k$ площадь первого треугольника вдвое больше площади второго?',opts:['$k = 2$','$k = \\sqrt{2}$','$k = 4$','$k = 0{,}5$'],ans:1},
{q:'Верно ли, что для любых подобных фигур (не только треугольников) $S_1/S_2 = k^2$?',opts:['Только для треугольников','Только для прямоугольников','Да, для любых подобных фигур','Нет, только для равнобедренных'],ans:2},
{q:'$\\triangle ABC \\sim \\triangle A\'B\'C\'$, $k = 3$. Периметр $\\triangle A\'B\'C\' = 12$. Периметр $\\triangle ABC$ равен...',opts:['36','108','4','144'],ans:0},
];
const wrap=document.getElementById('p9-quiz-wrap');
wrap.innerHTML=qs.map((q,qi)=>`
<div style="margin-bottom:14px;padding:12px;background:var(--card);border:1px solid var(--border);border-radius:10px">
<div style="font-weight:700;margin-bottom:8px;font-size:.95rem">${qi+1}. ${q.q}</div>
<div style="display:flex;flex-direction:column;gap:6px">
${q.opts.map((o,oi)=>`<label style="display:flex;align-items:center;gap:8px;cursor:pointer;font-size:.92rem"><input type="radio" name="p9q${qi}" value="${oi}" style="accent-color:var(--sec-acc,var(--pri))"> ${o}</label>`).join('')}
</div>
</div>`).join('');
renderMath(wrap);
document.getElementById('p9-quiz-check').addEventListener('click',()=>{
const fb=document.getElementById('p9-quiz-fb');
let correct=0;
qs.forEach((q,qi)=>{
const sel=document.querySelector(`input[name="p9q${qi}"]:checked`);
if(sel&&+sel.value===q.ans)correct++;
});
if(correct===qs.length){
feedback(fb,true,`Все ${qs.length} ответов верны! +8 XP`);
addXp(8,'p9-quiz');bumpProgress('p9',12);confetti();
} else {
feedback(fb,false,`Верных ответов: ${correct} из ${qs.length}. Повтори: $S_1/S_2 = k^2$.`);
}
});
})();
/* == INIT: Босс §9 == */
(function(){
const tasks=[
{q:'<svg viewBox="0 0 280 148" style="display:block;max-width:280px;margin:0 auto 8px;background:#ede9fe;border:1px solid #c4b5fd;border-radius:8px"><polygon points="100,18 20,135 220,135" fill="rgba(124,58,237,.14)" stroke="#7c3aed" stroke-width="2"/><polygon points="235,78 210,135 292,135" fill="rgba(99,102,241,.22)" stroke="#6366f1" stroke-width="1.8"/><text x="100" y="13" text-anchor="middle" font-size="10" fill="#6d28d9" font-weight="800">A</text><text x="10" y="143" font-size="10" fill="#6d28d9" font-weight="800">B</text><text x="222" y="143" font-size="10" fill="#6d28d9" font-weight="800">C</text><text x="235" y="73" text-anchor="middle" font-size="9" fill="#4f46e5" font-weight="800">A\'</text><text x="202" y="143" font-size="9" fill="#4f46e5" font-weight="800">B\'</text><text x="294" y="143" font-size="9" fill="#4f46e5" font-weight="800">C\'</text><text x="140" y="10" text-anchor="middle" font-size="8" fill="#7c3aed">S₂=8, k=3</text></svg>$\\triangle ABC \\sim \\triangle A\'B\'C\'$, $k=3$, $S_{A\'B\'C\'}=8$. Найди $S_{ABC}$.',ans:72,hint:'S₁ = k²·S₂ = 9·8 = 72.'},
{q:'Стороны двух подобных треугольников: первый $12$, второй $8$. Площадь первого $S_1=54$. Найди $S_2$.',ans:24,hint:'k = 12/8 = 1.5. S₂ = S₁/k² = 54/2.25 = 24.'},
{q:'$S_1 = 75$, $S_2 = 48$. Найди коэффициент подобия $k = \\sqrt{S_1/S_2}$ (Ответ в виде десятичной дроби).',ans:1.25,hint:'k = √(75/48) = √(25/16) = 5/4 = 1.25.'},
{q:'Прямоугольный треугольник с катетами $3$ и $4$. Подобный с $k=2$. Найди площадь большего треугольника.',ans:24,hint:'S_мал = 0.5·3·4 = 6. S_бол = k²·S_мал = 4·6 = 24.'},
];
const bossBox=document.getElementById('p9-boss-tasks');
bossBox.innerHTML=tasks.map((t,i)=>`
<div style="padding:14px;background:var(--card);border-radius:10px;border:1px solid var(--border);margin-bottom:10px">
<div style="margin-bottom:8px;font-size:.95rem">${t.q}</div>
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:center">
<input type="number" class="tinp" id="p9b-a${i}" placeholder="Ответ" style="width:110px">
<button class="btn primary small" onclick="(function(){
const v=+document.getElementById('p9b-a${i}').value;
const fb=document.getElementById('p9b-fb${i}');
if(Math.abs(v-${t.ans})<0.05){
feedback(fb,true,'Верно! +5 XP');
if(!window.p9BossSolved.has(${i})){ window.p9BossSolved.add(${i}); addXp(5,'p9-boss${i}'); bumpProgress('p9',8); }
} else feedback(fb,false,'Неверно. ${t.hint}');
})()">Проверить</button>
</div>
<div class="feedback" id="p9b-fb${i}" style="display:none;margin-top:8px"></div>
</div>`).join('');
window.p9BossSolved=new Set();
renderMath(bossBox);
})();
}
function buildFinal3stub(){ document.getElementById('final3-body').innerHTML='<div class="card"><div class="card-body"><p><b>Финал главы 3 — Волна 1</b>: боссы и итоги появятся в следующем обновлении.</p></div></div>'+secNav('p9',null); }
</script>
</body>