1(function () { 2 'use strict'; 3 4 const themeKey = 'make-qr-theme'; 5 const financeTools = new Set([ 6 'finance-calculator.html', 'mortgage-calculator.html', 'loan-calculator.html', 7 'auto-loan-calculator.html', 'compound-interest-calculator.html', 8 'investment-calculator.html', 'retirement-calculator.html', 9 '401k-calculator.html', 'amortization-calculator.html', 10 'mortgage-payoff-calculator.html', 'payment-calculator.html', 11 'interest-calculator.html', 'inflation-calculator.html', 'tax-calculator.html', 12 'salary-calculator.html', 'debt-calculator.html', 'credit-card-calculator.html', 13 'currency-calculator.html' 14 ]); 15 const healthTools = new Set([ 16 'bmi-calculator.html', 'calorie-calculator.html', 'body-fat-calculator.html', 17 'bmr-calculator.html', 'pregnancy-calculator.html', 18 'pregnancy-weight-gain-calculator.html', 'target-heart-rate-calculator.html', 19 'protein-calculator.html', 'ideal-weight-calculator.html', 20 'macro-calculator.html', 'pace-calculator.html', 'water-calculator.html', 21 'height-calculator.html' 22 ]); 23 24 function preferredTheme() { 25 const saved = localStorage.getItem(themeKey); 26 if (saved === 'dark' || saved === 'light') return saved; 27 return 'light'; 28 } 29 30 function applyTheme(theme) { 31 document.documentElement.dataset.theme = theme; 32 document.documentElement.style.colorScheme = theme; 33 document.querySelectorAll('[data-calculator-theme]').forEach(button => { 34 const dark = theme === 'dark'; 35 button.textContent = dark ? 'â' : 'â¾'; 36 button.setAttribute('aria-label', dark ? 'Use light mode' : 'Use dark mode'); 37 button.setAttribute('aria-pressed', String(dark)); 38 }); 39 } 40 41 function addAccuracyNotice() { 42 const filename = location.pathname.split('/').pop() || 'index.html'; 43 let message = ''; 44 45 if (filename === 'currency-calculator.html') { 46 message = 'Reference only: this calculator uses built-in exchange rates, not live market data. Confirm the current rate before a transaction.'; 47 } else if (financeTools.has(filename)) { 48 message = 'Estimate only: financial results depend on the values and assumptions entered. Verify important decisions with current official information or a qualified professional.'; 49 } else if (healthTools.has(filename)) { 50 message = 'General information only: this result is not a medical diagnosis or a substitute for advice from a qualified healthcare professional.'; 51 } 52 53 if (!message) return; 54 const notice = document.createElement('aside'); 55 notice.className = 'makeqr-calculator-notice'; 56 notice.setAttribute('role', 'note'); 57 notice.textContent = message; 58 const footer = document.querySelector('footer'); 59 (footer || document.body).insertAdjacentElement(footer ? 'beforebegin' : 'beforeend', notice); 60 } 61 62 applyTheme(preferredTheme()); 63 64 document.addEventListener('DOMContentLoaded', function () { 65 applyTheme(preferredTheme()); 66 document.querySelectorAll('[data-calculator-theme]').forEach(button => { 67 button.addEventListener('click', function () { 68 const next = document.documentElement.dataset.theme === 'dark' ? 'light' : 'dark'; 69 localStorage.setItem(themeKey, next); 70 applyTheme(next); 71 }); 72 }); 73 addAccuracyNotice(); 74 }); 75 76 if ('serviceWorker' in navigator && location.protocol !== 'file:') { 77 addEventListener('load', () => { 78 navigator.serviceWorker.register('/sw.js', {scope: '/'}) 79 .catch(error => console.warn('Service worker registration failed:', error)); 80 }); 81 } 82})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.