i hate web development so much
This commit is contained in:
parent
7253482a89
commit
649c1c7bd9
10 changed files with 403 additions and 165 deletions
18
index.html
18
index.html
|
@ -61,8 +61,8 @@
|
|||
<div>
|
||||
<h1>What Happens Next?</h1>
|
||||
<h2>COVID-19 Futures, Explained With Playable Simulations</h2>
|
||||
<h3>by Marcel Salathé (epidemiologist) and Nicky Case (art/code)</h3>
|
||||
<h3>🕐 28 min play/read</h3>
|
||||
<h3>by <a href='https://scholar.google.com/citations?user=_wHMGkUAAAAJ&hl=en'>Marcel Salathé</a> (epidemiologist) and <a href='https://ncase.me/'>Nicky Case</a> (art/code)</h3>
|
||||
<h3>🕐 30 min play/read</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -78,7 +78,7 @@
|
|||
|
||||
<ul>
|
||||
<li><strong>The Last Few Months</strong> (epidemiology 101, SEIR model, R & R<sub>0</sub>)</li>
|
||||
<li><strong>The Next Few Months</strong> (lockdowns, contact tracing, masks?)</li>
|
||||
<li><strong>The Next Few Months</strong> (lockdowns, contact tracing, masks)</li>
|
||||
<li><strong>The Next Few Years</strong> (loss of immunity? no vaccine?)</li>
|
||||
</ul>
|
||||
|
||||
|
@ -304,7 +304,7 @@
|
|||
|
||||
<p>That was the other finding of the March 16 Imperial College report, which convinced the UK to abandon its original plan. Any attempt at <strong>mitigation</strong> (reduce R, but R > 1) will fail. The only way out is <strong>suppression</strong> (reduce R so that R < 1).</p>
|
||||
|
||||
<p>// TODO: pic difference</p>
|
||||
<p><img src="pics/mitigation_vs_suppression.png" alt=""></p>
|
||||
|
||||
<p>That is, don't merely "flatten" the curve, <em>crush</em> the curve. For example, with a...</p>
|
||||
|
||||
|
@ -326,7 +326,7 @@
|
|||
|
||||
<h3 id="toc_3">Scenario 3: Intermittent Lockdown</h3>
|
||||
|
||||
<p>This solution was first suggested by the March 16 Imperial College report, and later again by a Harvard paper<sup id="fnref19"><a href="#fn19" rel="footnote">19</a></sup>.</p>
|
||||
<p>This solution was first suggested by the March 16 Imperial College report, and later again by a Harvard paper.<sup id="fnref19"><a href="#fn19" rel="footnote">19</a></sup></p>
|
||||
|
||||
<p><strong>Here's a simulation:</strong> (After playing the "recorded scenario", you can try simulating your <em>own</em> lockdown schedule, by changing the sliders <em>while</em> the simulation is running! Remember you can pause & continue the sim, and change the simulation speed)</p>
|
||||
|
||||
|
@ -537,7 +537,7 @@
|
|||
<p>But for COVID-19 <em>in humans</em>, as of May 1st 2020, "how long" is the big unknown.</p>
|
||||
|
||||
<p>For these simulations, let's say it's 1 year.
|
||||
<strong>Here's a simulation starting with 100% <icon r></icon></strong>, exponentially decaying into susceptible, no-immunity <icon s></icon>s after 1 year, on <em>average</em>:</p>
|
||||
<strong>Here's a simulation starting with 100% <icon r></icon></strong>, exponentially decaying into susceptible, no-immunity <icon s></icon>s after 1 year, on <em>average</em>, with variation:</p>
|
||||
|
||||
<div class="sim">
|
||||
<iframe src="sim?stage=yrs-1&format=lines&height=600" width="800" height="600"></iframe>
|
||||
|
@ -608,7 +608,7 @@
|
|||
<p><strong>Here's an (optional) Sandbox Mode, with <em>everything</em> available. Simulate & play around to your heart's content:</strong></p>
|
||||
|
||||
<div class="sim">
|
||||
<iframe src="sim?stage=SB&format=sb&height=1000" width="800" height="1000"></iframe>
|
||||
<iframe src="sim?stage=SB&format=sb" width="800" height="540"></iframe>
|
||||
</div>
|
||||
|
||||
<p>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.</p>
|
||||
|
@ -718,9 +718,7 @@
|
|||
</li>
|
||||
|
||||
<li id="fn15">
|
||||
<p>“[Graham Medley] says that the actual goal is the same as that of other countries: flatten the curve by staggering the onset of infections. As a consequence, the nation may achieve herd immunity; it’s a side effect, not an aim. [...] <a href="#fnref15" rev="footnote">↩</a></p>
|
||||
|
||||
<p>The government’s actual coronavirus action plan, available online, doesn’t mention herd immunity at all. [...] “It’s been a case of how not to communicate during an outbreak,” says Devi Sridhar, a public-health specialist at the University of Edinburgh.”</p>
|
||||
<p>“He says that the actual goal is the same as that of other countries: flatten the curve by staggering the onset of infections. As a consequence, the nation may achieve herd immunity; it’s a side effect, not an aim. [...] The government’s actual coronavirus action plan, available online, doesn’t mention herd immunity at all.” <a href="#fnref15" rev="footnote">↩</a></p>
|
||||
|
||||
<p>From a <a href="https://www.theatlantic.com/health/archive/2020/03/coronavirus-pandemic-herd-immunity-uk-boris-johnson/608065/">The Atlantic article by Ed Yong</a></p>
|
||||
</li>
|
||||
|
|
|
@ -31,6 +31,7 @@ div{
|
|||
/*height:500px;*/
|
||||
float:left;
|
||||
position: relative;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
#label_s{
|
||||
|
@ -198,6 +199,7 @@ hr{
|
|||
right:15px;
|
||||
top:8px;
|
||||
width: 500px;
|
||||
pointer-events: none;
|
||||
}
|
||||
#graphCanvas{
|
||||
width:500px;
|
||||
|
@ -236,16 +238,16 @@ icon{
|
|||
background-size: 100% 100%;
|
||||
}
|
||||
icon[s]{
|
||||
background-image: url(../icons/s.png);
|
||||
background-image: url(../../icons/s.png);
|
||||
}
|
||||
icon[e]{
|
||||
background-image: url(../icons/e.png);
|
||||
background-image: url(../../icons/e.png);
|
||||
}
|
||||
icon[i]{
|
||||
background-image: url(../icons/i.png);
|
||||
background-image: url(../../icons/i.png);
|
||||
}
|
||||
icon[r]{
|
||||
background-image: url(../icons/r.png);
|
||||
background-image: url(../../icons/r.png);
|
||||
}
|
||||
|
||||
#legend{
|
||||
|
@ -279,7 +281,7 @@ icon[r]{
|
|||
}
|
||||
#hand{
|
||||
position: absolute;
|
||||
background: url(../icons/hand.png);
|
||||
background: url(../../icons/hand.png);
|
||||
background-size: 100% 100%;
|
||||
width:80px; height:80px;
|
||||
|
||||
|
@ -310,7 +312,7 @@ icon[r]{
|
|||
.control_icon{
|
||||
width:36px;
|
||||
height:36px;
|
||||
background: url(../icons/controls.png);
|
||||
background: url(../../icons/controls.png);
|
||||
background-size: auto 100%;
|
||||
display: inline-block;
|
||||
|
||||
|
@ -326,3 +328,7 @@ icon[r]{
|
|||
.control_icon[reset]{
|
||||
background-position: -300% 0;
|
||||
}
|
||||
|
||||
.simplebar-wrapper{
|
||||
height: 450px !important;
|
||||
}
|
215
sim/css/simplebar.css
Normal file
215
sim/css/simplebar.css
Normal file
|
@ -0,0 +1,215 @@
|
|||
[data-simplebar] {
|
||||
position: relative;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
align-content: flex-start;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.simplebar-wrapper {
|
||||
overflow: hidden;
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
max-width: inherit;
|
||||
max-height: inherit;
|
||||
}
|
||||
|
||||
.simplebar-mask {
|
||||
direction: inherit;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: auto !important;
|
||||
height: auto !important;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.simplebar-offset {
|
||||
direction: inherit !important;
|
||||
box-sizing: inherit !important;
|
||||
resize: none !important;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.simplebar-content-wrapper {
|
||||
direction: inherit;
|
||||
box-sizing: border-box !important;
|
||||
position: relative;
|
||||
display: block;
|
||||
height: 100%; /* Required for horizontal native scrollbar to not appear if parent is taller than natural height */
|
||||
width: auto;
|
||||
visibility: visible;
|
||||
max-width: 100%; /* Not required for horizontal scroll to trigger */
|
||||
max-height: 100%; /* Needed for vertical scroll to trigger */
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
.simplebar-content-wrapper::-webkit-scrollbar,
|
||||
.simplebar-hide-scrollbar::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.simplebar-content:before,
|
||||
.simplebar-content:after {
|
||||
content: ' ';
|
||||
display: table;
|
||||
}
|
||||
|
||||
.simplebar-placeholder {
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.simplebar-height-auto-observer-wrapper {
|
||||
box-sizing: inherit !important;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
max-width: 1px;
|
||||
position: relative;
|
||||
float: left;
|
||||
max-height: 1px;
|
||||
overflow: hidden;
|
||||
z-index: -1;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
pointer-events: none;
|
||||
flex-grow: inherit;
|
||||
flex-shrink: 0;
|
||||
flex-basis: 0;
|
||||
}
|
||||
|
||||
.simplebar-height-auto-observer {
|
||||
box-sizing: inherit;
|
||||
display: block;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 1000%;
|
||||
width: 1000%;
|
||||
min-height: 1px;
|
||||
min-width: 1px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.simplebar-track {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
pointer-events: none;
|
||||
overflow: hidden;
|
||||
|
||||
background: #333;
|
||||
}
|
||||
|
||||
[data-simplebar].simplebar-dragging .simplebar-content {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
[data-simplebar].simplebar-dragging .simplebar-track {
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.simplebar-scrollbar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
min-height: 10px;
|
||||
}
|
||||
|
||||
.simplebar-scrollbar:before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
/*background: black;*/
|
||||
background: #fff;
|
||||
border-radius: 7px;
|
||||
left: 2px;
|
||||
right: 2px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
|
||||
.simplebar-scrollbar.simplebar-visible:before {
|
||||
/* When hovered, remove all transitions from drag handle */
|
||||
opacity: 0.5;
|
||||
transition: opacity 0s linear;
|
||||
}
|
||||
|
||||
.simplebar-track.simplebar-vertical {
|
||||
top: 0;
|
||||
width: 11px;
|
||||
}
|
||||
|
||||
.simplebar-track.simplebar-vertical .simplebar-scrollbar:before {
|
||||
top: 2px;
|
||||
bottom: 2px;
|
||||
}
|
||||
|
||||
.simplebar-track.simplebar-horizontal {
|
||||
left: 0;
|
||||
height: 11px;
|
||||
}
|
||||
|
||||
.simplebar-track.simplebar-horizontal .simplebar-scrollbar:before {
|
||||
height: 100%;
|
||||
left: 2px;
|
||||
right: 2px;
|
||||
}
|
||||
|
||||
.simplebar-track.simplebar-horizontal .simplebar-scrollbar {
|
||||
right: auto;
|
||||
left: 0;
|
||||
top: 2px;
|
||||
height: 7px;
|
||||
min-height: 0;
|
||||
min-width: 10px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* Rtl support */
|
||||
[data-simplebar-direction='rtl'] .simplebar-track.simplebar-vertical {
|
||||
right: auto;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.hs-dummy-scrollbar-size {
|
||||
direction: rtl;
|
||||
position: fixed;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
height: 500px;
|
||||
width: 500px;
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
.simplebar-hide-scrollbar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
visibility: hidden;
|
||||
overflow-y: scroll;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
|
@ -2,7 +2,8 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="sim.css" />
|
||||
<link rel="stylesheet" type="text/css" href="css/sim.css" />
|
||||
<link rel="stylesheet" type="text/css" href="css/simplebar.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -256,4 +257,8 @@
|
|||
<script src="js/Model.js"></script>
|
||||
<script src="js/Controls.js"></script>
|
||||
<script src="js/Stages.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
<script src="js/Params.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
|
||||
<script src="js/simplebar.min.js"></script>
|
||||
|
||||
|
|
137
sim/js/Params.js
Normal file
137
sim/js/Params.js
Normal file
|
@ -0,0 +1,137 @@
|
|||
let changeSliders = (idValPair)=>{
|
||||
|
||||
DONT_RECORD_HISTORY = true;
|
||||
_DO_NOT_RECURSE = true;
|
||||
|
||||
idValPair.forEach((idValPair)=>{
|
||||
let [id,val] = idValPair;
|
||||
let slider = $('#'+id);
|
||||
if(slider){
|
||||
slider.value = val;
|
||||
slider.oninput();
|
||||
}
|
||||
params[id] = val;
|
||||
});
|
||||
|
||||
DONT_RECORD_HISTORY = false;
|
||||
_DO_NOT_RECURSE = false;
|
||||
|
||||
};
|
||||
|
||||
let CURRENT_STAGE;
|
||||
|
||||
let setStage = (stageID)=>{
|
||||
|
||||
let stage = STAGES[stageID];
|
||||
CURRENT_STAGE = stage;
|
||||
|
||||
// Hide what
|
||||
stage.hide = stage.hide || [];
|
||||
stage.hide.forEach((domID)=>{
|
||||
$('#'+domID).style.display = 'none';
|
||||
});
|
||||
|
||||
// Sliders
|
||||
stage.inputs = stage.inputs || [];
|
||||
changeSliders(defaultParams);
|
||||
changeSliders(stage.inputs);
|
||||
|
||||
// Checkboxes
|
||||
stage.checkboxes = stage.checkboxes || [];
|
||||
stage.checkboxes.forEach((idValPair)=>{
|
||||
let [id,val] = idValPair;
|
||||
let checkbox = $('#'+id);
|
||||
checkbox.checked = val;
|
||||
checkbox.oninput();
|
||||
params[id] = val;
|
||||
});
|
||||
|
||||
// Disabled Sliders
|
||||
stage.disabled = stage.disabled || [];
|
||||
stage.disabled.forEach((idValPair)=>{
|
||||
let [id,val] = idValPair;
|
||||
let slider = $('#'+id);
|
||||
slider.disabled = val;
|
||||
});
|
||||
|
||||
// Start SIR
|
||||
if(stage.SIR){
|
||||
START_S = stage.SIR[0];
|
||||
START_E = 0;
|
||||
START_I = stage.SIR[1];
|
||||
START_R = stage.SIR[2];
|
||||
}
|
||||
|
||||
// Show all?
|
||||
if(stage.SHOW_ALL_AT_START){
|
||||
_showAllControls();
|
||||
}
|
||||
|
||||
// Show hand?
|
||||
if(stage.SHOW_HAND){
|
||||
if(stage.SHOW_HAND=="tutorial_2"){
|
||||
showHand('recording');
|
||||
}else{
|
||||
showHand('start');
|
||||
}
|
||||
}
|
||||
|
||||
// Show herd immunity?
|
||||
if(params.DO_NOT_SHOW_HERD_IMMUNITY){
|
||||
$('.herd').style.display = 'none';
|
||||
}
|
||||
|
||||
// PLAY BACK?
|
||||
if(stage.PLAY_RECORDING){
|
||||
IS_PLAYING_RECORDING = true;
|
||||
recordedHistory = JSON.parse(JSON.stringify(stage.PLAY_RECORDING));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
let stageParams = new URLSearchParams(location.search);
|
||||
if(stageParams.has('stage')) setStage(stageParams.get('stage'));
|
||||
|
||||
if(stageParams.has('format')){
|
||||
|
||||
if(stageParams.get('format')=='calc'){
|
||||
document.body.style.overflow = 'hidden';
|
||||
$('#sandbox').style.margin = '0';
|
||||
}
|
||||
if(stageParams.get('format')=='lines'){
|
||||
$all('.lines').forEach((dom)=>{
|
||||
dom.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
window.onload = ()=>{
|
||||
|
||||
if(stageParams.get('format')=='sb'){
|
||||
$('#legend').style.display = 'none';
|
||||
/*$('#sandbox').style.margin = '0';*/
|
||||
|
||||
setTimeout(()=>{
|
||||
|
||||
let sbDOM = $('#sandbox');
|
||||
sbDOM.style.overflow = 'auto';
|
||||
sbDOM.style.height = 'auto';
|
||||
sbDOM.setAttribute('data-simplebar-direction','rtl');
|
||||
new SimpleBar(sbDOM,{
|
||||
autoHide: false,
|
||||
direction: 'rtl'
|
||||
});
|
||||
sbDOM.scrollTop = 0;
|
||||
|
||||
$('#graph').style.position = 'fixed';
|
||||
|
||||
},2000);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if(stageParams.has('height')){
|
||||
$('#sandbox').style.height = stageParams.get('height')+'px';
|
||||
}
|
141
sim/js/Stages.js
141
sim/js/Stages.js
|
@ -37,25 +37,6 @@ SB Full Sandbox
|
|||
|
||||
const STAGES = {
|
||||
|
||||
"00": {
|
||||
hide: [
|
||||
"section_dynamics",
|
||||
"c_recovery","label_c_waning","section_meta_years","c_exposed",
|
||||
"int_block_1","int_block_2","int_block_3","int_block_4","int_block_5","hospital_capacity"
|
||||
],
|
||||
inputs: [
|
||||
["p_transmission",4],
|
||||
["p_years",1],
|
||||
["p_speed",5],
|
||||
["TIME_DELTA", 0.5],
|
||||
//["EXPONENTIAL",true],
|
||||
],
|
||||
checkboxes: [
|
||||
["c_recovery", true],
|
||||
["c_exposed",true]
|
||||
],
|
||||
},
|
||||
|
||||
//////////////////////////////////////////
|
||||
// THE SIMULATION ////////////////////////
|
||||
//////////////////////////////////////////
|
||||
|
@ -707,124 +688,12 @@ const STAGES = {
|
|||
["c_waning", true],
|
||||
["c_exposed",true],
|
||||
],
|
||||
inputs: [
|
||||
["p_years",5],
|
||||
["p_speed",10]
|
||||
],
|
||||
SHOW_ALL_AT_START: true,
|
||||
},
|
||||
|
||||
|
||||
};
|
||||
|
||||
let changeSliders = (idValPair)=>{
|
||||
|
||||
DONT_RECORD_HISTORY = true;
|
||||
_DO_NOT_RECURSE = true;
|
||||
|
||||
idValPair.forEach((idValPair)=>{
|
||||
let [id,val] = idValPair;
|
||||
let slider = $('#'+id);
|
||||
if(slider){
|
||||
slider.value = val;
|
||||
slider.oninput();
|
||||
}
|
||||
params[id] = val;
|
||||
});
|
||||
|
||||
DONT_RECORD_HISTORY = false;
|
||||
_DO_NOT_RECURSE = false;
|
||||
|
||||
};
|
||||
|
||||
let CURRENT_STAGE;
|
||||
|
||||
let setStage = (stageID)=>{
|
||||
|
||||
let stage = STAGES[stageID];
|
||||
CURRENT_STAGE = stage;
|
||||
|
||||
// Hide what
|
||||
stage.hide = stage.hide || [];
|
||||
stage.hide.forEach((domID)=>{
|
||||
$('#'+domID).style.display = 'none';
|
||||
});
|
||||
|
||||
// Sliders
|
||||
stage.inputs = stage.inputs || [];
|
||||
changeSliders(defaultParams);
|
||||
changeSliders(stage.inputs);
|
||||
|
||||
// Checkboxes
|
||||
stage.checkboxes = stage.checkboxes || [];
|
||||
stage.checkboxes.forEach((idValPair)=>{
|
||||
let [id,val] = idValPair;
|
||||
let checkbox = $('#'+id);
|
||||
checkbox.checked = val;
|
||||
checkbox.oninput();
|
||||
params[id] = val;
|
||||
});
|
||||
|
||||
// Disabled Sliders
|
||||
stage.disabled = stage.disabled || [];
|
||||
stage.disabled.forEach((idValPair)=>{
|
||||
let [id,val] = idValPair;
|
||||
let slider = $('#'+id);
|
||||
slider.disabled = val;
|
||||
});
|
||||
|
||||
// Start SIR
|
||||
if(stage.SIR){
|
||||
START_S = stage.SIR[0];
|
||||
START_E = 0;
|
||||
START_I = stage.SIR[1];
|
||||
START_R = stage.SIR[2];
|
||||
}
|
||||
|
||||
// Show all?
|
||||
if(stage.SHOW_ALL_AT_START){
|
||||
_showAllControls();
|
||||
}
|
||||
|
||||
// Show hand?
|
||||
if(stage.SHOW_HAND){
|
||||
if(stage.SHOW_HAND=="tutorial_2"){
|
||||
showHand('recording');
|
||||
}else{
|
||||
showHand('start');
|
||||
}
|
||||
}
|
||||
|
||||
// Show herd immunity?
|
||||
if(params.DO_NOT_SHOW_HERD_IMMUNITY){
|
||||
$('.herd').style.display = 'none';
|
||||
}
|
||||
|
||||
// PLAY BACK?
|
||||
if(stage.PLAY_RECORDING){
|
||||
IS_PLAYING_RECORDING = true;
|
||||
recordedHistory = JSON.parse(JSON.stringify(stage.PLAY_RECORDING));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
let stageParams = new URLSearchParams(location.search);
|
||||
if(stageParams.has('stage')) setStage(stageParams.get('stage'));
|
||||
|
||||
if(stageParams.has('format')){
|
||||
|
||||
if(stageParams.get('format')=='calc'){
|
||||
document.body.style.overflow = 'hidden';
|
||||
$('#sandbox').style.margin = '0';
|
||||
}
|
||||
if(stageParams.get('format')=='lines'){
|
||||
$all('.lines').forEach((dom)=>{
|
||||
dom.style.display = 'none';
|
||||
});
|
||||
}
|
||||
if(stageParams.get('format')=='sb'){
|
||||
$('#legend').style.display = 'none';
|
||||
$('#sandbox').style.margin = '0';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(stageParams.has('height')){
|
||||
$('#sandbox').style.height = stageParams.get('height')+'px';
|
||||
}
|
||||
};
|
10
sim/js/simplebar.min.js
vendored
Normal file
10
sim/js/simplebar.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
sim/legend.png
BIN
sim/legend.png
Binary file not shown.
Before Width: | Height: | Size: 15 KiB |
|
@ -16,8 +16,8 @@
|
|||
<div>
|
||||
<h1>What Happens Next?</h1>
|
||||
<h2>COVID-19 Futures, Explained With Playable Simulations</h2>
|
||||
<h3>by Marcel Salathé (epidemiologist) and Nicky Case (art/code)</h3>
|
||||
<h3>🕐 28 min play/read</h3>
|
||||
<h3>by <a href='https://scholar.google.com/citations?user=_wHMGkUAAAAJ&hl=en'>Marcel Salathé</a> (epidemiologist) and <a href='https://ncase.me/'>Nicky Case</a> (art/code)</h3>
|
||||
<h3>🕐 30 min play/read</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
|||
|
||||
<ul>
|
||||
<li><strong>The Last Few Months</strong> (epidemiology 101, SEIR model, R & R<sub>0</sub>)</li>
|
||||
<li><strong>The Next Few Months</strong> (lockdowns, contact tracing, masks?)</li>
|
||||
<li><strong>The Next Few Months</strong> (lockdowns, contact tracing, masks)</li>
|
||||
<li><strong>The Next Few Years</strong> (loss of immunity? no vaccine?)</li>
|
||||
</ul>
|
||||
|
||||
|
@ -259,7 +259,7 @@ the <em>second</em>-most important idea in Epidemiology 101:</p>
|
|||
|
||||
<p>That was the other finding of the March 16 Imperial College report, which convinced the UK to abandon its original plan. Any attempt at <strong>mitigation</strong> (reduce R, but R > 1) will fail. The only way out is <strong>suppression</strong> (reduce R so that R < 1).</p>
|
||||
|
||||
<p>// TODO: pic difference</p>
|
||||
<p><img src="pics/mitigation_vs_suppression.png" alt=""></p>
|
||||
|
||||
<p>That is, don't merely "flatten" the curve, <em>crush</em> the curve. For example, with a...</p>
|
||||
|
||||
|
@ -281,7 +281,7 @@ the <em>second</em>-most important idea in Epidemiology 101:</p>
|
|||
|
||||
<h3 id="toc_3">Scenario 3: Intermittent Lockdown</h3>
|
||||
|
||||
<p>This solution was first suggested by the March 16 Imperial College report, and later again by a Harvard paper<sup id="fnref19"><a href="#fn19" rel="footnote">19</a></sup>.</p>
|
||||
<p>This solution was first suggested by the March 16 Imperial College report, and later again by a Harvard paper.<sup id="fnref19"><a href="#fn19" rel="footnote">19</a></sup></p>
|
||||
|
||||
<p><strong>Here's a simulation:</strong> (After playing the "recorded scenario", you can try simulating your <em>own</em> lockdown schedule, by changing the sliders <em>while</em> the simulation is running! Remember you can pause & continue the sim, and change the simulation speed)</p>
|
||||
|
||||
|
@ -492,7 +492,7 @@ the <em>second</em>-most important idea in Epidemiology 101:</p>
|
|||
<p>But for COVID-19 <em>in humans</em>, as of May 1st 2020, "how long" is the big unknown.</p>
|
||||
|
||||
<p>For these simulations, let's say it's 1 year.
|
||||
<strong>Here's a simulation starting with 100% <icon r></icon></strong>, exponentially decaying into susceptible, no-immunity <icon s></icon>s after 1 year, on <em>average</em>:</p>
|
||||
<strong>Here's a simulation starting with 100% <icon r></icon></strong>, exponentially decaying into susceptible, no-immunity <icon s></icon>s after 1 year, on <em>average</em>, with variation:</p>
|
||||
|
||||
<div class="sim">
|
||||
<iframe src="sim?stage=yrs-1&format=lines&height=600" width="800" height="600"></iframe>
|
||||
|
@ -563,7 +563,7 @@ the <em>second</em>-most important idea in Epidemiology 101:</p>
|
|||
<p><strong>Here's an (optional) Sandbox Mode, with <em>everything</em> available. Simulate & play around to your heart's content:</strong></p>
|
||||
|
||||
<div class="sim">
|
||||
<iframe src="sim?stage=SB&format=sb&height=1000" width="800" height="1000"></iframe>
|
||||
<iframe src="sim?stage=SB&format=sb" width="800" height="450"></iframe>
|
||||
</div>
|
||||
|
||||
<p>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.</p>
|
||||
|
@ -673,9 +673,7 @@ the <em>second</em>-most important idea in Epidemiology 101:</p>
|
|||
</li>
|
||||
|
||||
<li id="fn15">
|
||||
<p>“[Graham Medley] says that the actual goal is the same as that of other countries: flatten the curve by staggering the onset of infections. As a consequence, the nation may achieve herd immunity; it’s a side effect, not an aim. [...] <a href="#fnref15" rev="footnote">↩</a></p>
|
||||
|
||||
<p>The government’s actual coronavirus action plan, available online, doesn’t mention herd immunity at all. [...] “It’s been a case of how not to communicate during an outbreak,” says Devi Sridhar, a public-health specialist at the University of Edinburgh.”</p>
|
||||
<p>“He says that the actual goal is the same as that of other countries: flatten the curve by staggering the onset of infections. As a consequence, the nation may achieve herd immunity; it’s a side effect, not an aim. [...] The government’s actual coronavirus action plan, available online, doesn’t mention herd immunity at all.” <a href="#fnref15" rev="footnote">↩</a></p>
|
||||
|
||||
<p>From a <a href="https://www.theatlantic.com/health/archive/2020/03/coronavirus-pandemic-herd-immunity-uk-boris-johnson/608065/">The Atlantic article by Ed Yong</a></p>
|
||||
</li>
|
||||
|
|
|
@ -658,7 +658,7 @@ Maybe you'd like to challenge our assumptions, and try different R<sub>0</sub>'s
|
|||
**Here's an (optional) Sandbox Mode, with *everything* available. Simulate & play around to your heart's content:**
|
||||
|
||||
<div class="sim">
|
||||
<iframe src="sim?stage=SB&format=sb&height=1000" width="800" height="1000"></iframe>
|
||||
<iframe src="sim?stage=SB&format=sb" width="800" height="540"></iframe>
|
||||
</div>
|
||||
|
||||
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.
|
||||
|
|
Loading…
Reference in a new issue