`;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:()=>buildP8(),p9:()=>buildP9(),p10:()=>buildP10(),p11:()=>buildP11(),p12:()=>buildP12stub(),p13:()=>buildP13stub(),p14:()=>buildP14stub(),p15:()=>buildP15stub(),p16:()=>buildP16stub(),final4:()=>buildFinal4stub()};
+const BUILDERS={p1:()=>buildP1(),p2:()=>buildP2(),p3:()=>buildP3(),p4:()=>buildP4(),p5:()=>buildP5(),p6:()=>buildP6(),p7:()=>buildP7(),p8:()=>buildP8(),p9:()=>buildP9(),p10:()=>buildP10(),p11:()=>buildP11(),p12:()=>buildP12(),p13:()=>buildP13(),p14:()=>buildP14(),p15:()=>buildP15(),p16:()=>buildP16(),final4:()=>buildFinal4stub()};
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);}
@@ -438,6 +438,11 @@ const GLOSSARY=[
{term:'гипотенуза',def:'Сторона прямоугольного треугольника, противолежащая прямому углу.',sec:'p1',aliases:['гипотенуза','гипотенузы','гипотенузу']},
{term:'высота',def:'Перпендикуляр из вершины на противоположную сторону.',sec:'p1',aliases:['высота','высоты','высоту']},
{term:'теорема Фалеса',def:'Параллельные прямые пропорционально рассекают секущие.',sec:'p1',aliases:['теорема Фалеса','теореме Фалеса','теоремы Фалеса']},
+ {term:'угол между касательной и хордой',def:'Угол, образованный касательной к окружности и хордой, проведённой из точки касания; равен половине дуги, заключённой между ними.',sec:'p12',aliases:['угол между касательной и хордой','угла между касательной и хордой']},
+ {term:'пересекающиеся хорды',def:'Две хорды окружности, имеющие общую точку внутри окружности. Произведения их отрезков равны: PA·PB = PC·PD.',sec:'p15',aliases:['пересекающиеся хорды','пересекающихся хорд','пересекающимся хордам']},
+ {term:'полусумма дуг',def:'Выражение вида ½(дуга₁ + дуга₂), возникающее в теореме об угле между двумя хордами, пересекающимися внутри окружности.',sec:'p13',aliases:['полусумма дуг','полусуммы дуг','полусумме дуг']},
+ {term:'полуразность дуг',def:'Выражение вида ½|дуга₁ − дуга₂|, возникающее в теореме об угле между секущими из внешней точки.',sec:'p14',aliases:['полуразность дуг','полуразности дуг','полуразностью дуг']},
+ {term:'квадрат касательной',def:'Если из внешней точки P проведены касательная PT и секущая через A и B, то PT² = PA·PB.',sec:'p16',aliases:['квадрат касательной','квадрата касательной']},
];
function wrapGlossary(root){if(!root||root.__glossDone)return;const allAliases=[];GLOSSARY.forEach((g,i)=>g.aliases.forEach(a=>allAliases.push({a,i})));allAliases.sort((x,y)=>y.a.length-x.a.length);const re=new RegExp('(?x.a.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')).join('|')+')(?![\\w\\u0400-\\u04ff-])','iu');const walker=document.createTreeWalker(root,NodeFilter.SHOW_TEXT,{acceptNode(node){const p=node.parentElement;if(!p)return NodeFilter.FILTER_REJECT;if(p.closest('.katex,.gloss-term,button,input,select,.wg-badge,.card-icon,.sec-num,.psel-num,.hdr,.ach-popup,script,style,.search-modal,.sidecard,.gloss-tip'))return NodeFilter.FILTER_REJECT;if(!re.test(node.nodeValue))return NodeFilter.FILTER_REJECT;return NodeFilter.FILTER_ACCEPT;}});const nodes=[];let n;while((n=walker.nextNode()))nodes.push(n);nodes.forEach(node=>{const text=node.nodeValue;const out=document.createDocumentFragment();let cursor=0;const global=new RegExp(re.source,'giu');let m;while((m=global.exec(text))!==null){if(m.index>cursor)out.appendChild(document.createTextNode(text.slice(cursor,m.index)));const found=m[0].toLowerCase();const hit=allAliases.find(x=>x.a.toLowerCase()===found);const g=hit?GLOSSARY[hit.i]:null;const sp=document.createElement('span');sp.className='gloss-term';sp.dataset.gloss=g?g.term:'';sp.textContent=m[0];out.appendChild(sp);cursor=m.index+m[0].length;}if(cursorx.term===elm.dataset.gloss);if(!g)return;tip.innerHTML=''+g.term[0].toUpperCase()+g.term.slice(1)+'
Шаг 2. Угол между $l$ и хордой $AB$: $\\angle(l,AB) = 90° - \\angle(AB,OA) = 90° - \\angle BAC'$, где $C'$ — точка на $l$. Точнее: $\\angle(l,AB) = \\angle CAB = $ вписанный угол на дуге $BC$... нет, используем другой подход.
+
Шаг 3 (прямо). $\\angle(l,AB) = \\dfrac{1}{2}\\smile AB$ — следует из того, что $\\angle CAB = \\dfrac{1}{2}\\smile CB$ (вписанный), и $90° = \\dfrac{1}{2}\\cdot 180°$, поэтому $\\angle(l,AB) = 90° - \\angle CAB = \\dfrac{1}{2}(180° - \\smile CB) = \\dfrac{1}{2}\\smile AB$.
Нажимай «Далее» — пошаговое доказательство через диаметр.
+
+
+
+
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 3 — калькулятор */
+ html+=`
+
ИНТЕРАКТИВ 3
Калькулятор: угол ↔ дуга
+
Введи дугу — получи угол, или наоборот.
+
+
+
+
+
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 4 — тренажёр */
+ html+=`
+
ИНТЕРАКТИВ 4
Тренажёр §12
+
5 задач на угол между касательной и хордой.
+
Задача 1 / 5Очки: 0
+
+
+
+
+
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 5 — DnD */
+ html+=`
+
ИНТЕРАКТИВ 5
Верно или неверно?
+
Рассортируй утверждения об угле между касательной и хордой.
+
+
+
Верно
+
Неверно
+
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 6 — Босс §12 */
+ html+=`
+
БОСС §12
Итоговые задачи
+
4 задачи повышенной сложности — каждая верная даёт +5 XP.
+
+
`;
+
+ html+=`
+
+
`;
+ html+=secNav('p11','p13');
+ box.innerHTML=html;
+ if(window.renderMathInElement) setTimeout(()=>renderMath(box),0);
+
+ /* === INIT 1: слайдер хорды === */
+ (function(){
+ const sl=document.getElementById('p12-arc-sl');
+ const valEl=document.getElementById('p12-arc-val');
+ const svgWrap=document.getElementById('p12-svg-wrap');
+ const info=document.getElementById('p12-info');
+ const R=65, cx=130, cy=100, W=260, H=200;
+ function draw(){
+ const arcDeg=+sl.value;
+ valEl.textContent=arcDeg;
+ const ang=arcDeg/2;
+ // A is leftmost point of circle
+ const aA=Math.PI; // angle for A = 180deg => A=(cx-R, cy)
+ const Ax=cx+R*Math.cos(aA), Ay=cy+R*Math.sin(aA);
+ // B is at angle (PI - arcDeg*PI/180) from positive x-axis, going CCW from A
+ const aB=Math.PI - arcDeg*Math.PI/180;
+ const Bx=cx+R*Math.cos(aB), By=cy+R*Math.sin(aB);
+ // tangent at A is vertical (perpendicular to radius OA which is horizontal)
+ const tLen=50;
+ const T1x=Ax, T1y=Ay-tLen;
+ const T2x=Ax, T2y=Ay+tLen;
+ // arc indicator small
+ const large=arcDeg>180?1:0;
+ svgWrap.innerHTML=``;
+ info.textContent='Дуга AB = '+arcDeg+'° → Угол (l, AB) = '+Math.round(ang)+'° (= '+arcDeg+'°/2)';
+ }
+ sl.addEventListener('input',draw);
+ draw();
+ })();
+
+ /* === INIT 2: пошаговое доказательство === */
+ (function(){
+ const R=55, cx=115, cy=85, W=250, H=175;
+ const aA=Math.PI;
+ const Ax=cx+R*Math.cos(aA), Ay=cy;
+ const aB=Math.PI-70*Math.PI/180;
+ const Bx=cx+R*Math.cos(aB), By=cy+R*Math.sin(aB);
+ // diameter through A: C is diametrically opposite to A
+ const Ccx=cx+R, Ccy=cy;
+ const steps=[
+ {text:'Дано: $l$ — касательная в точке $A$, $AB$ — хорда. Обозначим $\\angle(l,AB)=\\alpha$. Доказать: $\\alpha = \\dfrac{1}{2}\\smile AB$.'},
+ {text:'Шаг 1. Проведём диаметр $AC$ через точку $A$. Так как касательная перпендикулярна радиусу $OA$, то $l \\perp OA$, следовательно $\\angle(l,AC) = 90°$.'},
+ {text:'Шаг 2. Угол $\\angle BAC$ — вписанный, опирается на дугу $\\smile BC$. По теореме §9: $\\angle BAC = \\dfrac{1}{2}\\smile BC$.'},
+ {text:'Шаг 3. Из рисунка: $\\alpha = \\angle(l,AB) = 90° - \\angle BAC = 90° - \\dfrac{1}{2}\\smile BC = \\dfrac{1}{2}(180° - \\smile BC) = \\dfrac{1}{2}\\smile AB$. ч.т.д.'},
+ ];
+ let step=0;
+ const svgEl=document.getElementById('p12-proof-svg'), txtEl=document.getElementById('p12-proof-text');
+ function draw(){
+ let ex='';
+ if(step>=1){
+ ex+=``;
+ ex+=``;
+ ex+=`C`;
+ ex+=`90°`;
+ }
+ if(step>=2){
+ ex+=``;
+ ex+=`∠BAC`;
+ }
+ if(step>=3){
+ ex+=`α=½⌢AB`;
+ }
+ svgEl.innerHTML=``;
+ txtEl.innerHTML=steps[step].text;
+ if(window.renderMathInElement) try{renderMath(txtEl);}catch(e){}
+ document.getElementById('p12-proof-next').textContent=step>=steps.length-1?'Готово':'Далее';
+ }
+ document.getElementById('p12-proof-next').addEventListener('click',()=>{if(step{step=0;draw();});
+ draw();
+ })();
+
+ /* === INIT 3: калькулятор === */
+ (function(){
+ document.getElementById('p12-arc2ang').addEventListener('click',()=>{
+ const v=parseFloat(document.getElementById('p12-arc-inp').value);
+ const out=document.getElementById('p12-calc-out');
+ out.style.display='block';
+ if(isNaN(v)||v<=0||v>=360){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Введите дугу от 1 до 359°.';return;}
+ out.style.background='var(--pri-soft,#cffafe)';out.style.color='var(--pri2,#0e7490)';
+ out.textContent='Дуга '+v+'° → Угол = '+v+'°/2 = '+(v/2)+'°';
+ });
+ document.getElementById('p12-ang2arc').addEventListener('click',()=>{
+ const v=parseFloat(document.getElementById('p12-ang-inp').value);
+ const out=document.getElementById('p12-calc-out');
+ out.style.display='block';
+ if(isNaN(v)||v<=0||v>=180){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Введите угол от 1 до 179°.';return;}
+ out.style.background='var(--pri-soft,#cffafe)';out.style.color='var(--pri2,#0e7490)';
+ out.textContent='Угол '+v+'° → Дуга AB = 2·'+v+'° = '+(2*v)+'°';
+ });
+ })();
+
+ /* === INIT 4: тренажёр === */
+ (function(){
+ const tasks=[
+ {q:'Угол между касательной $l$ и хордой $AB$ равен $40°$. Найди дугу $\\smile AB$.',a:80,hint:'Дуга = 2·40° = 80°'},
+ {q:'Дуга $\\smile AB = 130°$. Найди угол между касательной в точке $A$ и хордой $AB$.',a:65,hint:'Угол = 130°/2 = 65°'},
+ {q:'Угол между касательной и хордой $= 90°$. Чему равна дуга, отсекаемая хордой?',a:180,hint:'Дуга = 2·90° = 180°, значит хорда — диаметр'},
+ {q:'Угол между касательной и хордой $= 45°$. Найди дугу.',a:90,hint:'Дуга = 2·45° = 90°'},
+ {q:'Дуга $\\smile AB = 54°$. Угол между касательной в точке $A$ и хордой $AB$:',a:27,hint:'Угол = 54°/2 = 27°'},
+ ];
+ let cur=0, score=0;
+ const iEl=document.getElementById('p12-tr-i'), scEl=document.getElementById('p12-tr-score');
+ const taskEl=document.getElementById('p12-tr-task'), ansEl=document.getElementById('p12-tr-ans');
+ const goBtn=document.getElementById('p12-tr-go'), startBtn=document.getElementById('p12-tr-start');
+ const fb=document.getElementById('p12-tr-fb');
+ function showTask(){
+ if(cur>=tasks.length){taskEl.innerHTML='Тренажёр завершён! Очки: '+score+'/'+tasks.length+'';ansEl.style.display='none';goBtn.style.display='none';addXp(score*4,'p12-trainer');bumpProgress('p12',20);return;}
+ taskEl.innerHTML=tasks[cur].q;iEl.textContent=cur+1;ansEl.value='';fb.style.display='none';
+ if(window.renderMathInElement) try{renderMath(taskEl);}catch(e){}
+ }
+ goBtn.addEventListener('click',()=>{
+ const ans=parseFloat(ansEl.value.replace(',','.'));
+ const ok=Math.abs(ans-tasks[cur].a)<0.5;
+ feedback(fb,ok,ok?'Верно!':'Неверно. Подсказка: '+tasks[cur].hint);
+ if(ok){score++;scEl.textContent=score;cur++;setTimeout(showTask,900);}
+ });
+ startBtn.addEventListener('click',()=>{cur=0;score=0;scEl.textContent=0;ansEl.style.display='';goBtn.style.display='';showTask();});
+ showTask();
+ })();
+
+ /* === INIT 5: DnD верно/неверно === */
+ (function(){
+ const items=[
+ {label:'Угол (касательная, хорда) = ½ дуги',cat:'true'},
+ {label:'Угол (касательная, хорда) = дуге целиком',cat:'false'},
+ {label:'Если дуга AB = 100°, угол = 50°',cat:'true'},
+ {label:'Угол между касательной и хордой может быть больше 90°',cat:'false'},
+ {label:'Если угол = 90°, то хорда — диаметр',cat:'true'},
+ {label:'Касательная параллельна хорде всегда',cat:'false'},
+ ];
+ const pool=document.getElementById('p12-dnd-pool');
+ const boxes={true:document.getElementById('p12-drop-true-items'),false:document.getElementById('p12-drop-false-items')};
+ const fb=document.getElementById('p12-dnd-fb');
+ let placed={};
+ function reset(){
+ pool.innerHTML='';placed={};
+ Object.values(boxes).forEach(b=>b.innerHTML='');
+ fb.style.display='none';
+ items.forEach((it,i)=>{
+ const chip=document.createElement('div');
+ chip.className='dnd-chip';chip.dataset.i=i;chip.textContent=it.label;
+ chip.addEventListener('click',()=>chip.classList.toggle('armed'));
+ Object.entries(boxes).forEach(([cat,bx])=>{
+ bx.parentElement.addEventListener('click',()=>{
+ if(!chip.classList.contains('armed'))return;
+ chip.classList.remove('armed');
+ if(placed[i]!==undefined) boxes[placed[i]].removeChild(chip);
+ placed[i]=cat;
+ bx.appendChild(chip);
+ });
+ });
+ pool.appendChild(chip);
+ });
+ }
+ document.getElementById('p12-dnd-check').addEventListener('click',()=>{
+ let ok=0;
+ items.forEach((it,i)=>{if(placed[i]===it.cat)ok++;});
+ feedback(fb,ok===items.length,'Верно: '+ok+'/'+items.length+(ok===items.length?'. Отлично!':'. Попробуй ещё.'));
+ if(ok===items.length){addXp(8,'p12-dnd');bumpProgress('p12',15);}
+ });
+ document.getElementById('p12-dnd-reset').addEventListener('click',reset);
+ reset();
+ })();
+
+ /* === INIT 6: Босс §12 === */
+ (function(){
+ const tasks=[
+ {q:'Угол между касательной и хордой $AB = 35°$. Дуга $\\smile AB$:',
+ opts:['70°','35°','17,5°'],cor:0,
+ exp:'$\\smile AB = 2 \\cdot 35° = 70°$.'},
+ {q:'Дуга $\\smile AB = 160°$. Угол между касательной в $A$ и хордой $AB$:',
+ opts:['80°','160°','40°'],cor:0,
+ exp:'Угол $= \\dfrac{1}{2}\\cdot 160° = 80°$.'},
+ {q:'Угол между касательной и хордой $= 60°$. Дуга между ними:',
+ opts:['120°','60°','30°'],cor:0,
+ exp:'Дуга $= 2\\cdot 60° = 120°$.'},
+ {q:'Если хорда — диаметр, угол между касательной в точке начала диаметра и диаметром равен:',
+ opts:['90°','180°','45°'],cor:0,
+ exp:'Диаметр стягивает дугу $180°$. Угол $= \\dfrac{1}{2}\\cdot 180° = 90°$.'},
+ ];
+ const cont=document.getElementById('p12-boss-tasks');
+ let bhtml='';
+ tasks.forEach((t,i)=>{
+ bhtml+=`
+
${i+1}. ${t.q}
+
+ ${t.opts.map((o,j)=>``).join('')}
+
+
+
`;
+ });
+ cont.innerHTML=bhtml;
+ if(window.renderMathInElement) try{renderMath(cont);}catch(e){}
+ })();
+}
+function buildP13(){
+ const box=document.getElementById('p13-body');
+ let html='';
+
+ html+=makeCard('rule','Угол между двумя хордами','13.1',`
+
Теорема. Угол между двумя хордами, пересекающимися внутри окружности, равен полусумме двух дуг: той, которую он «охватывает», и противоположной.
+ $$\\angle APС = \\dfrac{1}{2}(\\smile AC + \\smile BD)$$
+
Хорды $AB$ и $CD$ пересекаются в точке $P$ внутри окружности. Угол $\\angle APC$ (и вертикальный ему $\\angle BPD$) равен полусумме дуг $\\smile AC$ и $\\smile BD$.
Шаг 2. Угол $\\angle ADP$ — вписанный, опирается на дугу $\\smile AC$ (от $A$ до $C$ через вершины хорды $AB$). По теореме §9: $\\angle DAB = \\dfrac{1}{2}\\smile BD$.
+
Шаг 3. Угол $\\angle DAB$ — вписанный, опирается на $\\smile DB$: $\\angle DAB = \\dfrac{1}{2}\\smile DB$. Угол $\\angle ADP$ опирается на $\\smile AC$: $\\angle ADP = \\dfrac{1}{2}\\smile AC$.
+
Шаг 4. По теореме о внешнем угле треугольника: $\\angle APC = \\angle DAB + \\angle ADB = \\dfrac{1}{2}\\smile BD + \\dfrac{1}{2}\\smile AC = \\dfrac{1}{2}(\\smile AC + \\smile BD)$. ч.т.д.
Нажимай «Далее» — каждый шаг раскрывает ключевую идею.
+
+
+
+
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 3 — калькулятор */
+ html+=`
+
ИНТЕРАКТИВ 3
Калькулятор: угол между хордами
+
Введи две дуги — получи угол. Или угол и одну дугу — найди вторую дугу.
+
+
+
+
+
+
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 4 — тренажёр */
+ html+=`
+
ИНТЕРАКТИВ 4
Тренажёр §13
+
5 задач на угол между хордами внутри окружности.
+
Задача 1 / 5Очки: 0
+
+
+
+
+
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 5 — DnD */
+ html+=`
+
ИНТЕРАКТИВ 5
Верно или неверно?
+
Рассортируй утверждения об угле при пересечении хорд.
+
+
+
Верно
+
Неверно
+
+
+
+
`;
+
+ /* ИНТЕРАКТИВ 6 — Босс §13 */
+ html+=`
+
БОСС §13
Итоговые задачи
+
4 задачи повышенной сложности — каждая верная даёт +5 XP.
+
+
`;
+
+ html+=`
+
+
`;
+ html+=secNav('p12','p14');
+ box.innerHTML=html;
+ if(window.renderMathInElement) setTimeout(()=>renderMath(box),0);
+
+ /* === INIT 1: слайдеры дуг === */
+ (function(){
+ const sl1=document.getElementById('p13-arc1-sl'), sl2=document.getElementById('p13-arc2-sl');
+ const v1=document.getElementById('p13-arc1-val'), v2=document.getElementById('p13-arc2-val');
+ const svgWrap=document.getElementById('p13-svg-wrap'), info=document.getElementById('p13-info');
+ const R=64, cx=128, cy=95, W=256, H=192;
+ function draw(){
+ const a1=+sl1.value, a2=+sl2.value;
+ v1.textContent=a1; v2.textContent=a2;
+ const ang=Math.round((a1+a2)/2);
+ // Place A, C, B, D on circle such that arc AC = a1, arc BD = a2
+ // A at 200deg, C at 200+a1, B at 200+a1+50 (gap), D at 200+a1+50+a2
+ const aA=200*Math.PI/180;
+ const aC=(200+a1)*Math.PI/180;
+ const aB=(200+a1+a2+20)*Math.PI/180;
+ const aD=(200+a1+a2+20+a2)*Math.PI/180;
+ const Ax=cx+R*Math.cos(aA), Ay=cy+R*Math.sin(aA);
+ const Ccx=cx+R*Math.cos(aC), Ccy=cy+R*Math.sin(aC);
+ const Bx=cx+R*Math.cos(aB), By=cy+R*Math.sin(aB);
+ const Dx=cx+R*Math.cos(aD), Dy=cy+R*Math.sin(aD);
+ // intersection of chords AC and BD — line-line intersection
+ const denom=(Ax-Ccx)*(By-Dy)-(Ay-Ccy)*(Bx-Dx);
+ let Px=cx, Py=cy;
+ if(Math.abs(denom)>0.01){
+ const t=((Ax-Bx)*(By-Dy)-(Ay-By)*(Bx-Dx))/denom;
+ Px=Ax+t*(Ccx-Ax); Py=Ay+t*(Ccy-Ay);
+ }
+ svgWrap.innerHTML=``;
+ info.textContent='⌢AC = '+a1+'°, ⌢BD = '+a2+'° → Угол = ½('+a1+'+'+a2+') = '+ang+'°';
+ }
+ sl1.addEventListener('input',draw); sl2.addEventListener('input',draw);
+ draw();
+ })();
+
+ /* === INIT 2: пошаговое доказательство === */
+ (function(){
+ const R=55, cx=115, cy=85, W=250, H=175;
+ const aA=210*Math.PI/180, aC=290*Math.PI/180;
+ const aB=350*Math.PI/180, aD=70*Math.PI/180;
+ const Ax=cx+R*Math.cos(aA), Ay=cy+R*Math.sin(aA);
+ const Ccx=cx+R*Math.cos(aC), Ccy=cy+R*Math.sin(aC);
+ const Bx=cx+R*Math.cos(aB), By=cy+R*Math.sin(aB);
+ const Dx=cx+R*Math.cos(aD), Dy=cy+R*Math.sin(aD);
+ const denom=(Ax-Ccx)*(By-Dy)-(Ay-Ccy)*(Bx-Dx);
+ const t=((Ax-Bx)*(By-Dy)-(Ay-By)*(Bx-Dx))/denom;
+ const Px=Ax+t*(Ccx-Ax), Py=Ay+t*(Ccy-Ay);
+ const steps=[
+ {text:'Дано: хорды $AB$ и $CD$ пересекаются в точке $P$ внутри окружности. Обозначим: $\\smile AC$ — дуга между $A$ и $C$ (со стороны угла $\\angle APC$), $\\smile BD$ — противоположная дуга.'},
+ {text:'Шаг 1. Соединим $A$ и $D$. Рассмотрим треугольник $\\triangle APD$. Угол $\\angle APC$ является внешним углом этого треугольника при вершине $P$.'},
+ {text:'Шаг 2. По теореме о внешнем угле треугольника: $\\angle APC = \\angle PAD + \\angle PDA$. Угол $\\angle PAD = \\angle BAD$ — вписанный, опирается на $\\smile BD$: $\\angle BAD = \\dfrac{1}{2}\\smile BD$.'},
+ {text:'Шаг 3. Угол $\\angle PDA = \\angle CDA$ — вписанный, опирается на $\\smile CA$: $\\angle CDA = \\dfrac{1}{2}\\smile AC$. Итого: $\\angle APC = \\dfrac{1}{2}\\smile BD + \\dfrac{1}{2}\\smile AC = \\dfrac{1}{2}(\\smile AC + \\smile BD)$. ч.т.д.'},
+ ];
+ let step=0;
+ const svgEl=document.getElementById('p13-proof-svg'), txtEl=document.getElementById('p13-proof-text');
+ function draw(){
+ let ex='';
+ if(step>=1){
+ ex+=``;
+ }
+ if(step>=2){
+ ex+=`∠BAD`;
+ }
+ if(step>=3){
+ ex+=`∠CDA`;
+ ex+=`∠APC`;
+ }
+ svgEl.innerHTML=``;
+ txtEl.innerHTML=steps[step].text;
+ if(window.renderMathInElement) try{renderMath(txtEl);}catch(e){}
+ document.getElementById('p13-proof-next').textContent=step>=steps.length-1?'Готово':'Далее';
+ }
+ document.getElementById('p13-proof-next').addEventListener('click',()=>{if(step{step=0;draw();});
+ draw();
+ })();
+
+ /* === INIT 3: калькулятор === */
+ (function(){
+ document.getElementById('p13-calc-ang').addEventListener('click',()=>{
+ const d1=parseFloat(document.getElementById('p13-d1').value);
+ const d2=parseFloat(document.getElementById('p13-d2').value);
+ const out=document.getElementById('p13-calc-out');
+ out.style.display='block';
+ if(isNaN(d1)||isNaN(d2)||d1<=0||d2<=0){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Введите положительные дуги.';return;}
+ out.style.background='var(--acc-soft,#a5f3fc)';out.style.color='var(--acc2,#0891b2)';
+ out.textContent='Угол = ½('+d1+'+'+d2+') = '+(d1+d2)/2+'°';
+ });
+ document.getElementById('p13-calc-arc').addEventListener('click',()=>{
+ const ang=parseFloat(document.getElementById('p13-ang').value);
+ const d1=parseFloat(document.getElementById('p13-d1').value);
+ const out=document.getElementById('p13-calc-out');
+ out.style.display='block';
+ if(isNaN(ang)||isNaN(d1)||ang<=0||d1<=0){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Введите угол и дугу 1.';return;}
+ const d2=2*ang-d1;
+ if(d2<=0){out.style.background='#fee2e2';out.style.color='#7f1d1d';out.textContent='Дуга 2 должна быть положительной.';return;}
+ out.style.background='var(--acc-soft,#a5f3fc)';out.style.color='var(--acc2,#0891b2)';
+ out.textContent='Дуга 2 = 2·'+ang+' − '+d1+' = '+d2+'°';
+ });
+ })();
+
+ /* === INIT 4: тренажёр === */
+ (function(){
+ const tasks=[
+ {q:'Хорды пересекаются внутри окружности. Дуга $\\smile AC = 70°$, дуга $\\smile BD = 50°$. Угол при пересечении:',a:60,hint:'½(70+50) = 60°'},
+ {q:'Угол при пересечении хорд $= 75°$, одна дуга $= 80°$. Найди вторую дугу.',a:70,hint:'2·75−80 = 70°'},
+ {q:'Обе дуги равны $100°$. Угол при пересечении хорд:',a:100,hint:'½(100+100) = 100°'},
+ {q:'Дуга $\\smile AC = 120°$, дуга $\\smile BD = 40°$. Угол при пересечении хорд:',a:80,hint:'½(120+40) = 80°'},
+ {q:'Угол при пересечении $= 90°$, дуга $\\smile AC = \\smile BD$. Чему равна каждая дуга?',a:90,hint:'½(x+x)=90° ⟹ x=90°'},
+ ];
+ let cur=0, score=0;
+ const iEl=document.getElementById('p13-tr-i'), scEl=document.getElementById('p13-tr-score');
+ const taskEl=document.getElementById('p13-tr-task'), ansEl=document.getElementById('p13-tr-ans');
+ const goBtn=document.getElementById('p13-tr-go'), startBtn=document.getElementById('p13-tr-start');
+ const fb=document.getElementById('p13-tr-fb');
+ function showTask(){
+ if(cur>=tasks.length){taskEl.innerHTML='Тренажёр завершён! Очки: '+score+'/'+tasks.length+'';ansEl.style.display='none';goBtn.style.display='none';addXp(score*4,'p13-trainer');bumpProgress('p13',20);return;}
+ taskEl.innerHTML=tasks[cur].q;iEl.textContent=cur+1;ansEl.value='';fb.style.display='none';
+ if(window.renderMathInElement) try{renderMath(taskEl);}catch(e){}
+ }
+ goBtn.addEventListener('click',()=>{
+ const ans=parseFloat(ansEl.value.replace(',','.'));
+ const ok=Math.abs(ans-tasks[cur].a)<0.5;
+ feedback(fb,ok,ok?'Верно!':'Неверно. Подсказка: '+tasks[cur].hint);
+ if(ok){score++;scEl.textContent=score;cur++;setTimeout(showTask,900);}
+ });
+ startBtn.addEventListener('click',()=>{cur=0;score=0;scEl.textContent=0;ansEl.style.display='';goBtn.style.display='';showTask();});
+ showTask();
+ })();
+
+ /* === INIT 5: DnD верно/неверно === */
+ (function(){
+ const items=[
+ {label:'Угол между хордами = ½(сумма двух дуг)',cat:'true'},
+ {label:'Угол между хордами = разности двух дуг',cat:'false'},
+ {label:'Если обе дуги по 90°, угол = 90°',cat:'true'},
+ {label:'Угол между хордами всегда острый',cat:'false'},
+ {label:'Вертикальные углы при пересечении хорд равны',cat:'true'},
+ {label:'Угол при пересечении = вписанному углу',cat:'false'},
+ ];
+ const pool=document.getElementById('p13-dnd-pool');
+ const boxes={true:document.getElementById('p13-drop-true-items'),false:document.getElementById('p13-drop-false-items')};
+ const fb=document.getElementById('p13-dnd-fb');
+ let placed={};
+ function reset(){
+ pool.innerHTML='';placed={};
+ Object.values(boxes).forEach(b=>b.innerHTML='');
+ fb.style.display='none';
+ items.forEach((it,i)=>{
+ const chip=document.createElement('div');
+ chip.className='dnd-chip';chip.dataset.i=i;chip.textContent=it.label;
+ chip.addEventListener('click',()=>chip.classList.toggle('armed'));
+ Object.entries(boxes).forEach(([cat,bx])=>{
+ bx.parentElement.addEventListener('click',()=>{
+ if(!chip.classList.contains('armed'))return;
+ chip.classList.remove('armed');
+ if(placed[i]!==undefined) boxes[placed[i]].removeChild(chip);
+ placed[i]=cat;
+ bx.appendChild(chip);
+ });
+ });
+ pool.appendChild(chip);
+ });
+ }
+ document.getElementById('p13-dnd-check').addEventListener('click',()=>{
+ let ok=0;
+ items.forEach((it,i)=>{if(placed[i]===it.cat)ok++;});
+ feedback(fb,ok===items.length,'Верно: '+ok+'/'+items.length+(ok===items.length?'. Отлично!':'. Попробуй ещё.'));
+ if(ok===items.length){addXp(8,'p13-dnd');bumpProgress('p13',15);}
+ });
+ document.getElementById('p13-dnd-reset').addEventListener('click',reset);
+ reset();
+ })();
+
+ /* === INIT 6: Босс §13 === */
+ (function(){
+ const tasks=[
+ {q:'Дуги $\\smile AC = 50°$, $\\smile BD = 90°$. Угол при пересечении хорд:',
+ opts:['70°','140°','45°'],cor:0,
+ exp:'$\\angle = \\dfrac{1}{2}(50+90) = 70°$.'},
+ {q:'Угол при пересечении $= 100°$, одна дуга $= 120°$. Другая дуга:',
+ opts:['80°','60°','200°'],cor:0,
+ exp:'$2\\cdot100 - 120 = 80°$.'},
+ {q:'Две хорды пересекаются в центре окружности. Угол между ними равен:',
+ opts:['Центральному углу','Вписанному углу','Может быть любым'],cor:2,
+ exp:'Если хорды пересекаются в центре, это два диаметра. Угол определяется расположением точек.'},
+ {q:'Дуга $\\smile AC = \\smile BD = 80°$. Угол при пересечении хорд:',
+ opts:['80°','40°','160°'],cor:0,
+ exp:'$\\angle = \\dfrac{1}{2}(80+80) = 80°$.'},
+ ];
+ const cont=document.getElementById('p13-boss-tasks');
+ let bhtml='';
+ tasks.forEach((t,i)=>{
+ bhtml+=`
+
${i+1}. ${t.q}
+
+ ${t.opts.map((o,j)=>``).join('')}
+
+
+
`;
+ });
+ cont.innerHTML=bhtml;
+ if(window.renderMathInElement) try{renderMath(cont);}catch(e){}
+ })();
+}
+function buildP14(){
+ const box=document.getElementById('p14-body');
+ let html='';
+
+ html+=makeCard('rule','Угол между двумя секущими из внешней точки','14.1',`
+
Теорема. Угол между двумя секущими, проведёнными из одной точки вне окружности, равен полуразности дуг, заключённых между секущими (большей минус меньшей).
+ $$\\angle P = \\dfrac{1}{2}(\\smile AB - \\smile CD)$$
+
Шаг 4. В треугольнике $\\triangle PAD$: $\\angle ADB$ — внешний угол при $D$. Поэтому $\\angle ADB = \\angle P + \\angle PAD$, откуда $\\angle P = \\angle ADB - \\angle CAD = \\dfrac{1}{2}\\smile AB - \\dfrac{1}{2}\\smile CD = \\dfrac{1}{2}(\\smile AB - \\smile CD)$. ч.т.д.
Теорема. Если из внешней точки $P$ проведены касательная $PT$ (где $T$ — точка касания) и секущая, пересекающая окружность в точках $A$ и $B$ ($PA < PB$), то:
+ $$PT^2 = PA \\cdot PB$$
+
Следствие: квадрат длины касательной равен произведению полной секущей ($PB$) на её внешнюю часть ($PA$).
+
+
+
`);
+
+ html+=makeCard('theory','Доказательство через подобие','16.2',`
+
Из точки $P$ вне окружности проведены: касательная $PT$ и секущая через $A$, $B$ ($PA < PB$). Докажем $PT^2 = PA \\cdot PB$.
+
+
Шаг 1. Рассмотрим треугольники $\\triangle PTA$ и $\\triangle PBT$.
+
Шаг 2. Общий угол при $P$: $\\angle TPА = \\angle BPT$ (общий угол).
+
Шаг 3. По теореме §12: $\\angle PTA = \\angle TBA$ (угол между касательной $PT$ и хордой $TA$ равен вписанному углу $\\angle TBA$, опирающемуся на ту же дугу $\\smile TA$).
+
Шаг 4. Значит $\\triangle PTA \\sim \\triangle PBT$ (по АА). Из подобия: $\\dfrac{PT}{PB} = \\dfrac{PA}{PT}$, откуда $PT^2 = PA \\cdot PB$. ч.т.д.