Load data

Summary 2020-05-05

Today we had 408 new positive tests which is 12% percent of the total tests recorded in the last 24 hours. In Iowa there are 6332 people still sick with COVID-19 and 6% percent of those people are hospitalized. From the logisitc growth model, we predict that in 14 days, Iowa will have 17053 infected people.

View Data

So, it turns out to be very difficult to find past data in the State of Iowa since they re-publish everything daily. Here are the last 6 days of data if you are interested:

tail(clean)

Data Exploration

Positive Tests

Exponential Model

Run a linear model on the logarithm of the positive cases.

qplot(date, log(positive), data =clean) + geom_point() + geom_smooth()+
  stat_smooth(method = "lm", col = "red") 

For the model \(positive = e^{k date}\), \(k=\) 0.1249087. Estimated doubling time for positive cases is 5.5492285 days. Here is what that looks like on the original data.

Modified Exponential Model

By now there is strong evidence that the curve is flattening. We can create a new linear model that uses the more recent data to improve our model. Let’s look to see what happens if we only use data from later when we were doing more testing.

For the model \(positive = e^{k date}\), \(k=\) 0.0945819. Estimated doubling time for positive cases is 7.7553693 days. Here is what that looks like on the original data.

Deaths

Exponential Model

We will start the data when we have non-zero deaths.

For the model \(deaths = e^{k date}\), \(k=\) 4.8943337. Estimated time for deaths to double is 6.4972116 days.

Later Data

As above, let’s look at the same models, but only after we got serious about testing.

For the model \(deaths = e^{k date}\), \(k=\) 0.076684. Estimated time for deaths to double is 9.0390105 days.

Logistic Model

To try to fit a logistic model to the data, we want to fit a parabola to the rate of change, but the input variable is cases or deaths and not time. This is because the logistic model comes from the differential equation \(\displaystyle{\frac{dP}{dt}= kP(1-\frac{P}{M})}\). Note that this equation as a function of \(P\) is a parabola with zeroes at \(P=0\) and \(P=M\).

clean <- clean[-c(1,10),]
with(clean, plot(positive, New.Positive, pch=16, xlab = "Positive Counts", ylab = "Rate of Change of Positive", cex.lab = 1.3, col = "blue"))

Now, it doesn’t really look quadratic, but we are not going to let that stop us from mathematics. Next, we will fit a quadratic model to the data.

clean$P2 <- as.numeric(clean$positive)^2
quadratic <-lm(New.Positive ~ positive + P2-1, data = clean)
r <- quadratic$coefficients[2]*(-1)
M <- quadratic$coefficients[1]/r
Mprint <- format(M, scientific = FALSE)
predictedcounts <- with(clean,predict(quadratic,list(positive = positive, P2 = P2)))

Let’s plot the model:

with(clean, plot(positive, New.Positive, pch=16, xlab = "Positive Counts", ylab = "Rate of Change of Positive", cex.lab = 1.3, col = "blue"))
with(clean,lines(positive, predictedcounts, col = "darkgreen", lwd = 3))

IowaPercent <- M/IowaPop

So, we have a quadratic model that looks like \(\frac{dP}{dt}\) = 0.1063176\(P^2\) + -5.015821810^{-6}\(P\) = 5.015821810^{-6}\(P(1-P/\) 21196.45\()\). This is looking pretty good. In particular, because \(M=\) 21196.45, we can estimate that 0.0067184 of Iowa’s population will become infected. We would like to see what that looks like for the original data. When R performs logistic modeling, it usually has binomial data and thus expects numbers that are between zero and one. We will use our estimate of \(M\) to create postitive counts that are a percentage of \(M\).

non-integer #successes in a binomial glm!

Okay, that looks quite good. What will it predict for the next 14 days?

This predicts that in 14 days, Iowa will have 17053 infected people.

New Positives

For the model \(new positives = e^{k date}\), \(k=\) 0.0945819. Estimated time for new positives to double is 7.328543 days.

Alternative Modeling

This didn’t turn out well, but it is still here for historical perspective:

Positives Linear Model

First run a linear model on positive test results.

qplot(date, positive, data =clean) + geom_point() + geom_smooth()+
  stat_smooth(method = "lm", col = "red")

Deaths Linear Model

qplot(date, deaths, data =cdeaths, rm.na=TRUE) + geom_point() + geom_smooth()+
  stat_smooth(method = "lm", col = "red")
Ignoring unknown parameters: rm.na

model <- lm(deaths~date, data=cdeaths)
#model$coefficients
LS0tDQp0aXRsZTogIkNvdmlkLTE5IEFuYWx5c2lzIg0KYXV0aG9yOiAiTWFyaWFoIEJpcmdlbiINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCmBgYHtyIGluaXRpYWxpemF0aW9uLCBlY2hvPUZBTFNFfQ0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKCByZXF1aXJlKGRwbHlyKSkNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyggcmVxdWlyZShsdWJyaWRhdGUpKQ0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKCByZXF1aXJlKGdncGxvdDIpKQ0KYGBgDQoNCkxvYWQgZGF0YQ0KYGBge3IgbG9hZCwgZWNobyA9IEZBTFNFfQ0KY292aWQxOSA8LSByZWFkLmNzdigiY292aWQxOS5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQpjb3ZpZDE5JGRhdGUgPC0gbWR5KGNvdmlkMTkkZGF0ZSkNCmNsZWFybiA8LSAhaXMubmEoY292aWQxOSRwb3NpdGl2ZSkNCmNsZWFuIDwtIGNvdmlkMTlbY2xlYXJuLF0NCmNkZWF0aHMgPC0gY292aWQxOVshaXMubmEoY292aWQxOSRkZWF0aHMpLF0NCmxhc3Ryb3cgPC0gbnJvdyhjbGVhbikNCmNsZWFuIDwtIGNsZWFuICU+JSBtdXRhdGUoDQogICNOZXcuUG9zaXRpdmVbbGFzdHJvd10gPSBwb3NpdGl2ZVtsYXN0cm93XSAtIHBvc2l0aXZlW2xhc3Ryb3ctMV0pIA0KICBuZWdhdGl2ZSA9IFRvdGFsLlRlc3RlZCAtIHBvc2l0aXZlLA0KICBQZXJjZW50LlBvcyA9IHBvc2l0aXZlL1RvdGFsLlRlc3RlZCoxMDAsDQogIG5wXzdkYXkgPSByb2xsbWVhbihOZXcuUG9zaXRpdmUsIGs9NywgZmlsbCA9IE5BKQ0KKQ0KYGBgDQpgYGB7ciwgZWNobyA9IEZBTFNFfQ0KdG9kYXkgPC0gY2RlYXRoc1tucm93KGNkZWF0aHMpLF0NCmRheSA8LSB0b2RheSRkYXRlDQpuZXdfcG9zIDwtIHRvZGF5JE5ldy5Qb3NpdGl2ZQ0KcGVyY2VudF9wb3MgPC0gdG9kYXkkTmV3LlBlcmNlbnQuUG9zaXRpdmUNCnBlcmNlbnRfaG9zcGl0YWwgPC0gdG9kYXkkUGVyY2VudC5Ib3NwaXRhbGl6ZWQNCnNpY2sgPC0gdG9kYXkkU3RpbGwuU2ljaw0KSW93YVBvcCA8LSAzLjE1NSoxMF42DQpgYGANCiMgU3VtbWFyeSBgciBkYXlgDQoNClRvZGF5IHdlIGhhZCBgciBuZXdfcG9zYCBuZXcgcG9zaXRpdmUgdGVzdHMgd2hpY2ggaXMgYHIgcGVyY2VudF9wb3NgIHBlcmNlbnQgb2YgdGhlIHRvdGFsIHRlc3RzIHJlY29yZGVkIGluIHRoZSBsYXN0IDI0IGhvdXJzLiBJbiBJb3dhIHRoZXJlIGFyZSBgciBzaWNrYCBwZW9wbGUgc3RpbGwgc2ljayB3aXRoIENPVklELTE5IGFuZCBgciBwZXJjZW50X2hvc3BpdGFsYCBwZXJjZW50IG9mIHRob3NlIHBlb3BsZSBhcmUgaG9zcGl0YWxpemVkLiBGcm9tIHRoZSBsb2dpc2l0YyBncm93dGggbW9kZWwsIHdlIHByZWRpY3QgdGhhdCBpbiAxNCBkYXlzLCBJb3dhIHdpbGwgaGF2ZSBgciBwcmVkaWN0MTRgIGluZmVjdGVkIHBlb3BsZS4NCg0KIyMgVmlldyBEYXRhDQpTbywgaXQgdHVybnMgb3V0IHRvIGJlIHZlcnkgZGlmZmljdWx0IHRvIGZpbmQgcGFzdCBkYXRhIGluIHRoZSBTdGF0ZSBvZiBJb3dhIHNpbmNlIHRoZXkgcmUtcHVibGlzaCBldmVyeXRoaW5nIGRhaWx5LiAgSGVyZSBhcmUgdGhlIGxhc3QgNiBkYXlzIG9mIGRhdGEgaWYgeW91IGFyZSBpbnRlcmVzdGVkOg0KYGBge3J9DQp0YWlsKGNsZWFuKQ0KYGBgDQoNCiMgRGF0YSBFeHBsb3JhdGlvbg0KDQojIyBQb3NpdGl2ZSBUZXN0cw0KDQojIyMgRXhwb25lbnRpYWwgTW9kZWwNClJ1biBhIGxpbmVhciBtb2RlbCBvbiB0aGUgbG9nYXJpdGhtIG9mIHRoZSBwb3NpdGl2ZSBjYXNlcy4NCmBgYHtyIGxvZyBtb2RlbCwgZXJyb3I9RkFMU0V9DQpxcGxvdChkYXRlLCBsb2cocG9zaXRpdmUpLCBkYXRhID1jbGVhbikgKyBnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aCgpKw0KICBzdGF0X3Ntb290aChtZXRob2QgPSAibG0iLCBjb2wgPSAicmVkIikgDQpgYGANCg0KYGBge3IsIGVjaG8gPSBGQUxTRX0NCm1vZGVsMCA8LSBsbShsb2cocG9zaXRpdmUpfmRhdGUsIGRhdGE9Y2xlYW4pDQojbW9kZWwwJGNvZWZmaWNpZW50c1syXQ0KcG9zaXRpdmVfZG91YmxpbmdfdGltZSA8LSBsb2coMikvbW9kZWwwJGNvZWZmaWNpZW50c1syXQ0KI3Bvc2l0aXZlX2RvdWJsaW5nX3RpbWUNCmBgYA0KRm9yIHRoZSBtb2RlbCAkcG9zaXRpdmUgPSBlXntrIGRhdGV9JCwgJGs9JCBgciBtb2RlbDAkY29lZmZpY2llbnRzWzJdYC4gDQpFc3RpbWF0ZWQgZG91YmxpbmcgdGltZSBmb3IgcG9zaXRpdmUgY2FzZXMgaXMgYHIgcG9zaXRpdmVfZG91YmxpbmdfdGltZWAgZGF5cy4gIEhlcmUgaXMgd2hhdCB0aGF0IGxvb2tzIGxpa2Ugb24gdGhlIG9yaWdpbmFsIGRhdGEuDQpgYGB7ciwgZWNobyA9IEZBTFNFfQ0KeCA9IGFzLm51bWVyaWMoY2xlYW4kZGF0ZSkNCnkgPSBleHAobW9kZWwwJGNvZWZmaWNpZW50c1sxXSsgbW9kZWwwJGNvZWZmaWNpZW50c1syXSAqeCkNCkEgPSBkYXRhLmZyYW1lKGRhdGUgPSBjbGVhbiRkYXRlLCBwb3NpdGl2ZSA9IGNsZWFuJHBvc2l0aXZlLCB5ID0geSkNCg0KZ2dwbG90KEEsIGFlcyhkYXRlLCB5ID0gdmFsdWUsIGNvbG9yID0gdmFyaWFibGUpKSArIA0KICAgIGdlb21fcG9pbnQoYWVzKHkgPSBwb3NpdGl2ZSwgY29sID0gInBvc2l0aXZlIikpICsgICAgIGdlb21fbGluZShhZXMoeSA9IHksIGNvbCA9ICJtb2RlbCIpKSANCg0KYGBgDQoNCiMjIyBNb2RpZmllZCBFeHBvbmVudGlhbCBNb2RlbA0KQnkgbm93IHRoZXJlIGlzIHN0cm9uZyBldmlkZW5jZSB0aGF0IHRoZSBjdXJ2ZSBpcyBmbGF0dGVuaW5nLiBXZSBjYW4gY3JlYXRlIGEgbmV3IGxpbmVhciBtb2RlbCB0aGF0IHVzZXMgdGhlIG1vcmUgcmVjZW50IGRhdGEgdG8gaW1wcm92ZSBvdXIgbW9kZWwuIExldCdzIGxvb2sgdG8gc2VlIHdoYXQgaGFwcGVucyBpZiB3ZSBvbmx5IHVzZSBkYXRhIGZyb20gbGF0ZXIgd2hlbiB3ZSB3ZXJlIGRvaW5nIG1vcmUgdGVzdGluZy4NCmBgYHtyLCBlY2hvID0gRkFMU0V9DQpsYXRlZGF0YSA8LSBjbGVhblstKDE6MTApLF0NCm1vZGVsNCA8LSBsbShsb2cocG9zaXRpdmUpfmRhdGUsIGRhdGE9bGF0ZWRhdGEpDQpwb3NpdGl2ZV9kb3VibGluZ190aW1lMiA8LSBsb2coMikvbW9kZWw0JGNvZWZmaWNpZW50c1syXQ0KcXBsb3QoZGF0ZSwgbG9nKHBvc2l0aXZlKSwgZGF0YSA9bGF0ZWRhdGEpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgoKSsNCiAgc3RhdF9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sID0gInB1cnBsZSIpIA0KYGBgDQpGb3IgdGhlIG1vZGVsICRwb3NpdGl2ZSA9IGVee2sgZGF0ZX0kLCAkaz0kIGByIG1vZGVsNCRjb2VmZmljaWVudHNbMl1gLiANCkVzdGltYXRlZCBkb3VibGluZyB0aW1lIGZvciBwb3NpdGl2ZSBjYXNlcyBpcyBgciBwb3NpdGl2ZV9kb3VibGluZ190aW1lMmAgZGF5cy4gIEhlcmUgaXMgd2hhdCB0aGF0IGxvb2tzIGxpa2Ugb24gdGhlIG9yaWdpbmFsIGRhdGEuDQpgYGB7ciwgZWNobyA9IEZBTFNFfQ0KeCA9IGFzLm51bWVyaWMobGF0ZWRhdGEkZGF0ZSkNCnkgPSBleHAobW9kZWw0JGNvZWZmaWNpZW50c1sxXSsgbW9kZWw0JGNvZWZmaWNpZW50c1syXSAqeCkNCkEgPSBkYXRhLmZyYW1lKGRhdGUgPSBsYXRlZGF0YSRkYXRlLCBwb3NpdGl2ZSA9IGxhdGVkYXRhJHBvc2l0aXZlLCB5ID0geSkNCmdncGxvdChBLCBhZXMoZGF0ZSwgeSA9IHZhbHVlLCBjb2xvciA9IHZhcmlhYmxlKSkgKyANCiAgICBnZW9tX3BvaW50KGFlcyh5ID0gcG9zaXRpdmUsIGNvbCA9ICJwb3NpdGl2ZSIpKSArICAgICBnZW9tX2xpbmUoYWVzKHkgPSB5LCBjb2wgPSAibW9kZWwiKSkgDQpgYGANCg0KIyMgRGVhdGhzDQoNCg0KIyMjIEV4cG9uZW50aWFsIE1vZGVsDQpXZSB3aWxsIHN0YXJ0IHRoZSBkYXRhIHdoZW4gd2UgaGF2ZSBub24temVybyBkZWF0aHMuDQpgYGB7ciwgZWNobyA9IEZBTFNFfQ0KemVyb2RlYXRocyA8LSBjZGVhdGhzJGRlYXRocyA9PSAwDQpjZGVhdGhzIDwtIGNkZWF0aHNbIXplcm9kZWF0aHMsXQ0KYGBgDQoNCmBgYHtyLCBlY2hvID0gRkFMU0V9DQpxcGxvdChkYXRlLCBsb2coZGVhdGhzKSwgZGF0YSA9Y2RlYXRocykgKyBnZW9tX3BvaW50KCkgKyBnZW9tX3Ntb290aCgpKw0KICBzdGF0X3Ntb290aChtZXRob2QgPSAibG0iLCBjb2wgPSAicmVkIikNCmBgYA0KDQpgYGB7ciwgZWNobyA9IEZBTFNFfQ0KbW9kZWwgPC0gbG0obG9nKGRlYXRocyl+ZGF0ZSwgZGF0YT1jZGVhdGhzKQ0KI21vZGVsJGNvZWZmaWNpZW50c1syXQ0KZGVhdGhfZG91YmxpbmdfdGltZSA8LSBsb2coMikvbW9kZWwkY29lZmZpY2llbnRzWzJdDQojZGVhdGhfZG91YmxpbmdfdGltZQ0KYGBgDQpGb3IgdGhlIG1vZGVsICRkZWF0aHMgPSBlXntrIGRhdGV9JCwgJGs9JCBgciBtb2RlbCRjb2VmZmljaWVudHNbMl1gLiANCkVzdGltYXRlZCB0aW1lIGZvciBkZWF0aHMgdG8gZG91YmxlIGlzIGByIGRlYXRoX2RvdWJsaW5nX3RpbWVgIGRheXMuDQoNCiMjIyBMYXRlciBEYXRhDQpBcyBhYm92ZSwgbGV0J3MgbG9vayBhdCB0aGUgc2FtZSBtb2RlbHMsIGJ1dCBvbmx5IGFmdGVyIHdlIGdvdCBzZXJpb3VzIGFib3V0IHRlc3RpbmcuDQoNCmBgYHtyICwgZWNobyA9IEZBTFNFfQ0KbGF0ZWRhdGEyIDwtIGxhdGVkYXRhWy0oMTo4KSxdDQpxcGxvdChkYXRlLCBsb2coZGVhdGhzKSwgZGF0YSA9bGF0ZWRhdGEyKSArIGdlb21fcG9pbnQoKSArIGdlb21fc21vb3RoKCkrDQogIHN0YXRfc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbCA9ICJyZWQiKQ0KYGBgDQoNCmBgYHtyLCBlY2hvID0gRkFMU0V9DQptb2RlbDUgPC0gbG0obG9nKGRlYXRocyl+ZGF0ZSwgZGF0YT1sYXRlZGF0YTIpDQojbW9kZWwkY29lZmZpY2llbnRzWzJdDQpkZWF0aF9kb3VibGluZ190aW1lMiA8LSBsb2coMikvbW9kZWw1JGNvZWZmaWNpZW50c1syXQ0KI2RlYXRoX2RvdWJsaW5nX3RpbWUNCmBgYA0KRm9yIHRoZSBtb2RlbCAkZGVhdGhzID0gZV57ayBkYXRlfSQsICRrPSQgYHIgbW9kZWw1JGNvZWZmaWNpZW50c1syXWAuIA0KRXN0aW1hdGVkIHRpbWUgZm9yIGRlYXRocyB0byBkb3VibGUgaXMgYHIgZGVhdGhfZG91YmxpbmdfdGltZTJgIGRheXMuDQoNCmBgYHtyLCBlY2hvID0gRkFMU0V9DQp4ID0gYXMubnVtZXJpYyhsYXRlZGF0YTIkZGF0ZSkNCnkgPSBleHAobW9kZWw1JGNvZWZmaWNpZW50c1sxXSsgbW9kZWw1JGNvZWZmaWNpZW50c1syXSAqeCkNCkIgPSBkYXRhLmZyYW1lKGRhdGUgPSBsYXRlZGF0YTIkZGF0ZSwgZGVhdGhzID0gbGF0ZWRhdGEyJGRlYXRocywgeSA9IHkpDQpnZ3Bsb3QoQiwgYWVzKGRhdGUsIHkgPSB2YWx1ZSwgY29sb3IgPSB2YXJpYWJsZSkpICsgDQogICAgZ2VvbV9wb2ludChhZXMoeSA9IGRlYXRocywgY29sID0gImRlYXRocyIpKSArICAgICBnZW9tX2xpbmUoYWVzKHkgPSB5LCBjb2wgPSAibW9kZWwiKSkgDQpgYGANCiMjIyBMb2dpc3RpYyBNb2RlbA0KVG8gdHJ5IHRvIGZpdCBhIGxvZ2lzdGljIG1vZGVsIHRvIHRoZSBkYXRhLCB3ZSB3YW50IHRvIGZpdCBhIHBhcmFib2xhIHRvIHRoZSByYXRlIG9mIGNoYW5nZSwgYnV0IHRoZSBpbnB1dCB2YXJpYWJsZSBpcyBjYXNlcyBvciBkZWF0aHMgYW5kIG5vdCB0aW1lLiAgVGhpcyBpcyBiZWNhdXNlIHRoZSBsb2dpc3RpYyBtb2RlbCBjb21lcyBmcm9tIHRoZSBkaWZmZXJlbnRpYWwgZXF1YXRpb24gJFxkaXNwbGF5c3R5bGV7XGZyYWN7ZFB9e2R0fT0ga1AoMS1cZnJhY3tQfXtNfSl9JC4gIE5vdGUgdGhhdCB0aGlzIGVxdWF0aW9uIGFzIGEgZnVuY3Rpb24gb2YgJFAkIGlzIGEgcGFyYWJvbGEgd2l0aCB6ZXJvZXMgYXQgJFA9MCQgYW5kICRQPU0kLg0KYGBge3J9DQpjbGVhbiA8LSBjbGVhblstYygxLDEwKSxdDQp3aXRoKGNsZWFuLCBwbG90KHBvc2l0aXZlLCBOZXcuUG9zaXRpdmUsIHBjaD0xNiwgeGxhYiA9ICJQb3NpdGl2ZSBDb3VudHMiLCB5bGFiID0gIlJhdGUgb2YgQ2hhbmdlIG9mIFBvc2l0aXZlIiwgY2V4LmxhYiA9IDEuMywgY29sID0gImJsdWUiKSkNCmBgYA0KTm93LCBpdCBkb2Vzbid0IHJlYWxseSBsb29rIHF1YWRyYXRpYywgYnV0IHdlIGFyZSBub3QgZ29pbmcgdG8gbGV0IHRoYXQgc3RvcCB1cyBmcm9tIG1hdGhlbWF0aWNzLiBOZXh0LCB3ZSB3aWxsIGZpdCBhIHF1YWRyYXRpYyBtb2RlbCB0byB0aGUgZGF0YS4NCmBgYHtyfQ0KY2xlYW4kUDIgPC0gYXMubnVtZXJpYyhjbGVhbiRwb3NpdGl2ZSleMg0KcXVhZHJhdGljIDwtbG0oTmV3LlBvc2l0aXZlIH4gcG9zaXRpdmUgKyBQMi0xLCBkYXRhID0gY2xlYW4pDQpyIDwtIHF1YWRyYXRpYyRjb2VmZmljaWVudHNbMl0qKC0xKQ0KTSA8LSBxdWFkcmF0aWMkY29lZmZpY2llbnRzWzFdL3INCk1wcmludCA8LSBmb3JtYXQoTSwgc2NpZW50aWZpYyA9IEZBTFNFKQ0KcHJlZGljdGVkY291bnRzIDwtIHdpdGgoY2xlYW4scHJlZGljdChxdWFkcmF0aWMsbGlzdChwb3NpdGl2ZSA9IHBvc2l0aXZlLCBQMiA9IFAyKSkpDQpgYGANCkxldCdzIHBsb3QgdGhlIG1vZGVsOg0KYGBge3J9DQp3aXRoKGNsZWFuLCBwbG90KHBvc2l0aXZlLCBOZXcuUG9zaXRpdmUsIHBjaD0xNiwgeGxhYiA9ICJQb3NpdGl2ZSBDb3VudHMiLCB5bGFiID0gIlJhdGUgb2YgQ2hhbmdlIG9mIFBvc2l0aXZlIiwgY2V4LmxhYiA9IDEuMywgY29sID0gImJsdWUiKSkNCndpdGgoY2xlYW4sbGluZXMocG9zaXRpdmUsIHByZWRpY3RlZGNvdW50cywgY29sID0gImRhcmtncmVlbiIsIGx3ZCA9IDMpKQ0KSW93YVBlcmNlbnQgPC0gTS9Jb3dhUG9wDQpgYGANClNvLCB3ZSBoYXZlIGEgcXVhZHJhdGljIG1vZGVsIHRoYXQgbG9va3MgbGlrZSAkXGZyYWN7ZFB9e2R0fSQgPSBgciBxdWFkcmF0aWMkY29lZmZpY2llbnRzWzFdYCRQXjIkICsgYHIgcXVhZHJhdGljJGNvZWZmaWNpZW50c1syXWAkUCQgPSBgciByYCRQKDEtUC8kIGByIE1wcmludGAkKSQuIFRoaXMgaXMgbG9va2luZyBwcmV0dHkgZ29vZC4gSW4gcGFydGljdWxhciwgYmVjYXVzZSAkTT0kIGByIE1wcmludGAsIHdlIGNhbiBlc3RpbWF0ZSB0aGF0IGByIElvd2FQZXJjZW50YCBvZiBJb3dhJ3MgcG9wdWxhdGlvbiB3aWxsIGJlY29tZSBpbmZlY3RlZC4gIFdlIHdvdWxkIGxpa2UgdG8gc2VlIHdoYXQgdGhhdCBsb29rcyBsaWtlIGZvciB0aGUgb3JpZ2luYWwgZGF0YS4gV2hlbiBSIHBlcmZvcm1zIGxvZ2lzdGljIG1vZGVsaW5nLCBpdCB1c3VhbGx5IGhhcyBiaW5vbWlhbCBkYXRhIGFuZCB0aHVzIGV4cGVjdHMgbnVtYmVycyB0aGF0IGFyZSBiZXR3ZWVuIHplcm8gYW5kIG9uZS4gV2Ugd2lsbCB1c2Ugb3VyIGVzdGltYXRlIG9mICRNJCB0byBjcmVhdGUgcG9zdGl0aXZlIGNvdW50cyB0aGF0IGFyZSBhIHBlcmNlbnRhZ2Ugb2YgJE0kLiANCmBgYHtyLCBlY2hvID0gRkFMU0V9DQpjbGVhbiRiaW5vbWlhbCA8LSBjbGVhbiRwb3NpdGl2ZS9NDQpteWxvZ2l0IDwtIGdsbShiaW5vbWlhbCB+IGRhdGUsIGRhdGEgPSBjbGVhbiwgZmFtaWx5ID0gImJpbm9taWFsIikNCiNnZ3Bsb3QoY2xlYW4sIGFlcyh4PWRhdGUsIHk9Ymlub21pYWwpKSArIA0KICMgZ2VvbV9wb2ludCgpICsgDQogICNzdGF0X3Ntb290aChtZXRob2Q9ImdsbSIsIG1ldGhvZC5hcmdzPWxpc3QoZmFtaWx5PSJiaW5vbWlhbCIpKQ0KeXByZWRpY3QgPC0gcHJlZGljdChteWxvZ2l0LCBsaXN0KGRhdGUgPSBjbGVhbiRkYXRlKSwgdHlwZSA9ICJyZXNwb25zZSIpKk0NCnFwbG90KGRhdGUsIHBvc2l0aXZlLCBkYXRhID0gY2xlYW4pICsNCiAgI3N0YXRfc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbCA9ICJncmVlbiIpICsNCiAgZ2VvbV9saW5lKGFlcyh5ID0geXByZWRpY3QsIGNvbCA9ICJtb2RlbCIpLCBzaXplID0gMS4yNSkgDQpgYGANCk9rYXksIHRoYXQgbG9va3MgcXVpdGUgZ29vZC4gV2hhdCB3aWxsIGl0IHByZWRpY3QgZm9yIHRoZSBuZXh0IDE0IGRheXM/DQpgYGB7ciwgZWNobz1GQUxTRX0NCm5kYXRlIDwtc2VxKGFzLkRhdGUoIjIwMjAtMDMtMDkiKSxhcy5EYXRlKGRheSArIDE0KSxieSA9IDEpDQojcGxheSA8LSBjbGVhbiAlPiUgZmlsdGVyKHJvd19udW1iZXIoKSA+PSAobigpIC0gNykpDQpwbGF5IDwtIGNsZWFuDQp5cHJlZGljdDIgPC0gcHJlZGljdChteWxvZ2l0LCBsaXN0KGRhdGUgPW5kYXRlKSwgdHlwZSA9ICJyZXNwb25zZSIpKk0NCmRmIDwtIGRhdGEuZnJhbWUoZGF0ZSA9IG5kYXRlLCBtb2RlbCA9IHlwcmVkaWN0MikNCmRmIDwtIG1lcmdlKGRmLCBwbGF5LCBhbGwgPSBUUlVFKQ0KcHJlZGljdDE0IDwtIGZvcm1hdChyb3VuZCh5cHJlZGljdDJbbGVuZ3RoKHlwcmVkaWN0MildLCBkaWdpdHMgPSAwKSwgc2NpZW50aWZpYyA9IEZBTFNFKQ0KcXBsb3QoZGF0ZSwgbW9kZWwsIHlsYWIgPSAiUG9zaXRpdmUgQ2FzZXMiLCBkYXRhID0gZGYsIGdlb20gPSAic21vb3RoIikgKyANCiAgI2dlb21fbGluZShzaXplID0gMS4yNSwgY29sb3IgPSAicmVkIikgKw0KICBnZW9tX3BvaW50KGFlcyh5PXBvc2l0aXZlKSwgc2hhcGUgPSA4KSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICdyaWdodCcpDQpgYGANClRoaXMgcHJlZGljdHMgdGhhdCBpbiAxNCBkYXlzLCBJb3dhIHdpbGwgaGF2ZSBgciBwcmVkaWN0MTRgIGluZmVjdGVkIHBlb3BsZS4NCg0KIyMgTmV3IFBvc2l0aXZlcw0KYGBge3IsIGVjaG8gPSBGQUxTRX0NCm1vZGVsNCA8LSBsbShsb2coTmV3LlBvc2l0aXZlKSB+IGRhdGUsIGRhdGEgPSBjbGVhbikNCnByZWQgPC0gcHJlZGljdChtb2RlbDQsIG5ld2RhdGEgPSBkYXRhLmZyYW1lKGRhdGUgPWNsZWFuJGRhdGUpKQ0KbnBfZG91YmxpbmdfdGltZSA8LSBsb2coMikvbW9kZWw0JGNvZWZmaWNpZW50c1syXQ0KcXBsb3QoZGF0ZSwgTmV3LlBvc2l0aXZlLCBkYXRhID0gY2xlYW4sIGdlb20gPSBjKCJwb2ludCIsICJzbW9vdGgiKSkgKw0KICAjc3RhdF9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sID0gImdyZWVuIikgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBleHAocHJlZCksIGNvbCA9ICJtb2RlbCIpKSArIA0KICBnZW9tX2xpbmUoYWVzKHk9bnBfN2RheSwgY29sID0gIjcgZGF5IGF2ZXJhZ2UiKSwgc2l6ZSA9IDEuMjUpDQogIA0KYGBgDQpGb3IgdGhlIG1vZGVsICRuZXcgcG9zaXRpdmVzID0gZV57ayBkYXRlfSQsICRrPSQgYHIgbW9kZWw0JGNvZWZmaWNpZW50c1syXWAuIA0KRXN0aW1hdGVkIHRpbWUgZm9yIG5ldyBwb3NpdGl2ZXMgdG8gZG91YmxlIGlzIGByIG5wX2RvdWJsaW5nX3RpbWVgIGRheXMuDQoNCg0KDQojIyBBbHRlcm5hdGl2ZSBNb2RlbGluZw0KVGhpcyBkaWRuJ3QgdHVybiBvdXQgd2VsbCwgYnV0IGl0IGlzIHN0aWxsIGhlcmUgZm9yIGhpc3RvcmljYWwgcGVyc3BlY3RpdmU6DQoNCiMjIyBQb3NpdGl2ZXMgTGluZWFyIE1vZGVsDQoNCkZpcnN0IHJ1biBhIGxpbmVhciBtb2RlbCBvbiBwb3NpdGl2ZSB0ZXN0IHJlc3VsdHMuDQpgYGB7ciwgZXJyb3I9RkFMU0V9DQpxcGxvdChkYXRlLCBwb3NpdGl2ZSwgZGF0YSA9Y2xlYW4pICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgoKSsNCiAgc3RhdF9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sID0gInJlZCIpDQpgYGANCg0KIyMjIERlYXRocyBMaW5lYXIgTW9kZWwNCg0KYGBge3IgbGluZWFyIG1vZGVsfQ0KcXBsb3QoZGF0ZSwgZGVhdGhzLCBkYXRhID1jZGVhdGhzLCBybS5uYT1UUlVFKSArIGdlb21fcG9pbnQoKSArIGdlb21fc21vb3RoKCkrDQogIHN0YXRfc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbCA9ICJyZWQiKQ0KbW9kZWwgPC0gbG0oZGVhdGhzfmRhdGUsIGRhdGE9Y2RlYXRocykNCiNtb2RlbCRjb2VmZmljaWVudHMNCmBgYA0KDQoNCg0K