Skip to main content
360° Human: Protect & Prevent BINGO
🫁 Respiratory Coins: 0
Dashboard
🫁

Respiratory System

Know Your Systems. Prevent What You Can. Share What You Know.

Understand your risks and take action to prevent them.

0
Learned
0
BINGO Lines
0
Coins Earned
Overall Progress
0 of 16
Conditions Completed
0 of 10
Possible BINGO Lines
0
Total Coins Earned
🏆 Bonus Coins — Complete a Line for +50 Coins!
Complete all 4 conditions in any row, column, or diagonal to earn bonus coins. Complete all 16 for +200 Champion Bonus!
Row 1 (Top)
+50 🪙
Row 2
+50 🪙
Row 3
+50 🪙
Row 4 (Bottom)
+50 🪙
Col 1
+50 🪙
Col 2
+50 🪙
Col 3
+50 🪙
Col 4
+50 🪙
Diagonal ↘
+50 🪙
Diagonal ↗
+50 🪙
🔬 System Mastery
❤️
Cardiovascular
🫁
Respiratory
🔄
Digestive
🧠
Nervous
⚖️
Endocrine
💪
Musculoskeletal
🛡️
Immune
💧
Urinary
🌱
Reproductive
👨
Integumentary
👁️
Sensory
`; // Open in new window for print/save as PDF const printWin = window.open('', '_blank'); printWin.document.write(printHTML); printWin.document.close(); setTimeout(() => printWin.print(), 500); } function closeModal() { document.getElementById('modalBackdrop').classList.remove('active'); // Close Dr. Rob chat if open closeDrRobChat(); } // ═══════════════════════════════════════════════════════════ // DR. ROB AI CHATBOT ENGINE // ═══════════════════════════════════════════════════════════ var drRobChatHistory = []; // ── Dr. Rob In-House AI (Anthropic Claude API via Vercel) ── // Dr. Rob In-House AI - Direct Anthropic Claude API via Vercel serverless function // No third-party middleware. FFH owns the prompts, logs, and data. var DR_ROB_API = { // Use relative URL when deployed on same Vercel project, or absolute for dev/testing endpoint: '/api/drRob', conversationHistory: [], enabled: true }; function callDrRobAI(userMessage, callback) { if (!DR_ROB_API.enabled) { callback(null); return; } var condName = STATE.currentConditionName || 'respiratory health'; var tabName = STATE.currentTab === 'live' ? 'Live It' : STATE.currentTab === 'share' ? 'Share It' : 'Learn It'; var body = { message: userMessage, context: { condition: condName, tab: tabName }, conversationHistory: DR_ROB_API.conversationHistory.slice(-20) }; console.log('[Dr.Rob AI] Sending to in-house API:', userMessage.substring(0, 50)); var xhr = new XMLHttpRequest(); xhr.open('POST', DR_ROB_API.endpoint, true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.timeout = 30000; xhr.onload = function() { console.log('[Dr.Rob AI] Response status:', xhr.status); if (xhr.status >= 200 && xhr.status < 300) { try { var data = JSON.parse(xhr.responseText); if (data.reply) { // Store conversation history for context DR_ROB_API.conversationHistory.push({ role: 'user', content: userMessage }); DR_ROB_API.conversationHistory.push({ role: 'assistant', content: data.reply }); // Keep history manageable if (DR_ROB_API.conversationHistory.length > 20) { DR_ROB_API.conversationHistory = DR_ROB_API.conversationHistory.slice(-20); } console.log('[Dr.Rob AI] Got reply:', data.reply.substring(0, 100)); callback(data.reply); } else if (data.fallback) { console.warn('[Dr.Rob AI] Server returned fallback signal'); callback(null); } else { callback(null); } } catch(e) { console.error('[Dr.Rob AI] Parse error:', e); callback(null); } } else { console.error('[Dr.Rob AI] HTTP error:', xhr.status); callback(null); } }; xhr.onerror = function() { console.error('[Dr.Rob AI] Network error'); callback(null); }; xhr.ontimeout = function() { console.error('[Dr.Rob AI] Timeout (30s)'); callback(null); }; xhr.send(JSON.stringify(body)); } function openDrRobChat(e) { if (e) e.stopPropagation(); var panel = document.getElementById('drRobChatPanel'); var backdrop = document.getElementById('drRobChatBackdrop'); var avatar = document.getElementById('drRobChatAvatar'); if (avatar) avatar.src = DR_ROB_SRC; var condLabel = document.getElementById('drRobChatCondition'); if (condLabel) condLabel.textContent = STATE.currentConditionName || 'Health Guide'; panel.classList.add('active'); backdrop.classList.add('active'); // Show welcome if empty if (drRobChatHistory.length === 0) { var condName = STATE.currentConditionName || 'this condition'; var tabName = STATE.currentTab === 'live' ? 'Live It' : STATE.currentTab === 'share' ? 'Share It' : 'Learn It'; addBotMessage("Hey there! I'm Dr. Rob, your AI educational guide. I'm not a real doctor or healthcare provider, but I'm here to help you learn!\n\nYou're working on " + condName + " — currently on the " + tabName + " tab.\n\nTap a button below to find out what to do!"); } setTimeout(function() { var input = document.getElementById('drRobChatInput'); if (input) input.focus(); }, 300); } function closeDrRobChat() { document.getElementById('drRobChatPanel').classList.remove('active'); document.getElementById('drRobChatBackdrop').classList.remove('active'); } function resetDrRobChat() { drRobChatHistory = []; drRobMode = 'guide'; DR_ROB_API.conversationHistory = []; var msgs = document.getElementById('drRobChatMessages'); if (msgs) msgs.innerHTML = ''; // Reset to guide mode UI var suggestions = document.getElementById('drRobChatSuggestions'); var footer = document.getElementById('drRobGuideFooter'); var inputArea = document.getElementById('drRobChatInputArea'); var badge = document.getElementById('liveBadge'); if (suggestions) suggestions.style.display = 'flex'; if (footer) footer.style.display = 'block'; if (inputArea) inputArea.style.display = 'none'; if (badge) badge.remove(); } function addBotMessage(text) { drRobChatHistory.push({ role: 'bot', text: text }); var msgs = document.getElementById('drRobChatMessages'); var msgDiv = document.createElement('div'); msgDiv.className = 'drRob-msg bot'; var img = document.createElement('img'); img.src = DR_ROB_SRC; img.className = 'drRob-msg-avatar'; var bubble = document.createElement('div'); bubble.className = 'drRob-msg-bubble'; bubble.textContent = text; msgDiv.appendChild(img); msgDiv.appendChild(bubble); msgs.appendChild(msgDiv); msgs.scrollTop = msgs.scrollHeight; } function addUserMessage(text) { drRobChatHistory.push({ role: 'user', text: text }); var msgs = document.getElementById('drRobChatMessages'); var msgDiv = document.createElement('div'); msgDiv.className = 'drRob-msg user'; var bubble = document.createElement('div'); bubble.className = 'drRob-msg-bubble'; bubble.textContent = text; msgDiv.appendChild(bubble); msgs.appendChild(msgDiv); msgs.scrollTop = msgs.scrollHeight; } function showTyping() { var msgs = document.getElementById('drRobChatMessages'); var msgDiv = document.createElement('div'); msgDiv.className = 'drRob-msg bot'; msgDiv.id = 'drRobTyping'; var img = document.createElement('img'); img.src = DR_ROB_SRC; img.className = 'drRob-msg-avatar'; var dots = document.createElement('div'); dots.className = 'drRob-msg-typing'; dots.innerHTML = ''; msgDiv.appendChild(img); msgDiv.appendChild(dots); msgs.appendChild(msgDiv); msgs.scrollTop = msgs.scrollHeight; } function hideTyping() { var t = document.getElementById('drRobTyping'); if (t) t.remove(); } var drRobMode = 'guide'; // 'guide' or 'chat' function switchToLiveChat() { drRobMode = 'chat'; // Hide guide elements, show chat input document.getElementById('drRobChatSuggestions').style.display = 'none'; document.getElementById('drRobGuideFooter').style.display = 'none'; document.getElementById('drRobChatInputArea').style.display = 'flex'; // Update header to show LIVE badge var statusEl = document.querySelector('.drRob-chat-status'); if (statusEl && !document.getElementById('liveBadge')) { var badge = document.createElement('span'); badge.className = 'drRob-live-badge'; badge.id = 'liveBadge'; badge.textContent = 'LIVE'; statusEl.appendChild(badge); } // Show transition message var condName = STATE.currentConditionName || 'your lesson'; addBotMessage("You're now chatting live with Dr. Rob, your AI health education assistant! I can help you learn about " + condName + " and health prevention. Remember, I'm an AI — for personal health questions, always talk to a real healthcare provider.\n\nTap ← to go back to the lesson guide."); setTimeout(function() { var input = document.getElementById('drRobChatInput'); if (input) input.focus(); }, 200); } function switchToGuideMode() { drRobMode = 'guide'; // Show guide elements, hide chat input document.getElementById('drRobChatSuggestions').style.display = 'flex'; document.getElementById('drRobGuideFooter').style.display = 'block'; document.getElementById('drRobChatInputArea').style.display = 'none'; // Remove LIVE badge var badge = document.getElementById('liveBadge'); if (badge) badge.remove(); addBotMessage("Back to lesson guide mode! Tap a button below for quick help."); } function sendSuggestion(action) { var labels = { 'todo': '📋 What do I do here?', 'coins': '🪙 How do I earn coins?', 'progress': '✅ Am I done yet?', 'next': '👉 What\'s next?' }; addUserMessage(labels[action] || action); showTyping(); setTimeout(function() { hideTyping(); var response = getDrRobResponse(action, ''); addBotMessage(response); }, 600 + Math.random() * 400); } function sendDrRobMessage() { var input = document.getElementById('drRobChatInput'); var text = (input.value || '').trim(); if (!text) return; input.value = ''; addUserMessage(text); showTyping(); // Call in-house Dr. Rob AI (Claude API via Vercel) callDrRobAI(text, function(aiReply) { hideTyping(); if (aiReply) { addBotMessage(aiReply); } else { // Fallback to local navigator responses var action = classifyQuestion(text); var response = getDrRobResponse(action, text); addBotMessage(response); } }); } function classifyQuestion(text) { var lower = text.toLowerCase(); if (/what do i do|what should i|how does this work|what.s this|what am i supposed|instructions|help me start|where do i begin/.test(lower)) return 'todo'; if (/coin|point|reward|earn|score|how many|how much/.test(lower)) return 'coins'; if (/done|finish|complete|progress|status|check/.test(lower)) return 'progress'; if (/next|after this|what.s left|move on|what else|then what/.test(lower)) return 'next'; if (/learn it|learn tab|blue tab|first tab/.test(lower)) return 'tab_learn'; if (/live it|live tab|green tab|second tab|actions|rate/.test(lower)) return 'tab_live'; if (/share it|share tab|gold tab|third tab|pledge|social/.test(lower)) return 'tab_share'; if (/pre.?check|quiz|assessment|test/.test(lower)) return 'precheck'; if (/bingo|board|grid|pattern/.test(lower)) return 'bingo'; return 'todo'; // default to showing what to do } function getProgressSnapshot() { var cid = STATE.currentConditionId; var comp = STATE.completed[cid] || {}; var tab = STATE.currentTab || 'learn'; // Learn It: marked true when user visits (auto-complete) var learnDone = !!comp.learnIt; // Live It: check if self-assessment cards are rated var liveItData = {}; try { liveItData = JSON.parse(localStorage.getItem('ffh_rs_liveit_' + cid) || '{}'); } catch(e) {} var ratedCount = Object.keys(liveItData).filter(function(k) { return liveItData[k] && liveItData[k].rating; }).length; var c = CONDITIONS.find(function(x) { return x.id === cid; }); var totalActions = (c && c.liveItActions) ? c.liveItActions.length : 5; var liveDone = ratedCount >= totalActions; // Share It: pledge taken + any shares var pledgeDone = !!comp.pledgeChoice; var shares = comp.shares || {}; var shareCount = Object.keys(shares).length; var shareDone = pledgeDone; // Pre-check assessment var precheck = null; try { var assessments = JSON.parse(localStorage.getItem('ffh_rs_assessments') || '{}'); precheck = assessments[cid] || null; } catch(e) {} var preCheckDone = !!(precheck && precheck.post); var preCheckStarted = !!(precheck && precheck.pre); return { tab: tab, learnDone: learnDone, liveDone: liveDone, shareDone: shareDone, pledgeDone: pledgeDone, ratedCount: ratedCount, totalActions: totalActions, shareCount: shareCount, preCheckDone: preCheckDone, preCheckStarted: preCheckStarted, allDone: learnDone && liveDone && shareDone && preCheckDone }; } function getDrRobResponse(action, userText) { var name = STATE.currentConditionName || 'this condition'; var snap = getProgressSnapshot(); var tabLabel = snap.tab === 'live' ? 'Live It' : snap.tab === 'share' ? 'Share It' : 'Learn It'; if (action === 'todo') { if (snap.tab === 'learn') { if (!snap.preCheckStarted) { return "You're on the Learn It tab for " + name + ". Here's what to do:\n\n" + "1. First, take the Pre-Check quiz — it tests what you already know and earns you 5 coins\n" + "2. Then explore the lesson content: how your body works, what goes wrong, risk factors, and county health data\n" + "3. When you feel ready, move on to the Live It tab!\n\n" + "The Pre-Check button should appear when you open this condition. Look for the blue overlay!"; } return "You're on the Learn It tab for " + name + ".\n\n" + (snap.preCheckStarted ? "✅ Pre-Check started" : "⬜ Take the Pre-Check quiz") + "\n" + "📖 Read through the lesson sections: physiology, what goes wrong, risk factors, and your local health data.\n\n" + "Once you've explored the content, tap the Live It tab to start taking action!"; } if (snap.tab === 'live') { return "You're on the Live It tab for " + name + ". Here's what to do:\n\n" + "1. Rate yourself on each action card (1-5 stars) — be honest, this is your baseline!\n" + "2. Read the prevention strategies and daily action tips\n" + "3. Each card you rate earns you coins\n\n" + "Progress: " + snap.ratedCount + " of " + snap.totalActions + " action cards rated.\n" + (snap.liveDone ? "✅ All rated! Head to the Share It tab when ready." : "Keep going — rate them all to complete this phase!"); } if (snap.tab === 'share') { var tasks = []; tasks.push(snap.pledgeDone ? "✅ Pledge — done!" : "⬜ Take the Prevention Pledge (or tell us why you're not ready — that earns coins too!)"); tasks.push(snap.shareCount > 0 ? "✅ Shared " + snap.shareCount + " item(s)" : "⬜ Share a branded post, text a friend, or use the Doctor Discussion Guide"); return "You're on the Share It tab for " + name + ". Here's what to do:\n\n" + tasks.join("\n") + "\n\n" + "Every share action earns you Share It Coins. The more you share, the more you earn!"; } return "You're working on " + name + ". Tap the tabs at the top — Learn It, Live It, Share It — to progress through the lesson!"; } if (action === 'coins') { var totalCoins = STATE.coins || 0; var available = []; if (!snap.preCheckStarted) available.push("🧠 Pre-Check quiz: 5 coins"); if (snap.ratedCount < snap.totalActions) available.push("💪 Rate action cards: " + (snap.totalActions - snap.ratedCount) + " cards left (coins per card)"); if (!snap.pledgeDone) available.push("✊ Take the Pledge: up to 5 coins"); if (snap.shareCount < 3) available.push("📤 Share actions: up to " + (3 - snap.shareCount) + " more shares (3-5 coins each)"); if (available.length === 0) { return "You have " + totalCoins + " coins total! 🎉\n\nYou've earned all available coins for " + name + ". Nice work! Close this condition and try another one on the Bingo board."; } return "You have " + totalCoins + " coins so far.\n\nCoins still available for " + name + ":\n\n" + available.join("\n") + "\n\n" + "Complete these to maximize your earnings!"; } if (action === 'progress') { var checks = []; checks.push(snap.preCheckStarted ? "✅ Pre-Check taken" : "⬜ Pre-Check quiz"); checks.push(snap.learnDone ? "✅ Learn It explored" : "⬜ Learn It tab"); checks.push(snap.liveDone ? "✅ Live It complete (" + snap.ratedCount + "/" + snap.totalActions + ")" : "⏳ Live It (" + snap.ratedCount + "/" + snap.totalActions + " rated)"); checks.push(snap.shareDone ? "✅ Share It complete" : "⬜ Share It tab"); if (snap.allDone) { return "🎉 You've completed " + name + "!\n\n" + checks.join("\n") + "\n\n" + "This condition is done on your Bingo board. Keep going to build BINGO patterns and earn bonus coins!"; } return "Your progress on " + name + ":\n\n" + checks.join("\n") + "\n\n" + "Keep going! Complete all phases to mark this condition done on your Bingo board."; } if (action === 'next') { if (!snap.preCheckStarted) { return "👉 Start with the Pre-Check quiz! It pops up when you first open a condition. If you dismissed it, close and re-open this condition to try again.\n\nThe Pre-Check earns you 5 coins and sets your learning baseline."; } if (!snap.learnDone) { return "👉 You're on Learn It — scroll through the content to learn about " + name + ". Once you've read through it, tap the Live It tab."; } if (!snap.liveDone) { return "👉 Head to the Live It tab and rate yourself on all " + snap.totalActions + " action cards. You've done " + snap.ratedCount + " so far. Once they're all rated, move to Share It!"; } if (!snap.pledgeDone) { return "👉 Head to the Share It tab and decide on your Prevention Pledge. You can pledge for 5 coins, share why you're not ready for 3 coins, or skip."; } if (snap.shareCount < 1) { return "👉 Try sharing what you learned! On the Share It tab you'll find a branded social media card, a text message for family, and a Doctor Discussion Guide. Each one earns coins!"; } if (snap.allDone) { return "🎉 You've completed everything for " + name + "! Close this modal and pick another condition on your Bingo board. Try to complete a full row, column, or diagonal for a BINGO bonus!"; } return "👉 Keep working through the tabs — Learn It, Live It, then Share It. You're making great progress!"; } if (action === 'tab_learn') { return "The Learn It tab (blue) is where you discover how your body works and what goes wrong with " + name + ".\n\n" + "It includes: how the body system normally functions, what happens with this condition, risk factors, and health data for your county.\n\n" + "Tap the Learn It tab at the top to go there!"; } if (action === 'tab_live') { return "The Live It tab (green) is where you take action!\n\n" + "You'll rate yourself on prevention behaviors using 1-5 stars. Be honest — there's no wrong answer. You earn coins for each card you rate.\n\n" + "Progress: " + snap.ratedCount + " of " + snap.totalActions + " rated. Tap the Live It tab to go there!"; } if (action === 'tab_share') { return "The Share It tab (gold) is where you spread the word and earn bonus coins!\n\n" + "Start with the Prevention Pledge, then share branded content on social media, text a friend, or prep for a doctor visit.\n\n" + "Tap the Share It tab at the top to go there!"; } if (action === 'precheck') { if (snap.preCheckDone) { return "✅ You've already completed both the Pre-Check and Post-Check for " + name + ". Great job!"; } if (snap.preCheckStarted) { return "You've taken the Pre-Check! After you finish all three tabs (Learn It, Live It, Share It), you'll get a Post-Check to see how much you've learned. That earns bonus coins too!"; } return "The Pre-Check is a short quiz that tests what you already know about " + name + " before the lesson. It earns 5 coins and pops up when you first open a condition. If you missed it, try closing and re-opening this condition."; } if (action === 'bingo') { return "The Bingo board is your 4×4 grid of 16 respiratory conditions. Complete all three phases (Learn It, Live It, Share It) for a condition to mark it done.\n\n" + "Get 4 in a row (horizontal, vertical, or diagonal) for a BINGO bonus of 50 coins! Complete ALL 16 for a 200-coin jackpot! 🎉"; } // Fallback — always navigate-oriented return "I'm here to help you navigate this lesson on " + name + "!\n\n" + "You're on the " + tabLabel + " tab right now. Tap a button below to find out what to do, check your progress, or see what coins you can still earn."; } function switchTab(tabName) { STATE.currentTab = tabName; // Update tab buttons document.querySelectorAll('.modal-tab').forEach(tab => tab.classList.remove('active')); document.querySelector(`.modal-tab:nth-child(${tabName === 'learn' ? '1' : tabName === 'live' ? '2' : '3'})`).classList.add('active'); // Update tab content document.querySelectorAll('.modal-content').forEach(content => content.classList.remove('active')); document.getElementById(`tab-${tabName}`).classList.add('active'); // Mark phase as completed if (STATE.currentConditionId) { if (!STATE.completed[STATE.currentConditionId]) { STATE.completed[STATE.currentConditionId] = { learnIt: false, liveIt: false, shareIt: false }; } if (tabName === 'learn') { STATE.completed[STATE.currentConditionId].learnIt = true; updatePostAssessSection(); } else if (tabName === 'live') { STATE.completed[STATE.currentConditionId].liveIt = true; } else if (tabName === 'share') { // Share It completes when pledge choice is made restoreShareTabState(); } saveState(); updateCompletionTracker(); } } function updateCompletionTracker() { if (!STATE.currentConditionId) return; const completion = STATE.completed[STATE.currentConditionId] || { learnIt: false, liveIt: false, shareIt: false }; const tab = STATE.currentTab || 'learn'; const steps = [ { el: document.getElementById('step-learn'), done: completion.learnIt, phase: 'learn', num: '1' }, { el: document.getElementById('step-live'), done: completion.liveIt, phase: 'live', num: '2' }, { el: document.getElementById('step-share'), done: completion.shareIt, phase: 'share', num: '3' } ]; steps.forEach(s => { s.el.classList.toggle('completed', s.done); s.el.classList.toggle('active-phase', s.phase === tab); s.el.textContent = s.done ? '✓' : s.num; }); } function toggleAction(element, type) { const checkbox = element.querySelector('input[type="checkbox"]'); checkbox.checked = !checkbox.checked; if (checkbox.checked && type === 'liveit') { const coinsText = element.querySelector('.action-text-coins').textContent; const coins = parseInt(coinsText.match(/\d+/)[0]); STATE.coins += coins; updateCoinDisplay(); saveState(); } } function takePledge() { if (!STATE.currentConditionId) return; var cid = STATE.currentConditionId; if (STATE.completed[cid] && STATE.completed[cid].pledgeChoice) return; STATE.completed[cid].pledgeChoice = 'pledge'; STATE.completed[cid].shareIt = true; STATE.coins = (STATE.coins || 0) + 5; document.getElementById('pledgePaths').style.display = 'none'; document.getElementById('whyNotPanel').style.display = 'none'; var result = document.getElementById('pledgeResult'); result.style.display = 'block'; result.innerHTML = '
✊ Pledge Taken!
' + '
+5 Coins Earned
' + '
You are a Force for Health!
'; updateCompletionTracker(); saveState(); updateCoinDisplay(); updateShareCoinsDisplay(); checkConditionCompletion(); } function showWhyNot() { document.getElementById('pledgePaths').style.display = 'none'; document.getElementById('whyNotPanel').style.display = 'block'; // Enable submit when a radio is selected var radios = document.querySelectorAll('#whyNotOptions input[type="radio"]'); radios.forEach(function(r) { r.addEventListener('change', function() { var btn = document.getElementById('whyNotSubmitBtn'); btn.style.opacity = '1'; btn.style.pointerEvents = 'auto'; }); }); } function submitWhyNot() { if (!STATE.currentConditionId) return; var cid = STATE.currentConditionId; var selected = document.querySelector('#whyNotOptions input[type="radio"]:checked'); if (!selected) return; STATE.completed[cid].pledgeChoice = 'whynot'; STATE.completed[cid].pledgeReason = selected.value; STATE.completed[cid].shareIt = true; STATE.coins = (STATE.coins || 0) + 3; document.getElementById('whyNotPanel').style.display = 'none'; var result = document.getElementById('pledgeResult'); result.style.display = 'block'; result.innerHTML = '
🙏 Thanks for sharing!
' + '
+3 Coins Earned
' + '
Your feedback helps us improve the experience.
'; updateCompletionTracker(); saveState(); updateCoinDisplay(); updateShareCoinsDisplay(); checkConditionCompletion(); } function skipPledge() { if (!STATE.currentConditionId) return; var cid = STATE.currentConditionId; STATE.completed[cid].pledgeChoice = 'skip'; STATE.completed[cid].shareIt = true; document.getElementById('pledgePaths').style.display = 'none'; document.getElementById('whyNotPanel').style.display = 'none'; var result = document.getElementById('pledgeResult'); result.style.display = 'block'; result.innerHTML = '
⏭️ Skipped
' + '
No worries! You can always come back. Check out the sharing options below.
'; updateCompletionTracker(); saveState(); updateCoinDisplay(); updateShareCoinsDisplay(); checkConditionCompletion(); } // ═══════════════════════════════════════════════════════════ // SHARE IT — Content Generator & Share Actions // ═══════════════════════════════════════════════════════════ function getShareContent(conditionId) { var c = CONDITIONS.find(function(x) { return x.id === conditionId; }); if (!c) return null; var topPrev = c.preventionStrategies ? c.preventionStrategies.slice(0, 2) : []; var topRisk = c.riskFactors ? c.riskFactors.slice(0, 2) : []; var dykFact = topPrev.length > 0 ? 'You can help prevent ' + c.name + ' by: ' + topPrev[0].toLowerCase() + ' and ' + (topPrev[1] ? topPrev[1].toLowerCase() : 'staying informed') + '.' : 'Learn how to protect yourself and your loved ones from ' + c.name + '.'; var socialCaption = c.emoji + ' Did you know? ' + dykFact + '\n\nI learned this on the 360\u00b0 Human: Protect & Prevent BINGO Challenge from @TheForceForHealth!' + '\n\n#ForceForHealth #PreventionBingo #Know360 #HealthLiteracy #' + c.name.replace(/[\s\-\/]/g, ''); var familyText = 'Hey! I just learned something important about ' + c.name + ' that I wanted to share with you.' + '\n\n' + c.emoji + ' ' + dykFact + '\n\nTop risk factors include: ' + topRisk.join(', ') + '.' + '\n\nI\'m doing the 360\u00b0 Human: Protect & Prevent BINGO Challenge at theforceforhealth.com \u2014 check it out!'; var doctorQs = [ 'Am I at risk for ' + c.name + ' based on my history?', 'What screening or tests should I consider for ' + c.name + '?', 'What lifestyle changes would help me prevent ' + c.name + '?' ]; if (topRisk.length > 0) { doctorQs.push('I learned that "' + topRisk[0] + '" is a risk factor \u2014 does this apply to me?'); } return { dykFact: dykFact, socialCaption: socialCaption, familyText: familyText, doctorQuestions: doctorQs, emoji: c.emoji, name: c.name }; } function populateShareAssets() { if (!STATE.currentConditionId) return; var content = getShareContent(STATE.currentConditionId); if (!content) return; // Did You Know card var dykLogo = document.getElementById('dykLogo'); if (dykLogo) dykLogo.src = FFH_WHITE_LOGO_SRC; var dykEmoji = document.getElementById('dykEmoji'); if (dykEmoji) dykEmoji.textContent = content.emoji; var dykCond = document.getElementById('dykCondition'); if (dykCond) dykCond.textContent = content.name; var dykFact = document.getElementById('dykFact'); if (dykFact) dykFact.textContent = content.dykFact; // Social caption var cap = document.getElementById('socialCaption'); if (cap) cap.textContent = content.socialCaption; // Family text var bubble = document.getElementById('familyTextBubble'); if (bubble) bubble.textContent = content.familyText; // Doctor questions var docBody = document.getElementById('doctorGuideBody'); if (docBody) { docBody.innerHTML = content.doctorQuestions.map(function(q, i) { return '
Q' + (i + 1) + ': ' + q + '
'; }).join(''); } } function awardShareCoins(action, coins) { if (!STATE.currentConditionId) return false; var cid = STATE.currentConditionId; if (!STATE.completed[cid].shares) STATE.completed[cid].shares = {}; if (STATE.completed[cid].shares[action]) return false; // already awarded STATE.completed[cid].shares[action] = new Date().toISOString(); STATE.coins = (STATE.coins || 0) + coins; saveState(); updateCoinDisplay(); updateShareCoinsDisplay(); return true; } function shareToSocial() { var content = getShareContent(STATE.currentConditionId); if (!content) return; var shared = false; if (navigator.share) { navigator.share({ title: 'Did You Know? ' + content.name + ' Prevention', text: content.socialCaption, url: 'https://theforceforhealth.com' }).then(function() { shared = true; completeSocialShare(); }).catch(function() { // User cancelled share sheet — fall back to copy copySocialPost(); }); } else { copySocialPost(); } } function copySocialPost() { var content = getShareContent(STATE.currentConditionId); if (!content) return; copyToClipboard(content.socialCaption); completeSocialShare(); } function completeSocialShare() { if (awardShareCoins('social', 5)) { var btn = document.getElementById('shareSocialBtn'); if (btn) { btn.classList.add('done'); btn.innerHTML = ' Shared!'; } var msg = document.getElementById('shareDoneSocial'); if (msg) msg.style.display = 'block'; } } function shareToFamily() { var content = getShareContent(STATE.currentConditionId); if (!content) return; if (navigator.share) { navigator.share({ title: 'Health info about ' + content.name, text: content.familyText }).then(function() { completeFamilyShare(); }).catch(function() { copyFamilyText(); }); } else { copyFamilyText(); } } function copyFamilyText() { var content = getShareContent(STATE.currentConditionId); if (!content) return; copyToClipboard(content.familyText); completeFamilyShare(); } function completeFamilyShare() { if (awardShareCoins('family', 3)) { var btn = document.getElementById('shareFamilyBtn'); if (btn) { btn.classList.add('done'); btn.innerHTML = ' Sent!'; } var msg = document.getElementById('shareDoneFamily'); if (msg) msg.style.display = 'block'; } } function shareDoctorGuide() { var content = getShareContent(STATE.currentConditionId); if (!content) return; var guideText = 'My Discussion Guide for ' + content.name + ':\n\n' + content.doctorQuestions.map(function(q, i) { return (i + 1) + '. ' + q; }).join('\n') + '\n\n(From 360\u00b0 Human: Protect & Prevent BINGO — theforceforhealth.com)'; if (navigator.share) { navigator.share({ title: content.name + ' — Doctor Discussion Guide', text: guideText }).then(function() { completeDoctorShare(); }).catch(function() { copyDoctorGuide(); }); } else { copyToClipboard(guideText); completeDoctorShare(); } } function copyDoctorGuide() { var content = getShareContent(STATE.currentConditionId); if (!content) return; var guideText = 'My Discussion Guide for ' + content.name + ':\n\n' + content.doctorQuestions.map(function(q, i) { return (i + 1) + '. ' + q; }).join('\n'); copyToClipboard(guideText); completeDoctorShare(); } function completeDoctorShare() { if (awardShareCoins('doctor', 5)) { var btn = document.getElementById('shareDoctorBtn'); if (btn) { btn.classList.add('done'); btn.innerHTML = ' Saved!'; } var msg = document.getElementById('shareDoneDoctor'); if (msg) msg.style.display = 'block'; } } function copyToClipboard(text) { if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(function() { showCopyToast(); }).catch(function() { fallbackCopy(text); }); } else { fallbackCopy(text); } } function fallbackCopy(text) { var ta = document.createElement('textarea'); ta.value = text; ta.style.cssText = 'position:fixed;left:-9999px;'; document.body.appendChild(ta); ta.select(); try { document.execCommand('copy'); showCopyToast(); } catch(e) {} document.body.removeChild(ta); } function showCopyToast() { var existing = document.getElementById('copyToast'); if (existing) existing.remove(); var toast = document.createElement('div'); toast.id = 'copyToast'; toast.textContent = 'Copied to clipboard!'; toast.style.cssText = 'position:fixed;bottom:80px;left:50%;transform:translateX(-50%);background:#1e293b;color:white;padding:0.6rem 1.2rem;border-radius:10px;font-size:0.88rem;font-weight:600;z-index:100002;box-shadow:0 4px 12px rgba(0,0,0,0.2);animation:drRobSlideIn 0.25s ease-out;'; document.body.appendChild(toast); setTimeout(function() { if (toast.parentNode) toast.remove(); }, 2000); } function updateShareCoinsDisplay() { if (!STATE.currentConditionId) return; var cid = STATE.currentConditionId; var comp = STATE.completed[cid] || {}; var total = 0; // Pledge coins var pledgeVal = document.getElementById('coinValPledge'); if (comp.pledgeChoice === 'pledge') { total += 5; if (pledgeVal) pledgeVal.textContent = '+5'; } else if (comp.pledgeChoice === 'whynot') { total += 3; if (pledgeVal) pledgeVal.textContent = '+3'; } else if (comp.pledgeChoice === 'skip') { if (pledgeVal) pledgeVal.textContent = '0'; } else { if (pledgeVal) pledgeVal.textContent = '\u2014'; } // Share coins var socialVal = document.getElementById('coinValSocial'); var familyVal = document.getElementById('coinValFamily'); var doctorVal = document.getElementById('coinValDoctor'); if (comp.shares && comp.shares.social) { total += 5; if (socialVal) socialVal.textContent = '+5'; } else { if (socialVal) socialVal.textContent = '\u2014'; } if (comp.shares && comp.shares.family) { total += 3; if (familyVal) familyVal.textContent = '+3'; } else { if (familyVal) familyVal.textContent = '\u2014'; } if (comp.shares && comp.shares.doctor) { total += 5; if (doctorVal) doctorVal.textContent = '+5'; } else { if (doctorVal) doctorVal.textContent = '\u2014'; } var el = document.getElementById('shareCoinsEarned'); if (el) el.textContent = total; } function restoreShareTabState() { if (!STATE.currentConditionId) return; var cid = STATE.currentConditionId; var comp = STATE.completed[cid] || {}; // Restore pledge state if (comp.pledgeChoice) { document.getElementById('pledgePaths').style.display = 'none'; document.getElementById('whyNotPanel').style.display = 'none'; var result = document.getElementById('pledgeResult'); result.style.display = 'block'; if (comp.pledgeChoice === 'pledge') { result.innerHTML = '
\u270a Pledge Taken!
' + '
You are a Force for Health!
'; } else if (comp.pledgeChoice === 'whynot') { result.innerHTML = '
\ud83d\ude4f Feedback Submitted
' + '
Thanks for sharing your thoughts.
'; } else { result.innerHTML = '
\u23ed\ufe0f Skipped
' + '
No worries! Check out the sharing options below.
'; } } else { document.getElementById('pledgePaths').style.display = ''; document.getElementById('whyNotPanel').style.display = 'none'; document.getElementById('pledgeResult').style.display = 'none'; } // Restore share button states ['social', 'family', 'doctor'].forEach(function(action) { var btnId = action === 'social' ? 'shareSocialBtn' : action === 'family' ? 'shareFamilyBtn' : 'shareDoctorBtn'; var msgId = 'shareDone' + action.charAt(0).toUpperCase() + action.slice(1); var btn = document.getElementById(btnId); var msg = document.getElementById(msgId); if (comp.shares && comp.shares[action]) { var label = action === 'social' ? 'Shared!' : action === 'family' ? 'Sent!' : 'Saved!'; if (btn) { btn.classList.add('done'); btn.innerHTML = '\u2713 ' + label; } if (msg) msg.style.display = 'block'; } else { if (btn) btn.classList.remove('done'); if (msg) msg.style.display = 'none'; } }); // Populate share content and update coin display populateShareAssets(); updateShareCoinsDisplay(); } function checkConditionCompletion() { if (!STATE.currentConditionId) return; const completion = STATE.completed[STATE.currentConditionId]; if (completion && completion.learnIt && completion.liveIt && completion.shareIt) { // Mark card as completed const card = document.getElementById(`card-${STATE.currentConditionId}`); if (card) { card.classList.remove('in-progress'); card.classList.add('completed'); } // Check for bingo checkForBingo(); updateProgressUI(); } } function checkForBingo() { const completedCards = new Set( Object.entries(STATE.completed) .filter(([id, status]) => status.learnIt && status.liveIt && status.shareIt) .map(([id]) => CONDITIONS.findIndex(c => c.id === id)) ); let newBingoLines = []; for (const [name, pattern] of Object.entries(BINGO_PATTERNS)) { if (pattern.every(i => completedCards.has(i)) && !STATE.bingoLines.has(name)) { newBingoLines.push(name); STATE.bingoLines.add(name); } } if (newBingoLines.length > 0) { STATE.coins += 50 * newBingoLines.length; triggerBingoAnimation(newBingoLines); updateTrackerUI(); } // Check for full board if (completedCards.size === 16) { STATE.coins += 200; triggerBingoAnimation(['CHAMPION']); } saveState(); } function triggerBingoAnimation(lines) { const alert = document.createElement('div'); alert.className = 'bingo-alert'; alert.innerHTML = `
🎉
BINGO!
${lines.includes('CHAMPION') ? 'Respiratory Champion!' : 'Line Complete!'}
+${lines.includes('CHAMPION') ? '200' : '50'} coins
`; document.body.appendChild(alert); // Confetti createConfetti(50); setTimeout(() => alert.remove(), 3000); } function createConfetti(count) { for (let i = 0; i < count; i++) { const confetti = document.createElement('div'); confetti.className = 'confetti'; confetti.textContent = ['🎉', '❤️', '🏆', '⭐', '💝'][Math.floor(Math.random() * 5)]; confetti.style.left = Math.random() * window.innerWidth + 'px'; confetti.style.top = '-10px'; confetti.style.fontSize = (Math.random() * 1.5 + 1) + 'rem'; confetti.style.animation = `confetti-fall ${3 + Math.random() * 2}s linear forwards`; confetti.style.opacity = Math.random() * 0.7 + 0.3; document.body.appendChild(confetti); setTimeout(() => confetti.remove(), 5000); } } function updateTrackerUI() { document.querySelectorAll('.tracker-item').forEach(item => { const lineKey = item.getAttribute('data-line'); if (STATE.bingoLines.has(lineKey)) { item.classList.add('completed'); item.querySelector('.tracker-item-icon').textContent = '✅'; } }); } function updateProgressUI() { const completed = Object.values(STATE.completed).filter( status => status && status.learnIt && status.liveIt && status.shareIt ).length; const progress = (completed / 16) * 100; document.getElementById('progressFill').style.width = progress + '%'; document.getElementById('progressValue').textContent = `${completed} of 16`; document.getElementById('heroProgress').textContent = completed; document.getElementById('heroBingo').textContent = STATE.bingoLines.size; document.getElementById('heroCoins').textContent = STATE.coins; document.getElementById('bingoLines').textContent = `${STATE.bingoLines.size} of 10`; document.getElementById('totalCoins').textContent = STATE.coins; updateTrackerUI(); } function updateCoinDisplay() { document.getElementById('coinCount').textContent = STATE.coins; document.getElementById('totalCoins').textContent = STATE.coins; document.getElementById('heroCoins').textContent = STATE.coins; } function saveState() { localStorage.setItem('ffh_rs_coins', STATE.coins.toString()); localStorage.setItem('ffh_rs_completed', JSON.stringify(STATE.completed)); localStorage.setItem('ffh_rs_assessments', JSON.stringify(STATE.assessments)); localStorage.setItem('ffh_rs_bingo_lines', JSON.stringify(Array.from(STATE.bingoLines))); } function loadUserLocation() { // Helper: strip trailing " County" from FCC county_name to avoid "Pima County County" function cleanCountyName(raw) { if (!raw) return ''; return raw.replace(/\s+County$/i, '').trim(); } // Helper: resolve county from lat/lon using FCC Area API function resolveCountyFromCoords(lat, lon, fallbackCity, fallbackState) { fetch(`https://geo.fcc.gov/api/census/area?lat=${lat}&lon=${lon}&format=json`) .then(r => { if (!r.ok) throw new Error('FCC API failed'); return r.json(); }) .then(fcc => { let rawCounty = ''; let fips = ''; let state = fallbackState || ''; if (fcc && fcc.results && fcc.results.length > 0) { rawCounty = fcc.results[0].county_name || ''; fips = fcc.results[0].county_fips || ''; if (!state && fcc.results[0].state_name) state = fcc.results[0].state_name; } const county = cleanCountyName(rawCounty); displayCountyData(county, state, fallbackCity, fips); }) .catch(() => { displayCountyData('', fallbackState, fallbackCity, ''); }); } // Helper: render county header + fetch CDC PLACES data function displayCountyData(county, state, city, fips) { // Display name: "Pima County, Arizona" (not "Pima County County") const displayName = county && state ? `${county} County, ${state}` : (city && state ? `${city}, ${state}` : (state || 'Your Location')); STATE.userCounty = county || city; STATE.userState = state; STATE.countyFips = fips; document.getElementById('countyName').textContent = displayName; // Build County Health Rankings link — URL pattern: /health-data/{state}/{county} const stateSlug = (state || '').toLowerCase().replace(/\s+/g, '-'); const countySlug = (county || '').toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''); if (county && state) { document.getElementById('countyMetric').innerHTML = `Heart disease is a leading health concern in ${county} County. See your county's cardiovascular health data below.`; const countyURL = `https://www.countyhealthrankings.org/health-data/${stateSlug}/${countySlug}`; document.getElementById('countyLinkBar').innerHTML = `📊 Full ${county} County Health Report →`; } else if (state) { document.getElementById('countyMetric').innerHTML = `Heart disease is a leading health concern in ${state}.`; document.getElementById('countyLinkBar').innerHTML = `📊 View ${state} Health Rankings →`; } else { document.getElementById('countyMetric').innerHTML = 'Allow location access to see your county health data.'; document.getElementById('countyLinkBar').innerHTML = `📊 Search County Health Rankings →`; } // Fetch CDC PLACES data if we have state + county info if (county && state) { fetchCDCPlacesData(county, state, fips); } } // Fetch embedded CDC PLACES county health data function fetchCDCPlacesData(county, state, fips) { // CDC PLACES County Data 2025 release — Socrata Open Data API // Endpoint: https://data.cdc.gov/resource/swc5-untb.json // Respiratory-relevant measures we want: const measures = ['CHD', 'STROKE', 'BPHIGH', 'HIGHCHOL', 'OBESITY', 'CSMOKING', 'LPA', 'DIABETES']; const stateAbbr = getStateAbbr(state); if (!stateAbbr) return; // Build query — filter by state abbreviation + county name, category = Health Outcomes/Risk Behaviors const apiUrl = `https://data.cdc.gov/resource/swc5-untb.json?stateabbr=${stateAbbr}&$where=countyfips=%27${fips}%27&$limit=50`; fetch(apiUrl) .then(r => { if (!r.ok) throw new Error('CDC API ' + r.status); return r.json(); }) .then(data => { if (!data || data.length === 0) throw new Error('No CDC data'); renderCDCData(data, county, measures); }) .catch(err => { console.log('CDC PLACES fetch failed:', err.message); // Try alternate query without FIPS const altUrl = `https://data.cdc.gov/resource/swc5-untb.json?stateabbr=${stateAbbr}&countyname=${encodeURIComponent(county)}&$limit=50`; fetch(altUrl) .then(r => r.ok ? r.json() : Promise.reject()) .then(data => { if (data && data.length > 0) renderCDCData(data, county, measures); }) .catch(() => { console.log('CDC PLACES alternate also failed'); }); }); } // Render the CDC data into the embedded grid function renderCDCData(data, county, targetMeasures) { const measureLabels = { 'CHD': { label: 'Coronary Heart Disease', icon: '❤️' }, 'STROKE': { label: 'Stroke', icon: '🧠' }, 'BPHIGH': { label: 'High Blood Pressure', icon: '🩺' }, 'HIGHCHOL': { label: 'High Cholesterol', icon: '🔬' }, 'OBESITY': { label: 'Obesity', icon: '⚖️' }, 'CSMOKING': { label: 'Current Smoking', icon: '🚭' }, 'LPA': { label: 'Physical Inactivity', icon: '🏃' }, 'DIABETES': { label: 'Diabetes', icon: '💉' } }; // Filter to our target cardiovascular-relevant measures, crude prevalence const filtered = data.filter(d => targetMeasures.includes(d.measureid) && d.data_value && (d.datavaluetypeid === 'CrdPrv' || d.datavaluetypeid === 'AgeAdjPrv') ); // Deduplicate — prefer CrdPrv (crude prevalence) const byMeasure = {}; filtered.forEach(d => { if (!byMeasure[d.measureid] || d.datavaluetypeid === 'CrdPrv') { byMeasure[d.measureid] = d; } }); const cards = targetMeasures .filter(m => byMeasure[m]) .map(m => { const d = byMeasure[m]; const val = parseFloat(d.data_value).toFixed(1); const info = measureLabels[m] || { label: m, icon: '📊' }; return `
${info.icon} ${val}%
${info.label}
`; }); if (cards.length > 0) { const grid = document.getElementById('countyHealthGrid'); grid.innerHTML = cards.join(''); grid.style.display = 'grid'; } } // State name → abbreviation mapping function getStateAbbr(state) { const map = { 'Alabama':'AL','Alaska':'AK','Arizona':'AZ','Arkansas':'AR','California':'CA', 'Colorado':'CO','Connecticut':'CT','Delaware':'DE','Florida':'FL','Georgia':'GA', 'Hawaii':'HI','Idaho':'ID','Illinois':'IL','Indiana':'IN','Iowa':'IA', 'Kansas':'KS','Kentucky':'KY','Louisiana':'LA','Maine':'ME','Maryland':'MD', 'Massachusetts':'MA','Michigan':'MI','Minnesota':'MN','Mississippi':'MS','Missouri':'MO', 'Montana':'MT','Nebraska':'NE','Nevada':'NV','New Hampshire':'NH','New Jersey':'NJ', 'New Mexico':'NM','New York':'NY','North Carolina':'NC','North Dakota':'ND','Ohio':'OH', 'Oklahoma':'OK','Oregon':'OR','Pennsylvania':'PA','Rhode Island':'RI','South Carolina':'SC', 'South Dakota':'SD','Tennessee':'TN','Texas':'TX','Utah':'UT','Vermont':'VT', 'Virginia':'VA','Washington':'WA','West Virginia':'WV','Wisconsin':'WI','Wyoming':'WY', 'District of Columbia':'DC' }; return map[state] || ''; } // === PRIMARY METHOD: Browser Geolocation API (works on file:// AND https://) === if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( function(pos) { resolveCountyFromCoords(pos.coords.latitude, pos.coords.longitude, '', ''); }, function(geoErr) { console.log('Geolocation denied/unavailable, trying IP lookup...', geoErr.message); ipApiFallback(); }, { timeout: 8000, maximumAge: 300000 } ); } else { ipApiFallback(); } // === FALLBACK METHOD: IP-based geolocation (ipapi.co) === function ipApiFallback() { fetch('https://ipapi.co/json/') .then(r => { if (!r.ok) throw new Error('ipapi failed: ' + r.status); return r.json(); }) .then(data => { const city = data.city || ''; const state = data.region || ''; const lat = data.latitude; const lon = data.longitude; if (lat && lon) { resolveCountyFromCoords(lat, lon, city, state); } else { displayCountyData('', state, city, ''); } }) .catch(err => { console.log('IP lookup also failed:', err.message); document.getElementById('countyName').textContent = 'Your Location'; document.getElementById('countyMetric').innerHTML = 'Allow location access above to see your county health data, or view ' + 'RWJ County Health Rankings to search your county.'; }); } } // Close modal when clicking backdrop + set logos after DOM loads document.addEventListener('DOMContentLoaded', function() { var navLogo = document.getElementById('navLogoImg'); if (navLogo) navLogo.src = FFH_WHITE_LOGO_SRC; var navIcon = document.getElementById('navExplorerIcon'); if (navIcon) navIcon.src = EXPLORER_WHITE_SRC; var drRobModal = document.getElementById('drRobModalAvatar'); if (drRobModal) drRobModal.src = DR_ROB_SRC; document.getElementById('modalBackdrop').addEventListener('click', function(e) { if (e.target === this) closeModal(); }); // Dr. Rob chat is handled by its own backdrop click handler }); // ═════════════════════════════════════════════════════════════ // ASSESSMENT ENGINE // ═════════════════════════════════════════════════════════════ const ASSESSMENT_QUESTIONS = { "rs-asthma": [ { q: "In a healthy person, what happens to the muscles around the airways when they breathe normally?", choices: [ "The airway muscles stay relaxed and open", "The airway muscles tighten and squeeze", "The airway muscles produce extra mucus", "The airway muscles move downward" ], correct: 0, explanation: "In healthy airways, the muscles are relaxed and open, allowing air to flow freely. This is normal physiology." }, { q: "What is the main thing that goes wrong in the airways of someone with asthma?", choices: [ "The airways become inflamed and too sensitive to triggers", "The lungs stop producing oxygen", "The heart pumps blood too slowly", "The nose becomes permanently blocked" ], correct: 0, explanation: "Asthma causes chronic inflammation and hypersensitivity of the airways, making them overreact to triggers." }, { q: "Which of the following is NOT a common trigger for an asthma attack?", choices: [ "Pet fur", "Cold air", "Eating fruit", "Air pollution" ], correct: 2, explanation: "While allergens like pet fur, cold air, and pollution can trigger asthma, eating fruit is not a typical trigger." }, { q: "Which symptom is MOST typical of an asthma attack?", choices: [ "Wheezing and shortness of breath", "High fever and chills", "Stomach pain and nausea", "Rash all over the skin" ], correct: 0, explanation: "Wheezing (a whistling sound when breathing) and shortness of breath are hallmark asthma symptoms." }, { q: "What is one of the best ways to prevent asthma attacks?", choices: [ "Identify triggers and avoid them", "Stop exercising completely", "Take medicine only when symptoms appear", "Never leave your house" ], correct: 0, explanation: "Identifying and avoiding triggers is a key prevention strategy, along with medication as prescribed by doctors." } ], "rs-copd": [ { q: "What are the tiny air sacs in the lungs called, where oxygen and carbon dioxide are exchanged?", choices: [ "Alveoli", "Bronchitis", "Ventricles", "Trachea" ], correct: 0, explanation: "Alveoli are the tiny air sacs where gas exchange happens. COPD destroys these important structures." }, { q: "Which of the following BEST describes what happens in COPD?", choices: [ "The alveolar walls break down and airways become inflamed", "The heart muscle stops working properly", "The brain stops controlling breathing", "The stomach prevents food from moving" ], correct: 0, explanation: "COPD involves destruction of alveoli (emphysema) and inflammation of airways (chronic bronchitis)." }, { q: "What is the PRIMARY risk factor for developing COPD?", choices: [ "Cigarette smoking (85-90% of cases)", "Eating too much salt", "Playing sports too much", "Being too short" ], correct: 0, explanation: "Smoking causes 85-90% of COPD cases. This is by far the biggest risk factor." }, { q: "Which symptom would be MOST concerning in someone with COPD?", choices: [ "A chronic cough that won't go away", "Feeling hungry all the time", "Seeing colors differently", "Having very cold hands" ], correct: 0, explanation: "A chronic cough is a key symptom of COPD, especially in people with a smoking history." }, { q: "What is the MOST important step to prevent COPD?", choices: [ "Quit smoking or never start smoking", "Drink more water", "Eat only vegetables", "Stay indoors at all times" ], correct: 0, explanation: "Quitting smoking is the most powerful way to prevent COPD and slow its progression." } ], "rs-pneumonia": [ { q: "What is the normal job of the macrophages in healthy lungs?", choices: [ "To patrol the airways and attack germs that enter", "To produce oxygen from air", "To control the heart rate", "To make the voice louder" ], correct: 0, explanation: "Macrophages are immune cells that patrol the lungs and kill invading bacteria, viruses, and fungi." }, { q: "What happens inside the alveoli when someone gets pneumonia?", choices: [ "They fill with fluid, pus, and cellular debris instead of air", "They grow bigger to hold more air", "They produce special healing oils", "They turn a different color" ], correct: 0, explanation: "Pneumonia causes the air sacs to fill with fluid and pus, preventing oxygen from being absorbed." }, { q: "Which of these is a major risk factor for getting pneumonia?", choices: [ "Having a weakened immune system", "Having brown eyes instead of blue eyes", "Being left-handed", "Wearing thick clothing" ], correct: 0, explanation: "People with weakened immune systems are at much higher risk for developing pneumonia." }, { q: "Which symptom combination would suggest someone might have pneumonia?", choices: [ "Fever, cough, and shortness of breath", "Itchy skin and sore eyes", "Loud snoring at night", "Pain in the teeth and jaw" ], correct: 0, explanation: "Fever, productive cough, and shortness of breath are classic pneumonia symptoms." }, { q: "What is one of the best ways to prevent pneumonia?", choices: [ "Get the pneumococcal and flu vaccines", "Never go outside", "Wear three layers of clothing", "Eat only cold foods" ], correct: 0, explanation: "Vaccines are among the most effective ways to prevent pneumonia and other respiratory infections." } ], "rs-lung-cancer": [ { q: "In a healthy lung, what normally controls how often lung cells divide?", choices: [ "Growth signals, tumor suppressors, and DNA repair mechanisms", "The amount of food a person eats", "The person's eye color", "The time of day" ], correct: 0, explanation: "Healthy cells have built-in controls (growth signals, suppressors, and repair systems) that keep division regulated." }, { q: "What happens to lung cells when they are exposed to carcinogens from tobacco smoke?", choices: [ "Their DNA is damaged, disabling growth controls, allowing uncontrolled multiplication", "They become better at filtering air", "They grow larger to protect the body", "They move to another part of the body" ], correct: 0, explanation: "Carcinogens damage DNA and disable the cell's natural growth controls, leading to cancer." }, { q: "What percentage of lung cancers are caused by smoking?", choices: [ "About 85%", "About 20%", "About 50%", "About 10%" ], correct: 0, explanation: "Smoking is responsible for about 85% of lung cancer cases. It's by far the biggest risk factor." }, { q: "Which of these would be an EARLY warning sign of lung cancer?", choices: [ "A persistent cough lasting more than 3 weeks", "Temporary tiredness after exercise", "Occasional sneezing", "Mild sore throat in winter" ], correct: 0, explanation: "A persistent cough that doesn't go away can be an early sign of lung cancer and should be checked by a doctor." }, { q: "How can someone best prevent lung cancer?", choices: [ "Never smoke and avoid secondhand smoke exposure", "Exercise more on weekends", "Wear a scarf in winter", "Drink orange juice daily" ], correct: 0, explanation: "Not smoking and avoiding secondhand smoke exposure are the most effective ways to prevent lung cancer." } ], "rs-tb": [ { q: "How does a healthy immune system normally respond to TB bacteria that enters the lungs?", choices: [ "It forms granulomas to wall off and isolate the bacteria", "It immediately kills all the bacteria", "It prevents the bacteria from entering at all", "It converts the bacteria into harmless particles" ], correct: 0, explanation: "The immune system forms granulomas, which are clusters of immune cells that wall off and contain the TB bacteria." }, { q: "In latent TB, where are the TB bacteria and what is happening?", choices: [ "The bacteria are walled off in granulomas, inactive and contained", "The bacteria are actively destroying lung tissue", "The bacteria have died completely", "The bacteria have spread to the brain" ], correct: 0, explanation: "In latent TB, bacteria are contained within granulomas but alive. They can reactivate if immunity weakens." }, { q: "Which group of people is at HIGHEST risk for developing active TB?", choices: [ "People with weakened immune systems, such as those with HIV/AIDS", "People who eat too much meat", "People who live in warm climates", "People who exercise daily" ], correct: 0, explanation: "People with weakened immunity are at high risk because their immune system cannot control latent TB bacteria." }, { q: "Which symptom is MOST typical of active tuberculosis?", choices: [ "A persistent cough lasting 3 or more weeks, often with blood", "Pain in the legs when walking", "Loss of all sense of taste", "Sudden loss of consciousness" ], correct: 0, explanation: "A persistent cough (often with hemoptysis or blood) is a hallmark TB symptom that lasts weeks." }, { q: "What is the MOST important prevention action if someone is exposed to TB?", choices: [ "Get tested for TB infection and follow up care if positive", "Stay outside all day", "Never see the infected person again", "Take vitamins to boost immunity" ], correct: 0, explanation: "Testing is critical because early treatment of latent TB (with antibiotics) prevents active disease from developing." } ], "rs-sleep-apnea": [ { q: "What normally happens to throat muscles during sleep in a healthy person?", choices: [ "They relax slightly but keep the airway open", "They tighten and squeeze the throat", "They disappear completely", "They move up toward the nose" ], correct: 0, explanation: "In healthy sleep, throat muscles naturally relax but not enough to block breathing." }, { q: "What is the main problem that occurs in sleep apnea?", choices: [ "The throat muscles relax too much, causing the airway to collapse and block breathing", "The lungs stop producing oxygen", "The heart rate becomes too slow", "The brain stops sending signals to breathe" ], correct: 0, explanation: "Sleep apnea happens when throat muscles collapse the airway, stopping breathing temporarily." }, { q: "Which of the following is a major risk factor for sleep apnea?", choices: [ "Obesity and excess weight", "Playing video games", "Drinking too much orange juice", "Being right-handed" ], correct: 0, explanation: "Obesity and excess weight, especially around the neck, are major risk factors for sleep apnea." }, { q: "Which symptom would suggest someone might have sleep apnea?", choices: [ "Loud snoring and gasping for air during sleep", "Feeling cold all the time", "Seeing flashing lights", "Pain in the feet" ], correct: 0, explanation: "Loud snoring and episodes of gasping for air during sleep are classic signs of sleep apnea." }, { q: "What is one of the best ways to help prevent sleep apnea?", choices: [ "Achieve and maintain a healthy weight", "Sleep with the lights on", "Stay up as late as possible", "Eat heavy meals before bed" ], correct: 0, explanation: "Weight loss is one of the most effective ways to prevent and reduce sleep apnea severity." } ], "rs-pulmonary-fibrosis": [ { q: "What is the normal structure and function of healthy lung tissue?", choices: [ "Thin and elastic, allowing easy expansion and efficient gas exchange", "Thick and stiff, limiting air movement", "Solid like bone, providing structure", "Hollow like a balloon with no walls" ], correct: 0, explanation: "Healthy lung tissue is thin and elastic, which allows the lungs to expand and allows efficient gas exchange." }, { q: "What happens to the lungs in pulmonary fibrosis?", choices: [ "The lung tissue becomes scarred and thick with dense fibrous tissue that cannot exchange gases", "The lungs become larger and more elastic", "The lungs produce more oxygen", "The lungs shrink and disappear" ], correct: 0, explanation: "Scarring replaces normal lung tissue, making the lungs stiff and unable to function properly." }, { q: "Which occupational exposure is a risk factor for pulmonary fibrosis?", choices: [ "Long-term exposure to silica dust or asbestos", "Typing on a computer keyboard", "Talking on the phone", "Reading books in a library" ], correct: 0, explanation: "Occupational exposures like silica dust and asbestos are known risk factors for pulmonary fibrosis." }, { q: "Which symptom is MOST characteristic of pulmonary fibrosis?", choices: [ "Progressive shortness of breath that gets worse over time", "Temporary itching in the fingers", "Occasional hiccups", "Pain in the lower back" ], correct: 0, explanation: "Progressive shortness of breath that worsens over time is the main symptom of pulmonary fibrosis." }, { q: "How can someone working with occupational hazards help prevent pulmonary fibrosis?", choices: [ "Use proper respiratory protection at work and avoid exposures", "Drink more coffee before work", "Work in a very hot environment", "Skip lunch breaks to work more" ], correct: 0, explanation: "Proper respiratory protective equipment and avoiding hazardous exposures are key prevention strategies." } ], "rs-bronchitis": [ { q: "What is the job of the cilia that line the bronchial tubes?", choices: [ "To move mucus upward like an escalator, trapping and removing particles and pathogens", "To produce oxygen from air", "To control body temperature", "To make sounds for speech" ], correct: 0, explanation: "Cilia are hair-like structures that sweep mucus and trapped particles out of the airways." }, { q: "What happens to the cilia and mucus production in chronic bronchitis?", choices: [ "Smoking destroys the cilia and causes glands to overproduce mucus", "The cilia grow longer and stronger", "Mucus production decreases completely", "The cilia turn different colors" ], correct: 0, explanation: "Smoking damage destroys cilia and causes mucus glands to overproduce, creating a persistent cough." }, { q: "What is the PRIMARY cause of chronic bronchitis?", choices: [ "Cigarette smoking", "Eating ice cream", "Cold weather", "Loud noises" ], correct: 0, explanation: "Smoking is the primary cause of chronic bronchitis. It damages the airways and mucus-clearing system." }, { q: "Which symptom would be MOST typical of someone with chronic bronchitis?", choices: [ "A persistent productive cough lasting 3 or more months", "Pain in the ears", "Temporary vision changes", "Swelling in the legs" ], correct: 0, explanation: "A persistent productive cough (with mucus/phlegm) for 3+ months is the defining symptom of chronic bronchitis." }, { q: "What is the best way to prevent chronic bronchitis?", choices: [ "Quit smoking or never start, and avoid air pollution", "Eat more protein", "Exercise only at night", "Stay in one room all day" ], correct: 0, explanation: "Not smoking and avoiding pollution are the most effective prevention strategies for chronic bronchitis." } ], "rs-flu": [ { q: "What are the THREE main defenses the respiratory tract uses against germs?", choices: [ "Nasal hairs that filter, mucus that traps, and immune cells that destroy", "Strong muscles that squeeze pathogens out", "Acid that burns the germs", "Sound waves that shake germs loose" ], correct: 0, explanation: "The respiratory system has multiple layers of defense: physical filtration, mucus trapping, and immune cells." }, { q: "What does the influenza virus do when it enters the respiratory tract?", choices: [ "It attaches to cells, invades them, and uses their machinery to reproduce", "It turns into harmless water droplets", "It strengthens the immune system", "It prevents the lungs from working" ], correct: 0, explanation: "Flu viruses hijack cells and force them to produce more virus, which triggers the immune response." }, { q: "What causes most of the symptoms of the flu?", choices: [ "The body's immune response to the virus, not the virus itself", "The virus directly damaging every organ", "Bacteria growing in the lungs", "The cold weather affecting the body" ], correct: 0, explanation: "Most flu symptoms (fever, body aches, fatigue) come from the immune system's response, not the virus directly." }, { q: "What is a CLASSIC symptom pattern of influenza?", choices: [ "Sudden fever (101-104°F), cough, sore throat, and body aches", "Gradual increase in energy and appetite", "Pain only in the right knee", "Loss of ability to see colors" ], correct: 0, explanation: "Sudden high fever along with cough, sore throat, and body aches are hallmark flu symptoms." }, { q: "What is the MOST effective way to prevent getting the flu?", choices: [ "Get the annual flu vaccine", "Stay indoors all winter", "Wear heavy coats constantly", "Never eat cold foods" ], correct: 0, explanation: "The annual flu vaccine is the most effective prevention method against influenza infection." } ], "rs-covid": [ { q: "What are ACE2 receptors and where are they found in the body?", choices: [ "Proteins on lung cells that also exist in the heart, kidneys, and blood vessels", "Viruses that attack the immune system", "Bones that support the chest", "Muscles that help breathing" ], correct: 0, explanation: "ACE2 receptors are found throughout the body, especially in the lungs, and COVID-19 uses them to enter cells." }, { q: "How does the SARS-CoV-2 virus enter lung cells?", choices: [ "Its spike protein binds to ACE2 receptors on the cell surface", "It eats through the cell wall", "It enters through the mouth directly", "It floats through undefended cells" ], correct: 0, explanation: "The spike protein is like a key that unlocks the ACE2 receptor, allowing the virus to enter the cell." }, { q: "What can happen in severe COVID-19 infections?", choices: [ "The immune system overreacts, causing massive inflammation that floods alveoli with fluid", "The virus kills all immune cells instantly", "The lungs grow extra large", "The heart stops beating immediately" ], correct: 0, explanation: "A cytokine storm (excessive immune response) causes severe inflammation and fluid in the lungs." }, { q: "Which of these is a COMMON symptom of COVID-19?", choices: [ "Loss of taste or smell", "Permanent loss of all senses", "Ability to see in the dark", "Sudden ability to hear high frequencies" ], correct: 0, explanation: "Many COVID-19 patients report temporary loss of taste and smell, which is a distinctive symptom." }, { q: "What is the MOST important step to prevent severe COVID-19?", choices: [ "Get fully vaccinated and receive booster shots", "Stay in complete isolation forever", "Wear 10 layers of protective gear", "Never breathe outside air" ], correct: 0, explanation: "Vaccination and boosters are the most effective way to prevent severe COVID-19 illness." } ], "rs-allergic-rhinitis": [ { q: "What is the normal job of the nasal passages?", choices: [ "To warm, humidify, and filter air, and to help distinguish smells", "To produce sound for speaking", "To control body temperature", "To produce tears for the eyes" ], correct: 0, explanation: "The nose prepares air before it reaches the lungs by warming, humidifying, and filtering it." }, { q: "What mistake does the immune system make in allergic rhinitis?", choices: [ "It identifies harmless substances (like pollen) as dangerous threats", "It stops protecting the body from real germs", "It only works on weekends", "It makes the nose grow larger" ], correct: 0, explanation: "Allergic rhinitis occurs when the immune system mistakenly attacks harmless allergens like pollen." }, { q: "What do mast cells release when triggered by allergen exposure?", choices: [ "Histamine and other chemicals that cause itching, swelling, and congestion", "Oxygen that makes you stronger", "Poison that kills allergens", "Glue that seals up the nose" ], correct: 0, explanation: "Histamine and related chemicals cause the inflammation and symptoms of allergic rhinitis." }, { q: "Which of these is a TYPICAL symptom of allergic rhinitis?", choices: [ "Sneezing, nasal congestion, and itchy nose and throat", "Permanent blue discoloration of the nose", "Inability to smell anything ever again", "Constant severe nosebleeds" ], correct: 0, explanation: "Sneezing, congestion, and itching are the classic symptoms of allergic rhinitis." }, { q: "What is the BEST first step in managing allergic rhinitis?", choices: [ "Identify your personal allergen triggers and avoid them", "Move to a different planet", "Never use your nose again", "Take medicine without knowing what you're allergic to" ], correct: 0, explanation: "Identifying and avoiding triggers is the foundation of allergic rhinitis management." } ], "rs-pneumothorax": [ { q: "What are the pleura and what is their function?", choices: [ "Two thin membranes surrounding the lungs with fluid between them that keeps the lungs expanded", "Bones in the chest that protect the heart", "Muscles that pump air into the lungs", "Organs that filter blood" ], correct: 0, explanation: "The pleura are membranes with negative pressure between them that keeps the lungs inflated against the chest wall." }, { q: "What happens during a pneumothorax?", choices: [ "Air leaks into the pleural space, destroying negative pressure and causing lung collapse", "The lungs fill with water", "The heart moves to the other side", "All the air escapes from the body" ], correct: 0, explanation: "A pneumothorax occurs when air enters the pleural space, causing the lung to collapse." }, { q: "Who is MOST likely to experience a spontaneous pneumothorax?", choices: [ "Young, tall, thin males", "Short, overweight elderly women", "Children under age 5", "Professional athletes only" ], correct: 0, explanation: "Primary spontaneous pneumothorax is most common in young, tall, thin males." }, { q: "Which symptom would be MOST alarming and suggest a pneumothorax?", choices: [ "Sudden onset chest pain with sudden shortness of breath", "Mild itching on the back", "Sore throat after eating", "Occasional dizziness when standing" ], correct: 0, explanation: "Sudden sharp chest pain combined with sudden shortness of breath is a red flag for pneumothorax." }, { q: "What can someone do to reduce their pneumothorax risk?", choices: [ "Quit smoking, avoid lung disease, and prevent chest injuries", "Sleep 20 hours a day", "Never move or exercise", "Wrap the entire body in plastic" ], correct: 0, explanation: "Avoiding smoking, treating lung disease, and preventing injuries reduce pneumothorax risk." } ], "rs-pertussis": [ { q: "How do the mucociliary escalator and immune system normally prevent whooping cough?", choices: [ "They prevent bacteria from colonizing the airways", "They make the air taste bad so bacteria leave", "They turn the bacteria into food", "They freeze the bacteria" ], correct: 0, explanation: "The mucociliary system and immune surveillance are the body's natural defenses against bacterial colonization." }, { q: "What do pertussis bacteria do when they colonize the airways?", choices: [ "They produce toxins that paralyze cilia and cause inflammation and damage", "They turn the lungs white", "They make the person grow taller", "They clean the airways" ], correct: 0, explanation: "Pertussis toxins disable the ciliary escalator and damage the airway lining, causing the characteristic cough." }, { q: "Why is pertussis vaccine important if immunity can fade over time?", choices: [ "Booster shots (like Tdap) maintain immunity and protect communities", "Once vaccinated, you have lifelong immunity", "Vaccines are only needed for infants", "The vaccine prevents all diseases forever" ], correct: 0, explanation: "Vaccine immunity wanes, so boosters (Tdap every 10 years) maintain protection." }, { q: "What is the MOST distinctive symptom of pertussis (whooping cough)?", choices: [ "A characteristic 'whooping' cough sound followed by gasping", "A gentle tickling sensation", "Temporary loss of the ability to walk", "Skin that changes color to green" ], correct: 0, explanation: "The characteristic 'whoop' sound when breathing in after coughing fits is the hallmark of pertussis." }, { q: "How can a pregnant woman help protect her newborn from pertussis?", choices: [ "Get Tdap vaccine in the 3rd trimester to pass antibodies to the baby", "Stay indoors during pregnancy", "Never visit hospitals", "Avoid all vaccinations during pregnancy" ], correct: 0, explanation: "Tdap vaccination during pregnancy transfers protective antibodies to the newborn." } ], "rs-ards": [ { q: "What is special about the alveolar-capillary membrane?", choices: [ "It is incredibly thin (0.5 micrometers), allowing rapid gas exchange while keeping fluid out", "It is thick like a wall, blocking any gas exchange", "It is solid and prevents any air movement", "It can stretch to 10 times its normal size" ], correct: 0, explanation: "This ultra-thin barrier is essential for efficient gas exchange and must stay dry to work." }, { q: "What happens to the alveolar-capillary membrane in ARDS?", choices: [ "Severe inflammation damages the membrane, allowing protein-rich fluid to flood the alveoli", "The membrane becomes thicker and stronger", "The membrane disappears completely", "The membrane produces extra oxygen" ], correct: 0, explanation: "Damage to the membrane allows fluid to leak into air sacs, preventing oxygen exchange." }, { q: "Which condition is the LEADING cause of ARDS?", choices: [ "Sepsis (severe infection)", "Seasonal allergies", "Eating too much salt", "Lack of sleep" ], correct: 0, explanation: "Sepsis is the leading cause of ARDS, followed by severe pneumonia and other critical conditions." }, { q: "What would be the MOST severe symptom of ARDS?", choices: [ "Severe shortness of breath even at rest, with rapid breathing and confusion", "Mild itching on the arm", "Occasional cough in the morning", "Slight tiredness after meals" ], correct: 0, explanation: "ARDS causes severe respiratory failure requiring intensive care and often mechanical ventilation." }, { q: "How can the risk of developing ARDS be reduced?", choices: [ "Prevent infections like sepsis and pneumonia through early recognition and treatment", "Avoid all physical activity", "Never eat protein", "Stay in a completely sealed room" ], correct: 0, explanation: "Early treatment of sepsis and pneumonia are key to preventing ARDS development." } ], "rs-sarcoidosis": [ { q: "What is the normal, healthy job of granulomas in the immune system?", choices: [ "To wall off and isolate persistent infections like tuberculosis", "To produce oxygen for the body", "To filter blood from the heart", "To control body temperature" ], correct: 0, explanation: "Granulomas are a normal immune response that isolates certain infections." }, { q: "What is unusual about sarcoidosis granulomas compared to normal granulomas?", choices: [ "They form without an identifiable trigger (no infection causing them)", "They are much larger than normal", "They are filled with water", "They turn the skin blue" ], correct: 0, explanation: "In sarcoidosis, granulomas appear without an obvious cause like infection." }, { q: "Which group of people is MOST commonly affected by sarcoidosis?", choices: [ "African Americans and those of African heritage", "People who live in cold climates", "Children under age 2", "People who exercise excessively" ], correct: 0, explanation: "African Americans have significantly higher rates of sarcoidosis than other populations." }, { q: "Which organs are MOST commonly affected in sarcoidosis?", choices: [ "The lungs and lymph nodes", "Only the stomach", "Only the feet and toes", "Only the brain" ], correct: 0, explanation: "Although sarcoidosis can affect any organ, the lungs and lymph nodes are most commonly involved." }, { q: "How can someone with sarcoidosis manage their condition?", choices: [ "Take anti-inflammatory medications, monitor for progression, and manage symptoms", "Never see a doctor again", "Only eat raw vegetables", "Stay outdoors all day and night" ], correct: 0, explanation: "Regular monitoring and anti-inflammatory treatment are key to managing sarcoidosis." } ], "rs-pe-respiratory": [ { q: "How is the respiratory system designed to protect against air pollution particles?", choices: [ "Nasal passages filter large particles, while the mucociliary system clears smaller ones from airways", "The lungs are completely sealed and prevent all particles", "The nose produces acid that burns particles", "Particles are invisible and ignored by the body" ], correct: 0, explanation: "The respiratory system has graduated defenses, but very fine particles can bypass all of them." }, { q: "What happens when fine particulate matter (PM2.5) reaches the alveoli?", choices: [ "It lodges deep in the alveoli and triggers chronic inflammation and DNA damage", "It passes harmlessly through the body", "It strengthens the lungs", "It turns the lungs pink" ], correct: 0, explanation: "PM2.5 bypasses natural defenses and causes chronic inflammation and damage to lung cells." }, { q: "Which group is at HIGHEST risk for respiratory damage from air pollution?", choices: [ "People with pre-existing lung disease or who live near major pollution sources", "People who live on mountains", "People who exercise never", "People with perfect eyesight" ], correct: 0, explanation: "Those with existing lung disease or high pollution exposure are most vulnerable to additional harm." }, { q: "What is a typical symptom of air pollution-related respiratory disease?", choices: [ "Increased cough and shortness of breath, especially during poor air quality days", "Permanent loss of voice", "Inability to see colors", "Sudden growth spurt" ], correct: 0, explanation: "Air pollution worsens respiratory symptoms, particularly when air quality is worst." }, { q: "What is one practical way to reduce personal exposure to air pollution?", choices: [ "Check air quality index daily and avoid outdoor exercise during poor quality days", "Move to a different planet", "Stay awake 24 hours a day", "Wear a special helmet always" ], correct: 0, explanation: "Monitoring air quality and limiting outdoor exposure during poor air quality is an effective personal strategy." } ] }; if (typeof module !== 'undefined' && module.exports) { module.exports = { ASSESSMENT_QUESTIONS }; } const ASSESS_STATE = { pre: { currentQ: 0, answers: [], submitted: false }, post: { currentQ: 0, answers: [], submitted: false, attempts: 0 } }; function startPreAssessment(conditionId) { var questions = ASSESSMENT_QUESTIONS[conditionId]; if (!questions) { proceedToModal(); return; } ASSESS_STATE.pre = { currentQ: 0, answers: new Array(5).fill(-1), submitted: false }; // Check if pre-assessment already taken var assessData = STATE.assessments && STATE.assessments[conditionId]; if (assessData && typeof assessData.preScore === 'number') { proceedToModal(); return; } // Use the existing static overlay HTML — just set dynamic content var coinImg = document.getElementById('preCheckCoin'); if (coinImg) coinImg.src = HUMAN_COIN_SRC; var robImg = document.getElementById('drRobAvatar'); if (robImg) robImg.src = DR_ROB_SRC; document.getElementById('preAssessTitle').textContent = STATE.currentConditionName + ' — What Do You Know?'; renderAssessQuestion('pre', conditionId); document.getElementById('preAssessmentOverlay').classList.add('active'); } function startPostAssessment() { const conditionId = STATE.currentConditionId; const questions = ASSESSMENT_QUESTIONS[conditionId]; if (!questions) return; ASSESS_STATE.post = { currentQ: 0, answers: new Array(5).fill(-1), submitted: false, attempts: (STATE.assessments?.[conditionId]?.postAttempts || 0) }; var postCoinImg = document.getElementById('postCheckCoin'); if (postCoinImg) postCoinImg.src = HUMAN_COIN_SRC; document.getElementById('postAssessTitle').textContent = STATE.currentConditionName + ' — Prove What You Learned!'; document.getElementById('postResults').style.display = 'none'; document.getElementById('postAssessNav').style.display = 'flex'; renderAssessQuestion('post', conditionId); document.getElementById('postAssessmentOverlay').classList.add('active'); } function renderAssessQuestion(type, conditionId) { const questions = ASSESSMENT_QUESTIONS[conditionId || STATE.currentConditionId]; const state = ASSESS_STATE[type]; const q = questions[state.currentQ]; const letters = ['A', 'B', 'C', 'D']; // Progress dots const dotsHtml = questions.map((_, i) => { let cls = 'dot'; if (i === state.currentQ) cls += ' active'; else if (state.answers[i] >= 0) { if (state.submitted) { cls += state.answers[i] === questions[i].correct ? ' answered' : ' wrong'; } else { cls += ' answered'; } } return '
'; }).join(''); document.getElementById(type + 'ProgressDots').innerHTML = dotsHtml; // Question let html = '
'; html += '
Question ' + (state.currentQ + 1) + ' of 5
'; html += '
' + q.q + '
'; q.choices.forEach((choice, idx) => { let btnClass = 'choice-btn'; let disabled = ''; if (state.submitted) { disabled = 'disabled'; if (idx === q.correct) btnClass += ' correct-reveal'; else if (state.answers[state.currentQ] === idx) btnClass += ' wrong-reveal'; else btnClass += ' wrong-reveal'; if (state.answers[state.currentQ] === idx) btnClass += ' selected'; } else if (state.answers[state.currentQ] === idx) { btnClass += ' selected'; } html += ''; }); // Show explanation after submission if (state.submitted) { const isCorrect = state.answers[state.currentQ] === q.correct; html += '
'; html += (isCorrect ? '✅ Correct! ' : '❌ The correct answer is ' + letters[q.correct] + '. ') + q.explanation; html += '
'; } html += '
'; document.getElementById(type + 'QuestionArea').innerHTML = html; // Nav buttons document.getElementById(type + 'PrevBtn').style.visibility = state.currentQ > 0 ? 'visible' : 'hidden'; const nextBtn = document.getElementById(type + 'NextBtn'); if (state.submitted && state.currentQ === 4) { nextBtn.textContent = type === 'pre' ? 'Start Learning →' : 'See Results →'; nextBtn.disabled = false; } else if (state.submitted) { nextBtn.textContent = 'Next Question →'; nextBtn.disabled = false; } else { nextBtn.textContent = 'Select an answer →'; nextBtn.disabled = state.answers[state.currentQ] < 0; } } function selectAssessAnswer(type, idx) { const state = ASSESS_STATE[type]; if (state.submitted) return; state.answers[state.currentQ] = idx; renderAssessQuestion(type, STATE.currentConditionId); // Auto-submit after selection to show answer immediately state.submitted = true; renderAssessQuestion(type, STATE.currentConditionId); } function nextAssessQuestion(type) { const state = ASSESS_STATE[type]; if (state.currentQ === 4 && state.submitted) { // Assessment complete finishAssessment(type); return; } if (state.submitted) { // Move to next question, reset submitted for the new question state.currentQ++; // Check if this question was already answered if (state.answers[state.currentQ] >= 0) { state.submitted = true; // Already answered, show in submitted state } else { state.submitted = false; } } renderAssessQuestion(type, STATE.currentConditionId); } function prevAssessQuestion(type) { const state = ASSESS_STATE[type]; if (state.currentQ > 0) { state.currentQ--; state.submitted = state.answers[state.currentQ] >= 0; renderAssessQuestion(type, STATE.currentConditionId); } } function finishAssessment(type) { const conditionId = STATE.currentConditionId; const questions = ASSESSMENT_QUESTIONS[conditionId]; const state = ASSESS_STATE[type]; // Calculate score let correct = 0; state.answers.forEach((a, i) => { if (a === questions[i].correct) correct++; }); const score = correct; const pct = Math.round((correct / 5) * 100); // Initialize assessment tracking if (!STATE.assessments) STATE.assessments = {}; if (!STATE.assessments[conditionId]) { STATE.assessments[conditionId] = { preScore: null, postScore: null, postAttempts: 0, postPassed: false }; } if (type === 'pre') { STATE.assessments[conditionId].preScore = score; // Award 5 coins for completing the Quick Pre-Check STATE.coins = (STATE.coins || 0) + 5; saveState(); updateCoinDisplay(); // Show coin celebration briefly before proceeding var card = document.querySelector('#preAssessmentOverlay .assessment-card'); var celebHTML = '
' + '
' + 'Coin' + '
' + '

+5 Coins Earned!

' + '

Pre-Check complete — square unlocked!

' + '
Score: ' + score + '/5 (' + pct + '%)
' + '
'; card.innerHTML = celebHTML; var celebCoin = document.getElementById('celebCoinImg'); if (celebCoin) celebCoin.src = HUMAN_COIN_SRC; setTimeout(function() { document.getElementById('preAssessmentOverlay').classList.remove('active'); proceedToModal(); }, 1800); } else { // Post assessment STATE.assessments[conditionId].postAttempts++; STATE.assessments[conditionId].postScore = Math.max(STATE.assessments[conditionId].postScore || 0, score); const passed = score >= 4; if (passed) { STATE.assessments[conditionId].postPassed = true; } saveState(); // Show results const preScore = STATE.assessments[conditionId].preScore ?? '—'; const improvement = typeof preScore === 'number' ? score - preScore : null; document.getElementById('postAssessNav').style.display = 'none'; let resultsHtml = '
'; resultsHtml += '' + score + '/5'; resultsHtml += '' + pct + '%
'; if (passed) { resultsHtml += '

🎉 You Passed!

'; } else { resultsHtml += '

Not quite — you need 4/5 to pass

'; } resultsHtml += '
Pre-Assessment Score: ' + preScore + '/5
'; resultsHtml += '
Post-Assessment Score: ' + score + '/5
'; resultsHtml += '
Attempt #' + STATE.assessments[conditionId].postAttempts + '
'; if (improvement !== null && improvement > 0) { resultsHtml += '
📈 +' + improvement + ' point improvement!
'; } else if (improvement !== null && improvement === 0) { resultsHtml += '
📊 Same score as pre-assessment
'; } if (passed) { resultsHtml += ''; } else { resultsHtml += ''; resultsHtml += '

Review the Learn It tab and try again — answers are shown so you can learn!

'; } document.getElementById('postResults').innerHTML = resultsHtml; document.getElementById('postResults').style.display = 'block'; } } function retryPostAssessment() { document.getElementById('postAssessmentOverlay').classList.remove('active'); // Small delay then restart setTimeout(() => startPostAssessment(), 300); } function claimPostAssessment() { document.getElementById('postAssessmentOverlay').classList.remove('active'); // Mark Share It as complete and trigger the pledge const conditionId = STATE.currentConditionId; if (conditionId) { STATE.completed[conditionId].shareIt = true; // Award coins STATE.coins += 25; updateCoinDisplay(); // Update pledge button const btn = document.getElementById('pledgeBtn'); if (btn && !btn.classList.contains('taken')) { btn.classList.add('taken'); btn.textContent = '✓ Pledge Taken!'; } updateCompletionTracker(); saveState(); checkConditionCompletion(); } // Update the post-assessment section to show passed state updatePostAssessSection(); } function updatePostAssessSection() { const conditionId = STATE.currentConditionId; if (!conditionId) return; const assessData = STATE.assessments?.[conditionId]; const section = document.getElementById('postAssessmentSection'); if (!section) return; if (assessData && assessData.postPassed) { section.className = ''; section.style.cssText = 'text-align:center; padding:1.5rem; background:linear-gradient(135deg, #dcfce7, #f0fdf4); border-radius:15px; border:2px solid var(--green);'; section.innerHTML = '
' + '

Assessment Passed!

' + '

Pre-Score: ' + (assessData.preScore ?? '—') + '/5 → Post-Score: ' + (assessData.postScore ?? '—') + '/5

' + '

Attempts: ' + assessData.postAttempts + '

'; } else if (assessData && assessData.postAttempts > 0) { document.getElementById('attemptCounter').textContent = 'Previous attempts: ' + assessData.postAttempts + ' | Best score: ' + (assessData.postScore || 0) + '/5'; } }
Dr. Rob
Dr. Rob
AI Lesson Guide • Health Guide
360° Human Explorer Coin
🪙 Earn 5 Coins
Quick Pre-Check

Health Literacy Check

Complete this quick check to unlock the square and earn coins!
Don't worry — this is just to see what you already know.
Dr. Rob
Dr. Rob — AI Education Guide Official 360° Bingo Challenge Guide
Need help? Dr. Rob is always available in the top right of the Bingo Square!
360° Human Explorer Coin
🪙 Earn 10 Coins
Post-Assessment

Prove What You Learned!

Show what you've learned! Score 4/5 or better to claim your square and earn bonus coins.