Files
Learn_System/frontend/textbooks/algebra_10_ch2.html
T

1525 lines
105 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>Алгебра 10 · Глава 2 · Корень n-й степени</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"
onload="renderMathInElement(document.body,{delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false})"></script>
<script src="/js/api.js" defer></script>
<script src="/js/xp.js" defer></script>
<script src="/js/alg10_svg.js?v=1" defer></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Manrope:wght@600;700;800;900&family=Unbounded:wght@700;800;900&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
<style>
:root{
--bg:#faf5ff; --card:#fff; --card-soft:#f8f5ff; --text:#1a0f1f; --muted:#6b5b7c;
--border:#ede9fe; --sh:0 1px 3px rgba(0,0,0,.06); --sh2:0 4px 14px rgba(0,0,0,.08);
--pri:#7c3aed; --pri2:#6d28d9; --pri-soft:#ede9fe;
--acc:#a855f7; --acc2:#9333ea; --acc-soft:#e9d5ff;
--ok:#10b981; --ok-bg:#d1fae5; --warn:#f59e0b; --warn-bg:#fef3c7;
--bad:#ef4444; --fail:#dc2626; --fail-bg:#fee2e2;
}
.dark{--bg:#160a1d; --card:#1f1029; --card-soft:#281338; --text:#f3e8ff; --muted:#a08bb5; --border:#321e42}
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{font-family:'Inter',system-ui,sans-serif;background:var(--bg);color:var(--text);line-height:1.55;font-size:15px}
button,input,select,textarea{font-family:inherit;font-size:inherit}
button{cursor:pointer;border:0;background:transparent;color:inherit}
a{color:inherit;text-decoration:none}
.ic{width:16px;height:16px;display:inline-block;flex-shrink:0;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;vertical-align:middle}
.hdr{position:relative;background:linear-gradient(110deg,#3b0764 0%,#7c3aed 55%,#c4b5fd 100%);color:#fff;padding:46px 22px 30px;overflow:hidden;border-bottom:2px solid rgba(237,233,254,.2);min-height:130px}
.hdr::before{content:'ГЛАВА 2';position:absolute;right:-12px;top:50%;transform:translateY(-50%);font-family:'Unbounded',sans-serif;font-size:clamp(5rem,15vw,11rem);font-weight:900;letter-spacing:-.04em;color:transparent;-webkit-text-stroke:1.5px rgba(237,233,254,.12);line-height:1;pointer-events:none;z-index:0}
.hdr-row{position:relative;z-index:1;display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.hdr h1{font-family:'Unbounded',sans-serif;font-size:1.5rem;font-weight:900;letter-spacing:-.01em;line-height:1.3;padding-top:4px}
.hdr-sub{font-size:.85rem;opacity:.88;margin-top:6px;font-weight:500;line-height:1.4}
.hdr-side{margin-left:auto;display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.hdr-btn{padding:7px 12px;border-radius:9px;background:rgba(255,255,255,.14);color:#fff;font-weight:600;font-size:.82rem;display:inline-flex;align-items:center;gap:6px;transition:background .15s;text-decoration:none}
.hdr-btn:hover{background:rgba(255,255,255,.24)}
.main{max-width:1240px;margin:0 auto;padding:22px;width:100%;display:grid;grid-template-columns:1fr 280px;gap:24px}
@media(max-width:980px){.main{grid-template-columns:1fr;padding:14px}}
.col-main{min-width:0}
.hero{background:linear-gradient(135deg,var(--pri-soft) 0%,var(--acc-soft) 50%,var(--pri-soft) 100%);background-size:200% 200%;animation:heroShift 12s ease-in-out infinite;border:1px solid var(--border);border-radius:18px;padding:24px 22px;margin-bottom:24px;position:relative;overflow:hidden}
@keyframes heroShift{0%,100%{background-position:0% 50%}50%{background-position:100% 50%}}
.hero::before{content:'ⁿ√';position:absolute;right:-10px;top:-20px;font-size:clamp(2rem,8vw,5.5rem);font-weight:900;color:var(--pri);opacity:.10;line-height:1;pointer-events:none;font-family:'Unbounded',sans-serif}
.hero h2{font-family:'Unbounded',sans-serif;font-size:1.55rem;font-weight:800;color:var(--pri2);margin-bottom:10px}
.hero p{font-size:.95rem;color:var(--text);opacity:.88;margin-bottom:14px;max-width:640px}
.hero-row{display:flex;gap:14px;flex-wrap:wrap;align-items:center}
.btn-primary{padding:11px 22px;background:linear-gradient(135deg,var(--pri),var(--pri2));color:#fff;border-radius:11px;font-weight:700;font-size:.92rem;display:inline-flex;align-items:center;gap:8px;box-shadow:var(--sh2)}
.btn-primary:hover{transform:translateY(-1px);box-shadow:0 8px 28px rgba(124,58,237,.32)}
.hero-progress{flex:1;min-width:200px;max-width:280px}
.hp-label{font-size:.74rem;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;display:block;margin-bottom:5px}
.hp-bar{height:8px;background:rgba(124,58,237,.18);border-radius:5px;overflow:hidden}
.hp-fill{height:100%;background:linear-gradient(90deg,var(--pri),var(--acc));border-radius:5px;width:0%;transition:width .6s cubic-bezier(.16,1,.3,1)}
.hp-text{font-size:.78rem;color:var(--muted);font-weight:700;margin-top:4px;display:block}
.hero-xp-badge{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;background:linear-gradient(135deg,var(--warn,#f59e0b),var(--pri));color:#fff;border-radius:99px;font-size:.82rem;font-weight:800;font-family:'Unbounded',sans-serif}
.psel{margin-bottom:24px}
.psel-title{font-size:.72rem;font-weight:800;color:var(--muted);text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px}
.psel-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:10px}
.psel-card{background:var(--card);border:1.5px solid var(--border);border-radius:13px;padding:14px;cursor:pointer;transition:transform .2s,box-shadow .2s,border-color .2s;text-align:left;position:relative}
.psel-card:hover{transform:translateY(-3px);box-shadow:var(--sh2);border-color:var(--pri)}
.psel-card.active{border-color:var(--pri);background:linear-gradient(135deg,var(--pri-soft),var(--card));box-shadow:var(--sh2)}
.psel-card.active::after{content:'';position:absolute;top:0;left:0;right:0;height:3px;background:linear-gradient(90deg,var(--pri),var(--acc));border-radius:13px 13px 0 0}
.psel-num{font-family:'Unbounded',sans-serif;font-size:.72rem;font-weight:800;color:var(--pri);text-transform:uppercase;letter-spacing:.08em;margin-bottom:5px}
.psel-name{font-size:.86rem;font-weight:700;color:var(--text);line-height:1.3;margin-bottom:8px}
.psel-prog{height:4px;background:rgba(124,58,237,.10);border-radius:3px;overflow:hidden}
.psel-prog-fill{height:100%;background:var(--pri);width:0%;transition:width .4s}
.psel-card.final{background:linear-gradient(135deg,#fff5e1,#fef3c7)}
.sec[id="sec-p13"] { --sec-acc:#7c3aed; --sec-acc-d:#6d28d9; --sec-acc-soft:#ede9fe; }
.sec[id="sec-p14"] { --sec-acc:#a855f7; --sec-acc-d:#9333ea; --sec-acc-soft:#f3e8ff; }
.sec[id="sec-p15"] { --sec-acc:#c026d3; --sec-acc-d:#a21caf; --sec-acc-soft:#fae8ff; }
.sec[id="sec-p16"] { --sec-acc:#8b5cf6; --sec-acc-d:#7c3aed; --sec-acc-soft:#ede9fe; }
.sec[id="sec-p17"] { --sec-acc:#6d28d9; --sec-acc-d:#5b21b6; --sec-acc-soft:#ddd6fe; }
.sec[id="sec-final2"]{ --sec-acc:#7c3aed; --sec-acc-d:#6d28d9; --sec-acc-soft:#ede9fe; }
.sec{display:none;position:relative;animation:fadeIn .35s ease}
.sec.active{display:block}
@keyframes fadeIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.sec::before{content:attr(data-watermark);position:absolute;right:-20px;top:10%;font-family:'Unbounded',sans-serif;font-size:clamp(6rem,18vw,14rem);font-weight:900;color:transparent;-webkit-text-stroke:1.5px var(--sec-acc-soft,var(--pri-soft));line-height:1;pointer-events:none;z-index:0;opacity:.35}
.sec-header{margin-bottom:22px;padding-bottom:14px;border-bottom:2px solid var(--sec-acc-soft,var(--pri-soft));position:relative;z-index:1}
.sec-num{display:inline-block;padding:4px 10px;background:linear-gradient(135deg,var(--sec-acc,var(--pri)),var(--sec-acc-d,var(--pri2)));color:#fff;border-radius:7px;font-family:'Unbounded',sans-serif;font-size:.78rem;font-weight:800;letter-spacing:.04em;margin-bottom:8px}
.sec-h{font-family:'Unbounded',sans-serif;font-size:1.5rem;font-weight:800;color:var(--sec-acc-d,var(--pri2));line-height:1.25}
.card{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:18px 20px;margin-bottom:16px;box-shadow:0 1px 3px rgba(0,0,0,.04),0 8px 24px rgba(124,58,237,.06);position:relative;z-index:1}
.card-header{display:flex;align-items:center;gap:10px;margin-bottom:12px;padding-bottom:10px;border-bottom:1px dashed var(--border)}
.card-icon{width:32px;height:32px;border-radius:9px;display:flex;align-items:center;justify-content:center;flex-shrink:0;color:#fff}
.card-icon.theory{background:#8b5cf6}.card-icon.rule{background:#ec4899}.card-icon.algo{background:#f59e0b}.card-icon.example{background:#10b981}
.card-icon .ic{width:18px;height:18px}
.card-title{font-family:'Unbounded',sans-serif;font-size:.82rem;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);flex:1}
.card-num{font-size:.74rem;font-weight:700;color:var(--muted);background:var(--sec-acc-soft,var(--pri-soft));padding:3px 7px;border-radius:5px}
.card-body{font-size:.94rem;line-height:1.65}
.card-body p{margin-bottom:8px}
.wg{background:linear-gradient(135deg,var(--card),var(--sec-acc-soft,var(--pri-soft)));border:1.5px solid var(--sec-acc,var(--pri));border-radius:14px;padding:18px 20px;margin-bottom:18px;box-shadow:var(--sh2);position:relative;z-index:1}
.wg-header{display:flex;align-items:center;gap:8px;margin-bottom:14px}
.wg-badge{padding:4px 9px;background:var(--sec-acc,var(--pri));color:#fff;border-radius:6px;font-family:'Unbounded',sans-serif;font-size:.68rem;font-weight:800;text-transform:uppercase;letter-spacing:.06em}
.wg-title{font-family:'Unbounded',sans-serif;font-size:1.05rem;font-weight:800;color:var(--sec-acc-d,var(--pri2));flex:1}
.wg-help{font-size:.88rem;color:var(--text);margin-bottom:12px;line-height:1.55;background:linear-gradient(135deg,var(--warn-bg,#fef3c7),var(--sec-acc-soft,var(--pri-soft)));border-left:4px solid var(--warn,#f59e0b);padding:9px 14px;border-radius:9px}
.btn{padding:8px 16px;border-radius:8px;background:var(--card);color:var(--text);border:1.5px solid var(--border);font-weight:600;font-size:.88rem;transition:background .15s,border-color .15s}
.btn:hover{background:var(--sec-acc-soft,var(--pri-soft));border-color:var(--sec-acc,var(--pri))}
.btn.primary{background:var(--sec-acc,var(--pri));color:#fff;border-color:var(--sec-acc,var(--pri))}
.btn.primary:hover{background:var(--sec-acc-d,var(--pri2));border-color:var(--sec-acc-d,var(--pri2))}
.tinp{padding:8px 12px;border:1.5px solid var(--border);border-radius:8px;background:var(--card);color:var(--text);font-family:'JetBrains Mono',monospace}
.tinp:focus{outline:0;border-color:var(--sec-acc,var(--pri));box-shadow:0 0 0 3px var(--sec-acc-soft,var(--pri-soft))}
.feedback{padding:10px 14px;border-radius:9px;font-weight:600;font-size:.88rem;margin-top:8px;display:none}
.feedback.ok{display:block;background:var(--ok-bg);color:#065f46;border-left:4px solid var(--ok)}
.feedback.fail{display:block;background:var(--fail-bg);color:#7f1d1d;border-left:4px solid var(--fail)}
.col-side{position:sticky;top:14px;align-self:start;height:fit-content;max-height:calc(100vh - 28px);overflow-y:auto}
.sidecard{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:16px;margin-bottom:14px;box-shadow:var(--sh)}
.sidecard h4{font-family:'Unbounded',sans-serif;font-size:.74rem;font-weight:800;color:var(--pri2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:10px;padding-bottom:8px;border-bottom:1px solid var(--border)}
.sidecard-row{margin-bottom:8px;font-size:.86rem;line-height:1.6}
.sidecard-row b{color:var(--pri);font-weight:700}
@media(max-width:980px){.col-side{position:static;max-height:none}}
.xp-card{background:linear-gradient(135deg,var(--acc-soft),var(--pri-soft));border:1.5px solid var(--acc);border-radius:12px;padding:14px;margin-bottom:14px}
.xp-card-title{font-size:.68rem;font-weight:800;color:var(--acc2);text-transform:uppercase;letter-spacing:.07em;margin-bottom:8px;display:flex;align-items:center;justify-content:space-between}
.xp-level{font-size:1.1rem;font-weight:900;color:var(--acc2);font-family:'Unbounded',sans-serif}
.xp-bar{height:9px;background:rgba(124,58,237,.18);border-radius:6px;overflow:hidden;margin:7px 0}
.xp-fill{height:100%;background:linear-gradient(90deg,var(--acc),var(--pri));border-radius:6px;transition:width .5s cubic-bezier(.4,0,.2,1)}
.xp-nums{font-size:.74rem;color:var(--muted);display:flex;justify-content:space-between}
.spoiler{border:1px solid var(--border);border-radius:10px;background:var(--card);margin:10px 0;overflow:hidden}
.spoiler summary{padding:8px 14px;background:var(--sec-acc-soft,var(--pri-soft));font-weight:700;cursor:pointer;font-size:.88rem;color:var(--sec-acc-d,var(--pri2));list-style:none;display:flex;align-items:center;gap:8px}
.spoiler summary::-webkit-details-marker{display:none}
.spoiler summary::before{content:'+';font-size:1.2rem;font-weight:900;color:var(--sec-acc,var(--pri));width:18px}
.spoiler[open] summary::before{content:'\2212'}
.spoiler-body{padding:10px 14px;font-size:.92rem;line-height:1.6}
.sec-nav{display:flex;gap:10px;margin-top:24px;padding-top:20px;border-top:1px solid var(--border);justify-content:space-between;flex-wrap:wrap}
.foot{text-align:center;padding:30px 16px;color:var(--muted);font-size:.78rem;border-top:1px solid var(--border);margin-top:30px}
.ach-popup{position:fixed;top:80px;right:18px;background:linear-gradient(135deg,#7c3aed,#a855f7);color:#fff;padding:12px 18px;border-radius:11px;font-weight:700;font-size:.9rem;box-shadow:0 8px 28px rgba(124,58,237,.45);z-index:1002;display:none;align-items:center;gap:8px;max-width:340px}
.ach-popup.show{display:flex}
.score-display{display:flex;gap:14px;flex-wrap:wrap;align-items:center;padding:10px 14px;background:var(--sec-acc-soft,var(--pri-soft));border-radius:10px;margin-bottom:12px}
.score-display b{color:var(--sec-acc-d,var(--pri2));font-size:1.15rem}
.hp-boss{height:14px;background:rgba(220,38,38,.12);border-radius:9px;overflow:hidden;border:1px solid #fecaca;margin:8px 0}
.hp-boss-fill{height:100%;background:linear-gradient(90deg,#dc2626,#f59e0b);border-radius:9px;transition:width .5s cubic-bezier(.4,0,.2,1)}
.col-side-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.42);z-index:9990;display:none}
.col-side-backdrop.show{display:block}
@media(max-width:980px){
.col-side{position:fixed;top:0;right:0;height:100vh;width:300px;max-width:88vw;background:var(--bg);box-shadow:-12px 0 24px rgba(0,0,0,.18);padding:18px 16px;overflow-y:auto;transform:translateX(100%);transition:transform .25s ease;z-index:9991;max-height:none}
.col-side.open{transform:none}
}
.boss-card{padding:16px;background:var(--card);border-radius:12px;border:2px solid var(--bad,#dc2626);margin-bottom:14px}
.boss-head{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.boss-title{font-family:'Unbounded',sans-serif;font-weight:800;color:#7f1d1d;font-size:1.04rem;flex:1}
.boss-stage{font-size:.85rem;color:var(--muted)}
.boss-q{font-size:1rem;line-height:1.55;padding:11px 13px;background:var(--card-soft);border-radius:8px;margin-bottom:9px;border-left:3px solid var(--bad,#dc2626)}
.svg-host{display:flex;justify-content:center;margin:12px 0}
.svg-host-row{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin:12px 0}
/* Formula plates */
.formula-plate{margin:16px 0;border-radius:14px;overflow:hidden;border:1.5px solid var(--border);box-shadow:0 4px 16px rgba(0,0,0,.04);background:var(--card)}
.formula-plate-head{padding:14px 18px;text-align:center;border-bottom:1px solid var(--border);background:linear-gradient(180deg,rgba(124,58,237,.12),rgba(124,58,237,.06))}
.formula-plate-title{font-family:'Unbounded',sans-serif;font-size:1.02rem;font-weight:800;letter-spacing:.04em;margin-bottom:4px;text-transform:uppercase;color:#6d28d9}
.formula-plate-sub{font-size:.84rem;font-style:italic;color:var(--muted);line-height:1.4}
.formula-plate-body{padding:14px 22px}
.formula-row{padding:9px 4px;font-size:1.08rem;text-align:center;line-height:1.5;border-bottom:1px dashed rgba(0,0,0,.05)}
.formula-row:last-child{border-bottom:0}
.formula-row.alt{color:#0891b2}
.formula-row.danger{color:#dc2626}
</style>
</head>
<body>
<header class="hdr">
<div class="hdr-row">
<div>
<h1>Алгебра 10 · Глава 2</h1>
<div class="hdr-sub">Корень n-й степени · свойства · функция y = ⁿ√x · иррациональные уравнения</div>
</div>
<div class="hdr-side">
<a href="/textbook/algebra-10" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> К Алгебре 10</a>
<button id="sidebar-btn" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><line x1="4" y1="6" x2="20" y2="6"/><line x1="4" y1="12" x2="20" y2="12"/><line x1="4" y1="18" x2="14" y2="18"/></svg> Шпаргалка</button>
<button id="theme-btn" class="hdr-btn"><svg class="ic" viewBox="0 0 24 24"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg><span id="theme-lab">Тёмная</span></button>
</div>
</div>
</header>
<main class="main">
<div class="col-main">
<section class="hero">
<h2>Из квадратного корня — в корень любой степени</h2>
<p>Квадратный корень $\sqrt{x}$ — это число $y \ge 0$, что $y^2 = x$. А что если степень не $2$, а $3, 4, 5$? Этим занимается <b>корень $n$-й степени</b> $\sqrt[n]{x}$. У него есть особенности: при чётном $n$ — нужен модуль; при нечётном — корень есть из любого числа.</p>
<div class="hero-row">
<button class="btn-primary" onclick="goTo('p13')"><svg class="ic" viewBox="0 0 24 24"><polygon points="6 4 20 12 6 20 6 4" fill="currentColor" stroke="none"/></svg> Начать § 13</button>
<div class="hero-progress">
<span class="hp-label">Прогресс по главе</span>
<div class="hp-bar"><div id="hero-hp-fill" class="hp-fill"></div></div>
<span id="hero-hp-text" class="hp-text">0%</span>
</div>
<div id="hero-xp-badge" class="hero-xp-badge" data-gamified></div>
</div>
</section>
<section class="psel">
<div class="psel-title">Параграфы главы</div>
<div id="psel-grid" class="psel-grid"></div>
</section>
<section id="sec-p13" class="sec" data-watermark="ⁿ√"><div class="sec-header"><span class="sec-num">§ 13</span><h2 class="sec-h">Корень n-й степени из числа a</h2></div><div id="p13-body"></div></section>
<section id="sec-p14" class="sec" data-watermark="·"><div class="sec-header"><span class="sec-num">§ 14</span><h2 class="sec-h">Свойства корней n-й степени</h2></div><div id="p14-body"></div></section>
<section id="sec-p15" class="sec" data-watermark="↔"><div class="sec-header"><span class="sec-num">§ 15</span><h2 class="sec-h">Применение свойств для преобразований</h2></div><div id="p15-body"></div></section>
<section id="sec-p16" class="sec" data-watermark="∿"><div class="sec-header"><span class="sec-num">§ 16</span><h2 class="sec-h">Функция y = ⁿ√x. Свойства и график</h2></div><div id="p16-body"></div></section>
<section id="sec-p17" class="sec" data-watermark="="><div class="sec-header"><span class="sec-num">§ 17</span><h2 class="sec-h">Иррациональные уравнения</h2></div><div id="p17-body"></div></section>
<section id="sec-final2" class="sec" data-watermark="&#9733;"><div class="sec-header"><span class="sec-num" style="background:linear-gradient(135deg,#7c3aed,#c4b5fd)">Финал главы</span><h2 class="sec-h">Итоги. 4 босса главы 2</h2></div><div id="final2-body"></div></section>
</div>
<aside class="col-side" id="col-side"><div id="sidebar-content"></div></aside>
<div class="col-side-backdrop" id="col-side-backdrop"></div>
</main>
<footer class="foot">Интерактивный учебник «Алгебра — 10 класс» · Глава 2 · Корень n-й степени · LearnSpace</footer>
<div id="ach-popup" class="ach-popup"><svg class="ic" viewBox="0 0 24 24" style="width:22px;height:22px"><polygon points="12,2 22,20 2,20"/></svg><span id="ach-text">Достижение!</span></div>
<script>
'use strict';
const STATE = { current:'p13', progress:{p13:0,p14:0,p15:0,p16:0,p17:0,final2:0}, achievements:new Map(), xp:0, level:1 };
const TOTAL_PARAS = 6;
const _TB_SLUG = 'algebra-10-ch2';
function calcLevel(xp){ return Math.floor(Math.sqrt((xp||0)/100))+1; }
function _xpForLevel(lv){ return (lv-1)*(lv-1)*100; }
const ACH_LABELS = {
start:'Начало главы 2!',
p13_done:'Определение корня — освоено!',
p14_done:'Свойства корней — твои!',
p15_done:'Преобразования — мастер!',
p16_done:'Функция ⁿ√x — понятна!',
p17_done:'Иррациональные уравнения — решаешь!',
ch2_done:'Глава 2 — Корни пройдена!',
root_master:'Магистр корней! +100 XP',
};
function loadProgress(){
try{
const s=localStorage.getItem('algebra10_ch2_progress'); if(s) Object.assign(STATE.progress, JSON.parse(s));
const a=localStorage.getItem('algebra10_ch2_achievements');
if(a){ const p=JSON.parse(a); if(Array.isArray(p)) p.forEach(id=>STATE.achievements.set(id, ACH_LABELS[id]||id)); else if(p&&typeof p==='object'){ for(const[id,t] of Object.entries(p)) STATE.achievements.set(id,(t&&t!==id)?t:(ACH_LABELS[id]||id)); } }
STATE.xp=+(localStorage.getItem('algebra10_xp')||0); STATE.level=calcLevel(STATE.xp);
}catch(e){}
}
function saveProgress(){
try{
localStorage.setItem('algebra10_ch2_progress', JSON.stringify(STATE.progress));
localStorage.setItem('algebra10_ch2_achievements', JSON.stringify(Object.fromEntries(STATE.achievements)));
localStorage.setItem('algebra10_xp', String(STATE.xp));
}catch(e){}
}
function bumpProgress(key, delta){
STATE.progress[key]=Math.max(0,Math.min(100,(STATE.progress[key]||0)+delta));
saveProgress(); refreshProgressUI();
if(STATE.progress[key]>=50) markParaRead(key);
if(STATE.progress[key]>=100){
if(key==='p13') achievement('p13_done');
else if(key==='p14') achievement('p14_done');
else if(key==='p15') achievement('p15_done');
else if(key==='p16') achievement('p16_done');
else if(key==='p17') achievement('p17_done');
else if(key==='final2') achievement('ch2_done');
}
}
const _markedRead=new Set();
let _pendingProgressBody=null, _progressTimer=null;
function _flushProgress(){
const body=_pendingProgressBody; _pendingProgressBody=null; if(!body) return;
const tok=(window.LS&&LS.getToken)?LS.getToken():''; if(!tok) return;
fetch('/api/textbooks/'+_TB_SLUG+'/progress',{method:'POST',headers:{'Content-Type':'application/json','Authorization':'Bearer '+tok},body:JSON.stringify(body),keepalive:true}).catch(()=>{});
}
function _queueProgress(patch){ _pendingProgressBody=Object.assign(_pendingProgressBody||{},patch); if(_progressTimer) clearTimeout(_progressTimer); _progressTimer=setTimeout(_flushProgress, 600); }
function markLastPara(id){ _queueProgress({last_para:id}); }
function markParaRead(id){ if(_markedRead.has(id)) return; _markedRead.add(id); _queueProgress({mark_read:id}); }
window.addEventListener('beforeunload', _flushProgress);
function addXp(n,src){
if(!n) return;
const prev=STATE.level; STATE.xp=Math.max(0,(STATE.xp||0)+n); STATE.level=calcLevel(STATE.xp);
saveProgress(); refreshProgressUI();
if(window.LS&&window.LS.xp) window.LS.xp.add(n,'algebra10-ch2-'+(src||'misc'));
if(STATE.level>prev){
const pop=document.getElementById('ach-popup');
if(pop){ document.getElementById('ach-text').textContent='Уровень '+STATE.level+'!'; pop.classList.add('show'); setTimeout(()=>pop.classList.remove('show'),2600); }
}
}
function refreshProgressUI(){
const total=Math.round(Object.values(STATE.progress).reduce((a,b)=>a+b,0)/TOTAL_PARAS);
const f=document.getElementById('hero-hp-fill'); if(f) f.style.width=total+'%';
const t=document.getElementById('hero-hp-text'); if(t) t.textContent=total+'% пройдено';
document.querySelectorAll('[data-prog-card]').forEach(el=>{ const k=el.dataset.progCard; const fl=el.querySelector('.psel-prog-fill'); if(fl) fl.style.width=(STATE.progress[k]||0)+'%'; });
const xpBadge=document.getElementById('hero-xp-badge');
if(xpBadge){ xpBadge.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:13px;height:13px"><polygon points="12 2 22 20 2 20"/></svg> Ур. '+STATE.level+' \xb7 '+(STATE.xp||0)+' XP'; }
if(STATE.current && document.getElementById('sidebar-content')){ try{ buildSidebar(STATE.current); }catch(e){} }
}
function achievement(id,text){
if(STATE.achievements.has(id)) return;
STATE.achievements.set(id, text||ACH_LABELS[id]||id); saveProgress();
const pop=document.getElementById('ach-popup');
if(pop){ document.getElementById('ach-text').textContent=text||ACH_LABELS[id]||id; pop.classList.add('show'); setTimeout(()=>pop.classList.remove('show'),3300); }
addXp(20,'ach-'+id);
}
const PARAS = [
{ id:'p13', num:'§ 13', name:'Определение ⁿ√a', sub:'чётное/нечётное n' },
{ id:'p14', num:'§ 14', name:'Свойства корней', sub:'произв., частное, степень' },
{ id:'p15', num:'§ 15', name:'Преобразования', sub:'вынесение, рационализация' },
{ id:'p16', num:'§ 16', name:'y = ⁿ√x', sub:'свойства и графики' },
{ id:'p17', num:'§ 17', name:'Иррац. уравнения', sub:'возведение в степень' },
{ id:'final2', num:'&#9733;', name:'Финал главы', sub:'4 босса', final:true },
];
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);
});
if(window.renderMathInElement) try{ renderMath(g); }catch(e){}
}
const BUILT=new Set();
const BUILDERS = { p13:()=>buildP13(), p14:()=>buildP14(), p15:()=>buildP15(), p16:()=>buildP16(), p17:()=>buildP17(), final2:()=>buildFinal2() };
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);
markLastPara(id);
}
const SIDEBARS = {
p13:{title:'Шпаргалка §13',rows:[
['Опр.','$\\sqrt[n]{a} = b$ ⇔ $b^n = a$, $b \\ge 0$'],
['Чётное n','требует $a \\ge 0$'],
['Нечётное n','работает для любого $a$'],
['$\\sqrt[3]{-8}$','$= -2$ (нечёт., возможно)'],
['$\\sqrt[4]{-16}$','не существует'],
['Уравнение','$x^n = a$ ⇒ корней зависит от $n$ и знака $a$'],
]},
p14:{title:'Шпаргалка §14',rows:[
['Произведение','$\\sqrt[n]{ab} = \\sqrt[n]{a} \\cdot \\sqrt[n]{b}$'],
['Частное','$\\sqrt[n]{\\frac{a}{b}} = \\frac{\\sqrt[n]{a}}{\\sqrt[n]{b}}$'],
['Степень','$\\sqrt[n]{a^m} = (\\sqrt[n]{a})^m$'],
['Доумножение','$\\sqrt[n]{a} = \\sqrt[nk]{a^k}$'],
['Корень из корня','$\\sqrt[k]{\\sqrt[n]{a}} = \\sqrt[kn]{a}$'],
['$\\sqrt[n]{a^n}$','$= |a|$ (чёт.) или $a$ (нечёт.)'],
]},
p15:{title:'Шпаргалка §15',rows:[
['Вынесение','$\\sqrt[5]{160} = 2\\sqrt[5]{5}$'],
['Внесение','$2\\sqrt[3]{7} = \\sqrt[3]{56}$'],
['Рационализация','$\\frac{3}{\\sqrt[4]{8}} = \\frac{3\\sqrt[4]{2}}{2}$'],
['Сравнение','через приведение к общему показателю'],
['Сокращение','подкоренное на $k$-й степени'],
]},
p16:{title:'Шпаргалка §16',rows:[
['Чётное n','$D = [0;\\,+\\infty)$, $E = [0;\\,+\\infty)$'],
['','возрастает на $D$'],
['Нечётное n','$D = \\mathbb{R}$, $E = \\mathbb{R}$'],
['','возрастает, нечётная'],
['$y = \\sqrt[n]{x}$','обратная к $y = x^n$'],
['Чем больше n','тем график ближе к $y=1$ при $x \\to \\infty$'],
]},
p17:{title:'Шпаргалка §17',rows:[
['Метод','возвести обе части в $n$-ю степень'],
['ОДЗ','подкоренное $\\ge 0$ для чётных корней'],
['Проверка','подставить корень в исходное'],
['Посторонние','появляются при возведении'],
['$\\sqrt{f} = g$','⇔ $f = g^2$ и $g \\ge 0$'],
['Замена','часто $t = \\sqrt[n]{f(x)}$'],
]},
final2:{title:'Финал главы 2',rows:[
['Боссов','4 — все темы'],
['Босс 1','§13-§14 определение + свойства'],
['Босс 2','§15 преобразования'],
['Босс 3','§16 функция ⁿ√x'],
['Босс 4','§17 иррац. уравнения'],
['Награда','+100 XP + «Магистр корней»'],
]},
};
const TIPS=[
{sec:'p13',html:'Корень $n$-й степени из <b>отрицательного</b> числа существует <b>только при нечётном $n$</b>. Например, $\\sqrt[3]{-8} = -2$, но $\\sqrt[4]{-16}$ не существует.'},
{sec:'p14',html:'Свойства работают <b>в обе стороны</b> — и для упрощения произведения, и для разложения корня на множители. Главное: подкоренные выражения должны быть <b>неотрицательными</b> для чётных корней.'},
{sec:'p15',html:'Чтобы избавиться от иррациональности в знаменателе — умножь дробь на нужный множитель: для $\\sqrt[n]{a}$ умножай на $\\sqrt[n]{a^{n-1}}$, чтобы получить $\\sqrt[n]{a^n} = a$.'},
{sec:'p16',html:'Запомни: для <b>чётного $n$</b> функция $y = \\sqrt[n]{x}$ определена только при $x \\ge 0$. Для <b>нечётного $n$</b> — на всей оси. Все они возрастающие.'},
{sec:'p17',html:'После возведения в чётную степень <b>обязательно проверяй корни</b> подстановкой в исходное уравнение. Это исключает посторонние корни, появившиеся из-за возведения.'},
{sec:'final2',html:'4 интегрированных босса проверяют все темы главы. После победы — ачивка <b>«Магистр корней»</b> и +100 XP.'},
];
function buildSidebar(id){
const box=document.getElementById('sidebar-content');
const sb=SIDEBARS[id]||SIDEBARS.p13;
let html='';
const xpForLv=_xpForLevel(STATE.level), xpNext=_xpForLevel(STATE.level+1);
const xpInLv=STATE.xp-xpForLv, xpRange=xpNext-xpForLv;
const xpPct=xpRange>0?Math.round(xpInLv/xpRange*100):100;
html+='<div class="xp-card" data-gamified><div class="xp-card-title" data-gamified><span>XP-прогресс</span><span class="xp-level">Ур. '+STATE.level+'</span></div><div class="xp-bar"><div class="xp-fill" style="width:'+xpPct+'%"></div></div><div class="xp-nums"><span>'+STATE.xp+' XP</span><span>'+xpNext+' XP</span></div></div>';
html+='<div class="sidecard"><h4>'+sb.title+'</h4>';
sb.rows.forEach(([k,v])=>{ html+='<div class="sidecard-row"><b>'+k+'</b>'+(v?' — '+v:'')+'</div>'; });
html+='</div>';
const tip=TIPS.find(t=>t.sec===id)||TIPS[0];
html+='<div class="sidecard" style="background:linear-gradient(135deg,var(--warn-bg,#fef3c7),var(--pri-soft));border-color:var(--warn,#f59e0b)"><h4 style="color:#92400e">Подсказка</h4><div class="sidecard-row" style="font-size:.84rem;line-height:1.55">'+tip.html+'</div></div>';
if(STATE.achievements.size>0){
html+='<div class="sidecard"><h4>Достижения</h4>';
[...STATE.achievements.values()].slice(-4).forEach(text=>{ html+='<div class="sidecard-row" style="font-size:.78rem;color:var(--ok)">&#10003; '+text+'</div>'; });
html+='</div>';
}
box.innerHTML=html;
if(window.renderMathInElement) try{ renderMath(box); }catch(e){}
}
function initTheme(){
const t=localStorage.getItem('algebra10_ch2_theme')||'light';
if(t==='dark') document.documentElement.classList.add('dark');
document.getElementById('theme-lab').textContent=t==='dark'?'Светлая':'Тёмная';
document.getElementById('theme-btn').addEventListener('click', ()=>{
document.documentElement.classList.toggle('dark');
const dark=document.documentElement.classList.contains('dark');
localStorage.setItem('algebra10_ch2_theme', dark?'dark':'light');
document.getElementById('theme-lab').textContent=dark?'Светлая':'Тёмная';
});
}
function renderMath(root){ if(window.renderMathInElement){ try{ renderMathInElement(root, {delimiters:[{left:'$$',right:'$$',display:true},{left:'$',right:'$',display:false},{left:'\\[',right:'\\]',display:true},{left:'\\(',right:'\\)',display:false}],throwOnError:false}); }catch(e){} } }
function feedback(elm, ok, text){ if(!elm) return; elm.className='feedback '+(ok?'ok':'fail'); elm.innerHTML=text||(ok?'&#10003; Верно!':'&#10007; Неверно'); elm.style.display='block'; try{renderMath(elm);}catch(e){} }
const ICONS = {
theory:'<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>',
algo:'<svg class="ic" viewBox="0 0 24 24"><polyline points="17 11 21 7 17 3"/><line x1="21" y1="7" x2="9" y2="7"/><polyline points="7 13 3 17 7 21"/><line x1="3" y1="17" x2="15" y2="17"/></svg>',
rule:'<svg class="ic" viewBox="0 0 24 24"><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></svg>',
example:'<svg class="ic" viewBox="0 0 24 24"><path d="M9 18h6"/><path d="M10 22h4"/><path d="M12 2a7 7 0 0 0-4 13c1 1 2 2 2 4h4c0-2 1-3 2-4a7 7 0 0 0-4-13z"/></svg>',
};
function makeCard(kind, title, num, body){
const labels={theory:'Теория',algo:'Алгоритм',rule:'Правило',example:'Пример'};
return '<div class="card"><div class="card-header"><div class="card-icon '+kind+'">'+ICONS[kind]+'</div><div class="card-title">'+(labels[kind]||'')+(title&&title!==labels[kind]?' \xb7 '+title:'')+'</div>'+(num?'<div class="card-num">'+num+'</div>':'')+'</div><div class="card-body">'+body+'</div></div>';
}
function secNav(prev, next){
const NAMES={p13:'§13',p14:'§14',p15:'§15',p16:'§16',p17:'§17',final2:'Финал'};
let h='<div class="sec-nav">';
h+=prev?'<button class="btn" onclick="goTo(\''+prev+'\')"><svg class="ic" viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> '+NAMES[prev]+'</button>':'<span></span>';
h+=next?'<button class="btn primary" onclick="goTo(\''+next+'\')">'+NAMES[next]+' <svg class="ic" viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg></button>':'<span></span>';
h+='</div>'; return h;
}
function makeTrainer(opts){
let i=0, score=0;
const Q=opts.questions;
const parser = opts.parser || (v => parseFloat(String(v).replace(',','.')));
function show(){
if(i >= Q.length){
document.getElementById(opts.idPrefix+'-q').innerHTML = '<b>Готово!</b> Результат: '+score+' / '+Q.length;
if(opts.onComplete) opts.onComplete(score, Q.length);
return;
}
document.getElementById(opts.idPrefix+'-i').textContent = (i+1);
document.getElementById(opts.idPrefix+'-s').textContent = score;
document.getElementById(opts.idPrefix+'-q').innerHTML = Q[i].q;
document.getElementById(opts.idPrefix+'-ans').value = '';
renderMath(document.getElementById(opts.idPrefix+'-q'));
document.getElementById(opts.idPrefix+'-fb').style.display = 'none';
}
function go(){
if(i >= Q.length) return;
const fb = document.getElementById(opts.idPrefix+'-fb');
const raw = document.getElementById(opts.idPrefix+'-ans').value.trim();
if(raw === ''){ feedback(fb, false, '&#10007; Введи ответ.'); return; }
const expected = Q[i].a;
let ok = false;
if(typeof expected === 'function') ok = expected(raw);
else { const got = parser(raw); ok = !isNaN(got) && Math.abs(got - expected) < 1e-6; }
if(ok){ score++; feedback(fb, true, '&#10003; Верно! Дальше ▶'); }
else feedback(fb, false, '&#10007; Неверно. Правильно: <b>'+(Q[i].show||expected)+'</b>. Дальше ▶');
document.getElementById(opts.idPrefix+'-s').textContent = score;
i++; setTimeout(show, 1100);
}
document.getElementById(opts.idPrefix+'-go').addEventListener('click', go);
document.getElementById(opts.idPrefix+'-ans').addEventListener('keydown', e=>{ if(e.key==='Enter') go(); });
const restart = document.getElementById(opts.idPrefix+'-start');
if(restart) restart.addEventListener('click', ()=>{ i=0; score=0; show(); });
show();
}
function trainerHTML(idPrefix, total, placeholder){
return '<div class="score-display"><span>Задача <b id="'+idPrefix+'-i">1</b> / '+total+'</span><span>Очки: <b id="'+idPrefix+'-s">0</b> / '+total+'</span></div>'
+'<div id="'+idPrefix+'-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.05rem;margin-bottom:10px;text-align:center"></div>'
+'<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;justify-content:center">'
+'<input type="text" id="'+idPrefix+'-ans" class="tinp" placeholder="'+(placeholder||'Ответ')+'" style="width:140px;text-align:center">'
+'<button class="btn primary" id="'+idPrefix+'-go">Проверить</button>'
+'<button class="btn" id="'+idPrefix+'-start">Заново</button>'
+'</div><div class="feedback" id="'+idPrefix+'-fb"></div>';
}
function makeBoss(paraId, bossDef){
const idP = paraId+'-boss';
const SKEY = 'algebra10_ch2_'+paraId+'_boss';
let st = {stage:0, defeated:false};
try{ const s=localStorage.getItem(SKEY); if(s) st=JSON.parse(s); }catch(e){}
const html = '<div class="boss-card" style="border-color:'+bossDef.color+'">'
+'<div class="boss-head">'
+'<svg viewBox="0 0 24 24" fill="none" stroke="'+bossDef.color+'" stroke-width="2.2" style="width:28px;height:28px"><polygon points="12,2 22,20 2,20"/></svg>'
+'<div class="boss-title" style="color:'+bossDef.color+'">'+bossDef.title+'</div>'
+'<div class="boss-stage" id="'+idP+'-stage">Этап 1 / '+bossDef.steps.length+'</div>'
+'</div>'
+'<div class="hp-boss" style="border-color:'+bossDef.color+'66;background:'+bossDef.color+'1a"><div class="hp-boss-fill" id="'+idP+'-fill" style="width:0%;background:linear-gradient(90deg,'+bossDef.color+',#f59e0b)"></div></div>'
+'<div class="boss-q" id="'+idP+'-q" style="border-color:'+bossDef.color+'"></div>'
+'<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">'
+'<input type="text" id="'+idP+'-input" class="tinp" placeholder="Ответ" style="width:160px;text-align:center">'
+'<button class="btn primary" id="'+idP+'-go" style="background:'+bossDef.color+';border-color:'+bossDef.color+'">Атака</button>'
+'<button class="btn" id="'+idP+'-hint">Подсказка</button>'
+'<button class="btn" id="'+idP+'-restart">↻</button>'
+'</div>'
+'<div class="feedback" id="'+idP+'-fb"></div>'
+'</div>';
setTimeout(()=>{
function save(){ try{ localStorage.setItem(SKEY, JSON.stringify(st)); }catch(e){} }
function show(){
const stageEl=document.getElementById(idP+'-stage');
const fill=document.getElementById(idP+'-fill');
const q=document.getElementById(idP+'-q');
const fb=document.getElementById(idP+'-fb');
if(st.defeated){
stageEl.textContent='&#10003; Побеждён'; fill.style.width='100%';
q.innerHTML='<b style="color:'+bossDef.color+'">Босс повержен!</b>';
document.getElementById(idP+'-go').disabled=true;
document.getElementById(idP+'-go').style.opacity=.5;
return;
}
stageEl.textContent='Этап '+(st.stage+1)+' / '+bossDef.steps.length;
fill.style.width=(st.stage*100/bossDef.steps.length)+'%';
q.innerHTML=bossDef.steps[st.stage].q;
document.getElementById(idP+'-input').value='';
fb.style.display='none';
renderMath(q);
}
document.getElementById(idP+'-go').addEventListener('click',()=>{
if(st.defeated) return;
const step=bossDef.steps[st.stage];
const val=document.getElementById(idP+'-input').value;
const fb=document.getElementById(idP+'-fb');
if(!val.trim()){ feedback(fb,false,'&#10007; Введи ответ.'); return; }
if(step.verify(val)){
st.stage++;
if(st.stage>=bossDef.steps.length){
st.defeated=true; save();
feedback(fb,true,'&#10003; Босс повержен! +20 XP');
addXp(20,paraId+'-boss'); bumpProgress(paraId, 30);
setTimeout(show,1400);
}else{
save(); feedback(fb,true,'&#10003; Верно! +3 XP'); addXp(3,paraId+'-boss-step'); setTimeout(show,1100);
}
}else{ feedback(fb,false,'&#10007; Промах.'); }
});
document.getElementById(idP+'-hint').addEventListener('click',()=>{
if(st.defeated) return;
const fb=document.getElementById(idP+'-fb');
fb.className='feedback ok';
fb.innerHTML='<span style="color:#92400e">\u{1F4A1} Подсказка:</span> '+bossDef.steps[st.stage].hint;
fb.style.display='block';
fb.style.background='var(--warn-bg)'; fb.style.color='#92400e'; fb.style.borderLeftColor='var(--warn)';
renderMath(fb);
});
document.getElementById(idP+'-restart').addEventListener('click',()=>{
st={stage:0,defeated:false}; save();
document.getElementById(idP+'-go').disabled=false;
document.getElementById(idP+'-go').style.opacity=1;
show();
});
show();
}, 0);
return html;
}
function readButton(paraId){
return '<div style="margin-top:18px;display:flex;justify-content:center">'
+'<button class="btn primary" id="'+paraId+'-read-btn">'
+'<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>'
+' Я прочитал §'+paraId.replace('p','').replace('final','финал ')+' (+10 XP)'
+'</button></div>';
}
function wireReadBtn(paraId){
document.getElementById(paraId+'-read-btn').addEventListener('click', ()=>{
addXp(10, paraId+'-read'); bumpProgress(paraId, 30);
const b=document.getElementById(paraId+'-read-btn'); b.textContent='Прочитано! +10 XP'; b.disabled=true; b.style.opacity=.6;
});
}
function initSidebarToggle(){
const side=document.getElementById('col-side'),back=document.getElementById('col-side-backdrop'),btn=document.getElementById('sidebar-btn');
if(!side||!btn) return;
function open(){ side.classList.add('open'); back.classList.add('show'); }
function close(){ side.classList.remove('open'); back.classList.remove('show'); }
btn.addEventListener('click',()=>{ if(side.classList.contains('open')) close(); else open(); });
back.addEventListener('click',close);
document.addEventListener('keydown',e=>{ if(e.key==='Escape') close(); });
}
function init(){
loadProgress(); initTheme(); initSidebarToggle();
buildParaSelector(); refreshProgressUI(); goTo('p13');
setTimeout(()=>achievement('start','Начало главы 2!'), 600);
}
document.addEventListener('DOMContentLoaded', init);
/* ============================================================
§ 13 — Корень n-й степени из числа a
============================================================ */
function buildP13(){
const box = document.getElementById('p13-body');
const A = window.ALG10;
let html = '';
/* === SVG: графики y = xⁿ === */
let svgGraphs = '';
if(A){
const f = A.func.canvas({id:'p13-g', W:560, H:280, xRange:[-2.5, 2.5], yRange:[-6, 8], bg:'#fff'});
let s = f.open
+ f.grid({xStep:1, yStep:2, color:'#f1f5f9'})
+ f.axes({color:'#475569', xTicks:[{val:-2,label:'-2'},{val:-1,label:'-1'},{val:1,label:'1'},{val:2,label:'2'}], yTicks:[{val:-4,label:'-4'},{val:-2,label:'-2'},{val:2,label:'2'},{val:4,label:'4'},{val:6,label:'6'}]})
/* Горизонтальная линия y = 4 — пример */
+ '<line x1="0" y1="'+f.pxY(4)+'" x2="'+f.W+'" y2="'+f.pxY(4)+'" stroke="#dc2626" stroke-width="1.5" stroke-dasharray="5 3"/>'
+ '<text x="'+(f.W-50)+'" y="'+(f.pxY(4)-6)+'" font-size="11" font-family="JetBrains Mono,monospace" font-weight="700" fill="#dc2626">y = 4</text>'
/* Графики */
+ f.plot(x => x*x, {color:'#0d9488', width:2.5}) /* y=x² */
+ f.plot(x => x*x*x, {color:'#7c3aed', width:2.5}) /* y=x³ */
+ f.plot(x => Math.pow(Math.abs(x),4)*Math.sign(x*x), {color:'#0891b2', width:2.2, dash:'4 3'}) /* y=x⁴ */
+ f.plot(x => Math.pow(x,5), {color:'#dc2626', width:2.2, dash:'4 3'}) /* y=x⁵ */
/* Легенда */
+ '<rect x="20" y="20" width="92" height="92" rx="6" fill="rgba(255,255,255,.85)" stroke="#cbd5e1"/>'
+ '<line x1="30" y1="36" x2="50" y2="36" stroke="#0d9488" stroke-width="2.5"/>'
+ '<text x="56" y="40" font-size="12" font-family="JetBrains Mono,monospace" fill="#0d9488" font-weight="700">y = x²</text>'
+ '<line x1="30" y1="56" x2="50" y2="56" stroke="#7c3aed" stroke-width="2.5"/>'
+ '<text x="56" y="60" font-size="12" font-family="JetBrains Mono,monospace" fill="#7c3aed" font-weight="700">y = x³</text>'
+ '<line x1="30" y1="76" x2="50" y2="76" stroke="#0891b2" stroke-width="2.2" stroke-dasharray="4 3"/>'
+ '<text x="56" y="80" font-size="12" font-family="JetBrains Mono,monospace" fill="#0891b2" font-weight="700">y = x⁴</text>'
+ '<line x1="30" y1="96" x2="50" y2="96" stroke="#dc2626" stroke-width="2.2" stroke-dasharray="4 3"/>'
+ '<text x="56" y="100" font-size="12" font-family="JetBrains Mono,monospace" fill="#dc2626" font-weight="700">y = x⁵</text>'
+ f.close;
svgGraphs = s;
}
html += makeCard('theory', 'От квадратного корня к n-му', '13.1', `
<p>В 8 классе мы изучали <b>квадратный корень</b>: $\\sqrt{a} = b$, где $b \\ge 0$ и $b^2 = a$.</p>
<p>Естественное обобщение — <b>корень $n$-й степени</b> ($n \\ge 2$, $n \\in \\mathbb{N}$). Например:</p>
<ul style="padding-left:22px;line-height:1.85">
<li>$\\sqrt[3]{8} = 2$, потому что $2^3 = 8$;</li>
<li>$\\sqrt[4]{81} = 3$, потому что $3^4 = 81$;</li>
<li>$\\sqrt[5]{32} = 2$, потому что $2^5 = 32$.</li>
</ul>`);
html += makeCard('rule', 'Определение арифметического корня', '13.2', `
<p style="background:var(--sec-acc-soft);padding:10px 14px;border-radius:8px"><b>Определение.</b> <b>Арифметическим корнем $n$-й степени</b> ($n \\ge 2$) из неотрицательного числа $a$ называется такое <b>неотрицательное</b> число $b$, что $b^n = a$. Обозначается $\\sqrt[n]{a}$.</p>
<p>Запись: $\\sqrt[n]{a} = b \\;\\Leftrightarrow\\; b \\ge 0$ и $b^n = a$.</p>
<p>Число $n$ — <b>показатель корня</b>, $a$ — <b>подкоренное выражение</b>.</p>`);
html += makeCard('rule', 'Чётные и нечётные показатели', '13.3', `
<p>Поведение корня сильно зависит от того, чётное или нечётное $n$:</p>
<table style="width:100%;border-collapse:collapse;margin:8px 0;font-size:.94rem">
<tr style="background:var(--sec-acc-soft)"><th style="padding:6px;border:1px solid var(--border);text-align:left">$n$</th><th style="padding:6px;border:1px solid var(--border);text-align:left">$a \\ge 0$</th><th style="padding:6px;border:1px solid var(--border);text-align:left">$a < 0$</th></tr>
<tr><td style="padding:6px;border:1px solid var(--border)"><b>чётное</b> ($2, 4, 6, \\ldots$)</td><td style="padding:6px;border:1px solid var(--border);color:#065f46">$\\sqrt[n]{a}$ — единственное неотр. число</td><td style="padding:6px;border:1px solid var(--border);color:#dc2626"><b>не существует</b></td></tr>
<tr><td style="padding:6px;border:1px solid var(--border)"><b>нечётное</b> ($3, 5, 7, \\ldots$)</td><td style="padding:6px;border:1px solid var(--border);color:#065f46">$\\sqrt[n]{a}$ — единственное неотр. число</td><td style="padding:6px;border:1px solid var(--border);color:#065f46"><b>существует</b>, равно $-\\sqrt[n]{|a|}$</td></tr>
</table>
<div class="svg-host">${svgGraphs}</div>
<p>На графике видно: линия $y = 4$ пересекает <b>$y = x^2$</b> в двух точках ($\\pm 2$), но <b>$y = x^3$</b> только в одной ($\\sqrt[3]{4}$).</p>
<p><b>Примеры.</b></p>
<ul style="padding-left:22px;line-height:1.85">
<li>$\\sqrt[3]{-8} = -2$, так как $(-2)^3 = -8$ (нечёт. $n$, ОК);</li>
<li>$\\sqrt[4]{-16}$ — <b>не существует</b> (чёт. $n$, отриц. $a$).</li>
</ul>`);
html += makeCard('example', 'Связь с уравнением', '13.4', `
<p>Корень $n$-й степени тесно связан с уравнением $x^n = a$:</p>
<p><b>Чётное $n$:</b></p>
<ul style="padding-left:22px;line-height:1.85">
<li>$a > 0$: <b>2 корня</b> — $x = \\pm\\sqrt[n]{a}$;</li>
<li>$a = 0$: <b>1 корень</b> — $x = 0$;</li>
<li>$a < 0$: <b>корней нет</b>.</li>
</ul>
<p><b>Нечётное $n$:</b> <b>всегда ровно 1 корень</b> — $x = \\sqrt[n]{a}$ (положительный, если $a > 0$, отрицательный, если $a < 0$).</p>`);
/* === ИНТЕРАКТИВ 1: Существует ли === */
html += '<div class="wg" id="p13-iv1">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Существует ли корень?</div></div>'
+'<div class="wg-help">Чётный корень из отрицательного числа не существует. Из 0 и положительных — существует всегда.</div>'
+'<div class="score-display"><span>Задача <b id="p13-iv1-i">1</b> / 6</span><span>Очки: <b id="p13-iv1-s">0</b> / 6</span></div>'
+'<div id="p13-iv1-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.1rem;text-align:center;margin-bottom:10px"></div>'
+'<div style="display:flex;gap:8px;justify-content:center"><button class="btn primary" id="p13-iv1-y" style="background:#10b981;border-color:#10b981">Существует</button><button class="btn primary" id="p13-iv1-n" style="background:#dc2626;border-color:#dc2626">Не существует</button></div>'
+'<div class="feedback" id="p13-iv1-fb"></div></div>';
/* === ИНТЕРАКТИВ 2: Вычисли === */
html += '<div class="wg" id="p13-iv2">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Найди значение корня</div></div>'
+'<div class="wg-help">Подбирай: какое число в $n$-й степени даст подкоренное?</div>'
+trainerHTML('p13-iv2', 8, 'число')
+'</div>';
/* === ИНТЕРАКТИВ 3: число корней уравнения === */
html += '<div class="wg" id="p13-iv3">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Сколько корней у $x^n = a$?</div></div>'
+'<div class="wg-help">Чётное n: 2 / 1 / 0 (зависит от знака a). Нечётное n: всегда 1.</div>'
+trainerHTML('p13-iv3', 6, 'число корней')
+'</div>';
/* === БОСС === */
html += '<h3 style="font-family:Unbounded,sans-serif;font-size:1.05rem;color:var(--pri2);margin:20px 0 12px">Босс §13 — Определение корня</h3>';
html += makeBoss('p13', {
color:'#7c3aed',
title:'Босс §13 — Определение корня',
steps:[
{ q:'Существует ли $\\sqrt[4]{-81}$? «да» или «нет»', verify:(v)=>String(v).trim().toLowerCase().startsWith('н'), hint:'Чётное n, отрицательное a — не существует.' },
{ q:'Чему равен $\\sqrt[3]{-27}$?', verify:(v)=>+v===-3, hint:'$(-3)^3 = -27$.' },
{ q:'$\\sqrt[5]{32} = ?$', verify:(v)=>+v===2, hint:'$2^5 = 32$.' },
{ q:'Сколько корней у $x^4 = 16$?', verify:(v)=>+v===2, hint:'$x = \\pm 2$.' },
{ q:'Сколько корней у $x^7 = -128$?', verify:(v)=>+v===1, hint:'Нечётное n — всегда 1 корень.' },
]
});
html += secNav(null, 'p14') + readButton('p13');
box.innerHTML = html; renderMath(box);
/* IV1 */
(function(){
const Q=[
{ e:'$\\sqrt[4]{16}$', ok:true, why:'$2^4 = 16$.' },
{ e:'$\\sqrt[4]{-16}$', ok:false, why:'Чётное n, отриц. a — нет.' },
{ e:'$\\sqrt[3]{-27}$', ok:true, why:'$(-3)^3 = -27$.' },
{ e:'$\\sqrt[6]{0}$', ok:true, why:'$0^6 = 0$.' },
{ e:'$\\sqrt[8]{-1}$', ok:false, why:'Чётное n, отриц. a — нет.' },
{ e:'$\\sqrt[5]{-1}$', ok:true, why:'$(-1)^5 = -1$.' },
];
let i=0,score=0;
function show(){
if(i>=Q.length){ document.getElementById('p13-iv1-q').innerHTML='<b>Готово!</b> '+score+' / '+Q.length; if(score===Q.length){addXp(15,'p13-iv1');bumpProgress('p13',25);} else if(score>=4){addXp(8,'p13-iv1');bumpProgress('p13',12);} return; }
document.getElementById('p13-iv1-i').textContent=(i+1);
document.getElementById('p13-iv1-s').textContent=score;
document.getElementById('p13-iv1-q').innerHTML=Q[i].e;
renderMath(document.getElementById('p13-iv1-q'));
document.getElementById('p13-iv1-fb').style.display='none';
}
function ans(yes){
if(i>=Q.length) return;
const fb=document.getElementById('p13-iv1-fb');
if(yes===Q[i].ok){ score++; feedback(fb,true,'&#10003; Верно! '+Q[i].why); }
else feedback(fb,false,'&#10007; '+(Q[i].ok?'Существует: ':'Не существует: ')+Q[i].why);
document.getElementById('p13-iv1-s').textContent=score;
i++; setTimeout(show,1400);
}
document.getElementById('p13-iv1-y').addEventListener('click',()=>ans(true));
document.getElementById('p13-iv1-n').addEventListener('click',()=>ans(false));
show();
})();
/* IV2 */
makeTrainer({
idPrefix:'p13-iv2',
questions:[
{ q:'$\\sqrt[3]{64} = ?$', a:4 },
{ q:'$\\sqrt[4]{81} = ?$', a:3 },
{ q:'$\\sqrt[5]{32} = ?$', a:2 },
{ q:'$\\sqrt[3]{-125} = ?$', a:-5 },
{ q:'$\\sqrt[6]{1} = ?$', a:1 },
{ q:'$\\sqrt[4]{10000} = ?$', a:10 },
{ q:'$\\sqrt[5]{-1} = ?$', a:-1 },
{ q:'$\\sqrt[3]{0{,}008} = ?$', a:0.2 },
],
onComplete:(s,n)=>{ if(s===n){addXp(18,'p13-iv2');bumpProgress('p13',28);} else if(s>=5){addXp(9,'p13-iv2');bumpProgress('p13',14);} }
});
/* IV3 */
makeTrainer({
idPrefix:'p13-iv3',
questions:[
{ q:'$x^4 = 16$. Сколько корней?', a:2 },
{ q:'$x^3 = 27$. Сколько корней?', a:1 },
{ q:'$x^6 = -64$. Сколько корней?', a:0 },
{ q:'$x^5 = -32$. Сколько корней?', a:1 },
{ q:'$x^8 = 0$. Сколько корней?', a:1 },
{ q:'$x^{10} = 1$. Сколько корней?', a:2 },
],
onComplete:(s,n)=>{ if(s===n){addXp(15,'p13-iv3');bumpProgress('p13',25);} else if(s>=4){addXp(8,'p13-iv3');bumpProgress('p13',12);} }
});
wireReadBtn('p13');
}
/* ============================================================
§ 14 — Свойства корней n-й степени
============================================================ */
function buildP14(){
const box = document.getElementById('p14-body');
let html = '';
const plateProps = '<div class="formula-plate">'
+ '<div class="formula-plate-head">'
+ '<div class="formula-plate-title">5 основных свойств</div>'
+ '<div class="formula-plate-sub">все формулы — для неотрицательных подкоренных выражений</div>'
+ '</div>'
+ '<div class="formula-plate-body">'
+ '<div class="formula-row">$\\sqrt[n]{a \\cdot b} = \\sqrt[n]{a} \\cdot \\sqrt[n]{b}$</div>'
+ '<div class="formula-row alt">$\\sqrt[n]{\\dfrac{a}{b}} = \\dfrac{\\sqrt[n]{a}}{\\sqrt[n]{b}}$</div>'
+ '<div class="formula-row">$\\sqrt[n]{a^m} = \\left(\\sqrt[n]{a}\\right)^m$</div>'
+ '<div class="formula-row alt">$\\sqrt[nk]{a^{mk}} = \\sqrt[n]{a^m}$ &nbsp;&nbsp; (сокращение)</div>'
+ '<div class="formula-row">$\\sqrt[k]{\\sqrt[n]{a}} = \\sqrt[kn]{a}$ &nbsp;&nbsp; (корень из корня)</div>'
+ '</div>'
+ '</div>';
html += makeCard('rule', 'Основные свойства корней', '14.1', `
${plateProps}
<p>Эти свойства <b>можно применять в обе стороны</b> — для упрощения и для разложения.</p>`);
html += makeCard('rule', 'Корень из степени и модуль', '14.2', `
<p style="background:var(--warn-bg);padding:10px 14px;border-radius:8px;border-left:4px solid var(--warn)"><b>Важно!</b> Для произвольного $a$ (может быть отрицательным):</p>
<p style="text-align:center;font-size:1.15rem;margin:10px 0">$\\sqrt[n]{a^n} = \\begin{cases} |a|, & n \\text{ чётное} \\\\ a, & n \\text{ нечётное} \\end{cases}$</p>
<p>Например:</p>
<ul style="padding-left:22px;line-height:1.85">
<li>$\\sqrt{(-5)^2} = \\sqrt{25} = 5 = |-5|$;</li>
<li>$\\sqrt[3]{(-5)^3} = \\sqrt[3]{-125} = -5$.</li>
</ul>
<p>Чётный корень «выпрямляет» знак, нечётный — сохраняет.</p>`);
html += makeCard('example', 'Применение свойств', '14.3', `
<p><b>Пример 1.</b> $\\sqrt[3]{8 \\cdot 27} = \\sqrt[3]{8} \\cdot \\sqrt[3]{27} = 2 \\cdot 3 = 6$.</p>
<p><b>Пример 2.</b> $\\sqrt[4]{\\dfrac{16}{81}} = \\dfrac{\\sqrt[4]{16}}{\\sqrt[4]{81}} = \\dfrac{2}{3}$.</p>
<p><b>Пример 3.</b> $\\sqrt[6]{a^4} = \\sqrt[3]{a^2}$ (разделили оба показателя на 2).</p>
<p><b>Пример 4.</b> $\\sqrt[3]{\\sqrt{64}} = \\sqrt[6]{64} = 2$.</p>`);
/* === ИНТЕРАКТИВ 1 === */
html += '<div class="wg" id="p14-iv1">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Вычисли через свойства</div></div>'
+'<div class="wg-help">Раскладывай подкоренное на множители — степени с нужным показателем дают целое число.</div>'
+trainerHTML('p14-iv1', 8, 'число')
+'</div>';
/* === ИНТЕРАКТИВ 2 === */
html += '<div class="wg" id="p14-iv2">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">$\\sqrt[n]{a^n}$ с модулем</div></div>'
+'<div class="wg-help">Чётный корень даёт модуль, нечётный сохраняет знак.</div>'
+trainerHTML('p14-iv2', 6, 'число')
+'</div>';
/* === БОСС === */
html += '<h3 style="font-family:Unbounded,sans-serif;font-size:1.05rem;color:var(--pri2);margin:20px 0 12px">Босс §14 — Свойства корней</h3>';
html += makeBoss('p14', {
color:'#a855f7',
title:'Босс §14 — Свойства корней',
steps:[
{ q:'$\\sqrt[3]{8 \\cdot 125} = ?$', verify:(v)=>+v===10, hint:'$\\sqrt[3]{8} \\cdot \\sqrt[3]{125} = 2 \\cdot 5$.' },
{ q:'$\\sqrt[4]{\\dfrac{16}{81}} = ?$ Введи как 2/3.', verify:(v)=>{const s=String(v).replace(/\\s/g,''); return s==='2/3'||Math.abs(+v - 2/3)<0.01;}, hint:'$\\sqrt[4]{16}/\\sqrt[4]{81} = 2/3$.' },
{ q:'$\\sqrt[6]{a^6}$ при $a = -3$ = ?', verify:(v)=>+v===3, hint:'Чётный корень даёт $|a| = 3$.' },
{ q:'$\\sqrt[5]{a^5}$ при $a = -7$ = ?', verify:(v)=>+v===-7, hint:'Нечётный корень сохраняет знак.' },
{ q:'$\\sqrt{\\sqrt[3]{64}} = ?$', verify:(v)=>+v===2, hint:'$\\sqrt[6]{64} = 2$.' },
]
});
html += secNav('p13', 'p15') + readButton('p14');
box.innerHTML = html; renderMath(box);
/* IV1 */
makeTrainer({
idPrefix:'p14-iv1',
questions:[
{ q:'$\\sqrt[3]{27 \\cdot 64} = ?$', a:12 },
{ q:'$\\sqrt[4]{16 \\cdot 81} = ?$', a:6 },
{ q:'$\\sqrt[3]{\\dfrac{125}{8}} = ?$ Введи как 5/2 или 2.5.', a:(v)=>{const s=String(v).replace(/\\s/g,''); return s==='5/2'||+v===2.5;}, show:'$5/2$' },
{ q:'$\\sqrt[5]{32 \\cdot 1024} = ?$', a:4 },
{ q:'$\\sqrt[4]{2401} = ?$ ($2401 = 7^4$)', a:7 },
{ q:'$\\sqrt{\\sqrt{16}} = ?$', a:2 },
{ q:'$\\sqrt[3]{2} \\cdot \\sqrt[3]{4} = ?$', a:2 },
{ q:'$\\dfrac{\\sqrt[4]{162}}{\\sqrt[4]{2}} = ?$ ($162/2 = 81$)', a:3 },
],
onComplete:(s,n)=>{ if(s===n){addXp(20,'p14-iv1');bumpProgress('p14',32);} else if(s>=5){addXp(10,'p14-iv1');bumpProgress('p14',15);} }
});
/* IV2 */
makeTrainer({
idPrefix:'p14-iv2',
questions:[
{ q:'$\\sqrt{(-7)^2} = ?$', a:7 },
{ q:'$\\sqrt[3]{(-7)^3} = ?$', a:-7 },
{ q:'$\\sqrt[4]{(-2)^4} = ?$', a:2 },
{ q:'$\\sqrt[5]{(-3)^5} = ?$', a:-3 },
{ q:'$\\sqrt[6]{(-1)^6} = ?$', a:1 },
{ q:'$\\sqrt[7]{(-10)^7} = ?$', a:-10 },
],
onComplete:(s,n)=>{ if(s===n){addXp(15,'p14-iv2');bumpProgress('p14',25);} else if(s>=4){addXp(8,'p14-iv2');bumpProgress('p14',12);} }
});
wireReadBtn('p14');
}
/* ============================================================
§ 15 — Применение свойств для преобразований
============================================================ */
function buildP15(){
const box = document.getElementById('p15-body');
let html = '';
html += makeCard('algo', 'Вынесение множителя за знак корня', '15.1', `
<p><b>Идея:</b> разложи подкоренное на множители так, чтобы один из них был степенью с показателем, равным показателю корня.</p>
<p style="background:var(--sec-acc-soft);padding:10px 14px;border-radius:8px"><b>Пример.</b> $\\sqrt[5]{160}$.</p>
<p>$160 = 32 \\cdot 5 = 2^5 \\cdot 5$. Тогда $\\sqrt[5]{160} = \\sqrt[5]{2^5 \\cdot 5} = 2\\sqrt[5]{5}$.</p>
<p><b>Алгоритм (4 шага):</b></p>
<ol style="padding-left:22px;line-height:1.9">
<li>Разложи подкоренное на множители.</li>
<li>Найди множитель, который является степенью с показателем $n$.</li>
<li>Вынеси корень $n$-й степени из этого множителя.</li>
<li>Запиши: коэффициент перед корнем + оставшийся корень.</li>
</ol>`);
html += makeCard('algo', 'Внесение множителя под знак корня', '15.2', `
<p>Обратное действие. Чтобы внести положительный множитель $a$ под корень $n$-й степени, представь его как $\\sqrt[n]{a^n}$.</p>
<p style="background:var(--sec-acc-soft);padding:10px 14px;border-radius:8px"><b>Пример.</b> $2\\sqrt[3]{7} = \\sqrt[3]{2^3} \\cdot \\sqrt[3]{7} = \\sqrt[3]{8 \\cdot 7} = \\sqrt[3]{56}$.</p>
<p><b>Внимание:</b> если $a < 0$ и $n$ чётное, то $a \\cdot \\sqrt[n]{b} = -\\sqrt[n]{a^n b}$ (знак минус остаётся снаружи).</p>`);
html += makeCard('algo', 'Избавление от иррациональности в знаменателе', '15.3', `
<p>Дробь вида $\\dfrac{c}{\\sqrt[n]{a}}$ можно «рационализировать» — превратить в дробь без корня в знаменателе.</p>
<p style="background:var(--sec-acc-soft);padding:10px 14px;border-radius:8px"><b>Правило:</b> умножь числитель и знаменатель на $\\sqrt[n]{a^{n-1}}$. Тогда в знаменателе будет $\\sqrt[n]{a^n} = a$.</p>
<p><b>Пример 1.</b> $\\dfrac{3}{\\sqrt{2}} = \\dfrac{3 \\cdot \\sqrt{2}}{\\sqrt{2} \\cdot \\sqrt{2}} = \\dfrac{3\\sqrt{2}}{2}$.</p>
<p><b>Пример 2.</b> $\\dfrac{1}{\\sqrt[3]{4}} = \\dfrac{\\sqrt[3]{16}}{\\sqrt[3]{4 \\cdot 16}} = \\dfrac{\\sqrt[3]{16}}{\\sqrt[3]{64}} = \\dfrac{\\sqrt[3]{16}}{4}$.</p>
<details class="spoiler"><summary>Случай разности корней</summary>
<div class="spoiler-body">
<p>Для дроби $\\dfrac{c}{\\sqrt{a} - \\sqrt{b}}$ умножь на <b>сопряжённое</b> $\\sqrt{a} + \\sqrt{b}$:</p>
<p>$\\dfrac{c}{\\sqrt{a} - \\sqrt{b}} = \\dfrac{c(\\sqrt{a} + \\sqrt{b})}{(\\sqrt{a})^2 - (\\sqrt{b})^2} = \\dfrac{c(\\sqrt{a} + \\sqrt{b})}{a - b}$.</p>
</div></details>`);
html += makeCard('example', 'Сравнение значений корней', '15.4', `
<p>Чтобы сравнить $\\sqrt[n]{a}$ и $\\sqrt[m]{b}$, приведи их к <b>общему показателю</b> (НОК от $n$ и $m$).</p>
<p><b>Пример.</b> Сравни $\\sqrt[3]{5}$ и $\\sqrt[4]{10}$.</p>
<p>Общий показатель: $\\text{НОК}(3, 4) = 12$.</p>
<p>$\\sqrt[3]{5} = \\sqrt[12]{5^4} = \\sqrt[12]{625}$.</p>
<p>$\\sqrt[4]{10} = \\sqrt[12]{10^3} = \\sqrt[12]{1000}$.</p>
<p>$625 < 1000$, значит $\\sqrt[3]{5} < \\sqrt[4]{10}$.</p>`);
/* === ИНТЕРАКТИВ 1: Вынеси === */
html += '<div class="wg" id="p15-iv1">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Вынеси множитель</div></div>'
+'<div class="wg-help">Ответ в виде «k root» — целое k перед оставшимся корнем. Например, $2\\sqrt[5]{5}$ → введи 2.</div>'
+trainerHTML('p15-iv1', 6, 'коэф. k')
+'</div>';
/* === ИНТЕРАКТИВ 2: Внеси === */
html += '<div class="wg" id="p15-iv2">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Внеси множитель</div></div>'
+'<div class="wg-help">Возведи коэффициент в степень показателя корня и умножь на подкоренное.</div>'
+trainerHTML('p15-iv2', 5, 'число под корнем')
+'</div>';
/* === ИНТЕРАКТИВ 3: Рационализация === */
html += '<div class="wg" id="p15-iv3">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Избавься от иррациональности</div></div>'
+'<div class="wg-help">Умножь на нужный множитель так, чтобы в знаменателе осталось целое число.</div>'
+trainerHTML('p15-iv3', 5, 'знаменатель')
+'</div>';
/* === БОСС === */
html += '<h3 style="font-family:Unbounded,sans-serif;font-size:1.05rem;color:var(--pri2);margin:20px 0 12px">Босс §15 — Преобразования</h3>';
html += makeBoss('p15', {
color:'#c026d3',
title:'Босс §15 — Преобразования',
steps:[
{ q:'Вынеси: $\\sqrt[3]{54} = k\\sqrt[3]{2}$. Введи k.', verify:(v)=>+v===3, hint:'$54 = 27 \\cdot 2 = 3^3 \\cdot 2$.' },
{ q:'Внеси: $3\\sqrt[4]{5}$. Чему равно подкоренное?', verify:(v)=>+v===405, hint:'$3^4 \\cdot 5 = 81 \\cdot 5 = 405$.' },
{ q:'$\\dfrac{6}{\\sqrt{3}}$ после рационализации = $a\\sqrt{3}$. Введи a.', verify:(v)=>+v===2, hint:'$\\frac{6\\sqrt{3}}{3} = 2\\sqrt{3}$.' },
{ q:'Что больше: $\\sqrt[3]{5}$ или $\\sqrt{3}$? Введи: 1 (если первое) или 2.', verify:(v)=>+v===1, hint:'$\\sqrt[3]{5} = \\sqrt[6]{25}$, $\\sqrt{3} = \\sqrt[6]{27}$. Нет, тогда второе. Хм, проверим: $\\sqrt[6]{25} < \\sqrt[6]{27}$, значит $\\sqrt[3]{5} < \\sqrt{3}$. Ответ 2.', a:2 },
{ q:'$\\dfrac{1}{\\sqrt[3]{9}}$ после рационализации = $\\dfrac{\\sqrt[3]{?}}{3}$. Введи подкоренное.', verify:(v)=>+v===3, hint:'Умножь на $\\sqrt[3]{3}$ в числителе и знаменателе: $\\frac{\\sqrt[3]{3}}{\\sqrt[3]{27}} = \\frac{\\sqrt[3]{3}}{3}$.' },
]
});
html += secNav('p14', 'p16') + readButton('p15');
box.innerHTML = html; renderMath(box);
/* IV1 */
makeTrainer({
idPrefix:'p15-iv1',
questions:[
{ q:'$\\sqrt[3]{16} = k\\sqrt[3]{2}$. Введи k.', a:2, show:'$2$ ($16 = 2^3 \\cdot 2$)' },
{ q:'$\\sqrt[4]{48} = k\\sqrt[4]{3}$. Введи k.', a:2, show:'$2$ ($48 = 16 \\cdot 3$)' },
{ q:'$\\sqrt[5]{96} = k\\sqrt[5]{3}$. Введи k.', a:2, show:'$2$ ($96 = 32 \\cdot 3$)' },
{ q:'$\\sqrt{72} = k\\sqrt{2}$. Введи k.', a:6, show:'$6$ ($72 = 36 \\cdot 2$)' },
{ q:'$\\sqrt[3]{250} = k\\sqrt[3]{2}$. Введи k.', a:5, show:'$5$ ($250 = 125 \\cdot 2$)' },
{ q:'$\\sqrt[4]{162} = k\\sqrt[4]{2}$. Введи k.', a:3, show:'$3$ ($162 = 81 \\cdot 2$)' },
],
onComplete:(s,n)=>{ if(s===n){addXp(18,'p15-iv1');bumpProgress('p15',30);} else if(s>=4){addXp(9,'p15-iv1');bumpProgress('p15',14);} }
});
/* IV2 */
makeTrainer({
idPrefix:'p15-iv2',
questions:[
{ q:'$2\\sqrt[3]{7} = \\sqrt[3]{?}$', a:56 },
{ q:'$3\\sqrt{2} = \\sqrt{?}$', a:18 },
{ q:'$2\\sqrt[5]{3} = \\sqrt[5]{?}$', a:96 },
{ q:'$5\\sqrt[3]{2} = \\sqrt[3]{?}$', a:250 },
{ q:'$4\\sqrt{3} = \\sqrt{?}$', a:48 },
],
onComplete:(s,n)=>{ if(s===n){addXp(15,'p15-iv2');bumpProgress('p15',25);} else if(s>=3){addXp(8,'p15-iv2');bumpProgress('p15',12);} }
});
/* IV3 */
makeTrainer({
idPrefix:'p15-iv3',
questions:[
{ q:'$\\dfrac{1}{\\sqrt{5}}$ → $\\dfrac{\\sqrt{5}}{?}$. Введи знаменатель.', a:5 },
{ q:'$\\dfrac{2}{\\sqrt{3}}$ → $\\dfrac{2\\sqrt{3}}{?}$.', a:3 },
{ q:'$\\dfrac{3}{\\sqrt{2}}$ → $\\dfrac{3\\sqrt{2}}{?}$.', a:2 },
{ q:'$\\dfrac{1}{\\sqrt[3]{4}}$ → $\\dfrac{\\sqrt[3]{2}}{?}$.', a:2, show:'$2$ ($\\sqrt[3]{4} \\cdot \\sqrt[3]{2} = \\sqrt[3]{8} = 2$)' },
{ q:'$\\dfrac{1}{\\sqrt{7}+\\sqrt{5}}$ → $\\dfrac{\\sqrt{7}-\\sqrt{5}}{?}$.', a:2, show:'$2$ ($(\\sqrt{7})^2 - (\\sqrt{5})^2 = 2$)' },
],
onComplete:(s,n)=>{ if(s===n){addXp(15,'p15-iv3');bumpProgress('p15',25);} else if(s>=3){addXp(8,'p15-iv3');bumpProgress('p15',12);} }
});
wireReadBtn('p15');
}
/* ============================================================
§ 16 — Функция y = ⁿ√x. Свойства и график
============================================================ */
function buildP16(){
const box = document.getElementById('p16-body');
const A = window.ALG10;
let html = '';
/* === SVG: графики ⁿ√x для разных n === */
let svgEven = '', svgOdd = '';
if(A){
/* Графики для чётных n: ²√x, ⁴√x, ⁶√x (только x≥0) */
const f1 = A.func.canvas({id:'p16-ev', W:300, H:260, xRange:[-0.5, 4], yRange:[-0.5, 2.5], bg:'#fff'});
let s1 = f1.open
+ '<rect x="0" y="0" width="'+f1.W+'" height="36" fill="rgba(124,58,237,.08)"/>'
+ '<text x="'+(f1.W/2)+'" y="22" text-anchor="middle" font-size="12" font-family="Unbounded,Inter,sans-serif" font-weight="800" fill="#6d28d9">y = ⁿ√x, n чётное</text>'
+ f1.grid({xStep:1, yStep:0.5, color:'#f1f5f9'})
+ f1.axes({color:'#475569', xTicks:[{val:1,label:'1'},{val:2,label:'2'},{val:3,label:'3'}], yTicks:[{val:1,label:'1'},{val:2,label:'2'}]})
+ f1.plot(x => x>=0 ? Math.sqrt(x) : NaN, {color:'#0d9488', width:2.5})
+ f1.plot(x => x>=0 ? Math.pow(x, 1/4) : NaN, {color:'#7c3aed', width:2.5})
+ f1.plot(x => x>=0 ? Math.pow(x, 1/6) : NaN, {color:'#dc2626', width:2.2, dash:'4 3'})
/* Легенда */
+ '<rect x="195" y="195" width="98" height="56" rx="6" fill="rgba(255,255,255,.92)" stroke="#cbd5e1"/>'
+ '<line x1="202" y1="210" x2="222" y2="210" stroke="#0d9488" stroke-width="2.5"/>'
+ '<text x="226" y="214" font-size="11" font-family="JetBrains Mono,monospace" fill="#0d9488" font-weight="700">²√x</text>'
+ '<line x1="202" y1="226" x2="222" y2="226" stroke="#7c3aed" stroke-width="2.5"/>'
+ '<text x="226" y="230" font-size="11" font-family="JetBrains Mono,monospace" fill="#7c3aed" font-weight="700">⁴√x</text>'
+ '<line x1="202" y1="242" x2="222" y2="242" stroke="#dc2626" stroke-width="2.2" stroke-dasharray="4 3"/>'
+ '<text x="226" y="246" font-size="11" font-family="JetBrains Mono,monospace" fill="#dc2626" font-weight="700">⁶√x</text>'
+ f1.close;
svgEven = s1;
/* Графики для нечётных n: ³√x, ⁵√x, ⁷√x (вся ось) */
const f2 = A.func.canvas({id:'p16-od', W:300, H:260, xRange:[-3, 3], yRange:[-2, 2], bg:'#fff'});
function odd(x, n){ return x>=0 ? Math.pow(x, 1/n) : -Math.pow(-x, 1/n); }
let s2 = f2.open
+ '<rect x="0" y="0" width="'+f2.W+'" height="36" fill="rgba(168,85,247,.08)"/>'
+ '<text x="'+(f2.W/2)+'" y="22" text-anchor="middle" font-size="12" font-family="Unbounded,Inter,sans-serif" font-weight="800" fill="#9333ea">y = ⁿ√x, n нечётное</text>'
+ f2.grid({xStep:1, yStep:0.5, color:'#f1f5f9'})
+ f2.axes({color:'#475569', xTicks:[{val:-2,label:'-2'},{val:-1,label:'-1'},{val:1,label:'1'},{val:2,label:'2'}], yTicks:[{val:-1,label:'-1'},{val:1,label:'1'}]})
+ f2.plot(x => odd(x, 3), {color:'#0d9488', width:2.5})
+ f2.plot(x => odd(x, 5), {color:'#7c3aed', width:2.5})
+ f2.plot(x => odd(x, 7), {color:'#dc2626', width:2.2, dash:'4 3'})
+ '<rect x="195" y="50" width="98" height="56" rx="6" fill="rgba(255,255,255,.92)" stroke="#cbd5e1"/>'
+ '<line x1="202" y1="65" x2="222" y2="65" stroke="#0d9488" stroke-width="2.5"/>'
+ '<text x="226" y="69" font-size="11" font-family="JetBrains Mono,monospace" fill="#0d9488" font-weight="700">³√x</text>'
+ '<line x1="202" y1="81" x2="222" y2="81" stroke="#7c3aed" stroke-width="2.5"/>'
+ '<text x="226" y="85" font-size="11" font-family="JetBrains Mono,monospace" fill="#7c3aed" font-weight="700">⁵√x</text>'
+ '<line x1="202" y1="97" x2="222" y2="97" stroke="#dc2626" stroke-width="2.2" stroke-dasharray="4 3"/>'
+ '<text x="226" y="101" font-size="11" font-family="JetBrains Mono,monospace" fill="#dc2626" font-weight="700">⁷√x</text>'
+ f2.close;
svgOdd = s2;
}
html += makeCard('rule', 'Свойства функции y = ⁿ√x', '16.1', `
<p>Функция $y = \\sqrt[n]{x}$ — это <b>обратная</b> к $y = x^n$ (на подходящей области). Её свойства зависят от чётности $n$.</p>
<table style="width:100%;border-collapse:collapse;margin:8px 0;font-size:.9rem">
<tr style="background:var(--sec-acc-soft)"><th style="padding:6px;border:1px solid var(--border)">Свойство</th><th style="padding:6px;border:1px solid var(--border)">$n$ чётное</th><th style="padding:6px;border:1px solid var(--border)">$n$ нечётное</th></tr>
<tr><td style="padding:6px;border:1px solid var(--border)"><b>$D$</b></td><td style="padding:6px;border:1px solid var(--border);text-align:center">$[0;\\,+\\infty)$</td><td style="padding:6px;border:1px solid var(--border);text-align:center">$\\mathbb{R}$</td></tr>
<tr><td style="padding:6px;border:1px solid var(--border)"><b>$E$</b></td><td style="padding:6px;border:1px solid var(--border);text-align:center">$[0;\\,+\\infty)$</td><td style="padding:6px;border:1px solid var(--border);text-align:center">$\\mathbb{R}$</td></tr>
<tr><td style="padding:6px;border:1px solid var(--border)"><b>Монотонность</b></td><td style="padding:6px;border:1px solid var(--border);text-align:center">возрастает</td><td style="padding:6px;border:1px solid var(--border);text-align:center">возрастает</td></tr>
<tr><td style="padding:6px;border:1px solid var(--border)"><b>Чётность</b></td><td style="padding:6px;border:1px solid var(--border);text-align:center">— (только $x \\ge 0$)</td><td style="padding:6px;border:1px solid var(--border);text-align:center">нечётная</td></tr>
<tr><td style="padding:6px;border:1px solid var(--border)"><b>Нули</b></td><td style="padding:6px;border:1px solid var(--border);text-align:center">$x = 0$</td><td style="padding:6px;border:1px solid var(--border);text-align:center">$x = 0$</td></tr>
</table>`);
html += makeCard('rule', 'Графики для чётных и нечётных n', '16.2', `
<p>Чётные корни существуют только при $x \\ge 0$ — графики живут в правой полуплоскости:</p>
<div class="svg-host">${svgEven}</div>
<p>Нечётные корни определены для всех $x$ — графики симметричны относительно начала координат:</p>
<div class="svg-host">${svgOdd}</div>
<p><b>Закономерности:</b></p>
<ul style="padding-left:22px;line-height:1.85">
<li>Чем <b>больше $n$</b>, тем «положе» график при больших $x$ (всё ближе к 1 на интервале $[0; 1]$).</li>
<li>Все графики проходят через точки $(0; 0)$ и $(1; 1)$.</li>
<li>Для нечётных $n$ также проходят через $(-1; -1)$.</li>
</ul>`);
html += makeCard('example', 'Сравнение значений', '16.3', `
<p>Так как $y = \\sqrt[n]{x}$ возрастает на своей области, для сравнения корней одного показателя достаточно сравнить подкоренные выражения.</p>
<p>$\\sqrt[5]{8} < \\sqrt[5]{15}$, потому что $8 < 15$.</p>
<p>Для разных показателей — приводи к общему (через свойства из §14).</p>`);
/* === ИНТЕРАКТИВ 1 === */
html += '<div class="wg" id="p16-iv1">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Сравни корни</div></div>'
+'<div class="wg-help">Введи знак: <b>&lt;</b>, <b>&gt;</b> или <b>=</b>.</div>'
+trainerHTML('p16-iv1', 6, 'знак')
+'</div>';
/* === ИНТЕРАКТИВ 2 === */
html += '<div class="wg" id="p16-iv2">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Свойства y = ⁿ√x</div></div>'
+'<div class="wg-help">Используй таблицу свойств.</div>'
+trainerHTML('p16-iv2', 5, 'ответ')
+'</div>';
/* === БОСС === */
html += '<h3 style="font-family:Unbounded,sans-serif;font-size:1.05rem;color:var(--pri2);margin:20px 0 12px">Босс §16 — Функция ⁿ√x</h3>';
html += makeBoss('p16', {
color:'#8b5cf6',
title:'Босс §16 — Функция ⁿ√x',
steps:[
{ q:'Какая область определения $y = \\sqrt[4]{x}$? Введи минимум допустимого $x$.', verify:(v)=>+v===0, hint:'$D = [0; +\\infty)$, минимум $= 0$.' },
{ q:'$y = \\sqrt[3]{x}$ — чётная или нечётная? Введи слово.', verify:(v)=>String(v).trim().toLowerCase().startsWith('нечёт')||String(v).trim().toLowerCase().startsWith('нечет'), hint:'$\\sqrt[3]{-x} = -\\sqrt[3]{x}$.' },
{ q:'Сравни $\\sqrt[3]{10}$ и $\\sqrt[3]{7}$. Введи 1 (если первое больше) или 2.', verify:(v)=>+v===1, hint:'Корень возрастает: $10 > 7$.' },
{ q:'Через какую точку проходят ВСЕ графики $y = \\sqrt[n]{x}$ при $x = 1$? Введи $y$.', verify:(v)=>+v===1, hint:'$\\sqrt[n]{1} = 1$ для любого $n$.' },
{ q:'Функция $y = \\sqrt[6]{x}$ возрастает или убывает? Введи слово.', verify:(v)=>String(v).trim().toLowerCase().startsWith('возр'), hint:'Все ⁿ√x — возрастают на своей области.' },
]
});
html += secNav('p15', 'p17') + readButton('p16');
box.innerHTML = html; renderMath(box);
/* IV1 */
makeTrainer({
idPrefix:'p16-iv1',
parser:(v)=>v,
questions:[
{ q:'$\\sqrt[3]{8}$ и $\\sqrt[3]{27}$', a:(v)=>String(v).trim().startsWith('<'), show:'$<$' },
{ q:'$\\sqrt[5]{32}$ и $\\sqrt[5]{16}$', a:(v)=>String(v).trim().startsWith('>'), show:'$>$' },
{ q:'$\\sqrt[4]{16}$ и $\\sqrt[4]{16}$', a:(v)=>String(v).trim().startsWith('='), show:'$=$' },
{ q:'$\\sqrt{4}$ и $\\sqrt[3]{8}$ (оба равны 2)', a:(v)=>String(v).trim().startsWith('='), show:'$=$' },
{ q:'$\\sqrt[3]{2}$ и $\\sqrt{2}$ (общий показатель 6: $\\sqrt[6]{4}$ vs $\\sqrt[6]{8}$)', a:(v)=>String(v).trim().startsWith('<'), show:'$<$' },
{ q:'$\\sqrt[5]{-32}$ и $0$', a:(v)=>String(v).trim().startsWith('<'), show:'$<$' },
],
onComplete:(s,n)=>{ if(s===n){addXp(15,'p16-iv1');bumpProgress('p16',25);} else if(s>=4){addXp(8,'p16-iv1');bumpProgress('p16',12);} }
});
/* IV2 */
makeTrainer({
idPrefix:'p16-iv2',
parser:(v)=>v,
questions:[
{ q:'Сколько точек пересечения с осью $x$ у $y = \\sqrt[3]{x}$?', a:(v)=>+v===1, show:'1 (точка $0$)' },
{ q:'Сколько у $y = \\sqrt[4]{x}$?', a:(v)=>+v===1, show:'1 (точка $0$)' },
{ q:'Чему равно $\\sqrt[n]{1}$ для любого $n$?', a:(v)=>+v===1, show:'$1$' },
{ q:'$y = \\sqrt[3]{x}$ — какая область значений? Введи: «R» или конкретное число.', a:(v)=>{const s=String(v).trim().toLowerCase(); return s==='r'||s===''||s==='все';}, show:'$\\mathbb{R}$' },
{ q:'$y = \\sqrt[6]{x}$ — какая область определения? Введи минимум.', a:(v)=>+v===0, show:'$0$ ($D = [0;+\\infty)$)' },
],
onComplete:(s,n)=>{ if(s===n){addXp(15,'p16-iv2');bumpProgress('p16',25);} else if(s>=3){addXp(8,'p16-iv2');bumpProgress('p16',12);} }
});
wireReadBtn('p16');
}
/* ============================================================
§ 17 — Иррациональные уравнения
============================================================ */
function buildP17(){
const box = document.getElementById('p17-body');
let html = '';
html += makeCard('theory', 'Что такое иррациональное уравнение', '17.1', `
<p><b>Иррациональным</b> называется уравнение, в котором переменная находится <b>под знаком корня</b>.</p>
<p>Примеры:</p>
<ul style="padding-left:22px;line-height:1.85">
<li>$\\sqrt{x + 3} = 5$;</li>
<li>$\\sqrt[3]{2x - 1} = 2$;</li>
<li>$\\sqrt{x} + \\sqrt{x + 7} = 7$;</li>
<li>$\\sqrt{x - 1} - 2 = x$.</li>
</ul>`);
html += makeCard('algo', 'Метод возведения в степень', '17.2', `
<p style="background:var(--sec-acc-soft);padding:10px 14px;border-radius:8px"><b>Идея:</b> чтобы «избавиться» от корня $n$-й степени, возведи обе части в $n$-ю степень.</p>
<p><b>Алгоритм:</b></p>
<ol style="padding-left:22px;line-height:1.9">
<li><b>Уединить корень</b> в левой части (если нужно).</li>
<li><b>Возвести</b> обе части в $n$-ю степень.</li>
<li>Решить получившееся уравнение.</li>
<li><b>Обязательно проверить</b> корни подстановкой в исходное уравнение.</li>
</ol>
<p style="background:var(--warn-bg);padding:10px 14px;border-radius:8px;border-left:4px solid var(--warn)"><b>Почему проверка обязательна?</b> При возведении в чётную степень могут появиться <b>посторонние корни</b> — числа, удовлетворяющие уравнению после возведения, но <b>не</b> удовлетворяющие исходному.</p>`);
html += makeCard('example', 'Пример с проверкой', '17.3', `
<p><b>Уравнение.</b> $\\sqrt{x + 3} = 5$.</p>
<p><b>Решение.</b></p>
<ol style="padding-left:22px;line-height:1.9">
<li>Возводим в квадрат: $x + 3 = 25$.</li>
<li>$x = 22$.</li>
<li>Проверка: $\\sqrt{22 + 3} = \\sqrt{25} = 5$ &#10003;.</li>
</ol>
<p><b>Уравнение с подвохом.</b> $\\sqrt{x - 1} = x - 7$.</p>
<p>Возводим в квадрат: $x - 1 = (x - 7)^2 = x^2 - 14x + 49$.</p>
<p>$x^2 - 15x + 50 = 0$. Корни: $x_1 = 5, x_2 = 10$.</p>
<p><b>Проверка:</b></p>
<ul style="padding-left:22px;line-height:1.85">
<li>$x = 5$: $\\sqrt{4} = 5 - 7 = -2$. Но $\\sqrt{4} = 2 \\ne -2$. <b>Посторонний!</b></li>
<li>$x = 10$: $\\sqrt{9} = 10 - 7 = 3$. &#10003;</li>
</ul>
<p>Ответ: $x = 10$.</p>`);
html += makeCard('rule', 'Эквивалентность для $\\sqrt{f} = g$', '17.4', `
<p>Можно сразу записать <b>эквивалентную</b> систему:</p>
<p style="text-align:center;font-size:1.1rem;margin:10px 0">$\\sqrt{f(x)} = g(x) \\Leftrightarrow \\begin{cases} f(x) = g^2(x), \\\\ g(x) \\ge 0. \\end{cases}$</p>
<p>Условие $g(x) \\ge 0$ автоматически отсекает посторонние корни — и проверять подстановкой не нужно.</p>`);
html += makeCard('algo', 'Метод замены переменной', '17.5', `
<p>Если в уравнении встречается одно и то же корневое выражение, удобно ввести замену.</p>
<p><b>Пример.</b> $\\sqrt{x} + 6 = 5\\sqrt[4]{x}$.</p>
<p>Заметим: $\\sqrt{x} = (\\sqrt[4]{x})^2$. Пусть $t = \\sqrt[4]{x}$ ($t \\ge 0$). Тогда $t^2 + 6 = 5t$ ⇒ $t^2 - 5t + 6 = 0$ ⇒ $t = 2$ или $t = 3$.</p>
<p>Возвращаемся: $\\sqrt[4]{x} = 2$ ⇒ $x = 16$. $\\sqrt[4]{x} = 3$ ⇒ $x = 81$.</p>`);
/* === ИНТЕРАКТИВ 1: Простейшие === */
html += '<div class="wg" id="p17-iv1">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Реши простейшее уравнение</div></div>'
+'<div class="wg-help">Возведи в нужную степень, реши, проверь корни.</div>'
+trainerHTML('p17-iv1', 6, 'корень или число корней')
+'</div>';
/* === ИНТЕРАКТИВ 2: посторонние корни === */
html += '<div class="wg" id="p17-iv2">'
+'<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Сколько <b>истинных</b> корней?</div></div>'
+'<div class="wg-help">После возведения в степень может появиться больше корней. Подставь каждый и оставь только настоящие.</div>'
+trainerHTML('p17-iv2', 5, 'число корней')
+'</div>';
/* === БОСС === */
html += '<h3 style="font-family:Unbounded,sans-serif;font-size:1.05rem;color:var(--pri2);margin:20px 0 12px">Босс §17 — Иррациональные уравнения</h3>';
html += makeBoss('p17', {
color:'#6d28d9',
title:'Босс §17 — Иррац. уравнения',
steps:[
{ q:'Реши $\\sqrt{x - 5} = 3$. Введи $x$.', verify:(v)=>+v===14, hint:'Возведи в квадрат: $x - 5 = 9$.' },
{ q:'Реши $\\sqrt[3]{2x + 1} = 3$. Введи $x$.', verify:(v)=>+v===13, hint:'$2x + 1 = 27$, $x = 13$.' },
{ q:'Сколько <b>истинных</b> корней у $\\sqrt{x + 4} = x - 2$?', verify:(v)=>+v===1, hint:'$x + 4 = (x-2)^2 \\Rightarrow x^2 - 5x = 0 \\Rightarrow x = 0$ или $5$. Но $x \\ge 2$ для $g \\ge 0$. Только $x = 5$.' },
{ q:'Какое условие добавить к $\\sqrt{f(x)} = g(x)$ при возведении в квадрат? «g ≥ 0» или «g > 0»?', verify:(v)=>{const s=String(v).replace(/\\s/g,''); return s==='g≥0'||s==='g>=0'||s.toLowerCase().startsWith('g≥');}, hint:'Левая часть $\\sqrt{f} \\ge 0$, значит правая тоже.' },
{ q:'Реши $\\sqrt{x^2 - 5} = 2$. Введи положительный корень.', verify:(v)=>+v===3, hint:'$x^2 - 5 = 4$, $x^2 = 9$, $x = \\pm 3$. Положительный — 3.' },
{ q:'Заменой решаем $\\sqrt{x} - 5\\sqrt[4]{x} + 6 = 0$. Сколько корней?', verify:(v)=>+v===2, hint:'$t = \\sqrt[4]{x}$: $t^2 - 5t + 6 = 0$, $t = 2$ или $3$. $x = 16$ или $81$. Оба годятся.' },
]
});
html += secNav('p16', 'final2') + readButton('p17');
box.innerHTML = html; renderMath(box);
/* IV1 */
makeTrainer({
idPrefix:'p17-iv1',
questions:[
{ q:'$\\sqrt{x} = 4$. Корень $x = ?$', a:16 },
{ q:'$\\sqrt{x + 2} = 5$. Корень $x = ?$', a:23 },
{ q:'$\\sqrt[3]{x - 1} = 2$. Корень $x = ?$', a:9 },
{ q:'$\\sqrt{2x + 3} = 3$. Корень $x = ?$', a:3 },
{ q:'$\\sqrt{x^2} = 5$. Сколько <b>корней</b>?', a:2, show:'2 ($\\pm 5$)' },
{ q:'$\\sqrt{x - 1} = -3$. Сколько корней?', a:0, show:'0 (правая часть отрицательна, а $\\sqrt{} \\ge 0$)' },
],
onComplete:(s,n)=>{ if(s===n){addXp(18,'p17-iv1');bumpProgress('p17',30);} else if(s>=4){addXp(9,'p17-iv1');bumpProgress('p17',14);} }
});
/* IV2 */
makeTrainer({
idPrefix:'p17-iv2',
questions:[
{ q:'$\\sqrt{x + 2} = x$. Сколько истинных?', a:1, show:'1 ($x = 2$; $x = -1$ — посторонний)' },
{ q:'$\\sqrt{2x + 7} = x + 2$. Сколько?', a:1, show:'1 ($x = 3$; $x = -1$ даёт $\\sqrt{5} \\ne 1$)' },
{ q:'$\\sqrt{x - 3} = x - 5$. Сколько?', a:1, show:'1 ($x = 7$; $x = 4$ даёт $1 \\ne -1$)' },
{ q:'$\\sqrt{x^2 + 8} = x + 2$. Сколько?', a:1, show:'1 ($x = 1$; $x \\ge -2$ для $g \\ge 0$)' },
{ q:'$\\sqrt{x - 1} = 1 - x$. Сколько?', a:1, show:'1 ($x = 1$; единств. где обе части = 0)' },
],
onComplete:(s,n)=>{ if(s===n){addXp(18,'p17-iv2');bumpProgress('p17',30);} else if(s>=3){addXp(9,'p17-iv2');bumpProgress('p17',14);} }
});
wireReadBtn('p17');
}
/* ============================================================
ФИНАЛ ГЛАВЫ 2 — 4 интегрированных босса
============================================================ */
const FINAL2_BOSSES = [
{
n:1, tag:'§ 1314',
title:'Определение + свойства',
color:'#7c3aed',
steps:[
{ q:'Существует ли $\\sqrt[6]{-64}$? «да»/«нет»', verify:(v)=>String(v).trim().toLowerCase().startsWith('н'), hint:'Чётное n, отриц. a.' },
{ q:'$\\sqrt[3]{-216} = ?$', verify:(v)=>+v===-6, hint:'$(-6)^3 = -216$.' },
{ q:'$\\sqrt[4]{16 \\cdot 81} = ?$', verify:(v)=>+v===6, hint:'$\\sqrt[4]{16} \\cdot \\sqrt[4]{81} = 2 \\cdot 3$.' },
{ q:'$\\sqrt[8]{(-5)^8} = ?$', verify:(v)=>+v===5, hint:'Чётный корень → $|{-5}| = 5$.' },
{ q:'Сколько корней у $x^6 = 64$?', verify:(v)=>+v===2, hint:'$\\pm \\sqrt[6]{64} = \\pm 2$.' },
]
},
{
n:2, tag:'§ 15',
title:'Преобразования корней',
color:'#c026d3',
steps:[
{ q:'Вынеси: $\\sqrt[3]{40} = k\\sqrt[3]{5}$. Введи k.', verify:(v)=>+v===2, hint:'$40 = 8 \\cdot 5 = 2^3 \\cdot 5$.' },
{ q:'Внеси: $3\\sqrt[5]{2} = \\sqrt[5]{?}$', verify:(v)=>+v===486, hint:'$3^5 \\cdot 2 = 243 \\cdot 2 = 486$.' },
{ q:'$\\dfrac{4}{\\sqrt{2}}$ после рационализации = $a\\sqrt{2}$. Введи a.', verify:(v)=>+v===2, hint:'$\\frac{4\\sqrt{2}}{2} = 2\\sqrt{2}$.' },
{ q:'Сравни $\\sqrt[3]{4}$ и $\\sqrt{2}$. Введи 1 (если первое больше) или 2.', verify:(v)=>+v===1, hint:'$\\sqrt[3]{4} = \\sqrt[6]{16}$, $\\sqrt{2} = \\sqrt[6]{8}$. $16 > 8$.' },
{ q:'$(\\sqrt[3]{5})^6 = ?$', verify:(v)=>+v===25, hint:'$(\\sqrt[3]{5})^6 = 5^{6/3} = 5^2$.' },
]
},
{
n:3, tag:'§ 16',
title:'Функция y = ⁿ√x',
color:'#8b5cf6',
steps:[
{ q:'Область определения $y = \\sqrt[4]{x}$? Введи мин. допуст. $x$.', verify:(v)=>+v===0, hint:'$[0; +\\infty)$.' },
{ q:'$y = \\sqrt[5]{x}$ — чётная или нечётная?', verify:(v)=>String(v).trim().toLowerCase().startsWith('нечёт')||String(v).trim().toLowerCase().startsWith('нечет'), hint:'Нечётная.' },
{ q:'Все ⁿ√x возрастают или убывают?', verify:(v)=>String(v).trim().toLowerCase().startsWith('возр'), hint:'Возрастают.' },
{ q:'$\\sqrt[7]{0} = ?$', verify:(v)=>+v===0, hint:'$0^7 = 0$.' },
{ q:'Через какую точку $(1; y)$ проходят ВСЕ графики $y = \\sqrt[n]{x}$? Введи $y$.', verify:(v)=>+v===1, hint:'$\\sqrt[n]{1} = 1$.' },
]
},
{
n:4, tag:'§ 17 + синтез',
title:'Иррациональные уравнения + синтез',
color:'#6d28d9',
steps:[
{ q:'Реши $\\sqrt{2x - 1} = 5$. Введи $x$.', verify:(v)=>+v===13, hint:'$2x - 1 = 25$.' },
{ q:'Реши $\\sqrt[3]{x + 5} = -2$. Введи $x$.', verify:(v)=>+v===-13, hint:'$x + 5 = -8$.' },
{ q:'Сколько истинных корней у $\\sqrt{x + 6} = x$?', verify:(v)=>+v===1, hint:'$x + 6 = x^2 \\Rightarrow x = 3$ или $-2$. Но $x \\ge 0$ для $g \\ge 0$. Только $x = 3$.' },
{ q:'Реши заменой $t = \\sqrt{x}$ уравнение $x - 5\\sqrt{x} + 6 = 0$. Сколько корней?', verify:(v)=>+v===2, hint:'$t^2 - 5t + 6 = 0$, $t = 2$ или $3$. $x = 4$ или $9$.' },
{ q:'Чему равно $\\sqrt[3]{27} + \\sqrt[4]{16} - \\sqrt[5]{32}$?', verify:(v)=>+v===3, hint:'$3 + 2 - 2 = 3$.' },
]
},
];
function buildFinal2(){
const box = document.getElementById('final2-body');
let html = '';
/* === Hero card === */
html += '<div style="background:linear-gradient(135deg,#7c3aed,#c4b5fd);color:#fff;border-radius:18px;padding:24px 22px;margin-bottom:24px;box-shadow:0 8px 28px rgba(124,58,237,.25);position:relative;overflow:hidden">'
+'<div style="position:absolute;right:-20px;top:-30px;font-size:8rem;font-weight:900;color:rgba(255,255,255,.1);font-family:Unbounded,sans-serif;line-height:1;pointer-events:none">&#9733;</div>'
+'<div style="position:relative;z-index:1">'
+'<div style="font-size:.78rem;font-weight:800;letter-spacing:.1em;text-transform:uppercase;opacity:.85;margin-bottom:6px">ФИНАЛ ГЛАВЫ 2</div>'
+'<h2 style="font-family:Unbounded,sans-serif;font-size:1.55rem;font-weight:800;margin-bottom:8px">4 интегрированных босса</h2>'
+'<p style="font-size:.95rem;opacity:.92;margin-bottom:14px;max-width:580px">Каждый босс проверяет синтез знаний главы. Победи всех — получи ачивку <b>«Магистр корней»</b> и +100 XP.</p>'
+'<div style="display:flex;gap:12px;flex-wrap:wrap;align-items:center">'
+'<div style="padding:8px 14px;background:rgba(255,255,255,.18);border-radius:99px;font-size:.82rem;font-weight:700">&#9733; 4 босса</div>'
+'<div style="padding:8px 14px;background:rgba(255,255,255,.18);border-radius:99px;font-size:.82rem;font-weight:700">+ до 200 XP</div>'
+'<div style="padding:8px 14px;background:rgba(255,255,255,.18);border-radius:99px;font-size:.82rem;font-weight:700">&#9733; Финальная ачивка</div>'
+'</div></div></div>';
/* === Overall progress === */
html += '<div style="background:var(--card);border:1.5px solid var(--border);border-radius:14px;padding:16px 20px;margin-bottom:20px">'
+'<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px">'
+'<div style="font-family:Unbounded,sans-serif;font-size:.85rem;font-weight:800;color:var(--text);letter-spacing:.06em;text-transform:uppercase">Прогресс по боссам</div>'
+'<div id="final2-overall" style="font-size:.95rem;font-weight:700;color:var(--pri2)">0 / 4 побеждено</div>'
+'</div>'
+'<div style="height:12px;background:rgba(124,58,237,.12);border-radius:8px;overflow:hidden">'
+'<div id="final2-overall-fill" style="height:100%;width:0%;background:linear-gradient(90deg,#7c3aed,#c4b5fd);transition:width .6s cubic-bezier(.16,1,.3,1)"></div>'
+'</div></div>';
html += '<div id="final2-bosses"></div>';
/* === Celebration === */
html += '<div id="final2-cel" style="display:none;margin:24px 0;padding:24px 22px;background:linear-gradient(135deg,#fef3c7,#fde68a);border:2px solid #f59e0b;border-radius:18px;text-align:center;box-shadow:0 6px 22px rgba(245,158,11,.25)">'
+'<div style="font-size:3rem;margin-bottom:6px">&#9733;</div>'
+'<div style="font-family:Unbounded,sans-serif;font-size:1.4rem;font-weight:900;color:#92400e;margin-bottom:6px">МАГИСТР КОРНЕЙ!</div>'
+'<div style="font-size:.95rem;color:#78350f;margin-bottom:14px">Ты победил всех 4 боссов главы 2 и освоил корни n-й степени.<br>Получено: <b>+100 XP</b> и финальная ачивка.</div>'
+'<a href="/textbook/algebra-10" style="display:inline-flex;align-items:center;gap:8px;padding:11px 22px;background:linear-gradient(135deg,#7c3aed,#a855f7);color:#fff;border-radius:11px;font-weight:700;text-decoration:none">Вернуться к Алгебре 10 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" style="width:16px;height:16px"><polyline points="9 18 15 12 9 6"/></svg></a>'
+'</div>';
html += secNav('p17', null) + readButton('final2');
box.innerHTML = html; renderMath(box);
/* === State === */
const SKEY = 'algebra10_ch2_final2_state';
let state = {};
try{ const s=localStorage.getItem(SKEY); if(s) state = JSON.parse(s); }catch(e){}
FINAL2_BOSSES.forEach(b => { if(!state['b'+b.n]) state['b'+b.n] = {stage:0, defeated:false}; });
function save(){ try{ localStorage.setItem(SKEY, JSON.stringify(state)); }catch(e){} }
function refreshOverall(){
let won = 0;
FINAL2_BOSSES.forEach(b => { if(state['b'+b.n].defeated) won++; });
document.getElementById('final2-overall').textContent = won + ' / 4 побеждено';
document.getElementById('final2-overall-fill').style.width = (won*100/4) + '%';
if(won >= 4){
document.getElementById('final2-cel').style.display = 'block';
if(STATE.progress.final2 < 100) bumpProgress('final2', 100);
if(!STATE.achievements.has('root_master')){
achievement('root_master');
addXp(100, 'root-master');
}
}
}
const cont = document.getElementById('final2-bosses');
cont.innerHTML = FINAL2_BOSSES.map(b => {
return '<div class="boss-card" id="bb-'+b.n+'-card" style="border-color:'+b.color+'">'
+'<div class="boss-head" style="flex-wrap:wrap">'
+'<svg viewBox="0 0 24 24" fill="none" stroke="'+b.color+'" stroke-width="2.2" style="width:28px;height:28px"><polygon points="12,2 22,20 2,20"/></svg>'
+'<div style="padding:3px 10px;background:'+b.color+'22;color:'+b.color+';border-radius:99px;font-family:Unbounded,sans-serif;font-size:.7rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase">'+b.tag+'</div>'
+'<div class="boss-title" style="color:'+b.color+';flex:1;min-width:0">Босс '+b.n+'. '+b.title+'</div>'
+'<div class="boss-stage" id="bb-'+b.n+'-stage">Этап 1 / '+b.steps.length+'</div>'
+'</div>'
+'<div class="hp-boss" style="border-color:'+b.color+'66;background:'+b.color+'1a"><div class="hp-boss-fill" id="bb-'+b.n+'-fill" style="width:0%;background:linear-gradient(90deg,'+b.color+',#f59e0b)"></div></div>'
+'<div class="boss-q" id="bb-'+b.n+'-q" style="border-color:'+b.color+'"></div>'
+'<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">'
+'<input type="text" id="bb-'+b.n+'-input" class="tinp" placeholder="Ответ" style="width:160px;text-align:center">'
+'<button class="btn primary" id="bb-'+b.n+'-go" style="background:'+b.color+';border-color:'+b.color+'">Атака</button>'
+'<button class="btn" id="bb-'+b.n+'-hint">Подсказка</button>'
+'<button class="btn" id="bb-'+b.n+'-restart">↻</button>'
+'</div>'
+'<div class="feedback" id="bb-'+b.n+'-fb"></div>'
+'</div>';
}).join('');
if(window.renderMathInElement) try{ renderMath(cont); }catch(e){}
FINAL2_BOSSES.forEach(b => {
const stKey = 'b' + b.n;
function show(){
const st = state[stKey];
const stageEl=document.getElementById('bb-'+b.n+'-stage');
const fill=document.getElementById('bb-'+b.n+'-fill');
const q=document.getElementById('bb-'+b.n+'-q');
const fb=document.getElementById('bb-'+b.n+'-fb');
if(st.defeated){
stageEl.textContent='&#10003; Побеждён';
fill.style.width='100%';
q.innerHTML='<b style="color:'+b.color+'">Босс повержен!</b>';
document.getElementById('bb-'+b.n+'-go').disabled=true;
document.getElementById('bb-'+b.n+'-go').style.opacity=.5;
return;
}
stageEl.textContent='Этап '+(st.stage+1)+' / '+b.steps.length;
fill.style.width=(st.stage*100/b.steps.length)+'%';
q.innerHTML=b.steps[st.stage].q;
document.getElementById('bb-'+b.n+'-input').value='';
fb.style.display='none';
renderMath(q);
}
document.getElementById('bb-'+b.n+'-go').addEventListener('click', ()=>{
const st = state[stKey];
if(st.defeated) return;
const step=b.steps[st.stage];
const val=document.getElementById('bb-'+b.n+'-input').value;
const fb=document.getElementById('bb-'+b.n+'-fb');
if(!val.trim()){ feedback(fb,false,'&#10007; Введи ответ.'); return; }
if(step.verify(val)){
st.stage++;
if(st.stage>=b.steps.length){
st.defeated=true; save();
feedback(fb,true,'&#10003; Босс '+b.n+' повержен! +25 XP');
addXp(25,'final2-b'+b.n);
refreshOverall();
setTimeout(show, 1400);
} else {
save();
feedback(fb,true,'&#10003; Верно! +5 XP');
addXp(5,'final2-b'+b.n+'-step');
setTimeout(show, 1100);
}
} else {
feedback(fb,false,'&#10007; Промах. Подумай ещё.');
}
});
document.getElementById('bb-'+b.n+'-hint').addEventListener('click', ()=>{
const st = state[stKey];
if(st.defeated) return;
const fb=document.getElementById('bb-'+b.n+'-fb');
fb.className='feedback ok';
fb.innerHTML='<span style="color:#92400e">\u{1F4A1} Подсказка:</span> '+b.steps[st.stage].hint;
fb.style.display='block';
fb.style.background='var(--warn-bg)'; fb.style.color='#92400e'; fb.style.borderLeftColor='var(--warn)';
renderMath(fb);
});
document.getElementById('bb-'+b.n+'-restart').addEventListener('click', ()=>{
state[stKey] = {stage:0, defeated:false}; save();
document.getElementById('bb-'+b.n+'-go').disabled=false;
document.getElementById('bb-'+b.n+'-go').style.opacity=1;
show(); refreshOverall();
});
show();
});
refreshOverall();
wireReadBtn('final2');
}
</script>
</body>
</html>