<!-- НАЧАЛО -->
<div class="project__container">
<!-- ТОР С ПЛИТКОЙ -->
<div class="project__top-container">
<div class="project__top-bg-spots" aria-hidden="true">
<span class="project__top-spot"></span>
<span class="project__top-spot"></span>
<span class="project__top-spot"></span>
<span class="project__top-spot"></span>
<span class="project__top-spot"></span>
<span class="project__top-spot"></span>
<span class="project__top-spot"></span>
<span class="project__top-spot"></span>
<span class="project__top-spot"></span>
<span class="project__top-spot"></span>
<span class="project__top-spot"></span>
<span class="project__top-spot"></span>
<span class="project__top-spot"></span>
</div>
<div class="project__top-container2">
<div class="project__top">
<div class="project__top-left">
<h1 class="project__top-header">
Симфония кардиоренальной защиты
</h1>
<h3 class="project__top-header3">
Экспертный проект о диагностике и современной стратегии ведения пациентов
с хронической болезнью почек, сахарным диабетом 2 типа
и сердечно-сосудистым риском.
</h3>
<a class="project__btn" href="#expert-videos">Смотреть экспертные материалы </a>
<!--<span style="margin-left:20px;" class="project__mob-d-none"></span>
<a class="project__btn"
href="/events/khrustalnoe-serdtse-210526/?tab=main&?utm_source=mcompas&utm_medium=organic&utm_campaign=crystal-heart-21-05-2026&utm_content=reg_button&utm_term=registration_header"
target="_blank" rel="noopener"> Перейти к клиническому маршруту </a>
-->
</div>
</div>
</div>
</div><!-- /ТОР С ПЛИТКОЙ -->
<div class="project__bottom-container">
<div class="project__bottom">
<!-- СТАТЬЯ 3 КОЛОНКИ С КАРТИНКАМИ -->
<div class="article__container4">
<div class="article__main-container4">
<blockquote class="article__quote">
<p>
«Сахарный диабет 2 типа (СД2) прочно удерживает статус одного из
самых
распространенных неинфекционных заболеванийв мире. Однако главная опасность
диабета
кроется в его осложнениях: поражение почек и сердечно-сосудистые
заболевания (ССЗ)
входят в топ причин заболеваемости и смертности у пациентов
с СД2.
</p>
<p>
При этом ХБП зачастую является самым ранним признаком сердечно-сосудистого
неблагополучия, а прогрессирующее снижение функции почек выступает
катализатором
продолжающегося сердечно-сосудистого ремоделирования, с последующим
развитием
ССЗ и декомпенсаций.
</p>
<p>
Понимание практикующим врачом любой специальности взаимосвязи
кардиоренометаболических (КРМ) заболеваний позволяет осуществлять раннее
выявление
сочетанных патологий, а также осуществлять первичную и вторичную
профилактику за счет назначения болезнь-модифицирующих препаратов, влияющих
на
ключевые
патофизиологические нарушения и КРМ-прогноз пациента».
</p>
</blockquote>
<div class="article__cols-scroll4">
<div class="article__cols-container4">
<div class="expert-card">
<img class="expert-card__photo"
src="/upload/medialibrary/701/23gxj6x597lc88kheqaygygiwnn36x3q/expert.webp"
alt="Шамхалова Минара Шамхаловна">
<div class="expert-card__info">
<div class="expert-card__name">
<b>Шамхалова Минара Шамхаловна, </b>
</div>
<div class="expert-card__regalia">
д.м.н., заведующая отделением диабетической болезни почек
и посттрансплантационной реабилитации ФГБУ «НМИЦ эндокринологии имени
академика И.И. Дедова» МЗ РФ
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /СТАТЬЯ 3 КОЛОНКИ С КАРТИНКАМИ -->
</div>
</div>
<!-- ГРАФИК1 -->
<div class="project__bottom-container">
<div class="project__bottom">
<div class="project__bubble">
<div class="project__bubble-header">
Актуальность
</div>
<div class="project__bubble-line">
</div>
</div>
<div class="article__container4">
<div class="article__main-container4">
<h2 class="project__plain-header">
Поражение почек и СС-системы входят в топ причин заболеваемости
и смертности у пациентов с СД2<sup><a class="project__ref-link"
href="#ref-1">1</a></sup>
</h2>
<p class="project__plain-text">
Данные федерального регистра сахарного диабета на 01.01.2026.
</p>
<section class="project__charts"
aria-label="Данные федерального регистра сахарного диабета на 01.01.2026">
<article class="project__chart-card">
<h3 class="project__chart-title">Распределение частот осложнений при СД2 (n=5
366 010)</h3>
<ul class="project__chart-list ">
<li
class="project__chart-row project__chart-list--blue project__chart-row--accent ">
<span class="project__chart-label">Диабетическая нефропатия, ХБП</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:23.1; --max:23.1;"></span>
<span class="project__chart-value">23,1%</span>
</div>
</li>
<li class="project__chart-row project__chart-list--blue">
<span class="project__chart-label">Диабетическая нейропатия</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:22.9; --max:23.1;"></span>
<span class="project__chart-value">22,9%</span>
</div>
</li>
<li class="project__chart-row project__chart-list--blue">
<span class="project__chart-label">Диабетическая ретинопатия</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:10.7; --max:23.1;"></span>
<span class="project__chart-value">10,7%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Ишемическая болезнь сердца
(стенокардия)</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:8.3; --max:23.1;"></span>
<span class="project__chart-value">8,3%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Атеросклероз</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:5.9; --max:23.1;"></span>
<span class="project__chart-value">5,9%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Цереброваскулярные заболевания (ОНМК,
инсульт)</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:4; --max:23.1;"></span>
<span class="project__chart-value">4,0%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Хроническая сердечная
недостаточность</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:3.8; --max:23.1;"></span>
<span class="project__chart-value">3,8%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Инфаркт миокарда</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:3.4; --max:23.1;"></span>
<span class="project__chart-value">3,4%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Диабетическая катаракта</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:2.7; --max:23.1;"></span>
<span class="project__chart-value">2,7%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Синдром диабетической стопы</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:1; --max:23.1;"></span>
<span class="project__chart-value">1,0%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Ампутация</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.8; --max:23.1;"></span>
<span class="project__chart-value">0,8%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Анемия</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.4; --max:23.1;"></span>
<span class="project__chart-value">0,4%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Наличие переломов</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.2; --max:23.1;"></span>
<span class="project__chart-value">0,3%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Диабетический кетоацидоз (без
комы)</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.3; --max:23.1;"></span>
<span class="project__chart-value">0,2%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Остеопороз</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.2; --max:23.1;"></span>
<span class="project__chart-value">0,2%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Хайропатия</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.1; --max:23.1;"></span>
<span class="project__chart-value">0,1%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Гиперпаратиреоз</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.1; --max:23.1;"></span>
<span class="project__chart-value">0,1%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Кома</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.04; --max:23.1;"></span>
<span class="project__chart-value">0,04%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Диабетический макулярный отек</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.01; --max:23.1;"></span>
<span class="project__chart-value">0,01%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Тяжелые гипогликемии</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.01; --max:23.1;"></span>
<span class="project__chart-value">0,01%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Задержка физического развития у
детей</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.01; --max:23.1;"></span>
<span class="project__chart-value">0,01%</span>
</div>
</li>
</ul>
</article>
<article class="project__chart-card">
<h3 class="project__chart-title">Структура смертности при СД2 (n=131 973)</h3>
<ul class="project__chart-list project__chart-list--red">
<li class="project__chart-row">
<span class="project__chart-label">ХСН</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:22.6; --max:22.6;"></span>
<span class="project__chart-value">22,6%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Онкология</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:13.1; --max:22.6;"></span>
<span class="project__chart-value">13,1%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Нарушение мозгового
кровообращения</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:12.3; --max:22.6;"></span>
<span class="project__chart-value">12,3%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Острые СС события</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:12; --max:22.6;"></span>
<span class="project__chart-value">12,0%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Причина смерти не установлена</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:8.2; --max:22.6;"></span>
<span class="project__chart-value">8,2%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Сахарный диабет</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:7.7; --max:22.6;"></span>
<span class="project__chart-value">7,7%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Старость и дегенеративные
заболевания</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:6; --max:22.6;"></span>
<span class="project__chart-value">6,0%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Инфаркт миокарда</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:4.2; --max:22.6;"></span>
<span class="project__chart-value">4,2%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Заболевания печени, поджелудочной
железы, органов ЖКТ</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:3.8; --max:22.6;"></span>
<span class="project__chart-value">3,8%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Заболевания легких, органов
дыхательной системы</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:3.7; --max:22.6;"></span>
<span class="project__chart-value">3,7%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">ХПН</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:2.4; --max:22.6;"></span>
<span class="project__chart-value">2,4%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Инфекции, сепсис</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:1.4; --max:22.6;"></span>
<span class="project__chart-value">1,4%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Травмы</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:1.1; --max:22.6;"></span>
<span class="project__chart-value">1,1%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Гангрена</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.6; --max:22.6;"></span>
<span class="project__chart-value">0,6%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Алкоголь, др. отравления</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.4; --max:22.6;"></span>
<span class="project__chart-value">0,4%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Суицид</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.2; --max:22.6;"></span>
<span class="project__chart-value">0,2%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Коронавирус/осложнения
коронавируса</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.1; --max:22.6;"></span>
<span class="project__chart-value">0,1%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Диабетическая кома</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0.1; --max:22.6;"></span>
<span class="project__chart-value">0,1%</span>
</div>
</li>
<li class="project__chart-row">
<span class="project__chart-label">Гипогликемическая кома</span>
<div class="project__chart-bar-wrap">
<span class="project__chart-bar"
style="--value:0; --max:22.6;"></span>
<span class="project__chart-value">0,0%</span>
</div>
</li>
</ul>
<p class="project__chart-callout">
<span class="project__chart-callout-value">51,1%</span>
<span class="project__chart-callout-text">доля СС причин в структуре
смертности</span>
</p>
</article>
</section>
<article class="project__therapy-card project__therapy-card--dark">
<img class="project__therapy-card-badge"
src="/upload/medialibrary/e7e/bskos988bhsxou37odsyauzynvwvd00n/bage.webp"
alt="" aria-hidden="true">
<h3 class="project__therapy-card-title">
Медицина может победить в битве за гликемический контроль,
но проигрывает в войне с диабетом<sup><a
class="project__ref-link" href="#ref-2">2</a></sup>
</h3>
<p class="project__therapy-card-text">
1. Дедов И.И. и соавт. Сахарный диабет. 2026;29(2):104–136.
<a class="project__charts-footnote-link" href="https://doi.org/10.14341/DM13485"
target="_blank" rel="noopener">doi: 10.14341/DM13485</a>
</p>
<p class="project__therapy-card-text">
2. K.M. Venkat Narayan; Type 2 Diabetes: Why We Are Winning the Battle but
Losing the War? 2015 Kelly West Award Lecture. Diabetes Care 1 May 2016,
39 (5): 653–663. <a class="project__charts-footnote-link"
href="https://doi.org/10.2337/dc16-0205" target="_blank"
rel="noopener">https://doi.org/10.2337/dc16-0205</a>
</p>
</article>
</div>
</div>
</div>
</div>
<!-- /ГРАФИК1 -->
<!-- ВИДЕО С ТАЙМКОДАМИ -->
<div class="video__container">
<div class="video__left" id="a-video">
<div class="video__main">
<div class="video-player" id="player"><img src="/img/player1.png" alt="" style="width: 80%; height: 100%; object-fit: cover;"></div><!--TIMECODE-->
</div>
<h2 class="video__main-header">
Механизм поражения почек и сердца у пациентов с ХБП и СД2 </h2>
</div>
</div>
<!-- /ВИДЕО С ТАЙМКОДАМИ -->
<!-- ГРАФИК2 -->
<div class="project__bottom-container">
<div class="project__bottom">
<div class="project__bubble">
<div class="project__bubble-header">
Прогрессирование ХБП
</div>
<div class="project__bubble-line">
</div>
</div>
<div class="article__container4">
<div class="article__main-container4">
<h2 class="project__plain-header">
Прогрессирующее ухудшение функции почек приводит к кратному возрастанию риска
смерти от сердечно-сосудистых катастроф<sup><a class="project__ref-link"
href="#ref-1">1</a>–<a class="project__ref-link" href="#ref-4">4</a></sup>
</h2>
<p class="project__plain-text">
Пациенты с сахарным диабетом 2 типа и хронической болезнью почек находятся
в зоне
перекрестного кардиоренального риска. Такие пациенты характеризуются высоким риском
дальнейшего прогрессирования ХБП, а также имеют высокий риск присоединения
и/или
усугубления различных сердечно-сосудистых заболеваний (АГ, ФП, ХСН, инфаркт
миокарда, инсульт и т.д.). <sup><a class="project__ref-link"
href="#ref-1">1</a>–<a class="project__ref-link" href="#ref-4">4</a></sup>
</p>
<p class="project__plain-text">
Поражение почек, сердечно-сосудистые осложнения и метаболические нарушения
формируют
взаимосвязанный патологический континуум, требующий раннего выявления
и междисциплинарного подхода.
</p>
<h3 class="project__plain-header3">
Что происходит с пациентом с ХБП?
</h3>
<p class="project__plain-text">
Прогрессирование ХБП характеризуется безвозвратной гибелью нефронов
и замещением их
на фиброзную ткань. Клинически это проявляется в виде снижения скорости
клубочковой
фильтрации с параллельным возрастанием риска СС катастроф. <sup><a class="project__ref-link"
href="#ref-10">10</a>–<a class="project__ref-link" href="#ref-12">12</a></sup>
</p>
<div class="renal-dropdown-row">
<p class="renal-dropdown-label">Выберите темп снижения рСКФ:</p>
<div class="renal-line-dropdown"><button type="button"
class="renal-dropdown-toggle"> <span class="dropdown-value">3</span> <svg
xmlns="http://www.w3.org/2000/svg" width="14" height="8"
viewBox="0 0 14 8" fill="none">
<path d="M0.75 0.75L6.75 6.75L12.75 0.75" stroke="white"
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
</path>
</svg> </button>
<div class="renal-dropdown-menu"><button type="button"
class="renal-dropdown-item" data-line="1">1</button> <button
type="button" class="renal-dropdown-item" data-line="2">2</button>
<button class="renal-dropdown-item active" data-line="3">3</button> <button
class="renal-dropdown-item" data-line="4">4</button> <button
class="renal-dropdown-item" data-line="5">5</button> <button
class="renal-dropdown-item" data-line="6">6</button> <button
class="renal-dropdown-item" data-line="7">7</button> <button
class="renal-dropdown-item" data-line="8">8</button> <button
class="renal-dropdown-item" data-line="9">9</button> <button
class="renal-dropdown-item" data-line="10">10</button>
</div>
</div>
<p class="renal-dropdown-label">мл/мин в год</p>
</div>
<div class="renal-chart-container"><svg class="renal-chart-svg" viewBox="0 0 950 510"
xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="gradientZoneHover" x1="100%" y1="0%" x2="0%" y2="0%">
<stop offset="0%" stop-color="#EA6852"></stop>
<stop offset="100%" stop-color="#E9C463"></stop>
</linearGradient>
</defs>
<path class="renal-axes" d="M 60 443 L 60 20 M 60 443 L 920 443" stroke="#FFF"
stroke-width="1"></path>
<g class="renal-grid-horizontal">
<line x1="60" y1="20" x2="590" y2="20" stroke="rgba(255, 255, 255, 0.30)"
stroke-width="1.5"></line>
<line x1="60" y1="62" x2="556" y2="62" stroke="rgba(255, 255, 255, 0.30)"
stroke-width="1.5"></line>
<line x1="60" y1="105" x2="543" y2="105" stroke="rgba(255, 255, 255, 0.30)"
stroke-width="1.5"></line>
<line x1="60" y1="147" x2="556" y2="147" stroke="rgba(255, 255, 255, 0.30)"
stroke-width="1.5"></line>
<line x1="60" y1="189" x2="468" y2="189" stroke="rgba(255, 255, 255, 0.30)"
stroke-width="1.5"></line>
<line x1="60" y1="232" x2="468" y2="232" stroke="rgba(255, 255, 255, 0.30)"
stroke-width="1.5"></line>
<line x1="60" y1="274" x2="468" y2="274" stroke="rgba(255, 255, 255, 0.30)"
stroke-width="1.5"></line>
<line x1="60" y1="316" x2="920" y2="316" stroke="rgba(255, 255, 255, 0.30)"
stroke-width="1.5"></line>
<line x1="60" y1="358" x2="920" y2="358" stroke="rgba(255, 255, 255, 0.30)"
stroke-width="1.5"></line>
</g>
<rect class="renal-gradient-zone" x="60" y="380" width="860" height="62"
fill="rgba(255, 255, 255, 0.20)"></rect>
<g class="renal-y-labels"> <text x="53" y="20" class="axis-label"
dominant-baseline="middle">100</text> <text x="53" y="62"
class="axis-label" dominant-baseline="middle">90</text> <text x="53"
y="105" class="axis-label" dominant-baseline="middle">80</text> <text
x="53" y="147" class="axis-label" dominant-baseline="middle">70</text>
<text x="53" y="189" class="axis-label" dominant-baseline="middle">60</text>
<text x="53" y="232" class="axis-label" dominant-baseline="middle">50</text>
<text x="53" y="274" class="axis-label" dominant-baseline="middle">40</text>
<text x="53" y="316" class="axis-label" dominant-baseline="middle">30</text>
<text x="53" y="358" class="axis-label" dominant-baseline="middle">20</text>
<text x="53" y="401" class="axis-label" dominant-baseline="middle">10</text>
<text x="53" y="443" class="axis-label" dominant-baseline="middle">0</text>
</g>
<g class="renal-x-labels"> <text x="60" y="457" class="axis-label"
text-anchor="middle">45</text> <text x="156" y="457" class="axis-label"
text-anchor="middle">50</text> <text x="251" y="457" class="axis-label"
text-anchor="middle">55</text> <text x="347" y="457" class="axis-label"
text-anchor="middle">60</text>
<text x="442" y="457" class="axis-label" text-anchor="middle">65</text>
<text x="538" y="457" class="axis-label" text-anchor="middle">70</text>
<text x="633" y="457" class="axis-label" text-anchor="middle">75</text>
<text x="729" y="457" class="axis-label" text-anchor="middle">80</text>
<text x="824" y="457" class="axis-label" text-anchor="middle">85</text>
<text x="920" y="457" class="axis-label" text-anchor="middle">90</text>
</g> <text x="3" y="220" class="axis-title axis-title-y"
transform="rotate(-90, 39, 240)">рСКФ,
мл/мин/1,73 м²</text> <text x="505" y="500"
class="axis-title axis-title-x">Возраст, лет</text>
<g class="renal-progression-lines"></g>
</svg>
<div class="renal-mobile-stages">
<div class="swiper renal-stages-swiper">
<div class="swiper-wrapper"></div>
</div>
<div class="renal-navigation"><button class="renal-nav-prev"> <svg
xmlns="http://www.w3.org/2000/svg" width="50" height="50"
viewBox="0 0 50 50" fill="none">
<rect class="btn-bg" x="-1" y="1" width="48" height="48" rx="24"
transform="matrix(-1 0 0 1 48 0)" fill="#EA6852"></rect>
<rect class="btn-stroke" x="-1" y="1" width="48" height="48" rx="24"
transform="matrix(-1 0 0 1 48 0)" stroke="#EA6852"
stroke-width="2"></rect>
<path class="btn-arrow" d="M29 13.5L17.5 25L29 36.5" stroke="white"
stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
</path>
</svg> </button> <button class="renal-nav-next"> <svg
xmlns="http://www.w3.org/2000/svg" width="50" height="50"
viewBox="0 0 50 50" fill="none">
<rect class="btn-bg" x="1" y="1" width="48" height="48" rx="24"
fill="#EA6852"></rect>
<rect class="btn-stroke" x="1" y="1" width="48" height="48" rx="24"
stroke="#EA6852" stroke-width="2"></rect>
<path class="btn-arrow" d="M21 13.5L32.5 25L21 36.5" stroke="white"
stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
</path>
</svg> </button></div>
</div>
</div>
<p class="project__plain-note">
График снижения рСКФ представлен в иллюстративных целях и соответствует
темпу
снижения рСКФ -3,5 мл/мин/1,73 м2 в год (темп снижения рСКФ может изменяться
с течением времени и/или в зависимости от проводимой терапии).<sup><a
class="project__ref-link" href="#ref-10">10</a>–<a class="project__ref-link"
href="#ref-12">12</a></sup>
</p>
</div>
</div>
</div>
</div>
<!-- /ГРАФИК2 -->
<!-- DISORDERS BLOCK PILLARS BLOCK -->
<div class="project__bottom-container">
<div class="project__bottom">
<div class="project__bubble">
<div class="project__bubble-header">
Комплексная защита
</div>
<div class="project__bubble-line">
</div>
</div>
<div class="article__container4">
<div class="article__main-container4">
<p class="project__plain-text project__plain-text2">
Если кардиоренальный риск формируется через несколько независимых
патофизиологических
путей,
терапевтическая стратегия также должна быть многокомпонентной. Комбинированный
подход
позволяет более полно воздействовать на ключевые механизмы прогрессирования ХБП
и сердечно-сосудистых осложнений.<sup><a class="project__ref-link"
href="#ref-11">11</a></sup>
</p>
<div class="project__disorders">
<div class="project__disorders-media">
<img class="project__disorders-img"
src="/upload/medialibrary/773/vcqxn6avrux5m08lcrbva1cdlsf326k7/pic3.webp"
alt="Схема патофизиологических нарушений при ХБП и СД2">
</div>
<div class="project__disorders-content">
<p class="project__disorders-title">
<strong>Три группы взаимосвязанных нарушений</strong>
лежат в основе поражения почек и сердца у пациентов
с ХБП и СД2 <sup><a class="project__ref-link"
href="#ref-11">11</a>, <a class="project__ref-link"
href="#ref-13">13</a></sup>
</p>
<div class="project__disorders-cards">
<div class="project__disorders-card">
<span class="project__disorders-card-badge" aria-hidden="true">1</span>
<p class="project__disorders-card-title">Воспаление и фиброз<br>
<span class="project__disorders-card-sub">вследствие гиперактивации
МКР</span>
</p>
</div>
<div class="project__disorders-card project__disorders-card--single">
<span class="project__disorders-card-badge" aria-hidden="true">2</span>
<p class="project__disorders-card-title">Гемодинамические нарушения</p>
</div>
<div class="project__disorders-card project__disorders-card--single">
<span class="project__disorders-card-badge" aria-hidden="true">3</span>
<p class="project__disorders-card-title">Метаболические нарушения</p>
</div>
</div>
</div>
</div>
<p class="project__disorders-title">
<strong>Три группы препаратов</strong> формируют <strong>независимые столпы
кардионефропротективной терапии</strong> пациентов с ХБП и СД2
<sup><a class="project__ref-link" href="#ref-14">14</a>–<a class="project__ref-link"
href="#ref-17">17</a></sup>
</p>
<div class="project__pillars">
<article
class="project__therapy-card project__therapy-card--dark project__pillars-card">
<img class="project__therapy-card-badge"
src="/upload/medialibrary/e7e/bskos988bhsxou37odsyauzynvwvd00n/bage.webp"
alt="" aria-hidden="true">
<h3 class="project__therapy-card-text2">
Каждый из столпов терапии должен быть назначен вместе с другими,
а не в качестве альтернативы при их неэффективности <sup><a
class="project__ref-link" href="#ref-14">14</a>, <a
class="project__ref-link" href="#ref-16">16</a>, <a
class="project__ref-link" href="#ref-17">17</a></sup>
</h3>
</article>
<div class="project__pillars-media">
<img class="project__pillars-img"
src="/upload/medialibrary/026/yv9s0bugv6fu4arh8xe36g6i0l2ss1x7/pic4.webp"
alt="Три столпа кардионефропротективной терапии при ХБП и СД2">
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /DISORDERS BLOCK PILLARS BLOCK -->
<div class="project__bottom-container" id="expert-videos">
<div class="project__bottom">
<div class="project__bubble">
<div class="project__bubble-header">
Видео от экспертов
</div>
<div class="project__bubble-line">
</div>
</div>
</div>
</div>
<!-- ЭКСПЕРТЫ - СЛАЙДЕР -->
<div class="project__bottom-container">
<div class="project__bottom">
<div class="slider-overflow">
<div class="slider-container">
<div class="slider-content">
<div class="slider-single">
<img src="/upload/medialibrary/2cf/x9lruht84az7093052ifl0ea5ezp9zgw/arytunov.webp"
class="slider-single-image" alt="Арутюнов">
<div class="slider-single-title slider-single-main">
<span class="slider-single-main-big">Арутюнов</span> Григорий Павлович
</div>
<div class="slider-single-title slider-single-text">
член-корреспондент РАН, д.м.н., профессор, заведующий кафедрой пропедевтики
внутренних болезней №1 ИКМ ФГАОУ ВО РНИМУ им. Н.И. Пирогова Минздрава
России, заслуженный врач РФ
</div>
</div>
<div class="slider-single">
<img src="/upload/medialibrary/b56/wgmlj9qsr6fc3toh2lwbagsh97vfypdx/artemov.webp"
class="slider-single-image" alt="Артёмов">
<div class="slider-single-title slider-single-main">
<span class="slider-single-main-big">Артёмов</span> Дмитрий Владимирович
</div>
<div class="slider-single-title slider-single-text">
к.м.н., врач-нефролог, доцент кафедры трансплантологии, нефрологии
и искусственных органов ФУВ ГБУЗ МО МОНИКИ им. М.Ф. Владимирского,
главный врач центров диализа ООО «Медикал Групп»
</div>
</div>
<div class="slider-single">
<img src="/upload/medialibrary/65f/9nottu5wcqijb9sbsqgjid70whsvw01v/zhirov.webp"
class="slider-single-image" alt="Жиров">
<div class="slider-single-title slider-single-main">
<span class="slider-single-main-big">Жиров</span> Игорь Витальевич
</div>
<div class="slider-single-title slider-single-text">
д.м.н., профессор кафедры кардиологии ФГБОУ ДПО РМАНПО Минздрава России,
в.н.с. отдела заболеваний миокарда и сердечной недостаточности ФГБУ
«НМИЦК им. ак. Е.И. Чазова» Минздрава России
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /ЭКСПЕРТЫ - СЛАЙДЕР -->
<!-- ПЛИТКА С ВИДЕО - ШАШЕЧНАЯ -->
<div class="project__bottom-container">
<div class="project__bottom">
<div class="project__cols3">
<div class="project__cols-block3">
<div class="project__cols-video">
<a target="_blank"
href="/archive/lektsii/kardiorenometabolicheskiy-patsient-ot-khaosa-faktorov-riska-k-garmonii-organoprotektsii-zhirov-artyemov_cut/">
<div class="project__cols-container3">
<!--<img class="project__cols-playbtn3"
src="/upload/medialibrary/0a0/k6w5t0dmbqj4tiyffw4y9ft43a5bv23i/play_button.svg"
alt="смотреть"> -->
<img class="project__cols-player3"
src="/upload/medialibrary/b9a/l8jikpsxkgoye9778vwwhts4le1hqm7q/vid1.webp"
alt="видео">
</div>
</a>
</div>
<div class="project__cols-text3">
<h2 class="project__cols-text3-header">
КАРДИОРЕНОМЕТАБОЛИЧЕСКИЙ ПАЦИЕНТ: ОТ ХАОСА ФАКТОРОВ РИСКА К ГАРМОНИИ
ОРГАНОПРОТЕКЦИИ
</h2>
<p class="project__cols-text3-text">
Рассмотрим проблему с позиции двух специальностей: нефрологии
и кардиологии, разберем клинические случаи и кейсы.
</p>
<p class="project__cols-text3-text">
АРТЁМОВ Д. В. | ЖИРОВ И. В.
</p>
</div>
</div>
</div>
<div class="project__cols3">
<div class="project__cols-block3 project__cols-block3-reverse">
<div class="project__cols-text3 project__cols-text3-reverse">
<h2 class="project__cols-text3-header">
МЕТАБОЛИЧЕСКИЙ СИНДРОМ И ХБП: ОТ ОПРОСА КАРДИОЛОГОВ К СОВМЕСТНОМУ
АЛГОРИТМУ ДЕЙСТВИЙ КАРДИОЛОГА И НЕФРОЛОГА
</h2>
<p class="project__cols-text3-text">
В клинике современных внутренних болезней активно обсуждается два вопроса:
метаболический синдром, новые подходы к его трактовке и пониманию
и хроническая
болезнь почек, распространенность которой растет с огромной скоростью.
Что это:
большая выявляемость или лучшие знания в этой области?
</p>
<p class="project__cols-text3-text">
АРТЁМОВ Д. В. | АРУТЮНОВ Г. П.
</p>
</div>
<div class="project__cols-video">
<a target="_blank"
href="/archive/lektsii/metabolicheskiy-sindrom-i-khbp-ot-oprosa-kardiologov-k-sovmestnomu-algoritmu-deystviy-kardiologa-i-nefrologa-arutyunov-artyemov_cut/">
<div class="project__cols-container3">
<!--<img class="project__cols-playbtn3"
src="/upload/medialibrary/0a0/k6w5t0dmbqj4tiyffw4y9ft43a5bv23i/play_button.svg"
alt="смотреть"> -->
<img class="project__cols-player3"
src="/upload/medialibrary/a94/9cp0kuow1hmqto9mbtwxbxe7if2csm0j/vid2.webp"
alt="видео">
</div>
</a>
</div>
</div>
</div>
</div>
</div>
<!-- /ПЛИТКА С ВИДЕО - ШАШЕЧНАЯ -->
<!-- ARTICLES BLOCK -->
<div class="project__bottom-container">
<div class="project__bottom">
<div class="project__bubble">
<div class="project__bubble-header">
Полезные материалы
</div>
<div class="project__bubble-line">
</div>
</div>
</div>
</div>
<div class="project__articles">
<div class="project__articles-anons-container">
<div class="project__articles-anons">
<div class="project__articles-grid">
<article class="project__articles-card">
<a class="project__articles-card-image-link" target="_blank" rel="noopener"
href="/upload/medialibrary/036/qrxluvy4nf7mhz035fwy42xq2rhbmqs8/pamyatka_hbp.pdf">
<img class="project__articles-card-image"
src="/upload/medialibrary/bde/iyuwkhjfm6yug53qwq4nyq6grgxp5mdf/doc1.webp"
alt="Памятка ХБП">
</a>
<!-- <a target="_blank"
class="project__articles-card-title project__articles-card-title-link"
href="/upload/medialibrary/036/qrxluvy4nf7mhz035fwy42xq2rhbmqs8/pamyatka_hbp.pdf">Дефицит
железа: метаболизм и регуляция</a>-->
<a target="_blank" class="project__articles-btn"
href="/upload/medialibrary/036/qrxluvy4nf7mhz035fwy42xq2rhbmqs8/pamyatka_hbp.pdf">Сохранить
памятку</a>
</article>
<article class="project__articles-card">
<a class="project__articles-card-image-link" target="_blank" rel="noopener"
href="https://cr.minzdrav.gov.ru/preview-cr/469_3">
<img class="project__articles-card-image"
src="/upload/medialibrary/ecd/4211u8l36v0holoo4a3hwb632aoc9yc1/doc2.webp"
alt="Клинические рекомендации ХБП">
</a>
<a target="_blank" class="project__articles-btn"
href="https://cr.minzdrav.gov.ru/preview-cr/469_3">Открыть
рекомендации</a>
</article>
</div>
</div>
</div>
</div>
<!-- /ARTICLES BLOCK -->
<div class="project__bottom-container">
<div class="project__bottom">
<div class="project__bubble">
<div class="project__bubble-header">
Список литературы
</div>
<div class="project__bubble-line">
</div>
</div>
</div>
</div>
<!-- СПИСОК ЛИТЕРАТУРЫ -->
<div class="project__references">
<div class="project__references-inner">
<ol class="project__references-list" id="references">
<li id="ref-1">Алгоритмы специализированной медицинской помощи больным сахарным диабетом.
Под ред. И.И.
Дедова, М.В. Шестаковой, О.Ю. Сухаревой. 12-й выпуск. М.; 2025.</li>
<li id="ref-2">Национальная Ассоциация нефрологов. Клинические рекомендации «Хроническая
болезнь почек
(ХБП)» — 2024.</li>
<li id="ref-3">Общественная организация «Российская ассоциация эндокринологов». Клинические
рекомендации «Сахарный диабет 2 типа у взрослых» — 2022.</li>
<li id="ref-4">Минздрав РФ. Клинические рекомендации «Артериальная гипертензия у взрослых» —
2024.</li>
<li id="ref-5">Салухов В.В., Шамхалова М.Ш., Дуганова А.В. Кардиоренальные эффекты
финеренона и его
место в терапии хронической болезни почек у пациентов с сахарным диабетом 2-го типа.
Терапевтический архив. 2023;95(3):261–273.</li>
<li id="ref-6">Бутранова О.И., Зырянов С.К. Качество жизни у пациентов с диабетом и
хронической
болезнью почек. Клиническая нефрология. 2024;1:67–74.</li>
<li id="ref-7">Шилов Е.М., Сигитова О.Н. Хроническая болезнь почек в практике врачей
первичного звена.
Терапия. 2023; 9(3): 106–112.</li>
<li id="ref-8">Шамхалова М.Ш., Сухарева О.Ю., Мартынов С.А. и соавт. Хроническая болезнь
почек у
пациентов с сахарным диабетом: новые вызовы. Сахарный диабет. 2025;28(1):46-55.</li>
<li id="ref-9">Устранение пробелов в лечении почек: воплощение того, что мы знаем, в то, что
мы делаем.
Перевод на русский язык Е.В. Паршиной под редакцией Е.В. Захаровой. Нефрология и диализ.
2024. 26(1):9-22.</li>
<li id="ref-10">Denic A., Mathew J., Lerman L. O. et al. Single-Nephron Glomerular
Filtration Rate in
Healthy Adults. N Engl J Med. 2017; 376(24): 2349–2357. Doi: 10.1056/NEJMoa1614329.</li>
<li id="ref-11">Халимов Ю. Ш., Полякова Е. А., Шутова Ю. А. Новая эра кардионефропротекции у
больных с
сахарным диабетом 2 типа: как использовать возможности терапии препаратом финеренон.
Сахарный диабет. 2024; 27(6): 620–628. Doi: https://doi.org/10.14341/DM13222.</li>
<li id="ref-12">Matsushita K et al. Nat Rev Nephrol. 2022;18:696–707. doi:
10.1038/s41581-022-00616-6.
</li>
<li id="ref-13">Трубицына Н.П., Зайцева Н.В., Северина А.С., Шамхалова М.Ш. Хроническая
болезнь почек у
пациентов с сахарным диабетом 2 типа: новые мишени лекарственного воздействия //
Сахарный диабет. — 2022. — Т. 25. — № 5. — С. 492-498. Doi:
https://doi.org/10.14341/DM12944.</li>
<li id="ref-14">American Diabetes Association. Diabetes Care 2024;47(Suppl 1).</li>
<li id="ref-15">Blazek O, Bakris GL. American Heart Journal Plus. 2022(19). doi:
10.1016/j.ahjo.2022.100187.</li>
<li id="ref-16">ElSayed NA et al. Summary of Revisions: Standards of Care in Diabetes-2023.
Diabetes
Care. 2023;46(Suppl 1):S5-S9. doi: 10.2337/dc23-Srev.</li>
<li id="ref-17">Мкртумян А.М. и соавт. Эффективная фармакотерапия. 2023;19(12):16–28.</li>
</ol>
<p class="project__references-legal">МАТЕРИАЛ ДЛЯ СПЕЦИАЛИСТОВ ЗДРАВООХРАНЕНИЯ<br>
АО «БАЙЕР», 107113, Россия, Москва, ул. 3-я Рыбинская, д. 18, стр. 2;<br>тел.: +7 (495) 234
20 00<br>Номер одобрения: COM-FIR-RUS-06.2026-11487-1</p>
</div>
</div>
<!-- /СПИСОК ЛИТЕРАТУРЫ -->
</div>
<button type="button" class="project__to-top" aria-label="Наверх" hidden>
<svg class="project__to-top-icon" width="18" height="18" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M8 3L3 9h10L8 3z" fill="currentColor" />
</svg>
</button>
<!-- КОНЕЦ -->
<script>
function runWhenDomReady(callback) {
const run = () => {
try {
callback();
} catch (error) {
console.error("[bayer-project]", error);
}
};
if (typeof window.BX !== "undefined" && typeof window.BX.ready === "function") {
window.BX.ready(run);
return;
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", run);
return;
}
run();
}
function getProjectRoot() {
return (
document.querySelector(".project__container") ||
document.querySelector("main") ||
document.body
);
}
/**
* В админке/на сайте Битрикс визуальный редактор и HTML-фильтры часто
* срезают target="_blank" при сохранении. Дублируем поведение в JS.
*/
function bindProjectExternalLinks() {
const root = getProjectRoot();
if (!root || root.dataset.bayerExternalLinksBound === "1") {
return;
}
root.dataset.bayerExternalLinksBound = "1";
const isExternalHref = (href) => /^https?:\/\//i.test(href) || href.startsWith("//");
root.querySelectorAll("a[href]").forEach((link) => {
const href = (link.getAttribute("href") || "").trim();
if (!isExternalHref(href)) {
return;
}
link.setAttribute("target", "_blank");
const relParts = new Set((link.getAttribute("rel") || "").split(/\s+/).filter(Boolean));
relParts.add("noopener");
relParts.add("noreferrer");
link.setAttribute("rel", [...relParts].join(" "));
});
}
function getScrollRoots(fromElement) {
const roots = new Set();
if (window) {
roots.add(window);
}
if (document.scrollingElement) {
roots.add(document.scrollingElement);
}
roots.add(document.documentElement);
roots.add(document.body);
let node = fromElement;
while (node && node !== document.documentElement) {
if (node.scrollHeight > node.clientHeight + 1) {
const overflowY = window.getComputedStyle(node).overflowY;
if (/(auto|scroll|overlay)/.test(overflowY)) {
roots.add(node);
}
}
node = node.parentElement;
}
return [...roots];
}
function getPageScrollTop(fromElement) {
let maxScroll = 0;
getScrollRoots(fromElement).forEach((root) => {
if (root === window) {
maxScroll = Math.max(
maxScroll,
window.pageYOffset || 0,
window.scrollY || 0,
document.documentElement.scrollTop || 0,
document.body.scrollTop || 0
);
return;
}
maxScroll = Math.max(maxScroll, root.scrollTop || 0);
});
return maxScroll;
}
function scrollPageToTop(fromElement, behavior = "smooth") {
const scrollOptions = { top: 0, left: 0, behavior };
getScrollRoots(fromElement).forEach((root) => {
if (root === window) {
try {
window.scrollTo(scrollOptions);
} catch {
window.scrollTo(0, 0);
}
return;
}
if (typeof root.scrollTo === "function") {
try {
root.scrollTo(scrollOptions);
} catch {
root.scrollTop = 0;
}
} else {
root.scrollTop = 0;
}
});
}
const renalChartRegistry = new WeakMap();
let renalDelegationBound = false;
let dynamicBootObserver = null;
let dynamicBootTimer = null;
function ensureToTopButton() {
let button = document.querySelector(".project__to-top");
if (button) {
return button;
}
button = document.createElement("button");
button.type = "button";
button.className = "project__to-top";
button.setAttribute("aria-label", "Наверх");
button.hidden = true;
button.innerHTML = `
<svg class="project__to-top-icon" width="18" height="18" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M8 3L3 9h10L8 3z" fill="currentColor"></path>
</svg>
`;
document.body.appendChild(button);
return button;
}
function resolveRenalChartElements() {
const projectRoot = getProjectRoot();
const chartContainer =
projectRoot.querySelector(".renal-chart-container") ||
document.querySelector(".renal-chart-container");
if (!chartContainer) {
return null;
}
const svg = chartContainer.querySelector(".renal-chart-svg");
if (!svg) {
return null;
}
const sectionRoot =
chartContainer.closest(".article__main-container4") ||
chartContainer.parentElement ||
projectRoot;
const dropdown =
sectionRoot.querySelector(".renal-dropdown-toggle") ||
document.querySelector(".renal-line-dropdown .renal-dropdown-toggle");
const dropdownMenu =
sectionRoot.querySelector(".renal-line-dropdown .renal-dropdown-menu") ||
sectionRoot.querySelector(".renal-dropdown-menu") ||
document.querySelector(".renal-line-dropdown .renal-dropdown-menu");
if (!dropdown || !dropdownMenu) {
return null;
}
let linesGroup = svg.querySelector(".renal-progression-lines");
if (!linesGroup) {
linesGroup = document.createElementNS("http://www.w3.org/2000/svg", "g");
linesGroup.setAttribute("class", "renal-progression-lines");
svg.appendChild(linesGroup);
}
return { chartContainer, svg, dropdown, dropdownMenu, linesGroup };
}
function bindRenalDelegation() {
if (renalDelegationBound) {
return;
}
renalDelegationBound = true;
document.addEventListener("click", (event) => {
const lineItem = event.target.closest(".renal-dropdown-item[data-line]");
if (lineItem) {
const chartContainer = lineItem
.closest(".article__main-container4, .article__container4, .project__container")
?.querySelector(".renal-chart-container");
if (chartContainer) {
const api = renalChartRegistry.get(chartContainer);
if (api?.selectLine) {
event.preventDefault();
api.selectLine(Number(lineItem.dataset.line));
lineItem.closest(".renal-dropdown-menu")?.classList.remove("active");
}
}
}
const dropdownToggle = event.target.closest(".renal-dropdown-toggle");
if (dropdownToggle) {
event.preventDefault();
event.stopPropagation();
dropdownToggle
.closest(".renal-line-dropdown")
?.querySelector(".renal-dropdown-menu")
?.classList.toggle("active");
} else if (!event.target.closest(".renal-line-dropdown")) {
document.querySelectorAll(".renal-dropdown-menu.active").forEach((menu) => {
menu.classList.remove("active");
});
}
});
}
let toTopEventsAbort = null;
function bindToTopButton() {
const toTopButton = ensureToTopButton();
const SHOW_AFTER_PX = 400;
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
let scrollTicking = false;
if (toTopEventsAbort) {
toTopEventsAbort.abort();
}
toTopEventsAbort = new AbortController();
const { signal } = toTopEventsAbort;
const setButtonVisible = (isVisible) => {
toTopButton.classList.toggle("is-visible", isVisible);
toTopButton.toggleAttribute("hidden", !isVisible);
toTopButton.tabIndex = isVisible ? 0 : -1;
};
const updateButtonVisibility = () => {
setButtonVisible(getPageScrollTop(toTopButton) > SHOW_AFTER_PX);
scrollTicking = false;
};
const onScroll = () => {
if (scrollTicking) {
return;
}
scrollTicking = true;
requestAnimationFrame(updateButtonVisibility);
};
toTopButton.addEventListener(
"click",
() => {
scrollPageToTop(toTopButton, prefersReducedMotion ? "auto" : "smooth");
},
{ signal }
);
getScrollRoots(toTopButton).forEach((root) => {
root.addEventListener("scroll", onScroll, { passive: true, signal });
});
updateButtonVisibility();
}
function bootDynamicModules() {
ensureToTopButton();
bindToTopButton();
bindProjectExternalLinks();
bootRenalChart();
}
function setupDynamicModuleBoot() {
bindRenalDelegation();
bootDynamicModules();
if (dynamicBootObserver) {
return;
}
dynamicBootObserver = new MutationObserver(() => {
clearTimeout(dynamicBootTimer);
dynamicBootTimer = window.setTimeout(bootDynamicModules, 80);
});
dynamicBootObserver.observe(document.documentElement, {
childList: true,
subtree: true,
});
}
/* ==========================================================================
script.js — появление блоков при скролле
========================================================================== */
runWhenDomReady(() => {
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
const revealElements = [];
const STAGGER_MS = 90;
const MAX_STAGGER_MS = 360;
const registerReveal = (element, delayMs = 0) => {
element.classList.add("project__reveal");
element.style.setProperty("--reveal-delay", `${delayMs}ms`);
revealElements.push(element);
};
const topContainer = document.querySelector(".project__top-container");
if (topContainer) {
registerReveal(topContainer, 80);
}
document.querySelectorAll(".video__container").forEach((element) => {
registerReveal(element);
});
document.querySelectorAll(".project__bottom").forEach((bottom) => {
Array.from(bottom.children).forEach((child, index) => {
registerReveal(child, Math.min(index * STAGGER_MS, MAX_STAGGER_MS));
});
});
if (!revealElements.length) {
return;
}
if (prefersReducedMotion) {
revealElements.forEach((element) => element.classList.add("is-visible"));
return;
}
const revealObserver = new IntersectionObserver(
(entries, activeObserver) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) {
return;
}
entry.target.classList.add("is-visible");
activeObserver.unobserve(entry.target);
});
},
{
threshold: 0.12,
rootMargin: "0px 0px -8% 0px",
}
);
revealElements.forEach((element) => revealObserver.observe(element));
const revealInViewport = () => {
const viewportThreshold = window.innerHeight * 0.92;
revealElements.forEach((element) => {
const { top, bottom } = element.getBoundingClientRect();
if (top < viewportThreshold && bottom > 0) {
element.classList.add("is-visible");
revealObserver.unobserve(element);
}
});
};
requestAnimationFrame(revealInViewport);
});
runWhenDomReady(setupDynamicModuleBoot);
/* ==========================================================================
script.js — анимация столбчатых диаграмм
========================================================================== */
// ДИАГРАММЫ - АНИМАЦИЯ (script.js)
runWhenDomReady(() => {
const chartCards = Array.from(document.querySelectorAll(".project__chart-card"));
if (!chartCards.length) {
return;
}
const VALUE_GAP_PX = 56;
const MIN_BAR_WIDTH_PX = 1;
const ROW_DELAY_MS = 180;
const BAR_ANIMATION_MS = 3000;
const START_DELAY_MS = 500;
const parseCssNumber = (value) => {
const parsedValue = Number.parseFloat(value);
return Number.isFinite(parsedValue) ? parsedValue : 0;
};
const formatPercent = (value, decimals) => `${value.toFixed(decimals).replace(".", ",")}%`;
const parsePercentText = (text) => {
const normalizedText = text.replace("%", "").trim();
const decimals = normalizedText.includes(",") ? normalizedText.split(",")[1].length : 0;
const numericValue = parseCssNumber(normalizedText.replace(",", "."));
return { numericValue, decimals };
};
const animateValueCounter = (valueElement) => {
const targetValue = parseCssNumber(valueElement.dataset.targetValue || "0");
const decimals = Number.parseInt(valueElement.dataset.decimals || "0", 10);
const animationStart = performance.now();
const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);
const updateCounter = (timestamp) => {
const progress = Math.min((timestamp - animationStart) / BAR_ANIMATION_MS, 1);
const easedProgress = easeOutCubic(progress);
const currentValue = targetValue * easedProgress;
valueElement.textContent = formatPercent(currentValue, decimals);
if (progress < 1) {
window.requestAnimationFrame(updateCounter);
}
};
window.requestAnimationFrame(updateCounter);
};
const getBarTargetWidth = (bar, wrap) => {
const value = parseCssNumber(bar.style.getPropertyValue("--value"));
const max = parseCssNumber(bar.style.getPropertyValue("--max"));
if (max <= 0 || value <= 0) {
return MIN_BAR_WIDTH_PX;
}
const availableWidth = Math.max(MIN_BAR_WIDTH_PX, wrap.clientWidth - VALUE_GAP_PX);
return Math.max(MIN_BAR_WIDTH_PX, (value / max) * availableWidth);
};
const prepareCard = (card) => {
const rows = card.querySelectorAll(".project__chart-row");
const calloutValueElement = card.querySelector(".project__chart-callout-value");
rows.forEach((row) => {
const bar = row.querySelector(".project__chart-bar");
const valueElement = row.querySelector(".project__chart-value");
if (!bar) {
return;
}
bar.style.width = `${MIN_BAR_WIDTH_PX}px`;
bar.style.transition = "none";
if (!valueElement) {
return;
}
const { numericValue, decimals } = parsePercentText(valueElement.textContent);
valueElement.dataset.targetValue = String(numericValue);
valueElement.dataset.decimals = String(decimals);
valueElement.textContent = formatPercent(0, decimals);
});
if (calloutValueElement) {
const { numericValue, decimals } = parsePercentText(calloutValueElement.textContent);
calloutValueElement.dataset.targetValue = String(numericValue);
calloutValueElement.dataset.decimals = String(decimals);
calloutValueElement.textContent = formatPercent(0, decimals);
}
};
const animateCard = (card) => {
const rows = Array.from(card.querySelectorAll(".project__chart-row"));
const calloutValueElement = card.querySelector(".project__chart-callout-value");
window.setTimeout(() => {
if (calloutValueElement) {
animateValueCounter(calloutValueElement);
}
rows.forEach((row, index) => {
const bar = row.querySelector(".project__chart-bar");
const wrap = row.querySelector(".project__chart-bar-wrap");
const valueElement = row.querySelector(".project__chart-value");
if (!bar || !wrap) {
return;
}
const targetWidth = getBarTargetWidth(bar, wrap);
window.setTimeout(() => {
bar.style.transition = `width ${BAR_ANIMATION_MS}ms cubic-bezier(0.2, 0.65, 0.2, 1)`;
bar.style.width = `${targetWidth}px`;
if (valueElement) {
animateValueCounter(valueElement);
}
}, index * ROW_DELAY_MS);
});
}, START_DELAY_MS);
};
chartCards.forEach(prepareCard);
const observer = new IntersectionObserver(
(entries, activeObserver) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) {
return;
}
const card = entry.target;
animateCard(card);
activeObserver.unobserve(card);
});
},
{
threshold: 0.25,
rootMargin: "0px 0px -10% 0px",
}
);
chartCards.forEach((card) => observer.observe(card));
});
// /ДИАГРАММЫ - АНИМАЦИЯ (script.js)
/* ==========================================================================
script.js — слайдер экспертов
========================================================================== */
// ЭКСПЕРТЫ - СЛАЙДЕР (script.js)
runWhenDomReady(() => {
const container = document.querySelector(".slider-container");
if (!container) {
return;
}
const track = container.querySelector(".slider-content");
const slides = Array.from(container.querySelectorAll(".slider-single"));
if (!track || !slides.length) {
return;
}
const AUTO_PLAY_MS = 6000;
const slideTotal = slides.length - 1;
let slideCurrent = 0;
let autoPlayTimer = null;
const startAutoPlay = () => {
clearInterval(autoPlayTimer);
autoPlayTimer = setInterval(slideRight, AUTO_PLAY_MS);
};
const stopAutoPlay = () => {
clearInterval(autoPlayTimer);
};
const updateBullets = () => {
container.querySelectorAll(".bullet").forEach((bullet, index) => {
bullet.classList.toggle("active", index === slideCurrent);
});
};
const viewport = document.createElement("div");
viewport.classList.add("slider-viewport");
container.insertBefore(viewport, track);
viewport.appendChild(track);
const MAX_SLIDE_WIDTH_PX = 800;
const getSlideWidthRatio = () => (window.matchMedia("(max-width: 770px)").matches ? 0.78 : 0.68);
const getSlideWidth = () =>
Math.min(MAX_SLIDE_WIDTH_PX, Math.round(viewport.clientWidth * getSlideWidthRatio()));
const setSlideWidth = (slide, width) => {
slide.style.flexBasis = `${width}px`;
slide.style.width = `${width}px`;
slide.style.minWidth = `${width}px`;
slide.style.maxWidth = `${width}px`;
};
const applySlideWidths = () => {
const slideWidth = getSlideWidth();
slides.forEach((slide) => {
setSlideWidth(slide, slideWidth);
});
};
const updateTrackPosition = (instant = false) => {
const activeSlide = slides[slideCurrent];
const viewportWidth = viewport.clientWidth;
if (!activeSlide || !viewportWidth) {
return;
}
const slideCenter = activeSlide.offsetLeft + activeSlide.offsetWidth / 2;
const translateX = viewportWidth / 2 - slideCenter;
if (instant) {
track.style.transition = "none";
track.style.transform = `translateX(${translateX}px)`;
track.getBoundingClientRect();
track.style.transition = "";
return;
}
track.style.transform = `translateX(${translateX}px)`;
};
const refreshSliderLayout = () => {
applySlideWidths();
updateTrackPosition(true);
};
const goToSlide = (index) => {
if (index === slideCurrent) {
return;
}
slideCurrent = index;
slides.forEach((slide, slideIndex) => {
slide.classList.toggle("is-active", slideIndex === index);
});
updateBullets();
requestAnimationFrame(() => {
updateTrackPosition();
});
};
const changeSlide = (direction) => {
const nextIndex =
direction === "right"
? slideCurrent >= slideTotal
? 0
: slideCurrent + 1
: slideCurrent <= 0
? slideTotal
: slideCurrent - 1;
goToSlide(nextIndex);
};
const slideRight = () => changeSlide("right");
const slideLeft = () => changeSlide("left");
const navigateWithReset = (navigate) => {
stopAutoPlay();
navigate();
startAutoPlay();
};
const goToIndexSlide = (index) => {
if (index === slideCurrent) {
return;
}
navigateWithReset(() => goToSlide(index));
};
const bulletContainer = document.createElement("div");
bulletContainer.classList.add("bullet-container");
slides.forEach((_, index) => {
const bullet = document.createElement("div");
bullet.classList.add("bullet");
bullet.setAttribute("role", "button");
bullet.setAttribute("tabindex", "0");
bullet.setAttribute("aria-label", `Эксперт ${index + 1}`);
bullet.addEventListener("click", () => goToIndexSlide(index));
bulletContainer.appendChild(bullet);
});
container.appendChild(bulletContainer);
slides.forEach((slide, index) => {
slide.addEventListener("click", () => {
if (index === slideCurrent) {
return;
}
navigateWithReset(() => goToSlide(index));
});
});
slides.forEach((slide, slideIndex) => {
slide.classList.toggle("is-active", slideIndex === 0);
});
updateBullets();
refreshSliderLayout();
startAutoPlay();
window.addEventListener("resize", refreshSliderLayout);
if (typeof ResizeObserver !== "undefined") {
const resizeObserver = new ResizeObserver(refreshSliderLayout);
resizeObserver.observe(viewport);
}
if (document.fonts?.ready) {
document.fonts.ready.then(refreshSliderLayout);
}
requestAnimationFrame(refreshSliderLayout);
});
// /ЭКСПЕРТЫ - СЛАЙДЕР (script.js)
/* ==========================================================================
renal-chart.js — интерактивный график ХБП (ренальная прогрессия)
========================================================================== */
function bootRenalChart() {
const renalElements = resolveRenalChartElements();
if (!renalElements) {
return;
}
const { chartContainer, svg, dropdown, dropdownMenu, linesGroup } = renalElements;
const existingApi = renalChartRegistry.get(chartContainer);
if (existingApi) {
existingApi.rebind();
return;
}
if (chartContainer.dataset.bayerRenalReady === "1" && !chartContainer.querySelector(".renal-marker-group")) {
delete chartContainer.dataset.bayerRenalReady;
}
let eventsAbort = new AbortController();
const getEventSignal = () => eventsAbort.signal;
const config = {
minAge: 45,
maxAge: 90,
maxGfr: 100,
minGfr: 0,
minLineGfr: 17,
startGfr: 90,
maxLineSpeed: 10,
chart: { width: 950, height: 510, left: 60, right: 30, top: 20, bottom: 67 },
// Совпадает с подписями оси X в SVG (45 -> 60, 90 -> 920).
xAxis: { min: 60, max: 920 },
};
const lineProfiles = {
1: { ageAtGfr17: Number.POSITIVE_INFINITY, rate: 0.8 },
2: { ageAtGfr17: 81.5 },
3: { ageAtGfr17: 69 },
4: { ageAtGfr17: 63.25 },
5: { ageAtGfr17: 59.6 },
6: { ageAtGfr17: 57.17 },
7: { ageAtGfr17: 55.43 },
8: { ageAtGfr17: 54.13 },
9: { ageAtGfr17: 53.11 },
10: { ageAtGfr17: 52.3 },
};
let dropdownValue = dropdown.querySelector(".dropdown-value");
if (!dropdownValue) {
dropdownValue = document.createElement("span");
dropdownValue.className = "dropdown-value";
dropdownValue.textContent = "3";
dropdown.prepend(dropdownValue);
}
const lineButtons = Array.from(dropdownMenu.querySelectorAll(".renal-dropdown-item"));
if (!lineButtons.length) {
return;
}
let currentLineSpeed = 3;
let currentStageIndex = 0;
let markerElements = null;
let markerLayerSvg = null;
let chartStage = null;
let chartUiScaler = null;
let ageBadgeElements = null;
let isDragging = false;
function ageToX(age) {
const { min, max } = config.xAxis;
const ratio = (age - config.minAge) / (config.maxAge - config.minAge);
return min + (max - min) * ratio;
}
function syncXAxisLabels() {
const labelsGroup = svg.querySelector(".renal-x-labels");
if (!labelsGroup) {
return;
}
const ticks = Array.from(labelsGroup.querySelectorAll(".axis-label"));
ticks.forEach((label, index) => {
const age = config.minAge + index * 5;
label.setAttribute("x", String(ageToX(age)));
label.setAttribute("text-anchor", "middle");
label.setAttribute("dominant-baseline", "hanging");
});
}
function gfrToY(gfr) {
const innerHeight = config.chart.height - config.chart.top - config.chart.bottom;
const ratio = (gfr - config.minGfr) / (config.maxGfr - config.minGfr);
return config.chart.height - config.chart.bottom - innerHeight * ratio;
}
function gfrAtAge(lineSpeed, age) {
const line = lineProfiles[lineSpeed];
if (!line) {
return config.startGfr;
}
if (!Number.isFinite(line.ageAtGfr17)) {
const gfr = config.startGfr - line.rate * (age - config.minAge);
return Math.max(config.minLineGfr, Math.min(config.startGfr, gfr));
}
const slope = (config.minLineGfr - config.startGfr) / (line.ageAtGfr17 - config.minAge);
const gfr = config.startGfr + slope * (age - config.minAge);
return Math.max(config.minLineGfr, Math.min(config.startGfr, gfr));
}
function getLineEndAge(lineSpeed) {
const line = lineProfiles[lineSpeed];
if (!line || !Number.isFinite(line.ageAtGfr17)) {
return config.maxAge;
}
return Math.min(config.maxAge, line.ageAtGfr17);
}
function getStageFromGfr(gfr) {
if (gfr >= 90) return "С1";
if (gfr >= 60) return "С2";
if (gfr >= 45) return "С3a";
if (gfr >= 30) return "С3b";
return "С4";
}
function buildStages(lineSpeed) {
const stages = [];
const endAge = getLineEndAge(lineSpeed);
for (let age = config.minAge; age <= endAge; age += 5) {
stages.push({ age, gfr: gfrAtAge(lineSpeed, age) });
}
if (!stages.length || stages[stages.length - 1].age < endAge) {
stages.push({ age: endAge, gfr: gfrAtAge(lineSpeed, endAge) });
}
return stages;
}
const RENAL_MARKER_AVATAR_URL =
"/upload/medialibrary/309/acxc0cdhb90639uwzj587hu2zltc7c5m/avatar.webp";
const RENAL_MARKER_DOT_RADIUS = 32;
const RENAL_MARKER_DOT_SIZE = RENAL_MARKER_DOT_RADIUS * 2;
const RENAL_MARKER_BADGE_OFFSET = 24;
function ensureRenalMarkerDefs(targetSvg) {
let defs = targetSvg.querySelector("defs");
if (!defs) {
defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
targetSvg.prepend(defs);
}
if (!targetSvg.querySelector("#renalBadgeShadow")) {
const filter = document.createElementNS("http://www.w3.org/2000/svg", "filter");
filter.setAttribute("id", "renalBadgeShadow");
filter.setAttribute("x", "-30%");
filter.setAttribute("y", "-50%");
filter.setAttribute("width", "180%");
filter.setAttribute("height", "220%");
const shadow = document.createElementNS("http://www.w3.org/2000/svg", "feDropShadow");
shadow.setAttribute("dx", "0");
shadow.setAttribute("dy", "6");
shadow.setAttribute("stdDeviation", "5");
shadow.setAttribute("flood-color", "#1F1F2E");
shadow.setAttribute("flood-opacity", "0.2");
filter.appendChild(shadow);
defs.appendChild(filter);
}
}
function createRenalMarkerDot() {
const dot = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject");
dot.setAttribute("class", "renal-marker-dot");
dot.setAttribute("width", String(RENAL_MARKER_DOT_SIZE));
dot.setAttribute("height", String(RENAL_MARKER_DOT_SIZE));
const wrapper = document.createElement("div");
wrapper.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
wrapper.className = "renal-marker-dot-inner";
const avatar = document.createElement("img");
avatar.src = RENAL_MARKER_AVATAR_URL;
avatar.alt = "";
avatar.draggable = false;
avatar.decoding = "async";
wrapper.append(avatar);
dot.appendChild(wrapper);
return dot;
}
function ensureGradient() {
let defs = svg.querySelector("defs");
if (!defs) {
defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
svg.prepend(defs);
}
if (svg.querySelector("#renalLineGradient")) {
ensureRenalMarkerDefs(svg);
return;
}
const gradient = document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
gradient.setAttribute("id", "renalLineGradient");
gradient.setAttribute("x1", "100%");
gradient.setAttribute("y1", "0%");
gradient.setAttribute("x2", "0%");
gradient.setAttribute("y2", "0%");
const stop1 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
stop1.setAttribute("offset", "0%");
stop1.setAttribute("stop-color", "#A71843");
const stop2 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
stop2.setAttribute("offset", "100%");
stop2.setAttribute("stop-color", "#584A85");
gradient.append(stop1, stop2);
defs.appendChild(gradient);
ensureRenalMarkerDefs(svg);
}
function ensureChartStage() {
if (chartStage) {
return chartStage;
}
const existingStage = chartContainer.querySelector(":scope > .renal-chart-stage");
if (existingStage) {
chartStage = existingStage;
return chartStage;
}
chartStage = document.createElement("div");
chartStage.className = "renal-chart-stage";
chartContainer.insertBefore(chartStage, svg);
chartStage.appendChild(svg);
return chartStage;
}
function ensureChartUiScaler() {
if (chartUiScaler) {
return chartUiScaler;
}
const existingScaler = ensureChartStage().querySelector(":scope > .renal-chart-ui-scaler");
if (existingScaler) {
chartUiScaler = existingScaler;
return chartUiScaler;
}
chartUiScaler = document.createElement("div");
chartUiScaler.className = "renal-chart-ui-scaler";
ensureChartStage().appendChild(chartUiScaler);
return chartUiScaler;
}
const OVERLAY_SIZE_FACTOR = 0.8;
const NARROW_VIEWPORT_MAX = 500;
const NARROW_OVERLAY_SHRINK = 0.72;
const NARROW_OVERLAY_MIN_SCALE = 0.42;
const GRID_LINE_END_X = 920;
function updateRenalUiScale() {
const stage = ensureChartStage();
const stageWidth = stage.getBoundingClientRect().width;
if (!stageWidth) {
return;
}
const chartScale = stageWidth / config.chart.width;
chartContainer.style.setProperty("--renal-ui-scale", String(chartScale));
const isNarrow = window.innerWidth <= NARROW_VIEWPORT_MAX;
let overlayScale = chartScale * (isNarrow ? NARROW_OVERLAY_SHRINK : OVERLAY_SIZE_FACTOR);
if (isNarrow) {
overlayScale = Math.max(overlayScale, NARROW_OVERLAY_MIN_SCALE);
chartContainer.classList.add("renal-chart-container--narrow");
} else {
chartContainer.classList.remove("renal-chart-container--narrow");
}
const overlayRightPercent = ((config.chart.width - GRID_LINE_END_X) / config.chart.width) * 100;
chartContainer.style.setProperty("--renal-overlay-right", `${overlayRightPercent}%`);
chartContainer.style.setProperty("--renal-overlay-total-scale", String(overlayScale));
}
let resizeUiTimer = null;
function scheduleRenalUiScaleUpdate() {
clearTimeout(resizeUiTimer);
resizeUiTimer = setTimeout(updateRenalUiScale, 50);
}
function getMarkerLayerSvg() {
if (markerLayerSvg) {
return markerLayerSvg;
}
const existingLayer = chartContainer.querySelector(".renal-marker-layer");
if (existingLayer) {
markerLayerSvg = existingLayer;
ensureRenalMarkerDefs(markerLayerSvg);
return markerLayerSvg;
}
markerLayerSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
markerLayerSvg.setAttribute("class", "renal-marker-layer");
markerLayerSvg.setAttribute("viewBox", "0 0 950 510");
markerLayerSvg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
markerLayerSvg.setAttribute("aria-hidden", "true");
ensureRenalMarkerDefs(markerLayerSvg);
ensureChartStage().appendChild(markerLayerSvg);
return markerLayerSvg;
}
function resetMarker() {
const layer = markerLayerSvg || chartContainer.querySelector(".renal-marker-layer");
if (layer) {
layer.querySelectorAll(".renal-marker-group").forEach((group) => group.remove());
}
markerElements = null;
}
function createMarkerIfNeeded() {
if (markerElements) {
return markerElements;
}
const markerLayer = getMarkerLayerSvg();
const existingGroup = markerLayer.querySelector(".renal-marker-group");
if (existingGroup) {
markerElements = {
group: existingGroup,
dot: existingGroup.querySelector(".renal-marker-dot"),
hitArea: existingGroup.querySelector(".renal-marker-hit"),
label: existingGroup.querySelector(".renal-marker-label"),
connector: existingGroup.querySelector(".renal-marker-connector"),
badgeRect: existingGroup.querySelector(".renal-marker-badge-bg"),
valueText: existingGroup.querySelector(".renal-marker-value"),
metaText: existingGroup.querySelector(".renal-marker-meta"),
};
return markerElements;
}
const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
group.setAttribute("class", "renal-marker-group");
const hitArea = document.createElementNS("http://www.w3.org/2000/svg", "circle");
hitArea.setAttribute("r", "34");
hitArea.setAttribute("class", "renal-marker-hit");
hitArea.setAttribute("fill", "transparent");
const dot = createRenalMarkerDot();
const connector = document.createElementNS("http://www.w3.org/2000/svg", "line");
connector.setAttribute("class", "renal-marker-connector");
const label = document.createElementNS("http://www.w3.org/2000/svg", "g");
label.setAttribute("class", "renal-marker-label");
const badgeRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
badgeRect.setAttribute("class", "renal-marker-badge-bg");
badgeRect.setAttribute("rx", "12");
badgeRect.setAttribute("ry", "12");
badgeRect.setAttribute("height", "44");
const valueText = document.createElementNS("http://www.w3.org/2000/svg", "text");
valueText.setAttribute("class", "renal-marker-value");
const metaText = document.createElementNS("http://www.w3.org/2000/svg", "text");
metaText.setAttribute("class", "renal-marker-meta");
group.classList.add("renal-marker-group");
label.append(connector, badgeRect, valueText, metaText);
// SVG stacking: later nodes render above previous ones.
// Keep avatar above badge while preserving drag hit-area on top.
group.append(label, dot, hitArea);
getMarkerLayerSvg().appendChild(group);
markerElements = { group, dot, hitArea, label, connector, badgeRect, valueText, metaText };
return markerElements;
}
function getYearWord(age) {
const years = Math.round(Number(age));
if (!Number.isFinite(years)) return "лет";
const lastDigit = years % 10;
const lastTwoDigits = years % 100;
if (lastTwoDigits >= 11 && lastTwoDigits <= 14) return "лет";
if (lastDigit === 1) return "год";
if (lastDigit >= 2 && lastDigit <= 4) return "года";
return "лет";
}
function createAgeBadgeIfNeeded() {
if (ageBadgeElements) {
return ageBadgeElements;
}
const svgNS = "http://www.w3.org/2000/svg";
const ageLabelGroup = document.createElementNS(svgNS, "foreignObject");
ageLabelGroup.setAttribute("class", "age-label-group");
ageLabelGroup.setAttribute("width", "62");
ageLabelGroup.setAttribute("height", "62");
ageLabelGroup.innerHTML = `
<div xmlns="http://www.w3.org/1999/xhtml" class="age-label-container">
<svg class="kidney-icon" xmlns="http://www.w3.org/2000/svg" width="62" height="62" viewBox="0 0 62 62" fill="none">
<rect x="17.7321" y="9.50773" width="26.2105" height="43.3416" rx="1.45614" stroke="currentColor" stroke-width="2.56966"/>
<rect x="21.8415" y="13.6191" width="17.9876" height="11.1352" rx="1.45614" stroke="currentColor" stroke-width="2.56966"/>
<path d="M32.207 17.1311L32.207 21.243" stroke="currentColor" stroke-width="2.56966" stroke-linecap="round"/>
<path d="M35.6328 17.1311L35.6328 21.243" stroke="currentColor" stroke-width="2.56966" stroke-linecap="round"/>
<path d="M52.9316 18.5015L52.9364 28.7811" stroke="currentColor" stroke-width="2.56966" stroke-linecap="round"/>
<path d="M8.73828 18.5015L8.73352 28.7811" stroke="currentColor" stroke-width="2.56966" stroke-linecap="round"/>
<circle cx="30.8343" cy="41.115" r="3.51233" fill="currentColor" stroke="currentColor" stroke-width="2.56966"/>
<path d="M54.3047 26.0398C55.8186 26.0398 57.0459 24.8125 57.0459 23.2986C57.0459 21.7847 55.8186 20.5574 54.3047 20.5574" stroke="currentColor" stroke-width="2.56966"/>
<path d="M7.36719 26.0398C5.85325 26.0398 4.62595 24.8125 4.62595 23.2986C4.62595 21.7847 5.85325 20.5574 7.36719 20.5574" stroke="currentColor" stroke-width="2.56966"/>
<circle cx="39.0618" cy="37.1746" r="2.05593" fill="currentColor"/>
<circle cx="39.0618" cy="45.7403" r="2.05593" fill="currentColor"/>
<circle cx="22.6126" cy="37.1746" r="2.05593" fill="currentColor"/>
<circle cx="22.6126" cy="45.7403" r="2.05593" fill="currentColor"/>
<path d="M43.8517 26.7244C43.8517 28.6166 38.0227 30.1506 30.8321 30.1506C23.6416 30.1506 17.8125 28.6166 17.8125 26.7244" stroke="currentColor" stroke-width="2.56966"/>
</svg>
</div>
`;
const ageBadgeGroup = document.createElementNS(svgNS, "g");
ageBadgeGroup.setAttribute("class", "age-badge-svg-group");
const arrowLeft = document.createElementNS(svgNS, "path");
arrowLeft.setAttribute("class", "badge-arrow");
arrowLeft.setAttribute("d", "M0 0 L19 10 L19 -10 Z");
const circle = document.createElementNS(svgNS, "circle");
circle.setAttribute("class", "badge-circle");
circle.setAttribute("cx", "48");
circle.setAttribute("cy", "0");
circle.setAttribute("r", "35.5");
const arrowInner = document.createElementNS(svgNS, "path");
arrowInner.setAttribute("class", "badge-inner-arrow");
arrowInner.setAttribute("d", "M5 0 L21 8 L21 -8 Z");
const ageNumberText = document.createElementNS(svgNS, "text");
ageNumberText.setAttribute("class", "age-number");
ageNumberText.setAttribute("x", "48");
ageNumberText.setAttribute("y", "-5");
ageNumberText.setAttribute("text-anchor", "middle");
ageNumberText.setAttribute("dominant-baseline", "middle");
const ageWordText = document.createElementNS(svgNS, "text");
ageWordText.setAttribute("class", "age-label-word");
ageWordText.setAttribute("x", "48");
ageWordText.setAttribute("y", "13");
ageWordText.setAttribute("text-anchor", "middle");
ageWordText.setAttribute("dominant-baseline", "middle");
ageWordText.textContent = "лет";
ageBadgeGroup.append(arrowLeft, circle, arrowInner, ageNumberText, ageWordText);
svg.appendChild(ageLabelGroup);
svg.appendChild(ageBadgeGroup);
ageBadgeElements = { ageLabelGroup, ageBadgeGroup, ageNumberText, ageWordText };
return ageBadgeElements;
}
function updateAgeBadge(lineSpeed) {
if (!Number.isFinite(lineSpeed) || lineSpeed <= 0) return;
const { ageLabelGroup, ageBadgeGroup, ageNumberText, ageWordText } = createAgeBadgeIfNeeded();
const lineEndAge = getLineEndAge(lineSpeed);
if (lineEndAge >= config.maxAge) {
// Site behavior for the slowest line: only kidney icon in lower-left zone.
ageLabelGroup.setAttribute("x", "60");
ageLabelGroup.setAttribute("y", "380");
ageBadgeGroup.style.display = "none";
return;
}
const endAge = Math.max(config.minAge, lineEndAge);
const endX = ageToX(endAge);
const endY = gfrToY(gfrAtAge(lineSpeed, endAge));
ageLabelGroup.setAttribute("x", String(Math.max(config.chart.left, endX - 74)));
ageLabelGroup.setAttribute("y", String(Math.max(config.chart.top, endY + 6)));
ageBadgeGroup.style.display = "";
ageBadgeGroup.setAttribute("transform", `translate(${endX + 8}, ${endY + 42}) scale(1.1)`);
const roundedAge = Math.round(endAge);
ageNumberText.textContent = String(roundedAge);
ageWordText.textContent = getYearWord(roundedAge);
}
function animateTextSwap(textNode, nextValue) {
if (textNode.textContent === nextValue) {
return;
}
if (typeof textNode.animate !== "function") {
textNode.textContent = nextValue;
return;
}
textNode.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 120, easing: "ease-out" });
setTimeout(() => {
textNode.textContent = nextValue;
textNode.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 160, easing: "ease-out" });
}, 90);
}
function drawLine(lineSpeed) {
ensureGradient();
linesGroup.innerHTML = "";
resetMarker();
const stages = buildStages(lineSpeed);
const points = stages.map((s) => `${ageToX(s.age)} ${gfrToY(s.gfr)}`).join(" L ");
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute("class", "renal-progression-line");
path.setAttribute("d", `M ${points}`);
linesGroup.appendChild(path);
const currentStage = stages[currentStageIndex] || stages[0];
updateMarker(currentStage);
updateAgeBadge(lineSpeed);
}
function updateMarker(stage, options) {
if (!stage) {
return;
}
const { group, dot, hitArea, connector, badgeRect, valueText, metaText } = createMarkerIfNeeded();
const x = options?.markerX ?? ageToX(stage.age);
const y = gfrToY(stage.gfr);
const stageLabel = `ХБП ${getStageFromGfr(stage.gfr)} А3`;
dot.setAttribute("x", String(x - RENAL_MARKER_DOT_RADIUS));
dot.setAttribute("y", String(y - RENAL_MARKER_DOT_RADIUS));
hitArea.setAttribute("cx", String(x));
hitArea.setAttribute("cy", String(y));
const badgeX = x + RENAL_MARKER_BADGE_OFFSET;
const badgeHeight = 44;
const badgeY = Math.max(y - badgeHeight / 2, config.chart.top + 4);
const textWidth = stageLabel.length * 7.6;
const badgeWidth = Math.max(114, Math.min(190, Math.round(textWidth + 26)));
const cardX = badgeX;
const cardY = badgeY;
connector.setAttribute("display", "none");
badgeRect.setAttribute("x", String(cardX));
badgeRect.setAttribute("y", String(cardY));
badgeRect.setAttribute("width", String(badgeWidth));
badgeRect.setAttribute("height", String(badgeHeight));
valueText.setAttribute("x", String(cardX + badgeWidth / 2));
valueText.setAttribute("y", String(cardY + badgeHeight / 2));
valueText.setAttribute("text-anchor", "middle");
valueText.setAttribute("dominant-baseline", "middle");
animateTextSwap(valueText, stageLabel);
metaText.textContent = "";
group.dataset.age = String(stage.age);
group.dataset.gfr = String(stage.gfr);
}
const kidneyAnimation = {
currentNephronsPercent: 50,
animationDuration: 600,
lerp(start, end, t) {
return start + (end - start) * t;
},
getKidneyHeight(gfr) {
const thresholds = { 90: 28.5914, 75: 43, 59: 53, 37: 69, 20: 76, 17: 79 };
for (const [threshold, height] of Object.entries(thresholds)) {
if (Math.abs(gfr - Number(threshold)) < 0.5) return height;
}
if (gfr >= 90) return 28.5914;
if (gfr >= 75) return this.lerp(43, 28.5914, (gfr - 75) / 15);
if (gfr >= 59) return this.lerp(53, 43, (gfr - 59) / 16);
if (gfr >= 37) return this.lerp(69, 53, (gfr - 37) / 22);
if (gfr >= 20) return this.lerp(76, 69, (gfr - 20) / 17);
if (gfr >= 17) return this.lerp(79, 76, (gfr - 17) / 3);
return 79;
},
getNephronsCount(gfr) {
const thresholds = { 90: 2000000, 75: 1500000, 59: 1000000, 37: 500000, 20: 300000, 17: 200000 };
for (const [threshold, count] of Object.entries(thresholds)) {
if (Math.abs(gfr - Number(threshold)) < 0.5) return count;
}
if (gfr >= 90) return 2000000;
if (gfr >= 75) return Math.round(this.lerp(1500000, 2000000, (gfr - 75) / 15));
if (gfr >= 59) return Math.round(this.lerp(1000000, 1500000, (gfr - 59) / 16));
if (gfr >= 37) return Math.round(this.lerp(500000, 1000000, (gfr - 37) / 22));
if (gfr >= 20) return Math.round(this.lerp(300000, 500000, (gfr - 20) / 17));
if (gfr >= 17) return Math.round(this.lerp(200000, 300000, (gfr - 17) / 3));
return 200000;
},
getRiskMultiplier(gfr) {
const thresholds = { 90: 3, 75: 4, 59: 5, 37: 6, 20: 9, 17: 9 };
for (const [threshold, risk] of Object.entries(thresholds)) {
if (Math.abs(gfr - Number(threshold)) < 0.5) return risk;
}
if (gfr >= 90) return 3;
if (gfr >= 75) return Math.round(this.lerp(4, 3, (gfr - 75) / 15));
if (gfr >= 59) return Math.round(this.lerp(5, 4, (gfr - 59) / 16));
if (gfr >= 37) return Math.round(this.lerp(6, 5, (gfr - 37) / 22));
if (gfr >= 20) return Math.round(this.lerp(9, 6, (gfr - 20) / 17));
return 9;
},
formatNephronsPercent(percent) {
return `${Math.round(percent)}%`;
},
animateValue(start, end, onUpdate, onComplete) {
const startTime = performance.now();
const diff = end - start;
const step = (now) => {
const progress = Math.min((now - startTime) / this.animationDuration, 1);
const eased = 1 - Math.pow(1 - progress, 3);
onUpdate(start + diff * eased);
if (progress < 1) {
requestAnimationFrame(step);
} else if (onComplete) {
onComplete();
}
};
requestAnimationFrame(step);
},
updateKidneys(gfr, skipAnimation = false) {
const targetHeight = this.getKidneyHeight(gfr);
const targetNephrons = this.getNephronsCount(gfr);
const targetNephronsPercent = (targetNephrons / 2000000) * 100;
const targetRisk = this.getRiskMultiplier(gfr);
const rects = chartContainer.querySelectorAll(".kidneys-icon rect[height]");
const nephronsEl = chartContainer.querySelector(".nephrons-number");
const riskEl = chartContainer.querySelector(".risk-number");
if (!nephronsEl || !riskEl || !rects.length) {
return;
}
if (skipAnimation || isDragging) {
rects.forEach((rect) => rect.setAttribute("height", String(targetHeight)));
nephronsEl.textContent = this.formatNephronsPercent(targetNephronsPercent);
riskEl.textContent = `×${targetRisk}`;
this.currentNephronsPercent = targetNephronsPercent;
return;
}
const currentHeight = Number.parseFloat(rects[0].getAttribute("height")) || 53;
this.animateValue(currentHeight, targetHeight, (value) => {
rects.forEach((rect) => rect.setAttribute("height", String(value)));
});
this.animateValue(this.currentNephronsPercent, targetNephronsPercent, (value) => {
nephronsEl.textContent = this.formatNephronsPercent(value);
}, () => {
this.currentNephronsPercent = targetNephronsPercent;
});
const currentRisk = Number.parseInt(riskEl.textContent.replace("×", ""), 10) || 3;
this.animateValue(currentRisk, targetRisk, (value) => {
riskEl.textContent = `×${Math.round(value)}`;
});
},
};
function insertInfoOverlay() {
if (chartContainer.querySelector(".renal-info-cards-overlay")) {
return;
}
const overlay = document.createElement("div");
overlay.className = "renal-info-cards-overlay";
overlay.innerHTML = `
<div class="info-card nephrons-card">
<p class="nephrons-title">Кол-во нефронов в двух почках</p>
<div class="nephrons-visual">
<p class="nephrons-number">50%</p>
<div class="kidneys-container">
<svg class="kidneys-icon kidneys-default" xmlns="http://www.w3.org/2000/svg" width="124" height="103" viewBox="0 0 124 103" fill="none" aria-hidden="true">
<path d="M100.934 10.8008C96.8148 7.92328 92.5524 6.64804 88.7812 7.00684C85.1056 7.35661 81.5451 9.28601 78.6953 13.5488C73.7344 20.9696 74.0742 25.4487 75.333 27.9805C76.707 30.7438 79.7574 32.4271 82.3809 33.0273L86.5381 33.9785L84.2383 37.5703C82.0456 40.9935 81.8299 42.8958 82.0576 44.124C82.3137 45.5048 83.2382 46.8308 85.1465 48.998L88.4688 52.7725L83.5703 53.9043C82.38 54.1793 80.6424 55.7424 79.9492 58.8408C79.2992 61.7467 79.7613 65.4819 82.3682 68.9834C85.0448 72.5785 88.2961 74.3206 91.6211 74.7129C94.9994 75.1114 98.7448 74.1458 102.346 71.7793C109.55 67.0443 115.832 56.8656 116.184 42.8652C116.167 28.2999 109.172 16.5564 100.934 10.8008Z" fill="#584A85" stroke="#fff" stroke-width="6"/>
<mask id="mask0_blue_renal" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="71" y="3" width="49" height="75"><path d="M100.934 10.8008C96.8148 7.92328 92.5524 6.64804 88.7812 7.00684C85.1056 7.35661 81.5451 9.28601 78.6953 13.5488C73.7344 20.9696 74.0742 25.4487 75.333 27.9805C76.707 30.7438 79.7574 32.4271 82.3809 33.0273L86.5381 33.9785L84.2383 37.5703C82.0456 40.9935 81.8299 42.8958 82.0576 44.124C82.3137 45.5048 83.2382 46.8308 85.1465 48.998L88.4688 52.7725L83.5703 53.9043C82.38 54.1793 80.6424 55.7424 79.9492 58.8408C79.2992 61.7467 79.7613 65.4819 82.3682 68.9834C85.0448 72.5785 88.2961 74.3206 91.6211 74.7129C94.9994 75.1114 98.7448 74.1458 102.346 71.7793C109.55 67.0443 115.832 56.8656 116.184 42.8652C116.167 28.2999 109.172 16.5564 100.934 10.8008Z" fill="#D9D9D9" stroke="#749FAD" stroke-width="6"/></mask>
<g mask="url(#mask0_blue_renal)"><rect width="71.1119" height="53" transform="matrix(-1 0 0 1 129.445 -15.0579)" fill="#ffffff"/></g>
<path d="M68.2323 99V53.5471C68.2323 48.0811 72.6634 43.65 78.1293 43.65M67.8658 31.5537V33.0199C67.8658 38.6883 72.4609 43.2835 78.1293 43.2835M81.7119 35.9521C75.4663 34.5232 65.6204 27.7088 76.2011 11.8816C89.427 -7.90232 119.184 11.8814 119.184 42.9171C118.45 72.6082 92.483 87.5923 79.9621 70.7749C73.6767 62.3326 77.4297 52.2438 82.8945 50.9811C79.1528 46.7316 76.9335 43.412 81.7119 35.9521Z" stroke="#A71843" stroke-width="4" stroke-linecap="round"/>
<path d="M23.0664 10.8008C27.1852 7.92328 31.4476 6.64804 35.2188 7.00684C38.8944 7.35661 42.4549 9.28601 45.3047 13.5488C50.2656 20.9696 49.9258 25.4487 48.667 27.9805C47.293 30.7438 44.2426 32.4271 41.6191 33.0273L37.4619 33.9785L39.7617 37.5703C41.9544 40.9935 42.1701 42.8958 41.9424 44.124C41.6863 45.5048 40.7618 46.8308 38.8535 48.998L35.5312 52.7725L40.4297 53.9043C41.62 54.1793 43.3576 55.7424 44.0508 58.8408C44.7008 61.7467 44.2387 65.4819 41.6318 68.9834C38.9552 72.5785 35.7039 74.3206 32.3789 74.7129C29.0006 75.1114 25.2552 74.1458 21.6543 71.7793C14.4496 67.0443 8.16847 56.8656 7.81641 42.8652C7.83296 28.2999 14.8283 16.5564 23.0664 10.8008Z" fill="#584A85" stroke="#fff" stroke-width="6"/>
<mask id="mask1_blue_renal" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="4" y="3" width="49" height="75"><path d="M23.0664 10.8008C27.1852 7.92328 31.4476 6.64804 35.2188 7.00684C38.8944 7.35661 42.4549 9.28601 45.3047 13.5488C50.2656 20.9696 49.9258 25.4487 48.667 27.9805C47.293 30.7438 44.2426 32.4271 41.6191 33.0273L37.4619 33.9785L39.7617 37.5703C41.9544 40.9935 42.1701 42.8958 41.9424 44.124C41.6863 45.5048 40.7618 46.8308 38.8535 48.998L35.5312 52.7725L40.4297 53.9043C41.62 54.1793 43.3576 55.7424 44.0508 58.8408C44.7008 61.7467 44.2387 65.4819 41.6318 68.9834C38.9552 72.5785 35.7039 74.3206 32.3789 74.7129C29.0006 75.1114 25.2552 74.1458 21.6543 71.7793C14.4496 67.0443 8.16847 56.8656 7.81641 42.8652C7.83296 28.2999 14.8283 16.5564 23.0664 10.8008Z" fill="#D9D9D9" stroke="#749FAD" stroke-width="6"/></mask>
<g mask="url(#mask1_blue_renal)"><rect x="-5.44531" y="-15.0579" width="71.1119" height="53" fill="#ffffff"/></g>
<path d="M55.7677 99V53.5471C55.7677 48.0811 51.3366 43.65 45.8707 43.65M56.1342 31.5537V33.0199C56.1342 38.6883 51.5391 43.2835 45.8707 43.2835M42.2881 35.9521C48.5337 34.5232 58.3796 27.7088 47.7989 11.8816C34.573 -7.90232 4.81641 11.8814 4.81641 42.9171C5.54952 72.6082 31.517 87.5923 44.0379 70.7749C50.3233 62.3326 46.5703 52.2438 41.1055 50.9811C44.8472 46.7316 47.0665 43.412 42.2881 35.9521Z" stroke="#A71843" stroke-width="4" stroke-linecap="round"/>
</svg>
<svg class="kidneys-icon kidneys-hover" xmlns="http://www.w3.org/2000/svg" width="124" height="103" viewBox="0 0 124 103" fill="none" aria-hidden="true">
<path d="M100.934 10.8008C96.8148 7.92328 92.5524 6.64804 88.7812 7.00684C85.1056 7.35661 81.5451 9.28601 78.6953 13.5488C73.7344 20.9696 74.0742 25.4487 75.333 27.9805C76.707 30.7438 79.7574 32.4271 82.3809 33.0273L86.5381 33.9785L84.2383 37.5703C82.0456 40.9935 81.8299 42.8958 82.0576 44.124C82.3137 45.5048 83.2382 46.8308 85.1465 48.998L88.4688 52.7725L83.5703 53.9043C82.38 54.1793 80.6424 55.7424 79.9492 58.8408C79.2992 61.7467 79.7613 65.4819 82.3682 68.9834C85.0448 72.5785 88.2961 74.3206 91.6211 74.7129C94.9994 75.1114 98.7448 74.1458 102.346 71.7793C109.55 67.0443 115.832 56.8656 116.184 42.8652C116.167 28.2999 109.172 16.5564 100.934 10.8008Z" fill="#584A85" stroke="#A71843" stroke-width="6"/>
<mask id="mask0_pink_renal" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="71" y="3" width="49" height="75"><path d="M100.934 10.8008C96.8148 7.92328 92.5524 6.64804 88.7812 7.00684C85.1056 7.35661 81.5451 9.28601 78.6953 13.5488C73.7344 20.9696 74.0742 25.4487 75.333 27.9805C76.707 30.7438 79.7574 32.4271 82.3809 33.0273L86.5381 33.9785L84.2383 37.5703C82.0456 40.9935 81.8299 42.8958 82.0576 44.124C82.3137 45.5048 83.2382 46.8308 85.1465 48.998L88.4688 52.7725L83.5703 53.9043C82.38 54.1793 80.6424 55.7424 79.9492 58.8408C79.2992 61.7467 79.7613 65.4819 82.3682 68.9834C85.0448 72.5785 88.2961 74.3206 91.6211 74.7129C94.9994 75.1114 98.7448 74.1458 102.346 71.7793C109.55 67.0443 115.832 56.8656 116.184 42.8652C116.167 28.2999 109.172 16.5564 100.934 10.8008Z" fill="#D9D9D9" stroke="#A71843" stroke-width="6"/></mask>
<g mask="url(#mask0_pink_renal)"><rect width="71.1119" height="53" transform="matrix(-1 0 0 1 129.445 -15.0579)" fill="#A71843"/></g>
<path d="M68.2323 99V53.5471C68.2323 48.0811 72.6634 43.65 78.1293 43.65M67.8658 31.5537V33.0199C67.8658 38.6883 72.4609 43.2835 78.1293 43.2835M81.7119 35.9521C75.4663 34.5232 65.6204 27.7088 76.2011 11.8816C89.427 -7.90232 119.184 11.8814 119.184 42.9171C118.45 72.6082 92.483 87.5923 79.9621 70.7749C73.6767 62.3326 77.4297 52.2438 82.8945 50.9811C79.1528 46.7316 76.9335 43.412 81.7119 35.9521Z" stroke="#584A85" stroke-width="4" stroke-linecap="round"/>
<path d="M23.0664 10.8008C27.1852 7.92328 31.4476 6.64804 35.2188 7.00684C38.8944 7.35661 42.4549 9.28601 45.3047 13.5488C50.2656 20.9696 49.9258 25.4487 48.667 27.9805C47.293 30.7438 44.2426 32.4271 41.6191 33.0273L37.4619 33.9785L39.7617 37.5703C41.9544 40.9935 42.1701 42.8958 41.9424 44.124C41.6863 45.5048 40.7618 46.8308 38.8535 48.998L35.5312 52.7725L40.4297 53.9043C41.62 54.1793 43.3576 55.7424 44.0508 58.8408C44.7008 61.7467 44.2387 65.4819 41.6318 68.9834C38.9552 72.5785 35.7039 74.3206 32.3789 74.7129C29.0006 75.1114 25.2552 74.1458 21.6543 71.7793C14.4496 67.0443 8.16847 56.8656 7.81641 42.8652C7.83296 28.2999 14.8283 16.5564 23.0664 10.8008Z" fill="#584A85" stroke="#A71843" stroke-width="6"/>
<mask id="mask1_pink_renal" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="4" y="3" width="49" height="75"><path d="M23.0664 10.8008C27.1852 7.92328 31.4476 6.64804 35.2188 7.00684C38.8944 7.35661 42.4549 9.28601 45.3047 13.5488C50.2656 20.9696 49.9258 25.4487 48.667 27.9805C47.293 30.7438 44.2426 32.4271 41.6191 33.0273L37.4619 33.9785L39.7617 37.5703C41.9544 40.9935 42.1701 42.8958 41.9424 44.124C41.6863 45.5048 40.7618 46.8308 38.8535 48.998L35.5312 52.7725L40.4297 53.9043C41.62 54.1793 43.3576 55.7424 44.0508 58.8408C44.7008 61.7467 44.2387 65.4819 41.6318 68.9834C38.9552 72.5785 35.7039 74.3206 32.3789 74.7129C29.0006 75.1114 25.2552 74.1458 21.6543 71.7793C14.4496 67.0443 8.16847 56.8656 7.81641 42.8652C7.83296 28.2999 14.8283 16.5564 23.0664 10.8008Z" fill="#D9D9D9" stroke="#A71843" stroke-width="6"/></mask>
<g mask="url(#mask1_pink_renal)"><rect x="-5.44531" y="-15.0579" width="71.1119" height="53" fill="#A71843"/></g>
<path d="M55.7677 99V53.5471C55.7677 48.0811 51.3366 43.65 45.8707 43.65M56.1342 31.5537V33.0199C56.1342 38.6883 51.5391 43.2835 45.8707 43.2835M42.2881 35.9521C48.5337 34.5232 58.3796 27.7088 47.7989 11.8816C34.573 -7.90232 4.81641 11.8814 4.81641 42.9171C5.54952 72.6082 31.517 87.5923 44.0379 70.7749C50.3233 62.3326 46.5703 52.2438 41.1055 50.9811C44.8472 46.7316 47.0665 43.412 42.2881 35.9521Z" stroke="#584A85" stroke-width="4" stroke-linecap="round"/>
</svg>
</div>
</div>
</div>
<div class="info-card risk-card">
<div class="risk-alert-badge" aria-hidden="true">
<svg class="risk-alert-icon" xmlns="http://www.w3.org/2000/svg" width="100" height="90" viewBox="0 0 20 18" fill="none">
<path d="M8.61603 1.97554C9.21366 0.949901 10.7863 0.949901 11.384 1.97554L18.5319 14.2437C19.1335 15.2764 18.3888 16.5714 17.1959 16.5714H2.80408C1.61117 16.5714 0.866549 15.2764 1.46809 14.2437L8.61603 1.97554Z" fill="white" stroke="#A71843" stroke-width="1"/>
<rect x="9.23804" y="5.2" width="1.524" height="5.9" rx="0.762" fill="black"/>
<circle cx="10" cy="13.1" r="1" fill="black"/>
</svg>
</div>
<div class="risk-badge">
<span class="risk-number">×5</span>
</div>
<p class="risk-text">Риск умереть<br>от сердечно-сосудистых катастроф</p>
</div>
`;
ensureChartStage().appendChild(overlay);
}
function insertDragHint() {
if (chartContainer.querySelector(".renal-drag-hint")) {
return;
}
const hint = document.createElement("div");
hint.className = "renal-drag-hint";
hint.innerHTML = `
<img class="renal-drag-hint-icon" src="/upload/medialibrary/8b2/a3bpfqpvyolvlev0iputxp8ws910u13o/hint.webp" alt="" aria-hidden="true" />
<span class="renal-drag-hint-text">Потяните портрет пациента</span>
`;
ensureChartUiScaler().appendChild(hint);
}
function setActiveLine(lineSpeed) {
currentLineSpeed = lineSpeed;
dropdownValue.textContent = String(lineSpeed);
lineButtons.forEach((btn) => {
btn.classList.toggle("active", Number(btn.dataset.line) === lineSpeed);
});
drawLine(lineSpeed);
syncStageSlide(true);
}
function setupDropdown() {
dropdown.addEventListener(
"click",
(event) => {
event.preventDefault();
event.stopPropagation();
dropdownMenu.classList.toggle("active");
},
{ signal: getEventSignal() }
);
lineButtons.forEach((button) => {
button.addEventListener(
"click",
(event) => {
event.preventDefault();
const speed = Number(button.dataset.line);
if (!Number.isFinite(speed)) {
return;
}
currentStageIndex = 0;
setActiveLine(speed);
dropdownMenu.classList.remove("active");
},
{ signal: getEventSignal() }
);
});
}
function refreshSwiperRefs() {
swiper.root = chartContainer.querySelector(".renal-stages-swiper");
swiper.wrapper = chartContainer.querySelector(".renal-stages-swiper .swiper-wrapper");
swiper.prev = chartContainer.querySelector(".renal-nav-prev");
swiper.next = chartContainer.querySelector(".renal-nav-next");
}
function rebindInteractiveHandlers() {
eventsAbort.abort();
eventsAbort = new AbortController();
refreshSwiperRefs();
setupDropdown();
setupStageControls();
setupDragAndDrop();
}
const swiper = {
root: chartContainer.querySelector(".renal-stages-swiper"),
wrapper: chartContainer.querySelector(".renal-stages-swiper .swiper-wrapper"),
prev: chartContainer.querySelector(".renal-nav-prev"),
next: chartContainer.querySelector(".renal-nav-next"),
stages: [],
};
function updateButtons() {
if (!swiper.prev || !swiper.next) {
return;
}
swiper.prev.disabled = currentStageIndex === 0;
swiper.next.disabled = currentStageIndex >= swiper.stages.length - 1;
}
function renderSlides() {
if (!swiper.wrapper) {
return;
}
swiper.wrapper.innerHTML = "";
swiper.stages.forEach((stage, index) => {
const slide = document.createElement("div");
slide.className = "swiper-slide";
slide.textContent = `${stage.age} лет`;
slide.dataset.index = String(index);
swiper.wrapper.appendChild(slide);
});
}
function syncStageSlide(skipTransition) {
swiper.stages = buildStages(currentLineSpeed);
if (currentStageIndex >= swiper.stages.length) {
currentStageIndex = swiper.stages.length - 1;
}
renderSlides();
updateMarker(swiper.stages[currentStageIndex]);
if (swiper.wrapper) {
swiper.wrapper.style.transition = skipTransition ? "none" : "transform 0.25s ease";
swiper.wrapper.style.transform = `translateX(-${currentStageIndex * 100}%)`;
if (skipTransition) {
requestAnimationFrame(() => {
if (swiper.wrapper) {
swiper.wrapper.style.transition = "transform 0.25s ease";
}
});
}
}
updateButtons();
updateOverlayValues(swiper.stages[currentStageIndex]);
}
function updateOverlayValues(stage, skipAnimation = false) {
if (!stage) {
return;
}
kidneyAnimation.updateKidneys(stage.gfr, skipAnimation);
}
function setChartActive(active) {
chartContainer.classList.toggle("renal-chart-active", active);
}
function setupStageControls() {
if (swiper.prev) {
swiper.prev.addEventListener(
"click",
() => {
if (currentStageIndex <= 0) {
return;
}
currentStageIndex -= 1;
syncStageSlide(false);
},
{ signal: getEventSignal() }
);
}
if (swiper.next) {
swiper.next.addEventListener(
"click",
() => {
if (currentStageIndex >= swiper.stages.length - 1) {
return;
}
currentStageIndex += 1;
syncStageSlide(false);
},
{ signal: getEventSignal() }
);
}
if (!swiper.root) {
return;
}
let startX = 0;
let isSwiping = false;
swiper.root.addEventListener(
"touchstart",
(event) => {
startX = event.changedTouches[0].clientX;
isSwiping = true;
},
{ passive: true, signal: getEventSignal() }
);
swiper.root.addEventListener(
"touchend",
(event) => {
if (!isSwiping) {
return;
}
isSwiping = false;
const endX = event.changedTouches[0].clientX;
const delta = endX - startX;
if (Math.abs(delta) < 30) {
return;
}
if (delta < 0 && currentStageIndex < swiper.stages.length - 1) {
currentStageIndex += 1;
} else if (delta > 0 && currentStageIndex > 0) {
currentStageIndex -= 1;
}
syncStageSlide(false);
},
{ passive: true, signal: getEventSignal() }
);
}
function clientToSvgX(clientX) {
const rect = svg.getBoundingClientRect();
const relativeX = clientX - rect.left;
const scale = config.chart.width / rect.width;
return relativeX * scale;
}
function clamp(value, min, max) {
return Math.max(min, Math.min(max, value));
}
function nearestStageIndexByAge(age) {
let idx = 0;
let minDelta = Number.POSITIVE_INFINITY;
for (let i = 0; i < swiper.stages.length; i += 1) {
const delta = Math.abs(swiper.stages[i].age - age);
if (delta < minDelta) {
minDelta = delta;
idx = i;
}
}
return idx;
}
function setupDragAndDrop() {
const startDrag = (clientX) => {
if (!markerElements) {
return;
}
isDragging = true;
markerElements.group.classList.add("dragging");
setChartActive(true);
moveDrag(clientX, true);
};
const moveDrag = (clientX, instantSlide) => {
const rawX = clientToSvgX(clientX);
const minX = ageToX(config.minAge);
const maxAgeForLine = getLineEndAge(currentLineSpeed);
const maxX = ageToX(maxAgeForLine);
const x = clamp(rawX, minX, maxX);
const age = config.minAge + ((x - minX) / (maxX - minX)) * (maxAgeForLine - config.minAge);
const gfr = gfrAtAge(currentLineSpeed, age);
updateMarker({ age, gfr }, { markerX: x });
currentStageIndex = nearestStageIndexByAge(age);
if (swiper.wrapper) {
swiper.wrapper.style.transition = instantSlide ? "none" : "transform 0.15s ease";
swiper.wrapper.style.transform = `translateX(-${currentStageIndex * 100}%)`;
}
updateButtons();
updateOverlayValues({ age, gfr }, true);
};
const endDrag = () => {
if (!isDragging || !markerElements) {
return;
}
isDragging = false;
markerElements.group.classList.remove("dragging");
setChartActive(false);
syncStageSlide(false);
};
const markerLayer = getMarkerLayerSvg();
markerLayer.addEventListener(
"mousedown",
(event) => {
if (!(event.target instanceof Element)) return;
if (!event.target.closest(".renal-marker-group")) return;
event.preventDefault();
startDrag(event.clientX);
},
{ signal: getEventSignal() }
);
window.addEventListener(
"mousemove",
(event) => {
if (!isDragging) return;
event.preventDefault();
moveDrag(event.clientX, false);
},
{ signal: getEventSignal() }
);
window.addEventListener("mouseup", endDrag, { signal: getEventSignal() });
markerLayer.addEventListener(
"touchstart",
(event) => {
if (!(event.target instanceof Element)) return;
if (!event.target.closest(".renal-marker-group")) return;
startDrag(event.touches[0].clientX);
},
{ passive: true, signal: getEventSignal() }
);
window.addEventListener(
"touchmove",
(event) => {
if (!isDragging) return;
moveDrag(event.touches[0].clientX, false);
},
{ passive: true, signal: getEventSignal() }
);
window.addEventListener("touchend", endDrag, { signal: getEventSignal() });
}
syncXAxisLabels();
const axesPath = svg.querySelector(".renal-axes");
if (axesPath) {
axesPath.setAttribute("d", `M ${config.chart.left} 443 L ${config.chart.left} 20 M ${config.chart.left} 443 L ${config.xAxis.max} 443`);
}
ensureChartStage();
ensureChartUiScaler();
insertInfoOverlay();
insertDragHint();
getMarkerLayerSvg();
setupDropdown();
setupStageControls();
setupDragAndDrop();
updateRenalUiScale();
requestAnimationFrame(updateRenalUiScale);
window.addEventListener("resize", scheduleRenalUiScaleUpdate);
if (typeof ResizeObserver !== "undefined") {
const uiResizeObserver = new ResizeObserver(scheduleRenalUiScaleUpdate);
uiResizeObserver.observe(ensureChartStage());
}
setActiveLine(currentLineSpeed);
kidneyAnimation.updateKidneys(gfrAtAge(currentLineSpeed, config.minAge), true);
renalChartRegistry.set(chartContainer, {
rebind: rebindInteractiveHandlers,
selectLine: (lineSpeed) => {
currentStageIndex = 0;
setActiveLine(lineSpeed);
dropdownMenu.classList.remove("active");
},
});
chartContainer.dataset.bayerRenalReady = "1";
}
// /renal-chart.js
</script><script type="text/javascript">
var playerElement = document.getElementById('player');
if (playerElement) {
var player = new Playerjs({
id: "player",
file: "https://aztxstu9hc.a.trbcdn.net/content/video_s_vospaleniem_i_fibrozom.mp4/playlist.m3u8",
design: 6
});
} else {
console.error('Элемент с id="player" не найден.');
}
// Обработчик кнопки "doread" / таймкодов
function playerseek(tim) {
var playerElement = document.getElementById('player');
if (playerElement) {
playerElement.scrollIntoView({ behavior: 'smooth' });
player.api('seek', tim);
} else {
console.error('Плеер не найден при попытке перемотки.');
}
}
</script>