« MediaWiki:Common.js » : différence entre les versions
Page de l’interface de MediaWiki
Autres actions
Aucun résumé des modifications |
Aucun résumé des modifications Balise : Révocation manuelle |
||
| (27 versions intermédiaires par le même utilisateur non affichées) | |||
| Ligne 1 : | Ligne 1 : | ||
// | // Forcer l'ouverture des sections hidden dans citizen qui les cachent par défaut | ||
function ouvrirSections() { | function ouvrirSections() { | ||
| Ligne 15 : | Ligne 15 : | ||
}); | }); | ||
/* Enlever le téléverser sur hamburger et empêcher les menus défilent */ | |||
function ouvrirSections() { | |||
document.querySelectorAll('.citizen-section').forEach(function (el) { | |||
el.removeAttribute('hidden'); | |||
}); | |||
var upload = document.getElementById('t-upload'); | |||
if (upload) upload.remove(); | |||
} | |||
// ============================================ | // ============================================ | ||
| Ligne 62 : | Ligne 68 : | ||
.calc-imc-info { border-left: 1px solid #e2e8f0; padding-left: 16px; font-size: 11px; color: #d97706; } | .calc-imc-info { border-left: 1px solid #e2e8f0; padding-left: 16px; font-size: 11px; color: #d97706; } | ||
@media (max-width: 600px) { .calc-grid { grid-template-columns: 1fr 1fr; } } | @media (max-width: 600px) { .calc-grid { grid-template-columns: 1fr 1fr; } } | ||
.vanco-header { background: linear-gradient(135deg, #7c3aed 0%, #9f67f5 100%); padding: 18px 22px; border-radius: 12px; color: white; margin-bottom: 16px; } | |||
.vanco-header h1 { margin: 0; font-size: 20px; font-weight: 700; } | |||
.vanco-header p { margin: 4px 0 0; font-size: 12px; opacity: 0.75; } | |||
.vanco-card { background: white; border-radius: 12px; padding: 20px 22px; margin-bottom: 14px; box-shadow: 0 2px 8px rgba(124,58,237,0.08); border: 1px solid #ede9fe; } | |||
.vanco-card h2 { margin: 0 0 14px; font-size: 15px; font-weight: 700; color: #5b21b6; } | |||
.vanco-section-title { font-size: 13px; font-weight: 700; color: #5b21b6; margin: 14px 0 8px; padding-bottom: 4px; border-bottom: 2px solid #ede9fe; } | |||
.vanco-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: 8px; } | |||
.vanco-table th { background: #ede9fe; padding: 8px 12px; text-align: left; font-weight: 700; color: #5b21b6; } | |||
.vanco-table td { padding: 9px 12px; border-bottom: 1px solid #f5f3ff; } | |||
.vanco-table tr.vanco-active { background: #f3e8ff !important; } | |||
.vanco-table tr.vanco-active td { color: #6d28d9; font-weight: 700; } | |||
.vanco-badge { background: #7c3aed; color: white; font-size: 10px; padding: 2px 6px; border-radius: 4px; margin-left: 6px; font-weight: 700; } | |||
.vanco-input-row { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; } | |||
.vanco-input-group { flex: 1; min-width: 120px; } | |||
.vanco-input-group label { font-size: 11px; color: #7c3aed; font-weight: 600; display: block; margin-bottom: 4px; } | |||
.vanco-input-group input { width: 100%; padding: 8px 10px; border-radius: 8px; border: 1.5px solid #ede9fe; font-size: 14px; color: #4c1d95; font-weight: 600; outline: none; } | |||
.vanco-result-box { background: #f3e8ff; border: 2px solid #c4b5fd; border-radius: 10px; padding: 14px 18px; margin-top: 12px; display: flex; gap: 24px; flex-wrap: wrap; align-items: flex-start; } | |||
.vanco-result-val { font-size: 26px; font-weight: 800; color: #6d28d9; line-height: 1; } | |||
.vanco-warning { background: #fef2f2; border: 1px solid #fecaca; border-radius: 10px; padding: 12px 16px; font-size: 11px; color: #991b1b; margin-top: 14px; } | |||
.vanco-note { background: #fefce8; border: 1px solid #fde68a; border-radius: 8px; padding: 10px 14px; font-size: 12px; color: #92400e; margin-bottom: 12px; } | |||
.vanco-tab-btns { display: flex; gap: 8px; margin-bottom: 16px; } | |||
.vanco-tab-btn { padding: 7px 18px; border-radius: 8px; border: 1.5px solid #ede9fe; background: white; color: #7c3aed; font-weight: 600; cursor: pointer; font-size: 13px; } | |||
.vanco-tab-btn.active { background: #7c3aed; border-color: #7c3aed; color: white; } | |||
.vanco-prelevement { background: #f5f3ff; border-radius: 10px; padding: 14px 18px; margin-top: 12px; font-size: 13px; } | |||
@media (max-width: 600px) { .vanco-input-row { flex-direction: column; } } | |||
`; | `; | ||
document.head.appendChild(style); | document.head.appendChild(style); | ||
| Ligne 374 : | Ligne 405 : | ||
var state = { | var state = { | ||
age: '', poids: '', taille: '', creat: '', sexe: 'H', | age: '', poids: '', taille: '', creat: '', sexe: 'H', | ||
selectedCat: '', selectedDrug: '', search: '' | selectedCat: '', selectedDrug: '', search: '', | ||
mode: 'cg', dfgDirect: '' | |||
}; | }; | ||
| Ligne 382 : | Ligne 414 : | ||
function getActiveDose(doses, clcr) { | function getActiveDose(doses, clcr) { | ||
var clcrRounded = Math.round(clcr * 10) / 10; | |||
for (var i = 0; i < doses.length; i++) { | for (var i = 0; i < doses.length; i++) { | ||
if ( | if (clcrRounded >= doses[i].min && clcrRounded <= doses[i].max) return i; | ||
} | |||
for (var i = doses.length - 1; i >= 0; i--) { | |||
if (clcrRounded >= doses[i].min) return i; | |||
} | } | ||
return doses.length - 1; | return doses.length - 1; | ||
} | } | ||
function | function calcClcrFromState() { | ||
var | if (state.mode === 'direct') { | ||
var dfg = parseFloat(state.dfgDirect); | |||
return { clcr: isNaN(dfg) ? null : dfg, imc: null, pi: null, poidsCalc: null }; | |||
} | |||
var age = parseFloat(state.age); | var age = parseFloat(state.age); | ||
var poids = parseFloat(state.poids); | var poids = parseFloat(state.poids); | ||
var taille = parseFloat(state.taille); | var taille = parseFloat(state.taille); | ||
var creat = parseFloat(state.creat); | var creat = parseFloat(state.creat); | ||
var imc = (!isNaN(poids) && !isNaN(taille)) ? calcIMC(poids, taille) : null; | var imc = (!isNaN(poids) && !isNaN(taille)) ? calcIMC(poids, taille) : null; | ||
var pi = (!isNaN(taille)) ? calcPI(taille, state.sexe) : null; | var pi = (!isNaN(taille)) ? calcPI(taille, state.sexe) : null; | ||
| Ligne 404 : | Ligne 440 : | ||
} | } | ||
var clcr = (!isNaN(age) && poidsCalc !== null && !isNaN(creat)) ? calcClcr(age, poidsCalc, creat, state.sexe) : null; | var clcr = (!isNaN(age) && poidsCalc !== null && !isNaN(creat)) ? calcClcr(age, poidsCalc, creat, state.sexe) : null; | ||
return { clcr: clcr, imc: imc, pi: pi, poidsCalc: poidsCalc }; | |||
} | |||
var clcrColor = '#64748b'; | function renderResult() { | ||
var res = calcClcrFromState(); | |||
var clcr = res.clcr; var imc = res.imc; var pi = res.pi; var poidsCalc = res.poidsCalc; | |||
var clcrColor = '#64748b'; var clcrLabel = ''; | |||
if (clcr !== null) { | if (clcr !== null) { | ||
if (clcr >= 60) { clcrColor = '#16a34a'; clcrLabel = 'Normale / légèrement réduite'; } | if (clcr >= 60) { clcrColor = '#16a34a'; clcrLabel = 'Normale / légèrement réduite'; } | ||
| Ligne 413 : | Ligne 453 : | ||
else { clcrColor = '#dc2626'; clcrLabel = 'IRC très sévère / terminale'; } | else { clcrColor = '#dc2626'; clcrLabel = 'IRC très sévère / terminale'; } | ||
} | } | ||
var box = document.getElementById('calc-result-box'); | |||
if (box) { | |||
if (clcr !== null) { | |||
var html = '<div>'; | |||
html += '<div style="font-size:11px;color:#64748b;font-weight:600">' + (state.mode === 'direct' ? 'DFG (LABORATOIRE)' : 'CLAIRANCE CRÉATININE') + '</div>'; | |||
html += '<div class="calc-clcr-val" style="color:' + clcrColor + '">' + clcr.toFixed(1) + ' <span style="font-size:14px;font-weight:500">mL/min</span></div>'; | |||
html += '<div class="calc-clcr-label" style="color:' + clcrColor + '">' + clcrLabel + '</div>'; | |||
html += '</div>'; | |||
if (imc !== null) { | |||
html += '<div class="calc-imc-info">'; | |||
html += '<div style="font-size:11px;color:#64748b;font-weight:600">IMC</div>'; | |||
html += '<div style="font-size:20px;font-weight:700;color:#0f2d5e">' + imc.toFixed(1) + ' <span style="font-size:11px">kg/m\u00b2</span></div>'; | |||
if (imc >= 30 && pi) { | |||
html += '<div>IMC \u2265 30 \u2014 Poids de dosage : <b>' + poidsCalc.toFixed(1) + ' kg</b><br>Poids id\u00e9al : ' + pi.toFixed(1) + ' kg</div>'; | |||
} | |||
html += '</div>'; | |||
} | |||
box.innerHTML = html; | |||
box.style.display = 'flex'; | |||
box.style.border = '2px solid ' + clcrColor + '33'; | |||
} else { | |||
box.innerHTML = ''; | |||
box.style.display = 'none'; | |||
} | |||
} | |||
var btnH = document.getElementById('calc-btn-h'); | |||
var btnF = document.getElementById('calc-btn-f'); | |||
if (btnH) btnH.className = 'calc-sexe-btn' + (state.sexe === 'H' ? ' active' : ''); | |||
if (btnF) btnF.className = 'calc-sexe-btn' + (state.sexe === 'F' ? ' active' : ''); | |||
renderDrugResult(clcr); | |||
} | |||
function renderDrugResult(clcr) { | |||
var drugData = getDrugData(state.selectedCat, state.selectedDrug); | |||
var section = document.getElementById('calc-drug-result'); | |||
if (!section) return; | |||
if (!state.selectedDrug || !drugData) { section.innerHTML = ''; return; } | |||
var html = '<div class="calc-card">'; | |||
html += '<h2>3. Posologie recommand\u00e9e</h2>'; | |||
html += '<div style="font-size:13px;color:#64748b;margin-bottom:14px">' + state.selectedDrug + '</div>'; | |||
if (drugData.notes) html += '<div class="calc-note">\u26a0\ufe0f ' + drugData.notes + '</div>'; | |||
html += '<table class="calc-table"><thead><tr><th>ClCr (mL/min)</th><th>Posologie</th></tr></thead><tbody>'; | |||
var activeIdx = clcr !== null ? getActiveDose(drugData.doses, clcr) : -1; | |||
drugData.doses.forEach(function(d, i) { | |||
var isActive = clcr !== null && i === activeIdx; | |||
var rangeLabel = d.max >= 999 ? '\u2265 ' + d.min : d.min === 0 ? '< ' + (drugData.doses.filter(function(x){return x.min>0;}).map(function(x){return x.min;}).sort(function(a,b){return a-b;})[0]||5) : d.min + ' \u2013 ' + d.max; | |||
html += '<tr' + (isActive ? ' class="active-row"' : ' style="background:' + (i%2===0?'white':'#f8fafc') + '"') + '>'; | |||
html += '<td style="font-weight:600;white-space:nowrap">' + (isActive ? '\u25b6 ' : '') + rangeLabel + '</td>'; | |||
html += '<td>' + d.label + (isActive ? '<span class="calc-badge">VOTRE PATIENT</span>' : '') + '</td>'; | |||
html += '</tr>'; | |||
}); | |||
html += '</tbody></table>'; | |||
if (clcr === null) html += '<div class="calc-hint">\ud83d\udca1 Entrez les donn\u00e9es du patient (\u00e9tape 1) pour mettre en \u00e9vidence la posologie appropri\u00e9e.</div>'; | |||
html += '</div>'; | |||
section.innerHTML = html; | |||
} | |||
function renderDrugSelector() { | |||
var searchResults = []; | var searchResults = []; | ||
if (state.search && state.search.length >= 2) { | if (state.search && state.search.length >= 2) { | ||
| Ligne 424 : | Ligne 520 : | ||
}); | }); | ||
} | } | ||
var sr = document.getElementById('calc-search-results'); | |||
if (sr) { | |||
var html = ''; | |||
searchResults.forEach(function(r) { | |||
html += '<button onclick="calcSelectDrug(\'' + r.cat.replace(/'/g, "\\'") + '\',\'' + r.drug.replace(/'/g, "\\'") + '\')">'; | |||
html += '<span style="color:#64748b;font-size:11px">' + r.cat + ' / </span>' + r.drug + '</button>'; | |||
}); | |||
sr.innerHTML = html; | |||
} | |||
var cats = document.getElementById('calc-cats'); | |||
if (cats) { | |||
var html = ''; | |||
Object.keys(ANTIBIOS).forEach(function(cat) { | |||
html += '<button class="calc-cat-btn ' + (state.selectedCat === cat ? 'active' : '') + '" onclick="calcSetCat(\'' + cat.replace(/'/g, "\\'") + '\')">' + cat + '</button>'; | |||
}); | |||
cats.innerHTML = html; | |||
} | |||
var drugs = document.getElementById('calc-drugs'); | |||
if (drugs) { | |||
var html = ''; | |||
if (state.selectedCat && ANTIBIOS[state.selectedCat]) { | |||
Object.keys(ANTIBIOS[state.selectedCat]).forEach(function(drug) { | |||
html += '<button class="calc-drug-btn ' + (state.selectedDrug === drug ? 'active' : '') + '" onclick="calcSetDrug(\'' + drug.replace(/'/g, "\\'") + '\')">' + drug + '</button>'; | |||
}); | |||
} | |||
drugs.innerHTML = html; | |||
} | |||
} | |||
var | function renderVanco() { | ||
var app = document.getElementById('vanco-app'); | |||
if (!app) return; | |||
var html = ''; | var html = ''; | ||
// Header | // Header violet | ||
html += '<div class=" | html += '<div class="vanco-header">'; | ||
html += '<h1> | html += '<h1>Vancomycine IV \u2014 Tableaux posologiques</h1>'; | ||
html += '<p> | html += '<p>Bas\u00e9 sur les lignes directrices APES \u2022 Adultes seulement</p>'; | ||
html += '</div>'; | html += '</div>'; | ||
// | // Explication | ||
html += '<div class=" | html += '<div class="vanco-card">'; | ||
html += '<h2> | html += '<h2>\ud83d\udcd6 Comment utiliser ces tableaux</h2>'; | ||
html += '< | html += '<ol style="font-size:13px;color:#374151;line-height:1.8;margin:0;padding-left:20px;">'; | ||
html += '< | html += '<li><b>Dose de charge (optionnelle) :</b> Trouver le poids du patient dans le tableau 1 \u2192 administrer la dose correspondante en IV \u00d7 1 seule fois. Recommand\u00e9e chez les patients gravement malades.</li>'; | ||
html += '< | html += '<li><b>Dose d\u2019entretien :</b> Trouver le poids dans le tableau 2 \u2192 c\u2019est la dose par administration.</li>'; | ||
html += '< | html += '<li><b>Fr\u00e9quence :</b> Utiliser le DFGe fourni par le laboratoire (mL/min/1,73m\u00b2) dans le tableau 2 \u2192 d\u00e9termine l\u2019intervalle entre les doses (q8h, q12h, q24h).</li>'; | ||
html += '<li><b>Pr\u00e9l\u00e8vements :</b> Consulter le tableau 3 selon la fr\u00e9quence choisie pour planifier le moment des pr\u00e9l\u00e8vements PIC et creux.</li>'; | |||
html += '<li><b>Ajustement :</b> Toujours ajuster selon les dosages s\u00e9riques obtenus. Consulter un pharmacien pour les cas complexes (IMC \u2265 30, insuffisance r\u00e9nale s\u00e9v\u00e8re, soins intensifs).</li>'; | |||
html += '</ol>'; | |||
html += '<div style="margin-top:12px;padding:10px 14px;background:#f0fdf4;border-radius:8px;font-size:12px;color:#166534;">'; | |||
html += '\ud83d\udca1 <b>Astuce :</b> Pour un calcul plus pr\u00e9cis de la dose d\u2019entretien (particulièrement si IMC \u2265 30), utiliser <b>vancopk.com</b>.'; | |||
html += '</div>'; | html += '</div>'; | ||
html += '</div>'; | html += '</div>'; | ||
// Tableau 1 — Dose de charge | |||
html += '<div class="vanco-card">'; | |||
html += '<h2>Tableau 1 \u2014 Dose de charge \u00d7 1 dose</h2>'; | |||
html += '<div style="font-size:12px;color:#64748b;margin-bottom:12px;">Calcul\u00e9e \u00e0 25 mg/kg de poids r\u00e9el. Non applicable aux usagers sous th\u00e9rapie de remplacement r\u00e9nal.</div>'; | |||
html += '<div style="overflow-x:auto;">'; | |||
html += '<table class="vanco-table"><thead><tr><th>Poids (kg)</th><th>Dose (mg)</th><th>Poids (kg)</th><th>Dose (mg)</th><th>Poids (kg)</th><th>Dose (mg)</th></tr></thead><tbody>'; | |||
html += '<tr><td>35 \u2013 39,9</td><td><b>750</b></td><td>60 \u2013 69,9</td><td><b>1500</b></td><td>90 \u2013 99,9</td><td><b>2250</b></td></tr>'; | |||
html += '<tr><td>40 \u2013 49,9</td><td><b>1000</b></td><td>70 \u2013 79,9</td><td><b>1750</b></td><td>100 \u2013 129,9</td><td><b>2500</b></td></tr>'; | |||
html += '<tr><td>50 \u2013 59,9</td><td><b>1250</b></td><td>80 \u2013 89,9</td><td><b>2000</b></td><td>130 et plus</td><td><b>3000</b></td></tr>'; | |||
html += '</tbody></table>'; | |||
html += '</div></div>'; | |||
// Tableau 2 — Entretien | |||
html += '<div class="vanco-card">'; | |||
html += '<h2>Tableau 2 \u2014 Traitement d\u2019entretien</h2>'; | |||
html += '<div style="font-size:12px;color:#64748b;margin-bottom:12px;">Croiser la dose selon le poids <b>ET</b> la fr\u00e9quence selon le DFGe du laboratoire.</div>'; | |||
html += '<div style="display:flex;gap:16px;flex-wrap:wrap;">'; | |||
html += '<div style="flex:1;min-width:180px;">'; | |||
html += '<div | html += '<div class="vanco-section-title">Dose selon le poids</div>'; | ||
html += '< | html += '<table class="vanco-table"><thead><tr><th>Poids (kg)</th><th>Dose / administration</th></tr></thead><tbody>'; | ||
html += '< | html += '<tr><td>35 \u2013 39,9</td><td><b>500 mg</b></td></tr>'; | ||
html += '<tr><td>40 \u2013 59,9</td><td><b>750 mg</b></td></tr>'; | |||
html += '<tr><td>60 \u2013 79,9</td><td><b>1000 mg</b></td></tr>'; | |||
html += '<tr><td>80 \u2013 99,9</td><td><b>1250 mg</b></td></tr>'; | |||
html += '<tr><td>100 et plus</td><td><b>1500 mg</b></td></tr>'; | |||
html += '</tbody></table></div>'; | |||
html += '<div style="flex:1;min-width:220px;">'; | |||
html += '<div class="vanco-section-title">Fr\u00e9quence selon le DFGe (mL/min/1,73m\u00b2)</div>'; | |||
html += '<table class="vanco-table"><thead><tr><th>DFGe</th><th>Fr\u00e9quence</th></tr></thead><tbody>'; | |||
html += '<tr><td>Plus de 90</td><td><b>q 8h</b></td></tr>'; | |||
html += '<tr><td>50 \u2013 90</td><td><b>q 12h</b></td></tr>'; | |||
html += '<tr><td>15 \u2013 49</td><td><b>q 24h</b></td></tr>'; | |||
html += '<tr><td>Moins de 15</td><td><b>Dose unique puis selon dosage</b></td></tr>'; | |||
html += '</tbody></table></div>'; | |||
html += '</div></div>'; | |||
html += '<div class=" | // Tableau 3 — Prélèvements | ||
html += '<div class="vanco-card">'; | |||
html += '<h2>Tableau 3 \u2014 Moment des pr\u00e9l\u00e8vements recommand\u00e9s</h2>'; | |||
html += '<div style="font-size:12px;color:#64748b;margin-bottom:12px;">Incluant la dose de charge s\u2019il y a lieu.</div>'; | |||
html += '<div style="overflow-x:auto;">'; | |||
html += '<table class="vanco-table"><thead><tr><th>Intervalle posologique</th><th>PIC</th><th>CREUX</th></tr></thead><tbody>'; | |||
html += '<tr><td style="font-weight:700;">q8h ou q12h</td><td>60 \u00e0 120 min post fin de perfusion de la <b>4\u1d49 dose</b></td><td>Juste avant la <b>4\u1d49 dose</b></td></tr>'; | |||
html += '<tr><td style="font-weight:700;">q24h</td><td>60 \u00e0 120 min post fin de perfusion de la <b>3\u1d49 dose</b></td><td>Juste avant la <b>3\u1d49 dose</b></td></tr>'; | |||
html += '</tbody></table>'; | |||
html += '</div>'; | html += '</div>'; | ||
html += '<div style="font-size:12px;color:#64748b;margin-top:10px;">Des pr\u00e9l\u00e8vements par <b>creux seulement</b> doivent \u00eatre effectu\u00e9s pour les patients dont l\u2019\u00e9tat d\u2019\u00e9quilibre n\u2019est pas atteint.</div>'; | |||
html += '</div>'; | html += '</div>'; | ||
// | // Avertissement | ||
html += '<div class="vanco-warning">\u26a0\ufe0f <b>Avertissement clinique :</b> Ces tableaux sont fournis \u00e0 titre de r\u00e9f\u00e9rence. Toujours ajuster selon les dosages s\u00e9riques. Consulter un pharmacien pour tout ajustement posologique de la vancomycine et se r\u00e9f\u00e9rer au guide APES (bulletin N\u00b0 40).</div>'; | |||
app.innerHTML = html; | |||
} | |||
function render() { | |||
var app = document.getElementById('calc-app'); | |||
if (!app) return; | |||
var html = ''; | |||
html += '<div class="calc-header">'; | |||
html += '<h1>Calculateur posologique \u2014 Insuffisance r\u00e9nale</h1>'; | |||
html += '<p>Bas\u00e9 sur le guide APES (RPEI) \u2014 Octobre 2019 \u2022 Adultes seulement \u2022 Le jugement clinique doit pr\u00e9valoir</p>'; | |||
html += '</div>'; | |||
html += '<div class="calc-card">'; | |||
html += '<h2>1. Fonction r\u00e9nale</h2>'; | |||
} | html += '<div style="display:flex;gap:8px;margin-bottom:16px;">'; | ||
html += '<button id="calc-btn-cg" class="calc-sexe-btn ' + (state.mode === 'cg' ? 'active' : '') + '" onclick="calcSetMode(\'cg\')">Calculer (Cockcroft-Gault)</button>'; | |||
html += '<button id="calc-btn-direct" class="calc-sexe-btn ' + (state.mode === 'direct' ? 'active' : '') + '" onclick="calcSetMode(\'direct\')">DFG d\u00e9j\u00e0 connu</button>'; | |||
html += '</div>'; | |||
if (state.mode === 'cg') { | |||
html += '<div style="margin-bottom:12px;display:flex;align-items:center;gap:8px;">'; | |||
html += '<span style="font-size:13px;color:#64748b;width:50px">Sexe</span>'; | |||
html += '<button id="calc-btn-h" class="calc-sexe-btn ' + (state.sexe === 'H' ? 'active' : '') + '" onclick="calcSetSexe(\'H\')">Homme</button>'; | |||
html += '<button id="calc-btn-f" class="calc-sexe-btn ' + (state.sexe === 'F' ? 'active' : '') + '" onclick="calcSetSexe(\'F\')">Femme</button>'; | |||
html += '</div>'; | |||
html += '<div class="calc-grid">'; | |||
html += '<div><label>\u00c2ge (ans)</label><input id="calc-age" type="number" placeholder="ex: 65" oninput="calcSetField(\'age\',this.value)"></div>'; | |||
html += '<div><label>Poids r\u00e9el (kg)</label><input id="calc-poids" type="number" placeholder="ex: 70" oninput="calcSetField(\'poids\',this.value)"></div>'; | |||
html += '<div><label>Taille (cm)</label><input id="calc-taille" type="number" placeholder="ex: 170" oninput="calcSetField(\'taille\',this.value)"></div>'; | |||
html += '<div><label>Cr\u00e9atinine (\u03bcmol/L)</label><input id="calc-creat" type="number" placeholder="ex: 120" oninput="calcSetField(\'creat\',this.value)"></div>'; | |||
html += '</div>'; | |||
} else { | |||
html += '<div style="max-width:250px;">'; | |||
html += '<label style="font-size:11px;color:#64748b;font-weight:600;display:block;margin-bottom:4px;">DFG / ClCr (mL/min)</label>'; | |||
html += '<input id="calc-dfg-direct" type="number" placeholder="ex: 45" style="width:100%;padding:10px 14px;border-radius:8px;border:1.5px solid #e2e8f0;font-size:18px;font-weight:700;color:#0f2d5e;outline:none;" oninput="calcSetField(\'dfgDirect\',this.value)">'; | |||
html += '<div style="font-size:11px;color:#64748b;margin-top:6px;">Valeur fournie par le laboratoire</div>'; | |||
html += '</div>'; | html += '</div>'; | ||
} | } | ||
html += '<div id="calc-result-box" class="calc-result-box" style="display:none"></div>'; | |||
html += '</div>'; | |||
// | html += '<div class="calc-card">'; | ||
html += '<div class="calc-warning"> | html += '<h2>2. S\u00e9lection de l\'antimicrobien</h2>'; | ||
html += '<input id="calc-search-input" class="calc-search" type="text" placeholder="\ud83d\udd0d Rechercher un antimicrobien..." oninput="calcSetSearch(this.value)">'; | |||
html += '<div id="calc-search-results" class="calc-search-results"></div>'; | |||
html += '<div id="calc-cats" class="calc-cats"></div>'; | |||
html += '<div id="calc-drugs" class="calc-drugs"></div>'; | |||
html += '</div>'; | |||
html += '<div id="calc-drug-result"></div>'; | |||
html += '<div class="calc-warning">\u26a0\ufe0f <b>Avertissement clinique :</b> Cet outil est bas\u00e9 sur le guide APES (RPEI, octobre 2019). Les ajustements servent uniquement \u00e0 guider la d\u00e9cision clinique \u2014 le jugement clinique doit pr\u00e9valoir. Consulter un pharmacien pour les cas complexes.</div>'; | |||
html += '<div id="vanco-app" style="margin-top:24px;"></div>'; | |||
app.innerHTML = html; | app.innerHTML = html; | ||
renderResult(); | |||
renderDrugSelector(); | |||
renderVanco(); | |||
} | } | ||
window. | window.calcSetMode = function(mode) { state.mode = mode; render(); }; | ||
window.calcSetField = function(field, val) { state[field] = val; renderResult(); }; | |||
window.calcSetSexe = function(sexe) { state.sexe = sexe; renderResult(); }; | |||
window.calcSetSearch = function(val) { state.search = val; state.selectedCat = ''; state.selectedDrug = ''; renderDrugSelector(); renderDrugResult(calcClcrFromState().clcr); }; | |||
window.calcSetCat = function(cat) { state.selectedCat = cat; state.selectedDrug = ''; renderDrugSelector(); renderDrugResult(calcClcrFromState().clcr); }; | |||
window.calcSetDrug = function(drug) { state.selectedDrug = drug; renderDrugSelector(); renderDrugResult(calcClcrFromState().clcr); }; | |||
window.calcSelectDrug = function(cat, drug) { state.selectedCat = cat; state.selectedDrug = drug; state.search = ''; var si = document.getElementById('calc-search-input'); if(si) si.value=''; renderDrugSelector(); renderDrugResult(calcClcrFromState().clcr); }; | |||
window.calcSetSexe = function(sexe) { state.sexe = sexe; | |||
window.calcSetSearch = function(val) { state.search = val; state.selectedCat = ''; state.selectedDrug = ''; | |||
window.calcSetCat = function(cat) { state.selectedCat = cat; state.selectedDrug = ''; | |||
window.calcSetDrug = function(drug) { state.selectedDrug = drug; | |||
window.calcSelectDrug = function(cat, drug) { state.selectedCat = cat; state.selectedDrug = drug; state.search = ''; | |||
if (document.readyState === 'loading') { | if (document.readyState === 'loading') { | ||
Dernière version du 31 mars 2026 à 07:49
// Forcer l'ouverture des sections hidden dans citizen qui les cachent par défaut
function ouvrirSections() {
document.querySelectorAll('.citizen-section').forEach(function (el) {
el.removeAttribute('hidden');
});
}
document.addEventListener('DOMContentLoaded', ouvrirSections);
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
ouvrirSections();
}
});
/* Enlever le téléverser sur hamburger et empêcher les menus défilent */
function ouvrirSections() {
document.querySelectorAll('.citizen-section').forEach(function (el) {
el.removeAttribute('hidden');
});
var upload = document.getElementById('t-upload');
if (upload) upload.remove();
}
// ============================================
// CALCULATEUR IRC — Microguide
// ============================================
if (mw.config.get('wgPageName') === 'Calculateur') {
var style = document.createElement('style');
style.textContent = `
#calc-app * { box-sizing: border-box; font-family: 'Segoe UI', system-ui, sans-serif; }
#calc-app { background: #f0f4f8; padding: 16px; border-radius: 12px; }
.calc-header { background: linear-gradient(135deg, #1a5fa8 0%, #2980d4 100%); padding: 18px 22px; border-radius: 12px; color: white; margin-bottom: 16px; }
.calc-header h1 { margin: 0; font-size: 20px; font-weight: 700; }
.calc-header p { margin: 4px 0 0; font-size: 12px; opacity: 0.75; }
.calc-card { background: white; border-radius: 12px; padding: 20px 22px; margin-bottom: 14px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); border: 1px solid #e2e8f0; }
.calc-card h2 { margin: 0 0 14px; font-size: 15px; font-weight: 700; color: #0f2d5e; }
.calc-grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 10px; margin-bottom: 12px; }
.calc-grid label { font-size: 11px; color: #64748b; font-weight: 600; display: block; margin-bottom: 4px; }
.calc-grid input { width: 100%; padding: 8px 10px; border-radius: 8px; border: 1.5px solid #e2e8f0; font-size: 14px; color: #0f2d5e; font-weight: 600; outline: none; }
.calc-sexe-btn { padding: 6px 18px; border-radius: 8px; border: 1.5px solid #e2e8f0; background: white; color: #64748b; font-weight: 600; cursor: pointer; font-size: 13px; margin-right: 8px; }
.calc-sexe-btn.active { border-color: #0f2d5e; background: #0f2d5e; color: white; }
.calc-result-box { background: #f8fafc; border-radius: 10px; padding: 14px 18px; display: flex; align-items: center; gap: 20px; flex-wrap: wrap; margin-top: 10px; }
.calc-clcr-val { font-size: 32px; font-weight: 800; line-height: 1; }
.calc-clcr-label { font-size: 12px; font-weight: 600; margin-top: 2px; }
.calc-search { width: 100%; padding: 10px 14px; border-radius: 10px; border: 1.5px solid #e2e8f0; font-size: 14px; margin-bottom: 10px; outline: none; }
.calc-cats { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.calc-cat-btn { padding: 6px 14px; border-radius: 20px; border: 1.5px solid #e2e8f0; background: white; color: #475569; font-weight: 600; cursor: pointer; font-size: 12px; }
.calc-cat-btn.active { border-color: #0f2d5e; background: #0f2d5e; color: white; }
.calc-drugs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.calc-drug-btn { padding: 6px 12px; border-radius: 8px; border: 1.5px solid #e2e8f0; background: white; color: #475569; font-weight: 500; cursor: pointer; font-size: 12px; }
.calc-drug-btn.active { border-color: #1a9d8f; background: #e8f6f4; color: #0f7a6e; font-weight: 700; }
.calc-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: 10px; }
.calc-table th { background: #f1f5f9; padding: 8px 12px; text-align: left; font-weight: 700; color: #0f2d5e; }
.calc-table td { padding: 10px 12px; border-bottom: 1px solid #f1f5f9; }
.calc-table tr.active-row { background: #e8f4f0 !important; outline: 2px solid #1a9d8f; }
.calc-table tr.active-row td { color: #0a5a52; font-weight: 700; }
.calc-badge { background: #1a9d8f; color: white; font-size: 10px; padding: 2px 6px; border-radius: 4px; margin-left: 8px; font-weight: 700; }
.calc-note { background: #fefce8; border: 1px solid #fde68a; border-radius: 8px; padding: 10px 14px; font-size: 12px; color: #92400e; margin-bottom: 12px; }
.calc-warning { background: #fef2f2; border: 1px solid #fecaca; border-radius: 10px; padding: 12px 16px; font-size: 11px; color: #991b1b; margin-top: 14px; }
.calc-search-results button { display: block; width: 100%; text-align: left; padding: 8px 12px; margin-bottom: 4px; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 8px; cursor: pointer; font-size: 13px; color: #0f2d5e; }
.calc-hint { margin-top: 12px; padding: 10px 14px; background: #f0f9ff; border-radius: 8px; font-size: 12px; color: #0369a1; }
.calc-imc-info { border-left: 1px solid #e2e8f0; padding-left: 16px; font-size: 11px; color: #d97706; }
@media (max-width: 600px) { .calc-grid { grid-template-columns: 1fr 1fr; } }
.vanco-header { background: linear-gradient(135deg, #7c3aed 0%, #9f67f5 100%); padding: 18px 22px; border-radius: 12px; color: white; margin-bottom: 16px; }
.vanco-header h1 { margin: 0; font-size: 20px; font-weight: 700; }
.vanco-header p { margin: 4px 0 0; font-size: 12px; opacity: 0.75; }
.vanco-card { background: white; border-radius: 12px; padding: 20px 22px; margin-bottom: 14px; box-shadow: 0 2px 8px rgba(124,58,237,0.08); border: 1px solid #ede9fe; }
.vanco-card h2 { margin: 0 0 14px; font-size: 15px; font-weight: 700; color: #5b21b6; }
.vanco-section-title { font-size: 13px; font-weight: 700; color: #5b21b6; margin: 14px 0 8px; padding-bottom: 4px; border-bottom: 2px solid #ede9fe; }
.vanco-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: 8px; }
.vanco-table th { background: #ede9fe; padding: 8px 12px; text-align: left; font-weight: 700; color: #5b21b6; }
.vanco-table td { padding: 9px 12px; border-bottom: 1px solid #f5f3ff; }
.vanco-table tr.vanco-active { background: #f3e8ff !important; }
.vanco-table tr.vanco-active td { color: #6d28d9; font-weight: 700; }
.vanco-badge { background: #7c3aed; color: white; font-size: 10px; padding: 2px 6px; border-radius: 4px; margin-left: 6px; font-weight: 700; }
.vanco-input-row { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.vanco-input-group { flex: 1; min-width: 120px; }
.vanco-input-group label { font-size: 11px; color: #7c3aed; font-weight: 600; display: block; margin-bottom: 4px; }
.vanco-input-group input { width: 100%; padding: 8px 10px; border-radius: 8px; border: 1.5px solid #ede9fe; font-size: 14px; color: #4c1d95; font-weight: 600; outline: none; }
.vanco-result-box { background: #f3e8ff; border: 2px solid #c4b5fd; border-radius: 10px; padding: 14px 18px; margin-top: 12px; display: flex; gap: 24px; flex-wrap: wrap; align-items: flex-start; }
.vanco-result-val { font-size: 26px; font-weight: 800; color: #6d28d9; line-height: 1; }
.vanco-warning { background: #fef2f2; border: 1px solid #fecaca; border-radius: 10px; padding: 12px 16px; font-size: 11px; color: #991b1b; margin-top: 14px; }
.vanco-note { background: #fefce8; border: 1px solid #fde68a; border-radius: 8px; padding: 10px 14px; font-size: 12px; color: #92400e; margin-bottom: 12px; }
.vanco-tab-btns { display: flex; gap: 8px; margin-bottom: 16px; }
.vanco-tab-btn { padding: 7px 18px; border-radius: 8px; border: 1.5px solid #ede9fe; background: white; color: #7c3aed; font-weight: 600; cursor: pointer; font-size: 13px; }
.vanco-tab-btn.active { background: #7c3aed; border-color: #7c3aed; color: white; }
.vanco-prelevement { background: #f5f3ff; border-radius: 10px; padding: 14px 18px; margin-top: 12px; font-size: 13px; }
@media (max-width: 600px) { .vanco-input-row { flex-direction: column; } }
`;
document.head.appendChild(style);
var ANTIBIOS = {
"Céphalosporines": {
"Céfadroxil (PO)": { notes: "", doses: [
{ min: 30, max: 999, label: "500 mg PO q12h ou 1g PO q12-24h" },
{ min: 20, max: 29, label: "1g PO x1 dose puis 500 mg PO q12h" },
{ min: 10, max: 19, label: "1g PO x1 dose puis 500 mg PO q24h" },
{ min: 0, max: 9, label: "1g PO x1 dose puis 500 mg PO q24-36h" },
]},
"Céfazoline (IV)": { notes: "", doses: [
{ min: 35, max: 999, label: "1-2g IV q8h (fréq. max. q6h)" },
{ min: 11, max: 34, label: "1-2g IV q12h" },
{ min: 0, max: 10, label: "1g IV q24h" },
]},
"Céfépime (IV) — IIA/IU": { notes: "Infections intra-abdominales et urinaires", doses: [
{ min: 30, max: 999, label: "1-2g IV q12h" },
{ min: 11, max: 29, label: "1-2g IV q24h" },
{ min: 6, max: 10, label: "1g IV q24h" },
{ min: 0, max: 5, label: "500 mg IV q24h" },
]},
"Céfépime (IV) — NF": { notes: "Neutropénie fébrile", doses: [
{ min: 30, max: 999, label: "2g IV q8h" },
{ min: 11, max: 29, label: "2g IV q12h" },
{ min: 6, max: 10, label: "2g IV q24h" },
{ min: 0, max: 5, label: "1g IV q24h" },
]},
"Céfixime (PO)": { notes: "", doses: [
{ min: 21, max: 999, label: "400 mg PO q24h" },
{ min: 11, max: 20, label: "300 mg (¾ co.) PO q24h" },
{ min: 0, max: 10, label: "200 mg PO q24h" },
]},
"Céfotaxime (IV)": { notes: "", doses: [
{ min: 21, max: 999, label: "1-2g IV q6-8h (jusqu'à 2g IV q4h si SNC)" },
{ min: 0, max: 20, label: "Diminuer la dose de 50%. Certains: 2g IV q12-24h" },
]},
"Céfoxitine (IV)": { notes: "Dose max: 12g/jour", doses: [
{ min: 30, max: 999, label: "1-2g IV q6-8h" },
{ min: 11, max: 29, label: "1-2g IV q8-12h" },
{ min: 5, max: 10, label: "1-2g IV q12-24h" },
{ min: 1, max: 4, label: "50% de la dose IV q12-24h" },
{ min: 0, max: 0, label: "50% de la dose IV q24-48h" },
]},
"Cefprozil (PO)": { notes: "", doses: [
{ min: 31, max: 999, label: "250-500 mg PO q12h" },
{ min: 0, max: 30, label: "250 mg PO q12h" },
]},
"Ceftazidime (IV)": { notes: "", doses: [
{ min: 31, max: 999, label: "1-2g IV q8h" },
{ min: 16, max: 30, label: "1-2g IV q12h" },
{ min: 6, max: 15, label: "1-2g IV q24h" },
{ min: 1, max: 5, label: "500mg-1g IV q24h" },
{ min: 0, max: 0, label: "500mg-1g IV q48h" },
]},
"Ceftobiprole (IV)": { notes: "Perfusion sur 4h si Clcr > 150 mL/min", doses: [
{ min: 31, max: 999, label: "500 mg IV q8h perf. sur 2h" },
{ min: 16, max: 30, label: "500 mg IV q12h perf. sur 2h" },
{ min: 6, max: 15, label: "250 mg IV q12h perf. sur 2h" },
{ min: 0, max: 5, label: "250 mg IV q24h perf. sur 2h" },
]},
"Ceftriaxone (IV)": { notes: "Aucun ajustement requis sauf IR + IH (dose max: 2g/jour)", doses: [
{ min: 0, max: 999, label: "1-2g IV q24h (max: 2g IV q12h pour SNC)" },
]},
"Céfuroxime axétil (PO)": { notes: "", doses: [
{ min: 11, max: 999, label: "250-500 mg PO q12h" },
{ min: 0, max: 10, label: "250 mg PO q24h" },
]},
"Céfuroxime (IV)": { notes: "", doses: [
{ min: 21, max: 999, label: "750mg-1,5g IV q8h" },
{ min: 11, max: 20, label: "750 mg IV q12h" },
{ min: 0, max: 10, label: "750 mg IV q24h" },
]},
"Céphalexine (PO)": { notes: "", doses: [
{ min: 41, max: 999, label: "250mg-1g PO q6h" },
{ min: 11, max: 40, label: "250-500 mg PO q8-12h" },
{ min: 0, max: 10, label: "250-500 mg PO q12-24h" },
]},
},
"Carbapénèmes": {
"Ertapénem (IV)": { notes: "", doses: [
{ min: 31, max: 999, label: "1g IV q24h" },
{ min: 0, max: 30, label: "500 mg IV q24h" },
]},
"Imipénem-Cilastatine (IV)": { notes: "PR ≥ 70 kg: 500 mg IV q6h (max 4g/jour). PR < 70 kg: voir monographie.", doses: [
{ min: 71, max: 999, label: "500 mg IV q6h (max: 4g/jour)" },
{ min: 41, max: 70, label: "500 mg IV q6-8h" },
{ min: 21, max: 40, label: "500 mg IV q8-12h" },
{ min: 6, max: 20, label: "250 mg IV q12h" },
{ min: 0, max: 5, label: "⚠️ Non recommandé" },
]},
"Méropénem (IV) — usuel": { notes: "Posologie usuelle", doses: [
{ min: 26, max: 999, label: "1g IV q8h" },
{ min: 11, max: 25, label: "1g IV q12h" },
{ min: 6, max: 10, label: "500 mg IV q12h" },
{ min: 0, max: 5, label: "500 mg IV q24h" },
]},
"Méropénem (IV) — SNC": { notes: "Infections du SNC", doses: [
{ min: 26, max: 999, label: "2g IV q8h" },
{ min: 11, max: 25, label: "2g IV q12h" },
{ min: 6, max: 10, label: "1g IV q12h" },
{ min: 0, max: 5, label: "1g IV q24h" },
]},
},
"Macrolides": {
"Azithromycine (PO)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "250-500 mg PO q24h" }]},
"Azithromycine (IV)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "500 mg IV q24h" }]},
"Clarithromycine (PO)": { notes: "", doses: [
{ min: 31, max: 999, label: "250-500 mg PO q12h" },
{ min: 0, max: 30, label: "250 mg PO q24h (ou q12h si infection sévère)" },
]},
"Érythromycine (PO/IV)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "Posologie selon indication et formulation" }]},
},
"Pénicillines": {
"Amoxicilline (PO)": { notes: "", doses: [
{ min: 31, max: 999, label: "250mg-1g PO q8h" },
{ min: 11, max: 30, label: "250-500 mg PO q12h" },
{ min: 0, max: 10, label: "250-500 mg PO q24h" },
]},
"Amoxicilline-Clavulanate (PO)": { notes: "", doses: [
{ min: 31, max: 999, label: "500/125 mg PO q8h ou 875/125 mg PO q12h" },
{ min: 11, max: 30, label: "500/125 mg PO q12h" },
{ min: 0, max: 10, label: "500/125 mg PO q24h" },
]},
"Ampicilline (IV)": { notes: "Posologie usuelle: 1-2g IV q4-6h", doses: [
{ min: 41, max: 999, label: "1-2g IV q6h" },
{ min: 31, max: 40, label: "1-2g IV q6-8h" },
{ min: 16, max: 30, label: "1-2g IV q8-12h" },
{ min: 0, max: 15, label: "1-2g IV q12-24h" },
]},
"Cloxacilline (PO)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "250-500 mg PO q6h (jusqu'à 4g/jour)" }]},
"Cloxacilline (IV)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "1-2g IV q4-6h" }]},
"Pénicilline G sodique (IV)": { notes: "DC = dose de charge", doses: [
{ min: 21, max: 999, label: "1-4 mU IV q4-6h" },
{ min: 11, max: 20, label: "DC suivie de 50% de la dose IV q4-6h" },
{ min: 0, max: 10, label: "DC suivie de 50% de la dose IV q8-12h" },
]},
"Pipéracilline-Tazobactam (IV) — usuel": { notes: "Posologie usuelle", doses: [
{ min: 41, max: 999, label: "3,375g [3g/0,375g] IV q6h ou 4,5g [4g/0,5g] IV q8h" },
{ min: 21, max: 40, label: "2,25g [2g/0,25g] IV q6h" },
{ min: 0, max: 20, label: "2,25g [2g/0,25g] IV q8h" },
]},
"Pipéracilline-Tazobactam (IV) — PAH/NF": { notes: "Pneumonie hospitalière ou neutropénie fébrile", doses: [
{ min: 41, max: 999, label: "4,5g [4g/0,5g] IV q6h" },
{ min: 21, max: 40, label: "3,375g [3g/0,375g] IV q6h" },
{ min: 0, max: 20, label: "2,25g [2g/0,25g] IV q6h" },
]},
},
"Fluoroquinolones": {
"Ciprofloxacine (PO)": { notes: "", doses: [
{ min: 31, max: 999, label: "500-750 mg PO q12h" },
{ min: 16, max: 30, label: "500 mg PO q12h" },
{ min: 0, max: 15, label: "500 mg PO q24h ou 250 mg PO q12h" },
]},
"Ciprofloxacine (IV)": { notes: "", doses: [
{ min: 31, max: 999, label: "400 mg IV q8-12h" },
{ min: 16, max: 30, label: "400 mg IV q12h" },
{ min: 0, max: 15, label: "400 mg IV q24h ou 200 mg IV q12h" },
]},
"Lévofloxacine — légère/prostatite": { notes: "Ex: prostatite chronique", doses: [
{ min: 51, max: 999, label: "500 mg PO/IV q24h" },
{ min: 21, max: 50, label: "500 mg PO/IV x1 dose, puis 250 mg PO/IV q24h" },
{ min: 0, max: 20, label: "500 mg PO/IV x1 dose, puis 250 mg PO/IV q48h" },
]},
"Lévofloxacine — PAH": { notes: "Pneumonie hospitalière", doses: [
{ min: 51, max: 999, label: "750 mg PO/IV q24h" },
{ min: 21, max: 50, label: "750 mg PO/IV q48h" },
{ min: 0, max: 20, label: "750 mg PO/IV x1 dose, puis 500 mg PO/IV q48h" },
]},
"Moxifloxacine (PO/IV)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "400 mg PO/IV q24h" }]},
"Norfloxacine (PO) — IU": { notes: "Infection urinaire", doses: [
{ min: 31, max: 999, label: "400 mg PO q12-24h" },
{ min: 0, max: 30, label: "400 mg PO q24h" },
]},
},
"Autres antibactériens": {
"Clindamycine (PO)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "150-450 mg PO q6h" }]},
"Clindamycine (IV)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "600-900 mg IV q8h (fréq. max.: q6h)" }]},
"Daptomycine (IV) — usuelle": { notes: "Pour dose 6 mg/kg: utiliser PD si PR > 140 kg", doses: [
{ min: 31, max: 999, label: "4-6 mg/kg PR IV q24h" },
{ min: 0, max: 30, label: "Même dose IV q48h" },
]},
"Doxycycline (PO)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "100 mg PO q12h" }]},
"Linézolide (PO/IV)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "600 mg PO/IV q12h" }]},
"Métronidazole (PO)": { notes: "", doses: [
{ min: 11, max: 999, label: "250-500 mg PO q8h ou 500 mg PO q12h" },
{ min: 0, max: 10, label: "500 mg PO q12h" },
]},
"Métronidazole (IV)": { notes: "", doses: [
{ min: 11, max: 999, label: "500 mg IV q8h (fréq. max.: q6h)" },
{ min: 0, max: 10, label: "500 mg IV q12h" },
]},
"Nitrofurantoïne (PO)": { notes: "Cystite non compliquée uniquement", doses: [
{ min: 46, max: 999, label: "50-100 mg PO QID ou 100 mg PO q12h (monohydrate)" },
{ min: 31, max: 45, label: "Données limitées. Possiblement efficace à court terme." },
{ min: 0, max: 30, label: "⚠️ Contre-indiqué — risque de toxicité accru" },
]},
"Tétracycline (PO)": { notes: "", doses: [
{ min: 51, max: 999, label: "250-500 mg PO q6h" },
{ min: 11, max: 50, label: "250-500 mg PO q12h" },
{ min: 0, max: 10, label: "250-500 mg PO q24h" },
]},
"Tigécycline (IV)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "100 mg IV x1 dose puis 50 mg IV q12h" }]},
"Triméthoprime (PO)": { notes: "", doses: [
{ min: 16, max: 999, label: "100 mg PO q12h" },
{ min: 6, max: 15, label: "50 mg PO q12h" },
{ min: 0, max: 5, label: "⚠️ Non recommandé" },
]},
"TMP-SMX — usuel": { notes: "80 mg TMP = 1 co SS; 160 mg TMP = 1 co DS", doses: [
{ min: 31, max: 999, label: "160-320 mg TMP PO/IV q12h" },
{ min: 16, max: 30, label: "80 mg TMP PO/IV q12h ou 160 mg TMP PO/IV q24h" },
{ min: 0, max: 15, label: "⚠️ Non recommandé" },
]},
"Vancomycine (IV)": { notes: "⚠️ Amorcer empiriquement selon âge, fonction rénale et poids puis ajuster selon dosages sériques. DC = 25 mg/kg PR. DM: 15-20 mg/kg PD/dose q8-12h (max 2g/dose). Consulter pharmacien.", doses: [
{ min: 71, max: 999, label: "DM IV q12h — surveiller dosages sériques" },
{ min: 41, max: 70, label: "DM IV q24h — surveiller dosages sériques" },
{ min: 21, max: 40, label: "DM IV q36-48h — dosages sériques quotidiens" },
{ min: 11, max: 20, label: "DM IV q72-96h" },
{ min: 0, max: 10, label: "DM IV q5-7 jours — consulter pharmacien" },
]},
"Vancomycine (PO)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "125 mg PO QID (max 500 mg PO QID si infection compliquée)" }]},
},
"Antifongiques": {
"Anidulafungine (IV)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "200 mg IV x1 dose puis 100 mg IV q24h" }]},
"Caspofungine (IV)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "70 mg IV x1 dose puis 50 mg IV q24h" }]},
"Fluconazole (PO/IV)": { notes: "DC = 100% de la dose. Écart: 100-800 mg PO/IV q24h", doses: [
{ min: 51, max: 999, label: "DC puis 100% dose PO/IV q24h" },
{ min: 11, max: 50, label: "DC puis 50% de la dose PO/IV q24h" },
{ min: 0, max: 10, label: "DC puis 25-50% de la dose PO/IV q24h" },
]},
"Isavuconazole (PO/IV)": { notes: "Aucun ajustement requis. 372 mg sulfate = 200 mg isavuconazole.", doses: [{ min: 0, max: 999, label: "DC: 200 mg PO/IV q8h x6 doses, puis 200 mg PO/IV q24h" }]},
"Kétoconazole (PO)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "200-400 mg PO q24h" }]},
"Micafungine — prophylaxie": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "50-100 mg IV q24h" }]},
"Micafungine — traitement": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "100-150 mg IV q24h" }]},
"Terbinafine (PO)": { notes: "", doses: [
{ min: 51, max: 999, label: "250 mg PO q24h" },
{ min: 0, max: 50, label: "⚠️ Non recommandé — données limitées" },
]},
},
"Antimycobactériens": {
"Ethambutol (PO)": { notes: "Si PR > 120% PI, baser dose sur PI.", doses: [
{ min: 31, max: 999, label: "15-25 mg/kg PO q24h" },
{ min: 0, max: 30, label: "15-25 mg/kg/dose PO DIE 3 jours/semaine" },
]},
"Isoniazide (PO)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "5 mg/kg PO q24h (max: 300 mg)" }]},
"Pyrazinamide (PO)": { notes: "Si PR > 120% PI, baser dose sur PI.", doses: [
{ min: 31, max: 999, label: "20-25 mg/kg PO q24h (max: 2g)" },
{ min: 0, max: 30, label: "25-35 mg/kg/dose PO DIE 3 jours/semaine" },
]},
"Rifabutine (PO)": { notes: "", doses: [
{ min: 16, max: 999, label: "300 mg PO q24h" },
{ min: 0, max: 15, label: "150 mg PO q24h" },
]},
"Rifampicine (PO)": { notes: "Aucun ajustement requis", doses: [{ min: 0, max: 999, label: "10 mg/kg PO q24h (max: 600 mg)" }]},
},
"Antiviraux": {
"Acyclovir (IV)": { notes: "Posologie usuelle: 5-15 mg/kg/dose IV q8h", doses: [
{ min: 26, max: 999, label: "100% de la dose IV q8h" },
{ min: 11, max: 25, label: "100% de la dose IV q12h" },
{ min: 6, max: 10, label: "100% de la dose IV q24h" },
{ min: 0, max: 5, label: "50% de la dose IV q24h" },
]},
"Acyclovir (PO) — zona": { notes: "", doses: [
{ min: 26, max: 999, label: "800 mg PO q4h (5 fois/jour)" },
{ min: 11, max: 25, label: "800 mg PO q8h" },
{ min: 0, max: 10, label: "800 mg PO q12h" },
]},
"Famciclovir (PO) — zona": { notes: "", doses: [
{ min: 41, max: 999, label: "500 mg PO q8h" },
{ min: 21, max: 40, label: "500 mg PO q12h" },
{ min: 6, max: 20, label: "500 mg PO q24h" },
{ min: 0, max: 5, label: "250 mg PO q24h" },
]},
"Oseltamivir (PO) — traitement": { notes: "Influenza A et B", doses: [
{ min: 31, max: 999, label: "75 mg PO q12h" },
{ min: 11, max: 30, label: "30 mg PO q12h" },
{ min: 6, max: 10, label: "30 mg PO q24h" },
{ min: 0, max: 5, label: "75 mg PO x1 dose" },
]},
"Oseltamivir (PO) — prophylaxie": { notes: "Prophylaxie Influenza A et B", doses: [
{ min: 31, max: 999, label: "75 mg PO q24h" },
{ min: 11, max: 30, label: "30 mg PO q24h" },
{ min: 6, max: 10, label: "30 mg PO q48h" },
{ min: 0, max: 5, label: "Privilégier zanamivir inhalation" },
]},
"Valacyclovir (PO) — zona": { notes: "", doses: [
{ min: 31, max: 999, label: "1g PO q8h" },
{ min: 16, max: 30, label: "1g PO q12h" },
{ min: 6, max: 15, label: "1g PO q24h" },
{ min: 0, max: 5, label: "500 mg PO q24h" },
]},
"Valacyclovir (PO) — herpès génital": { notes: "", doses: [
{ min: 31, max: 999, label: "1g PO q12h" },
{ min: 16, max: 30, label: "1g PO q24h" },
{ min: 0, max: 15, label: "500 mg PO q24h" },
]},
},
};
function calcClcr(age, poids, creat, sexe) {
var k = sexe === 'F' ? 0.85 : 1.0;
return ((140 - age) * poids / (49 * creat)) * 60 * k;
}
function calcPI(taille, sexe) {
return sexe === 'F' ? 45.5 + 0.91 * (taille - 152) : 50 + 0.91 * (taille - 152);
}
function calcIMC(poids, taille) {
return poids / Math.pow(taille / 100, 2);
}
var state = {
age: '', poids: '', taille: '', creat: '', sexe: 'H',
selectedCat: '', selectedDrug: '', search: '',
mode: 'cg', dfgDirect: ''
};
function getDrugData(cat, drug) {
return ANTIBIOS[cat] && ANTIBIOS[cat][drug] ? ANTIBIOS[cat][drug] : null;
}
function getActiveDose(doses, clcr) {
var clcrRounded = Math.round(clcr * 10) / 10;
for (var i = 0; i < doses.length; i++) {
if (clcrRounded >= doses[i].min && clcrRounded <= doses[i].max) return i;
}
for (var i = doses.length - 1; i >= 0; i--) {
if (clcrRounded >= doses[i].min) return i;
}
return doses.length - 1;
}
function calcClcrFromState() {
if (state.mode === 'direct') {
var dfg = parseFloat(state.dfgDirect);
return { clcr: isNaN(dfg) ? null : dfg, imc: null, pi: null, poidsCalc: null };
}
var age = parseFloat(state.age);
var poids = parseFloat(state.poids);
var taille = parseFloat(state.taille);
var creat = parseFloat(state.creat);
var imc = (!isNaN(poids) && !isNaN(taille)) ? calcIMC(poids, taille) : null;
var pi = (!isNaN(taille)) ? calcPI(taille, state.sexe) : null;
var poidsCalc = null;
if (!isNaN(poids) && !isNaN(taille)) {
poidsCalc = imc < 30 ? poids : pi + 0.4 * (poids - pi);
}
var clcr = (!isNaN(age) && poidsCalc !== null && !isNaN(creat)) ? calcClcr(age, poidsCalc, creat, state.sexe) : null;
return { clcr: clcr, imc: imc, pi: pi, poidsCalc: poidsCalc };
}
function renderResult() {
var res = calcClcrFromState();
var clcr = res.clcr; var imc = res.imc; var pi = res.pi; var poidsCalc = res.poidsCalc;
var clcrColor = '#64748b'; var clcrLabel = '';
if (clcr !== null) {
if (clcr >= 60) { clcrColor = '#16a34a'; clcrLabel = 'Normale / légèrement réduite'; }
else if (clcr >= 30) { clcrColor = '#d97706'; clcrLabel = 'IRC modérée'; }
else if (clcr >= 15) { clcrColor = '#ea580c'; clcrLabel = 'IRC sévère'; }
else { clcrColor = '#dc2626'; clcrLabel = 'IRC très sévère / terminale'; }
}
var box = document.getElementById('calc-result-box');
if (box) {
if (clcr !== null) {
var html = '<div>';
html += '<div style="font-size:11px;color:#64748b;font-weight:600">' + (state.mode === 'direct' ? 'DFG (LABORATOIRE)' : 'CLAIRANCE CRÉATININE') + '</div>';
html += '<div class="calc-clcr-val" style="color:' + clcrColor + '">' + clcr.toFixed(1) + ' <span style="font-size:14px;font-weight:500">mL/min</span></div>';
html += '<div class="calc-clcr-label" style="color:' + clcrColor + '">' + clcrLabel + '</div>';
html += '</div>';
if (imc !== null) {
html += '<div class="calc-imc-info">';
html += '<div style="font-size:11px;color:#64748b;font-weight:600">IMC</div>';
html += '<div style="font-size:20px;font-weight:700;color:#0f2d5e">' + imc.toFixed(1) + ' <span style="font-size:11px">kg/m\u00b2</span></div>';
if (imc >= 30 && pi) {
html += '<div>IMC \u2265 30 \u2014 Poids de dosage : <b>' + poidsCalc.toFixed(1) + ' kg</b><br>Poids id\u00e9al : ' + pi.toFixed(1) + ' kg</div>';
}
html += '</div>';
}
box.innerHTML = html;
box.style.display = 'flex';
box.style.border = '2px solid ' + clcrColor + '33';
} else {
box.innerHTML = '';
box.style.display = 'none';
}
}
var btnH = document.getElementById('calc-btn-h');
var btnF = document.getElementById('calc-btn-f');
if (btnH) btnH.className = 'calc-sexe-btn' + (state.sexe === 'H' ? ' active' : '');
if (btnF) btnF.className = 'calc-sexe-btn' + (state.sexe === 'F' ? ' active' : '');
renderDrugResult(clcr);
}
function renderDrugResult(clcr) {
var drugData = getDrugData(state.selectedCat, state.selectedDrug);
var section = document.getElementById('calc-drug-result');
if (!section) return;
if (!state.selectedDrug || !drugData) { section.innerHTML = ''; return; }
var html = '<div class="calc-card">';
html += '<h2>3. Posologie recommand\u00e9e</h2>';
html += '<div style="font-size:13px;color:#64748b;margin-bottom:14px">' + state.selectedDrug + '</div>';
if (drugData.notes) html += '<div class="calc-note">\u26a0\ufe0f ' + drugData.notes + '</div>';
html += '<table class="calc-table"><thead><tr><th>ClCr (mL/min)</th><th>Posologie</th></tr></thead><tbody>';
var activeIdx = clcr !== null ? getActiveDose(drugData.doses, clcr) : -1;
drugData.doses.forEach(function(d, i) {
var isActive = clcr !== null && i === activeIdx;
var rangeLabel = d.max >= 999 ? '\u2265 ' + d.min : d.min === 0 ? '< ' + (drugData.doses.filter(function(x){return x.min>0;}).map(function(x){return x.min;}).sort(function(a,b){return a-b;})[0]||5) : d.min + ' \u2013 ' + d.max;
html += '<tr' + (isActive ? ' class="active-row"' : ' style="background:' + (i%2===0?'white':'#f8fafc') + '"') + '>';
html += '<td style="font-weight:600;white-space:nowrap">' + (isActive ? '\u25b6 ' : '') + rangeLabel + '</td>';
html += '<td>' + d.label + (isActive ? '<span class="calc-badge">VOTRE PATIENT</span>' : '') + '</td>';
html += '</tr>';
});
html += '</tbody></table>';
if (clcr === null) html += '<div class="calc-hint">\ud83d\udca1 Entrez les donn\u00e9es du patient (\u00e9tape 1) pour mettre en \u00e9vidence la posologie appropri\u00e9e.</div>';
html += '</div>';
section.innerHTML = html;
}
function renderDrugSelector() {
var searchResults = [];
if (state.search && state.search.length >= 2) {
var q = state.search.toLowerCase();
Object.keys(ANTIBIOS).forEach(function(cat) {
Object.keys(ANTIBIOS[cat]).forEach(function(drug) {
if (drug.toLowerCase().indexOf(q) !== -1) searchResults.push({ cat: cat, drug: drug });
});
});
}
var sr = document.getElementById('calc-search-results');
if (sr) {
var html = '';
searchResults.forEach(function(r) {
html += '<button onclick="calcSelectDrug(\'' + r.cat.replace(/'/g, "\\'") + '\',\'' + r.drug.replace(/'/g, "\\'") + '\')">';
html += '<span style="color:#64748b;font-size:11px">' + r.cat + ' / </span>' + r.drug + '</button>';
});
sr.innerHTML = html;
}
var cats = document.getElementById('calc-cats');
if (cats) {
var html = '';
Object.keys(ANTIBIOS).forEach(function(cat) {
html += '<button class="calc-cat-btn ' + (state.selectedCat === cat ? 'active' : '') + '" onclick="calcSetCat(\'' + cat.replace(/'/g, "\\'") + '\')">' + cat + '</button>';
});
cats.innerHTML = html;
}
var drugs = document.getElementById('calc-drugs');
if (drugs) {
var html = '';
if (state.selectedCat && ANTIBIOS[state.selectedCat]) {
Object.keys(ANTIBIOS[state.selectedCat]).forEach(function(drug) {
html += '<button class="calc-drug-btn ' + (state.selectedDrug === drug ? 'active' : '') + '" onclick="calcSetDrug(\'' + drug.replace(/'/g, "\\'") + '\')">' + drug + '</button>';
});
}
drugs.innerHTML = html;
}
}
function renderVanco() {
var app = document.getElementById('vanco-app');
if (!app) return;
var html = '';
// Header violet
html += '<div class="vanco-header">';
html += '<h1>Vancomycine IV \u2014 Tableaux posologiques</h1>';
html += '<p>Bas\u00e9 sur les lignes directrices APES \u2022 Adultes seulement</p>';
html += '</div>';
// Explication
html += '<div class="vanco-card">';
html += '<h2>\ud83d\udcd6 Comment utiliser ces tableaux</h2>';
html += '<ol style="font-size:13px;color:#374151;line-height:1.8;margin:0;padding-left:20px;">';
html += '<li><b>Dose de charge (optionnelle) :</b> Trouver le poids du patient dans le tableau 1 \u2192 administrer la dose correspondante en IV \u00d7 1 seule fois. Recommand\u00e9e chez les patients gravement malades.</li>';
html += '<li><b>Dose d\u2019entretien :</b> Trouver le poids dans le tableau 2 \u2192 c\u2019est la dose par administration.</li>';
html += '<li><b>Fr\u00e9quence :</b> Utiliser le DFGe fourni par le laboratoire (mL/min/1,73m\u00b2) dans le tableau 2 \u2192 d\u00e9termine l\u2019intervalle entre les doses (q8h, q12h, q24h).</li>';
html += '<li><b>Pr\u00e9l\u00e8vements :</b> Consulter le tableau 3 selon la fr\u00e9quence choisie pour planifier le moment des pr\u00e9l\u00e8vements PIC et creux.</li>';
html += '<li><b>Ajustement :</b> Toujours ajuster selon les dosages s\u00e9riques obtenus. Consulter un pharmacien pour les cas complexes (IMC \u2265 30, insuffisance r\u00e9nale s\u00e9v\u00e8re, soins intensifs).</li>';
html += '</ol>';
html += '<div style="margin-top:12px;padding:10px 14px;background:#f0fdf4;border-radius:8px;font-size:12px;color:#166534;">';
html += '\ud83d\udca1 <b>Astuce :</b> Pour un calcul plus pr\u00e9cis de la dose d\u2019entretien (particulièrement si IMC \u2265 30), utiliser <b>vancopk.com</b>.';
html += '</div>';
html += '</div>';
// Tableau 1 — Dose de charge
html += '<div class="vanco-card">';
html += '<h2>Tableau 1 \u2014 Dose de charge \u00d7 1 dose</h2>';
html += '<div style="font-size:12px;color:#64748b;margin-bottom:12px;">Calcul\u00e9e \u00e0 25 mg/kg de poids r\u00e9el. Non applicable aux usagers sous th\u00e9rapie de remplacement r\u00e9nal.</div>';
html += '<div style="overflow-x:auto;">';
html += '<table class="vanco-table"><thead><tr><th>Poids (kg)</th><th>Dose (mg)</th><th>Poids (kg)</th><th>Dose (mg)</th><th>Poids (kg)</th><th>Dose (mg)</th></tr></thead><tbody>';
html += '<tr><td>35 \u2013 39,9</td><td><b>750</b></td><td>60 \u2013 69,9</td><td><b>1500</b></td><td>90 \u2013 99,9</td><td><b>2250</b></td></tr>';
html += '<tr><td>40 \u2013 49,9</td><td><b>1000</b></td><td>70 \u2013 79,9</td><td><b>1750</b></td><td>100 \u2013 129,9</td><td><b>2500</b></td></tr>';
html += '<tr><td>50 \u2013 59,9</td><td><b>1250</b></td><td>80 \u2013 89,9</td><td><b>2000</b></td><td>130 et plus</td><td><b>3000</b></td></tr>';
html += '</tbody></table>';
html += '</div></div>';
// Tableau 2 — Entretien
html += '<div class="vanco-card">';
html += '<h2>Tableau 2 \u2014 Traitement d\u2019entretien</h2>';
html += '<div style="font-size:12px;color:#64748b;margin-bottom:12px;">Croiser la dose selon le poids <b>ET</b> la fr\u00e9quence selon le DFGe du laboratoire.</div>';
html += '<div style="display:flex;gap:16px;flex-wrap:wrap;">';
html += '<div style="flex:1;min-width:180px;">';
html += '<div class="vanco-section-title">Dose selon le poids</div>';
html += '<table class="vanco-table"><thead><tr><th>Poids (kg)</th><th>Dose / administration</th></tr></thead><tbody>';
html += '<tr><td>35 \u2013 39,9</td><td><b>500 mg</b></td></tr>';
html += '<tr><td>40 \u2013 59,9</td><td><b>750 mg</b></td></tr>';
html += '<tr><td>60 \u2013 79,9</td><td><b>1000 mg</b></td></tr>';
html += '<tr><td>80 \u2013 99,9</td><td><b>1250 mg</b></td></tr>';
html += '<tr><td>100 et plus</td><td><b>1500 mg</b></td></tr>';
html += '</tbody></table></div>';
html += '<div style="flex:1;min-width:220px;">';
html += '<div class="vanco-section-title">Fr\u00e9quence selon le DFGe (mL/min/1,73m\u00b2)</div>';
html += '<table class="vanco-table"><thead><tr><th>DFGe</th><th>Fr\u00e9quence</th></tr></thead><tbody>';
html += '<tr><td>Plus de 90</td><td><b>q 8h</b></td></tr>';
html += '<tr><td>50 \u2013 90</td><td><b>q 12h</b></td></tr>';
html += '<tr><td>15 \u2013 49</td><td><b>q 24h</b></td></tr>';
html += '<tr><td>Moins de 15</td><td><b>Dose unique puis selon dosage</b></td></tr>';
html += '</tbody></table></div>';
html += '</div></div>';
// Tableau 3 — Prélèvements
html += '<div class="vanco-card">';
html += '<h2>Tableau 3 \u2014 Moment des pr\u00e9l\u00e8vements recommand\u00e9s</h2>';
html += '<div style="font-size:12px;color:#64748b;margin-bottom:12px;">Incluant la dose de charge s\u2019il y a lieu.</div>';
html += '<div style="overflow-x:auto;">';
html += '<table class="vanco-table"><thead><tr><th>Intervalle posologique</th><th>PIC</th><th>CREUX</th></tr></thead><tbody>';
html += '<tr><td style="font-weight:700;">q8h ou q12h</td><td>60 \u00e0 120 min post fin de perfusion de la <b>4\u1d49 dose</b></td><td>Juste avant la <b>4\u1d49 dose</b></td></tr>';
html += '<tr><td style="font-weight:700;">q24h</td><td>60 \u00e0 120 min post fin de perfusion de la <b>3\u1d49 dose</b></td><td>Juste avant la <b>3\u1d49 dose</b></td></tr>';
html += '</tbody></table>';
html += '</div>';
html += '<div style="font-size:12px;color:#64748b;margin-top:10px;">Des pr\u00e9l\u00e8vements par <b>creux seulement</b> doivent \u00eatre effectu\u00e9s pour les patients dont l\u2019\u00e9tat d\u2019\u00e9quilibre n\u2019est pas atteint.</div>';
html += '</div>';
// Avertissement
html += '<div class="vanco-warning">\u26a0\ufe0f <b>Avertissement clinique :</b> Ces tableaux sont fournis \u00e0 titre de r\u00e9f\u00e9rence. Toujours ajuster selon les dosages s\u00e9riques. Consulter un pharmacien pour tout ajustement posologique de la vancomycine et se r\u00e9f\u00e9rer au guide APES (bulletin N\u00b0 40).</div>';
app.innerHTML = html;
}
function render() {
var app = document.getElementById('calc-app');
if (!app) return;
var html = '';
html += '<div class="calc-header">';
html += '<h1>Calculateur posologique \u2014 Insuffisance r\u00e9nale</h1>';
html += '<p>Bas\u00e9 sur le guide APES (RPEI) \u2014 Octobre 2019 \u2022 Adultes seulement \u2022 Le jugement clinique doit pr\u00e9valoir</p>';
html += '</div>';
html += '<div class="calc-card">';
html += '<h2>1. Fonction r\u00e9nale</h2>';
html += '<div style="display:flex;gap:8px;margin-bottom:16px;">';
html += '<button id="calc-btn-cg" class="calc-sexe-btn ' + (state.mode === 'cg' ? 'active' : '') + '" onclick="calcSetMode(\'cg\')">Calculer (Cockcroft-Gault)</button>';
html += '<button id="calc-btn-direct" class="calc-sexe-btn ' + (state.mode === 'direct' ? 'active' : '') + '" onclick="calcSetMode(\'direct\')">DFG d\u00e9j\u00e0 connu</button>';
html += '</div>';
if (state.mode === 'cg') {
html += '<div style="margin-bottom:12px;display:flex;align-items:center;gap:8px;">';
html += '<span style="font-size:13px;color:#64748b;width:50px">Sexe</span>';
html += '<button id="calc-btn-h" class="calc-sexe-btn ' + (state.sexe === 'H' ? 'active' : '') + '" onclick="calcSetSexe(\'H\')">Homme</button>';
html += '<button id="calc-btn-f" class="calc-sexe-btn ' + (state.sexe === 'F' ? 'active' : '') + '" onclick="calcSetSexe(\'F\')">Femme</button>';
html += '</div>';
html += '<div class="calc-grid">';
html += '<div><label>\u00c2ge (ans)</label><input id="calc-age" type="number" placeholder="ex: 65" oninput="calcSetField(\'age\',this.value)"></div>';
html += '<div><label>Poids r\u00e9el (kg)</label><input id="calc-poids" type="number" placeholder="ex: 70" oninput="calcSetField(\'poids\',this.value)"></div>';
html += '<div><label>Taille (cm)</label><input id="calc-taille" type="number" placeholder="ex: 170" oninput="calcSetField(\'taille\',this.value)"></div>';
html += '<div><label>Cr\u00e9atinine (\u03bcmol/L)</label><input id="calc-creat" type="number" placeholder="ex: 120" oninput="calcSetField(\'creat\',this.value)"></div>';
html += '</div>';
} else {
html += '<div style="max-width:250px;">';
html += '<label style="font-size:11px;color:#64748b;font-weight:600;display:block;margin-bottom:4px;">DFG / ClCr (mL/min)</label>';
html += '<input id="calc-dfg-direct" type="number" placeholder="ex: 45" style="width:100%;padding:10px 14px;border-radius:8px;border:1.5px solid #e2e8f0;font-size:18px;font-weight:700;color:#0f2d5e;outline:none;" oninput="calcSetField(\'dfgDirect\',this.value)">';
html += '<div style="font-size:11px;color:#64748b;margin-top:6px;">Valeur fournie par le laboratoire</div>';
html += '</div>';
}
html += '<div id="calc-result-box" class="calc-result-box" style="display:none"></div>';
html += '</div>';
html += '<div class="calc-card">';
html += '<h2>2. S\u00e9lection de l\'antimicrobien</h2>';
html += '<input id="calc-search-input" class="calc-search" type="text" placeholder="\ud83d\udd0d Rechercher un antimicrobien..." oninput="calcSetSearch(this.value)">';
html += '<div id="calc-search-results" class="calc-search-results"></div>';
html += '<div id="calc-cats" class="calc-cats"></div>';
html += '<div id="calc-drugs" class="calc-drugs"></div>';
html += '</div>';
html += '<div id="calc-drug-result"></div>';
html += '<div class="calc-warning">\u26a0\ufe0f <b>Avertissement clinique :</b> Cet outil est bas\u00e9 sur le guide APES (RPEI, octobre 2019). Les ajustements servent uniquement \u00e0 guider la d\u00e9cision clinique \u2014 le jugement clinique doit pr\u00e9valoir. Consulter un pharmacien pour les cas complexes.</div>';
html += '<div id="vanco-app" style="margin-top:24px;"></div>';
app.innerHTML = html;
renderResult();
renderDrugSelector();
renderVanco();
}
window.calcSetMode = function(mode) { state.mode = mode; render(); };
window.calcSetField = function(field, val) { state[field] = val; renderResult(); };
window.calcSetSexe = function(sexe) { state.sexe = sexe; renderResult(); };
window.calcSetSearch = function(val) { state.search = val; state.selectedCat = ''; state.selectedDrug = ''; renderDrugSelector(); renderDrugResult(calcClcrFromState().clcr); };
window.calcSetCat = function(cat) { state.selectedCat = cat; state.selectedDrug = ''; renderDrugSelector(); renderDrugResult(calcClcrFromState().clcr); };
window.calcSetDrug = function(drug) { state.selectedDrug = drug; renderDrugSelector(); renderDrugResult(calcClcrFromState().clcr); };
window.calcSelectDrug = function(cat, drug) { state.selectedCat = cat; state.selectedDrug = drug; state.search = ''; var si = document.getElementById('calc-search-input'); if(si) si.value=''; renderDrugSelector(); renderDrugResult(calcClcrFromState().clcr); };
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', render);
} else {
render();
}
}