LooseStool

Covid19 Risk By Age (Alberta) - bookmarklet (javascript)

Sep 25th, 2021 (edited)
1,641
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // javascript:void function(){var a,b={Alberta:"Severe Outcomes table"}.Alberta,c={Alberta:"#severe-outcomes"}.Alberta||"",d={Alberta:`alberta.ca/stats/covid-19-alberta-statistics.htm${c}`}.Alberta,e={Alberta:"#main #summary tr"}.Alberta,f={Alberta:function(a){var b=t(a[0]);if(10<a.length&&"Unknown"!=b){var c=m.length;m[c]=b.replace(/ years?/,"").replace(/Total/,"OVERALL"),n[c]=1*t(a[8]),o[c]=1*t(a[1]),p[c]=w(n[c],o[c]),q[c]=x(p[c]),r[c]=1-p[c]}}}.Alberta,g={Alberta:/^(?:Under (\d)|(\d+)\+|(\d+)-(\d+))$/}.Alberta,h={Alberta:0}.Alberta,j={Alberta:1}.Alberta,k={Alberta:3}.Alberta,l={Alberta:function(a,b){return a<b[1]||a>=b[2]||a>=b[k]&&a<=b[k+1]}}.Alberta,m=[],n=[],o=[],p=[],q=[],r=[],s=function(a,b){return(b||document).querySelectorAll(a)},t=function(a,b){return a&&a[b||"innerText"]},u=function(a,b){return`${a} ${b}${1==a?"":"s"}`},v=function(b,c){return isNaN(parseInt(b))?c===a?-1:c:parseInt(b)},w=function(a,b){return Math.max(a/b,0)||0},x=function(a){return a&&`1 in ${1/a}`||"ZERO"},y=function(){s(e).forEach(function(a){f(s("td",a))})},z=function(a){var b=!1,c=v(a);return 0>c?b:(m.forEach(function(a,d){var e=a.match(g)||[];!1===b&&(b=l(c,e)&&d)}),b)},A=function(a,b,c,d,e,f){return`${a}:\t${u(b,"death")} in ${u(c,"case")} = CFR ${100*d}%\n(risk: ${e}, survival rate ${100*f}%)`},B=function(a){var b="",e=m[a].match(g)||[],f=1*e[k+1]+1||0;if(f){for(var h,l=0,p=0,q=j;q<=a;q++)l+=n[q],p+=o[q];b=` ; \n\n${A(`Under ${f}`,l,p,h=w(l,p),x(h),1-h)}`}return b},C=function(a){var b=A(m[a],n[a],o[a],p[a],q[a],r[a]),c=B(a);return`\n${b}${c}\n`},D=function(b,c){var d=v(z(b),h),e=C(d),f=e.replace(/[\t ;]+/g," "),g=e.replace(/[\t \n]+/g," ").trim();return console.log(`${e.replace(";","")}\n`),e=c===a?prompt(f,g):null,null==e?-1:b};(function(c){if(c===a&&0>location.href.indexOf(d))return alert(`\nTry again after ${b} has loaded:\n\n${d}`),location.href=`https://${d}`;y();for(var e=0;0<=v(e);){var f=c===a?prompt("\nCOVID19 risk/survival based on Alberta stats:\n\nenter AGE [Cancel to quit]\n"):c;e=D(f,c)}})()}();
  2.  
  3.  
  4.  
  5. // https://pastebin.com/TAfjQdth = "Covid19 Risk By Age (Alberta) - bookmarklet (javascript)"
  6.  
  7. // TODO: adapt to other "where" values, to process the other major provinces as well:
  8. // BC, Ontario, Quebec, Sask, Manitoba -- haven't looked into how easy it is to grab and summarize similar data from their Official Covid Stats websites' tables...
  9. // Maybe USA states too? esp. NY, CA, FL, TX
  10.  
  11. void function(){
  12.  
  13.  
  14.  
  15. var where = "Alberta"
  16.  
  17. , pageName = {
  18.     Alberta: "Severe Outcomes table"
  19. }[where]
  20.  
  21. , hash = {
  22.     Alberta: "#severe-outcomes"
  23. }[where] || ""
  24.  
  25. , url = {
  26.     Alberta: `alberta.ca/stats/covid-19-alberta-statistics.htm${hash}`
  27. }[where]
  28.  
  29. , selSummaryRows = {
  30.     Alberta: "#main #summary tr"
  31. }[where]
  32.  
  33. , addRow = {
  34.     Alberta: function(cells) {
  35.         var ageGroup = txt(cells[0])
  36.         if(cells.length > 10 && ageGroup != "Unknown") {
  37.             var i = ageGroups.length;
  38.             ageGroups[i] = ageGroup.replace(/ years?/, "").replace(/Total/, "OVERALL");
  39.             deaths[i] = 1 * txt(cells[8]);
  40.             cases[i] = 1 * txt(cells[1]);
  41.             CFR[i] = div(deaths[i], cases[i]);  // {Alberta: sanityTestCFRpercent[i] = txt(cells[9])}
  42.             chance[i] = getChance(CFR[i]);
  43.             survival[i] = 1 - CFR[i]
  44.         }
  45.     }
  46. }[where]
  47.  
  48. , reGroupLabels = {
  49.     Alberta: /^(?:Under (\d)|(\d+)\+|(\d+)-(\d+))$/
  50. }[where]
  51.  
  52. , groupIndexOverall = {
  53.     Alberta: 0
  54. }[where]
  55.  
  56. , firstGroupIndexWithRange = {
  57.     Alberta: 1
  58. }[where]
  59.  
  60. , matchIndexForRange = {
  61.     Alberta: 3
  62. }[where]
  63.  
  64. , isAgeGroup = {
  65.     Alberta: function(age, matches) { return age < matches[1] || age >= matches[2] || (age >= matches[matchIndexForRange] && age <= matches[matchIndexForRange + 1]); }
  66. }[where]
  67.  
  68.  
  69.  
  70. , u = undefined
  71.  
  72. , message = `\nCOVID19 risk/survival based on ${where} stats:\n\nenter AGE [Cancel to quit]\n`
  73.  
  74. , ageGroups = [], deaths = [], cases = [], CFR = [], chance = [], survival = [] // , sanityTestCFRpercent = []
  75.  
  76. , qs = function(selectors, el) { return (el || document).querySelectorAll(selectors); }
  77.  
  78. , txt = function(el, attribute) { return el && el[attribute || "innerText"]; }  // || "textContent"
  79.  
  80. , plural = function(n, s) { return `${n} ${s}${n != 1 ? "s" : ""}`; }
  81.  
  82. , num = function(v, def) { return isNaN(parseInt(v)) ? (def === u ? -1 : def) : parseInt(v); }
  83.  
  84. , div = function(num, by) { return Math.max(num / by, 0) || 0; }
  85.  
  86. , getChance = function(n) { return (n && `1 in ${1 / n}`) || "ZERO"; }
  87.  
  88.  
  89.  
  90. , addRows = function() {
  91.     qs(selSummaryRows).forEach(function(el, i) {
  92.         addRow(qs("td", el));
  93.     });
  94. }
  95.  
  96. , getGroup = function(ageValue) {
  97.     var result = false, age = num(ageValue);
  98.     return age < 0 ? result : (ageGroups.forEach(function(label, i) {
  99.         var matches = label.match(reGroupLabels) || [];
  100.         if(result === false) {
  101.             result = isAgeGroup(age, matches) && i;
  102.         }
  103.     }), result);
  104. }
  105.  
  106. , getRisk = function(label, deaths, cases, CFR, chance, survival) {
  107.     return `${label}:\t${plural(deaths, "death")} in ${plural(cases, "case")} = CFR ${100 * CFR}%\n(risk: ${chance}, survival rate ${100 * survival}%)`
  108. }
  109.  
  110. , getSummaryUnder = function(groupIndex) {
  111.     var result = ""
  112.     , matches = ageGroups[groupIndex].match(reGroupLabels) || []
  113.     , ageUnder = (1 * matches[matchIndexForRange + 1] + 1) || 0;
  114.     if(ageUnder) {
  115.         var d = 0, c = 0, rate;
  116.         for(var i = firstGroupIndexWithRange; i <= groupIndex; i ++) {
  117.             d += deaths[i]
  118.             c += cases[i]
  119.         }
  120.         result = ` ; \n\n${getRisk(`Under ${ageUnder}`, d, c, rate = div(d, c), getChance(rate), 1 - rate)}`;
  121.     }
  122.     return result;
  123. }
  124.  
  125. , getRiskForAgeGroupIndex = function(i) {
  126.     var result = getRisk(ageGroups[i], deaths[i], cases[i], CFR[i], chance[i], survival[i])
  127.     , summary = getSummaryUnder(i);
  128.     return `\n${result}${summary}\n`
  129. }
  130.  
  131. , revealRiskForAge = function(age, local) {
  132.     var ageGroupIndex = num(getGroup(age), groupIndexOverall)
  133.     , result = getRiskForAgeGroupIndex(ageGroupIndex)
  134.     , msg = result.replace(/[\t ;]+/g, " ")
  135.     , def = result.replace(/[\t \n]+/g, " ").trim();
  136.     console.log(`${result.replace(";", "")}\n`);
  137.     result = local === u ? prompt(msg, def) : null;
  138.     return result == null ? -1 : age;
  139. }
  140.  
  141. , main = function(local) {
  142.     if(local === u && location.href.indexOf(url) < 0) {
  143.         return alert(`\nTry again after ${pageName} has loaded:\n\n${url}`), location.href = `https://${url}`;
  144.     }
  145.     addRows();
  146.     var age = 0;
  147.     while(num(age) >= 0) {
  148.         var result = local === u ? prompt(message) : local;
  149.         age = revealRiskForAge(result, local);
  150.     }
  151. };
  152.  
  153.  
  154.  
  155. main(); // bookmarklet, with redirect before it calls prompt()
  156.  
  157. // main(55);    // no redirect, no prompt, no loop; one-time hard-coded age, on current page (usually local .MHT snapshot)
  158.  
  159.  
  160.  
  161. }();
  162.  
RAW Paste Data