From a2003ea0bc68a2181ac7f4dd95aec53a3dd5274d Mon Sep 17 00:00:00 2001 From: Nicky Case Date: Mon, 27 Apr 2020 13:07:31 -0400 Subject: [PATCH] Ok it's ready to share for feedback jeez here we gooooo --- index.html | 28 +++++++--- sim/index.html | 6 +++ sim/js/Controls.js | 17 +++++- sim/js/Model.js | 130 ++++++++++++++++++++++++++++++++++++++++----- sim/js/Stages.js | 25 ++++++--- words/words.html | 26 ++++++--- words/words.md | 8 +-- 7 files changed, 205 insertions(+), 35 deletions(-) diff --git a/index.html b/index.html index 7ff423c..ec5beff 100644 --- a/index.html +++ b/index.html @@ -59,6 +59,8 @@

It's estimated that, at the start of a COVID-19 outbreak, the virus jumps from an to an approximately every 4 days.2

+

[TODO: Actually fill out source / footnotes]

+

If we simulate "double every 4 days" and nothing else, on a population starting with just 0.001% , what happens?

Click "Start" to play the simulation! You can re-play it later with different settings: (technical caveats: 3)

@@ -251,8 +253,6 @@

That was the other finding of the March 16 Imperial College report, which convinced the UK to abandon its original plan. Any attempt at mitigation (reduce R, but R > 1) will fail. The only way out is suppression (reduce R so that R < 1).

-

// pic: difference

-

That is, don't merely "flatten" the curve, crush the curve. For example, with a...

Scenario 2: Months-Long Lockdown

@@ -339,7 +339,7 @@ -

Thus, we can get R < 1 without a lockdown! Much better for our mental & financial health. (As for the cost to folks who have to self-isolate/quarantine, governments should support them – subsidized paid leave, job protection, etc. Still way cheaper than intermittent lockdown.)

+

Thus, even without 100% contact quarantining, we can get R < 1 without a lockdown! Much better for our mental & financial health. (As for the cost to folks who have to self-isolate/quarantine, governments should support them – subsidized paid leave, job protection, etc. Still way cheaper than intermittent lockdown.)

We then keep R < 1 until we have a vaccine, which turns susceptible s into immune s. Herd immunity, the right way:

@@ -396,6 +396,8 @@

Here's a calculator of how masks reduce R! You can switch between cloth & surgical: (assumes cloth masks are half as effective as surgical masks32)

+

[TODO: Actually allow toggling between cloth/surgical. Currently locked to cloth]

+
@@ -410,6 +412,8 @@

For COVID-19, every extra 1° Celsius (2.2° Fahrenheit) makes R drop by 1.2%.34 The summer-winter difference in New York City is 15°C (60°F), so summer will make R drop by 18%.

+

[TODO: Fix weird arrow glitch]

+
@@ -434,6 +438,8 @@ +

[TODO: Other options like temperature testing at malls, quarantines for travellers, replacing handshaking, etc]

+

. . .

We hope these plans give you hope.

@@ -490,7 +496,9 @@ -

Oh. Counterintuitively, summer makes the spikes worse, and regular! This is because summer reduces new s, but that in turn reduces new immune s. Which means immunity plummets in the summer, creating large regular spikes in the winter.

+

Oh.

+ +

Counterintuitively, summer makes the spikes worse and regular! This is because summer reduces new s, but that in turn reduces new immune s. Which means immunity plummets in the summer, creating large regular spikes in the winter.

Thankfully, the solution to this is pretty straightforward – just vaccinate people every fall/winter, like we do with flu shots:

@@ -516,7 +524,7 @@

3) Do the R < 1 interventions until we develop treatments that make COVID-19 way, way less likely to need critical care. (Which we should be doing anyway!) Reducing ICU use by 10x is the same as increasing our ICU capacity by 10x:

-

Here's a simulation of no lasting immunity, no vaccine, and not even any interventions – just increasing ICU capacity to survive the long-term spikes:

+

Here's a simulation of no lasting immunity, no vaccine, and not even any interventions – just slowly increasing capacity to survive the long-term spikes:

@@ -530,7 +538,11 @@

Here's an (optional) Sandbox Mode, with everything available. Simulate & play around to your heart's content:

-

[TODO TODO TODO!]

+

[TODO: EMBED THIS IN A WAY THAT DOESN'T SUCK]

+ +
+ +

This basic "epidemic flight simulator" has taught us so much. It's let us answer questions about the past few months, next few months, and next few years.

@@ -562,6 +574,8 @@

The only thing to fear is the idea that the only thing to fear is fear itself.

+

{ Please let me know what you think! How did it feel overall, any parts in particular that went too slow or were too confusing, factual inaccuracies, nuances I missed, stuff I oughta mention, etc. Thank you! }

+

    @@ -729,6 +743,8 @@ + + diff --git a/sim/index.html b/sim/index.html index 1333e14..cb80dbd 100644 --- a/sim/index.html +++ b/sim/index.html @@ -211,6 +211,12 @@ Once you're done playing around, scroll down to keep reading! + + This simulation has a "recorded scenario"! +
    + Click "Start" to watch the recording before + you change any of the numbers +
diff --git a/sim/js/Controls.js b/sim/js/Controls.js index fcfd7ba..0c623a4 100644 --- a/sim/js/Controls.js +++ b/sim/js/Controls.js @@ -219,6 +219,13 @@ bbDOM.onclick = ()=>{ } } + if(CURRENT_STAGE.SHOW_HAND=="tutorial_2"){ + if(handTutorial==0){ + hideHand(); + handTutorial = 1; + } + } + if(daysCurrent>daysTotal || params._HACK_RESET_WHEN_I_100=="go" || params._HACK_RESET_WHEN_R_100=="go"){ _resetTheSim(); @@ -255,7 +262,6 @@ let defaultParams = [ ["p_distancing", 0], ["p_isolate", 0], ["p_quarantine", 0], - ["p_cleaning", 0], ["p_masks", 0], ["p_summer", 0], ]; @@ -382,6 +388,15 @@ let showHand = (position)=>{ wordsDOM.style.textAlign = 'center'; $('#pointer_scroll').style.display = 'inline'; break; + case 'recording': + handDOM.style.top = '300px'; + handDOM.style.left = '280px'; + handDOM.style.transform = 'rotate(270deg)'; + wordsDOM.style.top = '317px'; + wordsDOM.style.left = '377px'; + wordsDOM.style.textAlign = 'left'; + $('#pointer_replay').style.display = 'inline'; + break; } diff --git a/sim/js/Model.js b/sim/js/Model.js index eaca156..cfc65a6 100644 --- a/sim/js/Model.js +++ b/sim/js/Model.js @@ -8,7 +8,6 @@ let int = { distancing: 0, isolate: 0, quarantine: 0, - cleaning: 0, masks: 0, summer: 0, vaccines: 0 @@ -26,8 +25,7 @@ let interventionStrengths = [ ['distancing', 0.7], ['isolate', 0.4], ['quarantine', 0.5], - ['cleaning', 0.1], - ['masks', 0.35], // 3.4 fold reduction (70%) (what CI?), subtract points for... improper usage? https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3591312/ // cloth masks... + ['masks', 0.35*0.5], // 3.4 fold reduction (70%) (what CI?), subtract points for... improper usage? https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3591312/ // cloth masks... ['summer', 0.333] // 15°C diff * 0.0225 (Wang et al) ]; @@ -62,7 +60,6 @@ let updateModel = (days, fake)=>{ int.distancing = params.p_distancing; int.isolate = params.p_isolate; int.quarantine = params.p_quarantine; - int.cleaning = params.p_cleaning; int.masks = params.p_masks; int.summer = (1 - Math.cos((daysCurrent-30)/365 * Math.TAU))/2; @@ -151,16 +148,123 @@ canvas.style.height = (canvas.height/2)+"px"; let interventionColors = [ ['non_s', '#bbbbbb'], - ['hygiene', 'hsl(230,100%,63%)', 0.1], - ['distancing', 'hsl(200,100%,63%)', 0.2], - ['isolate', 'hsl(140,100%,63%)', 0.2], - ['quarantine', 'hsl(100,100%,63%)', 0.2], - ['cleaning', 'hsl(290,100%,63%)', 0.2], - ['masks', 'hsl(260,100%,63%)', 0.2], - ['summer', 'hsl(20,100%,63%)', 0.3], - ['vaccines', 'hsl(53, 100%, 73%)', 0.6], + ['hygiene', '#40AEFF', 0.1], + ['distancing', '#405CFF', 0.2], + ['isolate', '#8FD68A', 0.2], + ['quarantine', '#75AD6F', 0.2], + ['masks', '#9240FF', 0.2], + ['summer', '#FF8142', 0.3], + ['vaccines', '#FFDF40', 0.6], ]; +// SUPER HACK SLIDER COLORS +// I hate browsers (thx https://stackoverflow.com/a/13348618 ) +let isThisFrikkinChrome = false; +{ + var isChromium = window.chrome; + var winNav = window.navigator; + var vendorName = winNav.vendor; + var isOpera = typeof window.opr !== "undefined"; + var isIEedge = winNav.userAgent.indexOf("Edge") > -1; + var isIOSChrome = winNav.userAgent.match("CriOS"); + + if (isIOSChrome) { + // is Google Chrome on IOS + isThisFrikkinChrome = true; + } else if( + isChromium !== null && + typeof isChromium !== "undefined" && + vendorName === "Google Inc." && + isOpera === false && + isIEedge === false + ) { + // is Google Chrome + isThisFrikkinChrome = true; + } else { + // not Google Chrome + isThisFrikkinChrome = false; + } +} +let sliderColors = JSON.parse(JSON.stringify(interventionColors)); +sliderColors.shift(); +sliderColors.push([ 'hospital', '#000' ]); +let hackStyle = ''; +sliderColors.forEach((icPair, i)=>{ + + if(i==0) return; + + let [name,color] = icPair; + + // Huge thanks to this person https://stackoverflow.com/a/38163892 + if(isThisFrikkinChrome){ + hackStyle += ` + + @media screen and (-webkit-min-device-pixel-ratio:0) { + input#p_${name} { + overflow: hidden; + -webkit-appearance: none; + background-color: #dddddd; + } + input#p_${name}::-webkit-slider-runnable-track { + height: 10px; + -webkit-appearance: none; + color: ${color}; + margin-top: -1px; + } + input#p_${name}::-webkit-slider-thumb { + width: 10px; + -webkit-appearance: none; + height: 9px; + cursor: ew-resize; + background: ${color}; + color: ${color}; + border:1px solid rgba(0,0,0,0.5); + position:relative; + top:1px; + cursor:grab; + + box-shadow: -250px 0 0 250px; + } + } + `; + }else{ + hackStyle += ` + input#p_${name}::-moz-range-progress { + background-color: ${color}; + } + input#p_${name}::-moz-range-track { + background-color: #dddddd; + } + input#p_${name}::-moz-range-thumb { + background: ${color}; + border-color: ${color}; + cursor: grab; + } + + + input#p_${name}::-ms-fill-lower { + background-color: ${color}; + } + + input#p_${name}::-ms-fill-upper { + background-color: #dddddd; + } + input#p_${name}::-ms-thumb { + background: ${color}; + border-color: ${color}; + cursor: grab; + } + + `; + } + + +}); +let hackStyleDOM = document.createElement('style'); +hackStyleDOM.innerHTML = hackStyle; +document.head.appendChild(hackStyleDOM); + + let _isItPastHerd = false; let label_p_r0 = $('#label_p_r0'); @@ -268,12 +372,14 @@ let show_percent_s = $('#show_percent_s'), show_percent_i = $('#show_percent_i'), show_percent_r = $('#show_percent_r'), herdDOM = $('.herd'); + let draw = ()=>{ // Redraw requestAnimationFrame(draw); // SUCH A HACK + if(!CURRENT_STAGE) return; if(CURRENT_STAGE._HACK_MAKE_TIME_KEEP_GOING){ daysTotal = Infinity; daysCurrent += 1; diff --git a/sim/js/Stages.js b/sim/js/Stages.js index 9a246e3..34f153c 100644 --- a/sim/js/Stages.js +++ b/sim/js/Stages.js @@ -302,7 +302,8 @@ const STAGES = { ["p_distancing",0.275,84], ["p_hygiene",1,84], ["p_distancing",0,340], ["p_hygiene",0,340], ], - SIR: [0.999995,0.000005,0] + SIR: [0.999995,0.000005,0], + SHOW_HAND: "tutorial_2" }, "int-3": { @@ -325,7 +326,8 @@ const STAGES = { ["p_distancing",1,84], ["p_hygiene",1,84], ["p_distancing",0,234], ["p_hygiene",0,234] ], - SIR: [0.999995,0.000005,0] + SIR: [0.999995,0.000005,0], + SHOW_HAND: "tutorial_2" }, "int-4": { @@ -355,7 +357,8 @@ const STAGES = { ["p_distancing",0,90+68+54+73+73+73+87+58], ["p_distancing",1,90+68+54+73+73+73+87+58+108], ], - SIR: [0.999995,0.000005,0] + SIR: [0.999995,0.000005,0], + SHOW_HAND: "tutorial_2" }, "int-4a": { @@ -432,7 +435,8 @@ const STAGES = { ["p_vaccines",0.61,550], ["p_vaccines",0,580], ], - SIR: [0.999995,0.000005,0] + SIR: [0.999995,0.000005,0], + SHOW_HAND: "tutorial_2" }, "int-6a": { @@ -531,7 +535,8 @@ const STAGES = { ["p_vaccines",0,580], ], - SIR: [0.999995,0.000005,0] + SIR: [0.999995,0.000005,0], + SHOW_HAND: "tutorial_2" }, @@ -655,6 +660,7 @@ const STAGES = { ], SHOW_ALL_AT_START: true, + SHOW_HAND: "tutorial_2" //SIR: [0.09,0.01,0.9] }, @@ -687,7 +693,8 @@ const STAGES = { ["p_hospital",750,365*2], ["p_hospital",1000,365*3] - ] + ], + SHOW_HAND: "tutorial_2" }, ////////////////////////////////////////// @@ -777,7 +784,11 @@ let setStage = (stageID)=>{ // Show hand? if(stage.SHOW_HAND){ - showHand('start'); + if(stage.SHOW_HAND=="tutorial_2"){ + showHand('recording'); + }else{ + showHand('start'); + } } // Show herd immunity? diff --git a/words/words.html b/words/words.html index ee1e55f..97aee7b 100644 --- a/words/words.html +++ b/words/words.html @@ -46,6 +46,8 @@

It's estimated that, at the start of a COVID-19 outbreak, the virus jumps from an to an approximately every 4 days.2

+

[TODO: Actually fill out source / footnotes]

+

If we simulate "double every 4 days" and nothing else, on a population starting with just 0.001% , what happens?

Click "Start" to play the simulation! You can re-play it later with different settings: (technical caveats: 3)

@@ -238,8 +240,6 @@

That was the other finding of the March 16 Imperial College report, which convinced the UK to abandon its original plan. Any attempt at mitigation (reduce R, but R > 1) will fail. The only way out is suppression (reduce R so that R < 1).

-

// pic: difference

-

That is, don't merely "flatten" the curve, crush the curve. For example, with a...

Scenario 2: Months-Long Lockdown

@@ -326,7 +326,7 @@ -

Thus, we can get R < 1 without a lockdown! Much better for our mental & financial health. (As for the cost to folks who have to self-isolate/quarantine, governments should support them – subsidized paid leave, job protection, etc. Still way cheaper than intermittent lockdown.)

+

Thus, even without 100% contact quarantining, we can get R < 1 without a lockdown! Much better for our mental & financial health. (As for the cost to folks who have to self-isolate/quarantine, governments should support them – subsidized paid leave, job protection, etc. Still way cheaper than intermittent lockdown.)

We then keep R < 1 until we have a vaccine, which turns susceptible s into immune s. Herd immunity, the right way:

@@ -383,6 +383,8 @@

Here's a calculator of how masks reduce R! You can switch between cloth & surgical: (assumes cloth masks are half as effective as surgical masks32)

+

[TODO: Actually allow toggling between cloth/surgical. Currently locked to cloth]

+
@@ -397,6 +399,8 @@

For COVID-19, every extra 1° Celsius (2.2° Fahrenheit) makes R drop by 1.2%.34 The summer-winter difference in New York City is 15°C (60°F), so summer will make R drop by 18%.

+

[TODO: Fix weird arrow glitch]

+
@@ -421,6 +425,8 @@ +

[TODO: Other options like temperature testing at malls, quarantines for travellers, replacing handshaking, etc]

+

. . .

We hope these plans give you hope.

@@ -477,7 +483,9 @@ -

Oh. Counterintuitively, summer makes the spikes worse, and regular! This is because summer reduces new s, but that in turn reduces new immune s. Which means immunity plummets in the summer, creating large regular spikes in the winter.

+

Oh.

+ +

Counterintuitively, summer makes the spikes worse and regular! This is because summer reduces new s, but that in turn reduces new immune s. Which means immunity plummets in the summer, creating large regular spikes in the winter.

Thankfully, the solution to this is pretty straightforward – just vaccinate people every fall/winter, like we do with flu shots:

@@ -503,7 +511,7 @@

3) Do the R < 1 interventions until we develop treatments that make COVID-19 way, way less likely to need critical care. (Which we should be doing anyway!) Reducing ICU use by 10x is the same as increasing our ICU capacity by 10x:

-

Here's a simulation of no lasting immunity, no vaccine, and not even any interventions – just increasing ICU capacity to survive the long-term spikes:

+

Here's a simulation of no lasting immunity, no vaccine, and not even any interventions – just slowly increasing capacity to survive the long-term spikes:

@@ -517,7 +525,11 @@

Here's an (optional) Sandbox Mode, with everything available. Simulate & play around to your heart's content:

-

[TODO TODO TODO!]

+

[TODO: EMBED THIS IN A WAY THAT DOESN'T SUCK]

+ +
+ +

This basic "epidemic flight simulator" has taught us so much. It's let us answer questions about the past few months, next few months, and next few years.

@@ -549,6 +561,8 @@

The only thing to fear is the idea that the only thing to fear is fear itself.

+

{ Please let me know what you think! How did it feel overall, any parts in particular that went too slow or were too confusing, factual inaccuracies, nuances I missed, stuff I oughta mention, etc. Thank you! }

+

    diff --git a/words/words.md b/words/words.md index 751e134..3709f9f 100644 --- a/words/words.md +++ b/words/words.md @@ -34,6 +34,8 @@ It's estimated that, *at the start* of a COVID-19 outbreak, the virus jumps from [^serial_interval]: https://wwwnc.cdc.gov/eid/article/26/6/20-0357_article +[TODO: Actually fill out source / footnotes] + If we simulate "double every 4 days" *and nothing else*, on a population starting with just 0.001% , what happens? **Click "Start" to play the simulation! You can re-play it later with different settings:** (technical caveats: [^caveats]) @@ -258,8 +260,6 @@ Three notes: That was the other finding of the March 16 Imperial College report, which convinced the UK to abandon its original plan. Any attempt at **mitigation** (reduce R, but R > 1) will fail. The only way out is **suppression** (reduce R so that R < 1). -// pic: difference - That is, don't merely "flatten" the curve, *crush* the curve. For example, with a... ###Scenario 2: Months-Long Lockdown @@ -617,4 +617,6 @@ So what does this mean for YOU, right now? Don't downplay fear to build up hope. Our fear should *team up* with our hope, like the inventors of airplanes & parachutes. Preparing for horrible futures is how we *create* a hopeful future. -The only thing to fear is the idea that the only thing to fear is fear itself. \ No newline at end of file +The only thing to fear is the idea that the only thing to fear is fear itself. + +**{ Please let me know what you think! How did it feel overall, any parts in particular that went too slow or were too confusing, factual inaccuracies, nuances I missed, stuff I oughta mention, etc. Thank you! }** \ No newline at end of file